style cleanup

This commit is contained in:
Campbell Barton
2012-06-04 22:44:58 +00:00
parent f94123a5c6
commit 2d290040a1
22 changed files with 1682 additions and 1635 deletions

View File

@@ -48,15 +48,15 @@ using namespace OSL;
/// ///
class GenericBackgroundClosure : public BackgroundClosure { class GenericBackgroundClosure : public BackgroundClosure {
public: 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 { void print_on(std::ostream &out) const {
out << name() << " ()"; out << name() << " ()";
} }
@@ -72,27 +72,29 @@ public:
/// ///
class HoldoutClosure : ClosurePrimitive { class HoldoutClosure : ClosurePrimitive {
public: 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 { void print_on(std::ostream &out) const {
out << name() << " ()"; out << name() << " ()";
} }
}; };
ClosureParam closure_background_params[] = { ClosureParam closure_background_params[] = {
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; CLOSURE_FINISH_PARAM(GenericBackgroundClosure)
};
CLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure) CLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure)
ClosureParam closure_holdout_params[] = { ClosureParam closure_holdout_params[] = {
CLOSURE_FINISH_PARAM(HoldoutClosure) }; CLOSURE_FINISH_PARAM(HoldoutClosure)
};
CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)

View File

@@ -48,25 +48,25 @@ public:
float m_sigma; float m_sigma;
float m_invsigma2; float m_invsigma2;
AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) { } AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {}
void setup() void setup()
{ {
m_sigma = max(m_sigma, 0.01f); m_sigma = max(m_sigma, 0.01f);
m_invsigma2 = 1.0f/(m_sigma * m_sigma); m_invsigma2 = 1.0f / (m_sigma * m_sigma);
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other;
return m_N == comp->m_N && m_sigma == comp->m_sigma && return m_N == comp->m_N && m_sigma == comp->m_sigma &&
BSDFClosure::mergeable(other); BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "ashikhmin_velvet"; } const char *name() const { return "ashikhmin_velvet"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
@@ -74,12 +74,12 @@ public:
out << ")"; out << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
@@ -106,17 +106,17 @@ public:
float out = 0.25f * (D * G) / cosNO; float out = 0.25f * (D * G) / cosNO;
pdf = 0.5f * (float) M_1_PI; pdf = 0.5f * (float) M_1_PI;
return Color3 (out, out, out); return Color3(out, out, out);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -124,7 +124,7 @@ public:
{ {
// we are viewing the surface from above - send a ray out with uniform // we are viewing the surface from above - send a ray out with uniform
// distribution over the hemisphere // distribution over the hemisphere
sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
if (Ng.dot(omega_in) > 0) { if (Ng.dot(omega_in) > 0) {
Vec3 H = omega_in + omega_out; Vec3 H = omega_in + omega_out;
H.normalize(); H.normalize();
@@ -156,7 +156,8 @@ public:
domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
domega_in_dx *= 125; domega_in_dx *= 125;
domega_in_dy *= 125; domega_in_dy *= 125;
} else }
else
pdf = 0; pdf = 0;
return Labels::REFLECT; return Labels::REFLECT;
} }
@@ -167,9 +168,10 @@ public:
ClosureParam bsdf_ashikhmin_velvet_params[] = { ClosureParam bsdf_ashikhmin_velvet_params[] = {
CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N),
CLOSURE_FLOAT_PARAM (AshikhminVelvetClosure, m_sigma), CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) }; CLOSURE_FINISH_PARAM(AshikhminVelvetClosure)
};
CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure)

View File

@@ -46,42 +46,42 @@ class DiffuseClosure : public BSDFClosure {
public: public:
Vec3 m_N; Vec3 m_N;
DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) { } DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {}
void setup() {}; void setup() {};
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const DiffuseClosure *comp = (const DiffuseClosure *)other; const DiffuseClosure *comp = (const DiffuseClosure *)other;
return m_N == comp->m_N && BSDFClosure::mergeable(other); return m_N == comp->m_N && BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "diffuse"; } const char *name() const { return "diffuse"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const 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; float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI;
pdf = cos_pi; pdf = cos_pi;
return Color3 (cos_pi, cos_pi, cos_pi); return Color3(cos_pi, cos_pi, cos_pi);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -89,7 +89,7 @@ public:
{ {
// we are viewing the surface from the right side - send a ray out with cosine // we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere // distribution over the hemisphere
sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
if (Ng.dot(omega_in) > 0) { if (Ng.dot(omega_in) > 0) {
eval.setValue(pdf, pdf, pdf); eval.setValue(pdf, pdf, pdf);
// TODO: find a better approximation for the diffuse bounce // TODO: find a better approximation for the diffuse bounce
@@ -97,7 +97,8 @@ public:
domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
domega_in_dx *= 125; domega_in_dx *= 125;
domega_in_dy *= 125; domega_in_dy *= 125;
} else }
else
pdf = 0; pdf = 0;
return Labels::REFLECT; return Labels::REFLECT;
} }
@@ -109,42 +110,42 @@ class TranslucentClosure : public BSDFClosure {
public: public:
Vec3 m_N; Vec3 m_N;
TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) { } TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {}
void setup() {}; void setup() {};
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const TranslucentClosure *comp = (const TranslucentClosure *)other; const TranslucentClosure *comp = (const TranslucentClosure *)other;
return m_N == comp->m_N && BSDFClosure::mergeable(other); return m_N == comp->m_N && BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "translucent"; } const char *name() const { return "translucent"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; 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 Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const 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; float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI;
pdf = cos_pi; pdf = cos_pi;
return Color3 (cos_pi, cos_pi, cos_pi); return Color3(cos_pi, cos_pi, cos_pi);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -152,7 +153,7 @@ public:
{ {
// we are viewing the surface from the right side - send a ray out with cosine // we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere // distribution over the hemisphere
sample_cos_hemisphere (-m_N, omega_out, randu, randv, omega_in, pdf); sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf);
if (Ng.dot(omega_in) < 0) { if (Ng.dot(omega_in) < 0) {
eval.setValue(pdf, pdf, pdf); eval.setValue(pdf, pdf, pdf);
// TODO: find a better approximation for the diffuse bounce // TODO: find a better approximation for the diffuse bounce
@@ -160,21 +161,24 @@ public:
domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
domega_in_dx *= -125; domega_in_dx *= -125;
domega_in_dy *= -125; domega_in_dy *= -125;
} else }
else
pdf = 0; pdf = 0;
return Labels::TRANSMIT; return Labels::TRANSMIT;
} }
}; };
ClosureParam bsdf_diffuse_params[] = { ClosureParam bsdf_diffuse_params[] = {
CLOSURE_VECTOR_PARAM (DiffuseClosure, m_N), CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM (DiffuseClosure) }; CLOSURE_FINISH_PARAM(DiffuseClosure)
};
ClosureParam bsdf_translucent_params[] = { ClosureParam bsdf_translucent_params[] = {
CLOSURE_VECTOR_PARAM (TranslucentClosure, m_N), CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM (TranslucentClosure) }; CLOSURE_FINISH_PARAM(TranslucentClosure)
};
CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure) CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure)
CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure) CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure)

View File

@@ -62,19 +62,19 @@ public:
m_ag = clamp(m_ag, 1e-5f, 1.0f); m_ag = clamp(m_ag, 1e-5f, 1.0f);
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other;
return m_N == comp->m_N && m_ag == comp->m_ag && return m_N == comp->m_N && m_ag == comp->m_ag &&
m_eta == comp->m_eta && BSDFClosure::mergeable(other); 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 { const char *name() const {
return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx";
} }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
out << m_ag << ", "; out << m_ag << ", ";
@@ -82,14 +82,14 @@ public:
out << ")"; out << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
if (Refractive == 1) return Color3 (0, 0, 0); if (Refractive == 1) return Color3(0, 0, 0);
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
if (cosNI > 0 && cosNO > 0) { if (cosNI > 0 && cosNO > 0) {
@@ -115,18 +115,18 @@ public:
// eq. 38 - but see also: // eq. 38 - but see also:
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
pdf = pm * 0.25f / Hr.dot(omega_out); pdf = pm * 0.25f / Hr.dot(omega_out);
return Color3 (out, out, out); return Color3(out, out, out);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
if (Refractive == 0) return Color3 (0, 0, 0); if (Refractive == 0) return Color3(0, 0, 0);
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
if (cosNO <= 0 || cosNI >= 0) if (cosNO <= 0 || cosNI >= 0)
return Color3 (0, 0, 0); // vectors on same side -- not possible return Color3(0, 0, 0); // vectors on same side -- not possible
// compute half-vector of the refraction (eq. 16) // compute half-vector of the refraction (eq. 16)
Vec3 ht = -(m_eta * omega_in + omega_out); Vec3 ht = -(m_eta * omega_in + omega_out);
Vec3 Ht = ht; Ht.normalize(); Vec3 Ht = ht; Ht.normalize();
@@ -148,10 +148,10 @@ public:
float invHt2 = 1 / ht.dot(ht); float invHt2 = 1 / ht.dot(ht);
pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
return Color3 (out, out, out); return Color3(out, out, out);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -213,7 +213,8 @@ public:
#endif #endif
} }
} }
} else { }
else {
// CAUTION: the i and o variables are inverted relative to the paper // CAUTION: the i and o variables are inverted relative to the paper
// eq. 39 - compute actual refractive direction // eq. 39 - compute actual refractive direction
Vec3 R, dRdx, dRdy; Vec3 R, dRdx, dRdy;
@@ -274,27 +275,30 @@ public:
Vec3 m_N; Vec3 m_N;
float m_ab; // width parameter (roughness) float m_ab; // width parameter (roughness)
float m_eta; // index of refraction (for fresnel term) float m_eta; // index of refraction (for fresnel term)
MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { } MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) {
}
void setup() void setup()
{ {
m_ab = clamp(m_ab, 1e-5f, 1.0f); m_ab = clamp(m_ab, 1e-5f, 1.0f);
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other;
return m_N == comp->m_N && m_ab == comp->m_ab && return m_N == comp->m_N && m_ab == comp->m_ab &&
m_eta == comp->m_eta && BSDFClosure::mergeable(other); 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 { const char *name() const {
return Refractive ? "microfacet_beckmann_refraction" return Refractive ? "microfacet_beckmann_refraction"
: "microfacet_beckmann"; : "microfacet_beckmann";
} }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
@@ -303,14 +307,14 @@ public:
out << ")"; out << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
if (Refractive == 1) return Color3 (0, 0, 0); if (Refractive == 1) return Color3(0, 0, 0);
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
if (cosNO > 0 && cosNI > 0) { if (cosNO > 0 && cosNI > 0) {
@@ -338,18 +342,18 @@ public:
// eq. 38 - but see also: // eq. 38 - but see also:
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
pdf = pm * 0.25f / Hr.dot(omega_out); pdf = pm * 0.25f / Hr.dot(omega_out);
return Color3 (out, out, out); return Color3(out, out, out);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
if (Refractive == 0) return Color3 (0, 0, 0); if (Refractive == 0) return Color3(0, 0, 0);
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
if (cosNO <= 0 || cosNI >= 0) if (cosNO <= 0 || cosNI >= 0)
return Color3 (0, 0, 0); return Color3(0, 0, 0);
// compute half-vector of the refraction (eq. 16) // compute half-vector of the refraction (eq. 16)
Vec3 ht = -(m_eta * omega_in + omega_out); Vec3 ht = -(m_eta * omega_in + omega_out);
Vec3 Ht = ht; Ht.normalize(); Vec3 Ht = ht; Ht.normalize();
@@ -373,10 +377,10 @@ public:
float invHt2 = 1 / ht.dot(ht); float invHt2 = 1 / ht.dot(ht);
pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
return Color3 (out, out, out); return Color3(out, out, out);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -441,7 +445,8 @@ public:
#endif #endif
} }
} }
} else { }
else {
// CAUTION: the i and o variables are inverted relative to the paper // CAUTION: the i and o variables are inverted relative to the paper
// eq. 39 - compute actual refractive direction // eq. 39 - compute actual refractive direction
Vec3 R, dRdx, dRdy; Vec3 R, dRdx, dRdy;
@@ -500,29 +505,33 @@ public:
ClosureParam bsdf_microfacet_ggx_params[] = { ClosureParam bsdf_microfacet_ggx_params[] = {
CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N),
CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<0>, m_ag), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) }; CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>)
};
ClosureParam bsdf_microfacet_ggx_refraction_params[] = { ClosureParam bsdf_microfacet_ggx_refraction_params[] = {
CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N),
CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_ag), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag),
CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_eta), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) }; CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>)
};
ClosureParam bsdf_microfacet_beckmann_params[] = { ClosureParam bsdf_microfacet_beckmann_params[] = {
CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N),
CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<0>, m_ab), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) }; CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>)
};
ClosureParam bsdf_microfacet_beckmann_refraction_params[] = { ClosureParam bsdf_microfacet_beckmann_refraction_params[] = {
CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N),
CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_ab), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab),
CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_eta), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) }; CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>)
};
CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>) CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>)
CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>) CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>)

View File

@@ -26,13 +26,13 @@ CCL_NAMESPACE_BEGIN
using namespace OSL; using namespace OSL;
class OrenNayarClosure: public BSDFClosure { class OrenNayarClosure : public BSDFClosure {
public: public:
Vec3 m_N; Vec3 m_N;
float m_sigma; float m_sigma;
float m_a, m_b; float m_a, m_b;
OrenNayarClosure(): BSDFClosure(Labels::DIFFUSE) {} OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {}
void setup() { void setup() {
m_sigma = clamp(m_sigma, 0.0f, 1.0f); m_sigma = clamp(m_sigma, 0.0f, 1.0f);
@@ -43,8 +43,8 @@ public:
m_b = m_sigma * div; m_b = m_sigma * div;
} }
bool mergeable(const ClosurePrimitive* other) const { bool mergeable(const ClosurePrimitive *other) const {
const OrenNayarClosure* comp = static_cast<const OrenNayarClosure*>(other); const OrenNayarClosure *comp = static_cast<const OrenNayarClosure *>(other);
return return
m_N == comp->m_N && m_N == comp->m_N &&
m_sigma == comp->m_sigma && m_sigma == comp->m_sigma &&
@@ -55,7 +55,7 @@ public:
return sizeof(*this); return sizeof(*this);
} }
const char* name() const { const char *name() const {
return "oren_nayar"; return "oren_nayar";
} }
@@ -93,7 +93,7 @@ public:
Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy,
float& pdf, Color3& eval float& pdf, Color3& eval
) const { ) const {
sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
if (Ng.dot(omega_in) > 0.0f) { if (Ng.dot(omega_in) > 0.0f) {
float is = get_intensity(m_N, omega_out, omega_in); float is = get_intensity(m_N, omega_out, omega_in);
@@ -118,7 +118,7 @@ private:
float nv = max(n.dot(v), 0.0f); float nv = max(n.dot(v), 0.0f);
float t = l.dot(v) - nl * nv; float t = l.dot(v) - nl * nv;
if(t > 0.0f) { if (t > 0.0f) {
t /= max(nl, nv) + 1e-8f; t /= max(nl, nv) + 1e-8f;
} }
return nl * (m_a + m_b * t); return nl * (m_a + m_b * t);
@@ -126,10 +126,10 @@ private:
}; };
ClosureParam bsdf_oren_nayar_params[] = { ClosureParam bsdf_oren_nayar_params[] = {
CLOSURE_VECTOR_PARAM (OrenNayarClosure, m_N), CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N),
CLOSURE_FLOAT_PARAM (OrenNayarClosure, m_sigma), CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma),
CLOSURE_STRING_KEYPARAM ("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM (OrenNayarClosure) CLOSURE_FINISH_PARAM(OrenNayarClosure)
}; };
CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure) CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure)

View File

@@ -43,40 +43,40 @@ using namespace OSL;
class ReflectionClosure : public BSDFClosure { class ReflectionClosure : public BSDFClosure {
public: public:
Vec3 m_N; // shading normal Vec3 m_N; // shading normal
ReflectionClosure() : BSDFClosure(Labels::SINGULAR) { } ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {}
void setup() {}; void setup() {};
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const ReflectionClosure *comp = (const ReflectionClosure *)other; const ReflectionClosure *comp = (const ReflectionClosure *)other;
return m_N == comp->m_N && BSDFClosure::mergeable(other); return m_N == comp->m_N && BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "reflection"; } const char *name() const { return "reflection"; }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -100,7 +100,8 @@ public:
ClosureParam bsdf_reflection_params[] = { ClosureParam bsdf_reflection_params[] = {
CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(ReflectionClosure) }; CLOSURE_FINISH_PARAM(ReflectionClosure)
};
CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure) CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure)

View File

@@ -44,43 +44,43 @@ class RefractionClosure : public BSDFClosure {
public: public:
Vec3 m_N; // shading normal Vec3 m_N; // shading normal
float m_eta; // ratio of indices of refraction (inside / outside) float m_eta; // ratio of indices of refraction (inside / outside)
RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) { } RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {}
void setup() {} void setup() {}
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const RefractionClosure *comp = (const RefractionClosure *)other; const RefractionClosure *comp = (const RefractionClosure *)other;
return m_N == comp->m_N && m_eta == comp->m_eta && return m_N == comp->m_N && m_eta == comp->m_eta &&
BSDFClosure::mergeable(other); 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 { void print_on(std::ostream &out) const {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
out << m_eta; out << m_eta;
out << ")"; out << ")";
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -110,9 +110,10 @@ public:
ClosureParam bsdf_refraction_params[] = { ClosureParam bsdf_refraction_params[] = {
CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), CLOSURE_VECTOR_PARAM(RefractionClosure, m_N),
CLOSURE_FLOAT_PARAM (RefractionClosure, m_eta), CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(RefractionClosure) }; CLOSURE_FINISH_PARAM(RefractionClosure)
};
CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure) CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure)

View File

@@ -42,34 +42,34 @@ using namespace OSL;
class TransparentClosure : public BSDFClosure { class TransparentClosure : public BSDFClosure {
public: public:
TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) { } TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {}
void setup() {} void setup() {}
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "transparent"; } const char *name() const { return "transparent"; }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << " ()"; out << name() << " ()";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -89,7 +89,8 @@ public:
ClosureParam bsdf_transparent_params[] = { ClosureParam bsdf_transparent_params[] = {
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(TransparentClosure) }; CLOSURE_FINISH_PARAM(TransparentClosure)
};
CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure)

View File

@@ -49,7 +49,7 @@ public:
Vec3 m_N; Vec3 m_N;
Vec3 m_T; Vec3 m_T;
float m_ax, m_ay; float m_ax, m_ay;
WardClosure() : BSDFClosure(Labels::GLOSSY) { } WardClosure() : BSDFClosure(Labels::GLOSSY) {}
void setup() void setup()
{ {
@@ -57,30 +57,30 @@ public:
m_ay = clamp(m_ay, 1e-5f, 1.0f); m_ay = clamp(m_ay, 1e-5f, 1.0f);
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const WardClosure *comp = (const WardClosure *)other; const WardClosure *comp = (const WardClosure *)other;
return m_N == comp->m_N && m_T == comp->m_T && return m_N == comp->m_N && m_T == comp->m_T &&
m_ax == comp->m_ax && m_ay == comp->m_ay && m_ax == comp->m_ax && m_ay == comp->m_ay &&
BSDFClosure::mergeable(other); BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "ward"; } const char *name() const { return "ward"; }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << " (("; out << name() << " ((";
out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), (";
out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), ";
out << m_ax << ", " << m_ay << ")"; out << m_ax << ", " << m_ay << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
float cosNI = m_N.dot(omega_in); float cosNI = m_N.dot(omega_in);
@@ -101,17 +101,17 @@ public:
float oh = H.dot(omega_out); float oh = H.dot(omega_out);
denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn;
pdf = exp_val / denom; pdf = exp_val / denom;
return Color3 (out, out, out); return Color3(out, out, out);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -134,19 +134,22 @@ public:
float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
sinPhi = tanPhi * cosPhi; sinPhi = tanPhi * cosPhi;
} else if (randu < 0.5) { }
else if (randu < 0.5) {
float val = 1 - 4 * (0.5f - randu); float val = 1 - 4 * (0.5f - randu);
float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
// phi = (float) M_PI - phi; // phi = (float) M_PI - phi;
cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
sinPhi = -tanPhi * cosPhi; sinPhi = -tanPhi * cosPhi;
} else if (randu < 0.75f) { }
else if (randu < 0.75f) {
float val = 4 * (randu - 0.5f); float val = 4 * (randu - 0.5f);
float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
//phi = (float) M_PI + phi; //phi = (float) M_PI + phi;
cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
sinPhi = tanPhi * cosPhi; sinPhi = tanPhi * cosPhi;
} else { }
else {
float val = 1 - 4 * (1 - randu); float val = 1 - 4 * (1 - randu);
float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
// phi = 2 * (float) M_PI - phi; // phi = 2 * (float) M_PI - phi;
@@ -211,10 +214,11 @@ public:
ClosureParam bsdf_ward_params[] = { ClosureParam bsdf_ward_params[] = {
CLOSURE_VECTOR_PARAM(WardClosure, m_N), CLOSURE_VECTOR_PARAM(WardClosure, m_N),
CLOSURE_VECTOR_PARAM(WardClosure, m_T), CLOSURE_VECTOR_PARAM(WardClosure, m_T),
CLOSURE_FLOAT_PARAM (WardClosure, m_ax), CLOSURE_FLOAT_PARAM(WardClosure, m_ax),
CLOSURE_FLOAT_PARAM (WardClosure, m_ay), CLOSURE_FLOAT_PARAM(WardClosure, m_ay),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(WardClosure) }; CLOSURE_FINISH_PARAM(WardClosure)
};
CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure) CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure)

View File

@@ -47,7 +47,7 @@ public:
Vec3 m_N; Vec3 m_N;
float m_roughness; float m_roughness;
float m_invroughness; float m_invroughness;
WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) { } WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {}
void setup() void setup()
{ {
@@ -55,17 +55,17 @@ public:
m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0;
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other;
return m_N == comp->m_N && m_roughness == comp->m_roughness && return m_N == comp->m_N && m_roughness == comp->m_roughness &&
BSDFClosure::mergeable(other); BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "westin_backscatter"; } const char *name() const { return "westin_backscatter"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
@@ -73,12 +73,12 @@ public:
out << ")"; out << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
{ {
// pdf is implicitly 0 (no indirect sampling) // pdf is implicitly 0 (no indirect sampling)
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
@@ -87,17 +87,17 @@ public:
float cosine = omega_out.dot(omega_in); float cosine = omega_out.dot(omega_in);
pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0;
pdf *= 0.5f * float(M_1_PI); pdf *= 0.5f * float(M_1_PI);
return Color3 (pdf, pdf, pdf); return Color3(pdf, pdf, pdf);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -108,14 +108,14 @@ public:
domega_in_dx = domega_out_dx; domega_in_dx = domega_out_dx;
domega_in_dy = domega_out_dy; domega_in_dy = domega_out_dy;
Vec3 T, B; Vec3 T, B;
make_orthonormals (omega_out, T, B); make_orthonormals(omega_out, T, B);
float phi = 2 * (float) M_PI * randu; float phi = 2 * (float) M_PI * randu;
float cosTheta = powf(randv, 1 / (m_invroughness + 1)); float cosTheta = powf(randv, 1 / (m_invroughness + 1));
float sinTheta2 = 1 - cosTheta * cosTheta; float sinTheta2 = 1 - cosTheta * cosTheta;
float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
omega_in = (cosf(phi) * sinTheta) * T + omega_in = (cosf(phi) * sinTheta) * T +
(sinf(phi) * sinTheta) * B + (sinf(phi) * sinTheta) * B +
( cosTheta) * omega_out; (cosTheta) * omega_out;
if (Ng.dot(omega_in) > 0) if (Ng.dot(omega_in) > 0)
{ {
// common terms for pdf and eval // common terms for pdf and eval
@@ -146,21 +146,21 @@ public:
Vec3 m_N; Vec3 m_N;
float m_edginess; float m_edginess;
// float m_normalization; // float m_normalization;
WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) { } WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {}
void setup() {}; void setup() {};
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const WestinSheenClosure *comp = (const WestinSheenClosure *)other; const WestinSheenClosure *comp = (const WestinSheenClosure *)other;
return m_N == comp->m_N && m_edginess == comp->m_edginess && return m_N == comp->m_N && m_edginess == comp->m_edginess &&
BSDFClosure::mergeable(other); BSDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "westin_sheen"; } const char *name() const { return "westin_sheen"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ("; out << name() << " (";
out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
@@ -168,12 +168,12 @@ public:
out << ")"; out << ")";
} }
float albedo (const Vec3 &omega_out) const float albedo(const Vec3 &omega_out) const
{ {
return 1.0f; return 1.0f;
} }
Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
{ {
// pdf is implicitly 0 (no indirect sampling) // pdf is implicitly 0 (no indirect sampling)
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
@@ -182,17 +182,17 @@ public:
float sinNO2 = 1 - cosNO * cosNO; float sinNO2 = 1 - cosNO * cosNO;
pdf = cosNI * float(M_1_PI); pdf = cosNI * float(M_1_PI);
float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0;
return Color3 (westin, westin, westin); return Color3(westin, westin, westin);
} }
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
{ {
return Color3 (0, 0, 0); return Color3(0, 0, 0);
} }
ustring sample (const Vec3 &Ng, ustring sample(const Vec3 &Ng,
const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
float randu, float randv, float randu, float randv,
Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
@@ -200,7 +200,7 @@ public:
{ {
// we are viewing the surface from the right side - send a ray out with cosine // we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere // distribution over the hemisphere
sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
if (Ng.dot(omega_in) > 0) { if (Ng.dot(omega_in) > 0) {
// TODO: account for sheen when sampling // TODO: account for sheen when sampling
float cosNO = m_N.dot(omega_out); float cosNO = m_N.dot(omega_out);
@@ -212,8 +212,10 @@ public:
domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
domega_in_dx *= 125; domega_in_dx *= 125;
domega_in_dy *= 125; domega_in_dy *= 125;
} else }
else {
pdf = 0; pdf = 0;
}
return Labels::REFLECT; return Labels::REFLECT;
} }
}; };
@@ -222,15 +224,17 @@ public:
ClosureParam bsdf_westin_backscatter_params[] = { ClosureParam bsdf_westin_backscatter_params[] = {
CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N),
CLOSURE_FLOAT_PARAM (WestinBackscatterClosure, m_roughness), CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(WestinBackscatterClosure) }; CLOSURE_FINISH_PARAM(WestinBackscatterClosure)
};
ClosureParam bsdf_westin_sheen_params[] = { ClosureParam bsdf_westin_sheen_params[] = {
CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N),
CLOSURE_FLOAT_PARAM (WestinSheenClosure, m_edginess), CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(WestinSheenClosure) }; CLOSURE_FINISH_PARAM(WestinSheenClosure)
};
CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure) CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure)
CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure) CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure)

View File

@@ -47,43 +47,43 @@ public:
float m_max_radius; float m_max_radius;
template <typename T> template <typename T>
static inline T pow3 (const T &x) { return x * x * x; } static inline T pow3(const T &x) { return x * x * x; }
template <typename T> template <typename T>
static inline T pow5 (const T &x) { T x2 = x * x; return x2 * x2 * x; } static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; }
BSSRDFCubicClosure() { } BSSRDFCubicClosure() {}
void setup() void setup()
{ {
// pre-compute some terms // pre-compute some terms
m_max_radius = 0; m_max_radius = 0;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
m_scale[i] = m_radius[i] > 0 ? 4 / pow5 (m_radius[i]) : 0; m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0;
m_max_radius = std::max (m_max_radius, m_radius[i]); m_max_radius = std::max(m_max_radius, m_radius[i]);
} }
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other;
return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "bssrdf_cubic"; } const char *name() const { return "bssrdf_cubic"; }
void print_on (std::ostream &out) const void print_on(std::ostream &out) const
{ {
out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), ("
<< m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))";
} }
Color3 eval (float r) const Color3 eval(float r) const
{ {
return Color3 ((r < m_radius.x) ? pow3 (m_radius.x - r) * m_scale.x : 0, 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.y) ? pow3(m_radius.y - r) * m_scale.y : 0,
(r < m_radius.z) ? pow3 (m_radius.z - r) * m_scale.z : 0); (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0);
} }
float max_radius() const float max_radius() const
@@ -95,9 +95,10 @@ public:
ClosureParam closure_bssrdf_cubic_params[] = { ClosureParam closure_bssrdf_cubic_params[] = {
CLOSURE_COLOR_PARAM (BSSRDFCubicClosure, m_radius), CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius),
CLOSURE_STRING_KEYPARAM ("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) }; CLOSURE_FINISH_PARAM(BSSRDFCubicClosure)
};
CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure) CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure)

View File

@@ -51,19 +51,19 @@ class DebugClosure : public ClosurePrimitive {
public: public:
ustring m_tag; ustring m_tag;
DebugClosure () : ClosurePrimitive (Debug) { } DebugClosure () : ClosurePrimitive(Debug) {}
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const DebugClosure *comp = (const DebugClosure *)other; const DebugClosure *comp = (const DebugClosure *)other;
return m_tag == comp->m_tag && return m_tag == comp->m_tag &&
ClosurePrimitive::mergeable(other); 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 { void print_on(std::ostream &out) const {
out << name() << " (\"" << m_tag.c_str() << "\")"; out << name() << " (\"" << m_tag.c_str() << "\")";
} }
@@ -72,7 +72,8 @@ public:
ClosureParam closure_debug_params[] = { ClosureParam closure_debug_params[] = {
CLOSURE_STRING_PARAM(DebugClosure, m_tag), CLOSURE_STRING_PARAM(DebugClosure, m_tag),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(DebugClosure) }; CLOSURE_FINISH_PARAM(DebugClosure)
};
CLOSURE_PREPARE(closure_debug_prepare, DebugClosure) CLOSURE_PREPARE(closure_debug_prepare, DebugClosure)

View File

@@ -51,24 +51,24 @@ class GenericEmissiveClosure : public EmissiveClosure {
public: public:
GenericEmissiveClosure() { } GenericEmissiveClosure() { }
void setup() { } void setup() {}
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "emission"; } const char *name() const { return "emission"; }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << "()"; out << name() << "()";
} }
Color3 eval (const Vec3 &Ng, const Vec3 &omega_out) const Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
{ {
float cosNO = fabsf(Ng.dot(omega_out)); float cosNO = fabsf(Ng.dot(omega_out));
float res = cosNO > 0 ? 1.0f: 0.0f; float res = cosNO > 0 ? 1.0f : 0.0f;
return Color3(res, res, res); return Color3(res, res, res);
} }
void sample (const Vec3 &Ng, float randu, float randv, void sample(const Vec3 &Ng, float randu, float randv,
Vec3 &omega_out, float &pdf) const Vec3 &omega_out, float &pdf) const
{ {
// We don't do anything sophisticated here for the step // We don't do anything sophisticated here for the step
@@ -87,11 +87,11 @@ public:
/// Return the probability distribution function in the direction omega_out, /// Return the probability distribution function in the direction omega_out,
/// given the parameters and the light's surface normal. This MUST match /// given the parameters and the light's surface normal. This MUST match
/// the PDF computed by sample(). /// the PDF computed by sample().
float pdf (const Vec3 &Ng, float pdf(const Vec3 &Ng,
const Vec3 &omega_out) const const Vec3 &omega_out) const
{ {
float cosNO = Ng.dot(omega_out); float cosNO = Ng.dot(omega_out);
return cosNO > 0 ? 1.0f: 0.0f; return cosNO > 0 ? 1.0f : 0.0f;
} }
}; };
@@ -99,7 +99,8 @@ public:
ClosureParam closure_emission_params[] = { ClosureParam closure_emission_params[] = {
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; CLOSURE_FINISH_PARAM(GenericEmissiveClosure)
};
CLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) CLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure)

View File

@@ -18,18 +18,18 @@
float color_srgb_to_scene_linear(float c) float color_srgb_to_scene_linear(float c)
{ {
if(c < 0.04045) if (c < 0.04045)
return (c < 0.0)? 0.0: c * (1.0/12.92); return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
else 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) float color_scene_linear_to_srgb(float c)
{ {
if(c < 0.0031308) if (c < 0.0031308)
return (c < 0.0)? 0.0: c * 12.92; return (c < 0.0) ? 0.0 : c * 12.92;
else else
return 1.055 * pow(c, 1.0/2.4) - 0.055; return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
} }
color color_srgb_to_scene_linear(color c) color color_srgb_to_scene_linear(color c)
@@ -61,27 +61,27 @@ color rgb_to_hsv(color rgb)
v = cmax; v = cmax;
if(cmax != 0.0) { if (cmax != 0.0) {
s = cdelta/cmax; s = cdelta / cmax;
} }
else { else {
s = 0.0; s = 0.0;
h = 0.0; h = 0.0;
} }
if(s == 0.0) { if (s == 0.0) {
h = 0.0; h = 0.0;
} }
else { else {
c = (color(cmax, cmax, cmax) - rgb)/cdelta; c = (color(cmax, cmax, cmax) - rgb) / cdelta;
if(rgb[0] == cmax) h = c[2] - c[1]; if (rgb[0] == cmax) h = c[2] - c[1];
else if(rgb[1] == cmax) h = 2.0 + c[0] - c[2]; else if (rgb[1] == cmax) h = 2.0 + c[0] - c[2];
else h = 4.0 + c[1] - c[0]; else h = 4.0 + c[1] - c[0];
h /= 6.0; h /= 6.0;
if(h < 0.0) if (h < 0.0)
h += 1.0; h += 1.0;
} }
@@ -97,26 +97,26 @@ color hsv_to_rgb(color hsv)
s = hsv[1]; s = hsv[1];
v = hsv[2]; v = hsv[2];
if(s==0.0) { if (s == 0.0) {
rgb = color(v, v, v); rgb = color(v, v, v);
} }
else { else {
if(h==1.0) if (h == 1.0)
h = 0.0; h = 0.0;
h *= 6.0; h *= 6.0;
i = floor(h); i = floor(h);
f = h - i; f = h - i;
rgb = color(f, f, f); rgb = color(f, f, f);
p = v*(1.0-s); p = v * (1.0 - s);
q = v*(1.0-(s*f)); q = v * (1.0 - (s * f));
t = v*(1.0-(s*(1.0-f))); t = v * (1.0 - (s * (1.0 - f)));
if(i == 0.0) rgb = color(v, t, p); if (i == 0.0) rgb = color(v, t, p);
else if(i == 1.0) rgb = color(q, v, p); else if (i == 1.0) rgb = color(q, v, p);
else if(i == 2.0) rgb = color(p, v, t); else if (i == 2.0) rgb = color(p, v, t);
else if(i == 3.0) rgb = color(p, q, v); else if (i == 3.0) rgb = color(p, q, v);
else if(i == 4.0) rgb = color(t, p, v); else if (i == 4.0) rgb = color(t, p, v);
else rgb = color(v, p, q); else rgb = color(v, p, q);
} }

View File

@@ -7,11 +7,11 @@ float fresnel_dielectric(vector Incoming, normal Normal, float eta)
float g = eta * eta - 1 + c * c; float g = eta * eta - 1 + c * c;
float result; float result;
if(g > 0) { if (g > 0) {
g = sqrt(g); g = sqrt(g);
float A =(g - c)/(g + c); float A = (g - c) / (g + c);
float B =(c *(g + c)- 1)/(c *(g - c)+ 1); float B = (c * (g + c) - 1) / (c * (g - c) + 1);
result = 0.5 * A * A *(1 + B * B); result = 0.5 * A * A * (1 + B * B);
} }
else else
result = 1.0; /* TIR (no refracted component) */ result = 1.0; /* TIR (no refracted component) */

View File

@@ -20,20 +20,20 @@ float voronoi_distance(string distance_metric, vector d, float e)
{ {
float result = 0.0; float result = 0.0;
if(distance_metric == "Distance Squared") if (distance_metric == "Distance Squared")
result = dot(d, d); result = dot(d, d);
if(distance_metric == "Actual Distance") if (distance_metric == "Actual Distance")
result = length(d); result = length(d);
if(distance_metric == "Manhattan") if (distance_metric == "Manhattan")
result = fabs(d[0]) + fabs(d[1]) + fabs(d[2]); 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]))); 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])); result = sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1]));
if(distance_metric == "Minkovsky 4") if (distance_metric == "Minkovsky 4")
result = sqrt(sqrt(dot(d*d, d*d))); result = sqrt(sqrt(dot(d * d, d * d)));
if(distance_metric == "Minkovsky") if (distance_metric == "Minkovsky")
result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0/e); result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e);
return result; 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[2] = 1e10;
da[3] = 1e10; da[3] = 1e10;
for(xx = xi-1; xx <= xi+1; xx++) { for (xx = xi - 1; xx <= xi + 1; xx++) {
for(yy = yi-1; yy <= yi+1; yy++) { for (yy = yi - 1; yy <= yi + 1; yy++) {
for(zz = zi-1; zz <= zi+1; zz++) { for (zz = zi - 1; zz <= zi + 1; zz++) {
point ip = point(xx, yy, zz); point ip = point(xx, yy, zz);
point vp = (point)cellnoise_color(ip); point vp = (point)cellnoise_color(ip);
point pd = p - (vp + 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); vp += point(xx, yy, zz);
if(d < da[0]) { if (d < da[0]) {
da[3] = da[2]; da[3] = da[2];
da[2] = da[1]; da[2] = da[1];
da[1] = da[0]; 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[1] = pa[0];
pa[0] = vp; pa[0] = vp;
} }
else if(d < da[1]) { else if (d < da[1]) {
da[3] = da[2]; da[3] = da[2];
da[2] = da[1]; da[2] = da[1];
da[1] = d; 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[2] = pa[1];
pa[1] = vp; pa[1] = vp;
} }
else if(d < da[2]) { else if (d < da[2]) {
da[3] = da[2]; da[3] = da[2];
da[2] = d; da[2] = d;
pa[3] = pa[2]; pa[3] = pa[2];
pa[2] = vp; pa[2] = vp;
} }
else if(d < da[3]) { else if (d < da[3]) {
da[3] = d; da[3] = d;
pa[3] = vp; pa[3] = vp;
} }
@@ -138,16 +138,16 @@ float voronoi_F1F2(point p) { return voronoi_FnFn(p, 0, 1); }
float voronoi_Cr(point p) float voronoi_Cr(point p)
{ {
/* crackle type pattern, just a scale/clamp of F2-F1 */ /* crackle type pattern, just a scale/clamp of F2-F1 */
float t = 10.0*voronoi_F1F2(p); float t = 10.0 * voronoi_F1F2(p);
return (t > 1.0)? 1.0: t; return (t > 1.0) ? 1.0 : t;
} }
float voronoi_F1S(point p) { return 2.0*voronoi_F1(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_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_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_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_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_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
/* Noise Bases */ /* Noise Bases */
@@ -155,21 +155,21 @@ float noise_basis(point p, string basis)
{ {
float result = 0.0; float result = 0.0;
if(basis == "Perlin") if (basis == "Perlin")
result = noise(p); result = noise(p);
if(basis == "Voronoi F1") if (basis == "Voronoi F1")
result = voronoi_F1S(p); result = voronoi_F1S(p);
if(basis == "Voronoi F2") if (basis == "Voronoi F2")
result = voronoi_F2S(p); result = voronoi_F2S(p);
if(basis == "Voronoi F3") if (basis == "Voronoi F3")
result = voronoi_F3S(p); result = voronoi_F3S(p);
if(basis == "Voronoi F4") if (basis == "Voronoi F4")
result = voronoi_F4S(p); result = voronoi_F4S(p);
if(basis == "Voronoi F2-F1") if (basis == "Voronoi F2-F1")
result = voronoi_F1F2S(p); result = voronoi_F1F2S(p);
if(basis == "Voronoi Crackle") if (basis == "Voronoi Crackle")
result = voronoi_CrS(p); result = voronoi_CrS(p);
if(basis == "Cell Noise") if (basis == "Cell Noise")
result = cellnoise(p); result = cellnoise(p);
return result; return result;
@@ -180,7 +180,7 @@ float noise_basis(point p, string basis)
float noise_basis_hard(point p, string basis, int hard) float noise_basis_hard(point p, string basis, int hard)
{ {
float t = noise_basis(p, basis); 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 */ /* Waves */
@@ -189,22 +189,22 @@ float noise_wave(string wave, float a)
{ {
float result = 0.0; float result = 0.0;
if(wave == "Sine") { if (wave == "Sine") {
result = 0.5 + 0.5*sin(a); result = 0.5 + 0.5 * sin(a);
} }
else if(wave == "Saw") { else if (wave == "Saw") {
float b = 2*M_PI; float b = 2 * M_PI;
int n = (int)(a / b); int n = (int)(a / b);
a -= n*b; a -= n * b;
if(a < 0) a += b; if (a < 0) a += b;
result = a / b; result = a / b;
} }
else if(wave == "Tri") { else if (wave == "Tri") {
float b = 2*M_PI; float b = 2 * M_PI;
float rmax = 1.0; 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; return result;
@@ -219,18 +219,18 @@ float noise_turbulence(point p, string basis, int octaves, int hard)
float sum = 0.0; float sum = 0.0;
int i; int i;
for(i = 0; i <= octaves; i++) { for (i = 0; i <= octaves; i++) {
float t = noise_basis(fscale*p, basis); float t = noise_basis(fscale * p, basis);
if(hard) if (hard)
t = fabs(2.0*t - 1.0); t = fabs(2.0 * t - 1.0);
sum += t*amp; sum += t * amp;
amp *= 0.5; amp *= 0.5;
fscale *= 2.0; fscale *= 2.0;
} }
sum *= ((float)(1 << octaves)/(float)((1 << (octaves+1)) - 1)); sum *= ((float)(1 << octaves) / (float)((1 << (octaves + 1)) - 1));
return sum; return sum;
} }
@@ -241,8 +241,8 @@ float nonzero(float f, float eps)
{ {
float r; float r;
if(abs(f) < eps) if (abs(f) < eps)
r = sign(f)*eps; r = sign(f) * eps;
else else
r = f; r = f;

View File

@@ -163,106 +163,109 @@ vector normalize (vector v) BUILTIN;
vector faceforward (vector N, vector I, vector Nref) BUILTIN; vector faceforward (vector N, vector I, vector Nref) BUILTIN;
vector faceforward (vector N, vector I) BUILTIN; vector faceforward (vector N, vector I) BUILTIN;
vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; } vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; }
vector refract (vector I, vector N, float eta) { vector refract(vector I, vector N, float eta) {
float IdotN = dot (I, N); float IdotN = dot(I, N);
float k = 1 - eta*eta * (1 - IdotN*IdotN); float k = 1 - eta * eta * (1 - IdotN * IdotN);
return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k))); return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k)));
} }
void fresnel (vector I, normal N, float eta, void fresnel(vector I, normal N, float eta,
output float Kr, output float Kt, output float Kr, output float Kt,
output vector R, output vector T) output vector R, output vector T)
{ {
float sqr(float x) { return x*x; } float sqr(float x) {
return x * x;
}
float c = dot(I, N); float c = dot(I, N);
if (c < 0) if (c < 0)
c = -c; c = -c;
R = reflect(I, N); R = reflect(I, N);
float g = 1.0 / sqr(eta) - 1.0 + c * c; float g = 1.0 / sqr(eta) - 1.0 + c * c;
if (g >= 0.0) { if (g >= 0.0) {
g = sqrt (g); g = sqrt(g);
float beta = g - c; float beta = g - c;
float F = (c * (g+c) - 1.0) / (c * beta + 1.0); float F = (c * (g + c) - 1.0) / (c * beta + 1.0);
F = 0.5 * (1.0 + sqr(F)); F = 0.5 * (1.0 + sqr(F));
F *= sqr (beta / (g+c)); F *= sqr(beta / (g + c));
Kr = F; Kr = F;
Kt = (1.0 - Kr) * eta*eta; Kt = (1.0 - Kr) * eta * eta;
// OPT: the following recomputes some of the above values, but it // OPT: the following recomputes some of the above values, but it
// gives us the same result as if the shader-writer called refract() // gives us the same result as if the shader-writer called refract()
T = refract(I, N, eta); T = refract(I, N, eta);
} else { }
else {
// total internal reflection // total internal reflection
Kr = 1.0; Kr = 1.0;
Kt = 0.0; Kt = 0.0;
T = vector (0,0,0); T = vector(0, 0, 0);
} }
#undef sqr #undef sqr
} }
void fresnel (vector I, normal N, float eta, void fresnel(vector I, normal N, float eta,
output float Kr, output float Kt) output float Kr, output float Kt)
{ {
vector R, T; vector R, T;
fresnel(I, N, eta, Kr, Kt, 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; normal transform(matrix Mto, normal p) BUILTIN;
vector transform (matrix Mto, vector p) BUILTIN; vector transform(matrix Mto, vector p) BUILTIN;
point transform (matrix Mto, point p) BUILTIN; point transform(matrix Mto, point p) BUILTIN;
// Implementation of transform-with-named-space in terms of matrices: // 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 tounits, float x) BUILTIN;
float transformu (string fromunits, string tounits, float x) BUILTIN; float transformu(string fromunits, string tounits, float x) BUILTIN;
// Color functions // Color functions
float luminance (color c) { float luminance(color c) {
return dot ((vector)c, vector(0.2126, 0.7152, 0.0722)); 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 color rgb_to_hsv(color rgb) { // See Foley & van Dam
float r = rgb[0], g = rgb[1], b = rgb[2]; float r = rgb[0], g = rgb[1], b = rgb[2];
float mincomp = min (r, min (g, b)); float mincomp = min(r, min(g, b));
float maxcomp = max (r, max (g, b)); float maxcomp = max(r, max(g, b));
float delta = maxcomp - mincomp; // chroma float delta = maxcomp - mincomp; // chroma
float h, s, v; float h, s, v;
v = maxcomp; v = maxcomp;
@@ -272,89 +275,91 @@ color transformc (string to, color x)
if (s <= 0) if (s <= 0)
h = 0; h = 0;
else { else {
if (r >= maxcomp) h = (g-b) / delta; if (r >= maxcomp) h = (g - b) / delta;
else if (g >= maxcomp) h = 2 + (b-r) / delta; else if (g >= maxcomp) h = 2 + (b - r) / delta;
else h = 4 + (r-g) / delta; else h = 4 + (r - g) / delta;
h /= 6; h /= 6;
if (h < 0) if (h < 0)
h += 1; h += 1;
} }
return color (h, s, v); return color(h, s, v);
} }
color rgb_to_hsl (color rgb) { // See Foley & van Dam color rgb_to_hsl(color rgb) { // See Foley & van Dam
// First convert rgb to hsv, then to hsl // First convert rgb to hsv, then to hsl
float minval = min (rgb[0], min (rgb[1], rgb[2])); float minval = min(rgb[0], min(rgb[1], rgb[2]));
color hsv = rgb_to_hsv (rgb); color hsv = rgb_to_hsv(rgb);
float maxval = hsv[2]; // v == maxval float maxval = hsv[2]; // v == maxval
float h = hsv[0], s, l = (minval+maxval) / 2; float h = hsv[0], s, l = (minval + maxval) / 2;
if (minval == maxval) if (minval == maxval)
s = 0; // special 'achromatic' case, hue is 0 s = 0; // special 'achromatic' case, hue is 0
else if (l <= 0.5) else if (l <= 0.5)
s = (maxval - minval) / (maxval + minval); s = (maxval - minval) / (maxval + minval);
else else
s = (maxval - minval) / (2 - maxval - minval); s = (maxval - minval) / (2 - maxval - minval);
return color (h, s, l); return color(h, s, l);
} }
color r; color r;
if (to == "rgb" || to == "RGB") if (to == "rgb" || to == "RGB")
r = x; r = x;
else if (to == "hsv") else if (to == "hsv")
r = rgb_to_hsv (x); r = rgb_to_hsv(x);
else if (to == "hsl") else if (to == "hsl")
r = rgb_to_hsl (x); r = rgb_to_hsl(x);
else if (to == "YIQ") else if (to == "YIQ")
r = color (dot (vector(0.299, 0.587, 0.114), (vector)x), 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.596, -0.275, -0.321), (vector)x),
dot (vector(0.212, -0.523, 0.311), (vector)x)); dot(vector(0.212, -0.523, 0.311), (vector)x));
else if (to == "xyz") else if (to == "xyz")
r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x), 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.212671, 0.715160, 0.072169), (vector)x),
dot (vector(0.019334, 0.119193, 0.950227), (vector)x)); dot(vector(0.019334, 0.119193, 0.950227), (vector)x));
else { else {
error ("Unknown color space \"%s\"", to); error("Unknown color space \"%s\"", to);
r = x; r = x;
} }
return r; 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 color hsv_to_rgb(color c) { // Reference: Foley & van Dam
float h = c[0], s = c[1], v = c[2]; float h = c[0], s = c[1], v = c[2];
color r; color r;
if (s < 0.0001) { if (s < 0.0001) {
r = v; r = v;
} else { }
else {
h = 6 * (h - floor(h)); // expand to [0..6) h = 6 * (h - floor(h)); // expand to [0..6)
int hi = (int)h; int hi = (int)h;
float f = h - hi; float f = h - hi;
float p = v * (1-s); float p = v * (1 - s);
float q = v * (1-s*f); float q = v * (1 - s * f);
float t = v * (1-s*(1-f)); float t = v * (1 - s * (1 - f));
if (hi == 0) r = color (v, t, p); if (hi == 0) r = color(v, t, p);
else if (hi == 1) r = color (q, v, p); else if (hi == 1) r = color(q, v, p);
else if (hi == 2) r = color (p, v, t); else if (hi == 2) r = color(p, v, t);
else if (hi == 3) r = color (p, q, v); else if (hi == 3) r = color(p, q, v);
else if (hi == 4) r = color (t, p, v); else if (hi == 4) r = color(t, p, v);
else r = color (v, p, q); else r = color(v, p, q);
} }
return r; return r;
} }
color hsl_to_rgb (color c) { color hsl_to_rgb(color c) {
float h = c[0], s = c[1], l = c[2]; float h = c[0], s = c[1], l = c[2];
// Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam) // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s); float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
color r; color r;
if (v <= 0) { if (v <= 0) {
r = 0; r = 0;
} else { }
else {
float min = 2 * l - v; float min = 2 * l - v;
s = (v - min) / v; s = (v - min) / v;
r = hsv_to_rgb (color (h, s, v)); r = hsv_to_rgb(color(h, s, v));
} }
return r; return r;
} }
@@ -363,41 +368,41 @@ color transformc (string from, string to, color x)
if (from == "rgb" || from == "RGB") if (from == "rgb" || from == "RGB")
r = x; r = x;
else if (from == "hsv") else if (from == "hsv")
r = hsv_to_rgb (x); r = hsv_to_rgb(x);
else if (from == "hsl") else if (from == "hsl")
r = hsl_to_rgb (x); r = hsl_to_rgb(x);
else if (from == "YIQ") else if (from == "YIQ")
r = color (dot (vector(1, 0.9557, 0.6199), (vector)x), r = color(dot(vector(1, 0.9557, 0.6199), (vector)x),
dot (vector(1, -0.2716, -0.6469), (vector)x), dot(vector(1, -0.2716, -0.6469), (vector)x),
dot (vector(1, -1.1082, 1.7051), (vector)x)); dot(vector(1, -1.1082, 1.7051), (vector)x));
else if (from == "xyz") else if (from == "xyz")
r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x), 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.969256, 1.875991, 0.041556), (vector)x),
dot (vector( 0.055648, -0.204043, 1.057311), (vector)x)); dot(vector(0.055648, -0.204043, 1.057311), (vector)x));
else { else {
error ("Unknown color space \"%s\"", to); error("Unknown color space \"%s\"", to);
r = x; r = x;
} }
return transformc (to, r); return transformc(to, r);
} }
// Matrix functions // Matrix functions
float determinant (matrix m) BUILTIN; float determinant(matrix m) BUILTIN;
matrix transpose (matrix m) BUILTIN; matrix transpose(matrix m) BUILTIN;
// Pattern generation // Pattern generation
float step (float edge, float x) BUILTIN; float step(float edge, float x) BUILTIN;
color step (color edge, color x) BUILTIN; color step(color edge, color x) BUILTIN;
point step (point edge, point x) BUILTIN; point step(point edge, point x) BUILTIN;
vector step (vector edge, vector x) BUILTIN; vector step(vector edge, vector x) BUILTIN;
normal step (normal edge, normal x) BUILTIN; normal step(normal edge, normal x) BUILTIN;
float smoothstep (float edge0, float edge1, float x) BUILTIN; float smoothstep(float edge0, float edge1, float x) BUILTIN;
// Derivatives and area operators // Derivatives and area operators
@@ -408,24 +413,26 @@ float smoothstep (float edge0, float edge1, float x) BUILTIN;
// String functions // String functions
int strlen (string s) BUILTIN; int strlen(string s) BUILTIN;
int startswith (string s, string prefix) BUILTIN; int startswith(string s, string prefix) BUILTIN;
int endswith (string s, string suffix) BUILTIN; int endswith(string s, string suffix) BUILTIN;
string substr (string s, int start, int len) BUILTIN; string substr(string s, int start, int len) BUILTIN;
string substr (string s, int start) { return substr (s, start, strlen(s)); } string substr(string s, int start) {
return substr(s, start, strlen(s));
}
// Define concat in terms of shorter concat // Define concat in terms of shorter concat
string concat (string a, string b, string c) { string concat(string a, string b, string c) {
return concat(concat(a,b), c); return concat(concat(a, b), c);
} }
string concat (string a, string b, string c, string d) { string concat(string a, string b, string c, string d) {
return concat(concat(a,b,c), d); return concat(concat(a, b, c), d);
} }
string concat (string a, string b, string c, string d, string e) { string concat(string a, string b, string c, string d, string e) {
return concat(concat(a,b,c,d), e); return concat(concat(a, b, c, d), e);
} }
string concat (string a, string b, string c, string d, string e, string f) { string concat(string a, string b, string c, string d, string e, string f) {
return concat(concat(a,b,c,d,e), 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 oren_nayar(normal N, float sigma) BUILTIN;
closure color translucent(normal N) BUILTIN; closure color translucent(normal N) BUILTIN;
closure color reflection(normal N, float eta) 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 refraction(normal N, float eta) BUILTIN;
closure color dielectric(normal N, float eta) BUILTIN; closure color dielectric(normal N, float eta) BUILTIN;
closure color transparent() 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_ggx_refraction(normal N, float ag, float eta) BUILTIN;
closure color microfacet_beckmann(normal N, float ab) BUILTIN; closure color microfacet_beckmann(normal N, float ab) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) 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 ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color westin_backscatter(normal N, float roughness) BUILTIN; closure color westin_backscatter(normal N, float roughness) BUILTIN;
closure color westin_sheen(normal N, float edginess) 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; closure color subsurface(float eta, float g, float mfp, float albedo) BUILTIN;
// Renderer state // Renderer state
int raytype (string typename) BUILTIN; int raytype(string typename) BUILTIN;
#undef BUILTIN #undef BUILTIN
#undef BUILTIN_DERIV #undef BUILTIN_DERIV

View File

@@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */ /* RenderServices implementation */
#define TO_MATRIX44(m) (*(OSL::Matrix44*)&(m)) #define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
/* static ustrings */ /* static ustrings */
ustring OSLRenderServices::u_distance("distance"); 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 /* 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. */ a concept of shader space, so we just use object space for both. */
if(xform) { if (xform) {
KernelGlobals *kg = kernel_globals; KernelGlobals *kg = kernel_globals;
const ShaderData *sd = (const ShaderData*)xform; const ShaderData *sd = (const ShaderData *)xform;
int object = sd->object; int object = sd->object;
if(object != ~0) { if (object != ~0) {
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
tfm = transform_transpose(tfm); tfm = transform_transpose(tfm);
result = TO_MATRIX44(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 /* 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. */ a concept of shader space, so we just use object space for both. */
if(xform) { if (xform) {
KernelGlobals *kg = kernel_globals; KernelGlobals *kg = kernel_globals;
const ShaderData *sd = (const ShaderData*)xform; const ShaderData *sd = (const ShaderData *)xform;
int object = sd->object; int object = sd->object;
if(object != ~0) { if (object != ~0) {
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
tfm = transform_transpose(tfm); tfm = transform_transpose(tfm);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
@@ -108,22 +108,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
{ {
KernelGlobals *kg = kernel_globals; KernelGlobals *kg = kernel_globals;
if(from == u_ndc) { if (from == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); Transform tfm = transform_transpose(kernel_data.cam.ndctoworld);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(from == u_raster) { else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(from == u_screen) { else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld); Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(from == u_camera) { else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
@@ -136,22 +136,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
{ {
KernelGlobals *kg = kernel_globals; KernelGlobals *kg = kernel_globals;
if(to == u_ndc) { if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc); Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(to == u_raster) { else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(to == u_screen) { else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
} }
else if(to == u_camera) { else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
result = TO_MATRIX44(tfm); result = TO_MATRIX44(tfm);
return true; return true;
@@ -170,16 +170,16 @@ bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives,
static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, 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) { if (attr.type == TypeDesc::TypeFloat) {
float *fval = (float*)val; float *fval = (float *)val;
fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset, 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 { else {
/* todo: this won't work when float3 has w component */ /* 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, 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; return true;
@@ -188,29 +188,30 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd,
static bool get_mesh_attribute_convert(KernelGlobals *kg, const ShaderData *sd, 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]; float tmp[3];
float3 *fval = (float3*)val; float3 *fval = (float3 *)val;
get_mesh_attribute(kg, sd, attr, derivatives, tmp); get_mesh_attribute(kg, sd, attr, derivatives, tmp);
fval[0] = make_float3(tmp[0], tmp[0], tmp[0]); 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[1] = make_float3(tmp[1], tmp[1], tmp[1]);
fval[2] = make_float3(tmp[2], tmp[2], tmp[2]); fval[2] = make_float3(tmp[2], tmp[2], tmp[2]);
} }
return true; return true;
} }
else if(attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
float3 tmp[3]; float3 tmp[3];
float *fval = (float*)val; float *fval = (float *)val;
get_mesh_attribute(kg, sd, attr, derivatives, tmp); get_mesh_attribute(kg, sd, attr, derivatives, tmp);
fval[0] = average(tmp[0]); fval[0] = average(tmp[0]);
if(derivatives) { if (derivatives) {
fval[1] = average(tmp[1]); fval[1] = average(tmp[1]);
fval[2] = average(tmp[2]); 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(); size_t datasize = attr.value.datasize();
memcpy(val, attr.value.data(), datasize); memcpy(val, attr.value.data(), datasize);
if(derivatives) if (derivatives)
memset((char*)val + datasize, 0, datasize*2); memset((char *)val + datasize, 0, datasize * 2);
} }
bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name, 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; KernelGlobals *kg = kernel_globals;
const ShaderData *sd = (const ShaderData*)renderstate; const ShaderData *sd = (const ShaderData *)renderstate;
int object = sd->object; int object = sd->object;
int tri = sd->prim; int tri = sd->prim;
/* lookup of attribute on another object */ /* 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); 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; return false;
object = it->second; object = it->second;
tri = ~0; tri = ~0;
} }
else if(object == ~0) { else if (object == ~0) {
/* no background attributes supported */ /* no background attributes supported */
return false; return false;
} }
@@ -257,22 +258,25 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
OSLGlobals::AttributeMap& attribute_map = kg->osl.attribute_map[object]; OSLGlobals::AttributeMap& attribute_map = kg->osl.attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name); OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
if(it == attribute_map.end()) if (it == attribute_map.end())
return false; return false;
/* type mistmatch? */ /* type mistmatch? */
const OSLGlobals::Attribute& attr = it->second; const OSLGlobals::Attribute& attr = it->second;
if(attr.elem != ATTR_ELEMENT_VALUE) { if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */ /* triangle and vertex attributes */
if(tri != ~0) { if (tri != ~0) {
if(attr.type == type || (attr.type == TypeDesc::TypeColor && if (attr.type == type || (attr.type == TypeDesc::TypeColor &&
(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal))) (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal)))
{
return get_mesh_attribute(kg, sd, attr, derivatives, val); return get_mesh_attribute(kg, sd, attr, derivatives, val);
else }
else {
return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val); return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val);
} }
} }
}
else { else {
/* object attribute */ /* object attribute */
get_object_attribute(attr, derivatives, val); get_object_attribute(attr, derivatives, val);
@@ -308,29 +312,33 @@ void *OSLRenderServices::get_pointcloud_attr_query(ustring *attr_names,
to the query. Just to prevent buffer overruns */ to the query. Just to prevent buffer overruns */
query.capacity = -1; query.capacity = -1;
for(int i = 0; i < nattrs; ++i) for (int i = 0; i < nattrs; ++i) {
{
query.attr_names[i] = attr_names[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) if (query.capacity < 0)
query.capacity = attr_types[i].numelements(); query.capacity = attr_types[i].numelements();
else 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 /* convert the OSL (OIIO) type to the equivalent Partio type so
we can do a fast check at query time. */ we can do a fast check at query time. */
if(element_type == TypeDesc::TypeFloat) if (element_type == TypeDesc::TypeFloat) {
query.attr_partio_types[i] = Partio::FLOAT; query.attr_partio_types[i] = Partio::FLOAT;
else if(element_type == TypeDesc::TypeInt) }
else if (element_type == TypeDesc::TypeInt) {
query.attr_partio_types[i] = Partio::INT; query.attr_partio_types[i] = Partio::INT;
else if(element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint || }
else if (element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint ||
element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal) element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal)
{
query.attr_partio_types[i] = Partio::VECTOR; query.attr_partio_types[i] = Partio::VECTOR;
else }
else {
return NULL; /* report some error of unknown type */ return NULL; /* report some error of unknown type */
} }
}
/* this is valid until the end of RenderServices */ /* this is valid until the end of RenderServices */
return &query; return &query;
@@ -355,11 +363,11 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 &center, flo
#ifdef WITH_PARTIO #ifdef WITH_PARTIO
/* query Partio for this pointcloud lookup using cached attr_query */ /* query Partio for this pointcloud lookup using cached attr_query */
if(!_attr_query) if (!_attr_query)
return 0; return 0;
AttrQuery *attr_query = (AttrQuery *)_attr_query; AttrQuery *attr_query = (AttrQuery *)_attr_query;
if(attr_query->capacity < max_points) if (attr_query->capacity < max_points)
return 0; return 0;
/* get the pointcloud entry for the given filename */ /* get the pointcloud entry for the given filename */
@@ -370,13 +378,13 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 &center, flo
int nattrs = attr_query->attr_names.size(); int nattrs = attr_query->attr_names.size();
Partio::ParticleAttribute *attr = (Partio::ParticleAttribute *)alloca(sizeof(Partio::ParticleAttribute) * nattrs); 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 */ /* 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; continue;
/* lookup the attribute by name*/ /* 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 */ /* issue an error here and return, types don't match */
Partio::endCachedAccess(cloud); Partio::endCachedAccess(cloud);
cloud->release(); cloud->release();
@@ -394,14 +402,14 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 &center, flo
int count = indices.size(); int count = indices.size();
/* retrieve the attributes directly to user space */ /* retrieve the attributes directly to user space */
for(int j = 0; j < nattrs; ++j) { for (int j = 0; j < nattrs; ++j) {
/* special cases */ /* special cases */
if(attr_query->attr_names[j] == u_distance) { if (attr_query->attr_names[j] == u_distance) {
for(int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
((float *)attr_outdata[j])[i] = sqrtf(dist2[i]); ((float *)attr_outdata[j])[i] = sqrtf(dist2[i]);
} }
else if(attr_query->attr_names[j] == u_index) { else if (attr_query->attr_names[j] == u_index) {
for(int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
((int *)attr_outdata[j])[i] = indices[i]; ((int *)attr_outdata[j])[i] = indices[i];
} }
else { else {

View File

@@ -79,8 +79,7 @@ private:
right now it only caches the types already converted to right now it only caches the types already converted to
Partio constants. this is what get_pointcloud_attr_query Partio constants. this is what get_pointcloud_attr_query
returns */ returns */
struct AttrQuery struct AttrQuery {
{
/* names of the attributes to query */ /* names of the attributes to query */
std::vector<ustring> attr_names; std::vector<ustring> attr_names;
/* types as (enum Partio::ParticleAttributeType) of the /* types as (enum Partio::ParticleAttributeType) of the

View File

@@ -37,7 +37,7 @@ tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
void OSLShader::thread_init(KernelGlobals *kg) 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(); OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData();
@@ -46,12 +46,12 @@ void OSLShader::thread_init(KernelGlobals *kg)
tls_set(kg->osl.thread_data, tdata); 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) 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); OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
@@ -62,8 +62,8 @@ void OSLShader::thread_free(KernelGlobals *kg)
/* Globals */ /* Globals */
#define TO_VEC3(v) (*(OSL::Vec3*)&(v)) #define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
#define TO_COLOR3(v) (*(OSL::Color3*)&(v)) #define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
@@ -86,7 +86,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->dvdy = sd->dv.dy; globals->dvdy = sd->dv.dy;
globals->dPdu = TO_VEC3(sd->dPdu); globals->dPdu = TO_VEC3(sd->dPdu);
globals->dPdv = TO_VEC3(sd->dPdv); 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 */ /* booleans */
globals->raytype = path_flag; /* todo: add our own ray types */ globals->raytype = path_flag; /* todo: add our own ray types */
@@ -114,30 +114,30 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
/* OSL gives use a closure tree, we flatten it into arrays per /* OSL gives use a closure tree, we flatten it into arrays per
* closure type, for evaluation, sampling, etc later on. */ * closure type, for evaluation, sampling, etc later on. */
if(closure->type == OSL::ClosureColor::COMPONENT) { if (closure->type == OSL::ClosureColor::COMPONENT) {
OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data();
if(prim) { if (prim) {
ShaderClosure sc; ShaderClosure sc;
sc.prim = prim; sc.prim = prim;
sc.weight = weight; sc.weight = weight;
switch(prim->category()) { switch (prim->category()) {
case ClosurePrimitive::BSDF: { case ClosurePrimitive::BSDF: {
if(sd->num_closure == MAX_CLOSURE) if (sd->num_closure == MAX_CLOSURE)
return; return;
OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)prim; OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim;
ustring scattering = bsdf->scattering(); ustring scattering = bsdf->scattering();
/* no caustics option */ /* no caustics option */
if(no_glossy && scattering == OSL::Labels::GLOSSY) if (no_glossy && scattering == OSL::Labels::GLOSSY)
return; return;
/* sample weight */ /* sample weight */
float albedo = bsdf->albedo(TO_VEC3(sd->I)); 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; float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight;
sc.sample_weight = 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; sd->osl_closure.bsdf_sample_sum = sample_sum;
/* scattering flags */ /* scattering flags */
if(scattering == OSL::Labels::DIFFUSE) if (scattering == OSL::Labels::DIFFUSE)
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL;
else if(scattering == OSL::Labels::GLOSSY) else if (scattering == OSL::Labels::GLOSSY)
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
else else
sd->flag |= SD_BSDF; sd->flag |= SD_BSDF;
@@ -157,7 +157,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break; break;
} }
case ClosurePrimitive::Emissive: { case ClosurePrimitive::Emissive: {
if(sd->num_closure == MAX_CLOSURE) if (sd->num_closure == MAX_CLOSURE)
return; return;
/* sample weight */ /* sample weight */
@@ -175,7 +175,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break; break;
} }
case ClosurePrimitive::Holdout: case ClosurePrimitive::Holdout:
if(sd->num_closure == MAX_CLOSURE) if (sd->num_closure == MAX_CLOSURE)
return; return;
sc.sample_weight = 0.0f; 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) { else if (closure->type == OSL::ClosureColor::MUL) {
OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight); flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight);
} }
else if(closure->type == OSL::ClosureColor::ADD) { else if (closure->type == OSL::ClosureColor::ADD) {
OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight); flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight);
flatten_surface_closure_tree(sd, no_glossy, add->closureB, 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) void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{ {
/* gather pointers */ /* 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); OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShaderGlobals *globals = &tdata->globals;
OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); 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 */ /* execute shader for this point */
int shader = sd->shader & SHADER_MASK; 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); ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals);
/* flatten closure tree */ /* flatten closure tree */
sd->num_closure = 0; sd->num_closure = 0;
sd->randb_closure = randb; sd->randb_closure = randb;
if(globals->Ci) { if (globals->Ci) {
bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics; bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics;
flatten_surface_closure_tree(sd, no_glossy, globals->Ci); flatten_surface_closure_tree(sd, no_glossy, globals->Ci);
} }
@@ -239,20 +239,20 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
* is only one supported closure type at the moment, which has no evaluation * is only one supported closure type at the moment, which has no evaluation
* functions, so we just sum the weights */ * functions, so we just sum the weights */
if(closure->type == OSL::ClosureColor::COMPONENT) { if (closure->type == OSL::ClosureColor::COMPONENT) {
OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); 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); return make_float3(1.0f, 1.0f, 1.0f);
} }
else if(closure->type == OSL::ClosureColor::MUL) { else if (closure->type == OSL::ClosureColor::MUL) {
OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure);
} }
else if(closure->type == OSL::ClosureColor::ADD) { else if (closure->type == OSL::ClosureColor::ADD) {
OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
return flatten_background_closure_tree(add->closureA) + return flatten_background_closure_tree(add->closureA) +
flatten_background_closure_tree(add->closureB); flatten_background_closure_tree(add->closureB);
@@ -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) float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
{ {
/* gather pointers */ /* 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); OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShaderGlobals *globals = &tdata->globals;
OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); 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); shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
/* execute shader for this point */ /* 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); ctx->execute(OSL::pvt::ShadUseSurface, *kg->osl.background_state, *globals);
/* return background color immediately */ /* return background color immediately */
if(globals->Ci) if (globals->Ci)
return flatten_background_closure_tree(globals->Ci); return flatten_background_closure_tree(globals->Ci);
return make_float3(0.0f, 0.0f, 0.0f); return make_float3(0.0f, 0.0f, 0.0f);
@@ -292,18 +292,18 @@ static void flatten_volume_closure_tree(ShaderData *sd,
/* OSL gives use a closure tree, we flatten it into arrays per /* OSL gives use a closure tree, we flatten it into arrays per
* closure type, for evaluation, sampling, etc later on. */ * closure type, for evaluation, sampling, etc later on. */
if(closure->type == OSL::ClosureColor::COMPONENT) { if (closure->type == OSL::ClosureColor::COMPONENT) {
OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data();
if(prim) { if (prim) {
ShaderClosure sc; ShaderClosure sc;
sc.prim = prim; sc.prim = prim;
sc.weight = weight; sc.weight = weight;
switch(prim->category()) { switch (prim->category()) {
case ClosurePrimitive::Volume: { case ClosurePrimitive::Volume: {
if(sd->num_closure == MAX_CLOSURE) if (sd->num_closure == MAX_CLOSURE)
return; return;
/* sample weight */ /* sample weight */
@@ -329,12 +329,12 @@ static void flatten_volume_closure_tree(ShaderData *sd,
} }
} }
} }
else if(closure->type == OSL::ClosureColor::MUL) { else if (closure->type == OSL::ClosureColor::MUL) {
OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
} }
else if(closure->type == OSL::ClosureColor::ADD) { else if (closure->type == OSL::ClosureColor::ADD) {
OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
flatten_volume_closure_tree(sd, add->closureA, weight); flatten_volume_closure_tree(sd, add->closureA, weight);
flatten_volume_closure_tree(sd, add->closureB, 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) void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{ {
/* gather pointers */ /* 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); OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShaderGlobals *globals = &tdata->globals;
OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); 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 */ /* execute shader */
int shader = sd->shader & SHADER_MASK; 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); ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals);
/* retrieve resulting closures */ /* 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.num_volume = 0;
sd->osl_closure.randb = randb; sd->osl_closure.randb = randb;
if(globals->Ci) if (globals->Ci)
flatten_volume_closure_tree(sd, 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) void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
{ {
/* gather pointers */ /* 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); OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShaderGlobals *globals = &tdata->globals;
OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);
@@ -384,7 +384,7 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
/* execute shader */ /* execute shader */
int shader = sd->shader & SHADER_MASK; 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); ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[shader]), *globals);
/* get back position */ /* get back position */
@@ -393,17 +393,17 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
void OSLShader::release(KernelGlobals *kg, const 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); 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 */ /* 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) 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; int label = LABEL_NONE;
pdf = 0.0f; pdf = 0.0f;
@@ -418,9 +418,9 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float
pdf, TO_COLOR3(eval)); pdf, TO_COLOR3(eval));
/* convert OSL label */ /* convert OSL label */
if(ulabel == OSL::Labels::REFLECT) if (ulabel == OSL::Labels::REFLECT)
label = LABEL_REFLECT; label = LABEL_REFLECT;
else if(ulabel == OSL::Labels::TRANSMIT) else if (ulabel == OSL::Labels::TRANSMIT)
label = LABEL_TRANSMIT; label = LABEL_TRANSMIT;
else else
return LABEL_NONE; /* sampling failed */ return LABEL_NONE; /* sampling failed */
@@ -428,11 +428,11 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float
/* convert scattering to our bitflag label */ /* convert scattering to our bitflag label */
ustring uscattering = sample_bsdf->scattering(); ustring uscattering = sample_bsdf->scattering();
if(uscattering == OSL::Labels::DIFFUSE) if (uscattering == OSL::Labels::DIFFUSE)
label |= LABEL_DIFFUSE; label |= LABEL_DIFFUSE;
else if(uscattering == OSL::Labels::GLOSSY) else if (uscattering == OSL::Labels::GLOSSY)
label |= LABEL_GLOSSY; label |= LABEL_GLOSSY;
else if(uscattering == OSL::Labels::SINGULAR) else if (uscattering == OSL::Labels::SINGULAR)
label |= LABEL_SINGULAR; label |= LABEL_SINGULAR;
else else
label |= LABEL_TRANSPARENT; 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) 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; 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); bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
else else
bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); 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) 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)); OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I));
eval += TO_FLOAT3(emissive_eval); 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) 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)); 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 CCL_NAMESPACE_END

View File

@@ -73,7 +73,8 @@ public:
// didn't quite converge, pick result in the middle of remaining interval // didn't quite converge, pick result in the middle of remaining interval
return 0.5f * (lo + hi); return 0.5f * (lo + hi);
} }
SubsurfaceClosure() { } SubsurfaceClosure() {
}
void setup() void setup()
{ {
@@ -87,10 +88,10 @@ public:
float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * 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); float A = (1 + Fdr) / (1 - Fdr);
// compute sigma_s, sigma_a (eq.16) // compute sigma_s, sigma_a (eq.16)
Color3 alpha_prime = Color3 (root_find_Rd(m_albedo[0], A), Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A),
root_find_Rd(m_albedo[1], A), root_find_Rd(m_albedo[1], A),
root_find_Rd(m_albedo[2], 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, 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.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); 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; Color3 sigma_s_prime = alpha_prime * sigma_t_prime;
@@ -99,35 +100,36 @@ public:
sigma_a(sigma_t_prime - sigma_s_prime); sigma_a(sigma_t_prime - sigma_s_prime);
} }
bool mergeable (const ClosurePrimitive *other) const { bool mergeable(const ClosurePrimitive *other) const {
const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other;
return m_g == comp->m_g && VolumeClosure::mergeable(other); return m_g == comp->m_g && VolumeClosure::mergeable(other);
} }
size_t memsize () const { return sizeof(*this); } size_t memsize() const { return sizeof(*this); }
const char *name () const { return "subsurface"; } const char *name() const { return "subsurface"; }
void print_on (std::ostream &out) const { void print_on(std::ostream &out) const {
out << name() << " ()"; out << name() << " ()";
} }
virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const {
float costheta = omega_in.dot(omega_out); 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)); 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); return Color3(ph, ph, ph);
} }
}; };
ClosureParam closure_subsurface_params[] = { ClosureParam closure_subsurface_params[] = {
CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_eta), CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta),
CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_g), CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g),
CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_mfp), CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp),
CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_albedo), CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(SubsurfaceClosure) }; CLOSURE_FINISH_PARAM(SubsurfaceClosure)
};
CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure) CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure)