Blender V2.61 - r43446
|
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