Esempio n. 1
0
	Vector sampleVNormal(const Vector &wi, Sampler *sampler, Float Sxx, Float Syy, Float Szz,
		Float Sxy, Float Sxz, Float Syz) const {
		Float u1 = sampler->next1D();
		Float u2 = sampler->next1D();
		
		Float r = sqrtf(u1);
		Float phi = 2.f * M_PI * u2;
		Float u = r * cosf(phi);
		Float v = r * sinf(phi);
		Float w = sqrtf(1.f - u * u - v * v);

		Vector wk, wj;
		Frame frame(wi);
		wk = frame.s;
		wj = frame.t;

		// project S in this basis
		Float Skk = wk.x * wk.x * Sxx + wk.y * wk.y * Syy + wk.z * wk.z * Szz +
			2.f * (wk.x * wk.y * Sxy + wk.x * wk.z * Sxz + wk.y * wk.z * Syz);
		Float Sjj = wj.x * wj.x * Sxx + wj.y * wj.y * Syy + wj.z * wj.z * Szz +
			2.f * (wj.x * wj.y * Sxy + wj.x * wj.z * Sxz + wj.y * wj.z * Syz);
		Float Sii = wi.x * wi.x * Sxx + wi.y * wi.y * Syy + wi.z * wi.z * Szz +
			2.f * (wi.x * wi.y * Sxy + wi.x * wi.z * Sxz + wi.y * wi.z * Syz);
		Float Skj = wk.x * wj.x * Sxx + wk.y * wj.y * Syy + wk.z * wj.z * Szz +
			(wk.x * wj.y + wk.y * wj.x) * Sxy + (wk.x * wj.z + wk.z * wj.x) * Sxz +
			(wk.y * wj.z + wk.z * wj.y) * Syz;
		Float Ski = wk.x * wi.x * Sxx + wk.y * wi.y * Syy + wk.z * wi.z * Szz +
			(wk.x * wi.y + wk.y * wi.x) * Sxy + (wk.x * wi.z + wk.z * wi.x) * Sxz +
			(wk.y * wi.z + wk.z * wi.y) * Syz;
		Float Sji = wj.x * wi.x * Sxx + wj.y * wi.y * Syy + wj.z * wi.z * Szz +
			(wj.x * wi.y + wj.y * wi.x) * Sxy + (wj.x * wi.z + wj.z * wi.x) * Sxz +
			(wj.y * wi.z + wj.z * wi.y) * Syz;

		Float sqrtDetSkji = sqrtf(fabs(Skk * Sjj * Sii - Skj * Skj * Sii - Ski * Ski * Sjj -
			Sji * Sji * Skk + 2.f * Skj * Ski * Sji));
		Float invSqrtSii = 1.f / sqrt(Sii);
		Float tmp = sqrtf(Sjj * Sii - Sji * Sji);
		Vector Mk(sqrtDetSkji / tmp, 0.f, 0.f);
		Vector Mj(-invSqrtSii * (Ski * Sji - Skj * Sii) / tmp, invSqrtSii * tmp, 0);
		Vector Mi(invSqrtSii * Ski, invSqrtSii * Sji, invSqrtSii * Sii);
		
		Vector wm_kji = normalize(u * Mk + v * Mj + w * Mi);
		return normalize(wm_kji.x * wk + wm_kji.y * wj + wm_kji.z * wi);
	}
vec3 sample_VNDF(const vec3 wi,
	const float S_xx, const float S_yy, const float S_zz,
	const float S_xy, const float S_xz, const float S_yz,
	const float U1, const float U2)
{
	// generate sample (u, v, w)
	const float r = sqrtf(U1);
	const float phi = 2.0f*M_PI*U2;
	const float u = r*cosf(phi);
	const float v = r*sinf(phi);
	const float w = sqrtf(1.0f - u*u - v*v);
	// build orthonormal basis
	vec3 wk, wj;
	buildOrthonormalBasis(wk, wj, wi);
	// project S in this basis
	const float S_kk = wk.x*wk.x*S_xx + wk.y*wk.y*S_yy + wk.z*wk.z*S_zz
		+ 2.0f * (wk.x*wk.y*S_xy + wk.x*wk.z*S_xz + wk.y*wk.z*S_yz);
	const float S_jj = wj.x*wj.x*S_xx + wj.y*wj.y*S_yy + wj.z*wj.z*S_zz
		+ 2.0f * (wj.x*wj.y*S_xy + wj.x*wj.z*S_xz + wj.y*wj.z*S_yz);
	const float S_ii = wi.x*wi.x*S_xx + wi.y*wi.y*S_yy + wi.z*wi.z*S_zz
		+ 2.0f * (wi.x*wi.y*S_xy + wi.x*wi.z*S_xz + wi.y*wi.z*S_yz);
	const float S_kj = wk.x*wj.x*S_xx + wk.y*wj.y*S_yy + wk.z*wj.z*S_zz
		+ (wk.x*wj.y + wk.y*wj.x)*S_xy
		+ (wk.x*wj.z + wk.z*wj.x)*S_xz
		+ (wk.y*wj.z + wk.z*wj.y)*S_yz;
	const float S_ki = wk.x*wi.x*S_xx + wk.y*wi.y*S_yy + wk.z*wi.z*S_zz
		+ (wk.x*wi.y + wk.y*wi.x)*S_xy + (wk.x*wi.z + wk.z*wi.x)*S_xz + (wk.y*wi.z + wk.z*wi.y)*S_yz;
	const float S_ji = wj.x*wi.x*S_xx + wj.y*wi.y*S_yy + wj.z*wi.z*S_zz
		+ (wj.x*wi.y + wj.y*wi.x)*S_xy
		+ (wj.x*wi.z + wj.z*wi.x)*S_xz
		+ (wj.y*wi.z + wj.z*wi.y)*S_yz;
	// compute normal
	float sqrtDetSkji = sqrtf(fabsf(S_kk*S_jj*S_ii - S_kj*S_kj*S_ii - S_ki*S_ki*S_jj - S_ji*S_ji*S_kk + 2.0f*S_kj*S_ki*S_ji));
	float inv_sqrtS_ii = 1.0f / sqrtf(S_ii);
	float tmp = sqrtf(S_jj*S_ii - S_ji*S_ji);
	vec3 Mk(sqrtDetSkji / tmp, 0.0f, 0.0f);
	vec3 Mj(-inv_sqrtS_ii*(S_ki*S_ji - S_kj*S_ii) / tmp, inv_sqrtS_ii*tmp, 0);
	vec3 Mi(inv_sqrtS_ii*S_ki, inv_sqrtS_ii*S_ji, inv_sqrtS_ii*S_ii);
	vec3 wm_kji = normalize(u*Mk + v*Mj + w*Mi);
	// rotate back to world basis
	return wm_kji.x * wk + wm_kji.y * wj + wm_kji.z * wi;
}