Value If::BuildPHI(const codegen::Value &v1, const codegen::Value &v2) { if (cg_->GetInsertBlock() != merge_bb_) { // The if hasn't been ended, end it now EndIf(); } PELOTON_ASSERT(v1.GetType() == v2.GetType()); std::vector<std::pair<Value, llvm::BasicBlock *>> vals = { {v1, last_bb_in_then_}, {v2, last_bb_in_else_ != nullptr ? last_bb_in_else_ : branch_->getParent()}}; return Value::BuildPHI(cg_, vals); }
const ADFloat *Emission(const ADFloat *buffer, const ADBSphere &sceneSphere, const ADVector3 &dirToLight, const ADVector3 &normalOnLight, const ADFloat time, ADVector3 &emission, ADFloat &directPdf, ADFloat &emissionPdf) { ADFloat type; buffer = Deserialize(buffer, type); std::vector<CondExprCPtr> ret = CreateCondExprVec(5); BeginIf(Eq(type, (Float)LightType::AreaLight), ret); { ADVector3 emission; ADFloat directPdf; ADFloat emissionPdf; EmissionAreaLight( buffer, sceneSphere, dirToLight, normalOnLight, time, emission, directPdf, emissionPdf); SetCondOutput({emission[0], emission[1], emission[2], directPdf, emissionPdf}); } BeginElseIf(Eq(type, (Float)LightType::EnvLight)); { ADVector3 emission; ADFloat directPdf; ADFloat emissionPdf; EmissionEnvLight( buffer, sceneSphere, dirToLight, normalOnLight, time, emission, directPdf, emissionPdf); SetCondOutput({emission[0], emission[1], emission[2], directPdf, emissionPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); emission[0] = ret[0]; emission[1] = ret[1]; emission[2] = ret[2]; directPdf = ret[3]; emissionPdf = ret[4]; buffer += (GetMaxLightSerializedSize() - 1); return buffer; }
void ParseCondBlock(sInt *elsemod,sBool useelse) { sInt mod; sBool kill,always; kill = always = sFALSE; if(!useelse) { mod = Modify++; if(elsemod) *elsemod = Modify++; } else mod = *elsemod; if(elsemod && Mode==2) { if(!useelse) { kill = !ModArray[*elsemod - 1]; always = !ModArray[*elsemod]; } else { kill = !ModArray[*elsemod]; always = !ModArray[*elsemod - 1]; } } Pre(); if(kill || always) { OutBOpen(); OutBClose(); NewLine(); if(kill) OutF("if(0)"); else OutF("if(1)"); } if(Token==TOK_BOPEN) { MatchBOpen(); sInt ind = Indent; BeginIf(mod); sInt ind2 = Indent; while(Token!=TOK_BCLOSE) { ParseStatement(); } sVERIFY(Indent == ind2); EndIf(mod); sVERIFY(Indent == ind); MatchBClose(); } else { OutBOpen(); BeginIf(mod); ParseStatement(); EndIf(mod); OutBClose(); } }
void SamplePhong(const bool adjoint, const ADFloat *buffer, const ADVector3 &wi, const ADVector3 &normal, const ADVector2 st, const ADVector2 rndParam, const ADFloat uDiscrete, const bool fixDiscrete, ADVector3 &wo, ADVector3 &contrib, ADFloat &cosWo, ADFloat &pdf, ADFloat &revPdf) { ADVector3 Kd; ADVector3 Ks; ADFloat exponent; ADFloat KsWeight; buffer = Deserialize(buffer, Kd); buffer = Deserialize(buffer, Ks); buffer = Deserialize(buffer, exponent); buffer = Deserialize(buffer, KsWeight); ADFloat cosWi = Dot(normal, wi); std::vector<CondExprCPtr> ret = CreateCondExprVec(4); BeginIf(Gt(cosWi, Float(0.0)), ret); { SetCondOutput({normal[0], normal[1], normal[2], cosWi}); } BeginElse(); { SetCondOutput({-normal[0], -normal[1], -normal[2], -cosWi}); } EndIf(); ADVector3 normal_(ret[0], ret[1], ret[2]); cosWi = ret[3]; ADVector3 R = Reflect(wi, normal_); ret = CreateCondExprVec(4); BeginIf(Gt(uDiscrete, KsWeight), ret); { ADVector3 localDir = SampleCosHemisphere(rndParam); ADVector3 b0; ADVector3 b1; CoordinateSystem(normal_, b0, b1); ADVector3 wo = localDir[0] * b0 + localDir[1] * b1 + localDir[2] * normal_; ADFloat factor = (Float(1.0) - KsWeight); SetCondOutput({wo[0], wo[1], wo[2], factor}); } BeginElse(); { ADFloat power = Float(1.0) / (exponent + Float(1.0)); ADFloat cosAlpha = pow(rndParam[1], power); // Ugly hack to avoid sqrt(0) which has undefined derivatives... ADFloat sinAlpha = sqrt(fmax(Float(1.0) - square(cosAlpha), Float(1e-6))); ADFloat phi = c_TWOPI * rndParam[0]; ADVector3 localDir = ADVector3(sinAlpha * cos(phi), sinAlpha * sin(phi), cosAlpha); ADVector3 b0; ADVector3 b1; CoordinateSystem(R, b0, b1); ADVector3 wo = localDir[0] * b0 + localDir[1] * b1 + localDir[2] * R; ADFloat factor = KsWeight; SetCondOutput({wo[0], wo[1], wo[2], factor}); } EndIf(); wo = ADVector3(ret[0], ret[1], ret[2]); ADFloat factor = ret[3]; cosWo = Dot(normal_, wo); BeginIf(Gt(KsWeight, Float(0.0)), ret); { ADFloat alpha = fmax(Dot(Reflect(wi, normal_), wo), Float(0.0)); ADFloat weight = pow(alpha, exponent) * c_INVTWOPI; ADFloat expoConst1 = (exponent + Float(1.0)); ADFloat expoConst2 = (exponent + Float(2.0)); std::vector<CondExprCPtr> ret = CreateCondExprVec(4); BeginIf(Gt(weight, Float(1e-10)), ret); { ADVector3 specContrib = Ks * (expoConst2 * weight); ADFloat specPdf = KsWeight * expoConst1 * weight; SetCondOutput({specContrib[0], specContrib[1], specContrib[2], specPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); ADVector3 specContrib = ADVector3(ret[0], ret[1], ret[2]); ADFloat specPdf = ret[3]; SetCondOutput({specContrib[0], specContrib[1], specContrib[2], specPdf}); } BeginElse(); { SetCondOutput( {Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); contrib[0] = ret[0]; contrib[1] = ret[1]; contrib[2] = ret[2]; pdf = ret[3]; revPdf = ret[3]; ret = CreateCondExprVec(5); BeginIf(Lt(KsWeight, Float(1.0)), ret); { ADVector3 diffContrib = Kd * Const<ADFloat>(c_INVPI); ADFloat tmp = (Float(1.0) - KsWeight) * c_INVPI; ADFloat diffPdf = tmp * cosWo; ADFloat revDiffPdf = tmp * cosWi; SetCondOutput({diffContrib[0], diffContrib[1], diffContrib[2], diffPdf, revDiffPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); contrib[0] += ret[0]; contrib[1] += ret[1]; contrib[2] += ret[2]; pdf += ret[3]; revPdf += ret[4]; contrib *= cosWo; contrib *= inverse(pdf); if (fixDiscrete) { contrib *= factor; } }
void EvaluatePhong(const bool adjoint, const ADFloat *buffer, const ADVector3 &wi, const ADVector3 &normal, const ADVector3 &wo, const ADVector2 st, ADVector3 &contrib, ADFloat &cosWo, ADFloat &pdf, ADFloat &revPdf) { ADVector3 Kd; ADVector3 Ks; ADFloat exponent; ADFloat KsWeight; buffer = Deserialize(buffer, Kd); buffer = Deserialize(buffer, Ks); buffer = Deserialize(buffer, exponent); buffer = Deserialize(buffer, KsWeight); ADFloat cosWi = Dot(normal, wi); std::vector<CondExprCPtr> ret = CreateCondExprVec(4); BeginIf(Gt(cosWi, Float(0.0)), ret); { SetCondOutput({normal[0], normal[1], normal[2], cosWi}); } BeginElse(); { SetCondOutput({-normal[0], -normal[1], -normal[2], -cosWi}); } EndIf(); ADVector3 normal_(ret[0], ret[1], ret[2]); cosWi = ret[3]; cosWo = Dot(normal_, wo); ret = CreateCondExprVec(4); BeginIf(Gt(KsWeight, Float(0.0)), ret); { ADFloat alpha = Dot(Reflect(wi, normal_), wo); ADFloat weight = pow(alpha, exponent) * c_INVTWOPI; std::vector<CondExprCPtr> ret = CreateCondExprVec(4); BeginIf(Gt(weight, Float(1e-10)), ret); { ADFloat expoConst1 = (exponent + Float(1.0)); ADFloat expoConst2 = (exponent + Float(2.0)); ADVector3 specContrib = Ks * (expoConst2 * weight); ADFloat specPdf = KsWeight * expoConst1 * weight; SetCondOutput({specContrib[0], specContrib[1], specContrib[2], specPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); ADVector3 specContrib = ADVector3(ret[0], ret[1], ret[2]); ADFloat specPdf = ret[3]; SetCondOutput({specContrib[0], specContrib[1], specContrib[2], specPdf}); } BeginElse(); { SetCondOutput( {Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); contrib[0] = ret[0]; contrib[1] = ret[1]; contrib[2] = ret[2]; pdf = ret[3]; revPdf = ret[3]; ret = CreateCondExprVec(5); BeginIf(Lt(KsWeight, Float(1.0)), ret); { ADVector3 diffContrib = Kd * Const<ADFloat>(c_INVPI); ADFloat tmp = (Float(1.0) - KsWeight) * c_INVPI; ADFloat diffPdf = tmp * cosWo; ADFloat revDiffPdf = tmp * cosWi; SetCondOutput({diffContrib[0], diffContrib[1], diffContrib[2], diffPdf, revDiffPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); contrib[0] += ret[0]; contrib[1] += ret[1]; contrib[2] += ret[2]; pdf += ret[3]; revPdf += ret[4]; contrib *= cosWo; }
const ADFloat *Emit(const ADFloat *buffer, const ADBSphere &sceneSphere, const ADVector2 rndParamPos, const ADVector2 rndParamDir, const ADFloat time, const bool isStatic, ADRay &ray, ADVector3 &emission, ADFloat &cosAtLight, ADFloat &emissionPdf, ADFloat &directPdf) { ADFloat type; buffer = Deserialize(buffer, type); std::vector<CondExprCPtr> ret = CreateCondExprVec(12); BeginIf(Eq(type, (Float)LightType::PointLight), ret); { ADRay ray; ADVector3 emission; ADFloat cosAtLight; ADFloat emissionPdf; ADFloat directPdf; EmitPointLight(buffer, sceneSphere, rndParamPos, rndParamDir, time, isStatic, ray, emission, cosAtLight, emissionPdf, directPdf); SetCondOutput({ray.org[0], ray.org[1], ray.org[2], ray.dir[0], ray.dir[1], ray.dir[2], emission[0], emission[1], emission[2], cosAtLight, emissionPdf, directPdf}); } BeginElseIf(Eq(type, (Float)LightType::AreaLight)); { ADRay ray; ADVector3 emission; ADFloat cosAtLight; ADFloat emissionPdf; ADFloat directPdf; EmitAreaLight(buffer, sceneSphere, rndParamPos, rndParamDir, time, isStatic, ray, emission, cosAtLight, emissionPdf, directPdf); SetCondOutput({ray.org[0], ray.org[1], ray.org[2], ray.dir[0], ray.dir[1], ray.dir[2], emission[0], emission[1], emission[2], cosAtLight, emissionPdf, directPdf}); } BeginElseIf(Eq(type, (Float)LightType::EnvLight)); { ADRay ray; ADVector3 emission; ADFloat cosAtLight; ADFloat emissionPdf; ADFloat directPdf; EmitEnvLight(buffer, sceneSphere, rndParamPos, rndParamDir, time, isStatic, ray, emission, cosAtLight, emissionPdf, directPdf); SetCondOutput({ray.org[0], ray.org[1], ray.org[2], ray.dir[0], ray.dir[1], ray.dir[2], emission[0], emission[1], emission[2], cosAtLight, emissionPdf, directPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); ray.org[0] = ret[0]; ray.org[1] = ret[1]; ray.org[2] = ret[2]; ray.dir[0] = ret[3]; ray.dir[1] = ret[4]; ray.dir[2] = ret[5]; emission[0] = ret[6]; emission[1] = ret[7]; emission[2] = ret[8]; cosAtLight = ret[9]; emissionPdf = ret[10]; directPdf = ret[11]; buffer += (GetMaxLightSerializedSize() - 1); return buffer; }
const ADFloat *SampleDirect(const ADFloat *buffer, const ADBSphere &sceneSphere, const ADVector3 &pos, const ADVector3 &normal, const ADVector2 rndParam, const ADFloat time, const bool isStatic, ADVector3 &dirToLight, ADVector3 &lightContrib, ADFloat &cosAtLight, ADFloat &directPdf, ADFloat &emissionPdf) { ADFloat type; buffer = Deserialize(buffer, type); std::vector<CondExprCPtr> ret = CreateCondExprVec(9); BeginIf(Eq(type, (Float)LightType::PointLight), ret); { ADVector3 dirToLight; ADVector3 lightContrib; ADFloat cosAtLight; ADFloat directPdf; ADFloat emissionPdf; SampleDirectPointLight(buffer, sceneSphere, pos, normal, rndParam, time, isStatic, dirToLight, lightContrib, cosAtLight, directPdf, emissionPdf); SetCondOutput({dirToLight[0], dirToLight[1], dirToLight[2], lightContrib[0], lightContrib[1], lightContrib[2], cosAtLight, directPdf, emissionPdf}); } BeginElseIf(Eq(type, (Float)LightType::AreaLight)); { ADVector3 dirToLight; ADVector3 lightContrib; ADFloat cosAtLight; ADFloat directPdf; ADFloat emissionPdf; SampleDirectAreaLight(buffer, sceneSphere, pos, normal, rndParam, time, isStatic, dirToLight, lightContrib, cosAtLight, directPdf, emissionPdf); SetCondOutput({dirToLight[0], dirToLight[1], dirToLight[2], lightContrib[0], lightContrib[1], lightContrib[2], cosAtLight, directPdf, emissionPdf}); } BeginElseIf(Eq(type, (Float)LightType::EnvLight)); { ADVector3 dirToLight; ADVector3 lightContrib; ADFloat cosAtLight; ADFloat directPdf; ADFloat emissionPdf; SampleDirectEnvLight(buffer, sceneSphere, pos, normal, rndParam, time, isStatic, dirToLight, lightContrib, cosAtLight, directPdf, emissionPdf); SetCondOutput({dirToLight[0], dirToLight[1], dirToLight[2], lightContrib[0], lightContrib[1], lightContrib[2], cosAtLight, directPdf, emissionPdf}); } BeginElse(); { SetCondOutput({Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0), Const<ADFloat>(0.0)}); } EndIf(); dirToLight[0] = ret[0]; dirToLight[1] = ret[1]; dirToLight[2] = ret[2]; lightContrib[0] = ret[3]; lightContrib[1] = ret[4]; lightContrib[2] = ret[5]; cosAtLight = ret[6]; directPdf = ret[7]; emissionPdf = ret[8]; buffer += (GetMaxLightSerializedSize() - 1); return buffer; }