diff options
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 7 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 20 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 1 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 51 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 195 | ||||
-rw-r--r-- | scene/3d/light.cpp | 2 | ||||
-rw-r--r-- | scene/resources/material.cpp | 268 | ||||
-rw-r--r-- | scene/resources/material.h | 49 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 25 | ||||
-rw-r--r-- | servers/visual/shader_language.h | 4 | ||||
-rw-r--r-- | servers/visual/shader_types.cpp | 7 |
12 files changed, 528 insertions, 105 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 4573f94d22..10a8912561 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -934,9 +934,13 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const if (!t) { switch(texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex); } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: { + glBindTexture(GL_TEXTURE_2D,storage->resources.aniso_tex); + } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex); } break; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index e04908ea67..3ead218226 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1035,9 +1035,13 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m if (!t) { //check hints switch(texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex); } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: { + glBindTexture(GL_TEXTURE_2D,storage->resources.aniso_tex); + } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex); } break; @@ -1046,7 +1050,6 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m } break; } - glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); continue; } @@ -1054,7 +1057,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m //if SRGB decode extension is present, simply switch the texture to whathever is needed bool must_srgb=false; - if (t->srgb && texture_hints[i]==ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO) { + if (t->srgb && (texture_hints[i]==ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || texture_hints[i]==ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO)) { must_srgb=true; } diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 8188fe3adb..669ab96036 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -2285,6 +2285,7 @@ void RasterizerStorageGLES3::_update_material(Material* material) { if (V) { //user provided _fill_std140_variant_ubo_value(E->get().type,V->get(),data,material->shader->mode==VS::SHADER_SPATIAL); + } else if (E->get().default_value.size()){ //default value _fill_std140_ubo_value(E->get().type,E->get().default_value,data); @@ -3304,7 +3305,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){ light->type=p_type; light->param[VS::LIGHT_PARAM_ENERGY]=1.0; - light->param[VS::LIGHT_PARAM_SPECULAR]=1.0; + light->param[VS::LIGHT_PARAM_SPECULAR]=0.5; light->param[VS::LIGHT_PARAM_RANGE]=1.0; light->param[VS::LIGHT_PARAM_SPOT_ANGLE]=45; light->param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE]=0; @@ -4491,7 +4492,7 @@ void RasterizerStorageGLES3::initialize() { glGenTextures(1, &resources.black_tex); unsigned char blacktexdata[8*8*3]; - for(int i=0;i<8*8;i++) { + for(int i=0;i<8*8*3;i++) { blacktexdata[i]=0; } @@ -4515,6 +4516,21 @@ void RasterizerStorageGLES3::initialize() { glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,0); + + glGenTextures(1, &resources.aniso_tex); + unsigned char anisotexdata[8*8*3]; + for(int i=0;i<8*8*3;i+=3) { + anisotexdata[i+0]=255; + anisotexdata[i+1]=128; + anisotexdata[i+2]=0; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,resources.aniso_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE,anisotexdata); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,0); + } glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&config.max_texture_image_units); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 5f07efeb0a..b433bcd517 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -74,6 +74,7 @@ public: GLuint white_tex; GLuint black_tex; GLuint normal_tex; + GLuint aniso_tex; GLuint quadie; GLuint quadie_array; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index dce52ecd93..c54fc011e9 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -52,6 +52,7 @@ static int _get_datatype_size(SL::DataType p_type) { } + static String _prestr(SL::DataPrecision p_pres) { @@ -248,7 +249,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.texture_hints.resize(max_texture_uniforms); Vector<int> uniform_sizes; + Vector<int> uniform_alignments; + Vector<StringName> uniform_defines; uniform_sizes.resize(max_uniforms); + uniform_alignments.resize(max_uniforms); + uniform_defines.resize(max_uniforms); for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) { @@ -272,19 +277,31 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii()); } - r_gen_code.uniforms+=ucode; + uniform_defines[E->get().order]=ucode; uniform_sizes[E->get().order]=_get_datatype_size(E->get().type); + uniform_alignments[E->get().order]=MIN(16,_get_datatype_size(E->get().type)); } p_actions.uniforms->insert(E->key(),E->get()); } + for(int i=0;i<max_uniforms;i++) { + r_gen_code.uniforms+=uniform_defines[i]; + } // add up for(int i=0;i<uniform_sizes.size();i++) { - if (i>0) + if (i>0) { + + int align = uniform_sizes[i-1] % uniform_alignments[i]; + if (align!=0) { + uniform_sizes[i-1]+=uniform_alignments[i]-align; + } + uniform_sizes[i]=uniform_sizes[i]+uniform_sizes[i-1]; + + } } //offset r_gen_code.uniform_offsets.resize(uniform_sizes.size()); @@ -294,8 +311,21 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.uniform_offsets[i]=uniform_sizes[i-1]; else r_gen_code.uniform_offsets[i]=0; + + } +/* + for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) { + + if (SL::is_sampler_type(E->get().type)) { + continue; + } + + print_line("u - "+String(E->key())+" offset: "+itos(r_gen_code.uniform_offsets[E->get().order])); + } + +*/ if (uniform_sizes.size()) { r_gen_code.uniform_total_size=uniform_sizes[ uniform_sizes.size() -1 ]; } else { @@ -549,13 +579,11 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String& p_code, r_gen_code.uses_vertex_time=false; - used_name_defines.clear(); used_rmode_defines.clear(); _dump_node_code(parser.get_shader(),1,r_gen_code,*p_actions,actions[p_mode]); - return OK; } @@ -636,8 +664,14 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["ALPHA"]="alpha"; actions[VS::SHADER_SPATIAL].renames["SPECULAR"]="specular"; actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"]="roughness"; + actions[VS::SHADER_SPATIAL].renames["RIM"]="rim"; + actions[VS::SHADER_SPATIAL].renames["RIM_TINT"]="rim_tint"; + actions[VS::SHADER_SPATIAL].renames["CLEARCOAT"]="clearcoat"; + actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"]="clearcoat_gloss"; + actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"]="anisotropy"; + actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"]="anisotropy_flow"; + actions[VS::SHADER_SPATIAL].renames["AO"]="ao"; actions[VS::SHADER_SPATIAL].renames["EMISSION"]="emission"; - actions[VS::SHADER_SPATIAL].renames["SPECIAL"]="special"; actions[VS::SHADER_SPATIAL].renames["DISCARD"]="_discard"; // actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2; actions[VS::SHADER_SPATIAL].renames["POINT_COORD"]="gl_PointCoord"; @@ -645,6 +679,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"]="#define ENABLE_TANGENT_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"]="@TANGENT"; + actions[VS::SHADER_SPATIAL].usage_defines["RIM"]="#define LIGHT_USE_RIM\n"; + actions[VS::SHADER_SPATIAL].usage_defines["RIM_TINT"]="@RIM"; + actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT"]="#define LIGHT_USE_CLEARCOAT\n"; + actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"]="@CLEARCOAT"; + actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY"]="#define LIGHT_USE_ANISOTROPY\n"; + actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"]="@ANISOTROPY"; + actions[VS::SHADER_SPATIAL].usage_defines["AO"]="#define ENABLE_AO\n"; actions[VS::SHADER_SPATIAL].usage_defines["UV"]="#define ENABLE_UV_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["UV2"]="#define ENABLE_UV2_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"]="#define ENABLE_NORMALMAP\n"; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index a923c130dc..aa8b3cacdc 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -108,7 +108,7 @@ out vec2 uv2_interp; #endif -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) out vec3 tangent_interp; out vec3 binormal_interp; #endif @@ -146,7 +146,7 @@ void main() { highp mat4 modelview = camera_inverse_matrix * world_transform; vec3 normal = normal_attrib * normal_mult; -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) vec3 tangent = tangent_attrib.xyz; tangent*=normal_mult; float binormalf = tangent_attrib.a; @@ -163,7 +163,7 @@ void main() { vertex = vertex_in * m; normal = (vec4(normal,0.0) * m).xyz; -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) tangent = (vec4(tangent,0.0) * m).xyz; #endif } @@ -176,7 +176,7 @@ void main() { normal = normalize((modelview * vec4(normal,0.0)).xyz); #endif -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) # if !defined(SKIP_TRANSFORM_USED) tangent=normalize((modelview * vec4(tangent,0.0)).xyz); @@ -207,7 +207,7 @@ VERTEX_SHADER_CODE vertex_interp = vertex.xyz; normal_interp = normal; -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) tangent_interp = tangent; binormal_interp = binormal; #endif @@ -276,7 +276,7 @@ in vec2 uv_interp; in vec2 uv2_interp; #endif -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) in vec3 tangent_interp; in vec3 binormal_interp; #endif @@ -455,40 +455,86 @@ float G1V(float dotNV, float k) return 1.0 / (dotNV * (1.0 - k) + k); } -float specularGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0) + +float SchlickFresnel(float u) { - float alpha = roughness * roughness; + float m = 1.0-u; + float m2 = m*m; + return m2*m2*m; // pow(m,5) +} + +float GTR1(float NdotH, float a) +{ + if (a >= 1.0) return 1.0/M_PI; + float a2 = a*a; + float t = 1.0 + (a2-1.0)*NdotH*NdotH; + return (a2-1.0) / (M_PI*log(a2)*t); +} - vec3 H = normalize(V + L); +void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) { - float dotNL = max(dot(N,L), 0.0 ); - float dotNV = max(dot(N,V), 0.0 ); - float dotNH = max(dot(N,H), 0.0 ); - float dotLH = max(dot(L,H), 0.0 ); + float dotNL = max(dot(N,L), 0.0 ); + float dotNV = max(dot(N,V), 0.0 ); - // D - float alphaSqr = alpha * alpha; - float pi = M_PI; - float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0; - float D = alphaSqr / (pi * denom * denom); +#if defined(LIGHT_USE_RIM) + float rim_light = pow(1.0-dotNV,(1.0-roughness)*16.0); + diffuse += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color; +#endif - // F - float dotLH5 = pow(1.0 - dotLH, 5.0); - float F = F0 + (1.0 - F0) * (dotLH5); + diffuse += dotNL * light_color * diffuse_color; - // V - float k = alpha / 2.0f; - float vis = G1V(dotNL, k) * G1V(dotNV, k); + if (roughness > 0.0) { - return dotNL * D * F * vis; -} + float alpha = roughness * roughness; + + vec3 H = normalize(V + L); + + float dotNH = max(dot(N,H), 0.0 ); + float dotLH = max(dot(L,H), 0.0 ); + + // D +#if defined(LIGHT_USE_ANISOTROPY) + + float aspect = sqrt(1.0-anisotropy*0.9); + float rx = roughness/aspect; + float ry = roughness*aspect; + float ax = rx*rx; + float ay = ry*ry; + float dotXH = dot( T, H ); + float dotYH = dot( B, H ); + float pi = M_PI; + float denom = dotXH*dotXH / (ax*ax) + dotYH*dotYH / (ay*ay) + dotNH*dotNH; + float D = 1.0 / ( pi * ax*ay * denom*denom ); + +#else + float alphaSqr = alpha * alpha; + float pi = M_PI; + float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0; + float D = alphaSqr / (pi * denom * denom); +#endif + // F + float F0 = 1.0; + float dotLH5 = SchlickFresnel( dotLH ); + float F = F0 + (1.0 - F0) * (dotLH5); + + // V + float k = alpha / 2.0f; + float vis = G1V(dotNL, k) * G1V(dotNV, k); + + float speci = dotNL * D * F * vis; + + specular += speci * light_color * specular_color * specular_blob_intensity; + +#if defined(LIGHT_USE_CLEARCOAT) + float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss)); + float Fr = mix(.04, 1.0, dotLH5); + float Gr = G1V(dotNL, .25) * G1V(dotNV, .25); + + specular += .25*clearcoat*Gr*Fr*Dr; +#endif + } -void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float roughness, inout vec3 diffuse, inout vec3 specular) { - diffuse += max(0.0,dot(normal,light_vec)) * light_color * diffuse_color; - //specular += specular_ggx( roughness, max(0.0,dot(normal,eye_vec)) ) * specular_color * attenuation; - float s = roughness > 0.0 ? specularGGX(normal,eye_vec,light_vec,roughness,1.0) : 0.0; - specular += s * light_color * specular_color; } @@ -536,7 +582,7 @@ in highp float dp_clip; #endif -void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 specular, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; float normalized_distance = length( light_rel_vec )*omni_lights[idx].light_pos_inv_radius.w; @@ -577,11 +623,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 albe light_attenuation*=mix(omni_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect)); } - light_compute(normal,normalize(light_rel_vec),eye_vec,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } -void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 specular, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; float normalized_distance = length( light_rel_vec )*spot_lights[idx].light_pos_inv_radius.w; @@ -589,8 +635,8 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 al vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz; float spot_cutoff=spot_lights[idx].light_params.y; float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff); - float rim = (1.0 - scos) / (1.0 - spot_cutoff); - light_attenuation *= 1.0 - pow( rim, spot_lights[idx].light_params.x); + float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff); + light_attenuation *= 1.0 - pow( spot_rim, spot_lights[idx].light_params.x); if (spot_lights[idx].light_params.w>0.5) { //there is a shadowmap @@ -599,11 +645,11 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 al light_attenuation*=mix(spot_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp)); } - light_compute(normal,normalize(light_rel_vec),eye_vec,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } -void reflection_process(int idx, vec3 vertex, vec3 normal,float roughness,vec3 ambient,vec3 skybox,vec2 brdf, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) { +void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox,vec2 brdf, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) { vec3 ref_vec = normalize(reflect(vertex,normal)); vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex,1.0)).xyz; @@ -729,7 +775,19 @@ void main() { highp vec3 vertex = vertex_interp; vec3 albedo = vec3(0.8,0.8,0.8); vec3 specular = vec3(0.2,0.2,0.2); + vec3 emission = vec3(0.0,0.0,0.0); float roughness = 1.0; + float rim = 0.0; + float rim_tint = 0.0; + float clearcoat=0.0; + float clearcoat_gloss=0.0; + float anisotropy = 1.0; + vec2 anisotropy_flow = vec2(1.0,0.0); + +#if defined(ENABLE_AO) + float ao=1.0; +#endif + float alpha = 1.0; #ifdef METERIAL_DOUBLESIDED @@ -739,9 +797,12 @@ void main() { #endif -#if defined(ENABLE_TANGENT_INTERP) +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) vec3 binormal = normalize(binormal_interp)*side; vec3 tangent = normalize(tangent_interp)*side; +#else + vec3 binormal = vec3(0.0); + vec3 tangent = vec3(0.0); #endif vec3 normal = normalize(normal_interp)*side; @@ -777,9 +838,26 @@ FRAGMENT_SHADER_CODE } + + #if defined(ENABLE_NORMALMAP) - normal = normalize( mix(normal_interp,tangent_interp * normalmap.x + binormal_interp * normalmap.y + normal_interp * normalmap.z,normaldepth) ) * side; + normalmap.xy=normalmap.xy*2.0-1.0; + normalmap.z=sqrt(1.0-dot(normalmap.xy,normalmap.xy)); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. + + normal = normalize( mix(normal_interp,tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z,normaldepth) ) * side; + +#endif + +#if defined(LIGHT_USE_ANISOTROPY) + + if (anisotropy>0.01) { + //rotation matrix + mat3 rot = mat3( tangent, binormal, normal ); + //make local to space + tangent = normalize(rot * vec3(anisotropy_flow.x,anisotropy_flow.y,0.0)); + binormal = normalize(rot * vec3(-anisotropy_flow.y,anisotropy_flow.x,0.0)); + } #endif @@ -799,6 +877,10 @@ FRAGMENT_SHADER_CODE /////////////////////// LIGHTING ////////////////////////////// + //apply energy conservation + vec3 diffuse=mix(albedo,vec3(0.0),specular); + specular = max(vec3(0.04),specular); + vec3 specular_light = vec3(0.0,0.0,0.0); vec3 ambient_light; vec3 diffuse_light = vec3(0.0,0.0,0.0); @@ -839,8 +921,7 @@ FRAGMENT_SHADER_CODE norm.xy/=norm.z; norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs); - vec3 radiance = textureLod(radiance_map, norm.xy, lod).xyz * ( brdf.x + brdf.y); - specular_light=mix(albedo,radiance,specular); + specular_light = textureLod(radiance_map, norm.xy, lod).xyz * ( brdf.x + brdf.y); } //no longer a cubemap @@ -996,7 +1077,7 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_DIRECTIONAL_SHADOW - light_compute(normal,-light_direction_attenuation.xyz,eye_vec,light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light); + light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,diffuse,specular,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); #endif //#USE_LIGHT_DIRECTIONAL @@ -1008,23 +1089,22 @@ FRAGMENT_SHADER_CODE highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0); for(int i=0;i<reflection_count;i++) { - reflection_process(reflection_indices[i],vertex,normal,roughness,ambient_light,specular_light,brdf,reflection_accum,ambient_accum); + reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,brdf,reflection_accum,ambient_accum); } if (reflection_accum.a>0.0) { specular_light=reflection_accum.rgb/reflection_accum.a; - specular_light*=specular; } if (ambient_accum.a>0.0) { ambient_light=ambient_accum.rgb/ambient_accum.a; } for(int i=0;i<omni_light_count;i++) { - light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light); + light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,diffuse,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } for(int i=0;i<spot_light_count;i++) { - light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light); + light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,diffuse,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } @@ -1048,16 +1128,28 @@ LIGHT_SHADER_CODE #else specular_light*=reflection_multiplier; + specular_light*=specular; + ambient_light*=albedo; //ambient must be multiplied by albedo at the end + +#if defined(ENABLE_AO) + ambient_light*=ao; +#endif #ifdef USE_MULTIPLE_RENDER_TARGETS +#if defined(ENABLE_AO) + + float ambient_scale=0.0; // AO is supplied by material +#else //approximate ambient scale for SSAO, since we will lack full ambient + float max_emission=max(emission.r,max(emission.g,emission.b)); float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b)); float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b)); - float total_ambient = max_ambient+max_diffuse; + float total_ambient = max_ambient+max_diffuse+max_emission; float ambient_scale = (total_ambient>0.0) ? max_ambient/total_ambient : 0.0; +#endif //ENABLE_AO - diffuse_buffer=vec4(diffuse_light+ambient_light,ambient_scale); + diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale); specular_buffer=vec4(specular_light,0.0); normal_mr_buffer=vec4(normal.x,normal.y,max(specular.r,max(specular.g,specular.b)),roughness); @@ -1067,11 +1159,14 @@ LIGHT_SHADER_CODE #ifdef SHADELESS frag_color=vec4(albedo,alpha); #else - frag_color=vec4(ambient_light+diffuse_light+specular_light,alpha); + frag_color=vec4(emission+ambient_light+diffuse_light+specular_light,alpha); #endif //SHADELESS + #endif //USE_MULTIPLE_RENDER_TARGETS + + #endif //RENDER_SHADOW diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index dfb9521639..49bffd3c21 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -254,7 +254,7 @@ Light::Light(VisualServer::LightType p_type) { set_cull_mask(0xFFFFFFFF); set_param(PARAM_ENERGY,1); - set_param(PARAM_SPECULAR,1); + set_param(PARAM_SPECULAR,0.5); set_param(PARAM_RANGE,5); set_param(PARAM_ATTENUATION,1); set_param(PARAM_SPOT_ANGLE,45); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index cb55f4f030..99b7a130f7 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -64,25 +64,30 @@ void FixedSpatialMaterial::init_shaders() { shader_names->specular="specular"; shader_names->roughness="roughness"; shader_names->emission="emission"; + shader_names->emission_energy="emission_energy"; shader_names->normal_scale="normal_scale"; - shader_names->sheen="sheen"; - shader_names->sheen_color="sheen_color"; + shader_names->rim="rim"; + shader_names->rim_tint="rim_tint"; shader_names->clearcoat="clearcoat"; shader_names->clearcoat_gloss="clearcoat_gloss"; - shader_names->anisotropy="anisotropy"; + shader_names->anisotropy="anisotropy_ratio"; shader_names->height_scale="height_scale"; shader_names->subsurface_scattering="subsurface_scattering"; shader_names->refraction="refraction"; shader_names->refraction_roughness="refraction_roughness"; shader_names->point_size="point_size"; + shader_names->uv1_scale="uv1_scale"; + shader_names->uv1_offset="uv1_offset"; + shader_names->uv2_scale="uv2_scale"; + shader_names->uv2_offset="uv2_offset"; shader_names->texture_names[TEXTURE_ALBEDO]="texture_albedo"; shader_names->texture_names[TEXTURE_SPECULAR]="texture_specular"; shader_names->texture_names[TEXTURE_EMISSION]="texture_emission"; shader_names->texture_names[TEXTURE_NORMAL]="texture_normal"; - shader_names->texture_names[TEXTURE_SHEEN]="texture_sheen"; + shader_names->texture_names[TEXTURE_RIM]="texture_rim"; shader_names->texture_names[TEXTURE_CLEARCOAT]="texture_clearcoat"; - shader_names->texture_names[TEXTURE_ANISOTROPY]="texture_anisotropy"; + shader_names->texture_names[TEXTURE_FLOWMAP]="texture_flowmap"; shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION]="texture_ambient_occlusion"; shader_names->texture_names[TEXTURE_HEIGHT]="texture_height"; shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING]="texture_subsurface_scattering"; @@ -172,6 +177,46 @@ void FixedSpatialMaterial::_update_shader() { code+="uniform float roughness : hint_range(0,1);\n"; code+="uniform float point_size : hint_range(0,128);\n"; code+="uniform sampler2D texture_specular : hint_white;\n"; + code+="uniform vec2 uv1_scale;\n"; + code+="uniform vec2 uv1_offset;\n"; + code+="uniform vec2 uv2_scale;\n"; + code+="uniform vec2 uv2_offset;\n"; + + if (features[FEATURE_EMISSION]) { + + code+="uniform sampler2D texture_emission : hint_black_albedo;\n"; + code+="uniform vec4 emission : hint_color;\n"; + code+="uniform float emission_energy;\n"; + } + + if (features[FEATURE_NORMAL_MAPPING]) { + code+="uniform sampler2D texture_normal : hint_normal;\n"; + code+="uniform float normal_scale : hint_range(-16,16);\n"; + } + if (features[FEATURE_RIM]) { + code+="uniform float rim : hint_range(0,1);\n"; + code+="uniform float rim_tint : hint_range(0,1);\n"; + code+="uniform sampler2D texture_rim : hint_white;\n"; + } + if (features[FEATURE_CLEARCOAT]) { + code+="uniform float clearcoat : hint_range(0,1);\n"; + code+="uniform float clearcoat_gloss : hint_range(0,1);\n"; + code+="uniform sampler2D texture_clearcoat : hint_white;\n"; + } + if (features[FEATURE_ANISOTROPY]) { + code+="uniform float anisotropy_ratio : hint_range(0,256);\n"; + code+="uniform sampler2D texture_flowmap : hint_aniso;\n"; + } + if (features[FEATURE_AMBIENT_OCCLUSION]) { + code+="uniform sampler2D texture_ambient_occlusion : hint_white;\n"; + } + + if (features[FEATURE_DETAIL]) { + code+="uniform sampler2D texture_detail_albedo : hint_albedo;\n"; + code+="uniform sampler2D texture_detail_normal : hint_normal;\n"; + code+="uniform sampler2D texture_detail_mask : hint_white;\n"; + } + code+="\n\n"; code+="void vertex() {\n"; @@ -184,6 +229,10 @@ void FixedSpatialMaterial::_update_shader() { code+="\tPOINT_SIZE=point_size;\n"; } + code+="\tUV=UV*uv1_scale+uv1_offset;\n"; + if (detail_blend_mode==DETAIL_UV_2) { + code+="\tUV2=UV2*uv2_scale+uv2_offset;\n"; + } code+="}\n"; code+="\n\n"; @@ -203,6 +252,66 @@ void FixedSpatialMaterial::_update_shader() { if (features[FEATURE_TRANSPARENT]) { code+="\tALPHA = albedo.a * albedo_tex.a;\n"; } + + if (features[FEATURE_EMISSION]) { + code+="\tEMISSION = (emission.rgb+texture(texture_emission,UV).rgb)*emission_energy;\n"; + } + + if (features[FEATURE_NORMAL_MAPPING]) { + code+="\tNORMALMAP = texture(texture_normal,UV).rgb;\n"; + code+="\tNORMALMAP_DEPTH = normal_scale;\n"; + } + + if (features[FEATURE_RIM]) { + code+="\tvec2 rim_tex = texture(texture_rim,UV).xw;\n"; + code+="\tRIM = rim*rim_tex.x;"; + code+="\tRIM_TINT = rim_tint*rim_tex.y;\n"; + } + + if (features[FEATURE_CLEARCOAT]) { + code+="\tvec2 clearcoat_tex = texture(texture_clearcoat,UV).xw;\n"; + code+="\tCLEARCOAT = clearcoat*clearcoat_tex.x;"; + code+="\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n"; + } + + if (features[FEATURE_ANISOTROPY]) { + code+="\tvec4 anisotropy_tex = texture(texture_flowmap,UV);\n"; + code+="\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n"; + code+="\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n"; + } + + if (features[FEATURE_AMBIENT_OCCLUSION]) { + code+="\tAO = texture(texture_ambient_occlusion,UV).r;\n"; + } + + if (features[FEATURE_DETAIL]) { + String det_uv=detail_uv==DETAIL_UV_1?"UV":"UV2"; + code+="\tvec4 detail_tex = texture(texture_detail_albedo,"+det_uv+");\n"; + code+="\tvec4 detail_norm_tex = texture(texture_detail_normal,"+det_uv+");\n"; + code+="\tvec4 detail_mask_tex = texture(texture_detail_mask,UV);\n"; + + switch(detail_blend_mode) { + case BLEND_MODE_MIX: { + code+="\tvec3 detail = mix(ALBEDO.rgb,detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_ADD: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb+detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_SUB: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb-detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_MUL: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n"; + } break; + + } + + code+="\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n"; + + code+="\tNORMALMAP = mix(NORMALMAP,detail_norm,detail_mask_tex.r);\n"; + code+="\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; + } + code+="\tvec4 specular_tex = texture(texture_specular,UV);\n"; code+="\tSPECULAR = specular.rgb * specular_tex.rgb;\n"; code+="\tROUGHNESS = specular.a * roughness;\n"; @@ -308,6 +417,18 @@ Color FixedSpatialMaterial::get_emission() const{ return emission; } + +void FixedSpatialMaterial::set_emission_energy(float p_emission_energy){ + + emission_energy=p_emission_energy; + VS::get_singleton()->material_set_param(_get_material(),shader_names->emission_energy,p_emission_energy); + +} +float FixedSpatialMaterial::get_emission_energy() const{ + + return emission_energy; +} + void FixedSpatialMaterial::set_normal_scale(float p_normal_scale){ normal_scale=p_normal_scale; @@ -319,27 +440,27 @@ float FixedSpatialMaterial::get_normal_scale() const{ return normal_scale; } -void FixedSpatialMaterial::set_sheen(float p_sheen){ +void FixedSpatialMaterial::set_rim(float p_rim){ - sheen=p_sheen; - VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen,p_sheen); + rim=p_rim; + VS::get_singleton()->material_set_param(_get_material(),shader_names->rim,p_rim); } -float FixedSpatialMaterial::get_sheen() const{ +float FixedSpatialMaterial::get_rim() const{ - return sheen; + return rim; } -void FixedSpatialMaterial::set_sheen_color(const Color& p_sheen_color){ +void FixedSpatialMaterial::set_rim_tint(float p_rim_tint){ - sheen_color=p_sheen_color; - VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen_color,p_sheen_color); + rim_tint=p_rim_tint; + VS::get_singleton()->material_set_param(_get_material(),shader_names->rim_tint,p_rim_tint); } -Color FixedSpatialMaterial::get_sheen_color() const{ +float FixedSpatialMaterial::get_rim_tint() const{ - return sheen_color; + return rim_tint; } void FixedSpatialMaterial::set_clearcoat(float p_clearcoat){ @@ -565,7 +686,8 @@ void FixedSpatialMaterial::_validate_feature(const String& text, Feature feature void FixedSpatialMaterial::_validate_property(PropertyInfo& property) const { _validate_feature("normal",FEATURE_NORMAL_MAPPING,property); - _validate_feature("sheen",FEATURE_SHEEN,property); + _validate_feature("emission",FEATURE_EMISSION,property); + _validate_feature("rim",FEATURE_RIM,property); _validate_feature("clearcoat",FEATURE_CLEARCOAT,property); _validate_feature("anisotropy",FEATURE_ANISOTROPY,property); _validate_feature("ao",FEATURE_AMBIENT_OCCLUSION,property); @@ -598,6 +720,53 @@ float FixedSpatialMaterial::get_point_size() const { return point_size; } + +void FixedSpatialMaterial::set_uv1_scale(const Vector2& p_scale) { + + uv1_scale=p_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv1_scale,p_scale); +} + +Vector2 FixedSpatialMaterial::get_uv1_scale() const{ + + return uv1_scale; +} + +void FixedSpatialMaterial::set_uv1_offset(const Vector2& p_offset){ + + uv1_offset=p_offset; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv1_offset,p_offset); + +} +Vector2 FixedSpatialMaterial::get_uv1_offset() const{ + + return uv1_offset; +} + + +void FixedSpatialMaterial::set_uv2_scale(const Vector2& p_scale) { + + uv2_scale=p_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv2_scale,p_scale); +} + +Vector2 FixedSpatialMaterial::get_uv2_scale() const{ + + return uv2_scale; +} + +void FixedSpatialMaterial::set_uv2_offset(const Vector2& p_offset){ + + uv2_offset=p_offset; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv2_offset,p_offset); + +} + +Vector2 FixedSpatialMaterial::get_uv2_offset() const{ + + return uv2_offset; +} + void FixedSpatialMaterial::_bind_methods() { @@ -613,14 +782,17 @@ void FixedSpatialMaterial::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_emission","emission"),&FixedSpatialMaterial::set_emission); ObjectTypeDB::bind_method(_MD("get_emission"),&FixedSpatialMaterial::get_emission); + ObjectTypeDB::bind_method(_MD("set_emission_energy","emission_energy"),&FixedSpatialMaterial::set_emission_energy); + ObjectTypeDB::bind_method(_MD("get_emission_energy"),&FixedSpatialMaterial::get_emission_energy); + ObjectTypeDB::bind_method(_MD("set_normal_scale","normal_scale"),&FixedSpatialMaterial::set_normal_scale); ObjectTypeDB::bind_method(_MD("get_normal_scale"),&FixedSpatialMaterial::get_normal_scale); - ObjectTypeDB::bind_method(_MD("set_sheen","sheen"),&FixedSpatialMaterial::set_sheen); - ObjectTypeDB::bind_method(_MD("get_sheen"),&FixedSpatialMaterial::get_sheen); + ObjectTypeDB::bind_method(_MD("set_rim","rim"),&FixedSpatialMaterial::set_rim); + ObjectTypeDB::bind_method(_MD("get_rim"),&FixedSpatialMaterial::get_rim); - ObjectTypeDB::bind_method(_MD("set_sheen_color","sheen_color"),&FixedSpatialMaterial::set_sheen_color); - ObjectTypeDB::bind_method(_MD("get_sheen_color"),&FixedSpatialMaterial::get_sheen_color); + ObjectTypeDB::bind_method(_MD("set_rim_tint","rim_tint"),&FixedSpatialMaterial::set_rim_tint); + ObjectTypeDB::bind_method(_MD("get_rim_tint"),&FixedSpatialMaterial::get_rim_tint); ObjectTypeDB::bind_method(_MD("set_clearcoat","clearcoat"),&FixedSpatialMaterial::set_clearcoat); ObjectTypeDB::bind_method(_MD("get_clearcoat"),&FixedSpatialMaterial::get_clearcoat); @@ -676,6 +848,18 @@ void FixedSpatialMaterial::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_detail_blend_mode","detail_blend_mode"),&FixedSpatialMaterial::set_detail_blend_mode); ObjectTypeDB::bind_method(_MD("get_detail_blend_mode"),&FixedSpatialMaterial::get_detail_blend_mode); + ObjectTypeDB::bind_method(_MD("set_uv1_scale","scale"),&FixedSpatialMaterial::set_uv1_scale); + ObjectTypeDB::bind_method(_MD("get_uv1_scale"),&FixedSpatialMaterial::get_uv1_scale); + + ObjectTypeDB::bind_method(_MD("set_uv1_offset","offset"),&FixedSpatialMaterial::set_uv1_offset); + ObjectTypeDB::bind_method(_MD("get_uv1_offset"),&FixedSpatialMaterial::get_uv1_offset); + + ObjectTypeDB::bind_method(_MD("set_uv2_scale","scale"),&FixedSpatialMaterial::set_uv2_scale); + ObjectTypeDB::bind_method(_MD("get_uv2_scale"),&FixedSpatialMaterial::get_uv2_scale); + + ObjectTypeDB::bind_method(_MD("set_uv2_offset","offset"),&FixedSpatialMaterial::set_uv2_offset); + ObjectTypeDB::bind_method(_MD("get_uv2_offset"),&FixedSpatialMaterial::get_uv2_offset); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/transparent"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_TRANSPARENT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/unshaded"),_SCS("set_flag"),_SCS("get_flag"),FLAG_UNSHADED); ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/on_top"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ONTOP); @@ -693,27 +877,32 @@ void FixedSpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR,"albedo/color"),_SCS("set_albedo"),_SCS("get_albedo")); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"albedo/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ALBEDO); - ADD_PROPERTY(PropertyInfo(Variant::COLOR,"specular/color"),_SCS("set_specular"),_SCS("get_specular")); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"specular/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_specular"),_SCS("get_specular")); ADD_PROPERTY(PropertyInfo(Variant::REAL,"specular/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_roughness"),_SCS("get_roughness")); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"specular/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SPECULAR); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"emission/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_EMISSION); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"emission/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_emission"),_SCS("get_emission")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"emission/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_emission_energy"),_SCS("get_emission_energy")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"emission/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_EMISSION); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"normal/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_NORMAL_MAPPING); ADD_PROPERTY(PropertyInfo(Variant::REAL,"normal/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_normal_scale"),_SCS("get_normal_scale")); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"normal/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_NORMAL); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"sheen/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SHEEN); - ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_sheen"),_SCS("get_sheen")); - ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/color"),_SCS("set_sheen_color"),_SCS("get_sheen_color")); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"sheen/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SHEEN); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"rim/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_RIM); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"rim/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_rim"),_SCS("get_rim")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"rim/tint",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_rim_tint"),_SCS("get_rim_tint")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"rim/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_RIM); ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"clearcoat/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_CLEARCOAT); ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat"),_SCS("get_clearcoat")); - ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/gloss"),_SCS("set_clearcoat_gloss"),_SCS("get_clearcoat_gloss")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/gloss",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat_gloss"),_SCS("get_clearcoat_gloss")); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"clearcoat/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_CLEARCOAT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"anisotropy/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_ANISOTROPY); - ADD_PROPERTY(PropertyInfo(Variant::REAL,"anisotropy/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_anisotropy"),_SCS("get_anisotropy")); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"anisotropy/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ANISOTROPY); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"anisotropy/anisotropy",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_anisotropy"),_SCS("get_anisotropy")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"anisotropy/flowmap",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_FLOWMAP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"ao/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_AMBIENT_OCCLUSION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"ao/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_AMBIENT_OCCLUSION); @@ -738,13 +927,19 @@ void FixedSpatialMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/albedo",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_ALBEDO); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_NORMAL); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv1/scale"),_SCS("set_uv1_scale"),_SCS("get_uv1_scale")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv1/offset"),_SCS("set_uv1_offset"),_SCS("get_uv1_offset")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv2/scale"),_SCS("set_uv2_scale"),_SCS("get_uv2_scale")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv2/offset"),_SCS("set_uv2_offset"),_SCS("get_uv2_offset")); + + BIND_CONSTANT( TEXTURE_ALBEDO ); BIND_CONSTANT( TEXTURE_SPECULAR ); BIND_CONSTANT( TEXTURE_EMISSION ); BIND_CONSTANT( TEXTURE_NORMAL ); - BIND_CONSTANT( TEXTURE_SHEEN ); + BIND_CONSTANT( TEXTURE_RIM ); BIND_CONSTANT( TEXTURE_CLEARCOAT ); - BIND_CONSTANT( TEXTURE_ANISOTROPY ); + BIND_CONSTANT( TEXTURE_FLOWMAP ); BIND_CONSTANT( TEXTURE_AMBIENT_OCCLUSION ); BIND_CONSTANT( TEXTURE_HEIGHT ); BIND_CONSTANT( TEXTURE_SUBSURFACE_SCATTERING ); @@ -762,7 +957,7 @@ void FixedSpatialMaterial::_bind_methods() { BIND_CONSTANT( FEATURE_TRANSPARENT ); BIND_CONSTANT( FEATURE_EMISSION ); BIND_CONSTANT( FEATURE_NORMAL_MAPPING ); - BIND_CONSTANT( FEATURE_SHEEN ); + BIND_CONSTANT( FEATURE_RIM ); BIND_CONSTANT( FEATURE_CLEARCOAT ); BIND_CONSTANT( FEATURE_ANISOTROPY ); BIND_CONSTANT( FEATURE_AMBIENT_OCCLUSION ); @@ -808,10 +1003,11 @@ FixedSpatialMaterial::FixedSpatialMaterial() : element(this) { set_specular(Color(0.1,0.1,0.1)); set_roughness(0.0); set_emission(Color(0,0,0)); + set_emission_energy(1.0); set_normal_scale(1); - set_sheen(0); - set_sheen_color(Color(1,1,1,1)); - set_clearcoat(0); + set_rim(1.0); + set_rim_tint(0.5); + set_clearcoat(1); set_clearcoat_gloss(0.5); set_anisotropy(0); set_height_scale(1); @@ -820,6 +1016,10 @@ FixedSpatialMaterial::FixedSpatialMaterial() : element(this) { set_refraction_roughness(0); set_line_width(1); set_point_size(1); + set_uv1_offset(Vector2(0,0)); + set_uv1_scale(Vector2(1,1)); + set_uv2_offset(Vector2(0,0)); + set_uv2_scale(Vector2(1,1)); detail_uv=DETAIL_UV_1; blend_mode=BLEND_MODE_MIX; diff --git a/scene/resources/material.h b/scene/resources/material.h index 35f01d4756..15c5910a9c 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -69,9 +69,9 @@ public: TEXTURE_SPECULAR, TEXTURE_EMISSION, TEXTURE_NORMAL, - TEXTURE_SHEEN, + TEXTURE_RIM, TEXTURE_CLEARCOAT, - TEXTURE_ANISOTROPY, + TEXTURE_FLOWMAP, TEXTURE_AMBIENT_OCCLUSION, TEXTURE_HEIGHT, TEXTURE_SUBSURFACE_SCATTERING, @@ -95,7 +95,7 @@ public: FEATURE_TRANSPARENT, FEATURE_EMISSION, FEATURE_NORMAL_MAPPING, - FEATURE_SHEEN, + FEATURE_RIM, FEATURE_CLEARCOAT, FEATURE_ANISOTROPY, FEATURE_AMBIENT_OCCLUSION, @@ -205,9 +205,10 @@ private: StringName specular; StringName roughness; StringName emission; + StringName emission_energy; StringName normal_scale; - StringName sheen; - StringName sheen_color; + StringName rim; + StringName rim_tint; StringName clearcoat; StringName clearcoat_gloss; StringName anisotropy; @@ -216,6 +217,10 @@ private: StringName refraction; StringName refraction_roughness; StringName point_size; + StringName uv1_scale; + StringName uv1_offset; + StringName uv2_scale; + StringName uv2_offset; StringName texture_names[TEXTURE_MAX]; }; @@ -234,9 +239,10 @@ private: Color specular; float roughness; Color emission; + float emission_energy; float normal_scale; - float sheen; - Color sheen_color; + float rim; + float rim_tint; float clearcoat; float clearcoat_gloss; float anisotropy; @@ -247,6 +253,12 @@ private: float line_width; float point_size; + Vector2 uv1_scale; + Vector2 uv1_offset; + + Vector2 uv2_scale; + Vector2 uv2_offset; + DetailUV detail_uv; BlendMode blend_mode; @@ -282,14 +294,17 @@ public: void set_emission(const Color& p_emission); Color get_emission() const; + void set_emission_energy(float p_emission_energy); + float get_emission_energy() const; + void set_normal_scale(float p_normal_scale); float get_normal_scale() const; - void set_sheen(float p_sheen); - float get_sheen() const; + void set_rim(float p_rim); + float get_rim() const; - void set_sheen_color(const Color& p_sheen_color); - Color get_sheen_color() const; + void set_rim_tint(float p_rim_tint); + float get_rim_tint() const; void set_clearcoat(float p_clearcoat); float get_clearcoat() const; @@ -345,6 +360,18 @@ public: void set_feature(Feature p_feature,bool p_enabled); bool get_feature(Feature p_feature) const; + void set_uv1_scale(const Vector2& p_scale); + Vector2 get_uv1_scale() const; + + void set_uv1_offset(const Vector2& p_offset); + Vector2 get_uv1_offset() const; + + void set_uv2_scale(const Vector2& p_scale); + Vector2 get_uv2_scale() const; + + void set_uv2_offset(const Vector2& p_offset); + Vector2 get_uv2_offset() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 357546e595..f6220250d9 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -183,7 +183,9 @@ const char * ShaderLanguage::token_names[TK_MAX]={ "HINT_WHITE_TEXTURE", "HINT_BLACK_TEXTURE", "HINT_NORMAL_TEXTURE", + "HINT_ANISO_TEXTURE", "HINT_ALBEDO_TEXTURE", + "HINT_BLACK_ALBEDO_TEXTURE", "HINT_COLOR", "HINT_RANGE", "CURSOR", @@ -263,7 +265,9 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[]={ {TK_HINT_WHITE_TEXTURE,"hint_white"}, {TK_HINT_BLACK_TEXTURE,"hint_black"}, {TK_HINT_NORMAL_TEXTURE,"hint_normal"}, + {TK_HINT_ANISO_TEXTURE,"hint_aniso"}, {TK_HINT_ALBEDO_TEXTURE,"hint_albedo"}, + {TK_HINT_BLACK_ALBEDO_TEXTURE,"hint_black_albedo"}, {TK_HINT_COLOR,"hint_color"}, {TK_HINT_RANGE,"hint_range"}, @@ -3303,8 +3307,12 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy uniform.hint=ShaderNode::Uniform::HINT_BLACK; } else if (tk.type==TK_HINT_NORMAL_TEXTURE) { uniform.hint=ShaderNode::Uniform::HINT_NORMAL; + } else if (tk.type==TK_HINT_ANISO_TEXTURE) { + uniform.hint=ShaderNode::Uniform::HINT_ANISO; } else if (tk.type==TK_HINT_ALBEDO_TEXTURE) { uniform.hint=ShaderNode::Uniform::HINT_ALBEDO; + } else if (tk.type==TK_HINT_BLACK_ALBEDO_TEXTURE) { + uniform.hint=ShaderNode::Uniform::HINT_BLACK_ALBEDO; } else if (tk.type==TK_HINT_COLOR) { if (type!=TYPE_VEC4) { _set_error("Color hint is for vec4 only"); @@ -3327,12 +3335,20 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy tk = _get_token(); + float sign=1.0; + + if (tk.type==TK_OP_SUB) { + sign=-1.0; + tk = _get_token(); + } + if (tk.type!=TK_REAL_CONSTANT && tk.type!=TK_INT_CONSTANT) { _set_error("Expected integer constant"); return ERR_PARSE_ERROR; } uniform.hint_range[0]=tk.constant; + uniform.hint_range[0]*=sign; tk = _get_token(); @@ -3343,12 +3359,21 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy tk = _get_token(); + sign=1.0; + + if (tk.type==TK_OP_SUB) { + sign=-1.0; + tk = _get_token(); + } + + if (tk.type!=TK_REAL_CONSTANT && tk.type!=TK_INT_CONSTANT) { _set_error("Expected integer constant after ','"); return ERR_PARSE_ERROR; } uniform.hint_range[1]=tk.constant; + uniform.hint_range[1]*=sign; tk = _get_token(); diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index dc1279efd3..e6b515167e 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -138,7 +138,9 @@ public: TK_HINT_WHITE_TEXTURE, TK_HINT_BLACK_TEXTURE, TK_HINT_NORMAL_TEXTURE, + TK_HINT_ANISO_TEXTURE, TK_HINT_ALBEDO_TEXTURE, + TK_HINT_BLACK_ALBEDO_TEXTURE, TK_HINT_COLOR, TK_HINT_RANGE, TK_CURSOR, @@ -385,9 +387,11 @@ public: HINT_COLOR, HINT_RANGE, HINT_ALBEDO, + HINT_BLACK_ALBEDO, HINT_NORMAL, HINT_BLACK, HINT_WHITE, + HINT_ANISO, HINT_MAX }; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index 8a0818c299..f799329026 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -60,6 +60,13 @@ ShaderTypes::ShaderTypes() shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA"]=ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"]=ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ROUGHNESS"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM_TINT"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT_GLOSS"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY"]=ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY_FLOW"]=ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["AO"]=ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"]=ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"]=ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"]=ShaderLanguage::TYPE_BOOL; |