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 #include <OpenImageIO/fmath.h> 00034 00035 #include <OSL/genclosure.h> 00036 00037 #include "osl_closures.h" 00038 00039 CCL_NAMESPACE_BEGIN 00040 00041 using namespace OSL; 00042 00043 class AshikhminVelvetClosure : public BSDFClosure { 00044 public: 00045 Vec3 m_N; 00046 float m_sigma; 00047 float m_invsigma2; 00048 00049 AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) { } 00050 00051 void setup() 00052 { 00053 m_sigma = std::max(m_sigma, 0.01f); 00054 m_invsigma2 = 1.0f/(m_sigma * m_sigma); 00055 } 00056 00057 bool mergeable (const ClosurePrimitive *other) const { 00058 const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; 00059 return m_N == comp->m_N && m_sigma == comp->m_sigma && 00060 BSDFClosure::mergeable(other); 00061 } 00062 00063 size_t memsize () const { return sizeof(*this); } 00064 00065 const char *name () const { return "ashikhmin_velvet"; } 00066 00067 void print_on (std::ostream &out) const 00068 { 00069 out << name() << " ("; 00070 out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; 00071 out << m_sigma; 00072 out << ")"; 00073 } 00074 00075 float albedo (const Vec3 &omega_out) const 00076 { 00077 return 1.0f; 00078 } 00079 00080 Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const 00081 { 00082 float cosNO = m_N.dot(omega_out); 00083 float cosNI = m_N.dot(omega_in); 00084 if (cosNO > 0 && cosNI > 0) { 00085 Vec3 H = omega_in + omega_out; 00086 H.normalize(); 00087 00088 float cosNH = m_N.dot(H); 00089 float cosHO = fabsf(omega_out.dot(H)); 00090 00091 float cosNHdivHO = cosNH / cosHO; 00092 cosNHdivHO = std::max(cosNHdivHO, 0.00001f); 00093 00094 float fac1 = 2 * fabsf(cosNHdivHO * cosNO); 00095 float fac2 = 2 * fabsf(cosNHdivHO * cosNI); 00096 00097 float sinNH2 = 1 - cosNH * cosNH; 00098 float sinNH4 = sinNH2 * sinNH2; 00099 float cotangent2 = (cosNH * cosNH) / sinNH2; 00100 00101 float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; 00102 float G = std::min(1.0f, std::min(fac1, fac2)); // TODO: derive G from D analytically 00103 00104 float out = 0.25f * (D * G) / cosNO; 00105 00106 pdf = 0.5f * (float) M_1_PI; 00107 return Color3 (out, out, out); 00108 } 00109 return Color3 (0, 0, 0); 00110 } 00111 00112 Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const 00113 { 00114 return Color3 (0, 0, 0); 00115 } 00116 00117 ustring sample (const Vec3 &Ng, 00118 const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, 00119 float randu, float randv, 00120 Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, 00121 float &pdf, Color3 &eval) const 00122 { 00123 // we are viewing the surface from above - send a ray out with uniform 00124 // distribution over the hemisphere 00125 sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); 00126 if (Ng.dot(omega_in) > 0) { 00127 Vec3 H = omega_in + omega_out; 00128 H.normalize(); 00129 00130 float cosNI = m_N.dot(omega_in); 00131 float cosNO = m_N.dot(omega_out); 00132 float cosNH = m_N.dot(H); 00133 float cosHO = fabsf(omega_out.dot(H)); 00134 00135 float cosNHdivHO = cosNH / cosHO; 00136 cosNHdivHO = std::max(cosNHdivHO, 0.00001f); 00137 00138 float fac1 = 2 * fabsf(cosNHdivHO * cosNO); 00139 float fac2 = 2 * fabsf(cosNHdivHO * cosNI); 00140 00141 float sinNH2 = 1 - cosNH * cosNH; 00142 float sinNH4 = sinNH2 * sinNH2; 00143 float cotangent2 = (cosNH * cosNH) / sinNH2; 00144 00145 float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; 00146 float G = std::min(1.0f, std::min(fac1, fac2)); // TODO: derive G from D analytically 00147 00148 float power = 0.25f * (D * G) / cosNO; 00149 00150 eval.setValue(power, power, power); 00151 00152 // TODO: find a better approximation for the retroreflective bounce 00153 domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; 00154 domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; 00155 domega_in_dx *= 125; 00156 domega_in_dy *= 125; 00157 } else 00158 pdf = 0; 00159 return Labels::REFLECT; 00160 } 00161 00162 }; 00163 00164 00165 00166 ClosureParam bsdf_ashikhmin_velvet_params[] = { 00167 CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), 00168 CLOSURE_FLOAT_PARAM (AshikhminVelvetClosure, m_sigma), 00169 CLOSURE_STRING_KEYPARAM("label"), 00170 CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) }; 00171 00172 CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) 00173 00174 CCL_NAMESPACE_END 00175