Also refactor SVM BSDF code, preparing it to be shared with OSL.
attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
/* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z;
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
}
#ifdef __DPDU__
/* dPdu/dPdv */
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
- sd->T = make_float3(0.0f, 0.0f, 0.0f);
#endif
#ifdef __INSTANCING__
#ifdef __DPDU__
sd->dPdu = -sd->dPdu;
sd->dPdv = -sd->dPdv;
- sd->T = make_float3(0.0f, 0.0f, 0.0f);
#endif
}
}
#endif
}
-
- sd->T = make_float3(0.0f, 0.0f, 0.0f);
#endif
/* backfacing test */
/* dPdu/dPdv */
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
- sd->T = make_float3(0.0f, 0.0f, 0.0f);
#endif
#ifdef __RAY_DIFFERENTIALS__
#endif
float data0;
float data1;
+
float3 N;
+ float3 T;
} ShaderClosure;
/* differential of P w.r.t. parametric coordinates. note that dPdu is
* not readily suitable as a tangent for shading on triangles. */
float3 dPdu, dPdv;
-
- /* tangent for shading */
- float3 T;
#endif
#ifdef __OBJECT_MOTION__
CCL_NAMESPACE_BEGIN
-typedef struct BsdfAshikhminVelvetClosure {
- //float3 m_N;
- float m_invsigma2;
-} BsdfAshikhminVelvetClosure;
-
__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma)
{
sigma = fmaxf(sigma, 0.01f);
{
}
-__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_invsigma2 = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
float3 H = normalize(omega_in + I);
- float cosNH = dot(m_N, H);
+ float cosNH = dot(N, H);
float cosHO = fabsf(dot(I, H));
if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f))
return make_float3(0, 0, 0);
}
-__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_ashikhmin_velvet_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_invsigma2 = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
// we are viewing the surface from above - send a ray out with uniform
// distribution over the hemisphere
- sample_uniform_hemisphere(m_N, randu, randv, omega_in, pdf);
+ sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0) {
- float3 H = normalize(*omega_in + sd->I);
+ if(dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(*omega_in + I);
- float cosNI = dot(m_N, *omega_in);
- float cosNO = dot(m_N, sd->I);
- float cosNH = dot(m_N, H);
- float cosHO = fabsf(dot(sd->I, H));
+ float cosNI = dot(N, *omega_in);
+ float cosNO = dot(N, I);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) {
float cosNHdivHO = cosNH / cosHO;
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the retroreflective bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
/* DIFFUSE */
-typedef struct BsdfDiffuseClosure {
- //float3 m_N;
-} BsdfDiffuseClosure;
-
__device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_DIFFUSE_ID;
{
}
-__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cos_pi = fmaxf(dot(m_N, omega_in), 0.0f) * M_1_PI_F;
+ float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
return make_float3(cos_pi, cos_pi, cos_pi);
}
-__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_diffuse_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float3 m_N = sc->N;
+ float3 N = sc->N;
// distribution over the hemisphere
- sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf);
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0.0f) {
+ if(dot(Ng, *omega_in) > 0.0f) {
*eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
/* TRANSLUCENT */
-typedef struct BsdfTranslucentClosure {
- //float3 m_N;
-} BsdfTranslucentClosure;
-
__device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_TRANSLUCENT_ID;
{
}
-__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cos_pi = fmaxf(-dot(m_N, omega_in), 0.0f) * M_1_PI_F;
+ float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
return make_float3 (cos_pi, cos_pi, cos_pi);
}
-__device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float3 m_N = sc->N;
+ float3 N = sc->N;
// we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere
- sample_cos_hemisphere (-m_N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) < 0) {
+ sample_cos_hemisphere (-N, randu, randv, omega_in, pdf);
+ if(dot(Ng, *omega_in) < 0) {
*eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= -125.0f;
*domega_in_dy *= -125.0f;
#endif
/* GGX */
-typedef struct BsdfMicrofacetGGXClosure {
- //float3 m_N;
- float m_ag;
- float m_eta;
-} BsdfMicrofacetGGXClosure;
-
__device_inline float safe_sqrtf(float f)
{
return sqrtf(max(f, 0.0f));
sc->data0 = m_ag;
}
-__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ag = sc->data0;
//float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
if(m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNI > 0 && cosNO > 0) {
// get half vector
float3 Hr = normalize(omega_in + I);
// eq. 20: (F*G*D)/(4*in*on)
// eq. 33: first we calculate D(m) with m=Hr:
float alpha2 = m_ag * m_ag;
- float cosThetaM = dot(m_N, Hr);
+ float cosThetaM = dot(N, Hr);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ag = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
if(!m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
return make_float3 (0, 0, 0); // vectors on same side -- not possible
// compute half-vector of the refraction (eq. 16)
float cosHI = dot(Ht, omega_in);
// eq. 33: first we calculate D(m) with m=Ht:
float alpha2 = m_ag * m_ag;
- float cosThetaM = dot(m_N, Ht);
+ float cosThetaM = dot(N, Ht);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_microfacet_ggx_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_ag = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- float3 X, Y, Z = m_N;
+ float3 X, Y, Z = N;
make_orthonormals(Z, &X, &Y);
// generate a random microfacet normal m
// eq. 35,36:
(sinf(phiM) * sinThetaM) * Y +
cosThetaM * Z;
if(!m_refractive) {
- float cosMO = dot(m, sd->I);
+ float cosMO = dot(m, I);
if(cosMO > 0) {
// eq. 39 - compute actual reflected direction
- *omega_in = 2 * cosMO * m - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = 2 * cosMO * m - I;
+ if(dot(Ng, *omega_in) > 0) {
// microfacet normal is visible to this ray
// eq. 33
float cosThetaM2 = cosThetaM * cosThetaM;
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
*pdf = pm * 0.25f / cosMO;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 34: now calculate G1(i,m) and G1(o,m)
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
float out = (G * D) * 0.25f / cosNO;
*eval = make_float3(out, out, out);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx;
- *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
float3 dRdx, dRdy, dTdx, dTdy;
#endif
bool inside;
- fresnel_dielectric(m_eta, m, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
// eq. 24
float pm = D * cosThetaM;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 34: now calculate G1(i,m) and G1(o,m)
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
float G = G1o * G1i;
// eq. 21
float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, sd->I);
+ float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
Ht2 *= Ht2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
/* BECKMANN */
-typedef struct BsdfMicrofacetBeckmannClosure {
- //float3 m_N;
- float m_ab;
- float m_eta;
-} BsdfMicrofacetBeckmannClosure;
-
__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive)
{
float m_ab = clamp(ab, 1e-4f, 1.0f);
sc->data0 = m_ab;
}
-__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ab = sc->data0;
//float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
if(m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
// get half vector
float3 Hr = normalize(omega_in + I);
// eq. 20: (F*G*D)/(4*in*on)
// eq. 25: first we calculate D(m) with m=Hr:
float alpha2 = m_ab * m_ab;
- float cosThetaM = dot(m_N, Hr);
+ float cosThetaM = dot(N, Hr);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ab = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
if(!m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
return make_float3 (0, 0, 0);
// compute half-vector of the refraction (eq. 16)
float cosHI = dot(Ht, omega_in);
// eq. 33: first we calculate D(m) with m=Ht:
float alpha2 = m_ab * m_ab;
- float cosThetaM = dot(m_N, Ht);
+ float cosThetaM = dot(N, Ht);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_microfacet_beckmann_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_ab = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- float3 X, Y, Z = m_N;
+ float3 X, Y, Z = N;
make_orthonormals(Z, &X, &Y);
// generate a random microfacet normal m
// eq. 35,36:
cosThetaM * Z;
if(!m_refractive) {
- float cosMO = dot(m, sd->I);
+ float cosMO = dot(m, I);
if(cosMO > 0) {
// eq. 39 - compute actual reflected direction
- *omega_in = 2 * cosMO * m - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = 2 * cosMO * m - I;
+ if(dot(Ng, *omega_in) > 0) {
// microfacet normal is visible to this ray
// eq. 25
float cosThetaM2 = cosThetaM * cosThetaM;
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
*pdf = pm * 0.25f / cosMO;
// Eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
float out = (G * D) * 0.25f / cosNO;
*eval = make_float3(out, out, out);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx;
- *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
float3 dRdx, dRdy, dTdx, dTdy;
#endif
bool inside;
- fresnel_dielectric(m_eta, m, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
// eq. 24
float pm = D * cosThetaM;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
float G = G1o * G1i;
// eq. 21
float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, sd->I);
+ float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
Ht2 *= Ht2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
CCL_NAMESPACE_BEGIN
-typedef struct BsdfOrenNayarClosure {
- float m_a;
- float m_b;
-} BsdfOrenNayarClosure;
-
__device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l)
{
float nl = max(dot(n, l), 0.0f);
{
}
-__device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
if (dot(sc->N, omega_in) > 0.0f) {
*pdf = 0.5f * M_1_PI_F;
}
}
-__device float3 bsdf_oren_nayar_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_oren_nayar_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_oren_nayar_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_oren_nayar_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf);
- if (dot(sd->Ng, *omega_in) > 0.0f) {
- *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, sd->I, *omega_in);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the bounce
- *domega_in_dx = (2.0f * dot(sc->N, sd->dI.dx)) * sc->N - sd->dI.dx;
- *domega_in_dy = (2.0f * dot(sc->N, sd->dI.dy)) * sc->N - sd->dI.dy;
+ *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
/* REFLECTION */
-typedef struct BsdfReflectionClosure {
- //float3 m_N;
-} BsdfReflectionClosure;
-
__device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_REFLECTION_ID;
{
}
-__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_reflection_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
//const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data;
- float3 m_N = sc->N;
+ float3 N = sc->N;
// only one direction is possible
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- *omega_in = (2 * cosNO) * m_N - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = (2 * cosNO) * N - I;
+ if(dot(Ng, *omega_in) > 0) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = 2 * dot(m_N, sd->dI.dx) * m_N - sd->dI.dx;
- *domega_in_dy = 2 * dot(m_N, sd->dI.dy) * m_N - sd->dI.dy;
+ *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
+ *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
#endif
*pdf = 1;
*eval = make_float3(1, 1, 1);
/* REFRACTION */
-typedef struct BsdfRefractionClosure {
- float m_eta;
-} BsdfRefractionClosure;
-
__device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta)
{
sc->data0 = eta;
{
}
-__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_refraction_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_eta = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
bool inside;
- fresnel_dielectric(m_eta, m_N, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, N, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
{
}
-__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_transparent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_transparent_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_transparent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
// only one direction is possible
- *omega_in = -sd->I;
+ *omega_in = -I;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = -sd->dI.dx;
- *domega_in_dy = -sd->dI.dy;
+ *domega_in_dx = -dIdx;
+ *domega_in_dy = -dIdy;
#endif
*pdf = 1;
*eval = make_float3(1, 1, 1);
/* WARD */
-typedef struct BsdfWardClosure {
- //float3 m_N;
- //float3 m_T;
- float m_ax;
- float m_ay;
-} BsdfWardClosure;
-
-__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float3 T, float ax, float ay)
+__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float ax, float ay)
{
float m_ax = clamp(ax, 1e-5f, 1.0f);
float m_ay = clamp(ay, 1e-5f, 1.0f);
sc->data1 = fmaxf(roughness, sc->data1);
}
-__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ax = sc->data0;
float m_ay = sc->data1;
- float3 m_N = sc->N;
- float3 m_T = sd->T;
+ float3 N = sc->N;
+ float3 T = sc->T;
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNI > 0 && cosNO > 0) {
// get half vector and get x,y basis on the surface for anisotropy
float3 H = normalize(omega_in + I); // normalize needed for pdf
float3 X, Y;
- make_orthonormals_tangent(m_N, m_T, &X, &Y);
+ make_orthonormals_tangent(N, T, &X, &Y);
// eq. 4
float dotx = dot(H, X) / m_ax;
float doty = dot(H, Y) / m_ay;
- float dotn = dot(H, m_N);
+ float dotn = dot(H, N);
float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
float denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
float exp_val = expf(-exp_arg);
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_ward_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_ward_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_ax = sc->data0;
float m_ay = sc->data1;
- float3 m_N = sc->N;
- float3 m_T = sd->T;
+ float3 N = sc->N;
+ float3 T = sc->T;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
// get x,y basis on the surface for anisotropy
float3 X, Y;
- make_orthonormals_tangent(m_N, m_T, &X, &Y);
+ make_orthonormals_tangent(N, T, &X, &Y);
// generate random angles for the half vector
// eq. 7 (taking care around discontinuities to keep
//ttoutput angle in the right quadrant)
float doty = h.y / m_ay;
float dotn = h.z;
// transform to world space
- h = h.x * X + h.y * Y + h.z * m_N;
+ h = h.x * X + h.y * Y + h.z * N;
// generate the final sample
- float oh = dot(h, sd->I);
- *omega_in = 2.0f * oh * h - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
- float cosNI = dot(m_N, *omega_in);
+ float oh = dot(h, I);
+ *omega_in = 2.0f * oh * h - I;
+ if(dot(Ng, *omega_in) > 0) {
+ float cosNI = dot(N, *omega_in);
if(cosNI > 0) {
// eq. 9
float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
float power = cosNI * expf(-exp_arg) / denom;
*eval = make_float3(power, power, power);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
/* WESTIN BACKSCATTER */
-typedef struct BsdfWestinBackscatterClosure {
- //float3 m_N;
- float m_invroughness;
-} BsdfWestinBackscatterClosure;
-
__device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness)
{
roughness = clamp(roughness, 1e-5f, 1.0f);
sc->data0 = m_invroughness;
}
-__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_invroughness = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
// pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
float cosine = dot(I, omega_in);
*pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0;
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_westin_backscatter_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_invroughness = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = sd->dI.dx;
- *domega_in_dy = sd->dI.dy;
+ *domega_in_dx = dIdx;
+ *domega_in_dy = dIdy;
#endif
float3 T, B;
- make_orthonormals (sd->I, &T, &B);
+ make_orthonormals (I, &T, &B);
float phi = 2 * M_PI_F * randu;
float cosTheta = powf(randv, 1 / (m_invroughness + 1));
float sinTheta2 = 1 - cosTheta * cosTheta;
float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
*omega_in = (cosf(phi) * sinTheta) * T +
(sinf(phi) * sinTheta) * B +
- (cosTheta) * sd->I;
- if(dot(sd->Ng, *omega_in) > 0)
+ (cosTheta) * I;
+ if(dot(Ng, *omega_in) > 0)
{
// common terms for pdf and eval
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// make sure the direction we chose is still in the right hemisphere
if(cosNI > 0)
{
/* WESTIN SHEEN */
-typedef struct BsdfWestinSheenClosure {
- //float3 m_N;
- float m_edginess;
-} BsdfWestinSheenClosure;
-
__device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess)
{
sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID;
{
}
-__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_edginess = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
// pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
float sinNO2 = 1 - cosNO * cosNO;
*pdf = cosNI * M_1_PI_F;
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_westin_sheen_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float m_edginess = sc->data0;
- float3 m_N = sc->N;
+ float3 N = sc->N;
// we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere
- sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0) {
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ if(dot(Ng, *omega_in) > 0) {
// TODO: account for sheen when sampling
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
float sinNO2 = 1 - cosNO * cosNO;
float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0;
*eval = make_float3(westin, westin, westin);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
case NODE_CLOSURE_WEIGHT:
svm_node_closure_weight(sd, stack, node.y);
break;
-#ifdef __DPDU__
- case NODE_CLOSURE_SET_TANGENT:
- svm_node_closure_set_tangent(sd, node.y, node.z, node.w);
- break;
- case NODE_CLOSURE_TANGENT:
- svm_node_closure_tangent(sd, stack, node.y);
- break;
-#endif
case NODE_EMISSION_WEIGHT:
svm_node_emission_weight(kg, sd, stack, node);
break;
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __SVM__
case CLOSURE_BSDF_OREN_NAYAR_ID:
- label = bsdf_oren_nayar_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- label = bsdf_ward_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#endif
default:
if(dot(sd->Ng, omega_in) >= 0.0f) {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#ifdef __SVM__
case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#endif
default:
else {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#ifdef __SVM__
case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#endif
default:
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
+ sc->T = stack_load_float3(stack, data_node.z);
svm_node_closure_set_mix_weight(sc, mix_weight);
float roughness_u = param1;
float roughness_v = param2;
- bsdf_ward_setup(sd, sc, sd->T, roughness_u, roughness_v);
+ bsdf_ward_setup(sd, sc, roughness_u, roughness_v);
break;
}
#endif
#endif
}
-/* Tangent */
-
-#ifdef __DPDU__
-__device_inline void svm_node_closure_store_tangent(ShaderData *sd, float3 tangent)
-{
- sd->T = normalize(tangent);
-}
-
-__device void svm_node_closure_set_tangent(ShaderData *sd, uint x, uint y, uint z)
-{
- float3 tangent = make_float3(__int_as_float(x), __int_as_float(y), __int_as_float(z));
- svm_node_closure_store_tangent(sd, tangent);
-}
-
-__device void svm_node_closure_tangent(ShaderData *sd, float *stack, uint tangent_offset)
-{
- float3 tangent = stack_load_float3(stack, tangent_offset);
- svm_node_closure_store_tangent(sd, tangent);
-}
-#endif
-
/* (Bump) normal */
__device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
NODE_OBJECT_INFO,
NODE_PARTICLE_INFO,
NODE_TEX_BRICK,
- NODE_CLOSURE_SET_TANGENT,
- NODE_CLOSURE_TANGENT,
NODE_CLOSURE_SET_NORMAL,
} NodeType;
{
ShaderInput *color_in = input("Color");
ShaderInput *normal_in = input("Normal");
+ ShaderInput *tangent_in = input("Tangent");
if(color_in->link) {
compiler.stack_assign(color_in);
if(normal_in->link)
compiler.stack_assign(normal_in);
- compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset);
+
+ if(tangent_in) {
+ if(tangent_in->link)
+ compiler.stack_assign(tangent_in);
+
+ compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset);
+ }
+ else {
+ compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset);
+ }
}
void BsdfNode::compile(SVMCompiler& compiler)
{
ShaderInput *tangent_in = input("Tangent");
- if(tangent_in->link) {
- int attr = compiler.attribute(ATTR_STD_TANGENT);
- compiler.stack_assign(tangent_in);
- compiler.add_node(NODE_ATTR, attr, tangent_in->stack_offset, NODE_ATTR_FLOAT3);
- compiler.add_node(NODE_CLOSURE_TANGENT, tangent_in->stack_offset);
- }
- else
- compiler.add_node(NODE_CLOSURE_SET_TANGENT, tangent_in->value);
-
BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V"));
}
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }
};