Blender V4.3
bsdf_sheen.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: Copyright 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7/* Shading model by Tizian Zeltner, Brent Burley, Matt Jen-Yuan Chiang:
8 * "Practical Multiple-Scattering Sheen Using Linearly Transformed Cosines" (2022)
9 * https://tizianzeltner.com/projects/Zeltner2022Practical/
10 */
11
13
15
22
23static_assert(sizeof(ShaderClosure) >= sizeof(SheenBsdf), "SheenBsdf is too large!");
24
26 ccl_private const ShaderData *sd,
28{
29 bsdf->type = CLOSURE_BSDF_SHEEN_ID;
30
31 bsdf->roughness = clamp(bsdf->roughness, 1e-3f, 1.0f);
32 make_orthonormals_safe_tangent(bsdf->N, sd->wi, &bsdf->T, &bsdf->B);
33 float cosNI = dot(bsdf->N, sd->wi);
34
35 int offset = kernel_data.tables.sheen_ltc;
36 bsdf->transformA = lookup_table_read_2D(kg, cosNI, bsdf->roughness, offset, 32, 32);
37 bsdf->transformB = lookup_table_read_2D(kg, cosNI, bsdf->roughness, offset + 32 * 32, 32, 32);
38 float albedo = lookup_table_read_2D(kg, cosNI, bsdf->roughness, offset + 2 * 32 * 32, 32, 32);
39
40 /* If the given roughness and angle result in an invalid LTC, skip the closure. */
41 if (fabsf(bsdf->transformA) < 1e-5f || albedo < 1e-5f) {
42 bsdf->type = CLOSURE_NONE_ID;
43 bsdf->sample_weight = 0.0f;
44 return 0;
45 }
46
47 bsdf->weight *= albedo;
48 bsdf->sample_weight *= albedo;
49
51}
52
54 const float3 wi,
55 const float3 wo,
56 ccl_private float *pdf)
57{
58 ccl_private const SheenBsdf *bsdf = (ccl_private const SheenBsdf *)sc;
59 const float3 N = bsdf->N, T = bsdf->T, B = bsdf->B;
60 float a = bsdf->transformA, b = bsdf->transformB;
61
62 if (dot(N, wo) <= 0.0f) {
63 *pdf = 0.0f;
64 return zero_spectrum();
65 }
66
67 float3 localO = make_float3(dot(T, wo), dot(B, wo), dot(N, wo));
68 if (localO.z <= 0.0f) {
69 *pdf = 0.0f;
70 return zero_spectrum();
71 }
72
73 float lenSqr = sqr(a * localO.x + b * localO.z) + sqr(a * localO.y) + sqr(localO.z);
74 float val = M_1_PI_F * localO.z * sqr(a / lenSqr);
75
76 *pdf = val;
77 return make_spectrum(val);
78}
79
81 float3 Ng,
82 float3 wi,
83 float2 rand,
86 ccl_private float *pdf)
87{
88 ccl_private const SheenBsdf *bsdf = (ccl_private const SheenBsdf *)sc;
89 const float3 N = bsdf->N, T = bsdf->T, B = bsdf->B;
90 float a = bsdf->transformA, b = bsdf->transformB;
91
92 float2 disk = sample_uniform_disk(rand);
93 float diskZ = safe_sqrtf(1.0f - dot(disk, disk));
94 float3 localO = normalize(make_float3((disk.x - diskZ * b), disk.y, diskZ * a));
95
96 *wo = localO.x * T + localO.y * B + localO.z * N;
97
98 if (dot(Ng, *wo) <= 0) {
99 *eval = zero_spectrum();
100 *pdf = 0.0f;
102 }
103
104 float lenSqr = sqr(a * localO.x + b * localO.z) + sqr(a * localO.y) + sqr(localO.z);
105 float val = M_1_PI_F * localO.z * sqr(a / lenSqr);
106 *pdf = val;
107 *eval = make_spectrum(val);
108
110}
111
MINLINE float safe_sqrtf(float a)
ccl_device int bsdf_sheen_setup(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private SheenBsdf *bsdf)
Definition bsdf_sheen.h:25
ccl_device Spectrum bsdf_sheen_eval(ccl_private const ShaderClosure *sc, const float3 wi, const float3 wo, ccl_private float *pdf)
Definition bsdf_sheen.h:53
ccl_device int bsdf_sheen_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf)
Definition bsdf_sheen.h:80
CCL_NAMESPACE_BEGIN struct SheenBsdf SheenBsdf
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device
#define ccl_private
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define fabsf(x)
@ CLOSURE_BSDF_SHEEN_ID
@ CLOSURE_NONE_ID
@ SD_BSDF_HAS_EVAL
@ SD_BSDF
ShaderData
@ LABEL_DIFFUSE
@ LABEL_REFLECT
ShaderClosure
ccl_device float lookup_table_read_2D(KernelGlobals kg, float x, float y, int offset, int xsize, int ysize)
#define N
#define B
CCL_NAMESPACE_BEGIN ccl_device float2 sample_uniform_disk(const float2 rand)
ccl_device void make_orthonormals_safe_tangent(const float3 N, const float3 T, ccl_private float3 *a, ccl_private float3 *b)
float roughness
Definition bsdf_sheen.h:18
float transformA
Definition bsdf_sheen.h:19
float3 T
Definition bsdf_sheen.h:20
float3 B
Definition bsdf_sheen.h:20
float transformB
Definition bsdf_sheen.h:19
SHADER_CLOSURE_BASE
Definition bsdf_sheen.h:17
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
#define zero_spectrum
#define make_spectrum(f)
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline float sqr(float a)
Definition util/math.h:782
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379