From 2d290040a1fea8319f33a982823bea13d1d95348 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 22:44:58 +0000 Subject: style cleanup --- intern/cycles/kernel/osl/background.cpp | 36 +- intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp | 240 +++---- intern/cycles/kernel/osl/bsdf_diffuse.cpp | 244 +++---- intern/cycles/kernel/osl/bsdf_microfacet.cpp | 779 +++++++++++---------- intern/cycles/kernel/osl/bsdf_oren_nayar.cpp | 40 +- intern/cycles/kernel/osl/bsdf_reflection.cpp | 113 +-- intern/cycles/kernel/osl/bsdf_refraction.cpp | 119 ++-- intern/cycles/kernel/osl/bsdf_transparent.cpp | 87 +-- intern/cycles/kernel/osl/bsdf_ward.cpp | 312 +++++---- intern/cycles/kernel/osl/bsdf_westin.cpp | 346 ++++----- intern/cycles/kernel/osl/bssrdf.cpp | 103 +-- intern/cycles/kernel/osl/debug.cpp | 31 +- intern/cycles/kernel/osl/emissive.cpp | 93 +-- intern/cycles/kernel/osl/nodes/node_color.h | 50 +- intern/cycles/kernel/osl/nodes/node_fresnel.h | 8 +- intern/cycles/kernel/osl/nodes/node_texture.h | 100 +-- intern/cycles/kernel/osl/nodes/stdosl.h | 397 +++++------ intern/cycles/kernel/osl/osl_services.cpp | 152 ++-- intern/cycles/kernel/osl/osl_services.h | 15 +- intern/cycles/kernel/osl/osl_shader.cpp | 152 ++-- intern/cycles/kernel/osl/osl_shader.h | 8 +- intern/cycles/kernel/osl/vol_subsurface.cpp | 156 +++-- 22 files changed, 1814 insertions(+), 1767 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index c35119ae9cf..81812a46b6c 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -48,17 +48,17 @@ using namespace OSL; /// class GenericBackgroundClosure : public BackgroundClosure { public: - GenericBackgroundClosure() { } + GenericBackgroundClosure() {} - void setup() {}; + void setup() {}; - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "background"; } + const char *name() const { return "background"; } - void print_on (std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { + out << name() << " ()"; + } }; @@ -72,27 +72,29 @@ public: /// class HoldoutClosure : ClosurePrimitive { public: - HoldoutClosure () : ClosurePrimitive (Holdout) { } + HoldoutClosure () : ClosurePrimitive(Holdout) {} - void setup() {}; + void setup() {}; - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "holdout"; } + const char *name() const { return "holdout"; } - void print_on (std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { + out << name() << " ()"; + } }; ClosureParam closure_background_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericBackgroundClosure) +}; CLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure) ClosureParam closure_holdout_params[] = { - CLOSURE_FINISH_PARAM(HoldoutClosure) }; + CLOSURE_FINISH_PARAM(HoldoutClosure) +}; CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp index 808837bf211..cb6be6959f5 100644 --- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp +++ b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp @@ -44,132 +44,134 @@ using namespace OSL; class AshikhminVelvetClosure : public BSDFClosure { public: - Vec3 m_N; - float m_sigma; - float m_invsigma2; - - AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() - { - m_sigma = max(m_sigma, 0.01f); - m_invsigma2 = 1.0f/(m_sigma * m_sigma); - } - - bool mergeable (const ClosurePrimitive *other) const { - const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; - return m_N == comp->m_N && m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "ashikhmin_velvet"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { + Vec3 m_N; + float m_sigma; + float m_invsigma2; + + AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() + { + m_sigma = max(m_sigma, 0.01f); + m_invsigma2 = 1.0f / (m_sigma * m_sigma); + } + + bool mergeable(const ClosurePrimitive *other) const { + const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; + return m_N == comp->m_N && m_sigma == comp->m_sigma && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "ashikhmin_velvet"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_sigma; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 0.00001f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float out = 0.25f * (D * G) / cosNO; - - pdf = 0.5f * (float) M_1_PI; - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from above - send a ray out with uniform - // distribution over the hemisphere - sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 0.00001f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float power = 0.25f * (D * G) / cosNO; - - eval.setValue(power, power, power); - - // TODO: find a better approximation for the retroreflective bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + Vec3 H = omega_in + omega_out; + H.normalize(); + + float cosNH = m_N.dot(H); + float cosHO = fabsf(omega_out.dot(H)); + + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = max(cosNHdivHO, 0.00001f); + + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; + + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + + float out = 0.25f * (D * G) / cosNO; + + pdf = 0.5f * (float) M_1_PI; + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from above - send a ray out with uniform + // distribution over the hemisphere + sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + Vec3 H = omega_in + omega_out; + H.normalize(); + + float cosNI = m_N.dot(omega_in); + float cosNO = m_N.dot(omega_out); + float cosNH = m_N.dot(H); + float cosHO = fabsf(omega_out.dot(H)); + + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = max(cosNHdivHO, 0.00001f); + + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; + + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + + float power = 0.25f * (D * G) / cosNO; + + eval.setValue(power, power, power); + + // TODO: find a better approximation for the retroreflective bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else + pdf = 0; + return Labels::REFLECT; + } }; ClosureParam bsdf_ashikhmin_velvet_params[] = { - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), - CLOSURE_FLOAT_PARAM (AshikhminVelvetClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) }; + CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), + CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) +}; CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp index 352e75f73c9..582ac01d959 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse.cpp @@ -44,137 +44,141 @@ using namespace OSL; class DiffuseClosure : public BSDFClosure { public: - Vec3 m_N; - - DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const DiffuseClosure *comp = (const DiffuseClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "diffuse"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(m_N.dot(omega_in),0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3 (cos_pi, cos_pi, cos_pi); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + Vec3 m_N; + + DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const DiffuseClosure *comp = (const DiffuseClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "diffuse"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI; + pdf = cos_pi; + return Color3(cos_pi, cos_pi, cos_pi); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + eval.setValue(pdf, pdf, pdf); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else + pdf = 0; + return Labels::REFLECT; + } }; class TranslucentClosure : public BSDFClosure { public: - Vec3 m_N; - - TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const TranslucentClosure *comp = (const TranslucentClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "translucent"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3 (cos_pi, cos_pi, cos_pi); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (-m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) < 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= -125; - domega_in_dy *= -125; - } else - pdf = 0; - return Labels::TRANSMIT; - } + Vec3 m_N; + + TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const TranslucentClosure *comp = (const TranslucentClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "translucent"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; + pdf = cos_pi; + return Color3(cos_pi, cos_pi, cos_pi); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) < 0) { + eval.setValue(pdf, pdf, pdf); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= -125; + domega_in_dy *= -125; + } + else + pdf = 0; + return Labels::TRANSMIT; + } }; ClosureParam bsdf_diffuse_params[] = { - CLOSURE_VECTOR_PARAM (DiffuseClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (DiffuseClosure) }; + CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(DiffuseClosure) +}; ClosureParam bsdf_translucent_params[] = { - CLOSURE_VECTOR_PARAM (TranslucentClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (TranslucentClosure) }; + CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(TranslucentClosure) +}; CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure) CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure) diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp index d87268da81e..09730d8c3e1 100644 --- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp +++ b/intern/cycles/kernel/osl/bsdf_microfacet.cpp @@ -52,85 +52,85 @@ CCL_NAMESPACE_BEGIN template class MicrofacetGGXClosure : public BSDFClosure { public: - Vec3 m_N; - float m_ag; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } + Vec3 m_N; + float m_ag; // width parameter (roughness) + float m_eta; // index of refraction (for fresnel term) + MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } - void setup() + void setup() { m_ag = clamp(m_ag, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; - return m_N == comp->m_N && m_ag == comp->m_ag && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; + return m_N == comp->m_N && m_ag == comp->m_ag && + m_eta == comp->m_eta && BSDFClosure::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { - return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; - } + const char *name() const { + return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; + } - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ag << ", "; - out << m_eta; - out << ")"; - } + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_ag << ", "; + out << m_eta; + out << ")"; + } - float albedo (const Vec3 &omega_out) const - { + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 33: first we calculate D(m) with m=Hr: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3 (0, 0, 0); // vectors on same side -- not possible - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 1) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNI > 0 && cosNO > 0) { + // get half vector + Vec3 Hr = omega_in + omega_out; + Hr.normalize(); + // eq. 20: (F*G*D)/(4*in*on) + // eq. 33: first we calculate D(m) with m=Hr: + float alpha2 = m_ag * m_ag; + float cosThetaM = m_N.dot(Hr); + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + float out = (G * D) * 0.25f / cosNO; + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / Hr.dot(omega_out); + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 0) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO <= 0 || cosNI >= 0) + return Color3(0, 0, 0); // vectors on same side -- not possible + // compute half-vector of the refraction (eq. 16) + Vec3 ht = -(m_eta * omega_in + omega_out); + Vec3 Ht = ht; Ht.normalize(); + float cosHO = Ht.dot(omega_out); float cosHI = Ht.dot(omega_in); // eq. 33: first we calculate D(m) with m=Ht: @@ -148,122 +148,123 @@ public: float invHt2 = 1 / ht.dot(ht); pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3 (out, out, out); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ag * m_ag; - float tanThetaM2 = alpha2 * randu / (1 - randu); - float cosThetaM = 1 / sqrtf(1 + tanThetaM2); - float sinThetaM = cosThetaM * sqrtf(tanThetaM2); - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; + return Color3(out, out, out); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + Vec3 X, Y, Z = m_N; + make_orthonormals(Z, X, Y); + // generate a random microfacet normal m + // eq. 35,36: + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alpha2 = m_ag * m_ag; + float tanThetaM2 = alpha2 * randu / (1 - randu); + float cosThetaM = 1 / sqrtf(1 + tanThetaM2); + float sinThetaM = cosThetaM * sqrtf(tanThetaM2); + float phiM = 2 * float(M_PI) * randv; + Vec3 m = (cosf(phiM) * sinThetaM) * X + + (sinf(phiM) * sinThetaM) * Y + + cosThetaM * Z; + if (Refractive == 0) { + float cosMO = m.dot(omega_out); + if (cosMO > 0) { + // eq. 39 - compute actual reflected direction + omega_in = 2 * cosMO * m - omega_out; + if (Ng.dot(omega_in) > 0) { + // microfacet normal is visible to this ray + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / cosMO; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + // eq. 20: (F*G*D)/(4*in*on) + float out = (G * D) * 0.25f / cosNO; + eval.setValue(out, out, out); + domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; + domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); + } + } + } + else { + // CAUTION: the i and o variables are inverted relative to the paper + // eq. 39 - compute actual refractive direction + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + + if (!inside) { + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 24 + float pm = D * cosThetaM; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + // eq. 21 + float cosHI = m.dot(omega_in); + float cosHO = m.dot(omega_out); + float Ht2 = m_eta * cosHI + cosHO; + Ht2 *= Ht2; + float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); + // eq. 38 and eq. 17 + pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; + eval.setValue(out, out, out); /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this refraction, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } + } + } + } + return Refractive ? Labels::TRANSMIT : Labels::REFLECT; + } }; // microfacet model with Beckmann facet distribution @@ -271,89 +272,92 @@ public: template class MicrofacetBeckmannClosure : public BSDFClosure { public: - Vec3 m_N; - float m_ab; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { } + Vec3 m_N; + float m_ab; // width parameter (roughness) + float m_eta; // index of refraction (for fresnel term) + MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { + } - void setup() + void setup() { m_ab = clamp(m_ab, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; - return m_N == comp->m_N && m_ab == comp->m_ab && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char * name () const { - return Refractive ? "microfacet_beckmann_refraction" - : "microfacet_beckmann"; - } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ab << ", "; - out << m_eta; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { + bool mergeable(const ClosurePrimitive *other) const { + const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; + return m_N == comp->m_N && m_ab == comp->m_ab && + m_eta == comp->m_eta && BSDFClosure::mergeable(other); + } + + size_t memsize() const { + return sizeof(*this); + } + + const char *name() const { + return Refractive ? "microfacet_beckmann_refraction" + : "microfacet_beckmann"; + } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_ab << ", "; + out << m_eta; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 25: first we calculate D(m) with m=Hr: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3 (0, 0, 0); - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 1) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + // get half vector + Vec3 Hr = omega_in + omega_out; + Hr.normalize(); + // eq. 20: (F*G*D)/(4*in*on) + // eq. 25: first we calculate D(m) with m=Hr: + float alpha2 = m_ab * m_ab; + float cosThetaM = m_N.dot(Hr); + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + float out = (G * D) * 0.25f / cosNO; + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / Hr.dot(omega_out); + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 0) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO <= 0 || cosNI >= 0) + return Color3(0, 0, 0); + // compute half-vector of the refraction (eq. 16) + Vec3 ht = -(m_eta * omega_in + omega_out); + Vec3 Ht = ht; Ht.normalize(); + float cosHO = Ht.dot(omega_out); float cosHI = Ht.dot(omega_in); // eq. 33: first we calculate D(m) with m=Ht: @@ -373,156 +377,161 @@ public: float invHt2 = 1 / ht.dot(ht); pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3 (out, out, out); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ab * m_ab; - float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); - float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); - float sinThetaM = cosThetaM * tanThetaM; - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 25 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // Eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; + return Color3(out, out, out); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + Vec3 X, Y, Z = m_N; + make_orthonormals(Z, X, Y); + // generate a random microfacet normal m + // eq. 35,36: + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alpha2 = m_ab * m_ab; + float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); + float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); + float sinThetaM = cosThetaM * tanThetaM; + float phiM = 2 * float(M_PI) * randv; + Vec3 m = (cosf(phiM) * sinThetaM) * X + + (sinf(phiM) * sinThetaM) * Y + + cosThetaM * Z; + if (Refractive == 0) { + float cosMO = m.dot(omega_out); + if (cosMO > 0) { + // eq. 39 - compute actual reflected direction + omega_in = 2 * cosMO * m - omega_out; + if (Ng.dot(omega_in) > 0) { + // microfacet normal is visible to this ray + // eq. 25 + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = tanThetaM * tanThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / cosMO; + // Eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + // eq. 20: (F*G*D)/(4*in*on) + float out = (G * D) * 0.25f / cosNO; + eval.setValue(out, out, out); + domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; + domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); + } + } + } + else { + // CAUTION: the i and o variables are inverted relative to the paper + // eq. 39 - compute actual refractive direction + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + if (!inside) { + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = tanThetaM * tanThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 24 + float pm = D * cosThetaM; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + // eq. 21 + float cosHI = m.dot(omega_in); + float cosHO = m.dot(omega_out); + float Ht2 = m_eta * cosHI + cosHO; + Ht2 *= Ht2; + float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); + // eq. 38 and eq. 17 + pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; + eval.setValue(out, out, out); /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this refraction, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } + } + } + } + return Refractive ? Labels::TRANSMIT : Labels::REFLECT; + } }; ClosureParam bsdf_microfacet_ggx_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<0>, m_ag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) }; + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) +}; ClosureParam bsdf_microfacet_ggx_refraction_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_ag), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) }; + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) +}; ClosureParam bsdf_microfacet_beckmann_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<0>, m_ab), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) }; + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) +}; ClosureParam bsdf_microfacet_beckmann_refraction_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_ab), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) }; + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) +}; CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>) CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>) diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp index dd6c59d98c2..83d0e583695 100644 --- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp +++ b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp @@ -26,13 +26,13 @@ CCL_NAMESPACE_BEGIN using namespace OSL; -class OrenNayarClosure: public BSDFClosure { +class OrenNayarClosure : public BSDFClosure { public: Vec3 m_N; float m_sigma; float m_a, m_b; - OrenNayarClosure(): BSDFClosure(Labels::DIFFUSE) {} + OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {} void setup() { m_sigma = clamp(m_sigma, 0.0f, 1.0f); @@ -43,19 +43,19 @@ public: m_b = m_sigma * div; } - bool mergeable(const ClosurePrimitive* other) const { - const OrenNayarClosure* comp = static_cast(other); + bool mergeable(const ClosurePrimitive *other) const { + const OrenNayarClosure *comp = static_cast(other); return - m_N == comp->m_N && - m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); + m_N == comp->m_N && + m_sigma == comp->m_sigma && + BSDFClosure::mergeable(other); } size_t memsize() const { return sizeof(*this); } - const char* name() const { + const char *name() const { return "oren_nayar"; } @@ -87,13 +87,13 @@ public: } ustring sample( - const Vec3& Ng, - const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, - float randu, float randv, - Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, - float& pdf, Color3& eval - ) const { - sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); + const Vec3& Ng, + const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, + float randu, float randv, + Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, + float& pdf, Color3& eval + ) const { + sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); if (Ng.dot(omega_in) > 0.0f) { float is = get_intensity(m_N, omega_out, omega_in); @@ -118,7 +118,7 @@ private: float nv = max(n.dot(v), 0.0f); float t = l.dot(v) - nl * nv; - if(t > 0.0f) { + if (t > 0.0f) { t /= max(nl, nv) + 1e-8f; } return nl * (m_a + m_b * t); @@ -126,10 +126,10 @@ private: }; ClosureParam bsdf_oren_nayar_params[] = { - CLOSURE_VECTOR_PARAM (OrenNayarClosure, m_N), - CLOSURE_FLOAT_PARAM (OrenNayarClosure, m_sigma), - CLOSURE_STRING_KEYPARAM ("label"), - CLOSURE_FINISH_PARAM (OrenNayarClosure) + CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N), + CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(OrenNayarClosure) }; CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure) diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp index b0caff6df44..7041b4ced6f 100644 --- a/intern/cycles/kernel/osl/bsdf_reflection.cpp +++ b/intern/cycles/kernel/osl/bsdf_reflection.cpp @@ -42,65 +42,66 @@ using namespace OSL; class ReflectionClosure : public BSDFClosure { public: - Vec3 m_N; // shading normal - ReflectionClosure() : BSDFClosure(Labels::SINGULAR) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const ReflectionClosure *comp = (const ReflectionClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "reflection"; } - - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - omega_in = (2 * cosNO) * m_N - omega_out; - if (Ng.dot(omega_in) > 0) { - domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; - domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - } - } - return Labels::REFLECT; - } + Vec3 m_N; // shading normal + ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const ReflectionClosure *comp = (const ReflectionClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "reflection"; } + + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // only one direction is possible + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + omega_in = (2 * cosNO) * m_N - omega_out; + if (Ng.dot(omega_in) > 0) { + domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; + domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; + pdf = 1; + eval.setValue(1, 1, 1); + } + } + return Labels::REFLECT; + } }; ClosureParam bsdf_reflection_params[] = { - CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(ReflectionClosure) }; + CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(ReflectionClosure) +}; CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure) diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp index 3ae7a3811b4..f56ad7b127c 100644 --- a/intern/cycles/kernel/osl/bsdf_refraction.cpp +++ b/intern/cycles/kernel/osl/bsdf_refraction.cpp @@ -42,77 +42,78 @@ using namespace OSL; class RefractionClosure : public BSDFClosure { public: - Vec3 m_N; // shading normal - float m_eta; // ratio of indices of refraction (inside / outside) - RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) { } + Vec3 m_N; // shading normal + float m_eta; // ratio of indices of refraction (inside / outside) + RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {} - void setup() {} + void setup() {} - bool mergeable (const ClosurePrimitive *other) const { - const RefractionClosure *comp = (const RefractionClosure *)other; - return m_N == comp->m_N && m_eta == comp->m_eta && - BSDFClosure::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const RefractionClosure *comp = (const RefractionClosure *)other; + return m_N == comp->m_N && m_eta == comp->m_eta && + BSDFClosure::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "refraction"; } + const char *name() const { return "refraction"; } - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_eta; - out << ")"; - } + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_eta; + out << ")"; + } - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } - float albedo (const Vec3 &omega_out) const - { + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - - fresnel_dielectric(m_eta, m_N, - omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - pdf = 1; - eval.setValue(1.0f, 1.0f, 1.0f); - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - } - - return Labels::TRANSMIT; - } + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + + fresnel_dielectric(m_eta, m_N, + omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + + if (!inside) { + pdf = 1; + eval.setValue(1.0f, 1.0f, 1.0f); + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + } + + return Labels::TRANSMIT; + } }; ClosureParam bsdf_refraction_params[] = { - CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), - CLOSURE_FLOAT_PARAM (RefractionClosure, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(RefractionClosure) }; + CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), + CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(RefractionClosure) +}; CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure) diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp index 941abd6a483..acde92530a2 100644 --- a/intern/cycles/kernel/osl/bsdf_transparent.cpp +++ b/intern/cycles/kernel/osl/bsdf_transparent.cpp @@ -42,54 +42,55 @@ using namespace OSL; class TransparentClosure : public BSDFClosure { public: - TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) { } - - void setup() {} - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "transparent"; } - - void print_on (std::ostream &out) const { - out << name() << " ()"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - omega_in = -omega_out; - domega_in_dx = -domega_out_dx; - domega_in_dy = -domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - return Labels::TRANSMIT; - } + TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {} + + void setup() {} + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "transparent"; } + + void print_on(std::ostream &out) const { + out << name() << " ()"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // only one direction is possible + omega_in = -omega_out; + domega_in_dx = -domega_out_dx; + domega_in_dy = -domega_out_dy; + pdf = 1; + eval.setValue(1, 1, 1); + return Labels::TRANSMIT; + } }; ClosureParam bsdf_transparent_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TransparentClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(TransparentClosure) +}; CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp index a7742a04d13..4aacbc4ffc3 100644 --- a/intern/cycles/kernel/osl/bsdf_ward.cpp +++ b/intern/cycles/kernel/osl/bsdf_ward.cpp @@ -46,175 +46,179 @@ using namespace OSL; // see http://www.graphics.cornell.edu/~bjw/wardnotes.pdf class WardClosure : public BSDFClosure { public: - Vec3 m_N; - Vec3 m_T; - float m_ax, m_ay; - WardClosure() : BSDFClosure(Labels::GLOSSY) { } + Vec3 m_N; + Vec3 m_T; + float m_ax, m_ay; + WardClosure() : BSDFClosure(Labels::GLOSSY) {} - void setup() + void setup() { m_ax = clamp(m_ax, 1e-5f, 1.0f); m_ay = clamp(m_ay, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const WardClosure *comp = (const WardClosure *)other; - return m_N == comp->m_N && m_T == comp->m_T && - m_ax == comp->m_ax && m_ay == comp->m_ay && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "ward"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; - out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; - out << m_ax << ", " << m_ay << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector and get x,y basis on the surface for anisotropy - Vec3 H = omega_in + omega_out; - H.normalize(); // normalize needed for pdf - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // eq. 4 - float dotx = H.dot(X) / m_ax; - float doty = H.dot(Y) / m_ay; - float dotn = H.dot(m_N); - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float exp_val = expf(-exp_arg); - float out = cosNI * exp_val / denom; - float oh = H.dot(omega_out); - denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = exp_val / denom; - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // get x,y basis on the surface for anisotropy - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // generate random angles for the half vector - // eq. 7 (taking care around discontinuities to keep - // output angle in the right quadrant) - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alphaRatio = m_ay / m_ax; - float cosPhi, sinPhi; - if (randu < 0.25f) { - float val = 4 * randu; - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } else if (randu < 0.5) { - float val = 1 - 4 * (0.5f - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = (float) M_PI - phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } else if (randu < 0.75f) { - float val = 4 * (randu - 0.5f); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - //phi = (float) M_PI + phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } else { - float val = 1 - 4 * (1 - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = 2 * (float) M_PI - phi; - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - // eq. 6 - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); - float tanTheta2 = -logf(1 - randv) / thetaDenom; - float cosTheta = 1 / sqrtf(1 + tanTheta2); - float sinTheta = cosTheta * sqrtf(tanTheta2); - - Vec3 h; // already normalized becaused expressed from spherical coordinates - h.x = sinTheta * cosPhi; - h.y = sinTheta * sinPhi; - h.z = cosTheta; - // compute terms that are easier in local space - float dotx = h.x / m_ax; - float doty = h.y / m_ay; - float dotn = h.z; - // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; - // generate the final sample - float oh = h.dot(omega_out); - omega_in.x = 2 * oh * h.x - omega_out.x; - omega_in.y = 2 * oh * h.y - omega_out.y; - omega_in.z = 2 * oh * h.z - omega_out.z; - if (Ng.dot(omega_in) > 0) { - float cosNI = m_N.dot(omega_in); - if (cosNI > 0) { - // eq. 9 - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = expf(-exp_arg) / denom; - // compiler will reuse expressions already computed - denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float power = cosNI * expf(-exp_arg) / denom; - eval.setValue(power, power, power); - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + bool mergeable(const ClosurePrimitive *other) const { + const WardClosure *comp = (const WardClosure *)other; + return m_N == comp->m_N && m_T == comp->m_T && + m_ax == comp->m_ax && m_ay == comp->m_ay && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "ward"; } + + void print_on(std::ostream &out) const { + out << name() << " (("; + out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; + out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; + out << m_ax << ", " << m_ay << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNI > 0 && cosNO > 0) { + // get half vector and get x,y basis on the surface for anisotropy + Vec3 H = omega_in + omega_out; + H.normalize(); // normalize needed for pdf + Vec3 X, Y; + make_orthonormals(m_N, m_T, X, Y); + // eq. 4 + float dotx = H.dot(X) / m_ax; + float doty = H.dot(Y) / m_ay; + float dotn = H.dot(m_N); + float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); + float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); + float exp_val = expf(-exp_arg); + float out = cosNI * exp_val / denom; + float oh = H.dot(omega_out); + denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; + pdf = exp_val / denom; + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + // get x,y basis on the surface for anisotropy + Vec3 X, Y; + make_orthonormals(m_N, m_T, X, Y); + // generate random angles for the half vector + // eq. 7 (taking care around discontinuities to keep + // output angle in the right quadrant) + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alphaRatio = m_ay / m_ax; + float cosPhi, sinPhi; + if (randu < 0.25f) { + float val = 4 * randu; + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = tanPhi * cosPhi; + } + else if (randu < 0.5) { + float val = 1 - 4 * (0.5f - randu); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + // phi = (float) M_PI - phi; + cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = -tanPhi * cosPhi; + } + else if (randu < 0.75f) { + float val = 4 * (randu - 0.5f); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + //phi = (float) M_PI + phi; + cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = tanPhi * cosPhi; + } + else { + float val = 1 - 4 * (1 - randu); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + // phi = 2 * (float) M_PI - phi; + cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = -tanPhi * cosPhi; + } + // eq. 6 + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); + float tanTheta2 = -logf(1 - randv) / thetaDenom; + float cosTheta = 1 / sqrtf(1 + tanTheta2); + float sinTheta = cosTheta * sqrtf(tanTheta2); + + Vec3 h; // already normalized becaused expressed from spherical coordinates + h.x = sinTheta * cosPhi; + h.y = sinTheta * sinPhi; + h.z = cosTheta; + // compute terms that are easier in local space + float dotx = h.x / m_ax; + float doty = h.y / m_ay; + float dotn = h.z; + // transform to world space + h = h.x * X + h.y * Y + h.z * m_N; + // generate the final sample + float oh = h.dot(omega_out); + omega_in.x = 2 * oh * h.x - omega_out.x; + omega_in.y = 2 * oh * h.y - omega_out.y; + omega_in.z = 2 * oh * h.z - omega_out.z; + if (Ng.dot(omega_in) > 0) { + float cosNI = m_N.dot(omega_in); + if (cosNI > 0) { + // eq. 9 + float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); + float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; + pdf = expf(-exp_arg) / denom; + // compiler will reuse expressions already computed + denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); + float power = cosNI * expf(-exp_arg) / denom; + eval.setValue(power, power, power); + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Labels::REFLECT; - } + } + } + } + return Labels::REFLECT; + } }; ClosureParam bsdf_ward_params[] = { - CLOSURE_VECTOR_PARAM(WardClosure, m_N), - CLOSURE_VECTOR_PARAM(WardClosure, m_T), - CLOSURE_FLOAT_PARAM (WardClosure, m_ax), - CLOSURE_FLOAT_PARAM (WardClosure, m_ay), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WardClosure) }; + CLOSURE_VECTOR_PARAM(WardClosure, m_N), + CLOSURE_VECTOR_PARAM(WardClosure, m_T), + CLOSURE_FLOAT_PARAM(WardClosure, m_ax), + CLOSURE_FLOAT_PARAM(WardClosure, m_ay), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WardClosure) +}; CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure) diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp index d322f6a7f7e..a476e8045f7 100644 --- a/intern/cycles/kernel/osl/bsdf_westin.cpp +++ b/intern/cycles/kernel/osl/bsdf_westin.cpp @@ -44,193 +44,197 @@ using namespace OSL; class WestinBackscatterClosure : public BSDFClosure { public: - Vec3 m_N; - float m_roughness; - float m_invroughness; - WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) { } + Vec3 m_N; + float m_roughness; + float m_invroughness; + WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {} - void setup() - { + void setup() + { m_roughness = clamp(m_roughness, 1e-5f, 1.0f); - m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; - } - - bool mergeable (const ClosurePrimitive *other) const { - const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; - return m_N == comp->m_N && m_roughness == comp->m_roughness && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "westin_backscatter"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_roughness; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float cosine = omega_out.dot(omega_in); - pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; - pdf *= 0.5f * float(M_1_PI); - return Color3 (pdf, pdf, pdf); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - domega_in_dx = domega_out_dx; - domega_in_dy = domega_out_dy; - Vec3 T, B; - make_orthonormals (omega_out, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_invroughness + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * omega_out; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); - pdf = (m_invroughness + 1) * pdf; - eval.setValue(pdf, pdf, pdf); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } + m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; + } + + bool mergeable(const ClosurePrimitive *other) const { + const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; + return m_N == comp->m_N && m_roughness == comp->m_roughness && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "westin_backscatter"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_roughness; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + // pdf is implicitly 0 (no indirect sampling) + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + float cosine = omega_out.dot(omega_in); + pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; + pdf *= 0.5f * float(M_1_PI); + return Color3(pdf, pdf, pdf); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + domega_in_dx = domega_out_dx; + domega_in_dy = domega_out_dy; + Vec3 T, B; + make_orthonormals(omega_out, T, B); + float phi = 2 * (float) M_PI * randu; + float cosTheta = powf(randv, 1 / (m_invroughness + 1)); + float sinTheta2 = 1 - cosTheta * cosTheta; + float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; + omega_in = (cosf(phi) * sinTheta) * T + + (sinf(phi) * sinTheta) * B + + (cosTheta) * omega_out; + if (Ng.dot(omega_in) > 0) + { + // common terms for pdf and eval + float cosNI = m_N.dot(omega_in); + // make sure the direction we chose is still in the right hemisphere + if (cosNI > 0) + { + pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); + pdf = (m_invroughness + 1) * pdf; + eval.setValue(pdf, pdf, pdf); + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // exponent but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; + } + } + } + return Labels::REFLECT; + } }; class WestinSheenClosure : public BSDFClosure { public: - Vec3 m_N; - float m_edginess; + Vec3 m_N; + float m_edginess; // float m_normalization; - WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const WestinSheenClosure *comp = (const WestinSheenClosure *)other; - return m_N == comp->m_N && m_edginess == comp->m_edginess && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "westin_sheen"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_edginess; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float sinNO2 = 1 - cosNO * cosNO; - pdf = cosNI * float(M_1_PI); - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - return Color3 (westin, westin, westin); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - // TODO: account for sheen when sampling - float cosNO = m_N.dot(omega_out); - float sinNO2 = 1 - cosNO * cosNO; - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - eval.setValue(westin, westin, westin); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const WestinSheenClosure *comp = (const WestinSheenClosure *)other; + return m_N == comp->m_N && m_edginess == comp->m_edginess && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "westin_sheen"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_edginess; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + // pdf is implicitly 0 (no indirect sampling) + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + float sinNO2 = 1 - cosNO * cosNO; + pdf = cosNI * float(M_1_PI); + float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; + return Color3(westin, westin, westin); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + // TODO: account for sheen when sampling + float cosNO = m_N.dot(omega_out); + float sinNO2 = 1 - cosNO * cosNO; + float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; + eval.setValue(westin, westin, westin); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else { + pdf = 0; + } + return Labels::REFLECT; + } }; ClosureParam bsdf_westin_backscatter_params[] = { - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), - CLOSURE_FLOAT_PARAM (WestinBackscatterClosure, m_roughness), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinBackscatterClosure) }; + CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), + CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WestinBackscatterClosure) +}; ClosureParam bsdf_westin_sheen_params[] = { - CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), - CLOSURE_FLOAT_PARAM (WestinSheenClosure, m_edginess), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinSheenClosure) }; + CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), + CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WestinSheenClosure) +}; CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure) CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure) diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp index 66d7818e677..b195cf513cd 100644 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ b/intern/cycles/kernel/osl/bssrdf.cpp @@ -42,62 +42,63 @@ using namespace OSL; class BSSRDFCubicClosure : public BSSRDFClosure { public: - Color3 m_radius; - Color3 m_scale; - float m_max_radius; - - template - static inline T pow3 (const T &x) { return x * x * x; } - - template - static inline T pow5 (const T &x) { T x2 = x * x; return x2 * x2 * x; } - - BSSRDFCubicClosure() { } - - void setup() - { - // pre-compute some terms - m_max_radius = 0; - for (int i = 0; i < 3; i++) { - m_scale[i] = m_radius[i] > 0 ? 4 / pow5 (m_radius[i]) : 0; - m_max_radius = std::max (m_max_radius, m_radius[i]); - } - } - - bool mergeable (const ClosurePrimitive *other) const { - const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; - return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "bssrdf_cubic"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" - << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; - } - - Color3 eval (float r) const - { - return Color3 ((r < m_radius.x) ? pow3 (m_radius.x - r) * m_scale.x : 0, - (r < m_radius.y) ? pow3 (m_radius.y - r) * m_scale.y : 0, - (r < m_radius.z) ? pow3 (m_radius.z - r) * m_scale.z : 0); - } - - float max_radius() const - { - return m_max_radius; - } + Color3 m_radius; + Color3 m_scale; + float m_max_radius; + + template + static inline T pow3(const T &x) { return x * x * x; } + + template + static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; } + + BSSRDFCubicClosure() {} + + void setup() + { + // pre-compute some terms + m_max_radius = 0; + for (int i = 0; i < 3; i++) { + m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0; + m_max_radius = std::max(m_max_radius, m_radius[i]); + } + } + + bool mergeable(const ClosurePrimitive *other) const { + const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; + return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "bssrdf_cubic"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" + << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; + } + + Color3 eval(float r) const + { + return Color3((r < m_radius.x) ? pow3(m_radius.x - r) * m_scale.x : 0, + (r < m_radius.y) ? pow3(m_radius.y - r) * m_scale.y : 0, + (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0); + } + + float max_radius() const + { + return m_max_radius; + } }; ClosureParam closure_bssrdf_cubic_params[] = { - CLOSURE_COLOR_PARAM (BSSRDFCubicClosure, m_radius), - CLOSURE_STRING_KEYPARAM ("label"), - CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) }; + CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) +}; CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure) diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp index 8c3f8b2b323..768a9100e8a 100644 --- a/intern/cycles/kernel/osl/debug.cpp +++ b/intern/cycles/kernel/osl/debug.cpp @@ -49,30 +49,31 @@ using namespace OSL; class DebugClosure : public ClosurePrimitive { public: - ustring m_tag; + ustring m_tag; - DebugClosure () : ClosurePrimitive (Debug) { } + DebugClosure () : ClosurePrimitive(Debug) {} - bool mergeable (const ClosurePrimitive *other) const { - const DebugClosure *comp = (const DebugClosure *)other; - return m_tag == comp->m_tag && - ClosurePrimitive::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const DebugClosure *comp = (const DebugClosure *)other; + return m_tag == comp->m_tag && + ClosurePrimitive::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "debug"; } + const char *name() const { return "debug"; } - void print_on (std::ostream &out) const { - out << name() << " (\"" << m_tag.c_str() << "\")"; - } + void print_on(std::ostream &out) const { + out << name() << " (\"" << m_tag.c_str() << "\")"; + } }; ClosureParam closure_debug_params[] = { - CLOSURE_STRING_PARAM(DebugClosure, m_tag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DebugClosure) }; + CLOSURE_STRING_PARAM(DebugClosure, m_tag), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(DebugClosure) +}; CLOSURE_PREPARE(closure_debug_prepare, DebugClosure) diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 2d2d6e1fdde..0a582c3f558 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -49,57 +49,58 @@ using namespace OSL; /// class GenericEmissiveClosure : public EmissiveClosure { public: - GenericEmissiveClosure() { } - - void setup() { } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "emission"; } - - void print_on (std::ostream &out) const { - out << name() << "()"; - } - - Color3 eval (const Vec3 &Ng, const Vec3 &omega_out) const - { - float cosNO = fabsf(Ng.dot(omega_out)); - float res = cosNO > 0 ? 1.0f: 0.0f; - return Color3(res, res, res); - } - - void sample (const Vec3 &Ng, float randu, float randv, - Vec3 &omega_out, float &pdf) const - { - // We don't do anything sophisticated here for the step - // We just sample the whole cone uniformly to the cosine - Vec3 T, B; - make_orthonormals(Ng, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = sqrtf(1.0f - 1.0f * randv); - float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); - omega_out = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - cosTheta * Ng; - pdf = 1.0f / float(M_PI); - } - - /// Return the probability distribution function in the direction omega_out, - /// given the parameters and the light's surface normal. This MUST match - /// the PDF computed by sample(). - float pdf (const Vec3 &Ng, - const Vec3 &omega_out) const - { - float cosNO = Ng.dot(omega_out); - return cosNO > 0 ? 1.0f: 0.0f; - } + GenericEmissiveClosure() { } + + void setup() {} + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "emission"; } + + void print_on(std::ostream &out) const { + out << name() << "()"; + } + + Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const + { + float cosNO = fabsf(Ng.dot(omega_out)); + float res = cosNO > 0 ? 1.0f : 0.0f; + return Color3(res, res, res); + } + + void sample(const Vec3 &Ng, float randu, float randv, + Vec3 &omega_out, float &pdf) const + { + // We don't do anything sophisticated here for the step + // We just sample the whole cone uniformly to the cosine + Vec3 T, B; + make_orthonormals(Ng, T, B); + float phi = 2 * (float) M_PI * randu; + float cosTheta = sqrtf(1.0f - 1.0f * randv); + float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); + omega_out = (cosf(phi) * sinTheta) * T + + (sinf(phi) * sinTheta) * B + + cosTheta * Ng; + pdf = 1.0f / float(M_PI); + } + + /// Return the probability distribution function in the direction omega_out, + /// given the parameters and the light's surface normal. This MUST match + /// the PDF computed by sample(). + float pdf(const Vec3 &Ng, + const Vec3 &omega_out) const + { + float cosNO = Ng.dot(omega_out); + return cosNO > 0 ? 1.0f : 0.0f; + } }; ClosureParam closure_emission_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericEmissiveClosure) +}; CLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) diff --git a/intern/cycles/kernel/osl/nodes/node_color.h b/intern/cycles/kernel/osl/nodes/node_color.h index 37d092eae78..80786e4e369 100644 --- a/intern/cycles/kernel/osl/nodes/node_color.h +++ b/intern/cycles/kernel/osl/nodes/node_color.h @@ -18,18 +18,18 @@ float color_srgb_to_scene_linear(float c) { - if(c < 0.04045) - return (c < 0.0)? 0.0: c * (1.0/12.92); + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); else - return pow((c + 0.055)*(1.0/1.055), 2.4); + return pow((c + 0.055) * (1.0 / 1.055), 2.4); } float color_scene_linear_to_srgb(float c) { - if(c < 0.0031308) - return (c < 0.0)? 0.0: c * 12.92; - else - return 1.055 * pow(c, 1.0/2.4) - 0.055; + if (c < 0.0031308) + return (c < 0.0) ? 0.0 : c * 12.92; + else + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; } color color_srgb_to_scene_linear(color c) @@ -61,27 +61,27 @@ color rgb_to_hsv(color rgb) v = cmax; - if(cmax != 0.0) { - s = cdelta/cmax; + if (cmax != 0.0) { + s = cdelta / cmax; } else { s = 0.0; h = 0.0; } - if(s == 0.0) { + if (s == 0.0) { h = 0.0; } else { - c = (color(cmax, cmax, cmax) - rgb)/cdelta; + c = (color(cmax, cmax, cmax) - rgb) / cdelta; - if(rgb[0] == cmax) h = c[2] - c[1]; - else if(rgb[1] == cmax) h = 2.0 + c[0] - c[2]; + if (rgb[0] == cmax) h = c[2] - c[1]; + else if (rgb[1] == cmax) h = 2.0 + c[0] - c[2]; else h = 4.0 + c[1] - c[0]; h /= 6.0; - if(h < 0.0) + if (h < 0.0) h += 1.0; } @@ -97,26 +97,26 @@ color hsv_to_rgb(color hsv) s = hsv[1]; v = hsv[2]; - if(s==0.0) { + if (s == 0.0) { rgb = color(v, v, v); } else { - if(h==1.0) + if (h == 1.0) h = 0.0; h *= 6.0; i = floor(h); f = h - i; rgb = color(f, f, f); - p = v*(1.0-s); - q = v*(1.0-(s*f)); - t = v*(1.0-(s*(1.0-f))); - - if(i == 0.0) rgb = color(v, t, p); - else if(i == 1.0) rgb = color(q, v, p); - else if(i == 2.0) rgb = color(p, v, t); - else if(i == 3.0) rgb = color(p, q, v); - else if(i == 4.0) rgb = color(t, p, v); + p = v * (1.0 - s); + q = v * (1.0 - (s * f)); + t = v * (1.0 - (s * (1.0 - f))); + + if (i == 0.0) rgb = color(v, t, p); + else if (i == 1.0) rgb = color(q, v, p); + else if (i == 2.0) rgb = color(p, v, t); + else if (i == 3.0) rgb = color(p, q, v); + else if (i == 4.0) rgb = color(t, p, v); else rgb = color(v, p, q); } diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.h b/intern/cycles/kernel/osl/nodes/node_fresnel.h index 0c8a5276ede..0368c1910aa 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.h +++ b/intern/cycles/kernel/osl/nodes/node_fresnel.h @@ -7,11 +7,11 @@ float fresnel_dielectric(vector Incoming, normal Normal, float eta) float g = eta * eta - 1 + c * c; float result; - if(g > 0) { + if (g > 0) { g = sqrt(g); - float A =(g - c)/(g + c); - float B =(c *(g + c)- 1)/(c *(g - c)+ 1); - result = 0.5 * A * A *(1 + B * B); + float A = (g - c) / (g + c); + float B = (c * (g + c) - 1) / (c * (g - c) + 1); + result = 0.5 * A * A * (1 + B * B); } else result = 1.0; /* TIR (no refracted component) */ diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/osl/nodes/node_texture.h index e0ec8038ee4..d2dbd6db8b3 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture.h +++ b/intern/cycles/kernel/osl/nodes/node_texture.h @@ -20,20 +20,20 @@ float voronoi_distance(string distance_metric, vector d, float e) { float result = 0.0; - if(distance_metric == "Distance Squared") + if (distance_metric == "Distance Squared") result = dot(d, d); - if(distance_metric == "Actual Distance") + if (distance_metric == "Actual Distance") result = length(d); - if(distance_metric == "Manhattan") + if (distance_metric == "Manhattan") result = fabs(d[0]) + fabs(d[1]) + fabs(d[2]); - if(distance_metric == "Chebychev") + if (distance_metric == "Chebychev") result = max(fabs(d[0]), max(fabs(d[1]), fabs(d[2]))); - if(distance_metric == "Minkovsky 1/2") + if (distance_metric == "Minkovsky 1/2") result = sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1])); - if(distance_metric == "Minkovsky 4") - result = sqrt(sqrt(dot(d*d, d*d))); - if(distance_metric == "Minkovsky") - result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0/e); + if (distance_metric == "Minkovsky 4") + result = sqrt(sqrt(dot(d * d, d * d))); + if (distance_metric == "Minkovsky") + result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e); return result; } @@ -63,9 +63,9 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) da[2] = 1e10; da[3] = 1e10; - for(xx = xi-1; xx <= xi+1; xx++) { - for(yy = yi-1; yy <= yi+1; yy++) { - for(zz = zi-1; zz <= zi+1; zz++) { + for (xx = xi - 1; xx <= xi + 1; xx++) { + for (yy = yi - 1; yy <= yi + 1; yy++) { + for (zz = zi - 1; zz <= zi + 1; zz++) { point ip = point(xx, yy, zz); point vp = (point)cellnoise_color(ip); point pd = p - (vp + ip); @@ -73,7 +73,7 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) vp += point(xx, yy, zz); - if(d < da[0]) { + if (d < da[0]) { da[3] = da[2]; da[2] = da[1]; da[1] = da[0]; @@ -84,7 +84,7 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) pa[1] = pa[0]; pa[0] = vp; } - else if(d < da[1]) { + else if (d < da[1]) { da[3] = da[2]; da[2] = da[1]; da[1] = d; @@ -93,14 +93,14 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) pa[2] = pa[1]; pa[1] = vp; } - else if(d < da[2]) { + else if (d < da[2]) { da[3] = da[2]; da[2] = d; pa[3] = pa[2]; pa[2] = vp; } - else if(d < da[3]) { + else if (d < da[3]) { da[3] = d; pa[3] = vp; } @@ -138,16 +138,16 @@ float voronoi_F1F2(point p) { return voronoi_FnFn(p, 0, 1); } float voronoi_Cr(point p) { /* crackle type pattern, just a scale/clamp of F2-F1 */ - float t = 10.0*voronoi_F1F2(p); - return (t > 1.0)? 1.0: t; + float t = 10.0 * voronoi_F1F2(p); + return (t > 1.0) ? 1.0 : t; } -float voronoi_F1S(point p) { return 2.0*voronoi_F1(p) - 1.0; } -float voronoi_F2S(point p) { return 2.0*voronoi_F2(p) - 1.0; } -float voronoi_F3S(point p) { return 2.0*voronoi_F3(p) - 1.0; } -float voronoi_F4S(point p) { return 2.0*voronoi_F4(p) - 1.0; } -float voronoi_F1F2S(point p) { return 2.0*voronoi_F1F2(p) - 1.0; } -float voronoi_CrS(point p) { return 2.0*voronoi_Cr(p) - 1.0; } +float voronoi_F1S(point p) { return 2.0 * voronoi_F1(p) - 1.0; } +float voronoi_F2S(point p) { return 2.0 * voronoi_F2(p) - 1.0; } +float voronoi_F3S(point p) { return 2.0 * voronoi_F3(p) - 1.0; } +float voronoi_F4S(point p) { return 2.0 * voronoi_F4(p) - 1.0; } +float voronoi_F1F2S(point p) { return 2.0 * voronoi_F1F2(p) - 1.0; } +float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; } /* Noise Bases */ @@ -155,21 +155,21 @@ float noise_basis(point p, string basis) { float result = 0.0; - if(basis == "Perlin") + if (basis == "Perlin") result = noise(p); - if(basis == "Voronoi F1") + if (basis == "Voronoi F1") result = voronoi_F1S(p); - if(basis == "Voronoi F2") + if (basis == "Voronoi F2") result = voronoi_F2S(p); - if(basis == "Voronoi F3") + if (basis == "Voronoi F3") result = voronoi_F3S(p); - if(basis == "Voronoi F4") + if (basis == "Voronoi F4") result = voronoi_F4S(p); - if(basis == "Voronoi F2-F1") + if (basis == "Voronoi F2-F1") result = voronoi_F1F2S(p); - if(basis == "Voronoi Crackle") + if (basis == "Voronoi Crackle") result = voronoi_CrS(p); - if(basis == "Cell Noise") + if (basis == "Cell Noise") result = cellnoise(p); return result; @@ -180,7 +180,7 @@ float noise_basis(point p, string basis) float noise_basis_hard(point p, string basis, int hard) { float t = noise_basis(p, basis); - return (hard)? fabs(2.0*t - 1.0): t; + return (hard) ? fabs(2.0 * t - 1.0) : t; } /* Waves */ @@ -189,22 +189,22 @@ float noise_wave(string wave, float a) { float result = 0.0; - if(wave == "Sine") { - result = 0.5 + 0.5*sin(a); + if (wave == "Sine") { + result = 0.5 + 0.5 * sin(a); } - else if(wave == "Saw") { - float b = 2*M_PI; + else if (wave == "Saw") { + float b = 2 * M_PI; int n = (int)(a / b); - a -= n*b; - if(a < 0) a += b; + a -= n * b; + if (a < 0) a += b; result = a / b; } - else if(wave == "Tri") { - float b = 2*M_PI; + else if (wave == "Tri") { + float b = 2 * M_PI; float rmax = 1.0; - result = rmax - 2.0*fabs(floor((a*(1.0/b))+0.5) - (a*(1.0/b))); + result = rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b))); } return result; @@ -219,18 +219,18 @@ float noise_turbulence(point p, string basis, int octaves, int hard) float sum = 0.0; int i; - for(i = 0; i <= octaves; i++) { - float t = noise_basis(fscale*p, basis); + for (i = 0; i <= octaves; i++) { + float t = noise_basis(fscale * p, basis); - if(hard) - t = fabs(2.0*t - 1.0); + if (hard) + t = fabs(2.0 * t - 1.0); - sum += t*amp; + sum += t * amp; amp *= 0.5; fscale *= 2.0; } - sum *= ((float)(1 << octaves)/(float)((1 << (octaves+1)) - 1)); + sum *= ((float)(1 << octaves) / (float)((1 << (octaves + 1)) - 1)); return sum; } @@ -241,8 +241,8 @@ float nonzero(float f, float eps) { float r; - if(abs(f) < eps) - r = sign(f)*eps; + if (abs(f) < eps) + r = sign(f) * eps; else r = f; diff --git a/intern/cycles/kernel/osl/nodes/stdosl.h b/intern/cycles/kernel/osl/nodes/stdosl.h index e4a110e737c..0c07c501d69 100644 --- a/intern/cycles/kernel/osl/nodes/stdosl.h +++ b/intern/cycles/kernel/osl/nodes/stdosl.h @@ -163,241 +163,246 @@ vector normalize (vector v) BUILTIN; vector faceforward (vector N, vector I, vector Nref) BUILTIN; vector faceforward (vector N, vector I) BUILTIN; vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; } -vector refract (vector I, vector N, float eta) { - float IdotN = dot (I, N); - float k = 1 - eta*eta * (1 - IdotN*IdotN); - return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k))); +vector refract(vector I, vector N, float eta) { + float IdotN = dot(I, N); + float k = 1 - eta * eta * (1 - IdotN * IdotN); + return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k))); } -void fresnel (vector I, normal N, float eta, - output float Kr, output float Kt, - output vector R, output vector T) +void fresnel(vector I, normal N, float eta, + output float Kr, output float Kt, + output vector R, output vector T) { - float sqr(float x) { return x*x; } - float c = dot(I, N); - if (c < 0) - c = -c; - R = reflect(I, N); - float g = 1.0 / sqr(eta) - 1.0 + c * c; - if (g >= 0.0) { - g = sqrt (g); - float beta = g - c; - float F = (c * (g+c) - 1.0) / (c * beta + 1.0); - F = 0.5 * (1.0 + sqr(F)); - F *= sqr (beta / (g+c)); - Kr = F; - Kt = (1.0 - Kr) * eta*eta; - // OPT: the following recomputes some of the above values, but it - // gives us the same result as if the shader-writer called refract() - T = refract(I, N, eta); - } else { - // total internal reflection - Kr = 1.0; - Kt = 0.0; - T = vector (0,0,0); - } + float sqr(float x) { + return x * x; + } + float c = dot(I, N); + if (c < 0) + c = -c; + R = reflect(I, N); + float g = 1.0 / sqr(eta) - 1.0 + c * c; + if (g >= 0.0) { + g = sqrt(g); + float beta = g - c; + float F = (c * (g + c) - 1.0) / (c * beta + 1.0); + F = 0.5 * (1.0 + sqr(F)); + F *= sqr(beta / (g + c)); + Kr = F; + Kt = (1.0 - Kr) * eta * eta; + // OPT: the following recomputes some of the above values, but it + // gives us the same result as if the shader-writer called refract() + T = refract(I, N, eta); + } + else { + // total internal reflection + Kr = 1.0; + Kt = 0.0; + T = vector(0, 0, 0); + } #undef sqr } -void fresnel (vector I, normal N, float eta, - output float Kr, output float Kt) +void fresnel(vector I, normal N, float eta, + output float Kr, output float Kt) { - vector R, T; - fresnel(I, N, eta, Kr, Kt, R, T); + vector R, T; + fresnel(I, N, eta, Kr, Kt, R, T); } -point rotate (point q, float angle, point a, point b) BUILTIN; +point rotate(point q, float angle, point a, point b) BUILTIN; -normal transform (matrix Mto, normal p) BUILTIN; -vector transform (matrix Mto, vector p) BUILTIN; -point transform (matrix Mto, point p) BUILTIN; +normal transform(matrix Mto, normal p) BUILTIN; +vector transform(matrix Mto, vector p) BUILTIN; +point transform(matrix Mto, point p) BUILTIN; // Implementation of transform-with-named-space in terms of matrices: -point transform (string tospace, point x) +point transform(string tospace, point x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -point transform (string fromspace, string tospace, point x) +point transform(string fromspace, string tospace, point x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -vector transform (string tospace, vector x) +vector transform(string tospace, vector x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -vector transform (string fromspace, string tospace, vector x) +vector transform(string fromspace, string tospace, vector x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -normal transform (string tospace, normal x) +normal transform(string tospace, normal x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -normal transform (string fromspace, string tospace, normal x) +normal transform(string fromspace, string tospace, normal x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -float transformu (string tounits, float x) BUILTIN; -float transformu (string fromunits, string tounits, float x) BUILTIN; +float transformu(string tounits, float x) BUILTIN; +float transformu(string fromunits, string tounits, float x) BUILTIN; // Color functions -float luminance (color c) { - return dot ((vector)c, vector(0.2126, 0.7152, 0.0722)); +float luminance(color c) { + return dot((vector)c, vector(0.2126, 0.7152, 0.0722)); } -color transformc (string to, color x) +color transformc(string to, color x) { - color rgb_to_hsv (color rgb) { // See Foley & van Dam - float r = rgb[0], g = rgb[1], b = rgb[2]; - float mincomp = min (r, min (g, b)); - float maxcomp = max (r, max (g, b)); - float delta = maxcomp - mincomp; // chroma - float h, s, v; - v = maxcomp; - if (maxcomp > 0) - s = delta / maxcomp; - else s = 0; - if (s <= 0) - h = 0; - else { - if (r >= maxcomp) h = (g-b) / delta; - else if (g >= maxcomp) h = 2 + (b-r) / delta; - else h = 4 + (r-g) / delta; - h /= 6; - if (h < 0) - h += 1; - } - return color (h, s, v); - } - - color rgb_to_hsl (color rgb) { // See Foley & van Dam - // First convert rgb to hsv, then to hsl - float minval = min (rgb[0], min (rgb[1], rgb[2])); - color hsv = rgb_to_hsv (rgb); - float maxval = hsv[2]; // v == maxval - float h = hsv[0], s, l = (minval+maxval) / 2; - if (minval == maxval) - s = 0; // special 'achromatic' case, hue is 0 - else if (l <= 0.5) - s = (maxval - minval) / (maxval + minval); - else - s = (maxval - minval) / (2 - maxval - minval); - return color (h, s, l); - } - - color r; - if (to == "rgb" || to == "RGB") - r = x; - else if (to == "hsv") - r = rgb_to_hsv (x); - else if (to == "hsl") - r = rgb_to_hsl (x); - else if (to == "YIQ") - r = color (dot (vector(0.299, 0.587, 0.114), (vector)x), - dot (vector(0.596, -0.275, -0.321), (vector)x), - dot (vector(0.212, -0.523, 0.311), (vector)x)); - else if (to == "xyz") - r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x), - dot (vector(0.212671, 0.715160, 0.072169), (vector)x), - dot (vector(0.019334, 0.119193, 0.950227), (vector)x)); - else { - error ("Unknown color space \"%s\"", to); - r = x; - } - return r; + color rgb_to_hsv(color rgb) { // See Foley & van Dam + float r = rgb[0], g = rgb[1], b = rgb[2]; + float mincomp = min(r, min(g, b)); + float maxcomp = max(r, max(g, b)); + float delta = maxcomp - mincomp; // chroma + float h, s, v; + v = maxcomp; + if (maxcomp > 0) + s = delta / maxcomp; + else s = 0; + if (s <= 0) + h = 0; + else { + if (r >= maxcomp) h = (g - b) / delta; + else if (g >= maxcomp) h = 2 + (b - r) / delta; + else h = 4 + (r - g) / delta; + h /= 6; + if (h < 0) + h += 1; + } + return color(h, s, v); + } + + color rgb_to_hsl(color rgb) { // See Foley & van Dam + // First convert rgb to hsv, then to hsl + float minval = min(rgb[0], min(rgb[1], rgb[2])); + color hsv = rgb_to_hsv(rgb); + float maxval = hsv[2]; // v == maxval + float h = hsv[0], s, l = (minval + maxval) / 2; + if (minval == maxval) + s = 0; // special 'achromatic' case, hue is 0 + else if (l <= 0.5) + s = (maxval - minval) / (maxval + minval); + else + s = (maxval - minval) / (2 - maxval - minval); + return color(h, s, l); + } + + color r; + if (to == "rgb" || to == "RGB") + r = x; + else if (to == "hsv") + r = rgb_to_hsv(x); + else if (to == "hsl") + r = rgb_to_hsl(x); + else if (to == "YIQ") + r = color(dot(vector(0.299, 0.587, 0.114), (vector)x), + dot(vector(0.596, -0.275, -0.321), (vector)x), + dot(vector(0.212, -0.523, 0.311), (vector)x)); + else if (to == "xyz") + r = color(dot(vector(0.412453, 0.357580, 0.180423), (vector)x), + dot(vector(0.212671, 0.715160, 0.072169), (vector)x), + dot(vector(0.019334, 0.119193, 0.950227), (vector)x)); + else { + error("Unknown color space \"%s\"", to); + r = x; + } + return r; } -color transformc (string from, string to, color x) +color transformc(string from, string to, color x) { - color hsv_to_rgb (color c) { // Reference: Foley & van Dam - float h = c[0], s = c[1], v = c[2]; - color r; - if (s < 0.0001) { - r = v; - } else { - h = 6 * (h - floor(h)); // expand to [0..6) - int hi = (int)h; - float f = h - hi; - float p = v * (1-s); - float q = v * (1-s*f); - float t = v * (1-s*(1-f)); - if (hi == 0) r = color (v, t, p); - else if (hi == 1) r = color (q, v, p); - else if (hi == 2) r = color (p, v, t); - else if (hi == 3) r = color (p, q, v); - else if (hi == 4) r = color (t, p, v); - else r = color (v, p, q); - } - return r; - } - - color hsl_to_rgb (color c) { - float h = c[0], s = c[1], l = c[2]; - // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam) - float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s); - color r; - if (v <= 0) { - r = 0; - } else { - float min = 2 * l - v; - s = (v - min) / v; - r = hsv_to_rgb (color (h, s, v)); - } - return r; - } - - color r; - if (from == "rgb" || from == "RGB") - r = x; - else if (from == "hsv") - r = hsv_to_rgb (x); - else if (from == "hsl") - r = hsl_to_rgb (x); - else if (from == "YIQ") - r = color (dot (vector(1, 0.9557, 0.6199), (vector)x), - dot (vector(1, -0.2716, -0.6469), (vector)x), - dot (vector(1, -1.1082, 1.7051), (vector)x)); - else if (from == "xyz") - r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x), - dot (vector(-0.969256, 1.875991, 0.041556), (vector)x), - dot (vector( 0.055648, -0.204043, 1.057311), (vector)x)); - else { - error ("Unknown color space \"%s\"", to); - r = x; - } - return transformc (to, r); + color hsv_to_rgb(color c) { // Reference: Foley & van Dam + float h = c[0], s = c[1], v = c[2]; + color r; + if (s < 0.0001) { + r = v; + } + else { + h = 6 * (h - floor(h)); // expand to [0..6) + int hi = (int)h; + float f = h - hi; + float p = v * (1 - s); + float q = v * (1 - s * f); + float t = v * (1 - s * (1 - f)); + if (hi == 0) r = color(v, t, p); + else if (hi == 1) r = color(q, v, p); + else if (hi == 2) r = color(p, v, t); + else if (hi == 3) r = color(p, q, v); + else if (hi == 4) r = color(t, p, v); + else r = color(v, p, q); + } + return r; + } + + color hsl_to_rgb(color c) { + float h = c[0], s = c[1], l = c[2]; + // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam) + float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s); + color r; + if (v <= 0) { + r = 0; + } + else { + float min = 2 * l - v; + s = (v - min) / v; + r = hsv_to_rgb(color(h, s, v)); + } + return r; + } + + color r; + if (from == "rgb" || from == "RGB") + r = x; + else if (from == "hsv") + r = hsv_to_rgb(x); + else if (from == "hsl") + r = hsl_to_rgb(x); + else if (from == "YIQ") + r = color(dot(vector(1, 0.9557, 0.6199), (vector)x), + dot(vector(1, -0.2716, -0.6469), (vector)x), + dot(vector(1, -1.1082, 1.7051), (vector)x)); + else if (from == "xyz") + r = color(dot(vector(3.240479, -1.537150, -0.498535), (vector)x), + dot(vector(-0.969256, 1.875991, 0.041556), (vector)x), + dot(vector(0.055648, -0.204043, 1.057311), (vector)x)); + else { + error("Unknown color space \"%s\"", to); + r = x; + } + return transformc(to, r); } // Matrix functions -float determinant (matrix m) BUILTIN; -matrix transpose (matrix m) BUILTIN; +float determinant(matrix m) BUILTIN; +matrix transpose(matrix m) BUILTIN; // Pattern generation -float step (float edge, float x) BUILTIN; -color step (color edge, color x) BUILTIN; -point step (point edge, point x) BUILTIN; -vector step (vector edge, vector x) BUILTIN; -normal step (normal edge, normal x) BUILTIN; -float smoothstep (float edge0, float edge1, float x) BUILTIN; +float step(float edge, float x) BUILTIN; +color step(color edge, color x) BUILTIN; +point step(point edge, point x) BUILTIN; +vector step(vector edge, vector x) BUILTIN; +normal step(normal edge, normal x) BUILTIN; +float smoothstep(float edge0, float edge1, float x) BUILTIN; // Derivatives and area operators @@ -408,24 +413,26 @@ float smoothstep (float edge0, float edge1, float x) BUILTIN; // String functions -int strlen (string s) BUILTIN; -int startswith (string s, string prefix) BUILTIN; -int endswith (string s, string suffix) BUILTIN; -string substr (string s, int start, int len) BUILTIN; -string substr (string s, int start) { return substr (s, start, strlen(s)); } +int strlen(string s) BUILTIN; +int startswith(string s, string prefix) BUILTIN; +int endswith(string s, string suffix) BUILTIN; +string substr(string s, int start, int len) BUILTIN; +string substr(string s, int start) { + return substr(s, start, strlen(s)); +} // Define concat in terms of shorter concat -string concat (string a, string b, string c) { - return concat(concat(a,b), c); +string concat(string a, string b, string c) { + return concat(concat(a, b), c); } -string concat (string a, string b, string c, string d) { - return concat(concat(a,b,c), d); +string concat(string a, string b, string c, string d) { + return concat(concat(a, b, c), d); } -string concat (string a, string b, string c, string d, string e) { - return concat(concat(a,b,c,d), e); +string concat(string a, string b, string c, string d, string e) { + return concat(concat(a, b, c, d), e); } -string concat (string a, string b, string c, string d, string e, string f) { - return concat(concat(a,b,c,d,e), f); +string concat(string a, string b, string c, string d, string e, string f) { + return concat(concat(a, b, c, d, e), f); } @@ -438,7 +445,7 @@ closure color diffuse(normal N) BUILTIN; closure color oren_nayar(normal N, float sigma) BUILTIN; closure color translucent(normal N) BUILTIN; closure color reflection(normal N, float eta) BUILTIN; -closure color reflection(normal N) { return reflection (N, 0.0); } +closure color reflection(normal N) { return reflection(N, 0.0); } closure color refraction(normal N, float eta) BUILTIN; closure color dielectric(normal N, float eta) BUILTIN; closure color transparent() BUILTIN; @@ -446,7 +453,7 @@ closure color microfacet_ggx(normal N, float ag) BUILTIN; closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN; closure color microfacet_beckmann(normal N, float ab) BUILTIN; closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN; -closure color ward(normal N, vector T,float ax, float ay) BUILTIN; +closure color ward(normal N, vector T, float ax, float ay) BUILTIN; closure color ashikhmin_velvet(normal N, float sigma) BUILTIN; closure color westin_backscatter(normal N, float roughness) BUILTIN; closure color westin_sheen(normal N, float edginess) BUILTIN; @@ -460,7 +467,7 @@ closure color holdout() BUILTIN; closure color subsurface(float eta, float g, float mfp, float albedo) BUILTIN; // Renderer state -int raytype (string typename) BUILTIN; +int raytype(string typename) BUILTIN; #undef BUILTIN #undef BUILTIN_DERIV diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 1b52a3e489b..ca9e47c9f77 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN /* RenderServices implementation */ -#define TO_MATRIX44(m) (*(OSL::Matrix44*)&(m)) +#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m)) /* static ustrings */ ustring OSLRenderServices::u_distance("distance"); @@ -66,12 +66,12 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr { /* this is only used for shader and object space, we don't really have a concept of shader space, so we just use object space for both. */ - if(xform) { + if (xform) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)xform; + const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; - if(object != ~0) { + if (object != ~0) { Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -87,12 +87,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform { /* this is only used for shader and object space, we don't really have a concept of shader space, so we just use object space for both. */ - if(xform) { + if (xform) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)xform; + const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; - if(object != ~0) { + if (object != ~0) { Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -108,22 +108,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti { KernelGlobals *kg = kernel_globals; - if(from == u_ndc) { + if (from == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_raster) { + else if (from == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_screen) { + else if (from == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.screentoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_camera) { + else if (from == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); result = TO_MATRIX44(tfm); return true; @@ -136,22 +136,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl { KernelGlobals *kg = kernel_globals; - if(to == u_ndc) { + if (to == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.worldtondc); result = TO_MATRIX44(tfm); return true; } - else if(to == u_raster) { + else if (to == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); result = TO_MATRIX44(tfm); return true; } - else if(to == u_screen) { + else if (to == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); result = TO_MATRIX44(tfm); return true; } - else if(to == u_camera) { + else if (to == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); result = TO_MATRIX44(tfm); return true; @@ -161,56 +161,57 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl } bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives, - ustring object, TypeDesc type, ustring name, - int index, void *val) + ustring object, TypeDesc type, ustring name, + int index, void *val) { return false; } static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, bool derivatives, void *val) + const OSLGlobals::Attribute& attr, bool derivatives, void *val) { - if(attr.type == TypeDesc::TypeFloat) { - float *fval = (float*)val; + if (attr.type == TypeDesc::TypeFloat) { + float *fval = (float *)val; fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset, - (derivatives)? &fval[1]: NULL, (derivatives)? &fval[2]: NULL); + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); } else { /* todo: this won't work when float3 has w component */ - float3 *fval = (float3*)val; + float3 *fval = (float3 *)val; fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset, - (derivatives)? &fval[1]: NULL, (derivatives)? &fval[2]: NULL); + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); } return true; } static bool get_mesh_attribute_convert(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) + const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) { - if(attr.type == TypeDesc::TypeFloat) { + if (attr.type == TypeDesc::TypeFloat) { float tmp[3]; - float3 *fval = (float3*)val; + float3 *fval = (float3 *)val; get_mesh_attribute(kg, sd, attr, derivatives, tmp); fval[0] = make_float3(tmp[0], tmp[0], tmp[0]); - if(derivatives) { + if (derivatives) { fval[1] = make_float3(tmp[1], tmp[1], tmp[1]); fval[2] = make_float3(tmp[2], tmp[2], tmp[2]); } return true; } - else if(attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || - attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { + else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || + attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) + { float3 tmp[3]; - float *fval = (float*)val; + float *fval = (float *)val; get_mesh_attribute(kg, sd, attr, derivatives, tmp); fval[0] = average(tmp[0]); - if(derivatives) { + if (derivatives) { fval[1] = average(tmp[1]); fval[2] = average(tmp[2]); } @@ -226,29 +227,29 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat size_t datasize = attr.value.datasize(); memcpy(val, attr.value.data(), datasize); - if(derivatives) - memset((char*)val + datasize, 0, datasize*2); + if (derivatives) + memset((char *)val + datasize, 0, datasize * 2); } bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name, - TypeDesc type, ustring name, void *val) + TypeDesc type, ustring name, void *val) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)renderstate; + const ShaderData *sd = (const ShaderData *)renderstate; int object = sd->object; int tri = sd->prim; /* lookup of attribute on another object */ - if(object_name != u_empty) { + if (object_name != u_empty) { OSLGlobals::ObjectNameMap::iterator it = kg->osl.object_name_map.find(object_name); - if(it == kg->osl.object_name_map.end()) + if (it == kg->osl.object_name_map.end()) return false; object = it->second; tri = ~0; } - else if(object == ~0) { + else if (object == ~0) { /* no background attributes supported */ return false; } @@ -257,20 +258,23 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri OSLGlobals::AttributeMap& attribute_map = kg->osl.attribute_map[object]; OSLGlobals::AttributeMap::iterator it = attribute_map.find(name); - if(it == attribute_map.end()) + if (it == attribute_map.end()) return false; /* type mistmatch? */ const OSLGlobals::Attribute& attr = it->second; - if(attr.elem != ATTR_ELEMENT_VALUE) { + if (attr.elem != ATTR_ELEMENT_VALUE) { /* triangle and vertex attributes */ - if(tri != ~0) { - if(attr.type == type || (attr.type == TypeDesc::TypeColor && - (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal))) + if (tri != ~0) { + if (attr.type == type || (attr.type == TypeDesc::TypeColor && + (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal))) + { return get_mesh_attribute(kg, sd, attr, derivatives, val); - else + } + else { return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val); + } } } else { @@ -283,7 +287,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri } bool OSLRenderServices::get_userdata(bool derivatives, ustring name, TypeDesc type, - void *renderstate, void *val) + void *renderstate, void *val) { return false; /* disabled by lockgeom */ } @@ -294,7 +298,7 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, void *renderst } void *OSLRenderServices::get_pointcloud_attr_query(ustring *attr_names, - TypeDesc *attr_types, int nattrs) + TypeDesc *attr_types, int nattrs) { #ifdef WITH_PARTIO m_attr_queries.push_back(AttrQuery()); @@ -308,28 +312,32 @@ void *OSLRenderServices::get_pointcloud_attr_query(ustring *attr_names, to the query. Just to prevent buffer overruns */ query.capacity = -1; - for(int i = 0; i < nattrs; ++i) - { + for (int i = 0; i < nattrs; ++i) { query.attr_names[i] = attr_names[i]; - TypeDesc element_type = attr_types[i].elementtype (); + TypeDesc element_type = attr_types[i].elementtype(); - if(query.capacity < 0) - query.capacity = attr_types[i].numelements(); + if (query.capacity < 0) + query.capacity = attr_types[i].numelements(); else - query.capacity = min(query.capacity, (int)attr_types[i].numelements()); + query.capacity = min(query.capacity, (int)attr_types[i].numelements()); /* convert the OSL (OIIO) type to the equivalent Partio type so we can do a fast check at query time. */ - if(element_type == TypeDesc::TypeFloat) - query.attr_partio_types[i] = Partio::FLOAT; - else if(element_type == TypeDesc::TypeInt) - query.attr_partio_types[i] = Partio::INT; - else if(element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint || - element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal) - query.attr_partio_types[i] = Partio::VECTOR; - else - return NULL; /* report some error of unknown type */ + if (element_type == TypeDesc::TypeFloat) { + query.attr_partio_types[i] = Partio::FLOAT; + } + else if (element_type == TypeDesc::TypeInt) { + query.attr_partio_types[i] = Partio::INT; + } + else if (element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint || + element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal) + { + query.attr_partio_types[i] = Partio::VECTOR; + } + else { + return NULL; /* report some error of unknown type */ + } } /* this is valid until the end of RenderServices */ @@ -348,18 +356,18 @@ Partio::ParticlesData *OSLRenderServices::get_pointcloud(ustring filename) #endif int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius, - int max_points, void *_attr_query, void **attr_outdata) + int max_points, void *_attr_query, void **attr_outdata) { /* todo: this code has never been tested, and most likely does not work. it's based on the example code in OSL */ #ifdef WITH_PARTIO /* query Partio for this pointcloud lookup using cached attr_query */ - if(!_attr_query) + if (!_attr_query) return 0; AttrQuery *attr_query = (AttrQuery *)_attr_query; - if(attr_query->capacity < max_points) + if (attr_query->capacity < max_points) return 0; /* get the pointcloud entry for the given filename */ @@ -370,13 +378,13 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, flo int nattrs = attr_query->attr_names.size(); Partio::ParticleAttribute *attr = (Partio::ParticleAttribute *)alloca(sizeof(Partio::ParticleAttribute) * nattrs); - for(int i = 0; i < nattrs; ++i) { + for (int i = 0; i < nattrs; ++i) { /* special case attributes */ - if(attr_query->attr_names[i] == u_distance || attr_query->attr_names[i] == u_index) + if (attr_query->attr_names[i] == u_distance || attr_query->attr_names[i] == u_index) continue; /* lookup the attribute by name*/ - if(!cloud->attributeInfo(attr_query->attr_names[i].c_str(), attr[i])) { + if (!cloud->attributeInfo(attr_query->attr_names[i].c_str(), attr[i])) { /* issue an error here and return, types don't match */ Partio::endCachedAccess(cloud); cloud->release(); @@ -394,14 +402,14 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, flo int count = indices.size(); /* retrieve the attributes directly to user space */ - for(int j = 0; j < nattrs; ++j) { + for (int j = 0; j < nattrs; ++j) { /* special cases */ - if(attr_query->attr_names[j] == u_distance) { - for(int i = 0; i < count; ++i) + if (attr_query->attr_names[j] == u_distance) { + for (int i = 0; i < count; ++i) ((float *)attr_outdata[j])[i] = sqrtf(dist2[i]); } - else if(attr_query->attr_names[j] == u_index) { - for(int i = 0; i < count; ++i) + else if (attr_query->attr_names[j] == u_index) { + for (int i = 0; i < count; ++i) ((int *)attr_outdata[j])[i] = indices[i]; } else { diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 85a01e54e5c..88735c073c2 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -57,19 +57,19 @@ public: bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time); bool get_array_attribute(void *renderstate, bool derivatives, - ustring object, TypeDesc type, ustring name, - int index, void *val); + ustring object, TypeDesc type, ustring name, + int index, void *val); bool get_attribute(void *renderstate, bool derivatives, ustring object, - TypeDesc type, ustring name, void *val); + TypeDesc type, ustring name, void *val); bool get_userdata(bool derivatives, ustring name, TypeDesc type, - void *renderstate, void *val); + void *renderstate, void *val); bool has_userdata(ustring name, TypeDesc type, void *renderstate); void *get_pointcloud_attr_query(ustring *attr_names, - TypeDesc *attr_types, int nattrs); + TypeDesc *attr_types, int nattrs); int pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius, - int max_points, void *attr_query, void **attr_outdata); + int max_points, void *attr_query, void **attr_outdata); private: KernelGlobals *kernel_globals; @@ -79,8 +79,7 @@ private: right now it only caches the types already converted to Partio constants. this is what get_pointcloud_attr_query returns */ - struct AttrQuery - { + struct AttrQuery { /* names of the attributes to query */ std::vector attr_names; /* types as (enum Partio::ParticleAttributeType) of the diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 18a8e974492..fc28833bb8c 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -37,7 +37,7 @@ tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data); void OSLShader::thread_init(KernelGlobals *kg) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData(); @@ -46,12 +46,12 @@ void OSLShader::thread_init(KernelGlobals *kg) tls_set(kg->osl.thread_data, tdata); - ((OSLRenderServices*)ssi->renderer())->thread_init(kg); + ((OSLRenderServices *)ssi->renderer())->thread_init(kg); } void OSLShader::thread_free(KernelGlobals *kg) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); @@ -62,12 +62,12 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ -#define TO_VEC3(v) (*(OSL::Vec3*)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3*)&(v)) +#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) +#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, - int path_flag, OSL::ShaderGlobals *globals) + int path_flag, OSL::ShaderGlobals *globals) { /* copy from shader data to shader globals */ globals->P = TO_VEC3(sd->P); @@ -86,7 +86,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, globals->dvdy = sd->dv.dy; globals->dPdu = TO_VEC3(sd->dPdu); globals->dPdv = TO_VEC3(sd->dPdv); - globals->surfacearea = (sd->object == ~0)? 1.0f: object_surface_area(kg, sd->object); + globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object); /* booleans */ globals->raytype = path_flag; /* todo: add our own ray types */ @@ -109,35 +109,35 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, /* Surface */ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, - const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) + const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { /* OSL gives use a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim) { + if (prim) { ShaderClosure sc; sc.prim = prim; sc.weight = weight; - switch(prim->category()) { + switch (prim->category()) { case ClosurePrimitive::BSDF: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)prim; + OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim; ustring scattering = bsdf->scattering(); /* no caustics option */ - if(no_glossy && scattering == OSL::Labels::GLOSSY) + if (no_glossy && scattering == OSL::Labels::GLOSSY) return; /* sample weight */ float albedo = bsdf->albedo(TO_VEC3(sd->I)); - float sample_weight = fabsf(average(weight))*albedo; + float sample_weight = fabsf(average(weight)) * albedo; float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight; sc.sample_weight = sample_weight; @@ -145,10 +145,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, sd->osl_closure.bsdf_sample_sum = sample_sum; /* scattering flags */ - if(scattering == OSL::Labels::DIFFUSE) - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; - else if(scattering == OSL::Labels::GLOSSY) - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; + if (scattering == OSL::Labels::DIFFUSE) + sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; + else if (scattering == OSL::Labels::GLOSSY) + sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; else sd->flag |= SD_BSDF; @@ -157,7 +157,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case ClosurePrimitive::Emissive: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; /* sample weight */ @@ -175,7 +175,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case ClosurePrimitive::Holdout: - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; sc.sample_weight = 0.0f; @@ -192,12 +192,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + else if (closure->type == OSL::ClosureColor::MUL) { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight); } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; + else if (closure->type == OSL::ClosureColor::ADD) { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight); flatten_surface_closure_tree(sd, no_glossy, add->closureB, weight); } @@ -206,7 +206,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -218,14 +218,14 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int /* execute shader for this point */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.surface_state[shader]) + if (kg->osl.surface_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals); /* flatten closure tree */ sd->num_closure = 0; sd->randb_closure = randb; - if(globals->Ci) { + if (globals->Ci) { bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics; flatten_surface_closure_tree(sd, no_glossy, globals->Ci); } @@ -239,23 +239,23 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) * is only one supported closure type at the moment, which has no evaluation * functions, so we just sum the weights */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim && prim->category() == OSL::ClosurePrimitive::Background) + if (prim && prim->category() == OSL::ClosurePrimitive::Background) return make_float3(1.0f, 1.0f, 1.0f); } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + else if (closure->type == OSL::ClosureColor::MUL) { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; + else if (closure->type == OSL::ClosureColor::ADD) { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; return flatten_background_closure_tree(add->closureA) + - flatten_background_closure_tree(add->closureB); + flatten_background_closure_tree(add->closureB); } return make_float3(0.0f, 0.0f, 0.0f); @@ -264,7 +264,7 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -274,11 +274,11 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl shaderdata_to_shaderglobals(kg, sd, path_flag, globals); /* execute shader for this point */ - if(kg->osl.background_state) + if (kg->osl.background_state) ctx->execute(OSL::pvt::ShadUseSurface, *kg->osl.background_state, *globals); /* return background color immediately */ - if(globals->Ci) + if (globals->Ci) return flatten_background_closure_tree(globals->Ci); return make_float3(0.0f, 0.0f, 0.0f); @@ -287,23 +287,23 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl /* Volume */ static void flatten_volume_closure_tree(ShaderData *sd, - const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) + const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { /* OSL gives use a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim) { + if (prim) { ShaderClosure sc; sc.prim = prim; sc.weight = weight; - switch(prim->category()) { + switch (prim->category()) { case ClosurePrimitive::Volume: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; /* sample weight */ @@ -329,12 +329,12 @@ static void flatten_volume_closure_tree(ShaderData *sd, } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + else if (closure->type == OSL::ClosureColor::MUL) { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; + else if (closure->type == OSL::ClosureColor::ADD) { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_volume_closure_tree(sd, add->closureA, weight); flatten_volume_closure_tree(sd, add->closureB, weight); } @@ -343,7 +343,7 @@ static void flatten_volume_closure_tree(ShaderData *sd, void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -355,7 +355,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int /* execute shader */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.volume_state[shader]) + if (kg->osl.volume_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals); /* retrieve resulting closures */ @@ -363,7 +363,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int sd->osl_closure.num_volume = 0; sd->osl_closure.randb = randb; - if(globals->Ci) + if (globals->Ci) flatten_volume_closure_tree(sd, globals->Ci); } @@ -372,7 +372,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -384,7 +384,7 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) /* execute shader */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.displacement_state[shader]) + if (kg->osl.displacement_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[shader]), *globals); /* get back position */ @@ -393,17 +393,17 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) void OSLShader::release(KernelGlobals *kg, const ShaderData *sd) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); - ssi->release_context((OSL::pvt::ShadingContext*)sd->osl_ctx, tdata->thread_info); + ssi->release_context((OSL::pvt::ShadingContext *)sd->osl_ctx, tdata->thread_info); } /* BSDF Closure */ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) { - OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure*)sc->prim; + OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim; int label = LABEL_NONE; pdf = 0.0f; @@ -412,27 +412,27 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float ustring ulabel; ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng), - TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), - randu, randv, - TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), - pdf, TO_COLOR3(eval)); + TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), + randu, randv, + TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), + pdf, TO_COLOR3(eval)); /* convert OSL label */ - if(ulabel == OSL::Labels::REFLECT) + if (ulabel == OSL::Labels::REFLECT) label = LABEL_REFLECT; - else if(ulabel == OSL::Labels::TRANSMIT) + else if (ulabel == OSL::Labels::TRANSMIT) label = LABEL_TRANSMIT; else - return LABEL_NONE; /* sampling failed */ + return LABEL_NONE; /* sampling failed */ /* convert scattering to our bitflag label */ ustring uscattering = sample_bsdf->scattering(); - if(uscattering == OSL::Labels::DIFFUSE) + if (uscattering == OSL::Labels::DIFFUSE) label |= LABEL_DIFFUSE; - else if(uscattering == OSL::Labels::GLOSSY) + else if (uscattering == OSL::Labels::GLOSSY) label |= LABEL_GLOSSY; - else if(uscattering == OSL::Labels::SINGULAR) + else if (uscattering == OSL::Labels::SINGULAR) label |= LABEL_SINGULAR; else label |= LABEL_TRANSPARENT; @@ -442,10 +442,10 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf) { - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)sc->prim; + OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim; OSL::Color3 bsdf_eval; - if(dot(sd->Ng, omega_in) >= 0.0f) + if (dot(sd->Ng, omega_in) >= 0.0f) bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); else bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); @@ -457,7 +457,7 @@ float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) { - OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure*)sc->prim; + OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure *)sc->prim; OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I)); eval += TO_FLOAT3(emissive_eval); @@ -468,9 +468,9 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { - OSL::VolumeClosure *volume = (OSL::VolumeClosure*)sc->prim; + OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim; OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out)); - return TO_FLOAT3(volume_eval)*sc->weight; + return TO_FLOAT3(volume_eval) * sc->weight; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index 6b1d402989b..815557ed203 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -68,15 +68,15 @@ public: /* sample & eval */ static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, - float randu, float randv, - float3& eval, float3& omega_in, differential3& domega_in, float& pdf); + float randu, float randv, + float3& eval, float3& omega_in, differential3& domega_in, float& pdf); static float3 bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, - const float3& omega_in, float& pdf); + const float3& omega_in, float& pdf); static float3 emissive_eval(const ShaderData *sd, const ShaderClosure *sc); static float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, - const float3 omega_in, const float3 omega_out); + const float3 omega_in, const float3 omega_out); /* release */ static void release(KernelGlobals *kg, const ShaderData *sd); diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp index 0cd3060051b..818a057b6cc 100644 --- a/intern/cycles/kernel/osl/vol_subsurface.cpp +++ b/intern/cycles/kernel/osl/vol_subsurface.cpp @@ -46,88 +46,90 @@ using namespace OSL; class SubsurfaceClosure : public VolumeClosure { public: - float m_g; - float m_eta; - Color3 m_mfp, m_albedo; - static float root_find_Rd(const float Rd0, const float A) { - // quick exit for trivial cases - if (Rd0 <= 0) return 0; - const float A43 = A * 4.0f / 3.0f; - // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection - // method can be used because this function is monotonicaly increasing. - float lo = 0, hi = 1; - for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient - // eval function at midpoint - float alpha = 0.5f * (lo + hi); - float a1 = sqrtf(3 * (1 - alpha)); - float e1 = expf(-a1); - float e2 = expf(-A43 * a1); - float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; - if (fabsf(Rd) < 1e-6f) - return alpha; // close enough - else if (Rd > 0) - hi = alpha; // root is on left side - else - lo = alpha; // root is on right side - } - // didn't quite converge, pick result in the middle of remaining interval - return 0.5f * (lo + hi); - } - SubsurfaceClosure() { } - - void setup() - { - ior(m_eta); - - if (m_g >= 0.99f) m_g = 0.99f; - if (m_g <= -0.99f) m_g = -0.99f; - - // eq.10 - float inv_eta = 1 / m_eta; - float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; - float A = (1 + Fdr) / (1 - Fdr); - // compute sigma_s, sigma_a (eq.16) - Color3 alpha_prime = Color3 (root_find_Rd(m_albedo[0], A), - root_find_Rd(m_albedo[1], A), - root_find_Rd(m_albedo[2], A)); - Color3 sigma_t_prime = Color3 (m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, - m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, - m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); - Color3 sigma_s_prime = alpha_prime * sigma_t_prime; - - sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); - sigma_a(sigma_t_prime - sigma_s_prime); - } - - bool mergeable (const ClosurePrimitive *other) const { - const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; - return m_g == comp->m_g && VolumeClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "subsurface"; } - - void print_on (std::ostream &out) const { - out << name() << " ()"; - } - - virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { - float costheta = omega_in.dot(omega_out); - float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); - return Color3 (ph, ph, ph); - } + float m_g; + float m_eta; + Color3 m_mfp, m_albedo; + static float root_find_Rd(const float Rd0, const float A) { + // quick exit for trivial cases + if (Rd0 <= 0) return 0; + const float A43 = A * 4.0f / 3.0f; + // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection + // method can be used because this function is monotonicaly increasing. + float lo = 0, hi = 1; + for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient + // eval function at midpoint + float alpha = 0.5f * (lo + hi); + float a1 = sqrtf(3 * (1 - alpha)); + float e1 = expf(-a1); + float e2 = expf(-A43 * a1); + float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; + if (fabsf(Rd) < 1e-6f) + return alpha; // close enough + else if (Rd > 0) + hi = alpha; // root is on left side + else + lo = alpha; // root is on right side + } + // didn't quite converge, pick result in the middle of remaining interval + return 0.5f * (lo + hi); + } + SubsurfaceClosure() { + } + + void setup() + { + ior(m_eta); + + if (m_g >= 0.99f) m_g = 0.99f; + if (m_g <= -0.99f) m_g = -0.99f; + + // eq.10 + float inv_eta = 1 / m_eta; + float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; + float A = (1 + Fdr) / (1 - Fdr); + // compute sigma_s, sigma_a (eq.16) + Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A), + root_find_Rd(m_albedo[1], A), + root_find_Rd(m_albedo[2], A)); + Color3 sigma_t_prime = Color3(m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, + m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, + m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); + Color3 sigma_s_prime = alpha_prime * sigma_t_prime; + + sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); + sigma_a(sigma_t_prime - sigma_s_prime); + } + + bool mergeable(const ClosurePrimitive *other) const { + const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; + return m_g == comp->m_g && VolumeClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "subsurface"; } + + void print_on(std::ostream &out) const { + out << name() << " ()"; + } + + virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { + float costheta = omega_in.dot(omega_out); + float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); + return Color3(ph, ph, ph); + } }; ClosureParam closure_subsurface_params[] = { - CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_eta), - CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_g), - CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_mfp), - CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_albedo), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(SubsurfaceClosure) }; + CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta), + CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g), + CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp), + CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(SubsurfaceClosure) +}; CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure) -- cgit v1.2.3