diff options
Diffstat (limited to 'source/blender/gpu')
9 files changed, 74 insertions, 44 deletions
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl index e029905a908..714792489f6 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl @@ -4,8 +4,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) N = normalize(N); result = CLOSURE_DEFAULT; eevee_closure_diffuse(N, color.rgb, 1.0, true, result.radiance); + result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb); closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result); - result.radiance *= color.rgb; } #else /* Stub diffuse because it is not compatible with volumetrics. */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl index 34062cc8d02..747395857ee 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl @@ -32,7 +32,9 @@ void node_eevee_specular(vec4 diffuse, float alpha = 1.0 - transp; result = CLOSURE_DEFAULT; - result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb; + result.radiance = render_pass_diffuse_mask(diffuse.rgb, out_diff * diffuse.rgb); + result.radiance += render_pass_glossy_mask(vec3(1.0), out_spec); + result.radiance += render_pass_emission_mask(emissive.rgb); result.radiance *= alpha; result.transmittance = vec3(transp); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl index 092b9ed08bb..502bc7f92d6 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl @@ -2,7 +2,7 @@ void node_emission(vec4 color, float strength, vec3 vN, out Closure result) { result = CLOSURE_DEFAULT; #ifndef VOLUMETRICS - result.radiance = color.rgb * strength; + result.radiance = render_pass_emission_mask(color.rgb) * strength; result.ssr_normal = normal_encode(vN, viewCameraVec); #else result.emission = color.rgb * strength; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl index 5038cb3892f..ece770f0e73 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl @@ -17,12 +17,12 @@ void node_bsdf_glass( out_spec, out_refr, ssr_spec); - out_refr *= refr_color; - out_spec *= color.rgb; float fresnel = F_eta(ior, dot(N, cameraVec)); vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; - result.radiance = mix(out_refr, out_spec, fresnel); + result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color) * (1.0 - fresnel); + result.radiance += render_pass_glossy_mask(color.rgb, out_spec * color.rgb) * fresnel; + closure_load_ssr_data( ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl index 75cc2e770c5..7513c3a4edb 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl @@ -7,7 +7,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec); vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; - result.radiance = out_spec * color.rgb; + result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb; closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result); } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 7af409dd410..3c85dc6456c 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -18,15 +18,22 @@ void convert_metallic_to_specular_tinted(vec3 basecol, diffuse = basecol * (1.0 - metallic); } -vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint) +/* Output sheen is to be multiplied by sheen_color. */ +void principled_sheen(float NV, + vec3 basecol_tint, + float sheen, + float sheen_tint, + out float out_sheen, + out vec3 sheen_color) { float f = 1.0 - NV; /* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps, * therefore we need to clamp value. */ f = clamp(f, 0.0, 1.0); /* Empirical approximation (manual curve fitting). Can be refined. */ - float sheen = f * f * f * 0.077 + f * 0.01 + 0.00026; - return sheen * mix(vec3(1.0), basecol_tint, sheen_tint); + out_sheen = f * f * f * 0.077 + f * 0.01 + 0.00026; + + sheen_color = sheen * mix(vec3(1.0), basecol_tint, sheen_tint); } void node_bsdf_principled(vec4 base_color, @@ -61,18 +68,23 @@ void node_bsdf_principled(vec4 base_color, ior = max(ior, 1e-5); metallic = saturate(metallic); transmission = saturate(transmission); + float m_transmission = 1.0 - transmission; + float dielectric = 1.0 - metallic; transmission *= dielectric; sheen *= dielectric; subsurface_color *= dielectric; - vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec; + vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec, sheen_color; + float out_sheen; vec3 ctint = tint_from_color(base_color.rgb); convert_metallic_to_specular_tinted( base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); float NV = dot(N, cameraVec); - vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); + principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color); + + vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic); /* Far from being accurate, but 2 glossy evaluation is too expensive. * Most noticeable difference is at grazing angles since the bsdf lut @@ -81,8 +93,12 @@ void node_bsdf_principled(vec4 base_color, float fresnel = F_eta(ior, NV); vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel; f0 = mix(f0, spec_col, transmission); + f90 = mix(f90, spec_col, transmission); - vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic); + /* Really poor approximation but needed to workaround issues with renderpasses. */ + spec_col = mix(vec3(1.0), spec_col, transmission); + /* Match cycles. */ + spec_col += float(clearcoat > 1e-5); vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); @@ -108,19 +124,22 @@ void node_bsdf_principled(vec4 base_color, vec3 refr_color = base_color.rgb; refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */ - out_refr *= refr_color * (1.0 - fresnel) * transmission; + refr_color *= saturate(1.0 - fresnel) * transmission; + + sheen_color *= m_transmission; + mixed_ss_base_color *= m_transmission; result = CLOSURE_DEFAULT; - result.radiance = out_spec + out_refr; - result.radiance += out_diff * out_sheen; /* Coarse approx. */ - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color); + result.radiance += render_pass_glossy_mask(spec_col, out_spec); + /* Coarse approx. */ + result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; - closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); - mixed_ss_base_color *= alpha * (1.0 - transmission); + mixed_ss_base_color *= alpha; closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result); - result.transmittance = vec3(1.0 - alpha); } @@ -156,22 +175,26 @@ void node_bsdf_principled_dielectric(vec4 base_color, metallic = saturate(metallic); float dielectric = 1.0 - metallic; - vec3 diffuse, f0, out_diff, out_spec, ssr_spec; + vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color; + float out_sheen; vec3 ctint = tint_from_color(base_color.rgb); convert_metallic_to_specular_tinted( base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); + vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic); + float NV = dot(N, cameraVec); - vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); + principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color); eevee_closure_default( - N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec); + N, diffuse, f0, f90, int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec); result = CLOSURE_DEFAULT; - result.radiance = out_spec + out_diff * (diffuse + out_sheen); - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec); + result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color); + result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; - closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.transmittance = vec3(1.0 - alpha); @@ -214,10 +237,9 @@ void node_bsdf_principled_metallic(vec4 base_color, N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec); result = CLOSURE_DEFAULT; - result.radiance = out_spec; - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; - closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.transmittance = vec3(1.0 - alpha); @@ -268,10 +290,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color, true, out_spec, ssr_spec); + /* Match cycles. */ + float spec_col = 1.0 + float(clearcoat > 1e-5); result = CLOSURE_DEFAULT; - result.radiance = out_spec; - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); @@ -310,7 +334,8 @@ void node_bsdf_principled_subsurface(vec4 base_color, metallic = saturate(metallic); N = normalize(N); - vec3 diffuse, f0, out_diff, out_spec, ssr_spec; + vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color; + float out_sheen; vec3 ctint = tint_from_color(base_color.rgb); convert_metallic_to_specular_tinted( base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); @@ -320,7 +345,7 @@ void node_bsdf_principled_subsurface(vec4 base_color, float sss_scalef = avg(sss_scale) * subsurface; float NV = dot(N, cameraVec); - vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); + principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color); vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic); @@ -338,14 +363,14 @@ void node_bsdf_principled_subsurface(vec4 base_color, ssr_spec); result = CLOSURE_DEFAULT; - result.radiance = out_spec; - result.radiance += out_diff * out_sheen; - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec); + result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); - mixed_ss_base_color *= alpha * (1.0 - transmission); + mixed_ss_base_color *= alpha; closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result); result.transmittance = vec3(1.0 - alpha); @@ -400,16 +425,18 @@ void node_bsdf_principled_glass(vec4 base_color, vec3 refr_color = base_color.rgb; refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission events */ - out_refr *= refr_color; float fresnel = F_eta(ior, dot(N, cameraVec)); vec3 spec_col = F_color_blend(ior, fresnel, f0); - out_spec *= spec_col; - ssr_spec *= spec_col * fresnel; + spec_col *= fresnel; + refr_color *= (1.0 - fresnel); + + ssr_spec *= spec_col; result = CLOSURE_DEFAULT; - result.radiance = mix(out_refr, out_spec, fresnel); - result.radiance += emission.rgb; + result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color); + result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col); + result.radiance += render_pass_emission_mask(emission.rgb); result.radiance *= alpha; closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.transmittance = vec3(1.0 - alpha); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl index 906964e1539..4088d6db06a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl @@ -8,7 +8,7 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.ssr_normal = normal_encode(vN, viewCameraVec); - result.radiance = out_refr * color.rgb; + result.radiance = render_pass_glossy_mask(color.rgb, out_refr * color.rgb); } #else /* Stub refraction because it is not compatible with volumetrics. */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl index 241228c0d4c..9bbbe71b206 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl @@ -19,6 +19,7 @@ void node_subsurface_scattering(vec4 color, /* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */ vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur); out_diff *= mix(vec3(1.0), color.rgb, texture_blur); + result.radiance = render_pass_sss_mask(sss_albedo); closure_load_sss_data(scale, out_diff, sss_albedo, int(sss_id), result); } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl index 749b3a4c11f..5c3ed81410a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl @@ -5,7 +5,7 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) result = CLOSURE_DEFAULT; eevee_closure_diffuse(-N, color.rgb, 1.0, false, result.radiance); closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result); - result.radiance *= color.rgb; + result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb); } #else /* Stub translucent because it is not compatible with volumetrics. */ |