From 80859a6cb2726a39fb22cb49f06e0355dc9390a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Thu, 14 Apr 2022 18:47:58 +0200 Subject: 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. --- .../gpu/shaders/gpu_shader_codegen_lib.glsl | 173 ++++++++++++++ .../gpu_shader_material_ambient_occlusion.glsl | 18 +- .../material/gpu_shader_material_anisotropic.glsl | 26 ++- .../material/gpu_shader_material_background.glsl | 16 +- .../shaders/material/gpu_shader_material_bump.glsl | 38 ++-- .../material/gpu_shader_material_camera.glsl | 8 +- .../material/gpu_shader_material_combine_hsv.glsl | 2 + .../material/gpu_shader_material_diffuse.glsl | 31 +-- .../material/gpu_shader_material_displacement.glsl | 8 +- .../gpu_shader_material_eevee_specular.glsl | 101 ++++----- .../material/gpu_shader_material_emission.glsl | 15 +- .../gpu_shader_material_fractal_noise.glsl | 3 + .../material/gpu_shader_material_fresnel.glsl | 7 +- .../material/gpu_shader_material_gamma.glsl | 2 + .../material/gpu_shader_material_geometry.glsl | 53 ++--- .../material/gpu_shader_material_glass.glsl | 64 ++---- .../material/gpu_shader_material_glossy.glsl | 39 ++-- .../shaders/material/gpu_shader_material_hair.glsl | 46 ++++ .../material/gpu_shader_material_hair_info.glsl | 26 +-- .../material/gpu_shader_material_holdout.glsl | 14 +- .../material/gpu_shader_material_hue_sat_val.glsl | 2 + .../material/gpu_shader_material_layer_weight.glsl | 10 +- .../material/gpu_shader_material_light_path.glsl | 16 +- .../material/gpu_shader_material_map_range.glsl | 2 + .../material/gpu_shader_material_mapping.glsl | 2 + .../shaders/material/gpu_shader_material_math.glsl | 2 + .../material/gpu_shader_material_math_util.glsl | 69 +++++- .../material/gpu_shader_material_mix_rgb.glsl | 2 + .../material/gpu_shader_material_noise.glsl | 2 + .../material/gpu_shader_material_normal_map.glsl | 14 +- .../material/gpu_shader_material_object_info.glsl | 16 +- .../material/gpu_shader_material_output_aov.glsl | 12 +- .../gpu_shader_material_output_material.glsl | 36 +-- .../material/gpu_shader_material_output_world.glsl | 18 +- .../gpu_shader_material_particle_info.glsl | 23 +- .../material/gpu_shader_material_point_info.glsl | 2 + .../material/gpu_shader_material_principled.glsl | 248 +++++++++------------ .../material/gpu_shader_material_refraction.glsl | 37 +-- .../material/gpu_shader_material_separate_hsv.glsl | 2 + .../gpu_shader_material_shader_to_rgba.glsl | 27 +-- .../gpu_shader_material_subsurface_scattering.glsl | 30 +-- .../material/gpu_shader_material_tangent.glsl | 6 +- .../material/gpu_shader_material_tex_brick.glsl | 3 + .../gpu_shader_material_tex_environment.glsl | 16 +- .../material/gpu_shader_material_tex_musgrave.glsl | 3 + .../material/gpu_shader_material_tex_noise.glsl | 4 + .../material/gpu_shader_material_tex_voronoi.glsl | 3 + .../material/gpu_shader_material_tex_wave.glsl | 4 + .../gpu_shader_material_tex_white_noise.glsl | 2 + .../gpu_shader_material_texture_coordinates.glsl | 84 +------ .../shaders/material/gpu_shader_material_toon.glsl | 20 +- .../material/gpu_shader_material_translucent.glsl | 23 +- .../material/gpu_shader_material_transparent.glsl | 17 +- .../gpu_shader_material_vector_displacement.glsl | 32 +-- .../material/gpu_shader_material_vector_math.glsl | 2 + .../gpu_shader_material_vector_rotate.glsl | 2 + .../material/gpu_shader_material_velvet.glsl | 19 +- .../gpu_shader_material_volume_absorption.glsl | 13 +- .../material/gpu_shader_material_volume_info.glsl | 24 +- .../gpu_shader_material_volume_principled.glsl | 22 +- .../gpu_shader_material_volume_scatter.glsl | 15 +- .../material/gpu_shader_material_wireframe.glsl | 23 +- .../gpu_shader_material_world_normals.glsl | 24 +- 63 files changed, 811 insertions(+), 812 deletions(-) create mode 100644 source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl (limited to 'source/blender/gpu/shaders') diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl index 193a4190cbf..5c97eada77d 100644 --- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl @@ -95,3 +95,176 @@ vec4 tangent_get(vec4 attr, mat3 normalmat) } #endif + +/* Assumes GPU_VEC4 is color data. So converting to luminance like cycles. */ +#define float_from_vec4(v) dot(v.rgb, vec3(0.2126, 0.7152, 0.0722)) +#define float_from_vec3(v) avg(v.rgb) +#define float_from_vec2(v) v.r + +#define vec2_from_vec4(v) vec2(avg(v.rgb), v.a) +#define vec2_from_vec3(v) vec2(avg(v.rgb), 1.0) +#define vec2_from_float(v) vec2(v) + +#define vec3_from_vec4(v) v.rgb +#define vec3_from_vec2(v) v.rrr +#define vec3_from_float(v) vec3(v) + +#define vec4_from_vec3(v) vec4(v, 1.0) +#define vec4_from_vec2(v) v.rrrg +#define vec4_from_float(v) vec4(vec3(v), 1.0) + +/* TODO: Move to shader_shared. */ +#define RAY_TYPE_CAMERA 0 +#define RAY_TYPE_SHADOW 1 +#define RAY_TYPE_DIFFUSE 2 +#define RAY_TYPE_GLOSSY 3 + +#ifdef GPU_FRAGMENT_SHADER +# define FrontFacing gl_FrontFacing +#else +# define FrontFacing true +#endif + +struct ClosureDiffuse { + float weight; + vec3 color; + vec3 N; + vec3 sss_radius; + uint sss_id; +}; + +struct ClosureTranslucent { + float weight; + vec3 color; + vec3 N; +}; + +struct ClosureReflection { + float weight; + vec3 color; + vec3 N; + float roughness; +}; + +struct ClosureRefraction { + float weight; + vec3 color; + vec3 N; + float roughness; + float ior; +}; + +struct ClosureHair { + float weight; + vec3 color; + float offset; + vec2 roughness; + vec3 T; +}; + +struct ClosureVolumeScatter { + float weight; + vec3 scattering; + float anisotropy; +}; + +struct ClosureVolumeAbsorption { + float weight; + vec3 absorption; +}; + +struct ClosureEmission { + float weight; + vec3 emission; +}; + +struct ClosureTransparency { + float weight; + vec3 transmittance; + float holdout; +}; + +struct GlobalData { + /** World position. */ + vec3 P; + /** Surface Normal. */ + vec3 N; + /** Geometric Normal. */ + vec3 Ng; + /** Surface default Tangent. */ + vec3 T; + /** Barycentric coordinates. */ + vec2 barycentric_coords; + vec3 barycentric_dists; + /** Ray properties (approximation). */ + int ray_type; + float ray_depth; + float ray_length; + /** Hair time along hair length. 0 at base 1 at tip. */ + float hair_time; + /** Hair time along width of the hair. */ + float hair_time_width; + /** Hair thickness in world space. */ + float hair_thickness; + /** Index of the strand for per strand effects. */ + int hair_strand_id; + /** Is hair. */ + bool is_strand; +}; + +GlobalData g_data; + +#ifndef GPU_FRAGMENT_SHADER +/* Stubs. */ +vec3 dF_impl(vec3 v) +{ + return vec3(0.0); +} + +void dF_branch(float fn, out vec2 result) +{ + result = vec2(0.0); +} + +#elif 0 /* TODO(@fclem): User Option? */ +/* Fast derivatives */ +vec3 dF_impl(vec3 v) +{ + return vec3(0.0); +} + +void dF_branch(float fn, out vec2 result) +{ + result.x = DFDX_SIGN * dFdx(fn); + result.y = DFDY_SIGN * dFdy(fn); +} + +#else +/* Precise derivatives */ +int g_derivative_flag = 0; + +vec3 dF_impl(vec3 v) +{ + if (g_derivative_flag > 0) { + return DFDX_SIGN * dFdx(v); + } + else if (g_derivative_flag < 0) { + return DFDY_SIGN * dFdy(v); + } + return vec3(0.0); +} + +# define dF_branch(fn, result) \ + if (true) { \ + g_derivative_flag = 1; \ + result.x = (fn); \ + g_derivative_flag = -1; \ + result.y = (fn); \ + g_derivative_flag = 0; \ + result -= vec2((fn)); \ + } + +#endif + +/* TODO(fclem): Remove. */ +#define CODEGEN_LIB diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl index 12921a31b23..4ba1f6f7368 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -1,4 +1,4 @@ -#ifndef VOLUMETRICS + void node_ambient_occlusion(vec4 color, float dist, vec3 normal, @@ -7,20 +7,6 @@ void node_ambient_occlusion(vec4 color, out vec4 result_color, out float result_ao) { - vec3 bent_normal; - vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); - OcclusionData data = occlusion_search(viewPosition, maxzBuffer, dist, inverted, sample_count); - - vec3 V = cameraVec(worldPosition); - vec3 N = normalize(normal); - vec3 Ng = safe_normalize(cross(dFdx(worldPosition), dFdy(worldPosition))); - - float unused_error; - vec3 unused; - occlusion_eval(data, V, N, Ng, inverted, result_ao, unused_error, unused); + result_ao = ambient_occlusion_eval(normal, dist, inverted, sample_count); result_color = result_ao * color; } -#else -/* Stub ambient occlusion because it is not compatible with volumetrics. */ -# define node_ambient_occlusion(a, b, c, d, e, f) (e = vec4(0); f = 0.0) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl index ec49cc86761..77de9e096a6 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl @@ -1,17 +1,27 @@ -#ifndef VOLUMETRICS + void node_bsdf_anisotropic(vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, - const float use_multiscatter, - const float ssr_id, + float weight, + const float do_multiscatter, out Closure result) { - node_bsdf_glossy(color, roughness, N, use_multiscatter, ssr_id, result); + N = safe_normalize(N); + vec3 V = cameraVec(g_data.P); + float NV = dot(N, V); + + vec2 split_sum = brdf_lut(NV, roughness); + + ClosureReflection reflection_data; + reflection_data.weight = weight; + reflection_data.color = (do_multiscatter != 0.0) ? + F_brdf_multi_scatter(color.rgb, color.rgb, split_sum) : + F_brdf_single_scatter(color.rgb, color.rgb, split_sum); + reflection_data.N = N; + reflection_data.roughness = roughness; + + result = closure_eval(reflection_data); } -#else -/* Stub anisotropic because it is not compatible with volumetrics. */ -# define node_bsdf_anisotropic(a, b, c, d, e, f, g, h, result) (result = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_background.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_background.glsl index 69ef4dcb7c7..2460bd63b38 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_background.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_background.glsl @@ -1,11 +1,9 @@ -void node_background(vec4 color, float strength, out Closure result) + +void node_background(vec4 color, float strength, float weight, out Closure result) { -#ifndef VOLUMETRICS - color *= strength; - result = CLOSURE_DEFAULT; - result.radiance = color.rgb; - result.transmittance = vec3(0.0); -#else - result = CLOSURE_DEFAULT; -#endif + ClosureEmission emission_data; + emission_data.weight = weight; + emission_data.emission = color.rgb * strength; + + result = closure_eval(emission_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl index 9f73f654217..e0931128485 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl @@ -1,28 +1,19 @@ -void dfdx_v3(vec3 v, out vec3 dy) -{ - dy = v + DFDX_SIGN * dFdx(v); -} -void dfdy_v3(vec3 v, out vec3 dy) +void differentiate_texco(vec3 v, out vec3 df) { - dy = v + DFDY_SIGN * dFdy(v); + /* Implementation defined. */ + df = v + dF_impl(v); } -void node_bump(float strength, - float dist, - float height, - float height_dx, - float height_dy, - vec3 N, - vec3 surf_pos, - float invert, - out vec3 result) +void node_bump( + float strength, float dist, float height, vec3 N, vec2 dHd, float invert, out vec3 result) { - N = mat3(ViewMatrix) * normalize(N); - dist *= gl_FrontFacing ? invert : -invert; + N = normalize(N); + dist *= FrontFacing ? invert : -invert; - vec3 dPdx = dFdx(surf_pos); - vec3 dPdy = dFdy(surf_pos); +#ifdef GPU_FRAGMENT_SHADER + vec3 dPdx = dFdx(g_data.P); + vec3 dPdy = dFdy(g_data.P); /* Get surface tangents from normal. */ vec3 Rx = cross(dPdy, N); @@ -31,14 +22,13 @@ void node_bump(float strength, /* Compute surface gradient and determinant. */ float det = dot(dPdx, Rx); - float dHdx = height_dx - height; - float dHdy = height_dy - height; - vec3 surfgrad = dHdx * Rx + dHdy * Ry; + vec3 surfgrad = dHd.x * Rx + dHd.y * Ry; strength = max(strength, 0.0); result = normalize(abs(det) * N - dist * sign(det) * surfgrad); result = normalize(mix(N, result, strength)); - - result = mat3(ViewMatrixInverse) * result; +#else + result = N; +#endif } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_camera.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_camera.glsl index 03e61e9f472..ff84a0a334c 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_camera.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_camera.glsl @@ -1,6 +1,6 @@ -void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist) +void camera(out vec3 outview, out float outdepth, out float outdist) { - outdepth = abs(co.z); - outdist = length(co); - outview = normalize(co); + outdepth = abs(transform_point(ViewMatrix, g_data.P).z); + outdist = distance(g_data.P, cameraPos); + outview = normalize(g_data.P - cameraPos); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_combine_hsv.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_combine_hsv.glsl index 2ce061da3cb..e8f444080b9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_combine_hsv.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_combine_hsv.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl) + void combine_hsv(float h, float s, float v, out vec4 col) { hsv_to_rgb(vec4(h, s, v, 1.0), col); 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 ab6024b073d..bbdd86bd664 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl @@ -1,28 +1,11 @@ -#ifndef VOLUMETRICS -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_diffuse, Diffuse) - -void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) +void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, float weight, out Closure result) { - CLOSURE_VARS_DECLARE_1(Diffuse); - - in_Diffuse_0.N = N; /* Normalized during eval. */ - in_Diffuse_0.albedo = color.rgb; - - CLOSURE_EVAL_FUNCTION_1(node_bsdf_diffuse, Diffuse); - - result = CLOSURE_DEFAULT; + ClosureDiffuse diffuse_data; + diffuse_data.weight = weight; + diffuse_data.color = color.rgb; + diffuse_data.N = N; + diffuse_data.sss_id = 0u; - out_Diffuse_0.radiance = render_pass_diffuse_mask(vec3(1.0), out_Diffuse_0.radiance); - out_Diffuse_0.radiance *= color.rgb; - - result.radiance = out_Diffuse_0.radiance; - - /* TODO(@fclem): Try to not use this. */ - closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); + result = closure_eval(diffuse_data); } - -#else -/* Stub diffuse because it is not compatible with volumetrics. */ -# define node_bsdf_diffuse(a, b, c, d) (d = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl index 0838b5c8b71..cdcdbe50917 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl @@ -1,9 +1,9 @@ -void node_displacement_object( - float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result) +void node_displacement_object(float height, float midlevel, float scale, vec3 N, out vec3 result) { - N = (vec4(N, 0.0) * obmat).xyz; + N = transform_direction(ModelMatrix, N); result = (height - midlevel) * scale * normalize(N); - result = (obmat * vec4(result, 0.0)).xyz; + /* Apply object scale and orientation. */ + result = transform_direction(ModelMatrix, result); } void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result) 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 0941482df45..c81880184e3 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 @@ -1,80 +1,69 @@ -#ifndef VOLUMETRICS - -CLOSURE_EVAL_FUNCTION_DECLARE_3(node_eevee_specular, Diffuse, Glossy, Glossy) void node_eevee_specular(vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, - vec3 normal, + vec3 N, float clearcoat, float clearcoat_roughness, - vec3 clearcoat_normal, + vec3 CN, float occlusion, - float ssr_id, + float weight, + const float use_clearcoat, out Closure result) { - CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy); - - in_common.occlusion = occlusion; - - in_Diffuse_0.N = normal; /* Normalized during eval. */ - in_Diffuse_0.albedo = diffuse.rgb; + N = safe_normalize(N); + CN = safe_normalize(CN); + vec3 V = cameraVec(g_data.P); - in_Glossy_1.N = normal; /* Normalized during eval. */ - in_Glossy_1.roughness = roughness; + ClosureEmission emission_data; + emission_data.weight = weight; + emission_data.emission = emissive.rgb; - in_Glossy_2.N = clearcoat_normal; /* Normalized during eval. */ - in_Glossy_2.roughness = clearcoat_roughness; + ClosureTransparency transparency_data; + transparency_data.weight = weight; + transparency_data.transmittance = vec3(transp); + transparency_data.holdout = 0.0; - CLOSURE_EVAL_FUNCTION_3(node_eevee_specular, Diffuse, Glossy, Glossy); + float alpha = (1.0 - transp) * weight; - result = CLOSURE_DEFAULT; + ClosureDiffuse diffuse_data; + diffuse_data.weight = alpha; + diffuse_data.color = diffuse.rgb; + diffuse_data.N = N; + diffuse_data.sss_id = 0u; - vec3 V = cameraVec(worldPosition); - - { - /* Diffuse. */ - out_Diffuse_0.radiance = render_pass_diffuse_mask(vec3(1), out_Diffuse_0.radiance); - out_Diffuse_0.radiance *= in_Diffuse_0.albedo; - result.radiance += out_Diffuse_0.radiance; - } - { - /* Glossy. */ - float NV = dot(in_Glossy_1.N, V); - vec2 split_sum = brdf_lut(NV, in_Glossy_1.roughness); + ClosureReflection reflection_data; + reflection_data.weight = alpha; + if (true) { + float NV = dot(N, V); + vec2 split_sum = brdf_lut(NV, roughness); vec3 brdf = F_brdf_single_scatter(specular.rgb, vec3(1.0), split_sum); - out_Glossy_1.radiance = closure_mask_ssr_radiance(out_Glossy_1.radiance, ssr_id); - out_Glossy_1.radiance *= brdf; - out_Glossy_1.radiance = render_pass_glossy_mask(specular.rgb, out_Glossy_1.radiance); - closure_load_ssr_data( - out_Glossy_1.radiance, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result); + reflection_data.color = specular.rgb * brdf; + reflection_data.N = N; + reflection_data.roughness = roughness; } - { - /* Clearcoat. */ - float NV = dot(in_Glossy_2.N, V); - vec2 split_sum = brdf_lut(NV, in_Glossy_2.roughness); + + ClosureReflection clearcoat_data; + clearcoat_data.weight = alpha * clearcoat * 0.25; + if (true) { + float NV = dot(CN, V); + vec2 split_sum = brdf_lut(NV, clearcoat_roughness); vec3 brdf = F_brdf_single_scatter(vec3(0.04), vec3(1.0), split_sum); - out_Glossy_2.radiance *= brdf * clearcoat * 0.25; - out_Glossy_2.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_2.radiance); - result.radiance += out_Glossy_2.radiance; - } - { - /* Emission. */ - vec3 out_emission_radiance = render_pass_emission_mask(emissive.rgb); - result.radiance += out_emission_radiance; + clearcoat_data.color = brdf; + clearcoat_data.N = CN; + clearcoat_data.roughness = clearcoat_roughness; } - float alpha = 1.0 - transp; - result.transmittance = vec3(transp); - result.radiance *= alpha; - result.ssr_data.rgb *= alpha; + if (use_clearcoat != 0.0f) { + result = closure_eval(diffuse_data, reflection_data, clearcoat_data); + } + else { + result = closure_eval(diffuse_data, reflection_data); + } + result = closure_add(result, closure_eval(emission_data)); + result = closure_add(result, closure_eval(transparency_data)); } - -#else -/* Stub specular because it is not compatible with volumetrics. */ -# define node_eevee_specular(a, b, c, d, e, f, g, h, i, j, k, result) (result = CLOSURE_DEFAULT) -#endif 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 f2de7c2da39..32484491abd 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl @@ -1,10 +1,9 @@ -void node_emission(vec4 color, float strength, vec3 vN, out Closure result) + +void node_emission(vec4 color, float strength, float weight, out Closure result) { - result = CLOSURE_DEFAULT; -#ifndef VOLUMETRICS - result.radiance = render_pass_emission_mask(color.rgb) * strength; - result.ssr_normal = normal_encode(vN, viewCameraVec(viewPosition)); -#else - result.emission = color.rgb * strength; -#endif + ClosureEmission emission_data; + emission_data.weight = weight; + emission_data.emission = color.rgb * strength; + + result = closure_eval(emission_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl index 95f2be4bd44..7f502f74c0c 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl @@ -1,3 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_noise.glsl) + /* The fractal_noise functions are all exactly the same except for the input type. */ float fractal_noise(float p, float octaves, float roughness) { diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_fresnel.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_fresnel.glsl index 7a4d28f2dd6..9fb98d598ab 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_fresnel.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_fresnel.glsl @@ -26,12 +26,11 @@ float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta) return fresnel_dielectric_cos(dot(Incoming, Normal), eta); } -void node_fresnel(float ior, vec3 N, vec3 I, out float result) +void node_fresnel(float ior, vec3 N, out float result) { N = normalize(N); - /* handle perspective/orthographic */ - vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + vec3 V = cameraVec(g_data.P); float eta = max(ior, 0.00001); - result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta); + result = fresnel_dielectric(V, N, (FrontFacing) ? eta : 1.0 / eta); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_gamma.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_gamma.glsl index 5733992f8dd..29fb09ceebd 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_gamma.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_gamma.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + void node_gamma(vec4 col, float gamma, out vec4 outcol) { outcol = col; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl index a14ff5021bf..5e86a4577ee 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl @@ -1,9 +1,6 @@ -void node_geometry(vec3 I, - vec3 N, - vec3 orco, - mat4 objmat, - mat4 toworld, - vec2 barycentric, +#pragma BLENDER_REQUIRE(gpu_shader_material_tangent.glsl) + +void node_geometry(vec3 orco, out vec3 position, out vec3 normal, out vec3 tangent, @@ -15,39 +12,21 @@ void node_geometry(vec3 I, out float random_per_island) { /* handle perspective/orthographic */ - vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); - incoming = -(toworld * vec4(I_view, 0.0)).xyz; - -#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) - position = -incoming; - true_normal = normal = incoming; - tangent = parametric = vec3(0.0); - vec3(0.0); - backfacing = 0.0; - pointiness = 0.0; -#else - - position = worldPosition; -# ifndef VOLUMETRICS - normal = normalize(N); - vec3 B = dFdx(worldPosition); - vec3 T = dFdy(worldPosition); - true_normal = normalize(cross(B, T)); -# else - normal = (toworld * vec4(N, 0.0)).xyz; - true_normal = normal; -# endif + incoming = coordinate_incoming(g_data.P); + position = g_data.P; + normal = g_data.N; + true_normal = g_data.Ng; -# ifdef HAIR_SHADER - tangent = -hairTangent; -# else - tangent_orco_z(orco, orco); - node_tangent(N, orco, objmat, tangent); -# endif + if (g_data.is_strand) { + tangent = g_data.T; + } + else { + tangent_orco_z(orco, orco); + node_tangent(orco, tangent); + } - parametric = vec3(barycentric, 0.0); - backfacing = (gl_FrontFacing) ? 0.0 : 1.0; + parametric = vec3(g_data.barycentric_coords, 0.0); + backfacing = (FrontFacing) ? 0.0 : 1.0; pointiness = 0.5; random_per_island = 0.0; -#endif } 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 aa0a8873596..36c71c27837 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl @@ -1,57 +1,33 @@ -#ifndef VOLUMETRICS - -CLOSURE_EVAL_FUNCTION_DECLARE_2(node_bsdf_glass, Glossy, Refraction) void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, - const float do_multiscatter, - const float ssr_id, + float weight, + float do_multiscatter, out Closure result) { - CLOSURE_VARS_DECLARE_2(Glossy, Refraction); - - in_Glossy_0.N = N; /* Normalized during eval. */ - in_Glossy_0.roughness = roughness; - - in_Refraction_1.N = N; /* Normalized during eval. */ - in_Refraction_1.roughness = roughness; - in_Refraction_1.ior = ior; + N = safe_normalize(N); + vec3 V = cameraVec(g_data.P); + float NV = dot(N, V); - CLOSURE_EVAL_FUNCTION_2(node_bsdf_glass, Glossy, Refraction); + vec2 split_sum = btdf_lut(NV, roughness, ior); - result = CLOSURE_DEFAULT; + float fresnel = (do_multiscatter != 0.0) ? split_sum.y : F_eta(ior, NV); + float btdf = (do_multiscatter != 0.0) ? 1.0 : split_sum.x; - float NV = dot(in_Refraction_1.N, cameraVec(worldPosition)); + ClosureReflection reflection_data; + reflection_data.weight = fresnel * weight; + reflection_data.color = color.rgb; + reflection_data.N = N; + reflection_data.roughness = roughness; - float fresnel = (do_multiscatter != 0.0) ? - btdf_lut(NV, in_Refraction_1.roughness, in_Refraction_1.ior).y : - F_eta(in_Refraction_1.ior, NV); + ClosureRefraction refraction_data; + refraction_data.weight = (1.0 - fresnel) * weight; + refraction_data.color = color.rgb * btdf; + refraction_data.N = N; + refraction_data.roughness = roughness; + refraction_data.ior = ior; - vec2 split_sum = brdf_lut(NV, in_Glossy_0.roughness); - vec3 brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(vec3(1.0), vec3(1.0), split_sum) : - F_brdf_single_scatter(vec3(1.0), vec3(1.0), split_sum); - - out_Glossy_0.radiance = closure_mask_ssr_radiance(out_Glossy_0.radiance, ssr_id); - out_Glossy_0.radiance *= brdf; - out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance); - out_Glossy_0.radiance *= color.rgb * fresnel; - closure_load_ssr_data( - out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result); - - float btdf = (do_multiscatter != 0.0) ? - 1.0 : - btdf_lut(NV, in_Refraction_1.roughness, in_Refraction_1.ior).x; - out_Refraction_1.radiance *= btdf; - out_Refraction_1.radiance = render_pass_glossy_mask(vec3(1.0), out_Refraction_1.radiance); - out_Refraction_1.radiance *= color.rgb * (1.0 - fresnel); - /* Simulate 2nd absorption event. */ - out_Refraction_1.radiance *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); - result.radiance += out_Refraction_1.radiance; + result = closure_eval(reflection_data, refraction_data); } - -#else -/* Stub glass because it is not compatible with volumetrics. */ -# define node_bsdf_glass(a, b, c, d, e, f, result) (result = CLOSURE_DEFAULT) -#endif 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 fa83bfb6c7a..2e48ddd1c5e 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl @@ -1,33 +1,20 @@ -#ifndef VOLUMETRICS - -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_glossy, Glossy) void node_bsdf_glossy( - vec4 color, float roughness, vec3 N, float use_multiscatter, float ssr_id, out Closure result) + vec4 color, float roughness, vec3 N, float weight, float do_multiscatter, out Closure result) { - bool do_ssr = (ssrToggle && int(ssr_id) == outputSsrId); - - CLOSURE_VARS_DECLARE_1(Glossy); + N = safe_normalize(N); + vec3 V = cameraVec(g_data.P); + float NV = dot(N, V); - in_Glossy_0.N = N; /* Normalized during eval. */ - in_Glossy_0.roughness = roughness; + vec2 split_sum = brdf_lut(NV, roughness); - CLOSURE_EVAL_FUNCTION_1(node_bsdf_glossy, Glossy); + ClosureReflection reflection_data; + reflection_data.weight = weight; + reflection_data.color = (do_multiscatter != 0.0) ? + F_brdf_multi_scatter(color.rgb, color.rgb, split_sum) : + F_brdf_single_scatter(color.rgb, color.rgb, split_sum); + reflection_data.N = N; + reflection_data.roughness = roughness; - result = CLOSURE_DEFAULT; - - vec2 split_sum = brdf_lut(dot(in_Glossy_0.N, cameraVec(worldPosition)), in_Glossy_0.roughness); - vec3 brdf = (use_multiscatter != 0.0) ? F_brdf_multi_scatter(vec3(1.0), vec3(1.0), split_sum) : - F_brdf_single_scatter(vec3(1.0), vec3(1.0), split_sum); - out_Glossy_0.radiance = closure_mask_ssr_radiance(out_Glossy_0.radiance, ssr_id); - out_Glossy_0.radiance *= brdf; - out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance); - out_Glossy_0.radiance *= color.rgb; - closure_load_ssr_data( - out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result); + result = closure_eval(reflection_data); } - -#else -/* Stub glossy because it is not compatible with volumetrics. */ -# define node_bsdf_glossy(a, b, c, d, e, result) (result = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl new file mode 100644 index 00000000000..7bf8795495a --- /dev/null +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl @@ -0,0 +1,46 @@ + +void node_bsdf_hair(vec4 color, + float offset, + float roughness_u, + float roughness_v, + vec3 T, + float weight, + out Closure result) +{ + ClosureHair hair_data; + hair_data.weight = weight; + hair_data.color = color.rgb; + hair_data.offset = offset; + hair_data.roughness = vec2(roughness_u, roughness_v); + hair_data.T = T; + + result = closure_eval(hair_data); +} + +void node_bsdf_hair_principled(vec4 color, + float melanin, + float melanin_redness, + vec4 tint, + vec3 absorption_coefficient, + float roughness, + float radial_roughness, + float coat, + float ior, + float offset, + float random_color, + float random_roughness, + float random, + float weight, + out Closure result) +{ + /* Placeholder closure. + * Some computation will have to happen here just like the Principled BSDF. */ + ClosureHair hair_data; + hair_data.weight = weight; + hair_data.color = color.rgb; + hair_data.offset = offset; + hair_data.roughness = vec2(0.0); + hair_data.T = g_data.T; + + result = closure_eval(hair_data); +} diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl index 59f0377869b..2885bf4e082 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl @@ -1,25 +1,19 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) + void node_hair_info(float hair_length, out float is_strand, out float intercept, - out float length, + out float out_length, out float thickness, out vec3 tangent, out float random) { - length = hair_length; -#ifdef HAIR_SHADER - is_strand = 1.0; - intercept = hairTime; - thickness = hairThickness; - tangent = normalize(worldNormal); - random = wang_hash_noise( - uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */ -#else - is_strand = 0.0; - intercept = 0.0; - thickness = 0.0; - tangent = vec3(1.0); - random = 0.0; -#endif + is_strand = float(g_data.is_strand); + intercept = g_data.hair_time; + thickness = g_data.hair_thickness; + out_length = hair_length; + tangent = g_data.T; + /* TODO: could be precomputed per strand instead. */ + random = wang_hash_noise(uint(g_data.hair_strand_id)); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_holdout.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_holdout.glsl index 50ce2bf2ab8..d022c1ced59 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_holdout.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_holdout.glsl @@ -1,8 +1,10 @@ -void node_holdout(out Closure result) + +void node_holdout(float weight, out Closure result) { - result = CLOSURE_DEFAULT; -#ifndef VOLUMETRICS - result.holdout = 1.0; - result.flag = CLOSURE_HOLDOUT_FLAG; -#endif + ClosureTransparency transparency_data; + transparency_data.weight = weight; + transparency_data.transmittance = vec3(0.0); + transparency_data.holdout = 1.0; + + result = closure_eval(transparency_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hue_sat_val.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hue_sat_val.glsl index 64ac73ecdf3..30b808508e9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hue_sat_val.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hue_sat_val.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl) + void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol) { vec4 hsv; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_layer_weight.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_layer_weight.glsl index 588d295bcc4..2b61343a200 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_layer_weight.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_layer_weight.glsl @@ -1,15 +1,17 @@ -void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing) +#pragma BLENDER_REQUIRE(gpu_shader_material_fresnel.glsl) + +void node_layer_weight(float blend, vec3 N, out float fresnel, out float facing) { N = normalize(N); /* fresnel */ float eta = max(1.0 - blend, 0.00001); - vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + vec3 V = cameraVec(g_data.P); - fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta); + fresnel = fresnel_dielectric(V, N, (FrontFacing) ? 1.0 / eta : eta); /* facing */ - facing = abs(dot(I_view, N)); + facing = abs(dot(V, N)); if (blend != 0.5) { blend = clamp(blend, 0.0, 0.99999); blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_light_path.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_light_path.glsl index 50c87e3f105..628a3d5e0e5 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_light_path.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_light_path.glsl @@ -13,19 +13,19 @@ void node_light_path(out float is_camera_ray, out float transmission_depth) { /* Supported. */ - is_camera_ray = (rayType == EEVEE_RAY_CAMERA) ? 1.0 : 0.0; - is_shadow_ray = (rayType == EEVEE_RAY_SHADOW) ? 1.0 : 0.0; - is_diffuse_ray = (rayType == EEVEE_RAY_DIFFUSE) ? 1.0 : 0.0; - is_glossy_ray = (rayType == EEVEE_RAY_GLOSSY) ? 1.0 : 0.0; + is_camera_ray = float(g_data.ray_type == RAY_TYPE_CAMERA); + is_shadow_ray = float(g_data.ray_type == RAY_TYPE_SHADOW); + is_diffuse_ray = float(g_data.ray_type == RAY_TYPE_DIFFUSE); + is_glossy_ray = float(g_data.ray_type == RAY_TYPE_GLOSSY); /* Kind of supported. */ is_singular_ray = is_glossy_ray; is_reflection_ray = is_glossy_ray; is_transmission_ray = is_glossy_ray; - ray_depth = rayDepth; - diffuse_depth = (is_diffuse_ray == 1.0) ? rayDepth : 0.0; - glossy_depth = (is_glossy_ray == 1.0) ? rayDepth : 0.0; + ray_depth = g_data.ray_depth; + diffuse_depth = (is_diffuse_ray == 1.0) ? g_data.ray_depth : 0.0; + glossy_depth = (is_glossy_ray == 1.0) ? g_data.ray_depth : 0.0; transmission_depth = (is_transmission_ray == 1.0) ? glossy_depth : 0.0; + ray_length = g_data.ray_length; /* Not supported. */ - ray_length = 1.0; transparent_depth = 0.0; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl index 1def3abec26..119ee3c0eaa 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + float smootherstep(float edge0, float edge1, float x) { x = clamp(safe_divide((x - edge0), (edge1 - edge0)), 0.0, 1.0); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_mapping.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_mapping.glsl index 07f152439fe..312c57231c5 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_mapping.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_mapping.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + void mapping_mat4( vec3 vec, vec4 m0, vec4 m1, vec4 m2, vec4 m3, vec3 minvec, vec3 maxvec, out vec3 outvec) { diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_math.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_math.glsl index f200d666e28..0948ce2c9fa 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_math.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_math.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + void math_add(float a, float b, float c, out float result) { result = a + b; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_math_util.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_math_util.glsl index 2a98d9fadd0..91a8996939a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_math_util.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_math_util.glsl @@ -140,17 +140,74 @@ mat3 euler_to_mat3(vec3 euler) return mat; } -void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout) +void normal_transform_object_to_world(vec3 vin, out vec3 vout) { - vout = (mat * vec4(vin, 0.0)).xyz; + vout = normal_object_to_world(vin); } -void normal_transform_transposed_m4v3(vec3 vin, mat4 mat, out vec3 vout) +void normal_transform_world_to_object(vec3 vin, out vec3 vout) { - vout = transpose(mat3(mat)) * vin; + vout = normal_world_to_object(vin); } -void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout) +void direction_transform_object_to_world(vec3 vin, out vec3 vout) { - vout = (mat * vec4(vin, 1.0)).xyz; + vout = transform_direction(ModelMatrix, vin); +} + +void direction_transform_object_to_view(vec3 vin, out vec3 vout) +{ + vout = transform_direction(ModelMatrix, vin); + vout = transform_direction(ViewMatrix, vout); +} + +void direction_transform_view_to_world(vec3 vin, out vec3 vout) +{ + vout = transform_direction(ViewMatrixInverse, vin); +} + +void direction_transform_view_to_object(vec3 vin, out vec3 vout) +{ + vout = transform_direction(ViewMatrixInverse, vin); + vout = transform_direction(ModelMatrixInverse, vout); +} + +void direction_transform_world_to_view(vec3 vin, out vec3 vout) +{ + vout = transform_direction(ViewMatrix, vin); +} + +void direction_transform_world_to_object(vec3 vin, out vec3 vout) +{ + vout = transform_direction(ModelMatrixInverse, vin); +} + +void point_transform_object_to_world(vec3 vin, out vec3 vout) +{ + vout = point_object_to_world(vin); +} + +void point_transform_object_to_view(vec3 vin, out vec3 vout) +{ + vout = point_object_to_view(vin); +} + +void point_transform_view_to_world(vec3 vin, out vec3 vout) +{ + vout = point_view_to_world(vin); +} + +void point_transform_view_to_object(vec3 vin, out vec3 vout) +{ + vout = point_view_to_object(vin); +} + +void point_transform_world_to_view(vec3 vin, out vec3 vout) +{ + vout = point_world_to_view(vin); +} + +void point_transform_world_to_object(vec3 vin, out vec3 vout) +{ + vout = point_world_to_object(vin); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_mix_rgb.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_mix_rgb.glsl index e089aec1d92..157a6a27c15 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_mix_rgb.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_mix_rgb.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl) + void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol) { fac = clamp(fac, 0.0, 1.0); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl index cc65b1eb57c..c84f34a834c 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) + /* clang-format off */ #define FLOORFRAC(x, x_int, x_fract) { float x_floor = floor(x); x_int = int(x_floor); x_fract = x - x_floor; } /* clang-format on */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl index 2b4a0204d97..e219e2b9bbe 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl @@ -1,13 +1,13 @@ -void node_normal_map(vec4 info, vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal) +void node_normal_map(vec4 tangent, vec3 texnormal, out vec3 outnormal) { if (all(equal(tangent, vec4(0.0, 0.0, 0.0, 1.0)))) { - outnormal = normal; + outnormal = g_data.N; return; } - tangent *= (gl_FrontFacing ? 1.0 : -1.0); - vec3 B = tangent.w * cross(normal, tangent.xyz) * sign(info.w); + tangent *= (FrontFacing ? 1.0 : -1.0); + vec3 B = tangent.w * cross(g_data.N, tangent.xyz) * sign(ObjectInfo.w); - outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal; + outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * g_data.N; outnormal = normalize(outnormal); } @@ -21,7 +21,7 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal) normal = vec3(2.0, -2.0, -2.0) * color - vec3(1.0); } -void node_normal_map_mix(float strength, vec3 newnormal, vec3 oldnormal, out vec3 outnormal) +void node_normal_map_mix(float strength, vec3 newnormal, out vec3 outnormal) { - outnormal = normalize(mix(oldnormal, newnormal, max(strength, 0.0))); + outnormal = normalize(mix(g_data.N, newnormal, max(strength, 0.0))); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_object_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_object_info.glsl index 607cf119b36..2dd2993ceb0 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_object_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_object_info.glsl @@ -1,7 +1,4 @@ -void node_object_info(mat4 obmat, - vec4 obcolor, - vec4 info, - float mat_index, +void node_object_info(float mat_index, out vec3 location, out vec4 color, out float alpha, @@ -9,10 +6,11 @@ void node_object_info(mat4 obmat, out float material_index, out float random) { - location = obmat[3].xyz; - color = obcolor; - alpha = obcolor.w; - object_index = info.x; + location = ModelMatrix[3].xyz; + color = ObjectColor; + alpha = ObjectColor.a; + object_index = ObjectInfo.x; + /* TODO(fclem): Put that inside the Material UBO. */ material_index = mat_index; - random = info.z; + random = ObjectInfo.z; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl index 648994739bf..b166c3e4e9f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl @@ -1,13 +1,5 @@ -void node_output_aov(vec4 color, float value, out Closure result) +void node_output_aov(vec4 color, float value, float hash, out Closure dummy) { - result = CLOSURE_DEFAULT; -#ifndef VOLUMETRICS - if (render_pass_aov_is_color()) { - result.radiance = color.rgb; - } - else { - result.radiance = vec3(value); - } -#endif + output_aov(color, value, floatBitsToUint(hash)); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl index 14271f9d107..2c24f50264c 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl @@ -1,20 +1,20 @@ -void node_output_material(Closure surface, - Closure volume, - vec3 displacement, - float alpha_threshold, - float shadow_threshold, - out Closure result) + +void node_output_material_surface(Closure surface, out Closure out_surface) { -#ifdef VOLUMETRICS - result = volume; -#else - result = surface; -# if defined(USE_ALPHA_HASH) - /* Alpha clip emulation. */ - if ((rayType != EEVEE_RAY_SHADOW) ? (alpha_threshold >= 0.0) : (shadow_threshold >= 0.0)) { - float alpha = saturate(1.0 - avg(result.transmittance)); - result.transmittance = vec3(step(alpha, max(alpha_threshold, shadow_threshold))); - } -# endif -#endif + out_surface = surface; +} + +void node_output_material_volume(Closure volume, out Closure out_volume) +{ + out_volume = volume; +} + +void node_output_material_displacement(vec3 displacement, out vec3 out_displacement) +{ + out_displacement = displacement; +} + +void node_output_material_thickness(float thickness, out float out_thickness) +{ + out_thickness = thickness; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl index 5eb853a4c1a..37c34a4f0d7 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl @@ -1,14 +1,10 @@ -uniform float backgroundAlpha; -void node_output_world(Closure surface, Closure volume, out Closure result) +void node_output_world_surface(Closure surface, out Closure out_surface) { -#ifndef VOLUMETRICS - float alpha = renderPassEnvironment ? 1.0 : backgroundAlpha; - result = CLOSURE_DEFAULT; - result.radiance = surface.radiance * alpha; - result.transmittance = vec3(0.0); - result.holdout = (1.0 - alpha); -#else - result = volume; -#endif /* VOLUMETRICS */ + out_surface = surface; +} + +void node_output_world_volume(Closure volume, out Closure out_volume) +{ + out_volume = volume; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_particle_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_particle_info.glsl index bdd60c20a81..5602345ea4a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_particle_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_particle_info.glsl @@ -1,8 +1,4 @@ -void particle_info(vec4 sprops, - vec4 loc, - vec3 vel, - vec3 avel, - out float index, +void particle_info(out float index, out float random, out float age, out float life_time, @@ -11,13 +7,14 @@ void particle_info(vec4 sprops, out vec3 velocity, out vec3 angular_velocity) { - index = sprops.x; - random = loc.w; - age = sprops.y; - life_time = sprops.z; - size = sprops.w; + /* Unsupported for now. */ + index = 0.0; + random = 0.0; + age = 0.0; + life_time = 0.0; + size = 0.0; - location = loc.xyz; - velocity = vel; - angular_velocity = avel; + location = vec3(0.0); + velocity = vec3(0.0); + angular_velocity = vec3(0.0); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl index d717ac97b28..1b1fed9502e 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) + void node_point_info(out vec3 position, out float radius, out float random) { 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 c97fc090fe2..033dc05c57d 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -1,4 +1,4 @@ -#ifndef VOLUMETRICS + vec3 tint_from_color(vec3 color) { float lum = dot(color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ @@ -13,8 +13,6 @@ float principled_sheen(float NV) return sheen; } -CLOSURE_EVAL_FUNCTION_DECLARE_4(node_bsdf_principled, Diffuse, Glossy, Glossy, Refraction) - void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, @@ -40,169 +38,137 @@ void node_bsdf_principled(vec4 base_color, vec3 N, vec3 CN, vec3 T, + float weight, const float do_diffuse, const float do_clearcoat, const float do_refraction, const float do_multiscatter, - float ssr_id, - float sss_id, - vec3 sss_scale, + float do_sss, out Closure result) { /* Match cycles. */ - metallic = saturate(metallic); - transmission = saturate(transmission); + metallic = clamp(metallic, 0.0, 1.0); + transmission = clamp(transmission, 0.0, 1.0) * (1.0 - metallic); float diffuse_weight = (1.0 - transmission) * (1.0 - metallic); - transmission *= (1.0 - metallic); float specular_weight = (1.0 - transmission); - clearcoat = max(clearcoat, 0.0); + float clearcoat_weight = max(clearcoat, 0.0) * 0.25; transmission_roughness = 1.0 - (1.0 - roughness) * (1.0 - transmission_roughness); specular = max(0.0, specular); - CLOSURE_VARS_DECLARE_4(Diffuse, Glossy, Glossy, Refraction); - - in_Diffuse_0.N = N; /* Normalized during eval. */ - in_Diffuse_0.albedo = mix(base_color.rgb, subsurface_color.rgb, subsurface); - - in_Glossy_1.N = N; /* Normalized during eval. */ - in_Glossy_1.roughness = roughness; - - in_Glossy_2.N = CN; /* Normalized during eval. */ - in_Glossy_2.roughness = clearcoat_roughness; - - in_Refraction_3.N = N; /* Normalized during eval. */ - in_Refraction_3.roughness = do_multiscatter != 0.0 ? roughness : transmission_roughness; - in_Refraction_3.ior = ior; + N = safe_normalize(N); + CN = safe_normalize(CN); + vec3 V = cameraVec(g_data.P); + float NV = dot(N, V); - CLOSURE_EVAL_FUNCTION_4(node_bsdf_principled, Diffuse, Glossy, Glossy, Refraction); + float fresnel = (do_multiscatter != 0.0) ? btdf_lut(NV, roughness, ior).y : F_eta(ior, NV); + float glass_reflection_weight = fresnel * transmission; + float glass_transmission_weight = (1.0 - fresnel) * transmission; - result = CLOSURE_DEFAULT; + vec3 base_color_tint = tint_from_color(base_color.rgb); - /* This will tag the whole eval for optimisation. */ - if (do_diffuse == 0.0) { - out_Diffuse_0.radiance = vec3(0); - } - if (do_clearcoat == 0.0) { - out_Glossy_2.radiance = vec3(0); - } - if (do_refraction == 0.0) { - out_Refraction_3.radiance = vec3(0); + vec2 split_sum = brdf_lut(NV, roughness); + + ClosureTransparency transparency_data; + transparency_data.weight = weight; + transparency_data.transmittance = vec3(1.0 - alpha); + transparency_data.holdout = 0.0; + + weight *= alpha; + + ClosureEmission emission_data; + emission_data.weight = weight; + emission_data.emission = emission.rgb * emission_strength; + + /* Diffuse. */ + ClosureDiffuse diffuse_data; + diffuse_data.weight = diffuse_weight * weight; + diffuse_data.color = mix(base_color.rgb, subsurface_color.rgb, subsurface); + /* Sheen Coarse approximation: We reuse the diffuse radiance and just scale it. */ + vec3 sheen_color = mix(vec3(1.0), base_color_tint, sheen_tint); + diffuse_data.color += sheen * sheen_color * principled_sheen(NV); + diffuse_data.N = N; + diffuse_data.sss_radius = subsurface_radius * subsurface; + diffuse_data.sss_id = uint(do_sss); + + /* NOTE(@fclem): We need to blend the reflection color but also need to avoid applying the + * weights so we compule the ratio. */ + float reflection_weight = specular_weight + glass_reflection_weight; + float reflection_weight_inv = safe_rcp(reflection_weight); + specular_weight *= reflection_weight_inv; + glass_reflection_weight *= reflection_weight_inv; + + /* Reflection. */ + ClosureReflection reflection_data; + reflection_data.weight = reflection_weight * weight; + reflection_data.N = N; + reflection_data.roughness = roughness; + if (true) { + vec3 dielectric_f0_color = mix(vec3(1.0), base_color_tint, specular_tint); + vec3 metallic_f0_color = base_color.rgb; + vec3 f0 = mix((0.08 * specular) * dielectric_f0_color, metallic_f0_color, metallic); + /* Cycles does this blending using the microfacet fresnel factor. However, our fresnel + * is already baked inside the split sum LUT. We approximate by changing the f90 color + * directly in a non linear fashion. */ + vec3 f90 = mix(f0, vec3(1.0), fast_sqrt(specular)); + + vec3 reflection_brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) : + F_brdf_single_scatter(f0, f90, split_sum); + reflection_data.color = reflection_brdf * specular_weight; } + if (true) { + /* Poor approximation since we baked the LUT using a fixed IOR. */ + vec3 f0 = mix(vec3(1.0), base_color.rgb, specular_tint); + vec3 f90 = vec3(1.0); - vec3 V = cameraVec(worldPosition); + vec3 glass_brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) : + F_brdf_single_scatter(f0, f90, split_sum); - /* Glossy_1 will always be evaluated. */ - float NV = dot(in_Glossy_1.N, V); - - vec3 base_color_tint = tint_from_color(base_color.rgb); + /* Avoid 3 glossy evaluation. Use the same closure for glass reflection. */ + reflection_data.color += glass_brdf * glass_reflection_weight; + } - float fresnel = (do_multiscatter != 0.0) ? - btdf_lut(NV, in_Glossy_1.roughness, in_Refraction_3.ior).y : - F_eta(in_Refraction_3.ior, NV); - - { - /* Glossy reflections. - * Separate Glass reflections and main specular reflections to match Cycles renderpasses. */ - out_Glossy_1.radiance = closure_mask_ssr_radiance(out_Glossy_1.radiance, ssr_id); - - vec2 split_sum = brdf_lut(NV, roughness); - - vec3 glossy_radiance_final = vec3(0.0); - if (transmission > 1e-5) { - /* Glass Reflection: Reuse radiance from Glossy1. */ - vec3 out_glass_refl_radiance = out_Glossy_1.radiance; - - /* Poor approximation since we baked the LUT using a fixed IOR. */ - vec3 f0 = mix(vec3(1.0), base_color.rgb, specular_tint); - vec3 f90 = vec3(1); - - vec3 brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) : - F_brdf_single_scatter(f0, f90, split_sum); - - out_glass_refl_radiance *= brdf; - out_glass_refl_radiance = render_pass_glossy_mask(vec3(1), out_glass_refl_radiance); - out_glass_refl_radiance *= fresnel * transmission; - glossy_radiance_final += out_glass_refl_radiance; - } - if (specular_weight > 1e-5) { - vec3 dielectric_f0_color = mix(vec3(1.0), base_color_tint, specular_tint); - vec3 metallic_f0_color = base_color.rgb; - vec3 f0 = mix((0.08 * specular) * dielectric_f0_color, metallic_f0_color, metallic); - /* Cycles does this blending using the microfacet fresnel factor. However, our fresnel - * is already baked inside the split sum LUT. We approximate using by modifying the - * changing the f90 color directly in a non linear fashion. */ - vec3 f90 = mix(f0, vec3(1), fast_sqrt(specular)); - - vec3 brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) : - F_brdf_single_scatter(f0, f90, split_sum); - - out_Glossy_1.radiance *= brdf; - out_Glossy_1.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_1.radiance); - out_Glossy_1.radiance *= specular_weight; - glossy_radiance_final += out_Glossy_1.radiance; - } - - closure_load_ssr_data( - glossy_radiance_final, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result); + ClosureReflection clearcoat_data; + clearcoat_data.weight = clearcoat_weight * weight; + clearcoat_data.N = CN; + clearcoat_data.roughness = clearcoat_roughness; + if (true) { + float NV = dot(clearcoat_data.N, V); + vec2 split_sum = brdf_lut(NV, clearcoat_data.roughness); + vec3 brdf = F_brdf_single_scatter(vec3(0.04), vec3(1.0), split_sum); + clearcoat_data.color = brdf; } - if (diffuse_weight > 1e-5) { - /* Mask over all diffuse radiance. */ - out_Diffuse_0.radiance *= diffuse_weight; + /* Refraction. */ + ClosureRefraction refraction_data; + refraction_data.weight = glass_transmission_weight * weight; + float btdf = (do_multiscatter != 0.0) ? 1.0 : btdf_lut(NV, roughness, ior).x; - /* Sheen Coarse approximation: We reuse the diffuse radiance and just scale it. */ - vec3 sheen_color = mix(vec3(1), base_color_tint, sheen_tint); - vec3 out_sheen_radiance = out_Diffuse_0.radiance * principled_sheen(NV); - out_sheen_radiance = render_pass_diffuse_mask(vec3(1), out_sheen_radiance); - out_sheen_radiance *= sheen * sheen_color; - result.radiance += out_sheen_radiance; + refraction_data.color = base_color.rgb * btdf; + refraction_data.N = N; + refraction_data.roughness = do_multiscatter != 0.0 ? roughness : + max(roughness, transmission_roughness); + refraction_data.ior = ior; - /* Diffuse / Subsurface. */ - float scale = avg(sss_scale) * subsurface; - closure_load_sss_data(scale, out_Diffuse_0.radiance, in_Diffuse_0.albedo, int(sss_id), result); + if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) { + /* Metallic & Clearcoat case. */ + result = closure_eval(reflection_data, clearcoat_data); } - - if (transmission > 1e-5) { - float btdf = (do_multiscatter != 0.0) ? - 1.0 : - btdf_lut(NV, in_Refraction_3.roughness, in_Refraction_3.ior).x; - /* TODO(@fclem): This could be going to a transmission render pass instead. */ - out_Refraction_3.radiance *= btdf; - out_Refraction_3.radiance = render_pass_glossy_mask(vec3(1), out_Refraction_3.radiance); - out_Refraction_3.radiance *= base_color.rgb; - /* Simulate 2nd transmission event. */ - out_Refraction_3.radiance *= (refractionDepth > 0.0) ? base_color.rgb : vec3(1); - out_Refraction_3.radiance *= (1.0 - fresnel) * transmission; - result.radiance += out_Refraction_3.radiance; + else if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) { + /* Metallic case. */ + result = closure_eval(reflection_data); } - - if (clearcoat > 1e-5) { - float NV = dot(in_Glossy_2.N, V); - vec2 split_sum = brdf_lut(NV, in_Glossy_2.roughness); - vec3 brdf = F_brdf_single_scatter(vec3(0.04), vec3(1.0), split_sum); - - out_Glossy_2.radiance *= brdf * clearcoat * 0.25; - out_Glossy_2.radiance = render_pass_glossy_mask(vec3(1), out_Glossy_2.radiance); - result.radiance += out_Glossy_2.radiance; + else if (do_diffuse != 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) { + /* Dielectric case. */ + result = closure_eval(diffuse_data, reflection_data); } - - { - vec3 out_emission_radiance = render_pass_emission_mask(emission.rgb); - out_emission_radiance *= emission_strength; - result.radiance += out_emission_radiance; + else if (do_diffuse == 0.0 && do_refraction != 0.0 && do_clearcoat == 0.0) { + /* Glass case. */ + result = closure_eval(reflection_data, refraction_data); } - - result.transmittance = vec3(1.0 - alpha); - result.radiance *= alpha; - result.ssr_data.rgb *= alpha; -# ifdef USE_SSS - result.sss_albedo *= alpha; -# endif + else { + /* Un-optimized case. */ + result = closure_eval(diffuse_data, reflection_data, clearcoat_data, refraction_data); + } + result = closure_add(result, closure_eval(emission_data)); + result = closure_add(result, closure_eval(transparency_data)); } - -#else -/* clang-format off */ -/* Stub principled because it is not compatible with volumetrics. */ -# define node_bsdf_principled(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd, ee, ff, result) (result = CLOSURE_DEFAULT) -/* clang-format on */ -#endif 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 8a42a131f43..871fa00b3d4 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl @@ -1,32 +1,15 @@ -#ifndef VOLUMETRICS -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_refraction, Refraction) - -void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result) +void node_bsdf_refraction( + vec4 color, float roughness, float ior, vec3 N, float weight, out Closure result) { - CLOSURE_VARS_DECLARE_1(Refraction); - - in_Refraction_0.N = N; /* Normalized during eval. */ - in_Refraction_0.roughness = roughness; - in_Refraction_0.ior = ior; - - CLOSURE_EVAL_FUNCTION_1(node_bsdf_refraction, Refraction); + N = safe_normalize(N); - result = CLOSURE_DEFAULT; + ClosureRefraction refraction_data; + refraction_data.weight = weight; + refraction_data.color = color.rgb; + refraction_data.N = N; + refraction_data.roughness = roughness; + refraction_data.ior = ior; - out_Refraction_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Refraction_0.radiance); - out_Refraction_0.radiance *= color.rgb; - /* Simulate 2nd absorption event. */ - out_Refraction_0.radiance *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); - - result.radiance = out_Refraction_0.radiance; - - /* TODO(@fclem): Try to not use this. */ - result.ssr_normal = normal_encode(mat3(ViewMatrix) * in_Refraction_0.N, - viewCameraVec(viewPosition)); + result = closure_eval(refraction_data); } - -#else -/* Stub refraction because it is not compatible with volumetrics. */ -# define node_bsdf_refraction(a, b, c, d, e) (e = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_separate_hsv.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_separate_hsv.glsl index fb64e424c6c..180e0fd1940 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_separate_hsv.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_separate_hsv.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl) + void separate_hsv(vec4 col, out float h, out float s, out float v) { vec4 hsv; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_shader_to_rgba.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_shader_to_rgba.glsl index f0f2f79c60e..d791f067821 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_shader_to_rgba.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_shader_to_rgba.glsl @@ -1,29 +1,6 @@ -#ifndef VOLUMETRICS - -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_shader_to_rgba, Glossy) void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha) { - vec4 spec_accum = vec4(0.0); - if (ssrToggle && FLAG_TEST(cl.flag, CLOSURE_SSR_FLAG)) { - CLOSURE_VARS_DECLARE_1(Glossy); - - vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec(viewPosition)); - vec3 N = transform_direction(ViewMatrixInverse, vN); - - in_Glossy_0.N = N; /* Normalized during eval. */ - in_Glossy_0.roughness = cl.ssr_data.a; - - CLOSURE_EVAL_FUNCTION_1(node_shader_to_rgba, Glossy); - - spec_accum.rgb = out_Glossy_0.radiance; - } - - outalpha = saturate(1.0 - avg(cl.transmittance)); - outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0); - -# ifdef USE_SSS - outcol.rgb += cl.sss_irradiance.rgb * cl.sss_albedo; -# endif + outcol = closure_to_rgba(cl); + outalpha = outcol.a; } -#endif /* 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 20b634aa801..c560dd01c4f 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 @@ -1,6 +1,3 @@ -#ifndef VOLUMETRICS - -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_subsurface_scattering, Diffuse) void node_subsurface_scattering(vec4 color, float scale, @@ -8,25 +5,18 @@ void node_subsurface_scattering(vec4 color, float ior, float anisotropy, vec3 N, - float sss_id, + float weight, + float do_sss, out Closure result) { - CLOSURE_VARS_DECLARE_1(Diffuse); - - in_Diffuse_0.N = N; /* Normalized during eval. */ - in_Diffuse_0.albedo = color.rgb; - - CLOSURE_EVAL_FUNCTION_1(node_subsurface_scattering, Diffuse); + N = safe_normalize(N); - result = CLOSURE_DEFAULT; + ClosureDiffuse diffuse_data; + diffuse_data.weight = weight; + diffuse_data.color = color.rgb; + diffuse_data.N = N; + diffuse_data.sss_radius = radius * scale; + diffuse_data.sss_id = uint(do_sss); - closure_load_sss_data(scale, out_Diffuse_0.radiance, color.rgb, int(sss_id), result); - - /* TODO(@fclem): Try to not use this. */ - closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); + result = closure_eval(diffuse_data); } - -#else -/* Stub subsurface scattering because it is not compatible with volumetrics. */ -# define node_subsurface_scattering(a, b, c, d, e, f, g, h) (h = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tangent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tangent.glsl index ff2dbc7ead3..4e4bf759ec9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tangent.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tangent.glsl @@ -18,8 +18,8 @@ void node_tangentmap(vec4 attr_tangent, out vec3 tangent) tangent = normalize(attr_tangent.xyz); } -void node_tangent(vec3 N, vec3 orco, mat4 objmat, out vec3 T) +void node_tangent(vec3 orco, out vec3 T) { - T = (objmat * vec4(orco, 0.0)).xyz; - T = cross(N, normalize(cross(T, N))); + T = transform_direction(ModelMatrix, orco); + T = cross(g_data.N, normalize(cross(T, g_data.N))); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_brick.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_brick.glsl index e252e5ba726..edc2fa32177 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_brick.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_brick.glsl @@ -1,3 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) + vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl index 434e07e7b86..89091316823 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl @@ -1,19 +1,5 @@ -void node_tex_environment_texco(vec3 viewvec, out vec3 worldvec) -{ -#ifdef MESH_SHADER - worldvec = worldPosition; -#else - vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogeneous = (ProjectionMatrixInverse * v); +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) - vec3 co = co_homogeneous.xyz / co_homogeneous.w; -# if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) - worldvec = mat3(ViewMatrixInverse) * co; -# else - worldvec = mat3(ModelMatrixInverse) * (mat3(ViewMatrixInverse) * co); -# endif -#endif -} void node_tex_environment_equirectangular(vec3 co, out vec3 uv) { diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_musgrave.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_musgrave.glsl index 586385b7e86..1552a2facc3 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_musgrave.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_musgrave.glsl @@ -1,3 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_noise.glsl) + /* 1D Musgrave fBm * * H: fractal increment parameter diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl index 5745f11ede4..c90b2211dcf 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl @@ -1,3 +1,7 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_noise.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_fractal_noise.glsl) + /* The following offset functions generate random offsets to be added to texture * coordinates to act as a seed since the noise functions don't have seed values. * A seed value is needed for generating distortion textures and color outputs. diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl index c8219848e29..dd12b602edf 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl @@ -1,3 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + /* * Original code is under the MIT License, Copyright (c) 2013 Inigo Quilez. * diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl index 070f42a5e30..eed98232d0b 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl @@ -1,3 +1,7 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_noise.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_material_fractal_noise.glsl) + float calc_wave(vec3 p, float distortion, float detail, diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_white_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_white_noise.glsl index b11d13a0413..030b58f0736 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_white_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_white_noise.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) + /* White Noise */ void node_white_noise_1d(vec3 vector, float w, out float value, out vec4 color) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_texture_coordinates.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_texture_coordinates.glsl index a8ef9687b0a..a3666164cf7 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_texture_coordinates.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_texture_coordinates.glsl @@ -1,38 +1,5 @@ -vec3 mtex_2d_mapping(vec3 vec) -{ - return vec3(vec.xy * 0.5 + vec2(0.5), vec.z); -} - -void generated_from_orco(vec3 orco, out vec3 generated) -{ -#ifdef VOLUMETRICS -# ifdef MESH_SHADER - generated = volumeObjectLocalCoord; -# else - generated = worldPosition; -# endif -#else - generated = orco; -#endif -} -void generated_texco(vec3 I, vec3 attr_orco, out vec3 generated) -{ - vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogeneous = (ProjectionMatrixInverse * v); - vec4 co = vec4(co_homogeneous.xyz / co_homogeneous.w, 0.0); - co.xyz = normalize(co.xyz); -#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) - generated = (ViewMatrixInverse * co).xyz; -#else - generated_from_orco(attr_orco, generated); -#endif -} - -void node_tex_coord(vec3 I, - vec3 wN, - mat4 obmatinv, - vec4 camerafac, +void node_tex_coord(mat4 obmatinv, vec3 attr_orco, vec3 attr_uv, out vec3 generated, @@ -44,49 +11,10 @@ void node_tex_coord(vec3 I, out vec3 reflection) { generated = attr_orco; - normal = normalize(normal_world_to_object(wN)); + normal = normal_world_to_object(g_data.N); uv = attr_uv; - object = (obmatinv * (ViewMatrixInverse * vec4(I, 1.0))).xyz; - camera = vec3(I.xy, -I.z); - vec4 projvec = ProjectionMatrix * vec4(I, 1.0); - window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0); - reflection = -reflect(cameraVec(worldPosition), normalize(wN)); -} - -void node_tex_coord_background(vec3 I, - vec3 N, - mat4 obmatinv, - vec4 camerafac, - vec3 attr_orco, - vec3 attr_uv, - out vec3 generated, - out vec3 normal, - out vec3 uv, - out vec3 object, - out vec3 camera, - out vec3 window, - out vec3 reflection) -{ - vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogeneous = (ProjectionMatrixInverse * v); - - vec4 co = vec4(co_homogeneous.xyz / co_homogeneous.w, 0.0); - - co = normalize(co); - - vec3 coords = (ViewMatrixInverse * co).xyz; - - generated = coords; - normal = -coords; - uv = vec3(attr_uv.xy, 0.0); - object = (obmatinv * vec4(coords, 1.0)).xyz; - - camera = vec3(co.xy, -co.z); - window = vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0); - - reflection = -coords; + object = transform_point((obmatinv[3][3] == 0.0) ? ModelMatrixInverse : obmatinv, g_data.P); + camera = coordinate_camera(g_data.P); + window = coordinate_screen(g_data.P); + reflection = coordinate_reflect(g_data.P, g_data.N); } - -#if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER)) -# define node_tex_coord node_tex_coord_background -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_toon.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_toon.glsl index bbfc99ccc73..ae7d4fc5631 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_toon.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_toon.glsl @@ -1,9 +1,15 @@ -#ifndef VOLUMETRICS -void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result) + +void node_bsdf_toon( + vec4 color, float size, float tsmooth, vec3 N, float weight, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); + N = safe_normalize(N); + + /* Fallback to diffuse. */ + ClosureDiffuse diffuse_data; + diffuse_data.weight = weight; + diffuse_data.color = color.rgb; + diffuse_data.N = N; + diffuse_data.sss_id = 0u; + + result = closure_eval(diffuse_data); } -#else -/* Stub toon because it is not compatible with volumetrics. */ -# define node_bsdf_toon(a, b, c, d, e) (e = CLOSURE_DEFAULT) -#endif 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 80bd3941b22..0cc162f42f5 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl @@ -1,21 +1,12 @@ -#ifndef VOLUMETRICS -CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_translucent, Translucent) - -void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) +void node_bsdf_translucent(vec4 color, vec3 N, float weight, out Closure result) { - CLOSURE_VARS_DECLARE_1(Translucent); - - in_Translucent_0.N = -N; /* Normalized during eval. */ + N = safe_normalize(N); - CLOSURE_EVAL_FUNCTION_1(node_bsdf_translucent, Translucent); + ClosureTranslucent translucent_data; + translucent_data.weight = weight; + translucent_data.color = color.rgb; + translucent_data.N = -N; - result = CLOSURE_DEFAULT; - closure_load_ssr_data(vec3(0.0), 0.0, -in_Translucent_0.N, -1.0, result); - result.radiance = render_pass_diffuse_mask(color.rgb, out_Translucent_0.radiance * color.rgb); + result = closure_eval(translucent_data); } - -#else -/* Stub translucent because it is not compatible with volumetrics. */ -# define node_bsdf_translucent(a, b, c) (c = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_transparent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_transparent.glsl index 9040f62bd3f..c650f10b6e4 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_transparent.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_transparent.glsl @@ -1,11 +1,10 @@ -#ifndef VOLUMETRICS -void node_bsdf_transparent(vec4 color, out Closure result) + +void node_bsdf_transparent(vec4 color, float weight, out Closure result) { - result = CLOSURE_DEFAULT; - result.radiance = vec3(0.0); - result.transmittance = abs(color.rgb); + ClosureTransparency transparency_data; + transparency_data.weight = weight; + transparency_data.transmittance = color.rgb; + transparency_data.holdout = 0.0; + + result = closure_eval(transparency_data); } -#else -/* Stub transparent because it is not compatible with volumetrics. */ -# define node_bsdf_transparent(a, b) (b = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_displacement.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_displacement.glsl index 4b5ed172081..0ff074bc04f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_displacement.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_displacement.glsl @@ -1,30 +1,22 @@ -void node_vector_displacement_tangent(vec4 vector, - float midlevel, - float scale, - vec4 tangent, - vec3 normal, - mat4 obmat, - mat4 viewmat, - out vec3 result) +void node_vector_displacement_tangent( + vec4 vector, float midlevel, float scale, vec4 T, out vec3 result) { - /* TODO(fclem): this is broken. revisit latter. */ - vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz); - vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz); - vec3 B_object = tangent.w * normalize(cross(N_object, T_object)); + vec3 oN = normalize(normal_world_to_object(g_data.N)); + vec3 oT = normalize(normal_world_to_object(T.xyz)); + vec3 oB = T.w * normalize(cross(oN, oT)); - vec3 offset = (vector.xyz - vec3(midlevel)) * scale; - result = offset.x * T_object + offset.y * N_object + offset.z * B_object; - result = (obmat * vec4(result, 0.0)).xyz; + result = (vector.xyz - midlevel) * scale; + result = result.x * oT + result.y * oN + result.z * oB; + result = transform_point(ModelMatrix, result); } -void node_vector_displacement_object( - vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result) +void node_vector_displacement_object(vec4 vector, float midlevel, float scale, out vec3 result) { - result = (vector.xyz - vec3(midlevel)) * scale; - result = (obmat * vec4(result, 0.0)).xyz; + result = (vector.xyz - midlevel) * scale; + result = transform_point(ModelMatrix, result); } void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result) { - result = (vector.xyz - vec3(midlevel)) * scale; + result = (vector.xyz - midlevel) * scale; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl index 4ad5d4232de..8f6bf17f195 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + void vector_math_add(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue) { outVector = a + b; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl index 41ad16cce0b..ff0fb1c0418 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) + vec3 rotate_around_axis(vec3 p, vec3 axis, float angle) { float costheta = cos(angle); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_velvet.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_velvet.glsl index 989f18b881a..97726bfe66f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_velvet.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_velvet.glsl @@ -1,9 +1,14 @@ -#ifndef VOLUMETRICS -void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result) + +void node_bsdf_velvet(vec4 color, float roughness, vec3 N, float weight, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); + N = safe_normalize(N); + + /* Fallback to diffuse. */ + ClosureDiffuse diffuse_data; + diffuse_data.weight = weight; + diffuse_data.color = color.rgb; + diffuse_data.N = N; + diffuse_data.sss_id = 0u; + + result = closure_eval(diffuse_data); } -#else -/* Stub velvet because it is not compatible with volumetrics. */ -# define node_bsdf_velvet(a, b, c, d) (d = CLOSURE_DEFAULT) -#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_absorption.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_absorption.glsl index e6c0880cd07..8fd2e179187 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_absorption.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_absorption.glsl @@ -1,8 +1,9 @@ -void node_volume_absorption(vec4 color, float density, out Closure result) + +void node_volume_absorption(vec4 color, float density, float weight, out Closure result) { -#ifdef VOLUMETRICS - result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0); -#else - result = CLOSURE_DEFAULT; -#endif + ClosureVolumeAbsorption volume_absorption_data; + volume_absorption_data.weight = weight; + volume_absorption_data.absorption = (1.0 - color.rgb) * density; + + result = closure_eval(volume_absorption_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl index e6d7b9d3721..464cf5227b4 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl @@ -4,14 +4,8 @@ uniform vec3 volumeColor = vec3(1.0); uniform vec2 volumeTemperature = vec2(0.0); /* Generic volume attribute. */ -void node_attribute_volume(sampler3D tex, mat4 transform, out vec3 outvec) +void node_attribute_volume(sampler3D tex, mat4 transform, vec3 cos, out vec3 outvec) { -#if defined(MESH_SHADER) && defined(VOLUMETRICS) - vec3 cos = volumeObjectLocalCoord; -#else - vec3 cos = vec3(0.0); -#endif - /* Optional per-grid transform. */ if (transform[3][3] != 0.0) { cos = (transform * vec4(cos, 1.0)).xyz; @@ -21,14 +15,8 @@ void node_attribute_volume(sampler3D tex, mat4 transform, out vec3 outvec) } /* Special color attribute for smoke. */ -void node_attribute_volume_color(sampler3D tex, mat4 transform, out vec3 outvec) +void node_attribute_volume_color(sampler3D tex, mat4 transform, vec3 cos, out vec3 outvec) { -#if defined(MESH_SHADER) && defined(VOLUMETRICS) - vec3 cos = volumeObjectLocalCoord; -#else - vec3 cos = vec3(0.0); -#endif - /* Optional per-grid transform. */ if (transform[3][3] != 0.0) { cos = (transform * vec4(cos, 1.0)).xyz; @@ -44,14 +32,8 @@ void node_attribute_volume_color(sampler3D tex, mat4 transform, out vec3 outvec) } /* Special temperature attribute for smoke. */ -void node_attribute_volume_temperature(sampler3D tex, mat4 transform, out float outf) +void node_attribute_volume_temperature(sampler3D tex, mat4 transform, vec3 cos, out float outf) { -#if defined(MESH_SHADER) && defined(VOLUMETRICS) - vec3 cos = volumeObjectLocalCoord; -#else - vec3 cos = vec3(0.0); -#endif - /* Optional per-grid transform. */ if (transform[3][3] != 0.0) { cos = (transform * vec4(cos, 1.0)).xyz; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl index 884d5415c51..1127c34b3ac 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(gpu_shader_material_blackbody.glsl) + void node_volume_principled(vec4 color, float density, float anisotropy, @@ -7,6 +9,7 @@ void node_volume_principled(vec4 color, float blackbody_intensity, vec4 blackbody_tint, float temperature, + float weight, float density_attribute, vec4 color_attribute, float temperature_attribute, @@ -14,7 +17,6 @@ void node_volume_principled(vec4 color, float layer, out Closure result) { -#ifdef VOLUMETRICS vec3 absorption_coeff = vec3(0.0); vec3 scatter_coeff = vec3(0.0); vec3 emission_coeff = vec3(0.0); @@ -60,8 +62,18 @@ void node_volume_principled(vec4 color, } } - result = Closure(absorption_coeff, scatter_coeff, emission_coeff, anisotropy); -#else - result = CLOSURE_DEFAULT; -#endif + ClosureVolumeScatter volume_scatter_data; + volume_scatter_data.weight = weight; + volume_scatter_data.scattering = scatter_coeff; + volume_scatter_data.anisotropy = anisotropy; + + ClosureVolumeAbsorption volume_absorption_data; + volume_absorption_data.weight = weight; + volume_absorption_data.absorption = absorption_coeff; + + ClosureEmission emission_data; + emission_data.weight = weight; + emission_data.emission = emission_coeff; + + result = closure_eval(volume_scatter_data, volume_absorption_data, emission_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_scatter.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_scatter.glsl index 02c54658be5..f01ead3618f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_scatter.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_scatter.glsl @@ -1,8 +1,11 @@ -void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result) + +void node_volume_scatter( + vec4 color, float density, float anisotropy, float weight, out Closure result) { -#ifdef VOLUMETRICS - result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy); -#else - result = CLOSURE_DEFAULT; -#endif + ClosureVolumeScatter volume_scatter_data; + volume_scatter_data.weight = weight; + volume_scatter_data.scattering = color.rgb * density; + volume_scatter_data.anisotropy = anisotropy; + + result = closure_eval(volume_scatter_data); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_wireframe.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_wireframe.glsl index e2789e046e1..0c02dab3ae4 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_wireframe.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_wireframe.glsl @@ -1,20 +1,21 @@ -#ifndef VOLUMETRICS -void node_wireframe(float size, vec2 barycentric, vec3 barycentric_dist, out float fac) + +void node_wireframe(float size, out float fac) { - vec3 barys = barycentric.xyy; - barys.z = 1.0 - barycentric.x - barycentric.y; + vec3 barys = g_data.barycentric_coords.xyy; + barys.z = 1.0 - barys.x - barys.y; size *= 0.5; - vec3 s = step(-size, -barys * barycentric_dist); + vec3 s = step(-size, -barys * g_data.barycentric_dists); fac = max(s.x, max(s.y, s.z)); } -void node_wireframe_screenspace(float size, vec2 barycentric, out float fac) +void node_wireframe_screenspace(float size, out float fac) { - vec3 barys = barycentric.xyy; - barys.z = 1.0 - barycentric.x - barycentric.y; + vec3 barys = g_data.barycentric_coords.xyy; + barys.z = 1.0 - barys.x - barys.y; +#ifdef GPU_FRAGMENT_SHADER size *= (1.0 / 3.0); vec3 dx = dFdx(barys); vec3 dy = dFdy(barys); @@ -23,9 +24,7 @@ void node_wireframe_screenspace(float size, vec2 barycentric, out float fac) vec3 s = step(-deltas * size, -barys); fac = max(s.x, max(s.y, s.z)); -} #else -/* Stub wireframe because it is not compatible with volumetrics. */ -# define node_wireframe(a, b, c, d) (d = 0.0) -# define node_wireframe_screenspace(a, b, c) (c = 0.0) + fac = 1.0; #endif +} diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl index 40e46bc250c..5a0aeb2f932 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl @@ -1,25 +1,5 @@ -/* TODO: clean this `ifdef` mess. */ + void world_normals_get(out vec3 N) { -#ifndef VOLUMETRICS -# ifdef HAIR_SHADER - vec3 B = normalize(cross(worldNormal, hairTangent)); - float cos_theta; - if (hairThicknessRes == 1) { - vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); - /* Random cosine normal distribution on the hair surface. */ - cos_theta = rand.x * 2.0 - 1.0; - } - else { - /* Shade as a cylinder. */ - cos_theta = hairThickTime / hairThickness; - } - float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); - N = normalize(worldNormal * sin_theta + B * cos_theta); -# else - N = gl_FrontFacing ? worldNormal : -worldNormal; -# endif -#else - generated_from_orco(vec3(0.0), N); -#endif + N = g_data.N; } -- cgit v1.2.3