style cleanup
This commit is contained in:
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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) */
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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 ¢er, 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 ¢er, 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 ¢er, 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 {
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user