diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp index b72196d4b9..d09b353007 100644 --- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp +++ b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp @@ -1302,6 +1302,14 @@ void RasterizerCanvasRD::_update_canvas_state_uniform_set() { uniforms.push_back(u_shadows); } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 4; + u.ids.push_back(state.shadow_sampler); + uniforms.push_back(u); + } + state.canvas_state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 3); // uses index 3 } @@ -1937,6 +1945,13 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { { //state allocate state.canvas_state_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(State::Buffer)); state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * MAX_RENDER_LIGHTS); + + RD::SamplerState shadow_sampler_state; + shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; + shadow_sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; + shadow_sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT; //shadow wrap around + shadow_sampler_state.compare_op = RD::COMPARE_OP_GREATER; + state.shadow_sampler = RD::get_singleton()->sampler_create(shadow_sampler_state); } } diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.h b/servers/visual/rasterizer/rasterizer_canvas_rd.h index 5a0d05d6f3..81e2815d6f 100644 --- a/servers/visual/rasterizer/rasterizer_canvas_rd.h +++ b/servers/visual/rasterizer/rasterizer_canvas_rd.h @@ -293,6 +293,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { RID lights_uniform_buffer; RID canvas_state_buffer; + RID shadow_sampler; //uniform set for all the above RID canvas_state_uniform_set; diff --git a/servers/visual/rasterizer/shaders/canvas.glsl b/servers/visual/rasterizer/shaders/canvas.glsl index eb5bdbe46e..defe8630be 100644 --- a/servers/visual/rasterizer/shaders/canvas.glsl +++ b/servers/visual/rasterizer/shaders/canvas.glsl @@ -522,33 +522,36 @@ FRAGMENT_SHADER_CODE //float distance = length(shadow_pos); float shadow; uint shadow_mode = light_array.data[light_base].flags&LIGHT_FLAGS_FILTER_MASK; + + vec4 shadow_uv = vec4(tex_ofs,0.0,distance,1.0); + if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) { - shadow = step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance); + shadow = textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) { - float shadow_pixel_size = light_array.data[light_base].shadow_pixel_size; + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0); shadow = 0.0; - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*2.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*2.0,0.0)).x,distance); + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; shadow/=5.0; } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) { - float shadow_pixel_size = light_array.data[light_base].shadow_pixel_size; + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0); shadow = 0.0; - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*6.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*5.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*4.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*3.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*2.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*2.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*3.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*4.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*5.0,0.0)).x,distance); - shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*6.0,0.0)).x,distance); + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x; + shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x; shadow/=13.0; } diff --git a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl index 7f55be051c..36a86c7f63 100644 --- a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl +++ b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl @@ -121,3 +121,5 @@ layout(set = 3, binding = 1, std140) uniform LightData { layout(set = 3, binding = 2) uniform texture2D light_textures[MAX_LIGHT_TEXTURES]; layout(set = 3, binding = 3) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES]; + +layout(set = 3, binding = 4) uniform sampler shadow_sampler;