TextureResult HosekWilkieSky(const BufferUploads::TextureDesc& desc, const ParameterBox& parameters) { // The "turbidity" parameter is Linke’s turbidity factor. Hosek and Wilkie give these example parameters: // T = 2 yields a very clear, Arctic-like sky // T = 3 a clear sky in a temperate climate // T = 6 a sky on a warm, moist day // T = 10 a slightly hazy day // T > 50 represent dense fog auto defaultSunDirection = Normalize(Float3(1.f, 1.f, 0.33f)); Float3 sunDirection = parameters.GetParameter<Float3>(ParameterBox::ParameterNameHash("SunDirection"), defaultSunDirection); sunDirection = Normalize(sunDirection); auto turbidity = (double)parameters.GetParameter(ParameterBox::ParameterNameHash("turbidity"), 3.f); auto albedo = (double)parameters.GetParameter(ParameterBox::ParameterNameHash("albedo"), 0.1f); auto elevation = (double)Deg2Rad(parameters.GetParameter(ParameterBox::ParameterNameHash("elevation"), XlASin(sunDirection[2]))); auto* state = arhosek_rgb_skymodelstate_alloc_init(turbidity, albedo, elevation); auto pixels = std::make_unique<Float4[]>(desc._width*desc._height); for (unsigned y=0; y<desc._height; ++y) for (unsigned x=0; x<desc._width; ++x) { auto p = y*desc._width+x; pixels[p] = Float4(0.f, 0.f, 0.f, 1.f); Float3 direction(0.f, 0.f, 0.f); bool hitPanel = false; for (unsigned c = 0; c < 6; ++c) { Float2 tc(x / float(desc._width), y / float(desc._height)); auto tcMins = s_verticalPanelCoords[c][0]; auto tcMaxs = s_verticalPanelCoords[c][1]; if (tc[0] >= tcMins[0] && tc[1] >= tcMins[1] && tc[0] < tcMaxs[0] && tc[1] < tcMaxs[1]) { tc[0] = 2.0f * (tc[0] - tcMins[0]) / (tcMaxs[0] - tcMins[0]) - 1.0f; tc[1] = 2.0f * (tc[1] - tcMins[1]) / (tcMaxs[1] - tcMins[1]) - 1.0f; hitPanel = true; auto plusX = s_verticalPanels[c][0]; auto plusY = s_verticalPanels[c][1]; auto center = s_verticalPanels[c][2]; direction = center + plusX * tc[0] + plusY * tc[1]; } } if (hitPanel) { auto theta = CartesianToSpherical(direction)[0]; theta = std::min(.4998f * gPI, theta); auto gamma = XlACos(std::max(0.f, Dot(Normalize(direction), sunDirection))); auto R = arhosek_tristim_skymodel_radiance(state, theta, gamma, 0); auto G = arhosek_tristim_skymodel_radiance(state, theta, gamma, 1); auto B = arhosek_tristim_skymodel_radiance(state, theta, gamma, 2); pixels[p][0] = (float)R; pixels[p][1] = (float)G; pixels[p][2] = (float)B; } } arhosekskymodelstate_free(state); return TextureResult { BufferUploads::CreateBasicPacket( (desc._width*desc._height)*sizeof(Float4), pixels.get(), BufferUploads::TexturePitches(desc._width*sizeof(Float4), desc._width*desc._height*sizeof(Float4))), RenderCore::Metal::NativeFormat::R32G32B32A32_FLOAT, UInt2(desc._width, desc._height) }; }
vec Plane::ProjectToPositiveHalf(const vec &point) const { return point - Min(0.f, (Dot(normal, point) - d)) * normal; }
float Plane::DihedralAngle(const Plane &plane) const { return Dot(normal, plane.normal); }
Vector2 TransformPoint(Mat3Param matrix, Vec2Param vector) { float x = Dot(*(Vector2*)&matrix[0], vector) + matrix[0][2]; float y = Dot(*(Vector2*)&matrix[1], vector) + matrix[1][2]; return Vector2(x, y); }
void PerceptionModule::UpdatePerception() { const float viewDistanceSqr = mViewDistance*mViewDistance; const float viewSpan = cos(mViewAngle * 0.5f); //const AgentList& agents = mOwner.GetWorld().GetAgentList(); const std::vector<Agent*> agents = mOwner.GetWorld().GetAgents(); //AgentList::const_iterator iter = agents.begin(); int size = agents.size(); //for(; iter!= agents.end(); ++iter) for (int i = 0; i < size; ++i) { const Agent* agent = agents[i]; //(*iter); // Ignore self if (&mOwner == agent) { continue; } // Check if agent is in range const SVector2 ownerToTarget = agent->GetPosition() - mOwner.GetPosition(); const float distanceSqr = LengthSquared(ownerToTarget); if (distanceSqr > viewDistanceSqr) { continue; } // Check if agent is in view cone const SVector2 dirToTarget = Normalize(ownerToTarget); const float dot = Dot(mOwner.GetHeading(), dirToTarget); if (dot < viewSpan) { continue; } // Check if we have line of site if (!mOwner.GetWorld().HasLOS(mOwner.GetPosition(), agent->GetPosition())) { continue; } // Check if we have a record for this agent bool hasRecord = false; MemoryRecords::iterator memoryIter = mMemoryRecords.begin(); while (memoryIter != mMemoryRecords.end()) { PerceptionData& record = (*memoryIter); if (record.pAgent == agent) { record.lastSeenLocation = agent->GetPosition(); record.lastRecordedTime = 0.0f; record.level = Confirm; hasRecord = true; break; } ++memoryIter; } // Add a new record if agent is new if (!hasRecord) { PerceptionData newRecord; newRecord.pAgent = agent; newRecord.lastSeenLocation = agent->GetPosition(); newRecord.lastRecordedTime = 0.0f; newRecord.level = Confirm; mMemoryRecords.push_back(newRecord); } } }
Vec4f PlaneEquation(void) const { return Vec4f(Normal(), -Dot(Normal(), _point)); }
void DMCWOS::advanceWalkerByWalker(BRANCHER& Branch) { //Pooma::Clock timer; RealType oneovertau = 1.0/Tau; RealType oneover2tau = 0.5*oneovertau; RealType g = sqrt(Tau); RealType vwos; //MCWalkerConfiguration::PropertyContainer_t Properties; int nh = H.size()+1; // extract the WOS potential //WOSPotential* wos = dynamic_cast<WOSPotential*>(H.getHamiltonian("wos")); MCWalkerConfiguration::iterator it = W.begin(); MCWalkerConfiguration::iterator it_end = W.end(); while(it != it_end) { (*it)->Properties(WEIGHT) = 1.0; (*it)->Properties(MULTIPLICITY) = 1.0; //copy the properties of the working walker W.Properties = (*it)->Properties; //save old local energy ValueType eold = W.Properties(LOCALENERGY); /* If doing WOS then we have to redo the old calculation for ROld to calculate G(Rold,Rnew). So we extract wos from the Hamiltonian and re-evaluate it. */ ValueType emixed = eold; if(wos_ref) { W.R = (*it)->R; DistanceTable::update(W); ValueType psi(Psi.evaluateLog(W));//not used anyway eold = H.evaluate(W); emixed += 0.5*W.Properties(WOSVAR)*Tau_var; } //ValueType emixed = eold + 0.5*W.Properties(WOSVAR)*Tau; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); W.R = g*deltaR + (*it)->R + (*it)->Drift; //update the distance table associated with W DistanceTable::update(W); //evaluate wave function ValueType logpsi(Psi.evaluateLog(W)); //update the properties W.Properties(LOCALENERGY) = H.evaluate(W); W.Properties(LOGPSI) =logpsi; W.Properties(SIGN) = Psi.getSign(); bool accepted=false; //deltaR = W.R - (*it)->R - (*it)->Drift; //RealType forwardGF = exp(-oneover2tau*Dot(deltaR,deltaR)); //RealType forwardGF = exp(-0.5*Dot(deltaR,deltaR)); RealType logGf = -0.5*Dot(deltaR,deltaR); //scale the drift term to prevent persistent cofigurations ValueType vsq = Dot(W.G,W.G); //converting gradients to drifts, D = tau*G (reuse G) // W.G *= Tau;//original implementation with bare drift ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); drift = scale*W.G; deltaR = (*it)->R - W.R - drift; //RealType backwardGF = exp(-oneover2tau*Dot(deltaR,deltaR)); RealType logGb = -oneover2tau*Dot(deltaR,deltaR); //set acceptance probability //RealType prob= std::min(backwardGF/forwardGF*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0); //RealType prob= std::min(exp(logGb-logGf)*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0); RealType prob= std::min(exp(logGb-logGf +2.0*(W.Properties(LOGPSI)-(*it)->Properties(LOGPSI))),1.0); if(Random() > prob) { (*it)->Properties(AGE)++; emixed += emixed; } else { accepted=true; W.Properties(AGE) = 0; (*it)->R = W.R; (*it)->Drift = drift; (*it)->Properties = W.Properties; H.copy((*it)->getEnergyBase()); emixed += W.Properties(LOCALENERGY) + 0.5*W.Properties(WOSVAR)*Tau_var; } //calculate the weight and multiplicity ValueType M = Branch.branchGF(Tau,emixed*0.5,1.0-prob); if((*it)->Properties(AGE) > 3.0) M = min(0.5,M); if((*it)->Properties(AGE) > 0.9) M = min(1.0,M); (*it)->Properties(WEIGHT) = M; (*it)->Properties(MULTIPLICITY) = M + Random(); //node-crossing: kill it for the time being if(Branch(W.Properties(SIGN),(*it)->Properties(SIGN))) { accepted=false; (*it)->Properties(WEIGHT) = 0.0; (*it)->Properties(MULTIPLICITY) = 0.0; } /* if(Branch(W.Properties(PSI),(*it)->Properties(PSI))) { accepted=false; (*it)->Properties(WEIGHT) = 0.0; (*it)->Properties(MULTIPLICITY) = 0.0; } else { RealType logGf = -0.5*Dot(deltaR,deltaR); ValueType vsq = Dot(W.G,W.G); ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); drift = scale*W.G; deltaR = (*it)->R - W.R - drift; RealType logGb = -oneover2tau*Dot(deltaR,deltaR); RealType prob = std::min(exp(logGb-logGf)*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0); if(Random() > prob){ (*it)->Properties(AGE)++; emixed += emixed; } else { accepted=true; W.Properties(AGE) = 0; (*it)->R = W.R; (*it)->Drift = drift; (*it)->Properties = W.Properties; // H.update(W.Energy[(*it)->ID]); //H.get((*it)->E); H.copy((*it)->getEnergyBase()); emixed += W.Properties(LOCALENERGY) + 0.5*W.Properties(WOSVAR)*Tau_var; } //calculate the weight and multiplicity ValueType M = Branch.branchGF(Tau,emixed*0.5,1.0-prob); if((*it)->Properties(AGE) > 3.0) M = min(0.5,M); if((*it)->Properties(AGE) > 0.9) M = min(1.0,M); (*it)->Properties(WEIGHT) = M; (*it)->Properties(MULTIPLICITY) = M + Random(); } */ if(accepted) ++nAccept; else ++nReject; ++it; } }
Float MicrofacetReflection::Pdf(const Vector3f &wo, const Vector3f &wi) const { if (!SameHemisphere(wo, wi)) return 0; Vector3f wh = Normalize(wo + wi); return distribution->Pdf(wo, wh) / (4 * Dot(wo, wh)); }
Float FresnelBlend::Pdf(const Vector3f &wo, const Vector3f &wi) const { if (!SameHemisphere(wo, wi)) return 0; Vector3f wh = Normalize(wo + wi); Float pdf_wh = distribution->Pdf(wo, wh); return .5f * (AbsCosTheta(wi) * InvPi + pdf_wh / (4 * Dot(wo, wh))); }
void Reflect(const Vector2D &v, const Vector2D &normal, Vector2D *result) { *result = (v - (normal * Dot(v, normal) * 2.0f)); }
Float Reflect(Float direction, const Vector2D &normal) { Vector2D v(cos(direction), sin(direction)); v = (v - (normal * Dot(v, normal) * Vector2D(2.0f, 2.0f))); return atan2(v.mY, v.mX); }
Vector2D Reflect(const Vector2D &v, const Vector2D &normal) { return (v - (normal * Dot(v, normal) * 2.0f)); }
void VoxelRenderer::Flush(RenderContext& renderContext, const SceneConstants& sceneConstants) { // Set up global shader constants m_constants.projectionViewMatrix = sceneConstants.viewMatrix * sceneConstants.projectionMatrix; m_constants.clipPlane = sceneConstants.clipPlane; // Calculate camera distances for all queued render ops float3 cameraPos = sceneConstants.cameraPos; for (size_t i = 0; i < m_renderOps.size(); ++i) { float3 diff = m_renderOps[i].position - cameraPos; m_renderOps[i].distance2 = Dot(diff, diff); } for (size_t i = 0; i < m_gapFillerRenderOps.size(); ++i) { float3 diff = m_gapFillerRenderOps[i].position - cameraPos; m_gapFillerRenderOps[i].distance2 = Dot(diff, diff); } for (size_t i = 0; i < m_transparentRenderOps.size(); ++i) { float3 diff = m_transparentRenderOps[i].position - cameraPos; m_transparentRenderOps[i].distance2 = Dot(diff, diff); } // Sort by camera distance (front to back for opaque render ops, // back to front for transparent) auto transparentSorter = [](const RenderOp& lhs, const RenderOp& rhs) { return lhs.distance2 > rhs.distance2; }; auto opaqueSorter = [](const RenderOp& lhs, const RenderOp& rhs) { return lhs.distance2 < rhs.distance2; }; std::sort(m_renderOps.begin(), m_renderOps.end(), opaqueSorter); std::sort(m_gapFillerRenderOps.begin(), m_gapFillerRenderOps.end(), opaqueSorter); std::sort(m_transparentRenderOps.begin(), m_transparentRenderOps.end(), transparentSorter); // Finally time to draw them renderContext.PushDepthStencilState(m_shared->depthStencilState); for (size_t i = 0; i < m_renderOps.size(); i++) { Draw(m_renderOps[i]); } m_renderOps.clear(); renderContext.PopDepthStencilState(); renderContext.PushDepthStencilState(m_shared->fillGapsDepthStencilState); for (size_t i = 0; i < m_gapFillerRenderOps.size(); ++i) { Draw(m_gapFillerRenderOps[i]); } m_gapFillerRenderOps.clear(); renderContext.PopDepthStencilState(); renderContext.PushDepthStencilState(m_shared->transparentDepthStencilState); renderContext.PushBlendState(m_shared->blendState); for (size_t i = 0; i < m_transparentRenderOps.size(); i++) { Draw(m_transparentRenderOps[i]); } m_transparentRenderOps.clear(); renderContext.PopBlendState(); renderContext.PopDepthStencilState(); }
bool Polyhedron::FaceContains(int faceIndex, const float3 &worldSpacePoint, float polygonThickness) const { // N.B. This implementation is a duplicate of Polygon::Contains, but adapted to avoid dynamic memory allocation // related to converting the face of a Polyhedron to a Polygon object. // Implementation based on the description from http://erich.realtimerendering.com/ptinpoly/ const Face &face = f[faceIndex]; const std::vector<int> &vertices = face.v; if (vertices.size() < 3) return false; Plane p = FacePlane(faceIndex); if (FacePlane(faceIndex).Distance(worldSpacePoint) > polygonThickness) return false; int numIntersections = 0; float3 basisU = v[vertices[1]] - v[vertices[0]]; basisU.Normalize(); float3 basisV = Cross(p.normal, basisU).Normalized(); mathassert(basisU.IsNormalized()); mathassert(basisV.IsNormalized()); mathassert(basisU.IsPerpendicular(basisV)); mathassert(basisU.IsPerpendicular(p.normal)); mathassert(basisV.IsPerpendicular(p.normal)); float2 localSpacePoint = float2(Dot(worldSpacePoint, basisU), Dot(worldSpacePoint, basisV)); const float epsilon = 1e-4f; float2 p0 = float2(Dot(v[vertices.back()], basisU), Dot(v[vertices.back()], basisV)) - localSpacePoint; if (Abs(p0.y) < epsilon) p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly. for(size_t i = 0; i < vertices.size(); ++i) { float2 p1 = float2(Dot(v[vertices[i]], basisU), Dot(v[vertices[i]], basisV)) - localSpacePoint; if (Abs(p1.y) < epsilon) p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly. if (p0.y * p1.y < 0.f) { if (p0.x > 1e-3f && p1.x > 1e-3f) ++numIntersections; else { // P = p0 + t*(p1-p0) == (x,0) // p0.x + t*(p1.x-p0.x) == x // p0.y + t*(p1.y-p0.y) == 0 // t == -p0.y / (p1.y - p0.y) // Test whether the lines (0,0) -> (+inf,0) and p0 -> p1 intersect at a positive X-coordinate. float2 d = p1 - p0; if (Abs(d.y) > 1e-5f) { float t = -p0.y / d.y; float x = p0.x + t * d.x; if (t >= 0.f && t <= 1.f && x > 1e-6f) ++numIntersections; } } } p0 = p1; } return numIntersections % 2 == 1; }
bool DMCParticleByParticle::run() { //add columns IndexType PopIndex = Estimators->addColumn("Population"); IndexType EtrialIndex = Estimators->addColumn("E_T"); //write the header Estimators->reportHeader(); MolecuFixedNodeBranch<RealType> brancher(Tau,W.getActiveWalkers()); //initialize parameters for fixed-node branching brancher.put(qmcNode,LogOut); if(BranchInfo != "default") brancher.read(BranchInfo); else { /*if VMC/DMC directly preceded DMC (Counter > 0) then use the average value of the energy estimator for the reference energy of the brancher*/ if(Counter) { RealType e_ref = W.getLocalEnergy(); LOGMSG("Overwriting the reference energy by the local energy " << e_ref) brancher.setEguess(e_ref); } } MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); while(it!=it_end) { (*it)->Properties(WEIGHT) = 1.0; (*it)->Properties(MULTIPLICITY) = 1.0; ++it; } //going to add routines to calculate how much we need bool require_register = W.createAuxDataSet(); int iwalker=0; it = W.begin(); it_end = W.end(); if(require_register) { while(it != it_end) { W.DataSet[iwalker]->rewind(); W.registerData(**it,*(W.DataSet[iwalker])); Psi.registerData(W,*(W.DataSet[iwalker])); ++it;++iwalker; } } Estimators->reset(); IndexType block = 0; Pooma::Clock timer; int Population = W.getActiveWalkers(); int tPopulation = W.getActiveWalkers(); RealType Eest = brancher.E_T; RealType E_T = Eest; RealType oneovertau = 1.0/Tau; RealType oneover2tau = 0.5*oneovertau; RealType g = sqrt(Tau); MCWalkerConfiguration::PropertyContainer_t Properties; ParticleSet::ParticlePos_t deltaR(W.getTotalNum()); ParticleSet::ParticleGradient_t G(W.getTotalNum()), dG(W.getTotalNum()); ParticleSet::ParticleLaplacian_t L(W.getTotalNum()), dL(W.getTotalNum()); IndexType accstep=0; IndexType nAcceptTot = 0; IndexType nRejectTot = 0; IndexType nat = W.getTotalNum(); int ncross = 0; do { IndexType step = 0; timer.start(); nAccept = 0; nReject=0; IndexType nAllRejected = 0; do { Population = W.getActiveWalkers(); it = W.begin(); it_end = W.end(); iwalker=0; while(it != it_end) { MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); (*it)->Properties(WEIGHT) = 1.0; (*it)->Properties(MULTIPLICITY) = 1.0; //save old local energy ValueType eold((*it)->Properties(LOCALENERGY)); ValueType emixed(eold); W.R = (*it)->R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); ValueType psi_old((*it)->Properties(SIGN)); ValueType psi(psi_old); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool notcrossed(true); int nAcceptTemp(0); int nRejectTemp(0); int iat=0; while(notcrossed && iat<nat){ PosType dr(g*deltaR[iat]+(*it)->Drift[iat]); PosType newpos(W.makeMove(iat,dr)); RealType ratio(Psi.ratio(W,iat,dG,dL)); if(ratio < 0.0) {//node is crossed, stop here notcrossed = false; } else { G = W.G+dG; RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); ValueType vsq = Dot(G,G); ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); dr = (*it)->R[iat]-newpos-scale*G[iat]; //dr = (*it)->R[iat]-newpos-Tau*G[iat]; RealType logGb = -oneover2tau*dot(dr,dr); //RealType ratio2 = pow(ratio,2) RealType prob = std::min(1.0,pow(ratio,2)*exp(logGb-logGf)); if(Random() < prob) { ++nAcceptTemp; W.acceptMove(iat); Psi.update2(W,iat); W.G = G; W.L += dL; // (*it)->Drift = Tau*G; (*it)->Drift = scale*G; } else { ++nRejectTemp; Psi.restore(iat); } } ++iat; } if(notcrossed) { if(nAcceptTemp) {//need to overwrite the walker properties w_buffer.rewind(); W.copyToBuffer(w_buffer); psi = Psi.evaluate(W,w_buffer); (*it)->R = W.R; (*it)->Properties(AGE) = 0; //This is not so useful: allow overflow/underflow (*it)->Properties(LOGPSI) = log(fabs(psi)); (*it)->Properties(SIGN) = psi; (*it)->Properties(LOCALENERGY) = H.evaluate(W); H.copy((*it)->getEnergyBase()); (*it)->Properties(LOCALPOTENTIAL) = H.getLocalPotential(); emixed += (*it)->Properties(LOCALENERGY); } else { //WARNMSG("All the particle moves are rejected.") (*it)->Properties(AGE)++; ++nAllRejected; emixed += eold; } ValueType M = brancher.branchGF(Tau,emixed*0.5,0.0); // if((*it)->Properties(AGE) > 3.0) M = min(0.5,M); //persistent configurations if((*it)->Properties(AGE) > 1.9) M = std::min(0.5,M); if((*it)->Properties(AGE) > 0.9) M = std::min(1.0,M); (*it)->Properties(WEIGHT) = M; (*it)->Properties(MULTIPLICITY) = M + Random(); nAccept += nAcceptTemp; nReject += nRejectTemp; } else {//set the weight and multiplicity to zero (*it)->Properties(WEIGHT) = 0.0; (*it)->Properties(MULTIPLICITY) = 0.0; nReject += W.getTotalNum();//not make sense } ++it; ++iwalker; } ++step;++accstep; Estimators->accumulate(W); Eest = brancher.update(Population,Eest); //E_T = brancher.update(Population,Eest); brancher.branch(accstep,W); } while(step<nSteps); //WARNMSG("The number of a complete rejectoin " << nAllRejected) timer.stop(); nAcceptTot += nAccept; nRejectTot += nReject; Estimators->flush(); Estimators->setColumn(PopIndex,static_cast<RealType>(Population)); Estimators->setColumn(EtrialIndex,Eest); //E_T); Estimators->setColumn(AcceptIndex, static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject)); Estimators->report(accstep); Eest = Estimators->average(0); LogOut->getStream() << "Block " << block << " " << timer.cpu_time() << " Fixed_configs " << static_cast<RealType>(nAllRejected)/static_cast<RealType>(step*W.getActiveWalkers()) << endl; if(pStride) { //create an output engine HDFWalkerOutput WO(RootName); WO.get(W); brancher.write(WO.getGroupID()); } nAccept = 0; nReject = 0; block++; } while(block<nBlocks); LogOut->getStream() << "Ratio = " << static_cast<double>(nAcceptTot)/static_cast<double>(nAcceptTot+nRejectTot) << endl; if(!pStride) { //create an output engine HDFWalkerOutput WO(RootName); WO.get(W); brancher.write(WO.getGroupID()); } Estimators->finalize(); return true; }
double TorranceSparrowSpecular::_NDF(const Vector &N, const Vector &H) { double ndoth=Dot(N,H); double ndoth2=ndoth*ndoth; return exp(((ndoth2)-1)/(mM*mM*ndoth2))*(1/(M_PI*mM*mM*ndoth2*ndoth2)); }
Spectrum IGIIntegrator::Li(const Scene *scene, const RayDifferential &ray, const Sample *sample, float *alpha) const { Spectrum L(0.); Intersection isect; if (scene->Intersect(ray, &isect)) { if (alpha) *alpha = 1.; Vector wo = -ray.d; // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray); const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; L += UniformSampleAllLights(scene, p, n, wo, bsdf, sample, lightSampleOffset, bsdfSampleOffset, bsdfComponentOffset); // Compute indirect illumination with virtual lights u_int lSet = min(u_int(sample->oneD[vlSetOffset][0] * nLightSets), nLightSets-1); for (u_int i = 0; i < virtualLights[lSet].size(); ++i) { const VirtualLight &vl = virtualLights[lSet][i]; // Add contribution from _VirtualLight_ _vl_ // Ignore light if it's too close to current point float d2 = DistanceSquared(p, vl.p); //if (d2 < .8 * minDist2) continue; float distScale = SmoothStep(.8 * minDist2, 1.2 * minDist2, d2); // Compute virtual light's tentative contribution _Llight_ Vector wi = Normalize(vl.p - p); Spectrum f = distScale * bsdf->f(wo, wi); if (f.Black()) continue; float G = AbsDot(wi, n) * AbsDot(wi, vl.n) / d2; Spectrum Llight = indirectScale * f * G * vl.Le / virtualLights[lSet].size(); Llight *= scene->Transmittance(Ray(p, vl.p - p)); // Possibly skip shadow ray with Russian roulette if (Llight.y() < rrThreshold) { float continueProbability = .1f; if (RandomFloat() > continueProbability) continue; Llight /= continueProbability; } static StatsCounter vlsr("IGI Integrator", "Shadow Rays to Virtual Lights"); //NOBOOK ++vlsr; //NOBOOK if (!scene->IntersectP(Ray(p, vl.p - p, RAY_EPSILON, 1.f - RAY_EPSILON))) L += Llight; } // Trace rays for specular reflection and refraction if (specularDepth++ < maxSpecularDepth) { Vector wi; // Trace rays for specular reflection and refraction Spectrum f = bsdf->Sample_f(wo, &wi, BxDFType(BSDF_REFLECTION | BSDF_SPECULAR)); if (!f.Black()) { // Compute ray differential _rd_ for specular reflection RayDifferential rd(p, wi); rd.hasDifferentials = true; rd.rx.o = p + isect.dg.dpdx; rd.ry.o = p + isect.dg.dpdy; // Compute differential reflected directions Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx; Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy; Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo; float dDNdx = Dot(dwodx, n) + Dot(wo, dndx); float dDNdy = Dot(dwody, n) + Dot(wo, dndy); rd.rx.d = wi - dwodx + 2 * Vector(Dot(wo, n) * dndx + dDNdx * n); rd.ry.d = wi - dwody + 2 * Vector(Dot(wo, n) * dndy + dDNdy * n); L += scene->Li(rd, sample) * f * AbsDot(wi, n); } f = bsdf->Sample_f(wo, &wi, BxDFType(BSDF_TRANSMISSION | BSDF_SPECULAR)); if (!f.Black()) { // Compute ray differential _rd_ for specular transmission RayDifferential rd(p, wi); rd.hasDifferentials = true; rd.rx.o = p + isect.dg.dpdx; rd.ry.o = p + isect.dg.dpdy; float eta = bsdf->eta; Vector w = -wo; if (Dot(wo, n) < 0) eta = 1.f / eta; Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx; Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy; Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo; float dDNdx = Dot(dwodx, n) + Dot(wo, dndx); float dDNdy = Dot(dwody, n) + Dot(wo, dndy); float mu = eta * Dot(w, n) - Dot(wi, n); float dmudx = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdx; float dmudy = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdy; rd.rx.d = wi + eta * dwodx - Vector(mu * dndx + dmudx * n); rd.ry.d = wi + eta * dwody - Vector(mu * dndy + dmudy * n); L += scene->Li(rd, sample) * f * AbsDot(wi, n); } } --specularDepth; } else { // Handle ray with no intersection if (alpha) *alpha = 0.; for (u_int i = 0; i < scene->lights.size(); ++i) L += scene->lights[i]->Le(ray); if (alpha && !L.Black()) *alpha = 1.; return L; } return L; }
RGB TorranceSparrowSpecular::_Fresnel(const Vector &wo, const Vector &H) { RGB one(1,1,1); RGB f0=mAlbedo*mScaleFactor; return f0+(one-f0)*pow(1-Dot(H,wo),5); }
RangeFit::RangeFit( ColourSet const* colours, int flags ) : ColourFit( colours, flags ) { // initialise the metric bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 ); if( perceptual ) m_metric = Vec3( 0.2126f, 0.7152f, 0.0722f ); else m_metric = Vec3( 1.0f ); // initialise the best error m_besterror = FLT_MAX; // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); float const* weights = m_colours->GetWeights(); // get the covariance matrix Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights ); // compute the principle component Vec3 principle = ComputePrincipleComponent( covariance ); // get the min and max range as the codebook endpoints Vec3 start( 0.0f ); Vec3 end( 0.0f ); if( count > 0 ) { float min, max; // compute the range start = end = values[0]; min = max = Dot( values[0], principle ); for( int i = 1; i < count; ++i ) { float val = Dot( values[i], principle ); if( val < min ) { start = values[i]; min = val; } else if( val > max ) { end = values[i]; max = val; } } } // clamp the output to [0, 1] Vec3 const one( 1.0f ); Vec3 const zero( 0.0f ); start = Min( one, Max( zero, start ) ); end = Min( one, Max( zero, end ) ); // clamp to the grid and save Vec3 const grid( 31.0f, 63.0f, 31.0f ); Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); Vec3 const half( 0.5f ); m_start = Truncate( grid*start + half )*gridrcp; m_end = Truncate( grid*end + half )*gridrcp; }
RGB TorranceSparrowSpecular::f(const Intersection &sr, const Vector &wi, const Vector &wo) { Vector half=Normalize(wi + wo); return mAlbedo/(4*M_PI*Dot(sr.normal,wi))*_NDF(sr.normal,half)*_Fresnel(wo,half)*_G(sr.normal,half,wi,wo); }
/** advance all the walkers with killnode==no * @param nat number of particles to move * * When killnode==no, any move resulting in node-crossing is treated * as a normal rejection. */ void DMCNonLocalUpdate::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { //RealType plusFactor(Tau*Gamma); //RealType minusFactor(-Tau*(1.0-Alpha*(1.0+Gamma))); for(; it!=it_end; ++it) { Walker_t& thisWalker(**it); //save old local energy RealType eold = thisWalker.Properties(LOCALENERGY); RealType signold = thisWalker.Properties(SIGN); RealType enew = eold; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); W.R = m_sqrttau*deltaR + thisWalker.R + thisWalker.Drift; //update the distance table associated with W //DistanceTable::update(W); W.update(); //evaluate wave function RealType logpsi(Psi.evaluateLog(W)); nonLocalOps.reset(); bool accepted=false; if(branchEngine->phaseChanged(Psi.getPhase(),thisWalker.Properties(SIGN))) { thisWalker.Age++; ++nReject; } else { //RealType enew(H.evaluate(W,nonLocalOps.Txy)); enew=H.evaluate(W,nonLocalOps.Txy); RealType logGf = -0.5*Dot(deltaR,deltaR); setScaledDrift(Tau,W.G,drift); deltaR = (*it)->R - W.R - drift; RealType logGb = -m_oneover2tau*Dot(deltaR,deltaR); RealType prob= std::min(std::exp(logGb-logGf +2.0*(logpsi-thisWalker.Properties(LOGPSI))),1.0); if(RandomGen() > prob){ thisWalker.Age++; ++nReject; enew=eold; } else { accepted=true; thisWalker.R = W.R; thisWalker.Drift = drift; thisWalker.resetProperty(logpsi,Psi.getPhase(),enew); H.saveProperty(thisWalker.getPropertyBase()); //emixed = (emixed+enew)*0.5; //eold=enew; ++nAccept; } } int ibar=nonLocalOps.selectMove(RandomGen()); //make a non-local move if(ibar) { int iat=nonLocalOps.id(ibar); W.R[iat] += nonLocalOps.delta(ibar); W.update(); logpsi=Psi.evaluateLog(W); setScaledDrift(Tau,W.G,thisWalker.Drift); thisWalker.resetProperty(logpsi,Psi.getPhase(),eold); thisWalker.R[iat] = W.R[iat]; ++NonLocalMoveAccepted; } thisWalker.Weight *= branchEngine->branchWeight(eold,enew); //branchEngine->accumulate(eold,1); } }
inline void HermitianTridiagU ( Matrix<Complex<R> >& A, Matrix<Complex<R> >& t ) { #ifndef RELEASE PushCallStack("HermitianTridiagU"); #endif const int tHeight = std::max(A.Height()-1,0); #ifndef RELEASE if( A.Height() != A.Width() ) throw std::logic_error("A must be square"); if( t.Viewing() && (t.Height() != tHeight || t.Width() != 1) ) throw std::logic_error("t is of the wrong size"); #endif typedef Complex<R> C; if( !t.Viewing() ) t.ResizeTo( tHeight, 1 ); // Matrix views Matrix<C> ATL, ATR, A00, a01, A02, a01T, ABL, ABR, a10, alpha11, a12, alpha01B, A20, a21, A22; // Temporary matrices Matrix<C> w01; PushBlocksizeStack( 1 ); PartitionUpDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ABR.Height()+1 < A.Height() ) { RepartitionUpDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); PartitionUp ( a01, a01T, alpha01B, 1 ); w01.ResizeTo( a01.Height(), 1 ); //--------------------------------------------------------------------// const C tau = Reflector( alpha01B, a01T ); const R epsilon1 = alpha01B.GetRealPart(0,0); t.Set(t.Height()-1-A22.Height(),0,tau); alpha01B.Set(0,0,C(1)); Hemv( UPPER, tau, A00, a01, C(0), w01 ); const C alpha = -tau*Dot( w01, a01 )/C(2); Axpy( alpha, a01, w01 ); Her2( UPPER, C(-1), a01, w01, A00 ); alpha01B.Set(0,0,epsilon1); //--------------------------------------------------------------------// SlidePartitionUpDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
Vector2 TransformNormal(Mat3Param matrix, Vec2Param normal) { float x = Dot(*(Vector2*)&matrix[0], normal); float y = Dot(*(Vector2*)&matrix[1], normal); return Vector2(x, y); }
bool Sphere::Intersect(const Ray &r, Float *tHit, SurfaceInteraction *isect, bool testAlphaTexture) const { Float phi; Point3f pHit; // Transform _Ray_ to object space Vector3f oErr, dErr; Ray ray = (*WorldToObject)(r, &oErr, &dErr); // Compute quadratic sphere coefficients // Initialize _EFloat_ ray coordinate values EFloat ox(ray.o.x, oErr.x), oy(ray.o.y, oErr.y), oz(ray.o.z, oErr.z); EFloat dx(ray.d.x, dErr.x), dy(ray.d.y, dErr.y), dz(ray.d.z, dErr.z); EFloat a = dx * dx + dy * dy + dz * dz; EFloat b = 2 * (dx * ox + dy * oy + dz * oz); EFloat c = ox * ox + oy * oy + oz * oz - EFloat(radius) * EFloat(radius); // Solve quadratic equation for _t_ values EFloat t0, t1; if (!Quadratic(a, b, c, &t0, &t1)) return false; // Check quadric shape _t0_ and _t1_ for nearest intersection if (t0.UpperBound() > ray.tMax || t1.LowerBound() <= 0) return false; EFloat tShapeHit = t0; if (tShapeHit.LowerBound() <= 0) { tShapeHit = t1; if (tShapeHit.UpperBound() > ray.tMax) return false; } // Compute sphere hit position and $\phi$ pHit = ray((Float)tShapeHit); // Refine sphere intersection point pHit *= radius / Distance(pHit, Point3f(0, 0, 0)); if (pHit.x == 0 && pHit.y == 0) pHit.x = 1e-5f * radius; phi = std::atan2(pHit.y, pHit.x); if (phi < 0) phi += 2 * Pi; // Test sphere intersection against clipping parameters if ((zMin > -radius && pHit.z < zMin) || (zMax < radius && pHit.z > zMax) || phi > phiMax) { if (tShapeHit == t1) return false; if (t1.UpperBound() > ray.tMax) return false; tShapeHit = t1; // Compute sphere hit position and $\phi$ pHit = ray((Float)tShapeHit); // Refine sphere intersection point pHit *= radius / Distance(pHit, Point3f(0, 0, 0)); if (pHit.x == 0 && pHit.y == 0) pHit.x = 1e-5f * radius; phi = std::atan2(pHit.y, pHit.x); if (phi < 0) phi += 2 * Pi; if ((zMin > -radius && pHit.z < zMin) || (zMax < radius && pHit.z > zMax) || phi > phiMax) return false; } // Find parametric representation of sphere hit Float u = phi / phiMax; Float theta = std::acos(Clamp(pHit.z / radius, -1, 1)); Float v = (theta - thetaMin) / (thetaMax - thetaMin); // Compute sphere $\dpdu$ and $\dpdv$ Float zRadius = std::sqrt(pHit.x * pHit.x + pHit.y * pHit.y); Float invZRadius = 1 / zRadius; Float cosPhi = pHit.x * invZRadius; Float sinPhi = pHit.y * invZRadius; Vector3f dpdu(-phiMax * pHit.y, phiMax * pHit.x, 0); Vector3f dpdv = (thetaMax - thetaMin) * Vector3f(pHit.z * cosPhi, pHit.z * sinPhi, -radius * std::sin(theta)); // Compute sphere $\dndu$ and $\dndv$ Vector3f d2Pduu = -phiMax * phiMax * Vector3f(pHit.x, pHit.y, 0); Vector3f d2Pduv = (thetaMax - thetaMin) * pHit.z * phiMax * Vector3f(-sinPhi, cosPhi, 0.); Vector3f d2Pdvv = -(thetaMax - thetaMin) * (thetaMax - thetaMin) * Vector3f(pHit.x, pHit.y, pHit.z); // Compute coefficients for fundamental forms Float E = Dot(dpdu, dpdu); Float F = Dot(dpdu, dpdv); Float G = Dot(dpdv, dpdv); Vector3f N = Normalize(Cross(dpdu, dpdv)); Float e = Dot(N, d2Pduu); Float f = Dot(N, d2Pduv); Float g = Dot(N, d2Pdvv); // Compute $\dndu$ and $\dndv$ from fundamental form coefficients Float invEGF2 = 1 / (E * G - F * F); Normal3f dndu = Normal3f((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv); Normal3f dndv = Normal3f((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv); // Compute error bounds for sphere intersection Vector3f pError = gamma(5) * Abs((Vector3f)pHit); // Initialize _SurfaceInteraction_ from parametric information *isect = (*ObjectToWorld)(SurfaceInteraction(pHit, pError, Point2f(u, v), -ray.d, dpdu, dpdv, dndu, dndv, ray.time, this)); // Update _tHit_ for quadric intersection *tHit = (Float)tShapeHit; return true; }
Vector Vector::Reflect(Vector normal) { return *this - (2 * Dot(normal) *normal); }
void GL3CalculateProjectionShadowMapMatrix(Vector3D viewp, Vector3D light_direction, Vector3D x_direction, Vector3D y_direction, float zmin, float zmax) { #if 0 char *s1 = light_direction.GetString(); char *s2 = x_direction.GetString(); char *s3 = y_direction.GetString(); sreMessage(SRE_MESSAGE_LOG, "GL3CalculateProjectionShadowMapMatrix: light_dir = %s, " "x_dir = %s, y_dir = %s, dot products: %f, %f, %f", s1, s2, s3, Dot(light_direction, x_direction), Dot(light_direction, y_direction), Dot(x_direction, y_direction)); delete s1; delete s2; delete s3; #endif Vector3D fvec = light_direction; Vector3D s = x_direction; Vector3D u = y_direction; Matrix4D M; // Note that the y direction has to be negated in order to preserve the handedness of // triangles when rendering the shadow map. M.Set( s.x, s.y, s.z, 0, - u.x, - u.y, - u.z, 0, - fvec.x, - fvec.y, - fvec.z, 0, 0.0f, 0.0f, 0.0f, 1.0f); Matrix4D T; T.AssignTranslation(- viewp); // Calculate the projection matrix with a field of view of 90 degrees. float aspect = 1.0; float e = 1 / tanf((90.0 * M_PI / 180) / 2); float n = zmin; float f = zmax; float l = - n / e; float r = n / e; float b = - (1.0f / aspect) * n / e; float t = (1.0f / aspect) * n / e; Matrix4D projection_matrix; projection_matrix.Set( 2 * n / (r - l), 0.0f, (r + l) / (r - l), 0.0f, 0.0f, 2 * n / (t - b), (t + b) / (t - b), 0.0f, 0.0f, 0.0f, - (f + n) / (f - n), - 2 * n * f / (f - n), 0.0f, 0.0f, - 1.0f, 0.0f); projection_shadow_map_matrix = projection_matrix * (M * T); MatrixTransform shadow_map_viewport_matrix; shadow_map_viewport_matrix.Set( 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f); projection_shadow_map_lighting_pass_matrix = shadow_map_viewport_matrix * projection_shadow_map_matrix; // projection_shadow_map_lighting_pass_matrix = projection_shadow_map_matrix; #if 0 Point3D P1 = viewp + light_direction * n; Point3D P2 = viewp + light_direction * f; Point3D P3 = viewp + light_direction * f + x_direction * f + y_direction * f; Vector4D P1_proj = projection_shadow_map_matrix * P1; Vector4D P2_proj = projection_shadow_map_matrix * P2; Vector4D P3_proj = projection_shadow_map_matrix * P3; Vector3D P1_norm = P1_proj.GetVector3D() / P1_proj.w; Vector3D P2_norm = P2_proj.GetVector3D() / P2_proj.w; Vector3D P3_norm = P3_proj.GetVector3D() / P3_proj.w; char *P1_norm_str = P1_norm.GetString(); char *P2_norm_str = P2_norm.GetString(); char *P3_norm_str = P3_norm.GetString(); sreMessage(SRE_MESSAGE_LOG, "CalculateProjectionShadowMapMatrix: Point transformations " "%s, %s and %s.", P1_norm_str, P2_norm_str, P3_norm_str); delete P1_norm_str; delete P2_norm_str; delete P3_norm_str; #endif }
bool Plane::Contains(const Circle &circle, float epsilon) const { return Contains(circle.pos, epsilon) && (EqualAbs(Abs(Dot(normal, circle.normal)), 1.f) || circle.r <= epsilon); }
/* Determine the polygon normal and project vertices onto the plane * of the polygon. */ void tessProjectPolygon( TESStesselator *tess ) { TESSvertex *v, *vHead = &tess->mesh->vHead; TESSreal norm[3]; TESSreal *sUnit, *tUnit; int i, first, computedNormal = FALSE; norm[0] = tess->normal[0]; norm[1] = tess->normal[1]; norm[2] = tess->normal[2]; if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { ComputeNormal( tess, norm ); computedNormal = TRUE; } sUnit = tess->sUnit; tUnit = tess->tUnit; i = LongAxis( norm ); #if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT) /* Choose the initial sUnit vector to be approximately perpendicular * to the normal. */ Normalize( norm ); sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; /* Now make it exactly perpendicular */ w = Dot( sUnit, norm ); sUnit[0] -= w * norm[0]; sUnit[1] -= w * norm[1]; sUnit[2] -= w * norm[2]; Normalize( sUnit ); /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1]; tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2]; tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0]; Normalize( tUnit ); #else /* Project perpendicular to a coordinate axis -- better numerically */ sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; tUnit[i] = 0; tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y; tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X; #endif /* Project the vertices onto the sweep plane */ for( v = vHead->next; v != vHead; v = v->next ) { v->s = Dot( v->coords, sUnit ); v->t = Dot( v->coords, tUnit ); } if( computedNormal ) { CheckOrientation( tess ); } /* Compute ST bounds. */ first = 1; for( v = vHead->next; v != vHead; v = v->next ) { if (first) { tess->bmin[0] = tess->bmax[0] = v->s; tess->bmin[1] = tess->bmax[1] = v->t; first = 0; } else { if (v->s < tess->bmin[0]) tess->bmin[0] = v->s; if (v->s > tess->bmax[0]) tess->bmax[0] = v->s; if (v->t < tess->bmin[1]) tess->bmin[1] = v->t; if (v->t > tess->bmax[1]) tess->bmax[1] = v->t; } } }
const float Vector4f::Dot(const Vector4 &a) const { return Dot(*this, a); }
Quaternion Quaternion::Normalize(const Quaternion& q) { return q / sqrtf(Dot(q, q)); }