diff options
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.glsl | 242 |
1 files changed, 82 insertions, 160 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 fefc8743691..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,172 +22,92 @@ 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. */ +#ifdef GPU_METAL + inline Closure() = default; +# ifdef VOLUMETRICS + /* Explicit Closure constructors -- To support GLSL syntax */ + inline Closure(vec3 in_absorption, vec3 in_scatter, vec3 in_emission, float in_anisotropy) + : absorption(in_absorption), + scatter(in_scatter), + emission(in_emission), + anisotropy(in_anisotropy) + { + } +# else + /* Explicit Closure constructors -- To support GLSL syntax */ + 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 */ }; #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 |