Geometry Nodes: Expose texture and material inputs to modifier
[blender.git] / intern / cycles / kernel / kernel_montecarlo.h
1 /*
2  * Parts adapted from Open Shading Language with this license:
3  *
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011, Blender Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  * * Redistributions of source code must retain the above copyright
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in the
16  *   documentation and/or other materials provided with the distribution.
17  * * Neither the name of Sony Pictures Imageworks nor the names of its
18  *   contributors may be used to endorse or promote products derived from
19  *   this software without specific prior written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef __KERNEL_MONTECARLO_CL__
34 #define __KERNEL_MONTECARLO_CL__
35
36 CCL_NAMESPACE_BEGIN
37
38 /* distribute uniform xy on [0,1] over unit disk [-1,1] */
39 ccl_device void to_unit_disk(float *x, float *y)
40 {
41   float phi = M_2PI_F * (*x);
42   float r = sqrtf(*y);
43
44   *x = r * cosf(phi);
45   *y = r * sinf(phi);
46 }
47
48 /* return an orthogonal tangent and bitangent given a normal and tangent that
49  * may not be exactly orthogonal */
50 ccl_device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b)
51 {
52   *b = normalize(cross(N, T));
53   *a = cross(*b, N);
54 }
55
56 /* sample direction with cosine weighted distributed in hemisphere */
57 ccl_device_inline void sample_cos_hemisphere(
58     const float3 N, float randu, float randv, float3 *omega_in, float *pdf)
59 {
60   to_unit_disk(&randu, &randv);
61   float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f));
62   float3 T, B;
63   make_orthonormals(N, &T, &B);
64   *omega_in = randu * T + randv * B + costheta * N;
65   *pdf = costheta * M_1_PI_F;
66 }
67
68 /* sample direction uniformly distributed in hemisphere */
69 ccl_device_inline void sample_uniform_hemisphere(
70     const float3 N, float randu, float randv, float3 *omega_in, float *pdf)
71 {
72   float z = randu;
73   float r = sqrtf(max(0.0f, 1.0f - z * z));
74   float phi = M_2PI_F * randv;
75   float x = r * cosf(phi);
76   float y = r * sinf(phi);
77
78   float3 T, B;
79   make_orthonormals(N, &T, &B);
80   *omega_in = x * T + y * B + z * N;
81   *pdf = 0.5f * M_1_PI_F;
82 }
83
84 /* sample direction uniformly distributed in cone */
85 ccl_device_inline void sample_uniform_cone(
86     const float3 N, float angle, float randu, float randv, float3 *omega_in, float *pdf)
87 {
88   float zMin = cosf(angle);
89   float z = zMin - zMin * randu + randu;
90   float r = safe_sqrtf(1.0f - sqr(z));
91   float phi = M_2PI_F * randv;
92   float x = r * cosf(phi);
93   float y = r * sinf(phi);
94
95   float3 T, B;
96   make_orthonormals(N, &T, &B);
97   *omega_in = x * T + y * B + z * N;
98   *pdf = M_1_2PI_F / (1.0f - zMin);
99 }
100
101 ccl_device_inline float pdf_uniform_cone(const float3 N, float3 D, float angle)
102 {
103   float zMin = cosf(angle);
104   float z = dot(N, D);
105   if (z > zMin) {
106     return M_1_2PI_F / (1.0f - zMin);
107   }
108   return 0.0f;
109 }
110
111 /* sample uniform point on the surface of a sphere */
112 ccl_device float3 sample_uniform_sphere(float u1, float u2)
113 {
114   float z = 1.0f - 2.0f * u1;
115   float r = sqrtf(fmaxf(0.0f, 1.0f - z * z));
116   float phi = M_2PI_F * u2;
117   float x = r * cosf(phi);
118   float y = r * sinf(phi);
119
120   return make_float3(x, y, z);
121 }
122
123 ccl_device float balance_heuristic(float a, float b)
124 {
125   return (a) / (a + b);
126 }
127
128 ccl_device float balance_heuristic_3(float a, float b, float c)
129 {
130   return (a) / (a + b + c);
131 }
132
133 ccl_device float power_heuristic(float a, float b)
134 {
135   return (a * a) / (a * a + b * b);
136 }
137
138 ccl_device float power_heuristic_3(float a, float b, float c)
139 {
140   return (a * a) / (a * a + b * b + c * c);
141 }
142
143 ccl_device float max_heuristic(float a, float b)
144 {
145   return (a > b) ? 1.0f : 0.0f;
146 }
147
148 /* distribute uniform xy on [0,1] over unit disk [-1,1], with concentric mapping
149  * to better preserve stratification for some RNG sequences */
150 ccl_device float2 concentric_sample_disk(float u1, float u2)
151 {
152   float phi, r;
153   float a = 2.0f * u1 - 1.0f;
154   float b = 2.0f * u2 - 1.0f;
155
156   if (a == 0.0f && b == 0.0f) {
157     return zero_float2();
158   }
159   else if (a * a > b * b) {
160     r = a;
161     phi = M_PI_4_F * (b / a);
162   }
163   else {
164     r = b;
165     phi = M_PI_2_F - M_PI_4_F * (a / b);
166   }
167
168   return make_float2(r * cosf(phi), r * sinf(phi));
169 }
170
171 /* sample point in unit polygon with given number of corners and rotation */
172 ccl_device float2 regular_polygon_sample(float corners, float rotation, float u, float v)
173 {
174   /* sample corner number and reuse u */
175   float corner = floorf(u * corners);
176   u = u * corners - corner;
177
178   /* uniform sampled triangle weights */
179   u = sqrtf(u);
180   v = v * u;
181   u = 1.0f - u;
182
183   /* point in triangle */
184   float angle = M_PI_F / corners;
185   float2 p = make_float2((u + v) * cosf(angle), (u - v) * sinf(angle));
186
187   /* rotate */
188   rotation += corner * 2.0f * angle;
189
190   float cr = cosf(rotation);
191   float sr = sinf(rotation);
192
193   return make_float2(cr * p.x - sr * p.y, sr * p.x + cr * p.y);
194 }
195
196 ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
197 {
198   float3 R;
199   float NI = dot(N, I);
200   float NgR, threshold;
201
202   /* Check if the incident ray is coming from behind normal N. */
203   if (NI > 0) {
204     /* Normal reflection */
205     R = (2 * NI) * N - I;
206     NgR = dot(Ng, R);
207
208     /* Reflection rays may always be at least as shallow as the incoming ray. */
209     threshold = min(0.9f * dot(Ng, I), 0.01f);
210     if (NgR >= threshold) {
211       return N;
212     }
213   }
214   else {
215     /* Bad incident */
216     R = -I;
217     NgR = dot(Ng, R);
218     threshold = 0.01f;
219   }
220
221   R = R + Ng * (threshold - NgR);            /* Lift the reflection above the threshold. */
222   return normalize(I * len(R) + R * len(I)); /* Find a bisector. */
223 }
224
225 CCL_NAMESPACE_END
226
227 #endif /* __KERNEL_MONTECARLO_CL__ */