~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/cycles/kernel/closure/bsdf_ward.h

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 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 __BSDF_WARD_H__
 
34
#define __BSDF_WARD_H__
 
35
 
 
36
CCL_NAMESPACE_BEGIN
 
37
 
 
38
/* WARD */
 
39
 
 
40
__device int bsdf_ward_setup(ShaderClosure *sc)
 
41
{
 
42
        float ax = sc->data0;
 
43
        float ay = sc->data1;
 
44
 
 
45
        float m_ax = clamp(ax, 1e-4f, 1.0f);
 
46
        float m_ay = clamp(ay, 1e-4f, 1.0f);
 
47
 
 
48
        sc->data0 = m_ax;
 
49
        sc->data1 = m_ay;
 
50
 
 
51
        sc->type = CLOSURE_BSDF_WARD_ID;
 
52
        return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
 
53
}
 
54
 
 
55
__device void bsdf_ward_blur(ShaderClosure *sc, float roughness)
 
56
{
 
57
        sc->data0 = fmaxf(roughness, sc->data0);
 
58
        sc->data1 = fmaxf(roughness, sc->data1);
 
59
}
 
60
 
 
61
__device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
 
62
{
 
63
        float m_ax = sc->data0;
 
64
        float m_ay = sc->data1;
 
65
        float3 N = sc->N;
 
66
        float3 T = sc->T;
 
67
 
 
68
        float cosNO = dot(N, I);
 
69
        float cosNI = dot(N, omega_in);
 
70
 
 
71
        if(cosNI > 0.0f && cosNO > 0.0f) {
 
72
                cosNO = max(cosNO, 1e-4f);
 
73
                cosNI = max(cosNI, 1e-4f);
 
74
 
 
75
                // get half vector and get x,y basis on the surface for anisotropy
 
76
                float3 H = normalize(omega_in + I); // normalize needed for pdf
 
77
                float3 X, Y;
 
78
                make_orthonormals_tangent(N, T, &X, &Y);
 
79
                // eq. 4
 
80
                float dotx = dot(H, X) / m_ax;
 
81
                float doty = dot(H, Y) / m_ay;
 
82
                float dotn = dot(H, N);
 
83
                float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
 
84
                float denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
 
85
                float exp_val = expf(-exp_arg);
 
86
                float out = cosNI * exp_val / denom;
 
87
                float oh = dot(H, I);
 
88
                denom = 4 * M_PI_F * m_ax * m_ay * oh * dotn * dotn * dotn;
 
89
                *pdf = exp_val / denom;
 
90
                return make_float3 (out, out, out);
 
91
        }
 
92
 
 
93
        return make_float3 (0, 0, 0);
 
94
}
 
95
 
 
96
__device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
 
97
{
 
98
        return make_float3(0.0f, 0.0f, 0.0f);
 
99
}
 
100
 
 
101
__device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
 
102
{
 
103
        float m_ax = sc->data0;
 
104
        float m_ay = sc->data1;
 
105
        float3 N = sc->N;
 
106
        float3 T = sc->T;
 
107
 
 
108
        float cosNO = dot(N, I);
 
109
        if(cosNO > 0.0f) {
 
110
                // get x,y basis on the surface for anisotropy
 
111
                float3 X, Y;
 
112
                make_orthonormals_tangent(N, T, &X, &Y);
 
113
                // generate random angles for the half vector
 
114
                // eq. 7 (taking care around discontinuities to keep
 
115
                //ttoutput angle in the right quadrant)
 
116
                // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
 
117
                //tttt  and sin(atan(x)) == x/sqrt(1+x^2)
 
118
                float alphaRatio = m_ay / m_ax;
 
119
                float cosPhi, sinPhi;
 
120
                if(randu < 0.25f) {
 
121
                        float val = 4 * randu;
 
122
                        float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
 
123
                        cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
 
124
                        sinPhi = tanPhi * cosPhi;
 
125
                }
 
126
                else if(randu < 0.5f) {
 
127
                        float val = 1 - 4 * (0.5f - randu);
 
128
                        float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
 
129
                        // phi = M_PI_F - phi;
 
130
                        cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
 
131
                        sinPhi = -tanPhi * cosPhi;
 
132
                }
 
133
                else if(randu < 0.75f) {
 
134
                        float val = 4 * (randu - 0.5f);
 
135
                        float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
 
136
                        //phi = M_PI_F + phi;
 
137
                        cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
 
138
                        sinPhi = tanPhi * cosPhi;
 
139
                }
 
140
                else {
 
141
                        float val = 1 - 4 * (1 - randu);
 
142
                        float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
 
143
                        // phi = 2 * M_PI_F - phi;
 
144
                        cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
 
145
                        sinPhi = -tanPhi * cosPhi;
 
146
                }
 
147
                // eq. 6
 
148
                // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
 
149
                //tttt  and sin(atan(x)) == x/sqrt(1+x^2)
 
150
                float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay);
 
151
                float tanTheta2 = -logf(1 - randv) / thetaDenom;
 
152
                float cosTheta  = 1 / sqrtf(1 + tanTheta2);
 
153
                float sinTheta  = cosTheta * sqrtf(tanTheta2);
 
154
 
 
155
                float3 h; // already normalized becaused expressed from spherical coordinates
 
156
                h.x = sinTheta * cosPhi;
 
157
                h.y = sinTheta * sinPhi;
 
158
                h.z = cosTheta;
 
159
                // compute terms that are easier in local space
 
160
                float dotx = h.x / m_ax;
 
161
                float doty = h.y / m_ay;
 
162
                float dotn = h.z;
 
163
                // transform to world space
 
164
                h = h.x * X + h.y * Y + h.z * N;
 
165
                // generate the final sample
 
166
                float oh = dot(h, I);
 
167
                *omega_in = 2.0f * oh * h - I;
 
168
                if(dot(Ng, *omega_in) > 0) {
 
169
                        float cosNI = dot(N, *omega_in);
 
170
                        if(cosNI > 0) {
 
171
                                cosNO = max(cosNO, 1e-4f);
 
172
                                cosNI = max(cosNI, 1e-4f);
 
173
 
 
174
                                // eq. 9
 
175
                                float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
 
176
                                float denom = 4 * M_PI_F * m_ax * m_ay * oh * dotn * dotn * dotn;
 
177
                                *pdf = expf(-exp_arg) / denom;
 
178
                                // compiler will reuse expressions already computed
 
179
                                denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
 
180
                                float power = cosNI * expf(-exp_arg) / denom;
 
181
                                *eval = make_float3(power, power, power);
 
182
#ifdef __RAY_DIFFERENTIALS__
 
183
                                *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
 
184
                                *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
 
185
#endif
 
186
                        }
 
187
                }
 
188
        }
 
189
        return LABEL_REFLECT|LABEL_GLOSSY;
 
190
}
 
191
 
 
192
CCL_NAMESPACE_END
 
193
 
 
194
#endif /* __BSDF_WARD_H__ */
 
195