void sampleLightPaths() { auto mis = [&](float v) { return Mis(v); }; processTasksDeterminist(m_SharedData.m_nLightPathCount, [&](uint32_t pathID, uint32_t threadID) { ThreadRNG rng(m_Rng, threadID); auto pLightPath = m_SharedData.m_LightVertexBuffer.getSlicePtr(pathID); m_SharedData.m_EmissionVertexBuffer[pathID] = sampleLightPath(pLightPath, m_SharedData.m_nLightPathMaxDepth, m_Params.m_Scene, m_SharedData.m_LightSampler, m_Params.m_nResamplingPathCount, mis, rng); }, getSystemThreadCount()); }
void UniformResamplingRecursiveMISBPTRenderer::sampleLightPaths() { m_LightPathBuffer.resize(getMaxLightPathDepth(), m_nLightPathCount); auto mis = [&](float v) { return Mis(v); }; processTasksDeterminist(m_nLightPathCount, [&](uint32_t pathID, uint32_t threadID) { ThreadRNG rng(*this, threadID); auto pLightPath = m_LightPathBuffer.getSlicePtr(pathID); sampleLightPath(pLightPath, getMaxLightPathDepth(), getScene(), m_LightSampler, getSppCount(), mis, rng); }, getThreadCount()); }
int CSolveAxb(CMatrCl &a,CVecCl &b,CVecCl &x,double Tol) { // double q=1,q2=1+q/2;while (q2>1) {q/=2;q2=1+q/2;} // long double q1=1;while (((long double)(1+q1/2)-1)>0) q1/=2; // Tol=q*a.Dim();cout<<" Tol = "<<Tol<<"\n"; my_comp d1; int N=a.Dim(),l; CMatrCl LU=a; CVecCl Mis(N); int d2,*rear=new int[N+1];rear[0]=N; int ret=URCunsymdet(LU,Tol,d1,d2,rear); if (!ret) {delete []rear;return ret;} //cout<<" Matrics \n"<<a<<" Det= "<<d1*pow(2,d2)<<" LU decompose \n"<<LU; //CMatrCl L=LU,U=LU;for (int k=1;k<=N;k++) {for (int k1=1;k1<k;k1++) //{U(k,k1)=0;L(k1,k)=0;} L(k,k)=LU(k,k);U(k,k)=my_comp(1,0);} //cout<<L<<U<<" L*U= \n"<<L*U; ret=URCunsymaccsol(a,LU,rear,b,Tol,x,Mis,l); //cout<<" Iter done "<<l<<" Error "<<ret<<" Input vector \n"<<b // <<" Result vector \n"<<x <<" Misfit \n"<<Mis<<" Delta\n"<<a*x-b // <<" Matrics a\n"<<a; delete []rear; return ret; };
void UniformResamplingRecursiveMISBPTRenderer::connectLightVerticesToSensor(uint32_t threadID, uint32_t tileID, const Vec4u& viewport) const { auto rcpPathCount = 1.f / m_nLightPathCount; auto mis = [&](float v) { return Mis(v); }; for(const auto& directImportanceSample: m_DirectImportanceSampleTilePartitionning[tileID]) { auto pLightVertex = &m_LightPathBuffer[directImportanceSample.m_nLightVertexIndex]; auto totalDepth = 1 + pLightVertex->m_nDepth; if(!acceptPathDepth(totalDepth) || totalDepth > m_nMaxDepth) { continue; } auto pixel = directImportanceSample.m_Pixel; auto pixelID = BnZ::getPixelIndex(pixel, getFramebufferSize()); PixelSensor sensor(getSensor(), pixel, getFramebufferSize()); auto contrib = rcpPathCount * connectVertices(*pLightVertex, SensorVertex(&sensor, directImportanceSample.m_LensSample), getScene(), m_nLightPathCount, mis); if(isInvalidMeasurementEstimate(contrib)) { reportInvalidContrib(threadID, tileID, pixelID, [&]() { debugLog() << "s = " << (pLightVertex->m_nDepth + 1) << ", t = " << 1 << std::endl; }); } accumulate(FINAL_RENDER, pixelID, Vec4f(contrib, 0.f)); accumulate(FINAL_RENDER_DEPTH1 + totalDepth - 1u, pixelID, Vec4f(contrib, 0.f)); auto strategyOffset = computeBPTStrategyOffset(totalDepth + 1, pLightVertex->m_nDepth + 1); accumulate(BPT_STRATEGY_s0_t2 + strategyOffset, pixelID, Vec4f(contrib, 0)); } }
void UniformResamplingRecursiveMISBPTRenderer::processSample(uint32_t threadID, uint32_t tileID, uint32_t pixelID, uint32_t sampleID, uint32_t x, uint32_t y) const { auto mis = [&](float v) { return Mis(v); }; ThreadRNG rng(*this, threadID); PixelSensor pixelSensor(getSensor(), Vec2u(x, y), getFramebufferSize()); auto pixelSample = getPixelSample(threadID, sampleID); auto sensorSample = getFloat2(threadID); auto fImportanceScale = 1.f / getSppCount(); BDPTPathVertex eyeVertex(getScene(), pixelSensor, sensorSample, pixelSample, m_nLightPathCount, mis); if(eyeVertex.m_Power == zero<Vec3f>() || !eyeVertex.m_fPathPdf) { return; } // Sample the light path to connect with the eye path auto lightPathIdx = clamp(std::size_t(getFloat(threadID) * m_nLightPathCount), std::size_t(0), m_nLightPathCount - 1); auto pLightPath = m_LightPathBuffer.getSlicePtr(lightPathIdx); auto maxEyePathDepth = getMaxEyePathDepth(); auto maxLightPathDepth = getMaxLightPathDepth(); auto extendEyePath = [&]() -> bool { return eyeVertex.m_nDepth < maxEyePathDepth && eyeVertex.extend(eyeVertex, getScene(), getSppCount(), false, rng, mis); }; // Iterate over an eye path do { // Intersection with light source auto totalLength = eyeVertex.m_nDepth; if(acceptPathDepth(totalLength) && totalLength <= m_nMaxDepth) { auto contrib = fImportanceScale * computeEmittedRadiance(eyeVertex, getScene(), m_LightSampler, getSppCount(), mis); if(isInvalidMeasurementEstimate(contrib)) { reportInvalidContrib(threadID, tileID, pixelID, [&]() { debugLog() << "s = " << 0 << ", t = " << (eyeVertex.m_nDepth + 1) << std::endl; }); } accumulate(FINAL_RENDER, pixelID, Vec4f(contrib, 0)); accumulate(FINAL_RENDER_DEPTH1 + totalLength - 1u, pixelID, Vec4f(contrib, 0)); auto strategyOffset = computeBPTStrategyOffset(totalLength + 1, 0u); accumulate(BPT_STRATEGY_s0_t2 + strategyOffset, pixelID, Vec4f(contrib, 0)); } // Connections if(eyeVertex.m_Intersection) { // Direct illumination auto totalLength = eyeVertex.m_nDepth + 1; if(acceptPathDepth(totalLength) && totalLength <= m_nMaxDepth) { float lightPdf; auto pLight = m_LightSampler.sample(getScene(), getFloat(threadID), lightPdf); auto s2D = getFloat2(threadID); auto contrib = fImportanceScale * connectVertices(eyeVertex, EmissionVertex(pLight, lightPdf, s2D), getScene(), getSppCount(), mis); if(isInvalidMeasurementEstimate(contrib)) { reportInvalidContrib(threadID, tileID, pixelID, [&]() { debugLog() << "s = " << 1 << ", t = " << (eyeVertex.m_nDepth + 1) << std::endl; }); } accumulate(FINAL_RENDER, pixelID, Vec4f(contrib, 0)); accumulate(FINAL_RENDER_DEPTH1 + totalLength - 1u, pixelID, Vec4f(contrib, 0)); auto strategyOffset = computeBPTStrategyOffset(totalLength + 1, 1); accumulate(BPT_STRATEGY_s0_t2 + strategyOffset, pixelID, Vec4f(contrib, 0)); } // Connection with each light vertex for(auto j = 0u; j < maxLightPathDepth; ++j) { auto pLightVertex = pLightPath + j; auto totalLength = eyeVertex.m_nDepth + pLightVertex->m_nDepth + 1; if(pLightVertex->m_fPathPdf > 0.f && acceptPathDepth(totalLength) && totalLength <= m_nMaxDepth) { auto contrib = fImportanceScale * connectVertices(eyeVertex, *pLightVertex, getScene(), getSppCount(), mis); if(isInvalidMeasurementEstimate(contrib)) { reportInvalidContrib(threadID, tileID, pixelID, [&]() { debugLog() << "s = " << (pLightVertex->m_nDepth + 1) << ", t = " << (eyeVertex.m_nDepth + 1) << std::endl; }); } accumulate(FINAL_RENDER, pixelID, Vec4f(contrib, 0)); accumulate(FINAL_RENDER_DEPTH1 + totalLength - 1u, pixelID, Vec4f(contrib, 0)); auto strategyOffset = computeBPTStrategyOffset(totalLength + 1, pLightVertex->m_nDepth + 1); accumulate(BPT_STRATEGY_s0_t2 + strategyOffset, pixelID, Vec4f(contrib, 0)); } } } } while(extendEyePath()); }