Exemplo n.º 1
0
///////////////////////////////////////////////////////////////////////////////
//		_Indirect_irradiance
// Estimate the in-direction irradiance (diffuse)
///////////////////////////////////////////////////////////////////////////////
CCol4 CMcBspTR::_Indirect_irradiance (const TBspCross &crs, int nPID, int nDepth)
{
	CCol4 cAccu = COLOR_BLACK;
	CBspMaterial *pm = &m_pMaterials[m_pTriangles[nPID].GetMaterialID()];

	if (m_nDistrRayNum <= 0) return cAccu;
	//-------------------------------------------------------------------------
	// If it is the first hit, we would need to estimate the indirect
	// illumination accurately. 
	//-------------------------------------------------------------------------
	if (nDepth == 0)
	{
		int nAccu = 0;
		BOOL bHitLig;
		TBspRay ray;

		// The local frame
		CVec3 vZ = crs.vNml.Normalized();
		CVec3 vY = RANDOM_VEC;
		CVec3 vX = (vY.Cross(vZ)).Normalized();
		vY = vZ.Cross(vX);

		// The inclination and azimuth resolution
		int m = (int) sqrt((double)(m_nDistrRayNum>>2));
		int n = m_nDistrRayNum / m;
		
		// Evenly distribute the sampling ray on the hemi-sphere according to
		// the inclination angle
		for (int i = 1; i <= n; i ++)
		{
			for (int j = 1; j <= m; j ++)
			{
				float fTheta = (float)asin(sqrt((j-RANDOM_0_1)/m));
				float fPhi   = 2 * PI * (i-RANDOM_0_1)/n;

				ray.vDir = vY * sin (fPhi) + vX * cos (fPhi);
				ray.vDir = vZ * sin (fTheta) + ray.vDir * cos (fTheta);
				ray.vOrg = crs.vPos;
				ray.vEnd = ray.vOrg + ray.vDir * m_fSceneSize;
				CCol4 cTemp = _PM_radiance_along_the_ray (ray, nPID, bHitLig);

				if (!bHitLig)
				{
					cAccu += cTemp;
					nAccu ++;
				}
			}
		}

		cAccu = cAccu * PI / nAccu;
		// cAccu = cAccu / nAccu;
	}
Exemplo n.º 2
0
///////////////////////////////////////////////////////////////////////////////
//		_Create_caustic_photonmap
// Build the caustic photon map after the creation of global photon map
///////////////////////////////////////////////////////////////////////////////
void CMcBspTR::_Create_caustic_photonmap(void)
{
	int     i, j;
	CCol4   cCurrPow;
	int     nStored = 0;
	TBspRay ray;
	float   fLen;

	printf("\nBuilding caustic photon map ...\n");

	TCausDir *p = m_tCausDir.next;

	for (i = 0; i < m_nCausDir; i ++)
	{
		printf (".");
		CCol4 cPow = m_tpLigPatches[p->nLID].cPhotonPow / m_nCauPhoSubd * 5;

		if (m_bDirectionalLight)
		{
			CBspTriangle *tri = &m_pTriangles[m_tpLigPatches[p->nLID].nTID];
			fLen = sqrt(tri->Calc_area() / m_tpLigPatches[p->nLID].nPhotonNum);
			CVec3 vZ = tri->Calc_normal();
			CVec3 vY = RANDOM_VEC;
			CVec3 vX = vY.Cross(vZ);
			vX.Normalize();
			vY = vZ.Cross(vX);

			vX *= fLen;
			vY *= fLen;

			for (j = 0; j < m_nCauPhoSubd; j ++)
			{
				ray.vOrg = p->vPos + vX * RANDOM_N1_P1 + vY * RANDOM_N1_P1;
				ray.vDir = p->vDir;
				ray.vEnd = ray.vOrg + ray.vDir * m_fSceneSize;
				_Trace_caustic_photon (ray, cPow, m_tpLigPatches[p->nLID].nTID,
					nStored);
			}
		}
		else
		{
			double fCos = cos(PI/sqrt(m_tpLigPatches[p->nLID].nPhotonNum*4.));
			fLen = 2.f * (float) tan( acos(fCos) );

			for (j = 0; j < m_nCauPhoSubd; j ++)
			{
				ray.vOrg = p->vPos;
				ray.vDir = p->vDir + (RANDOM_VEC * fLen);
				ray.vDir.Normalize();
				ray.vEnd = ray.vOrg + ray.vDir * m_fSceneSize;
				_Trace_caustic_photon (ray, cPow, m_tpLigPatches[p->nLID].nTID,
					nStored);
			}
		}
		
		m_tCausDir.next = p->next;
		delete p;
		p = m_tCausDir.next;
	}
	m_tCausDir.next = NULL;

	// Balance photon map kd-tree
	printf("\n Balance KD tree");
	m_pCausticPhotonMap->balance();
	printf("\nFinish building caustic photon map, %d photons stored\n", nStored);
}