code.cpp
// --------------------------------------------------------------------------
// This code snipplet projects the incoming radiance on hemi(spherical)
// harmonics and computes the translational gradient of the coefficient
// vector.
//
// The code is invoked once for every ray used for hemisphere sampling when
// a new radiance cache records is being created.
//
//
// Identifiers are
// float *H............... evaluated basis functions
// float *dH_dt
// float *dH_dp........... derivatives of the basis functions w.r.t theta
// and phi
// CVector3D raydir_loc... ray direction in the local frame
// CVector3D raydir_glob.. ray direction in the global frame
// float cos_theta, cos_phi, sin_theta, sin_phi
// ................ ray direction w.r.t. the local frame
// _sphBasis->EvalDerivCartVInt()
// ................ evaluates the basis functions (SH or HSH) and
// their derivatives up to 'desiredOrder' in a
// given direction.
// float r ............... distance to the hit point
// float ir .............. 1/r
// CVector3D U, V, N .... axes of the local coordinate frame
// float cos_xi .......... angle between the ray direction and the surface
// normal at the hit point
// float *dx_gray, *dy_gray .. aux arrays
//
// Results of the computation are:
// 'result'................ 3 vectors of projection coefficients, one vector
// for each color channel
// 'dx', 'dy' ............. 3 vectors of derivatives of the projection
// coefficients, one vector for each color channel
// sqrDesiredOrder ...... order^2
//
// After processing all rays, the vectors 'result', 'dx' and 'dy'
// have to be multiplies by 2*PI/N, where N is the number of cast rays.
//
//////////////////////////////////////////////////////////////////
// evaluate (H)SH coefficients + derivatives
_sphBasis->EvalDerivCartVInt(desiredOrder,
_localFrame ? raydir_loc : raydir_glob,
&H, &dH_dt, &dH_dp);
// transform the normal at the hit point to the local frame
CVector3D nl = ToLocalFrame(outgoingHitInfo.GetNormal(),U,V,N);
// derivatives of Omega w.r.t x and y
float dOmega_dx = ( nl.x + 3.0f*raydir_loc.x*cos_xi ) / (r*cos_xi);
float dOmega_dy = ( nl.y + 3.0f*raydir_loc.y*cos_xi ) / (r*cos_xi);
// derivatives needed to evaluate dH/dx
// using dH/dx = dH/dtheta*dtheta/dx + dH/dphi*dphi/dx
float dTheta_dx = -cos_theta * cos_phi * ir;
float dTheta_dy = -cos_theta * sin_phi * ir;
float dPhi_dx = sin_phi / (r * sin_theta);
float dPhi_dy = -cos_phi / (r * sin_theta);
// L_i - independent computation...
for(int i=0; iGetChannel(ch), dx_gray,Li[ch]);
gvectf::madvsip(sqrDesiredOrder,dy->GetChannel(ch), dy_gray,Li[ch]);
}
by
AMcneil
—
last modified
Feb 29, 2016 12:26 PM