Blender  V3.3
bsdf_phong_ramp.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Adapted from Open Shading Language
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011-2022 Blender Foundation. */
8 
9 #pragma once
10 
12 
13 #ifdef __OSL__
14 
15 typedef struct PhongRampBsdf {
17 
18  float exponent;
19  ccl_private float3 *colors;
20 } PhongRampBsdf;
21 
22 static_assert(sizeof(ShaderClosure) >= sizeof(PhongRampBsdf), "PhongRampBsdf is too large!");
23 
24 ccl_device float3 bsdf_phong_ramp_get_color(const float3 colors[8], float pos)
25 {
26  int MAXCOLORS = 8;
27 
28  float npos = pos * (float)(MAXCOLORS - 1);
29  int ipos = float_to_int(npos);
30  if (ipos < 0)
31  return colors[0];
32  if (ipos >= (MAXCOLORS - 1))
33  return colors[MAXCOLORS - 1];
34  float offset = npos - (float)ipos;
35  return colors[ipos] * (1.0f - offset) + colors[ipos + 1] * offset;
36 }
37 
38 ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf)
39 {
40  bsdf->type = CLOSURE_BSDF_PHONG_RAMP_ID;
41  bsdf->exponent = max(bsdf->exponent, 0.0f);
42  return SD_BSDF | SD_BSDF_HAS_EVAL;
43 }
44 
45 ccl_device float3 bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
46  const float3 I,
47  const float3 omega_in,
48  ccl_private float *pdf)
49 {
50  ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
51  float m_exponent = bsdf->exponent;
52  float cosNI = dot(bsdf->N, omega_in);
53  float cosNO = dot(bsdf->N, I);
54 
55  if (cosNI > 0 && cosNO > 0) {
56  // reflect the view vector
57  float3 R = (2 * cosNO) * bsdf->N - I;
58  float cosRI = dot(R, omega_in);
59  if (cosRI > 0) {
60  float cosp = powf(cosRI, m_exponent);
61  float common = 0.5f * M_1_PI_F * cosp;
62  float out = cosNI * (m_exponent + 2) * common;
63  *pdf = (m_exponent + 1) * common;
64  return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
65  }
66  }
67  *pdf = 0.0f;
68  return make_float3(0.0f, 0.0f, 0.0f);
69 }
70 
71 ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
72  const float3 I,
73  const float3 omega_in,
74  ccl_private float *pdf)
75 {
76  *pdf = 0.0f;
77  return make_float3(0.0f, 0.0f, 0.0f);
78 }
79 
80 ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
81  float3 Ng,
82  float3 I,
83  float3 dIdx,
84  float3 dIdy,
85  float randu,
86  float randv,
87  ccl_private float3 *eval,
88  ccl_private float3 *omega_in,
89  ccl_private float3 *domega_in_dx,
90  ccl_private float3 *domega_in_dy,
91  ccl_private float *pdf)
92 {
93  ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
94  float cosNO = dot(bsdf->N, I);
95  float m_exponent = bsdf->exponent;
96 
97  if (cosNO > 0) {
98  // reflect the view vector
99  float3 R = (2 * cosNO) * bsdf->N - I;
100 
101 # ifdef __RAY_DIFFERENTIALS__
102  *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
103  *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
104 # endif
105 
106  float3 T, B;
107  make_orthonormals(R, &T, &B);
108  float phi = M_2PI_F * randu;
109  float cosTheta = powf(randv, 1 / (m_exponent + 1));
110  float sinTheta2 = 1 - cosTheta * cosTheta;
111  float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
112  *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R;
113  if (dot(Ng, *omega_in) > 0.0f) {
114  // common terms for pdf and eval
115  float cosNI = dot(bsdf->N, *omega_in);
116  // make sure the direction we chose is still in the right hemisphere
117  if (cosNI > 0) {
118  float cosp = powf(cosTheta, m_exponent);
119  float common = 0.5f * M_1_PI_F * cosp;
120  *pdf = (m_exponent + 1) * common;
121  float out = cosNI * (m_exponent + 2) * common;
122  *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
123  }
124  }
125  }
126  else {
127  *eval = make_float3(0.0f, 0.0f, 0.0f);
128  *pdf = 0.0f;
129  }
130  return LABEL_REFLECT | LABEL_GLOSSY;
131 }
132 
133 #endif /* __OSL__ */
134 
typedef float(TangentPoint)[2]
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define powf(x, y)
Definition: cuda/compat.h:103
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
uint pos
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
@ CLOSURE_BSDF_PHONG_RAMP_ID
@ SD_BSDF_HAS_EVAL
Definition: kernel/types.h:744
@ SD_BSDF
Definition: kernel/types.h:742
#define SHADER_CLOSURE_BASE
Definition: kernel/types.h:711
#define __RAY_DIFFERENTIALS__
Definition: kernel/types.h:62
@ LABEL_GLOSSY
Definition: kernel/types.h:320
@ LABEL_REFLECT
Definition: kernel/types.h:318
ShaderClosure
Definition: kernel/types.h:726
#define T
#define B
#define R
#define sqrtf(x)
Definition: metal/compat.h:243
#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)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
#define I
float max
ccl_device_inline int float_to_int(float f)
Definition: util/math.h:410
#define M_2PI_F
Definition: util/math.h:60
#define M_1_PI_F
Definition: util/math.h:43
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
Definition: util/math.h:566