From 95b1b7756d6e09b0bcf98c120de2b6552c1848be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 15 Aug 2017 09:36:23 +0200 Subject: Eevee: Fix some problem with Glass & Diffuse BSDF with SSR Diffuse was not outputing the right normal. (this is not a problem with SSR actually) Glass did not have proper ssr_id and was receiving environment lighting twice. Also it did not have proper fresnel on lamps. --- .../draw/engines/eevee/shaders/lit_surface_frag.glsl | 20 +++++++++++++------- source/blender/gpu/shaders/gpu_shader_material.glsl | 8 ++++---- source/blender/nodes/shader/node_shader_tree.c | 1 + .../nodes/shader/nodes/node_shader_bsdf_glass.c | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 4ee2e778c21..16b3283b624 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -742,7 +742,7 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared); /* Starts at 1 because 0 is world probe */ - for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999 && trans_accum.a < 0.999; ++i) { + for (int i = 1; i < MAX_PROBE && i < probe_count && (spec_accum.a < 0.999 || trans_accum.a < 0.999); ++i) { CubeData cd = probes_data[i]; float fade = probe_attenuation_cube(cd, worldPosition); @@ -751,10 +751,10 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i if (!(ssrToggle && ssr_id == outputSsrId)) { vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); accumulate_light(spec, fade, spec_accum); - - spec = probe_evaluate_cube(float(i), cd, refr_pos, refr_dir, roughnessSquared); - accumulate_light(spec, fade, trans_accum); } + + spec = probe_evaluate_cube(float(i), cd, refr_pos, refr_dir, roughnessSquared); + accumulate_light(spec, fade, trans_accum); } } @@ -763,12 +763,14 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i if (!(ssrToggle && ssr_id == outputSsrId)) { vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); accumulate_light(spec, 1.0, spec_accum); - - spec = probe_evaluate_world_spec(refr_dir, roughnessSquared); - accumulate_light(spec, 1.0, trans_accum); } } + if (trans_accum.a < 0.999) { + spec = probe_evaluate_world_spec(refr_dir, roughnessSquared); + accumulate_light(spec, 1.0, trans_accum); + } + /* Ambient Occlusion */ /* TODO : when AO will be cheaper */ float final_ao = 1.0; @@ -780,9 +782,13 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i float fresnel = F_eta(ior, NV); + /* Apply fresnel on lamps. */ + out_light *= vec3(fresnel); + ssr_spec = vec3(fresnel) * F_ibl(vec3(1.0), brdf_lut) * specular_occlusion(NV, final_ao, roughness); out_light += spec_accum.rgb * ssr_spec; + float btdf = get_btdf_lut(utilTex, NV, roughness, ior); out_light += vec3(1.0 - fresnel) * transmission_col * trans_accum.rgb * btdf; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index f8ac92f3258..b667df16101 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2664,7 +2664,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) #ifdef EEVEE_ENGINE vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0); vec3 vN = normalize(mat3(ViewMatrix) * N); - result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(N, viewCameraVec), -1); + result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(vN, viewCameraVec), -1); #else /* ambient light */ vec3 L = vec3(0.2); @@ -2720,14 +2720,14 @@ void node_bsdf_anisotropic( node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out Closure result) +void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result) { #ifdef EEVEE_ENGINE vec3 ssr_spec; roughness = sqrt(roughness); - vec3 L = eevee_surface_glass(N, (refractionDepth > 0.0) ? color.rgb : vec3(1.0), roughness, ior, int(-2), ssr_spec); + vec3 L = eevee_surface_glass(N, (refractionDepth > 0.0) ? color.rgb : vec3(1.0), roughness, ior, int(ssr_id), ssr_spec); vec3 vN = normalize(mat3(ViewMatrix) * N); - result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(-2)); + result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); #else node_bsdf_diffuse(color, 0.0, N, result); #endif diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 29cfc6b0f17..b90297cc631 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -486,6 +486,7 @@ static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void * case SH_NODE_EEVEE_SPECULAR: case SH_NODE_BSDF_PRINCIPLED: case SH_NODE_BSDF_GLOSSY: + case SH_NODE_BSDF_GLASS: fromnode->ssr_id = (*(float *)userdata); (*(float *)userdata) += 1; break; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 25f76ba9ecb..1537e07ca16 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -52,7 +52,7 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); - return GPU_stack_link(mat, node, "node_bsdf_glass", in, out); + return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id)); } /* node type definition */ -- cgit v1.2.3