1 #include <core_api/surface.h>
2 #include <core_api/ray.h>
3 #include <utilities/interpolation.h>
4
5 __BEGIN_YAFRAY
6
spDifferentials_t(const surfacePoint_t & spoint,const diffRay_t & ray)7 spDifferentials_t::spDifferentials_t(const surfacePoint_t &spoint, const diffRay_t &ray): sp(spoint)
8 {
9 if (ray.hasDifferentials)
10 {
11 // Estimate screen-space change in \pt and $(u,v)$
12 // Compute auxiliary intersection points with plane
13 float d = -(sp.N * vector3d_t(sp.P));
14 vector3d_t rxv(ray.xfrom);
15 float tx = -((sp.N * rxv) + d) / (sp.N * ray.xdir);
16 point3d_t px = ray.xfrom + tx * ray.xdir;
17 vector3d_t ryv(ray.yfrom);
18 float ty = -((sp.N * ryv) + d) / (sp.N * ray.ydir);
19 point3d_t py = ray.yfrom + ty * ray.ydir;
20 dPdx = px - sp.P;
21 dPdy = py - sp.P;
22 }
23 else
24 {
25 //dudx = dvdx = 0.;
26 //dudy = dvdy = 0.;
27 dPdx = dPdy = vector3d_t(0,0,0);
28 }
29 }
30
reflectedRay(const diffRay_t & in,diffRay_t & out) const31 void spDifferentials_t::reflectedRay(const diffRay_t &in, diffRay_t &out) const
32 {
33 if(!in.hasDifferentials)
34 {
35 out.hasDifferentials = false;
36 return;
37 }
38 // Compute ray differential _rd_ for specular reflection
39 out.hasDifferentials = true;
40 out.xfrom = sp.P + dPdx;
41 out.yfrom = sp.P + dPdy;
42 // Compute differential reflected directions
43 // Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx +
44 // bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
45 // Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy +
46 // bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
47 vector3d_t dwodx = in.dir - in.xdir, dwody = in.dir - in.ydir;
48 float dDNdx = (dwodx * sp.N); // + (out.dir * dndx);
49 float dDNdy = (dwody * sp.N); // + (out.dir * dndy);
50 out.xdir = out.dir - dwodx + 2 * (/* (out.dir * sp.N) * dndx + */ dDNdx * sp.N);
51 out.ydir = out.dir - dwody + 2 * (/* (out.dir * sp.N) * dndy + */ dDNdy * sp.N);
52 }
53
refractedRay(const diffRay_t & in,diffRay_t & out,float IOR) const54 void spDifferentials_t::refractedRay(const diffRay_t &in, diffRay_t &out, float IOR) const
55 {
56 if(!in.hasDifferentials)
57 {
58 out.hasDifferentials = false;
59 return;
60 }
61 //RayDifferential rd(p, wi);
62 out.hasDifferentials = true;
63 out.xfrom = sp.P + dPdx;
64 out.yfrom = sp.P + dPdy;
65 //if (Dot(wo, n) < 0) eta = 1.f / eta;
66
67 //Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
68 //Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
69
70 vector3d_t dwodx = in.dir - in.xdir, dwody = in.dir - in.ydir;
71 float dDNdx = (dwodx * sp.N); // + Dot(wo, dndx);
72 float dDNdy = (dwody * sp.N); // + Dot(wo, dndy);
73
74 // float mu = IOR * (in.dir * sp.N) - (out.dir * sp.N);
75 float dmudx = (IOR - (IOR*IOR*(in.dir * sp.N))/(out.dir * sp.N)) * dDNdx;
76 float dmudy = (IOR - (IOR*IOR*(in.dir * sp.N))/(out.dir * sp.N)) * dDNdy;
77
78 out.xdir = out.dir + IOR * dwodx - (/* mu * dndx + */ dmudx * sp.N);
79 out.ydir = out.dir + IOR * dwody - (/* mu * dndy + */ dmudy * sp.N);
80 }
81
projectedPixelArea()82 float spDifferentials_t::projectedPixelArea()
83 {
84 return (dPdx ^ dPdy).length();
85 }
86
dU_dV_from_dP_dPdU_dPdV(float & dU,float & dV,const point3d_t & dP,const vector3d_t & dPdU,const vector3d_t & dPdV) const87 void spDifferentials_t::dU_dV_from_dP_dPdU_dPdV(float &dU, float &dV, const point3d_t &dP, const vector3d_t &dPdU, const vector3d_t &dPdV) const
88 {
89 float detXY = (dPdU.x*dPdV.y)-(dPdV.x*dPdU.y);
90 float detXZ = (dPdU.x*dPdV.z)-(dPdV.x*dPdU.z);
91 float detYZ = (dPdU.y*dPdV.z)-(dPdV.y*dPdU.z);
92
93 if(fabsf(detXY) > 0.f && fabsf(detXY) > fabsf(detXZ) && fabsf(detXY) > fabsf(detYZ))
94 {
95 dU = ((dP.x*dPdV.y)-(dPdV.x*dP.y)) / detXY;
96 dV = ((dPdU.x*dP.y)-(dP.x*dPdU.y)) / detXY;
97 }
98
99 else if(fabsf(detXZ) > 0.f && fabsf(detXZ) > fabsf(detXY) && fabsf(detXZ) > fabsf(detYZ))
100 {
101 dU = ((dP.x*dPdV.z)-(dPdV.x*dP.z)) / detXZ;
102 dV = ((dPdU.x*dP.z)-(dP.x*dPdU.z)) / detXZ;
103 }
104
105 else if(fabsf(detYZ) > 0.f && fabsf(detYZ) > fabsf(detXY) && fabsf(detYZ) > fabsf(detXZ))
106 {
107 dU = ((dP.y*dPdV.z)-(dPdV.y*dP.z)) / detYZ;
108 dV = ((dPdU.y*dP.z)-(dP.y*dPdU.z)) / detYZ;
109 }
110 }
111
getUVdifferentials(float & dUdx,float & dVdx,float & dUdy,float & dVdy) const112 void spDifferentials_t::getUVdifferentials(float &dUdx, float &dVdx, float &dUdy, float &dVdy) const
113 {
114 dU_dV_from_dP_dPdU_dPdV(dUdx, dVdx, dPdx, sp.dPdU_abs, sp.dPdV_abs);
115 dU_dV_from_dP_dPdU_dPdV(dUdy, dVdy, dPdy, sp.dPdU_abs, sp.dPdV_abs);
116 }
117
118
blend_surface_points(surfacePoint_t const & sp_0,surfacePoint_t const & sp_1,float const alpha)119 surfacePoint_t blend_surface_points(surfacePoint_t const& sp_0, surfacePoint_t const& sp_1, float const alpha)
120 {
121 surfacePoint_t sp_result(sp_0);
122
123 sp_result.N = lerp(sp_0.N, sp_1.N, alpha);
124
125 sp_result.NU = lerp(sp_0.NU, sp_1.NU, alpha);
126 sp_result.NV = lerp(sp_0.NV, sp_1.NV, alpha);
127 sp_result.dPdU = lerp(sp_0.dPdU, sp_1.dPdU, alpha);
128 sp_result.dPdV = lerp(sp_0.dPdV, sp_1.dPdV, alpha);
129 sp_result.dSdU = lerp(sp_0.dSdU, sp_1.dSdU, alpha);
130 sp_result.dSdV = lerp(sp_0.dSdV, sp_1.dSdV, alpha);
131
132 return sp_result;
133 }
134
135 __END_YAFRAY
136