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>2022-04-14 19:47:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-04-14 19:47:58 +0300
commit80859a6cb2726a39fb22cb49f06e0355dc9390a7 (patch)
treefd3f8ead5a247a79ea11e4aacc720843bbc5e2c2 /source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
parent66dc4d4efb88ecf2d18bfa08ab9c43b024ebd2fb (diff)
GPU: Make nodetree GLSL Codegen render engine agnostic
This commit removes all EEVEE specific code from the `gpu_shader_material*.glsl` files. It defines a clear interface to evaluate the closure nodes leaving more flexibility to the render engine. Some of the long standing workaround are fixed: - bump mapping support is no longer duplicating a lot of node and is instead compiled into a function call. - bump rewiring to Normal socket is no longer needed as we now use a global `g_data.N` for that. Closure sampling with upstread weight eval is now supported if the engine needs it. This also makes all the material GLSL sources use `GPUSource` for better debugging experience. The `GPUFunction` parsing now happens in `GPUSource` creation. The whole `GPUCodegen` now uses the `ShaderCreateInfo` and is object type agnostic. Is has also been rewritten in C++. This patch changes a view behavior for EEVEE: - Mix shader node factor imput is now clamped. - Tangent Vector displacement behavior is now matching cycles. - The chosen BSDF used for SSR might change. - Hair shading may have very small changes on very large hairs when using hair polygon stripes. - ShaderToRGB node will remove any SSR and SSS form a shader. - SSS radius input now is no longer a scaling factor but defines an average radius. The SSS kernel "shape" (radii) are still defined by the socket default values. Appart from the listed changes no other regressions are expected.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl252
1 files changed, 65 insertions, 187 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
index 9022a9d3130..0096cd1747f 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
@@ -1,6 +1,8 @@
-#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
-#pragma BLENDER_REQUIRE(renderpass_lib.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
+/* #pragma (common_math_geom_lib.glsl) */
+/* #pragma (common_uniforms_lib.glsl) */
+/* #pragma (renderpass_lib.glsl) */
#ifndef VOLUMETRICS
@@ -20,15 +22,6 @@ struct Closure {
vec3 radiance;
vec3 transmittance;
float holdout;
- vec4 ssr_data;
- vec2 ssr_normal;
- int flag;
-# ifdef USE_SSS
- vec3 sss_irradiance;
- vec3 sss_albedo;
- float sss_radius;
-# endif
-
#endif
/* Metal Default Constructor - Requred for C++ constructor syntax. */
@@ -45,191 +38,76 @@ struct Closure {
}
# else
/* Explicit Closure constructors -- To support GLSL syntax */
- inline Closure(vec3 in_radiance,
- vec3 in_transmittance,
- float in_holdout,
- vec4 in_ssr_data,
- vec2 in_ssr_normal,
- int in_flag
-# ifdef USE_SSS
- ,
- vec3 in_sss_irradiance,
- vec3 in_sss_albedo,
- float in_sss_radius
-# endif /* USE_SSS */
- )
- : radiance(in_radiance),
- transmittance(in_transmittance),
- holdout(in_holdout),
- ssr_data(in_ssr_data),
- ssr_normal(in_ssr_normal),
- flag(in_flag)
-# ifdef USE_SSS
- ,
- sss_irradiance(in_sss_irradiance),
- sss_albedo(in_sss_albedo),
- sss_radius(in_sss_radius)
-# endif /* USE_SSS */
+ inline Closure(vec3 in_radiance, vec3 in_transmittance, float in_holdout)
+ : radiance(in_radiance), transmittance(in_transmittance), holdout(in_holdout)
{
}
-# endif /* VOLUMETRICS */
-#endif /* GPU_METAL */
+# endif /* VOLUMETRICS */
+#endif /* GPU_METAL */
};
#ifndef GPU_METAL
/* Prototype */
-Closure nodetree_exec(void);
+Closure nodetree_exec();
+vec4 closure_to_rgba(Closure);
+void output_aov(vec4 color, float value, uint hash);
+vec3 coordinate_camera(vec3 P);
+vec3 coordinate_screen(vec3 P);
+vec3 coordinate_reflect(vec3 P, vec3 N);
+vec3 coordinate_incoming(vec3 P);
+
+/* Single BSDFs. */
+Closure closure_eval(ClosureDiffuse diffuse);
+Closure closure_eval(ClosureTranslucent translucent);
+Closure closure_eval(ClosureReflection reflection);
+Closure closure_eval(ClosureRefraction refraction);
+Closure closure_eval(ClosureEmission emission);
+Closure closure_eval(ClosureTransparency transparency);
+Closure closure_eval(ClosureVolumeScatter volume_scatter);
+Closure closure_eval(ClosureVolumeAbsorption volume_absorption);
+Closure closure_eval(ClosureHair hair);
+
+/* Glass BSDF. */
+Closure closure_eval(ClosureReflection reflection, ClosureRefraction refraction);
+/* Dielectric BSDF. */
+Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection);
+/* ClearCoat BSDF. */
+Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat);
+/* Volume BSDF. */
+Closure closure_eval(ClosureVolumeScatter volume_scatter,
+ ClosureVolumeAbsorption volume_absorption,
+ ClosureEmission emission);
+/* Specular BSDF. */
+Closure closure_eval(ClosureDiffuse diffuse,
+ ClosureReflection reflection,
+ ClosureReflection clearcoat);
+/* Principled BSDF. */
+Closure closure_eval(ClosureDiffuse diffuse,
+ ClosureReflection reflection,
+ ClosureReflection clearcoat,
+ ClosureRefraction refraction);
+
+Closure closure_add(Closure cl1, Closure cl2);
+Closure closure_mix(Closure cl1, Closure cl2, float fac);
+
+float ambient_occlusion_eval(vec3 normal,
+ float distance,
+ const float inverted,
+ const float sample_count);
+
+/* WORKAROUND: Included later with libs. This is because we are mixing include systems. */
+vec3 safe_normalize(vec3 N);
+float fast_sqrt(float a);
+vec3 cameraVec(vec3 P);
+vec2 btdf_lut(float a, float b, float c);
+vec2 brdf_lut(float a, float b);
+vec3 F_brdf_multi_scatter(vec3 a, vec3 b, vec2 c);
+vec3 F_brdf_single_scatter(vec3 a, vec3 b, vec2 c);
+float F_eta(float a, float b);
#endif
-/* clang-format off */
-/* Avoid multi-line defines. */
#ifdef VOLUMETRICS
# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), vec3(0), 0.0)
-#elif !defined(USE_SSS)
-# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0)
#else
-# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0, vec3(0), vec3(0), 0.0)
-#endif
-/* clang-format on */
-
-#define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
-
-#define CLOSURE_SSR_FLAG 1
-#define CLOSURE_SSS_FLAG 2
-#define CLOSURE_HOLDOUT_FLAG 4
-
-#ifdef VOLUMETRICS
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
- cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
- cl.emission = mix(cl1.emission, cl2.emission, fac);
- cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.absorption = cl1.absorption + cl2.absorption;
- cl.scatter = cl1.scatter + cl2.scatter;
- cl.emission = cl1.emission + cl2.emission;
- cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.emission = rgb;
- return cl;
-}
-
-#else /* SURFACE */
-
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
-
- if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 1.0;
- }
- else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 0.0;
- }
-
- cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
- cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz). */
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.transmittance = cl1.transmittance + cl2.transmittance;
- cl.radiance = cl1.radiance + cl2.radiance;
- cl.holdout = cl1.holdout + cl2.holdout;
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals. */
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.radiance = rgb;
- return cl;
-}
-
-#endif
-
-#ifndef VOLUMETRICS
-
-/* Let radiance passthrough or replace it to get the BRDF and color
- * to applied to the SSR result. */
-vec3 closure_mask_ssr_radiance(vec3 radiance, float ssr_id)
-{
- return (ssrToggle && int(ssr_id) == outputSsrId) ? vec3(1.0) : radiance;
-}
-
-void closure_load_ssr_data(
- vec3 ssr_radiance, float roughness, vec3 N, float ssr_id, inout Closure cl)
-{
- /* Still encode to avoid artifacts in the SSR pass. */
- vec3 vN = normalize(mat3(ViewMatrix) * N);
- cl.ssr_normal = normal_encode(vN, viewCameraVec(viewPosition));
-
- if (ssrToggle && int(ssr_id) == outputSsrId) {
- cl.ssr_data = vec4(ssr_radiance, roughness);
- cl.flag |= CLOSURE_SSR_FLAG;
- }
- else {
- cl.radiance += ssr_radiance;
- }
-}
-
-void closure_load_sss_data(
- float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
-{
-# ifdef USE_SSS
- if (sss_id == outputSssId) {
- cl.sss_irradiance = sss_irradiance;
- cl.sss_radius = radius;
- cl.sss_albedo = sss_albedo;
- cl.flag |= CLOSURE_SSS_FLAG;
- /* Irradiance will be convolved by SSSS pass. Do not add to radiance. */
- sss_irradiance = vec3(0);
- }
-# endif
- cl.radiance += render_pass_diffuse_mask(vec3(1), sss_irradiance) * sss_albedo;
-}
-
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0)
#endif