Blender V2.61 - r43446
|
00001 /* 00002 * Parts adapted from Open Shading Language with this license: 00003 * 00004 * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 00005 * All Rights Reserved. 00006 * 00007 * Modifications Copyright 2011, Blender Foundation. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions are 00011 * met: 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the distribution. 00017 * * Neither the name of Sony Pictures Imageworks nor the names of its 00018 * contributors may be used to endorse or promote products derived from 00019 * this software without specific prior written permission. 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00024 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00028 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00030 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifndef __KERNEL_MONTECARLO_CL__ 00034 #define __KERNEL_MONTECARLO_CL__ 00035 00036 CCL_NAMESPACE_BEGIN 00037 00041 __device void to_unit_disk(float *x, float *y) 00042 { 00043 float r, phi; 00044 float a = 2.0f * (*x) - 1.0f; 00045 float b = 2.0f * (*y) - 1.0f; 00046 if(a > -b) { 00047 if(a > b) { 00048 r = a; 00049 phi = M_PI_4_F *(b/a); 00050 } else { 00051 r = b; 00052 phi = M_PI_4_F *(2.0f - a/b); 00053 } 00054 } else { 00055 if(a < b) { 00056 r = -a; 00057 phi = M_PI_4_F *(4.0f + b/a); 00058 } else { 00059 r = -b; 00060 if(b != 0.0f) 00061 phi = M_PI_4_F *(6.0f - a/b); 00062 else 00063 phi = 0.0f; 00064 } 00065 } 00066 *x = r * cosf(phi); 00067 *y = r * sinf(phi); 00068 } 00069 00070 __device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b) 00071 { 00072 *b = cross(N, T); 00073 *a = cross(*b, N); 00074 } 00075 00076 __device_inline void sample_cos_hemisphere(const float3 N, 00077 float randu, float randv, float3 *omega_in, float *pdf) 00078 { 00079 // Default closure BSDF implementation: uniformly sample 00080 // cosine-weighted hemisphere above the point. 00081 to_unit_disk(&randu, &randv); 00082 float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f)); 00083 float3 T, B; 00084 make_orthonormals(N, &T, &B); 00085 *omega_in = randu * T + randv * B + costheta * N; 00086 *pdf = costheta *M_1_PI_F; 00087 } 00088 00089 __device_inline void sample_uniform_hemisphere(const float3 N, 00090 float randu, float randv, 00091 float3 *omega_in, float *pdf) 00092 { 00093 float z = randu; 00094 float r = sqrtf(max(0.f, 1.f - z*z)); 00095 float phi = 2.f * M_PI_F * randv; 00096 float x = r * cosf(phi); 00097 float y = r * sinf(phi); 00098 00099 float3 T, B; 00100 make_orthonormals (N, &T, &B); 00101 *omega_in = x * T + y * B + z * N; 00102 *pdf = 0.5f * M_1_PI_F; 00103 } 00104 00105 __device float3 sample_uniform_sphere(float u1, float u2) 00106 { 00107 float z = 1.0f - 2.0f*u1; 00108 float r = sqrtf(fmaxf(0.0f, 1.0f - z*z)); 00109 float phi = 2.0f*M_PI_F*u2; 00110 float x = r*cosf(phi); 00111 float y = r*sinf(phi); 00112 00113 return make_float3(x, y, z); 00114 } 00115 00116 __device float power_heuristic(float a, float b) 00117 { 00118 return (a*a)/(a*a + b*b); 00119 } 00120 00121 __device float2 concentric_sample_disk(float u1, float u2) 00122 { 00123 float r, theta; 00124 // Map uniform random numbers to $[-1,1]^2$ 00125 float sx = 2 * u1 - 1; 00126 float sy = 2 * u2 - 1; 00127 00128 // Map square to $(r,\theta)$ 00129 00130 // Handle degeneracy at the origin 00131 if(sx == 0.0f && sy == 0.0f) { 00132 return make_float2(0.0f, 0.0f); 00133 } 00134 if(sx >= -sy) { 00135 if(sx > sy) { 00136 // Handle first region of disk 00137 r = sx; 00138 if(sy > 0.0f) theta = sy/r; 00139 else theta = 8.0f + sy/r; 00140 } 00141 else { 00142 // Handle second region of disk 00143 r = sy; 00144 theta = 2.0f - sx/r; 00145 } 00146 } 00147 else { 00148 if(sx <= sy) { 00149 // Handle third region of disk 00150 r = -sx; 00151 theta = 4.0f - sy/r; 00152 } 00153 else { 00154 // Handle fourth region of disk 00155 r = -sy; 00156 theta = 6.0f + sx/r; 00157 } 00158 } 00159 00160 theta *= M_PI_4_F; 00161 return make_float2(r * cosf(theta), r * sinf(theta)); 00162 } 00163 00164 __device float2 regular_polygon_sample(float corners, float rotation, float u, float v) 00165 { 00166 /* sample corner number and reuse u */ 00167 float corner = floorf(u*corners); 00168 u = u*corners - corner; 00169 00170 /* uniform sampled triangle weights */ 00171 u = sqrtf(u); 00172 v = v*u; 00173 u = 1.0f - u; 00174 00175 /* point in triangle */ 00176 float angle = M_PI_F/corners; 00177 float2 p = make_float2((u + v)*cosf(angle), (u - v)*sinf(angle)); 00178 00179 /* rotate */ 00180 rotation += corner*2.0f*angle; 00181 00182 float cr = cosf(rotation); 00183 float sr = sinf(rotation); 00184 00185 return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y); 00186 } 00187 00188 /* Spherical coordinates <-> Cartesion direction */ 00189 00190 __device float2 direction_to_spherical(float3 dir) 00191 { 00192 float theta = acosf(dir.z); 00193 float phi = atan2f(dir.x, dir.y); 00194 00195 return make_float2(theta, phi); 00196 } 00197 00198 __device float3 spherical_to_direction(float theta, float phi) 00199 { 00200 return make_float3( 00201 sinf(theta)*cosf(phi), 00202 sinf(theta)*sinf(phi), 00203 cosf(theta)); 00204 } 00205 00206 CCL_NAMESPACE_END 00207 00208 #endif /* __KERNEL_MONTECARLO_CL__ */ 00209