2 * Copyright 2011-2016 Blender Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* Evaluate the BSDF from wi to wo.
18 * Evaluation is split into the analytical single-scattering BSDF and the multi-scattering BSDF,
19 * which is evaluated stochastically through a random walk. At each bounce (except for the first one),
20 * the amount of reflection from here towards wo is evaluated before bouncing again.
22 * Because of the random walk, the evaluation is not deterministic, but its expected value is equal to
23 * the correct BSDF, which is enough for Monte-Carlo rendering. The PDF also can't be determined
24 * analytically, so the single-scattering PDF plus a diffuse term to account for the multi-scattered
25 * energy is used. In combination with MIS, that is enough to produce an unbiased result, although
26 * the balance heuristic isn't necessarily optimal anymore.
28 ccl_device float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, float3 wo, const bool wo_outside, const float3 color, const float alpha_x, const float alpha_y, ccl_addr_space uint* lcg_state
31 #elif defined(MF_MULTI_GLOSSY)
32 , float3 *n, float3 *k
36 /* Evaluating for a shallower incoming direction produces less noise, and the properties of the BSDF guarantee reciprocity. */
39 if(wi.z*wo.z < 0.0f) {
40 /* Glass transmission is a special case and requires the directions to change hemisphere. */
57 if(wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside))
58 return make_float3(0.0f, 0.0f, 0.0f);
60 const float2 alpha = make_float2(alpha_x, alpha_y);
62 float lambda_r = mf_lambda(-wi, alpha);
63 float shadowing_lambda = mf_lambda(wo_outside? wo: -wo, alpha);
65 /* Analytically compute single scattering for lower noise. */
68 eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
70 eval *= -lambda_r / (shadowing_lambda - lambda_r);
72 eval *= -lambda_r * beta(-lambda_r, shadowing_lambda+1.0f);
73 #elif defined(MF_MULTI_DIFFUSE)
74 /* Diffuse has no special closed form for the single scattering bounce */
75 eval = make_float3(0.0f, 0.0f, 0.0f);
76 #else /* MF_MULTI_GLOSSY */
77 const float3 wh = normalize(wi+wo);
78 const float G2 = 1.0f / (1.0f - (lambda_r + 1.0f) + shadowing_lambda);
79 float val = G2 * 0.25f / wi.z;
80 if(alpha.x == alpha.y)
81 val *= D_ggx(wh, alpha.x);
83 val *= D_ggx_aniso(wh, alpha);
85 eval = fresnel_conductor(dot(wh, wi), *n, *k) * val;
88 eval = make_float3(val, val, val);
97 float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
99 for(int order = 0; order < 10; order++) {
100 /* Sample microfacet height and normal */
101 if(!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, lcg_step_float_addrspace(lcg_state)))
103 float3 wm = mf_sample_vndf(-wr, alpha, make_float2(lcg_step_float_addrspace(lcg_state),
104 lcg_step_float_addrspace(lcg_state)));
106 #ifdef MF_MULTI_DIFFUSE
108 /* Compute single-scattering for diffuse. */
109 const float G2_G1 = -lambda_r / (shadowing_lambda - lambda_r);
110 eval += throughput * G2_G1 * mf_eval_phase_diffuse(wo, wm);
114 /* Evaluate amount of scattering towards wo on this microfacet. */
116 #ifdef MF_MULTI_GLASS
118 phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
120 phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f/eta);
121 #elif defined(MF_MULTI_DIFFUSE)
122 phase = mf_eval_phase_diffuse(wo, wm);
123 #else /* MF_MULTI_GLOSSY */
124 phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha, n, k) * throughput;
126 eval += throughput * phase * mf_G1(wo_outside? wo: -wo, mf_C1((outside == wo_outside)? hr: -hr), shadowing_lambda);
129 /* Bounce from the microfacet. */
130 #ifdef MF_MULTI_GLASS
132 wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, lcg_step_float_addrspace(lcg_state), &next_outside);
138 #elif defined(MF_MULTI_DIFFUSE)
139 wr = mf_sample_phase_diffuse(wm,
140 lcg_step_float_addrspace(lcg_state),
141 lcg_step_float_addrspace(lcg_state));
142 #else /* MF_MULTI_GLOSSY */
143 wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
146 lambda_r = mf_lambda(wr, alpha);
151 G1_r = mf_G1(wr, C1_r, lambda_r);
156 eval *= fabsf(wi.z / wo.z);
160 /* Perform a random walk on the microsurface starting from wi, returning the direction in which the walk
161 * escaped the surface in wo. The function returns the throughput between wi and wo.
162 * Without reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal.
164 ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const float3 color, const float alpha_x, const float alpha_y, ccl_addr_space uint *lcg_state
165 #ifdef MF_MULTI_GLASS
167 #elif defined(MF_MULTI_GLOSSY)
168 , float3 *n, float3 *k
172 const float2 alpha = make_float2(alpha_x, alpha_y);
174 float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
176 float lambda_r = mf_lambda(wr, alpha);
183 for(order = 0; order < 10; order++) {
184 /* Sample microfacet height. */
185 if(!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, lcg_step_float_addrspace(lcg_state))) {
186 /* The random walk has left the surface. */
187 *wo = outside? wr: -wr;
190 /* Sample microfacet normal. */
191 float3 wm = mf_sample_vndf(-wr, alpha, make_float2(lcg_step_float_addrspace(lcg_state),
192 lcg_step_float_addrspace(lcg_state)));
194 /* First-bounce color is already accounted for in mix weight. */
198 /* Bounce from the microfacet. */
199 #ifdef MF_MULTI_GLASS
201 wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, lcg_step_float_addrspace(lcg_state), &next_outside);
207 #elif defined(MF_MULTI_DIFFUSE)
208 wr = mf_sample_phase_diffuse(wm,
209 lcg_step_float_addrspace(lcg_state),
210 lcg_step_float_addrspace(lcg_state));
211 #else /* MF_MULTI_GLOSSY */
212 wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
215 /* Update random walk parameters. */
216 lambda_r = mf_lambda(wr, alpha);
217 G1_r = mf_G1(wr, C1_r, lambda_r);
219 *wo = make_float3(0.0f, 0.0f, 1.0f);
220 return make_float3(0.0f, 0.0f, 0.0f);
223 #undef MF_MULTI_GLASS
224 #undef MF_MULTI_DIFFUSE
225 #undef MF_MULTI_GLOSSY
226 #undef MF_PHASE_FUNCTION