Blender V5.0
bsdf_toon.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Adapted code from Open Shading Language. */
7
8#pragma once
9
10#include "kernel/types.h"
11
13
15
16struct ToonBsdf {
18
19 float size;
20 float smooth;
21};
22
23static_assert(sizeof(ShaderClosure) >= sizeof(ToonBsdf), "ToonBsdf is too large!");
24
26{
27 bsdf->size = clamp(bsdf->size, 1e-5f, 1.0f) * M_PI_2_F;
28 bsdf->smooth = saturatef(bsdf->smooth) * M_PI_2_F;
29
31}
32
33/* DIFFUSE TOON */
34
40
41ccl_device float bsdf_toon_get_intensity(const float max_angle,
42 const float smooth,
43 const float angle)
44{
45 float is;
46
47 if (angle < max_angle) {
48 is = 1.0f;
49 }
50 else if (angle < (max_angle + smooth) && smooth != 0.0f) {
51 is = (1.0f - (angle - max_angle) / smooth);
52 }
53 else {
54 is = 0.0f;
55 }
56
57 return is;
58}
59
60ccl_device float bsdf_toon_get_sample_angle(const float max_angle, const float smooth)
61{
62 return fminf(max_angle + smooth, M_PI_2_F);
63}
64
66 const float3 /*wi*/,
67 const float3 wo,
68 ccl_private float *pdf)
69{
70 const ccl_private ToonBsdf *bsdf = (const ccl_private ToonBsdf *)sc;
71 const float max_angle = bsdf->size;
72 const float smooth = bsdf->smooth;
73 const float cosNO = dot(bsdf->N, wo);
74
75 if (cosNO >= 0.0f) {
76 const float angle = safe_acosf(fmaxf(cosNO, 0.0f));
77 const float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
78
79 if (angle < sample_angle) {
80 const float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
81 *pdf = M_1_2PI_F / one_minus_cos(sample_angle);
82 return make_spectrum(*pdf * eval);
83 }
84 }
85
86 *pdf = 0.0f;
87 return zero_spectrum();
88}
89
91 const float3 Ng,
92 const float3 /*wi*/,
93 const float2 rand,
96 ccl_private float *pdf)
97{
98 const ccl_private ToonBsdf *bsdf = (const ccl_private ToonBsdf *)sc;
99 const float max_angle = bsdf->size;
100 const float smooth = bsdf->smooth;
101 const float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
102
103 float cosNO;
104 *wo = sample_uniform_cone(bsdf->N, one_minus_cos(sample_angle), rand, &cosNO, pdf);
105
106 if (dot(Ng, *wo) > 0.0f) {
107 const float angle = acosf(cosNO);
108 *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
110 }
111
112 *pdf = 0.0f;
113 *eval = zero_spectrum();
114 return LABEL_NONE;
115}
116
117/* GLOSSY TOON */
118
124
126 const float3 wi,
127 const float3 wo,
128 ccl_private float *pdf)
129{
130 const ccl_private ToonBsdf *bsdf = (const ccl_private ToonBsdf *)sc;
131 const float max_angle = bsdf->size;
132 const float smooth = bsdf->smooth;
133 const float cosNI = dot(bsdf->N, wi);
134 const float cosNO = dot(bsdf->N, wo);
135
136 if (cosNI > 0 && cosNO > 0) {
137 /* reflect the view vector */
138 const float3 R = (2 * cosNI) * bsdf->N - wi;
139 const float cosRO = dot(R, wo);
140
141 const float angle = safe_acosf(fmaxf(cosRO, 0.0f));
142 const float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
143
144 if (angle < sample_angle) {
145 const float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
146 *pdf = M_1_2PI_F / one_minus_cos(sample_angle);
147 return make_spectrum(*pdf * eval);
148 }
149 }
150 *pdf = 0.0f;
151 return zero_spectrum();
152}
153
155 const float3 Ng,
156 const float3 wi,
157 const float2 rand,
158 ccl_private Spectrum *eval,
160 ccl_private float *pdf)
161{
162 const ccl_private ToonBsdf *bsdf = (const ccl_private ToonBsdf *)sc;
163 const float max_angle = bsdf->size;
164 const float smooth = bsdf->smooth;
165 const float cosNI = dot(bsdf->N, wi);
166
167 if (cosNI > 0) {
168 /* reflect the view vector */
169 const float3 R = (2 * cosNI) * bsdf->N - wi;
170
171 const float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
172
173 float cosRO;
174 *wo = sample_uniform_cone(R, one_minus_cos(sample_angle), rand, &cosRO, pdf);
175
176 /* make sure the direction we chose is still in the right hemisphere */
177 if (dot(Ng, *wo) > 0.0f && dot(bsdf->N, *wo) > 0.0f) {
178 const float angle = acosf(cosRO);
179 *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
181 }
182 }
183
184 *pdf = 0.0f;
185 *eval = zero_spectrum();
186 return LABEL_NONE;
187}
188
MINLINE float safe_acosf(float a)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
ccl_device Spectrum bsdf_glossy_toon_eval(const ccl_private ShaderClosure *sc, const float3 wi, const float3 wo, ccl_private float *pdf)
Definition bsdf_toon.h:125
ccl_device float bsdf_toon_get_sample_angle(const float max_angle, const float smooth)
Definition bsdf_toon.h:60
ccl_device int bsdf_diffuse_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:35
ccl_device float bsdf_toon_get_intensity(const float max_angle, const float smooth, const float angle)
Definition bsdf_toon.h:41
ccl_device int bsdf_diffuse_toon_sample(const ccl_private ShaderClosure *sc, const float3 Ng, const float3, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf)
Definition bsdf_toon.h:90
ccl_device int bsdf_glossy_toon_sample(const ccl_private ShaderClosure *sc, const float3 Ng, const float3 wi, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf)
Definition bsdf_toon.h:154
ccl_device_inline int bsdf_toon_setup_common(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:25
ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:119
ccl_device Spectrum bsdf_diffuse_toon_eval(const ccl_private ShaderClosure *sc, const float3, const float3 wo, ccl_private float *pdf)
Definition bsdf_toon.h:65
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define M_PI_2_F
#define zero_spectrum
#define make_spectrum(f)
#define ccl_private
#define ccl_device_inline
#define M_1_2PI_F
#define CCL_NAMESPACE_END
#define saturatef(x)
#define acosf(x)
constexpr T clamp(T, U, U) RET
@ CLOSURE_BSDF_DIFFUSE_TOON_ID
@ CLOSURE_BSDF_GLOSSY_TOON_ID
@ SD_BSDF_HAS_EVAL
@ SD_BSDF
@ LABEL_DIFFUSE
@ LABEL_NONE
@ LABEL_GLOSSY
@ LABEL_REFLECT
ccl_device_inline float one_minus_cos(const float angle)
Definition math_base.h:625
#define R
#define ccl_device
#define fmaxf
#define fminf
ccl_device_inline float3 sample_uniform_cone(const float3 N, const float one_minus_cos_angle, const float2 rand, ccl_private float *cos_theta, ccl_private float *pdf)
float smooth
Definition bsdf_toon.h:20
float size
Definition bsdf_toon.h:19
SHADER_CLOSURE_BASE
Definition bsdf_toon.h:17
float3 Spectrum