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 __BSDF_WESTIN_H__ 00034 #define __BSDF_WESTIN_H__ 00035 00036 CCL_NAMESPACE_BEGIN 00037 00038 /* WESTIN BACKSCATTER */ 00039 00040 typedef struct BsdfWestinBackscatterClosure { 00041 //float3 m_N; 00042 float m_invroughness; 00043 } BsdfWestinBackscatterClosure; 00044 00045 __device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness) 00046 { 00047 roughness = clamp(roughness, 1e-5f, 1.0f); 00048 float m_invroughness = 1.0f/roughness; 00049 00050 sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID; 00051 sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; 00052 sc->data0 = m_invroughness; 00053 } 00054 00055 __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) 00056 { 00057 float m_invroughness = sc->data0; 00058 m_invroughness = min(1.0f/roughness, m_invroughness); 00059 sc->data0 = m_invroughness; 00060 } 00061 00062 __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) 00063 { 00064 float m_invroughness = sc->data0; 00065 float3 m_N = sd->N; 00066 00067 // pdf is implicitly 0 (no indirect sampling) 00068 float cosNO = dot(m_N, I); 00069 float cosNI = dot(m_N, omega_in); 00070 if(cosNO > 0 && cosNI > 0) { 00071 float cosine = dot(I, omega_in); 00072 *pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; 00073 *pdf *= 0.5f * M_1_PI_F; 00074 return make_float3 (*pdf, *pdf, *pdf); 00075 } 00076 return make_float3 (0, 0, 0); 00077 } 00078 00079 __device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) 00080 { 00081 return make_float3(0.0f, 0.0f, 0.0f); 00082 } 00083 00084 __device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) 00085 { 00086 return 1.0f; 00087 } 00088 00089 __device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) 00090 { 00091 float m_invroughness = sc->data0; 00092 float3 m_N = sd->N; 00093 00094 float cosNO = dot(m_N, sd->I); 00095 if(cosNO > 0) { 00096 #ifdef __RAY_DIFFERENTIALS__ 00097 *domega_in_dx = sd->dI.dx; 00098 *domega_in_dy = sd->dI.dy; 00099 #endif 00100 float3 T, B; 00101 make_orthonormals (sd->I, &T, &B); 00102 float phi = 2 * M_PI_F * randu; 00103 float cosTheta = powf(randv, 1 / (m_invroughness + 1)); 00104 float sinTheta2 = 1 - cosTheta * cosTheta; 00105 float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; 00106 *omega_in = (cosf(phi) * sinTheta) * T + 00107 (sinf(phi) * sinTheta) * B + 00108 (cosTheta) * sd->I; 00109 if(dot(sd->Ng, *omega_in) > 0) 00110 { 00111 // common terms for pdf and eval 00112 float cosNI = dot(m_N, *omega_in); 00113 // make sure the direction we chose is still in the right hemisphere 00114 if(cosNI > 0) 00115 { 00116 *pdf = 0.5f * M_1_PI_F * powf(cosTheta, m_invroughness); 00117 *pdf = (m_invroughness + 1) * (*pdf); 00118 *eval = make_float3(*pdf, *pdf, *pdf); 00119 #ifdef __RAY_DIFFERENTIALS__ 00120 // Since there is some blur to this reflection, make the 00121 // derivatives a bit bigger. In theory this varies with the 00122 // exponent but the exact relationship is complex and 00123 // requires more ops than are practical. 00124 *domega_in_dx *= 10.0f; 00125 *domega_in_dy *= 10.0f; 00126 #endif 00127 } 00128 } 00129 } 00130 return LABEL_REFLECT|LABEL_GLOSSY; 00131 } 00132 00133 /* WESTIN SHEEN */ 00134 00135 typedef struct BsdfWestinSheenClosure { 00136 //float3 m_N; 00137 float m_edginess; 00138 } BsdfWestinSheenClosure; 00139 00140 __device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess) 00141 { 00142 sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID; 00143 sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; 00144 sc->data0 = edginess; 00145 } 00146 00147 __device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness) 00148 { 00149 } 00150 00151 __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) 00152 { 00153 float m_edginess = sc->data0; 00154 float3 m_N = sd->N; 00155 00156 // pdf is implicitly 0 (no indirect sampling) 00157 float cosNO = dot(m_N, I); 00158 float cosNI = dot(m_N, omega_in); 00159 if(cosNO > 0 && cosNI > 0) { 00160 float sinNO2 = 1 - cosNO * cosNO; 00161 *pdf = cosNI * M_1_PI_F; 00162 float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0; 00163 return make_float3 (westin, westin, westin); 00164 } 00165 return make_float3 (0, 0, 0); 00166 } 00167 00168 __device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) 00169 { 00170 return make_float3(0.0f, 0.0f, 0.0f); 00171 } 00172 00173 __device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) 00174 { 00175 return 1.0f; 00176 } 00177 00178 __device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) 00179 { 00180 float m_edginess = sc->data0; 00181 float3 m_N = sd->N; 00182 00183 // we are viewing the surface from the right side - send a ray out with cosine 00184 // distribution over the hemisphere 00185 sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); 00186 if(dot(sd->Ng, *omega_in) > 0) { 00187 // TODO: account for sheen when sampling 00188 float cosNO = dot(m_N, sd->I); 00189 float sinNO2 = 1 - cosNO * cosNO; 00190 float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0; 00191 *eval = make_float3(westin, westin, westin); 00192 #ifdef __RAY_DIFFERENTIALS__ 00193 // TODO: find a better approximation for the diffuse bounce 00194 *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; 00195 *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; 00196 *domega_in_dx *= 125.0f; 00197 *domega_in_dy *= 125.0f; 00198 #endif 00199 } else 00200 pdf = 0; 00201 return LABEL_REFLECT|LABEL_DIFFUSE; 00202 } 00203 00204 CCL_NAMESPACE_END 00205 00206 #endif /* __BSDF_WESTIN_H__ */ 00207