Blender  V3.3
bsdf_principled_sheen.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 /* DISNEY PRINCIPLED SHEEN BRDF
7  *
8  * Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
9  */
10 
12 
14 
15 typedef struct PrincipledSheenBsdf {
17  float avg_value;
19 
20 static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledSheenBsdf),
21  "PrincipledSheenBsdf is too large!");
22 
24 {
25  /* To compute the average, we set the half-vector to the normal, resulting in
26  * NdotI = NdotL = NdotV = LdotH */
27  float NdotI = dot(N, I);
28  if (NdotI < 0.0f) {
29  return 0.0f;
30  }
31 
32  return schlick_fresnel(NdotI) * NdotI;
33 }
34 
37 {
38  float NdotL = dot(N, L);
39  float NdotV = dot(N, V);
40 
41  if (NdotL < 0 || NdotV < 0) {
42  *pdf = 0.0f;
43  return make_float3(0.0f, 0.0f, 0.0f);
44  }
45 
46  float LdotH = dot(L, H);
47 
48  float value = schlick_fresnel(LdotH) * NdotL;
49 
50  return make_float3(value, value, value);
51 }
52 
55 {
57  bsdf->avg_value = calculate_avg_principled_sheen_brdf(bsdf->N, sd->I);
58  bsdf->sample_weight *= bsdf->avg_value;
59  return SD_BSDF | SD_BSDF_HAS_EVAL;
60 }
61 
63  const float3 I,
64  const float3 omega_in,
65  ccl_private float *pdf)
66 {
68 
69  float3 N = bsdf->N;
70  float3 V = I; // outgoing
71  float3 L = omega_in; // incoming
72  float3 H = normalize(L + V);
73 
74  if (dot(N, omega_in) > 0.0f) {
75  *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
76  return calculate_principled_sheen_brdf(N, V, L, H, pdf);
77  }
78  else {
79  *pdf = 0.0f;
80  return make_float3(0.0f, 0.0f, 0.0f);
81  }
82 }
83 
85  const float3 I,
86  const float3 omega_in,
87  ccl_private float *pdf)
88 {
89  *pdf = 0.0f;
90  return make_float3(0.0f, 0.0f, 0.0f);
91 }
92 
94  float3 Ng,
95  float3 I,
96  float3 dIdx,
97  float3 dIdy,
98  float randu,
99  float randv,
100  ccl_private float3 *eval,
101  ccl_private float3 *omega_in,
102  ccl_private float3 *domega_in_dx,
103  ccl_private float3 *domega_in_dy,
104  ccl_private float *pdf)
105 {
107 
108  float3 N = bsdf->N;
109 
110  sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
111 
112  if (dot(Ng, *omega_in) > 0) {
113  float3 H = normalize(I + *omega_in);
114 
115  *eval = calculate_principled_sheen_brdf(N, I, *omega_in, H, pdf);
116 
117 #ifdef __RAY_DIFFERENTIALS__
118  // TODO: find a better approximation for the diffuse bounce
119  *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
120  *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
121 #endif
122  }
123  else {
124  *eval = make_float3(0.0f, 0.0f, 0.0f);
125  *pdf = 0.0f;
126  }
127  return LABEL_REFLECT | LABEL_DIFFUSE;
128 }
129 
ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, ccl_private float3 *eval, ccl_private float3 *omega_in, ccl_private float3 *domega_in_dx, ccl_private float3 *domega_in_dy, ccl_private float *pdf)
ccl_device float3 calculate_principled_sheen_brdf(float3 N, float3 V, float3 L, float3 H, ccl_private float *pdf)
ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd, ccl_private PrincipledSheenBsdf *bsdf)
ccl_device_inline float calculate_avg_principled_sheen_brdf(float3 N, float3 I)
ccl_device float3 bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
CCL_NAMESPACE_BEGIN struct PrincipledSheenBsdf PrincipledSheenBsdf
ccl_device float3 bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
ccl_device float schlick_fresnel(float u)
Definition: bsdf_util.h:105
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
@ CLOSURE_BSDF_PRINCIPLED_SHEEN_ID
@ SD_BSDF_HAS_EVAL
Definition: kernel/types.h:744
@ SD_BSDF
Definition: kernel/types.h:742
ShaderData
Definition: kernel/types.h:925
@ LABEL_DIFFUSE
Definition: kernel/types.h:319
@ LABEL_REFLECT
Definition: kernel/types.h:318
ShaderClosure
Definition: kernel/types.h:726
#define N
#define L
#define H(x, y, z)
#define fmaxf(x, y)
Definition: metal/compat.h:228
#define make_float3(x, y, z)
Definition: metal/compat.h:204
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
#define I
ccl_device_inline void sample_cos_hemisphere(const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf)
#define M_1_PI_F
Definition: util/math.h:43
CCL_NAMESPACE_BEGIN struct Window V