/////////////////////////////////////////////////////////////////////////////// // _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; }
/////////////////////////////////////////////////////////////////////////////// // _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); }