diff options
author | Ton Roosendaal <ton@blender.org> | 2011-04-27 15:58:34 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2011-04-27 15:58:34 +0400 |
commit | da376e0237517543aa21740ee2363234ee1c20ae (patch) | |
tree | 014a513ed8d0eccc5e54fef42347781e85bae56a /intern/cycles/kernel/kernel_montecarlo.h | |
parent | 693780074388111e7b9ef1c3825e462f398dc6c4 (diff) |
Cycles render engine, initial commit. This is the engine itself, blender modifications and build instructions will follow later.
Cycles uses code from some great open source projects, many thanks them:
* BVH building and traversal code from NVidia's "Understanding the Efficiency of Ray Traversal on GPUs":
http://code.google.com/p/understanding-the-efficiency-of-ray-traversal-on-gpus/
* Open Shading Language for a large part of the shading system:
http://code.google.com/p/openshadinglanguage/
* Blender for procedural textures and a few other nodes.
* Approximate Catmull Clark subdivision from NVidia Mesh tools:
http://code.google.com/p/nvidia-mesh-tools/
* Sobol direction vectors from:
http://web.maths.unsw.edu.au/~fkuo/sobol/
* Film response functions from:
http://www.cs.columbia.edu/CAVE/software/softlib/dorf.php
Diffstat (limited to 'intern/cycles/kernel/kernel_montecarlo.h')
-rw-r--r-- | intern/cycles/kernel/kernel_montecarlo.h | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h new file mode 100644 index 00000000000..6f3a3dd3421 --- /dev/null +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -0,0 +1,196 @@ +/* + * Parts adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __KERNEL_MONTECARLO_CL__ +#define __KERNEL_MONTECARLO_CL__ + +CCL_NAMESPACE_BEGIN + +/// Given values x and y on [0,1], convert them in place to values on +/// [-1,1] uniformly distributed over a unit sphere. This code is +/// derived from Peter Shirley, "Realistic Ray Tracing", p. 103. +__device void to_unit_disk(float *x, float *y) +{ + float r, phi; + float a = 2.0f * (*x) - 1.0f; + float b = 2.0f * (*y) - 1.0f; + if(a > -b) { + if(a > b) { + r = a; + phi = M_PI_4_F *(b/a); + } else { + r = b; + phi = M_PI_4_F *(2.0f - a/b); + } + } else { + if(a < b) { + r = -a; + phi = M_PI_4_F *(4.0f + b/a); + } else { + r = -b; + if(b != 0.0f) + phi = M_PI_4_F *(6.0f - a/b); + else + phi = 0.0f; + } + } + *x = r * cosf(phi); + *y = r * sinf(phi); +} + +__device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b) +{ + if(N.x != N.y || N.x != N.z) + *a = make_float3(N.z-N.y, N.x-N.z, N.y-N.x); //(1,1,1)x N + else + *a = make_float3(N.z-N.y, N.x+N.z, -N.y-N.x); //(-1,1,1)x N + + *a = normalize(*a); + *b = cross(N, *a); +} + +__device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b) +{ + *b = cross(N, T); + *a = cross(*b, N); +} + +__device_inline void sample_cos_hemisphere(const float3 N, + float randu, float randv, float3 *omega_in, float *pdf) +{ + // Default closure BSDF implementation: uniformly sample + // cosine-weighted hemisphere above the point. + to_unit_disk(&randu, &randv); + float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f)); + float3 T, B; + make_orthonormals(N, &T, &B); + *omega_in = randu * T + randv * B + costheta * N; + *pdf = costheta *M_1_PI_F; +} + +__device_inline void sample_uniform_hemisphere(const float3 N, + float randu, float randv, + float3 *omega_in, float *pdf) +{ + float z = randu; + float r = sqrtf(max(0.f, 1.f - z*z)); + float phi = 2.f * M_PI_F * randv; + float x = r * cosf(phi); + float y = r * sinf(phi); + + float3 T, B; + make_orthonormals (N, &T, &B); + *omega_in = x * T + y * B + z * N; + *pdf = 0.5f * M_1_PI_F; +} + +__device float3 sample_uniform_sphere(float u1, float u2) +{ + float z = 1.0f - 2.0f*u1; + float r = sqrtf(fmaxf(0.0f, 1.0f - z*z)); + float phi = 2.0f*M_PI_F*u2; + float x = r*cosf(phi); + float y = r*sinf(phi); + + return make_float3(x, y, z); +} + +__device float power_heuristic(float a, float b) +{ + return (a*a)/(a*a + b*b); +} + +__device float2 concentric_sample_disk(float u1, float u2) +{ + float r, theta; + // Map uniform random numbers to $[-1,1]^2$ + float sx = 2 * u1 - 1; + float sy = 2 * u2 - 1; + + // Map square to $(r,\theta)$ + + // Handle degeneracy at the origin + if(sx == 0.0f && sy == 0.0f) { + return make_float2(0.0f, 0.0f); + } + if(sx >= -sy) { + if(sx > sy) { + // Handle first region of disk + r = sx; + if(sy > 0.0f) theta = sy/r; + else theta = 8.0f + sy/r; + } + else { + // Handle second region of disk + r = sy; + theta = 2.0f - sx/r; + } + } + else { + if(sx <= sy) { + // Handle third region of disk + r = -sx; + theta = 4.0f - sy/r; + } + else { + // Handle fourth region of disk + r = -sy; + theta = 6.0f + sx/r; + } + } + + theta *= M_PI_4_F; + return make_float2(r * cosf(theta), r * sinf(theta)); +} + +/* Spherical coordinates <-> Cartesion direction */ + +__device float2 direction_to_spherical(float3 dir) +{ + float theta = acosf(dir.z); + float phi = atan2f(dir.x, dir.y); + + return make_float2(theta, phi); +} + +__device float3 spherical_to_direction(float theta, float phi) +{ + return make_float3( + sinf(theta)*cosf(phi), + sinf(theta)*sinf(phi), + cosf(theta)); +} + +CCL_NAMESPACE_END + +#endif /* __KERNEL_MONTECARLO_CL__ */ + |