Blender V2.61 - r43446

bsdf.h

Go to the documentation of this file.
00001 /* 
00002  * 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 __OSL_BSDF_H__
00034 #define __OSL_BSDF_H__
00035 
00036 CCL_NAMESPACE_BEGIN
00037 
00038 __device float fresnel_dielectric(float eta, const float3 N,
00039         const float3 I, float3 *R, float3 *T,
00040 #ifdef __RAY_DIFFERENTIALS__
00041         const float3 dIdx, const float3 dIdy,
00042         float3 *dRdx, float3 *dRdy,
00043         float3 *dTdx, float3 *dTdy, 
00044 #endif
00045         bool *is_inside)
00046 {
00047     float cos = dot(N, I), neta;
00048     float3 Nn;
00049     // compute reflection
00050     *R =(2 * cos)* N - I;
00051 #ifdef __RAY_DIFFERENTIALS__
00052     *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
00053     *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
00054 #endif
00055     // check which side of the surface we are on
00056     if(cos > 0) {
00057         // we are on the outside of the surface, going in
00058         neta = 1 / eta;
00059         Nn   = N;
00060         *is_inside = false;
00061     } else {
00062         // we are inside the surface, 
00063         cos  = -cos;
00064         neta = eta;
00065         Nn   = -N;
00066         *is_inside = true;
00067     }
00068     *R =(2 * cos)* Nn - I;
00069     float arg = 1 -(neta * neta *(1 -(cos * cos)));
00070     if(arg < 0) {
00071         *T= make_float3(0.0f, 0.0f, 0.0f);
00072 #ifdef __RAY_DIFFERENTIALS__
00073         *dTdx= make_float3(0.0f, 0.0f, 0.0f);
00074         *dTdy= make_float3(0.0f, 0.0f, 0.0f);
00075 #endif
00076         return 1; // total internal reflection
00077     } else {
00078         float dnp = sqrtf(arg);
00079         float nK =(neta * cos)- dnp;
00080         *T = -(neta * I)+(nK * Nn);
00081 #ifdef __RAY_DIFFERENTIALS__
00082         *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
00083         *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
00084 #endif
00085         // compute Fresnel terms
00086         float cosTheta1 = cos; // N.R
00087         float cosTheta2 = -dot(Nn, *T);
00088         float pPara =(cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
00089         float pPerp =(eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
00090         return 0.5f * (pPara * pPara + pPerp * pPerp);
00091     }
00092 }
00093 
00094 __device float fresnel_dielectric_cos(float cosi, float eta)
00095 {
00096     // compute fresnel reflectance without explicitly computing
00097     // the refracted direction
00098     float c = fabsf(cosi);
00099     float g = eta * eta - 1 + c * c;
00100     if(g > 0) {
00101         g = sqrtf(g);
00102         float A =(g - c)/(g + c);
00103         float B =(c *(g + c)- 1)/(c *(g - c)+ 1);
00104         return 0.5f * A * A *(1 + B * B);
00105     }
00106     return 1.0f; // TIR(no refracted component)
00107 }
00108 
00109 __device float fresnel_conductor(float cosi, float eta, float k)
00110 {
00111     float tmp_f = eta * eta + k * k;
00112     float tmp = tmp_f * cosi * cosi;
00113     float Rparl2 =(tmp -(2.0f * eta * cosi)+ 1)/
00114                  (tmp +(2.0f * eta * cosi)+ 1);
00115     float Rperp2 =(tmp_f -(2.0f * eta * cosi)+ cosi * cosi)/
00116                  (tmp_f +(2.0f * eta * cosi)+ cosi * cosi);
00117     return(Rparl2 + Rperp2) * 0.5f;
00118 }
00119 
00120 __device float smooth_step(float edge0, float edge1, float x)
00121 {
00122     float result;
00123     if(x < edge0) result = 0.0f;
00124     else if(x >= edge1) result = 1.0f;
00125     else {
00126         float t = (x - edge0)/(edge1 - edge0);
00127         result = (3.0f-2.0f*t)*(t*t);
00128     }
00129     return result;
00130 }
00131 
00132 CCL_NAMESPACE_END
00133 
00134 #endif /* __OSL_BSDF_H__ */
00135