diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 168 |
2 files changed, 88 insertions, 82 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 51b73c93c86..6d9fda1c695 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -934,7 +934,7 @@ static char *code_generate_fragment(GPUMaterial *material, BLI_dynstr_append(ds, "void main()\n"); BLI_dynstr_append(ds, "{\n"); BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n"); - BLI_dynstr_append(ds, "\tfragColor = vec4(cl.radiance, cl.opacity);\n"); + BLI_dynstr_append(ds, "\tfragColor = vec4(cl.radiance, saturate(avg(cl.transmittance)));\n"); BLI_dynstr_append(ds, "}\n"); BLI_dynstr_append(ds, "#endif\n\n"); diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 83d008c3441..798d19b6b9d 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1239,10 +1239,9 @@ vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint) void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) { N = normalize(N); - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; - result.ssr_normal = normal_encode(vN, viewCameraVec); eevee_closure_diffuse(N, color.rgb, 1.0, result.radiance); + closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result); result.radiance *= color.rgb; } @@ -1254,9 +1253,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec * color.rgb; - result.ssr_data = vec4(ssr_spec * color.rgb, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result); } void node_bsdf_anisotropic(vec4 color, @@ -1285,9 +1282,8 @@ void node_bsdf_glass( vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = mix(out_refr, out_spec, fresnel); - result.ssr_data = vec4(ssr_spec * color.rgb * fresnel, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data( + ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result); } void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result) @@ -1352,7 +1348,7 @@ void node_bsdf_principled(vec4 base_color, vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); - float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + float sss_scalef = avg(sss_scale) * subsurface; eevee_closure_principled(N, mixed_ss_base_color, f0, @@ -1376,28 +1372,34 @@ void node_bsdf_principled(vec4 base_color, vec3(1.0); /* Simulate 2 transmission event */ out_refr *= refr_color * (1.0 - fresnel) * transmission; - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec + out_refr; result.radiance += out_diff * out_sheen; /* Coarse approx. */ + + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); + + vec3 sss_radiance = (out_diff + out_trans) * alpha; # ifndef USE_SSS - result.radiance += (out_diff + out_trans) * mixed_ss_base_color * (1.0 - transmission); -# endif - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); -# ifdef USE_SSS - result.sss_data.a = sss_scalef; - result.sss_data.rgb = out_diff + out_trans; + result.radiance += sss_radiance * mixed_ss_base_color * (1.0 - transmission); +# else # ifdef USE_SSS_ALBEDO - result.sss_albedo.rgb = mixed_ss_base_color; + vec3 sss_albedo = mixed_ss_base_color; # else - result.sss_data.rgb *= mixed_ss_base_color; + sss_radiance *= mixed_ss_base_color; # endif - result.sss_data.rgb *= (1.0 - transmission); -# endif + sss_radiance *= (1.0 - transmission); + closure_load_sss_data(sss_scalef, + sss_radiance, +# ifdef USE_SSS_ALBEDO + sss_albedo, +# endif + int(sss_id), + result); +# endif /* USE_SSS */ + result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_principled_dielectric(vec4 base_color, @@ -1443,14 +1445,12 @@ void node_bsdf_principled_dielectric(vec4 base_color, eevee_closure_default( N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec); - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec + out_diff * (diffuse + out_sheen); - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_principled_metallic(vec4 base_color, @@ -1488,14 +1488,12 @@ void node_bsdf_principled_metallic(vec4 base_color, eevee_closure_glossy(N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, out_spec, ssr_spec); - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec; - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_principled_clearcoat(vec4 base_color, @@ -1543,14 +1541,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color, out_spec, ssr_spec); - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec; - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_principled_subsurface(vec4 base_color, @@ -1591,7 +1587,7 @@ void node_bsdf_principled_subsurface(vec4 base_color, subsurface_color = subsurface_color * (1.0 - metallic); vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); - float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + float sss_scalef = avg(sss_scale) * subsurface; float NV = dot(N, cameraVec); vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); @@ -1611,26 +1607,33 @@ void node_bsdf_principled_subsurface(vec4 base_color, out_spec, ssr_spec); - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = out_spec; - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); -# ifdef USE_SSS - result.sss_data.a = sss_scalef; - result.sss_data.rgb = out_diff + out_trans; + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); + + vec3 sss_radiance = (out_diff + out_trans) * alpha; +# ifndef USE_SSS + result.radiance += sss_radiance * mixed_ss_base_color * (1.0 - transmission); +# else # ifdef USE_SSS_ALBEDO - result.sss_albedo.rgb = mixed_ss_base_color; + vec3 sss_albedo = mixed_ss_base_color; # else - result.sss_data.rgb *= mixed_ss_base_color; + sss_radiance *= mixed_ss_base_color; # endif -# else - result.radiance += (out_diff + out_trans) * mixed_ss_base_color; -# endif + sss_radiance *= (1.0 - transmission); + closure_load_sss_data(sss_scalef, + sss_radiance, +# ifdef USE_SSS_ALBEDO + sss_albedo, +# endif + int(sss_id), + result); +# endif /* USE_SSS */ + result.radiance += out_diff * out_sheen; result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_principled_glass(vec4 base_color, @@ -1680,14 +1683,12 @@ void node_bsdf_principled_glass(vec4 base_color, out_spec *= spec_col; ssr_spec *= spec_col * fresnel; - vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; result.radiance = mix(out_refr, out_spec, fresnel); - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result); result.radiance += emission.rgb; - result.opacity = alpha; + result.radiance *= alpha; + result.transmittance = vec3(1.0 - alpha); } void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) @@ -1697,11 +1698,9 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) void node_bsdf_transparent(vec4 color, out Closure result) { - /* this isn't right */ result = CLOSURE_DEFAULT; result.radiance = vec3(0.0); - result.opacity = clamp(1.0 - dot(color.rgb, vec3(0.3333334)), 0.0, 1.0); - result.ssr_id = TRANSPARENT_CLOSURE_FLAG; + result.transmittance = abs(color.rgb); } void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result) @@ -1723,19 +1722,25 @@ void node_subsurface_scattering(vec4 color, vec3 out_diff, out_trans; vec3 vN = mat3(ViewMatrix) * N; result = CLOSURE_DEFAULT; - result.ssr_data = vec4(0.0); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = -1; - result.sss_data.a = scale; + closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result); + eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans); - result.sss_data.rgb = out_diff + out_trans; + + vec3 sss_radiance = out_diff + out_trans; # ifdef USE_SSS_ALBEDO /* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */ - result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur); - result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur); + vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur); + sss_radiance *= mix(vec3(1.0), color.rgb, texture_blur); # else - result.sss_data.rgb *= color.rgb; + sss_radiance *= color.rgb; # endif + closure_load_sss_data(scale, + sss_radiance, +# ifdef USE_SSS_ALBEDO + sss_albedo, +# endif + int(sss_id), + result); # else node_bsdf_diffuse(color, 0.0, N, result); # endif @@ -1751,7 +1756,6 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl result = CLOSURE_DEFAULT; result.ssr_normal = normal_encode(vN, viewCameraVec); result.radiance = out_refr * color.rgb; - result.ssr_id = REFRACT_CLOSURE_FLAG; } void node_ambient_occlusion( @@ -1852,7 +1856,7 @@ void node_background(vec4 color, float strength, out Closure result) color *= strength; result = CLOSURE_DEFAULT; result.radiance = color.rgb; - result.opacity = color.a; + result.transmittance = vec3(0.0); #else result = CLOSURE_DEFAULT; #endif @@ -2034,7 +2038,7 @@ void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outv #endif outvec = texture(tex, cos).aaa; outcol = vec4(outvec, 1.0); - outf = dot(vec3(1.0 / 3.0), outvec); + outf = avg(outvec); } uniform vec3 volumeColor = vec3(1.0); @@ -2055,7 +2059,7 @@ void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec outvec = value.rgb * volumeColor; outcol = vec4(outvec, 1.0); - outf = dot(vec3(1.0 / 3.0), outvec); + outf = avg(outvec); } void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf) @@ -2089,7 +2093,7 @@ void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) { outcol = vec4(attr, 1.0); outvec = attr; - outf = dot(vec3(1.0 / 3.0), attr); + outf = avg(attr); } void node_uvmap(vec3 attr_uv, out vec3 outvec) @@ -3502,7 +3506,7 @@ void node_output_world(Closure surface, Closure volume, out Closure result) { #ifndef VOLUMETRICS result.radiance = surface.radiance * backgroundAlpha; - result.opacity = backgroundAlpha; + result.transmittance = vec3(0.0); #else result = volume; #endif /* VOLUMETRICS */ @@ -3549,6 +3553,8 @@ void node_eevee_specular(vec4 diffuse, float ssr_id, out Closure result) { + normal = normalize(normal); + vec3 out_diff, out_spec, ssr_spec; eevee_closure_default_clearcoat(normal, diffuse.rgb, @@ -3564,19 +3570,19 @@ void node_eevee_specular(vec4 diffuse, out_spec, ssr_spec); - vec3 vN = normalize(mat3(ViewMatrix) * normal); + float alpha = 1.0 - transp; result = CLOSURE_DEFAULT; result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb; - result.opacity = 1.0 - transp; - result.ssr_data = vec4(ssr_spec, roughness); - result.ssr_normal = normal_encode(vN, viewCameraVec); - result.ssr_id = int(ssr_id); + result.radiance *= alpha; + result.transmittance = vec3(transp); + + closure_load_ssr_data(ssr_spec * alpha, roughness, normal, viewCameraVec, int(ssr_id), result); } void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha) { vec4 spec_accum = vec4(0.0); - if (ssrToggle && cl.ssr_id == outputSsrId) { + if (ssrToggle && FLAG_TEST(cl.flag, CLOSURE_SSR_FLAG)) { vec3 V = cameraVec; vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec); vec3 N = transform_direction(ViewMatrixInverse, vN); @@ -3585,7 +3591,7 @@ void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha) fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum); } - outalpha = cl.opacity; + outalpha = avg(cl.transmittance); outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0); # ifdef USE_SSS |