diff options
Diffstat (limited to 'drivers/gles2')
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 136 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 1 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 8 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.h | 3 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 78 |
5 files changed, 170 insertions, 56 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 05c977f344..b40eccb239 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -1033,32 +1033,33 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu int mipmaps= (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && img.get_mipmaps()>0) ? img.get_mipmaps() +1 : 1; - int w=img.get_width(); - int h=img.get_height(); + //int w=img.get_width(); + //int h=img.get_height(); int tsize=0; for(int i=0;i<mipmaps;i++) { int size,ofs; - img.get_mipmap_offset_and_size(i,ofs,size); + int mm_w,mm_h; + img.get_mipmap_offset_size_and_dimensions(i,ofs,size,mm_w,mm_h); if (texture->compressed) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glCompressedTexImage2D( blit_target, i, format,w,h,0,size,&read[ofs] ); + glCompressedTexImage2D( blit_target, i, format,mm_w,mm_h,0,size,&read[ofs] ); } else { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) { - glTexSubImage2D( blit_target, i, 0,0,w,h,format,GL_UNSIGNED_BYTE,&read[ofs] ); + glTexSubImage2D( blit_target, i, 0,0,mm_w, mm_h,format,GL_UNSIGNED_BYTE,&read[ofs] ); } else { - glTexImage2D(blit_target, i, internal_format, w, h, 0, format, GL_UNSIGNED_BYTE,&read[ofs]); + glTexImage2D(blit_target, i, internal_format, mm_w, mm_h, 0, format, GL_UNSIGNED_BYTE,&read[ofs]); } } tsize+=size; - w = MAX(1,w>>1); - h = MAX(1,h>>1); + //w = MAX(Image::,w>>1); + //h = MAX(1,h>>1); } @@ -4611,6 +4612,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (fragment_flags.uses_texpixel_size) { enablers.push_back("#define USE_TEXPIXEL_SIZE\n"); } + if (light_flags.uses_shadow_color) { + enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n"); + } if (vertex_flags.uses_worldvec) { enablers.push_back("#define USE_WORLD_VEC\n"); @@ -8559,6 +8563,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) { #ifdef GLEW_ENABLED glDrawBuffer(GL_NONE); #endif + } else { // We'll use a RGBA texture into which we pack the depth info glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0, @@ -8567,6 +8572,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) { // Attach the RGBA texture to FBO color attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cls->depth, 0); + cls->rgba=cls->depth; // Allocate 16-bit depth buffer glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height); @@ -8845,10 +8851,14 @@ void RasterizerGLES2::canvas_debug_viewport_shadows(CanvasLight* p_lights_with_s int h = 10; int w = viewport.width; int ofs = h; + + //print_line(" debug lights "); while(light) { + // print_line("debug light"); if (light->shadow_buffer.is_valid()) { + // print_line("sb is valid"); CanvasLightShadow * sb = canvas_light_shadow_owner.get(light->shadow_buffer); if (sb) { glActiveTexture(GL_TEXTURE0); @@ -9129,6 +9139,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,false); + bool reset_modulate=false; bool prev_distance_field=false; @@ -9253,7 +9264,9 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const _canvas_item_setup_shader_uniforms(material,shader_cache); } - if (material && material->unshaded) { + bool unshaded = material && material->shading_mode==VS::CANVAS_ITEM_SHADING_UNSHADED; + + if (unshaded) { canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1)); reset_modulate=true; } else if (reset_modulate) { @@ -9310,13 +9323,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_opacity = ci->final_opacity; - _canvas_item_render_commands<false>(ci,current_clip,reclip); - if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && (!material || !material->unshaded)) { + if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT))) + _canvas_item_render_commands<false>(ci,current_clip,reclip); + + if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) { CanvasLight *light = p_light; bool light_used=false; - bool subtract=false; + VS::CanvasLightMode mode=VS::CANVAS_LIGHT_MODE_ADD; while(light) { @@ -9325,21 +9340,28 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const //intersects this light - if (!light_used || subtract!=light->subtract) { + if (!light_used || mode!=light->mode) { - subtract=light->subtract; + mode=light->mode; - if (subtract) { + switch(mode) { - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - glBlendFunc(GL_SRC_ALPHA,GL_ONE); - - } else { + case VS::CANVAS_LIGHT_MODE_ADD: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE); + } break; + case VS::CANVAS_LIGHT_MODE_SUB: { + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + } break; + case VS::CANVAS_LIGHT_MODE_MIX: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } break; } + } if (!light_used) { @@ -9377,7 +9399,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX,light->light_shader_xform); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos); - canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color); + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,Color(light->color.r*light->energy,light->color.g*light->energy,light->color.b*light->energy,light->color.a)); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); @@ -9857,9 +9879,9 @@ void RasterizerGLES2::free(const RID& p_rid) { glDeleteFramebuffers(1,&cls->fbo); glDeleteRenderbuffers(1,&cls->rbo); glDeleteTextures(1,&cls->depth); - if (!read_depth_supported) { - glDeleteTextures(1,&cls->rgba); - } + //if (!read_depth_supported) { + // glDeleteTextures(1,&cls->rgba); + //} canvas_light_shadow_owner.free(p_rid); memdelete(cls); @@ -10365,6 +10387,62 @@ void RasterizerGLES2::_update_blur_buffer() { } #endif + + +bool RasterizerGLES2::_test_depth_shadow_buffer() { + + + int size=16; + + GLuint fbo; + GLuint rbo; + GLuint depth; + + glActiveTexture(GL_TEXTURE0); + + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + // Create a render buffer + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + + // Create a texture for storing the depth + glGenTextures(1, &depth); + glBindTexture(GL_TEXTURE_2D, depth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Remove artifact on the edges of the shadowmap + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + + // We'll use a depth texture to store the depths in the shadow map + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + +#ifdef GLEW_ENABLED + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#endif + + // Attach the depth texture to FBO depth attachment point + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, depth, 0); + + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + glDeleteFramebuffers(1,&fbo); + glDeleteRenderbuffers(1,&rbo); + glDeleteTextures(1,&depth); + + return status == GL_FRAMEBUFFER_COMPLETE; + +} + void RasterizerGLES2::init() { #ifdef GLEW_ENABLED @@ -10437,7 +10515,7 @@ void RasterizerGLES2::init() { #ifdef GLEW_ENABLED - read_depth_supported=true; + pvr_supported=false; etc_supported=false; use_depth24 =true; @@ -10455,7 +10533,10 @@ void RasterizerGLES2::init() { use_anisotropic_filter=true; float_linear_supported=true; float_supported=true; - use_rgba_shadowmaps=false; + + read_depth_supported=_test_depth_shadow_buffer(); + use_rgba_shadowmaps=!read_depth_supported; + //print_line("read depth support? "+itos(read_depth_supported)); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level); anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0))); @@ -10578,6 +10659,7 @@ void RasterizerGLES2::init() { shadow_mat_ptr = material_owner.get(shadow_material); overdraw_material = create_overdraw_debug_material(); copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS,read_depth_supported); canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false)); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index b7895ad82e..ad18c8e7a1 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1288,6 +1288,7 @@ class RasterizerGLES2 : public Rasterizer { void _copy_screen_quad(); void _copy_to_texscreen(); + bool _test_depth_shadow_buffer(); Vector3 chunk_vertex; Vector3 chunk_normal; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 8d378ceec1..69bd269948 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -266,6 +266,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a uses_normal=true; } + if (vnode->name==vname_shadow) { + uses_shadow_color=true; + } } @@ -616,6 +619,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT uses_texpixel_size=false; uses_worldvec=false; vertex_code_writes_vertex=false; + uses_shadow_color=false; uniforms=r_uniforms; flags=&r_flags; r_flags.use_color_interp=false; @@ -651,6 +655,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_normal=uses_normal; r_flags.uses_texpixel_size=uses_texpixel_size; r_flags.uses_worldvec=uses_worldvec; + r_flags.uses_shadow_color=uses_shadow_color; r_code_line=code; r_globals_line=global_code; @@ -827,7 +832,9 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[5]["LIGHT_VEC"]="light_vec"; mode_replace_table[5]["LIGHT_HEIGHT"]="light_height"; mode_replace_table[5]["LIGHT_COLOR"]="light"; + mode_replace_table[5]["LIGHT_UV"]="light_uv"; mode_replace_table[5]["LIGHT"]="light_out"; + mode_replace_table[5]["SHADOW"]="shadow_color"; mode_replace_table[5]["SCREEN_UV"]="screen_uv"; mode_replace_table[5]["POINT_COORD"]="gl_PointCoord"; mode_replace_table[5]["TIME"]="time"; @@ -857,5 +864,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_normal="NORMAL"; vname_texpixel_size="TEXTURE_PIXEL_SIZE"; vname_world_vec="WORLD_VERTEX"; + vname_shadow="SHADOW"; } diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 87722602fd..87016fd968 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -55,6 +55,7 @@ private: bool uses_texpixel_size; bool uses_worldvec; bool vertex_code_writes_vertex; + bool uses_shadow_color; Flags *flags; StringName vname_discard; @@ -74,6 +75,7 @@ private: StringName vname_normal; StringName vname_texpixel_size; StringName vname_world_vec; + StringName vname_shadow; Map<StringName,ShaderLanguage::Uniform> *uniforms; @@ -110,6 +112,7 @@ public: bool uses_normal; bool uses_texpixel_size; bool uses_worldvec; + bool uses_shadow_color; }; 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); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index e6d2569977..c4f0847870 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -36,7 +36,7 @@ uniform vec2 normal_flip; #endif #ifdef USE_SHADOWS -highp varying vec2 pos; +varying highp vec2 pos; #endif #endif @@ -161,11 +161,11 @@ varying vec4 local_rot; #ifdef USE_SHADOWS -uniform sampler2D shadow_texture; +uniform highp sampler2D shadow_texture; uniform float shadow_attenuation; uniform highp mat4 shadow_matrix; -highp varying vec2 pos; +varying highp vec2 pos; uniform float shadowpixel_size; #ifdef SHADOW_ESM @@ -230,12 +230,16 @@ FRAGMENT_SHADER_CODE float att=1.0; - vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color; + vec2 light_uv = light_uv_interp.xy; + vec4 light = texture2D(light_texture,light_uv) * light_color; +#if defined(USE_LIGHT_SHADOW_COLOR) + vec4 shadow_color=vec4(0.0,0.0,0.0,0.0); +#endif #if defined(USE_LIGHT_SHADER_CODE) //light is written by the light shader { - vec4 light_out=vec4(0.0,0.0,0.0,0.0); + vec4 light_out=light*color; LIGHT_SHADER_CODE color=light_out; } @@ -292,39 +296,51 @@ LIGHT_SHADER_CODE } - vec4 s = shadow_matrix * vec4(point,0.0,1.0); + highp vec4 s = shadow_matrix * highp vec4(point,0.0,1.0); s.xyz/=s.w; su=s.x*0.5+0.5; sz=s.z*0.5+0.5; - float shadow_attenuation; + highp float shadow_attenuation=0.0; + +#ifdef USE_DEPTH_SHADOWS + +#define SHADOW_DEPTH(m_tex,m_uv) (texture2D((m_tex),(m_uv)).z) + +#else + +//#define SHADOW_DEPTH(m_tex,m_uv) dot(texture2D((m_tex),(m_uv)),highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ) +#define SHADOW_DEPTH(m_tex,m_uv) dot(texture2D((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ) + +#endif + + #ifdef SHADOW_PCF5 - shadow_attenuation=0.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*2.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*2.0,sh)).z<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*2.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*2.0,sh))<sz?0.0:1.0; shadow_attenuation/=5.0; #endif #ifdef SHADOW_PCF13 - shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*2.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*3.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*4.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*5.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*6.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*2.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*3.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*4.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*5.0,sh)).z<sz?0.0:1.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*6.0,sh)).z<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*2.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*3.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*4.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*5.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size*6.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*2.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*3.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*4.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*5.0,sh))<sz?0.0:1.0; + shadow_attenuation += SHADOW_DEPTH(shadow_texture,vec2(su-shadowpixel_size*6.0,sh))<sz?0.0:1.0; shadow_attenuation/=13.0; #endif @@ -336,8 +352,8 @@ LIGHT_SHADER_CODE float unnormalized = su/shadowpixel_size; float fractional = fract(unnormalized); unnormalized = floor(unnormalized); - float zc = texture2D(shadow_texture,vec2((unnormalized-0.5)*shadowpixel_size,sh)).z; - float zn = texture2D(shadow_texture,vec2((unnormalized+0.5)*shadowpixel_size,sh)).z; + float zc = SHADOW_DEPTH(shadow_texture,vec2((unnormalized-0.5)*shadowpixel_size,sh)); + float zn = SHADOW_DEPTH(shadow_texture,vec2((unnormalized+0.5)*shadowpixel_size,sh)); float z = mix(zc,zn,fractional); shadow_attenuation=clamp(exp(shadow_esm_multiplier* ( z - sz )),0.0,1.0); } @@ -346,11 +362,15 @@ LIGHT_SHADER_CODE #if !defined(SHADOW_PCF5) && !defined(SHADOW_PCF13) && !defined(SHADOW_ESM) - shadow_attenuation = texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0; + shadow_attenuation = SHADOW_DEPTH(shadow_texture,vec2(su+shadowpixel_size,sh))<sz?0.0:1.0; #endif - color.rgb*=shadow_attenuation; +#if defined(USE_LIGHT_SHADOW_COLOR) + color=mix(shadow_color,color,shadow_attenuation); +#else + color*=shadow_attenuation; +#endif //use shadows #endif } |