Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-08-12 02:47:30 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-08-14 14:36:56 +0300
commitd5002f007e8d770dea15f0881cd9d0a4f3aaf824 (patch)
treefabe9add7890d37884e2a9bf3c6e48c01bd7ff8a /source/blender/gpu
parent8a338950c6ddde37ddefadd75c39d4d2efc7aee3 (diff)
Eevee: Improve Transparent BSDF behavior
Alpha blended Transparency is now using dual source blending making it fully compatible with cycles Transparent BSDF. Multiply and additive blend mode can be achieved using some nodes and are going to be removed.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl168
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