-Initial working(?) implementation of shaders for 2D. Lighting still not there though.

Check for reference:
https://github.com/okamstudio/godot/wiki/shader
This commit is contained in:
Juan Linietsky 2015-01-12 10:19:09 -03:00
parent f3dc51fc69
commit 544ce2a1db
11 changed files with 115 additions and 7 deletions

View File

@ -1564,6 +1564,7 @@ void RasterizerGLES2::shader_set_default_texture_param(RID p_shader, const Strin
RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{ RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
const Shader *shader=shader_owner.get(p_shader); const Shader *shader=shader_owner.get(p_shader);
ERR_FAIL_COND_V(!shader,RID());
const Map<StringName,RID>::Element *E=shader->default_textures.find(p_name); const Map<StringName,RID>::Element *E=shader->default_textures.find(p_name);
if (!E) if (!E)
@ -1571,6 +1572,22 @@ RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const String
return E->get(); return E->get();
} }
Variant RasterizerGLES2::shader_get_default_param(RID p_shader, const StringName& p_name) {
Shader *shader=shader_owner.get(p_shader);
ERR_FAIL_COND_V(!shader,Variant());
//update shader params if necesary
//make sure the shader is compiled and everything
//so the actual parameters can be properly retrieved!
if (shader->dirty_list.in_list()) {
_update_shader(shader);
}
if (shader->valid && shader->uniforms.has(p_name))
return shader->uniforms[p_name].default_value;
return Variant();
}
/* COMMON MATERIAL API */ /* COMMON MATERIAL API */
@ -4567,6 +4584,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
if (fragment_flags.uses_screen_uv) { if (fragment_flags.uses_screen_uv) {
enablers.push_back("#define ENABLE_SCREEN_UV\n"); enablers.push_back("#define ENABLE_SCREEN_UV\n");
} }
if (fragment_flags.uses_texpixel_size) {
enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
}
canvas_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers); canvas_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
@ -4582,6 +4602,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex; p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex;
p_shader->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal; p_shader->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal;
p_shader->uses_time=uses_time; p_shader->uses_time=uses_time;
p_shader->uses_texpixel_size=fragment_flags.uses_texpixel_size;
p_shader->version++; p_shader->version++;
} }
@ -7874,7 +7895,7 @@ void RasterizerGLES2::canvas_end_rect() {
RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_texture) { RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_texture) {
if (p_texture==canvas_tex) { if (p_texture==canvas_tex && !rebind_texpixel_size) {
if (canvas_tex.is_valid()) { if (canvas_tex.is_valid()) {
Texture*texture=texture_owner.get(p_texture); Texture*texture=texture_owner.get(p_texture);
return texture; return texture;
@ -7882,14 +7903,16 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex
return NULL; return NULL;
} }
rebind_texpixel_size=false;
if (p_texture.is_valid()) { if (p_texture.is_valid()) {
Texture*texture=texture_owner.get(p_texture); Texture*texture=texture_owner.get(p_texture);
if (!texture) { if (!texture) {
canvas_tex=RID(); canvas_tex=RID();
glBindTexture(GL_TEXTURE_2D,white_tex); glBindTexture(GL_TEXTURE_2D,white_tex);
return NULL; return NULL;
} }
@ -7898,6 +7921,9 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex
glBindTexture(GL_TEXTURE_2D,texture->tex_id); glBindTexture(GL_TEXTURE_2D,texture->tex_id);
canvas_tex=p_texture; canvas_tex=p_texture;
if (uses_texpixel_size) {
canvas_shader.set_uniform(CanvasShaderGLES2::TEXPIXEL_SIZE,Size2(1.0/texture->width,1.0/texture->height));
}
return texture; return texture;
@ -8281,6 +8307,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
csy = -1.0; csy = -1.0;
canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) ); canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) );
canvas_opacity=1.0;
uses_texpixel_size=false;
canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
@ -8330,7 +8358,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
if (shader) { if (shader) {
canvas_shader.set_custom_shader(shader->custom_code_id); canvas_shader.set_custom_shader(shader->custom_code_id);
canvas_shader.bind(); if (canvas_shader.bind())
rebind_texpixel_size=true;
if (ci->shader_version!=shader->version) { if (ci->shader_version!=shader->version) {
//todo optimize uniforms //todo optimize uniforms
@ -8383,9 +8412,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
} }
//if uses TIME - draw_next_frame=true //if uses TIME - draw_next_frame=true
uses_texpixel_size=shader->uses_texpixel_size;
} else { } else {
canvas_shader.set_custom_shader(0); canvas_shader.set_custom_shader(0);
canvas_shader.bind(); canvas_shader.bind();
uses_texpixel_size=false;
} }

View File

@ -192,6 +192,7 @@ class RasterizerGLES2 : public Rasterizer {
bool uses_discard; bool uses_discard;
bool uses_time; bool uses_time;
bool uses_normal; bool uses_normal;
bool uses_texpixel_size;
Map<StringName,ShaderLanguage::Uniform> uniforms; Map<StringName,ShaderLanguage::Uniform> uniforms;
StringName first_texture; StringName first_texture;
@ -1171,6 +1172,8 @@ class RasterizerGLES2 : public Rasterizer {
GLuint white_tex; GLuint white_tex;
RID canvas_tex; RID canvas_tex;
float canvas_opacity; float canvas_opacity;
bool uses_texpixel_size;
bool rebind_texpixel_size;
_FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture); _FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture);
VS::MaterialBlendMode canvas_blend_mode; VS::MaterialBlendMode canvas_blend_mode;
@ -1262,6 +1265,8 @@ public:
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture); virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const; virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name);
/* COMMON MATERIAL API */ /* COMMON MATERIAL API */
virtual RID material_create(); virtual RID material_create();

View File

@ -147,6 +147,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
} break; } break;
case SL::Node::TYPE_VARIABLE: { case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode=(SL::VariableNode*)p_node; SL::VariableNode *vnode=(SL::VariableNode*)p_node;
if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) { if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) {
if (vnode->name==vname_vertex && p_assign_left) { if (vnode->name==vname_vertex && p_assign_left) {
@ -173,6 +174,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
} }
if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) { if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) {
if (vnode->name==vname_discard) { if (vnode->name==vname_discard) {
@ -181,9 +185,6 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
if (vnode->name==vname_normalmap) { if (vnode->name==vname_normalmap) {
uses_normalmap=true; uses_normalmap=true;
} }
if (vnode->name==vname_normal) {
uses_normal=true;
}
if (vnode->name==vname_screen_uv) { if (vnode->name==vname_screen_uv) {
uses_screen_uv=true; uses_screen_uv=true;
} }
@ -216,6 +217,47 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
uses_light=true; uses_light=true;
} }
}
if (type==ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX) {
if (vnode->name==vname_var1_interp) {
flags->use_var1_interp=true;
}
if (vnode->name==vname_var2_interp) {
flags->use_var2_interp=true;
}
}
if (type==ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT) {
if (vnode->name==vname_texpixel_size) {
uses_texpixel_size=true;
}
if (vnode->name==vname_normal) {
uses_normal=true;
}
if (vnode->name==vname_screen_uv) {
uses_screen_uv=true;
}
if (vnode->name==vname_var1_interp) {
flags->use_var1_interp=true;
}
if (vnode->name==vname_var2_interp) {
flags->use_var2_interp=true;
}
}
if (type==ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT) {
if (vnode->name==vname_light) {
uses_light=true;
}
} }
if (vnode->name==vname_time) { if (vnode->name==vname_time) {
@ -556,6 +598,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
uses_time=false; uses_time=false;
uses_normalmap=false; uses_normalmap=false;
uses_normal=false; uses_normal=false;
uses_texpixel_size=false;
vertex_code_writes_vertex=false; vertex_code_writes_vertex=false;
uniforms=r_uniforms; uniforms=r_uniforms;
flags=&r_flags; flags=&r_flags;
@ -590,6 +633,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
r_flags.uses_time=uses_time; r_flags.uses_time=uses_time;
r_flags.uses_normalmap=uses_normalmap; r_flags.uses_normalmap=uses_normalmap;
r_flags.uses_normal=uses_normalmap; r_flags.uses_normal=uses_normalmap;
r_flags.uses_texpixel_size=uses_texpixel_size;
r_code_line=code; r_code_line=code;
r_globals_line=global_code; r_globals_line=global_code;
@ -742,14 +786,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[4]["POSITION"]="gl_Position"; mode_replace_table[4]["POSITION"]="gl_Position";
mode_replace_table[4]["NORMAL"]="normal"; mode_replace_table[4]["NORMAL"]="normal";
mode_replace_table[4]["UV"]="uv_interp"; mode_replace_table[4]["UV"]="uv_interp";
mode_replace_table[4]["SRC_COLOR"]="color_interp";
mode_replace_table[4]["COLOR"]="color"; mode_replace_table[4]["COLOR"]="color";
mode_replace_table[4]["TEXTURE"]="texture"; mode_replace_table[4]["TEXTURE"]="texture";
mode_replace_table[4]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
mode_replace_table[4]["VAR1"]="var1_interp"; mode_replace_table[4]["VAR1"]="var1_interp";
mode_replace_table[4]["VAR2"]="var2_interp"; mode_replace_table[4]["VAR2"]="var2_interp";
mode_replace_table[4]["SCREEN_UV"]="screen_uv"; mode_replace_table[4]["SCREEN_UV"]="screen_uv";
mode_replace_table[4]["POINT_COORD"]="gl_PointCoord"; mode_replace_table[4]["POINT_COORD"]="gl_PointCoord";
mode_replace_table[4]["TIME"]="time"; mode_replace_table[4]["TIME"]="time";
mode_replace_table[5]["SRC_COLOR"]="color";
mode_replace_table[5]["COLOR"]="color"; mode_replace_table[5]["COLOR"]="color";
mode_replace_table[5]["NORMAL"]="normal"; mode_replace_table[5]["NORMAL"]="normal";
mode_replace_table[5]["LIGHT_DIR"]="light_dir"; mode_replace_table[5]["LIGHT_DIR"]="light_dir";
@ -781,5 +828,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
vname_time="TIME"; vname_time="TIME";
vname_normalmap="NORMALMAP"; vname_normalmap="NORMALMAP";
vname_normal="NORMAL"; vname_normal="NORMAL";
vname_texpixel_size="TEXTURE_PIXEL_SIZE";
} }

View File

@ -52,6 +52,7 @@ private:
bool uses_screen_uv; bool uses_screen_uv;
bool uses_normalmap; bool uses_normalmap;
bool uses_normal; bool uses_normal;
bool uses_texpixel_size;
bool vertex_code_writes_vertex; bool vertex_code_writes_vertex;
Flags *flags; Flags *flags;
@ -70,6 +71,7 @@ private:
StringName vname_time; StringName vname_time;
StringName vname_normalmap; StringName vname_normalmap;
StringName vname_normal; StringName vname_normal;
StringName vname_texpixel_size;
Map<StringName,ShaderLanguage::Uniform> *uniforms; Map<StringName,ShaderLanguage::Uniform> *uniforms;
@ -104,6 +106,7 @@ public:
bool uses_light; bool uses_light;
bool uses_time; bool uses_time;
bool uses_normal; bool uses_normal;
bool uses_texpixel_size;
}; };
Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL); Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL);

View File

@ -132,6 +132,11 @@ uniform float shadow_attenuation;
#endif #endif
#if defined(USE_TEXPIXEL_SIZE)
uniform vec2 texpixel_size;
#endif
FRAGMENT_SHADER_GLOBALS FRAGMENT_SHADER_GLOBALS

View File

@ -226,5 +226,6 @@ Size2 GridContainer::get_minimum_size() const {
GridContainer::GridContainer() { GridContainer::GridContainer() {
set_stop_mouse(false);
columns=1; columns=1;
} }

View File

@ -210,6 +210,8 @@ public:
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0; virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0; virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name)=0;
/* COMMON MATERIAL API */ /* COMMON MATERIAL API */
virtual RID material_create()=0; virtual RID material_create()=0;

View File

@ -231,6 +231,11 @@ RID RasterizerDummy::shader_get_default_texture_param(RID p_shader, const String
return RID(); return RID();
} }
Variant RasterizerDummy::shader_get_default_param(RID p_shader, const StringName& p_name) {
return Variant();
}
/* COMMON MATERIAL API */ /* COMMON MATERIAL API */

View File

@ -433,6 +433,8 @@ public:
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture); virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const; virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name);
/* COMMON MATERIAL API */ /* COMMON MATERIAL API */
virtual RID material_create(); virtual RID material_create();

View File

@ -1127,11 +1127,13 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[]={
}; };
const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={
{ "SRC_COLOR", TYPE_VEC4},
{ "POSITION", TYPE_VEC4}, { "POSITION", TYPE_VEC4},
{ "NORMAL", TYPE_VEC3}, { "NORMAL", TYPE_VEC3},
{ "UV", TYPE_VEC2}, { "UV", TYPE_VEC2},
{ "COLOR", TYPE_VEC4}, { "COLOR", TYPE_VEC4},
{ "TEXTURE", TYPE_TEXTURE}, { "TEXTURE", TYPE_TEXTURE},
{ "TEXTURE_PIXEL_SIZE", TYPE_VEC2},
{ "VAR1", TYPE_VEC4}, { "VAR1", TYPE_VEC4},
{ "VAR2", TYPE_VEC4}, { "VAR2", TYPE_VEC4},
{ "SCREEN_UV", TYPE_VEC2}, { "SCREEN_UV", TYPE_VEC2},

View File

@ -3730,7 +3730,10 @@ Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, cons
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
ERR_FAIL_COND_V(!canvas_item,Variant()); ERR_FAIL_COND_V(!canvas_item,Variant());
ERR_FAIL_COND_V(!canvas_item->shader_param.has(p_param),Variant()); if (!canvas_item->shader_param.has(p_param)) {
ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant());
return rasterizer->shader_get_default_param(canvas_item->shader,p_param);
}
return canvas_item->shader_param[p_param]; return canvas_item->shader_param[p_param];
} }