diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-03-12 20:54:41 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-03-13 22:59:20 +0300 |
commit | 40d579b69f2f0acdf2695fe23a315212ebffae13 (patch) | |
tree | 0f3e100a23d6088b28fff7b406ddb8b23c17d741 /source/blender/draw | |
parent | 6a7f6f2867dc8a7aba8e91bf0fdf299ef276a65b (diff) |
Cleanup: EEVEE: Split effect_ssr.glsl
This split is to make code easier to manage and rename the files to
`effect_reflection_*` to avoid confusion.
Also this cleans up a bit of the branching mess in the trace shader.
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_shaders.c | 15 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl | 48 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl (renamed from source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl) | 194 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl | 131 |
5 files changed, 196 insertions, 196 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 98f42858812..196b46953c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -234,6 +234,9 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_resolve_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_scatter_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_scatter_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_setup_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_resolve_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_trace_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC) @@ -242,7 +245,6 @@ data_to_c_simple(engines/eevee/shaders/effect_velocity_tile_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_mist_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) -data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_subsurface_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_translucency_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_temporal_aa.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index b704521ce39..f7b83fa6d23 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -217,7 +217,9 @@ extern char datatoc_effect_gtao_frag_glsl[]; extern char datatoc_effect_minmaxz_frag_glsl[]; extern char datatoc_effect_mist_frag_glsl[]; extern char datatoc_effect_motion_blur_frag_glsl[]; -extern char datatoc_effect_ssr_frag_glsl[]; +extern char datatoc_effect_reflection_lib_glsl[]; +extern char datatoc_effect_reflection_resolve_frag_glsl[]; +extern char datatoc_effect_reflection_trace_frag_glsl[]; extern char datatoc_effect_subsurface_frag_glsl[]; extern char datatoc_effect_temporal_aa_glsl[]; extern char datatoc_effect_translucency_frag_glsl[]; @@ -304,6 +306,7 @@ static void eevee_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib); DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib); DRW_SHADER_LIB_ADD(e_data.lib, effect_dof_lib); + DRW_SHADER_LIB_ADD(e_data.lib, effect_reflection_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_type_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_diffuse_lib); @@ -767,8 +770,14 @@ struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOpt char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines); BLI_dynstr_free(ds_defines); - e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_effect_ssr_frag_glsl, lib, ssr_define_str); + if (options & SSR_RESOLVE) { + e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_reflection_resolve_frag_glsl, lib, ssr_define_str); + } + else { + e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_reflection_trace_frag_glsl, lib, ssr_define_str); + } MEM_freeN(ssr_define_str); } diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl new file mode 100644 index 00000000000..0f3f04596a8 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl @@ -0,0 +1,48 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +/* Based on: + * "Stochastic Screen Space Reflections" + * by Tomasz Stachowiak. + * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections + * and + * "Stochastic all the things: raytracing in hybrid real-time rendering" + * by Tomasz Stachowiak. + * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf + */ + +uniform ivec2 halfresOffset; + +struct HitData { + /** Hit direction scaled by intersection time. */ + vec3 hit_dir; + /** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections. */ + float hit_depth; + /** Inverse probability of ray spawning in this direction. */ + float ray_pdf_inv; + /** True if ray has hit valid geometry. */ + bool is_hit; + /** True if ray was generated from a planar reflection probe. */ + bool is_planar; +}; + +void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) +{ + vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); + hit_data.xyz = hit_vP - vP; + hit_depth = data.is_planar ? -1.0 : hit_sP.z; + /* Record 1.0 / pdf to reduce the computation in the resolve phase. */ + /* Encode hit validity in sign. */ + hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); +} + +HitData decode_hit_data(vec4 hit_data, float hit_depth) +{ + HitData data; + data.hit_dir.xyz = hit_data.xyz; + data.hit_depth = hit_depth; + data.is_planar = (hit_depth == -1.0); + data.ray_pdf_inv = abs(hit_data.w); + data.is_hit = (hit_data.w > 0.0); + return data; +} diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index 11048a46f8e..45057109cdf 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -1,14 +1,12 @@ #pragma BLENDER_REQUIRE(common_math_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) -#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) #pragma BLENDER_REQUIRE(closure_eval_glossy_lib.glsl) #pragma BLENDER_REQUIRE(closure_eval_lib.glsl) -#pragma BLENDER_REQUIRE(raytrace_lib.glsl) #pragma BLENDER_REQUIRE(lightprobe_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) -#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(surface_lib.glsl) +#pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) /* Based on: * "Stochastic Screen Space Reflections" @@ -20,193 +18,7 @@ * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf */ -uniform ivec2 halfresOffset; - -struct HitData { - /** Hit direction scaled by intersection time. */ - vec3 hit_dir; - /** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections. */ - float hit_depth; - /** Inverse probability of ray spawning in this direction. */ - float ray_pdf_inv; - /** True if ray has hit valid geometry. */ - bool is_hit; - /** True if ray was generated from a planar reflection probe. */ - bool is_planar; -}; - -void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) -{ - vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); - hit_data.xyz = hit_vP - vP; - hit_depth = data.is_planar ? -1.0 : hit_sP.z; - /* Record 1.0 / pdf to reduce the computation in the resolve phase. */ - /* Encode hit validity in sign. */ - hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); -} - -HitData decode_hit_data(vec4 hit_data, float hit_depth) -{ - HitData data; - data.hit_dir.xyz = hit_data.xyz; - data.hit_depth = hit_depth; - data.is_planar = (hit_depth == -1.0); - data.ray_pdf_inv = abs(hit_data.w); - data.is_hit = (hit_data.w > 0.0); - return data; -} - -#ifdef STEP_RAYTRACE - -uniform sampler2D normalBuffer; -uniform sampler2D specroughBuffer; - -layout(location = 0) out vec4 hitData; -layout(location = 1) out float hitDepth; - -void do_planar_ssr(int index, - vec3 vV, - vec3 vN, - vec3 vT, - vec3 vB, - vec3 viewPlaneNormal, - vec3 vP, - float alpha, - vec4 rand) -{ - float pdf; - /* Microfacet normal */ - vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); - vec3 vR = reflect(-vV, vH); - vR = reflect(vR, viewPlaneNormal); - - Ray ray; - ray.origin = vP; - ray.direction = vR * 1e16; - - RayTraceParameters params; - params.jitter = rand.y; - params.trace_quality = ssrQuality; - params.roughness = alpha * alpha; - - vec3 hit_sP; - HitData data; - data.is_planar = true; - data.ray_pdf_inv = safe_rcp(pdf); - data.is_hit = raytrace_planar(ray, params, index, hit_sP); - - encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); -} - -void do_ssr(vec3 vV, vec3 vN, vec3 vT, vec3 vB, vec3 vP, float alpha, vec4 rand) -{ - float pdf; - /* Microfacet normal */ - vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); - vec3 vR = reflect(-vV, vH); - - Ray ray; - ray.origin = vP + vN * 1e-4; - ray.direction = vR * 1e16; - - RayTraceParameters params; - params.thickness = ssrThickness; - params.jitter = rand.y; - params.trace_quality = ssrQuality; - params.roughness = alpha * alpha; - - vec3 hit_sP; - HitData data; - data.is_planar = false; - data.ray_pdf_inv = safe_rcp(pdf); - data.is_hit = raytrace(ray, params, true, hit_sP); - - encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); -} - -in vec4 uvcoordsvar; - -void main() -{ - vec2 uvs = uvcoordsvar.xy; - float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r; - - HitData data; - data.is_planar = false; - data.ray_pdf_inv = 0.0; - data.is_hit = false; - data.hit_dir = vec3(0.0, 0.0, 0.0); - - /* Default: not hits. */ - encode_hit_data(data, data.hit_dir, data.hit_dir, hitData, hitDepth); - - /* Early out */ - /* We can't do discard because we don't clear the render target. */ - if (depth == 1.0) { - return; - } - - /* Using view space */ - vec3 vP = get_view_space_from_depth(uvs, depth); - vec3 P = transform_point(ViewMatrixInverse, vP); - vec3 vV = viewCameraVec(vP); - vec3 V = cameraVec(P); - vec3 vN = normal_decode(texture(normalBuffer, uvs, 0).rg, vV); - vec3 N = transform_direction(ViewMatrixInverse, vN); - - /* Retrieve pixel data */ - vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; - - /* Early out */ - if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { - return; - } - - float roughness = speccol_roughness.a; - float alpha = max(1e-3, roughness * roughness); - - /* Early out */ - if (roughness > ssrMaxRoughness + 0.2) { - return; - } - - vec4 rand = texelfetch_noise_tex(vec2(gl_FragCoord.xy)); - - /* Gives *perfect* reflection for very small roughness */ - if (roughness < 0.04) { - rand.xzw *= 0.0; - } - /* Importance sampling bias */ - rand.x = mix(rand.x, 0.0, ssrBrdfBias); - - vec3 vT, vB; - make_orthonormal_basis(vN, vT, vB); /* Generate tangent space */ - - /* Planar Reflections */ - for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { - PlanarData pd = planars_data[i]; - - float fade = probe_attenuation_planar(pd, P); - fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0); - - if (fade > 0.5) { - /* Find view vector / reflection plane intersection. */ - /* TODO optimize, use view space for all. */ - vec3 tracePosition = line_plane_intersect(P, V, pd.pl_plane_eq); - tracePosition = transform_point(ViewMatrix, tracePosition); - vec3 viewPlaneNormal = transform_direction(ViewMatrix, pd.pl_normal); - - do_planar_ssr(i, vV, vN, vT, vB, viewPlaneNormal, tracePosition, alpha, rand); - return; - } - } - - do_ssr(vV, vN, vT, vB, vP, alpha, rand); -} - -#else /* STEP_RESOLVE */ - -uniform sampler2D colorBuffer; /* previous frame */ +uniform sampler2D colorBuffer; uniform sampler2D normalBuffer; uniform sampler2D specroughBuffer; uniform sampler2D hitBuffer; @@ -398,5 +210,3 @@ void main() fragColor = vec4(out_Glossy_0.radiance * brdf, 1.0); } - -#endif diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl new file mode 100644 index 00000000000..268ba6a3e2e --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl @@ -0,0 +1,131 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) + +/* Based on: + * "Stochastic Screen Space Reflections" + * by Tomasz Stachowiak. + * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections + * and + * "Stochastic all the things: raytracing in hybrid real-time rendering" + * by Tomasz Stachowiak. + * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf + */ + +uniform sampler2D normalBuffer; +uniform sampler2D specroughBuffer; + +in vec4 uvcoordsvar; + +layout(location = 0) out vec4 hitData; +layout(location = 1) out float hitDepth; + +void main() +{ + vec2 uvs = uvcoordsvar.xy; + float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r; + + HitData data; + data.is_planar = false; + data.ray_pdf_inv = 0.0; + data.is_hit = false; + data.hit_dir = vec3(0.0, 0.0, 0.0); + /* Default: not hits. */ + encode_hit_data(data, data.hit_dir, data.hit_dir, hitData, hitDepth); + + /* Early out */ + /* We can't do discard because we don't clear the render target. */ + if (depth == 1.0) { + return; + } + + /* Using view space */ + vec3 vP = get_view_space_from_depth(uvs, depth); + vec3 P = transform_point(ViewMatrixInverse, vP); + vec3 vV = viewCameraVec(vP); + vec3 V = cameraVec(P); + vec3 vN = normal_decode(texture(normalBuffer, uvs, 0).rg, vV); + vec3 N = transform_direction(ViewMatrixInverse, vN); + + /* Retrieve pixel data */ + vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; + + /* Early out */ + if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { + return; + } + + float roughness = speccol_roughness.a; + float alpha = max(1e-3, roughness * roughness); + + /* Early out */ + if (roughness > ssrMaxRoughness + 0.2) { + return; + } + + /* Planar Reflections */ + int planar_id = -1; + for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { + PlanarData pd = planars_data[i]; + + float fade = probe_attenuation_planar(pd, P); + fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0); + + if (fade > 0.5) { + /* Find view vector / reflection plane intersection. */ + /* TODO optimize, use view space for all. */ + vec3 P_plane = line_plane_intersect(P, V, pd.pl_plane_eq); + vP = transform_point(ViewMatrix, P_plane); + + planar_id = i; + data.is_planar = true; + break; + } + } + + vec4 rand = texelfetch_noise_tex(vec2(gl_FragCoord.xy)); + /* Gives *perfect* reflection for very small roughness */ + if (roughness < 0.04) { + rand.xzw *= 0.0; + } + /* Importance sampling bias */ + rand.x = mix(rand.x, 0.0, ssrBrdfBias); + + vec3 vT, vB; + make_orthonormal_basis(vN, vT, vB); /* Generate tangent space */ + + float pdf; + vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); + vec3 vR = reflect(-vV, vH); + + if (data.is_planar) { + vec3 view_plane_normal = transform_direction(ViewMatrix, planars_data[planar_id].pl_normal); + /* For planar reflections, we trace inside the reflected view. */ + vR = reflect(vR, view_plane_normal); + } + + Ray ray; + ray.origin = vP; + ray.direction = vR * 1e16; + + RayTraceParameters params; + params.jitter = rand.y; + params.trace_quality = ssrQuality; + params.roughness = alpha * alpha; + + vec3 hit_sP; + if (data.is_planar) { + data.is_hit = raytrace_planar(ray, params, planar_id, hit_sP); + } + else { + data.is_hit = raytrace(ray, params, true, hit_sP); + } + data.ray_pdf_inv = safe_rcp(pdf); + + encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); +} |