diff options
Diffstat (limited to 'servers/visual/rasterizer_rd/shaders')
4 files changed, 83 insertions, 1 deletions
diff --git a/servers/visual/rasterizer_rd/shaders/SCsub b/servers/visual/rasterizer_rd/shaders/SCsub index 98c14144e9..9a28ef062c 100644 --- a/servers/visual/rasterizer_rd/shaders/SCsub +++ b/servers/visual/rasterizer_rd/shaders/SCsub @@ -19,3 +19,4 @@ if 'RD_GLSL' in env['BUILDERS']: env.RD_GLSL('ssao.glsl'); env.RD_GLSL('ssao_minify.glsl'); env.RD_GLSL('ssao_blur.glsl'); + env.RD_GLSL('roughness_limiter.glsl'); diff --git a/servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl new file mode 100644 index 0000000000..5e0491c979 --- /dev/null +++ b/servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl @@ -0,0 +1,73 @@ +/* clang-format off */ +[compute] +/* clang-format on */ + +#version 450 + +VERSION_DEFINES + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + + +layout(set = 0, binding = 0) uniform sampler2D source_normal; +layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_roughness; + +layout(push_constant, binding = 1, std430) uniform Params { + ivec2 screen_size; + float curve; + uint pad; +} params; + +#define HALF_PI 1.5707963267948966 + +void main() { + + // Pixel being shaded + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThan(pos,params.screen_size))) { //too large, do nothing + return; + } + + vec3 normal_accum = vec3(0.0); + float accum = 0.0; + for(int i=0;i<=1;i++) { + for(int j=0;j<=1;j++) { + normal_accum += normalize(texelFetch(source_normal,pos+ivec2(i,j),0).xyz * 2.0 - 1.0); + accum+=1.0; + } + } + + normal_accum /= accum; + + float r = length(normal_accum); + + float limit; + + if (r < 1.0) { + float threshold = 0.4; + +/* + //Formula from Filament, does not make sense to me. + + float r2 = r * r; + float kappa = (3.0f * r - r * r2) / (1.0f - r2); + float variance = 0.25f / kappa; + limit = sqrt(min(2.0f * variance, threshold * threshold)); +//*/ +/* + //Formula based on probability distribution graph + + float width = acos(max(0.0,r)); // convert to angle (width) + float roughness = pow(width,1.7)*0.854492; //approximate (crappy) formula to convert to roughness + limit = min(sqrt(roughness), threshold); //convert to perceptual roughness and apply threshold +//*/ + + limit = min(sqrt(pow(acos(max(0.0,r)) / HALF_PI ,params.curve)), threshold); //convert to perceptual roughness and apply threshold + + //limit = 0.5; + } else { + limit = 0.0; + } + + imageStore(dest_roughness,pos,vec4(limit)); +} diff --git a/servers/visual/rasterizer_rd/shaders/scene_high_end.glsl b/servers/visual/rasterizer_rd/shaders/scene_high_end.glsl index 66ce4b466f..8aee680c1e 100644 --- a/servers/visual/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/visual/rasterizer_rd/shaders/scene_high_end.glsl @@ -1272,6 +1272,7 @@ FRAGMENT_SHADER_CODE #endif // !USE_SHADOW_TO_OPACITY + #if defined(NORMALMAP_USED) normalmap.xy = normalmap.xy * 2.0 - 1.0; @@ -1310,6 +1311,13 @@ FRAGMENT_SHADER_CODE #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) + if (scene_data.roughness_limiter_enabled) { + float limit = texelFetch(sampler2D(roughness_buffer, material_samplers[SAMPLER_NEAREST_CLAMP]),ivec2(gl_FragCoord.xy),0).r; + roughness = max(roughness,limit); + + } + + if (scene_data.use_reflection_cubemap) { vec3 ref_vec = reflect(-view, normal); diff --git a/servers/visual/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/visual/rasterizer_rd/shaders/scene_high_end_inc.glsl index 5504d0fc2f..384e51bbce 100644 --- a/servers/visual/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/visual/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -63,7 +63,7 @@ layout(set = 0, binding = 3, std140) uniform SceneData { bool ssao_enabled; float ssao_light_affect; float ssao_ao_affect; - uint pad_ssao; + bool roughness_limiter_enabled; vec4 ao_color; |