protected override RgbSpectrumInfo Evaluate(ref HitPointInfo HitPoint, ref Vector localLightDir, ref Vector localEyeDir, out BsdfEvent _event, out float directPdfW, out float reversePdfW) { _event = this.Type.TypeToEvent(); directPdfW = 0f; reversePdfW = 0f; return RgbSpectrumInfo.Black; }
protected override RgbSpectrumInfo Evaluate(ref HitPointInfo HitPoint, ref Vector localLightDir, ref Vector localEyeDir, out BsdfEvent _event, out float directPdfW, out float reversePdfW) { _event = BsdfEvent.Diffuse | BsdfEvent.Reflect; directPdfW = Math.Abs((HitPoint.FromLight ? localEyeDir.z : localLightDir.z) * MathLab.INVPI); reversePdfW = Math.Abs((HitPoint.FromLight ? localLightDir.z : localEyeDir.z) * MathLab.INVPI); var kd = TexData.Diffuse; return (kd * MathLab.INVPI); }
protected override RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event) { _event = this.Type.TypeToEvent(); localSampledDir = new Vector(-localFixedDir.x, -localFixedDir.y, localFixedDir.z); pdfW = 1f; absCosDir = Math.Abs(localSampledDir.z); var kr = (RgbSpectrum)TexData.Specular; // The absCosSampledDir is used to compensate the other one used inside the integrator return kr / absCosDir; }
protected override RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event) { absCosDir = 0f; _event = BsdfEvent.Diffuse | BsdfEvent.Reflect; pdfW = 0f; localSampledDir = new Vector(); if (Math.Abs(localFixedDir.z) < MathLab.COS_EPSILON_STATIC) return RgbSpectrum.ZeroSpectrum(); localSampledDir = Sgn(localFixedDir.z) * MC.CosineSampleHemisphere(u0, u1, out pdfW); absCosDir = Math.Abs(localSampledDir.z); if (absCosDir < MathLab.COS_EPSILON_STATIC) return RgbSpectrum.ZeroSpectrum(); var kd = (RgbSpectrum)(TexData.Diffuse); kd.Mul(MathLab.INVPI); return (kd); }
protected override RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event) { _event = this.Type.TypeToEvent(); localSampledDir = new Vector(-localFixedDir.x, -localFixedDir.y, localFixedDir.z); pdfW = 1f; absCosDir = Math.Abs(localSampledDir.z); var kr = (RgbSpectrum)TexData.Specular; float e = 1f / (Math.Max(TexData.Exponent, 0f) + 1f); localSampledDir = GlossyReflection(ref localFixedDir, e, u0, u1); if (localSampledDir.z * localFixedDir.z > 0f) { _event = BsdfEvent.Specular | BsdfEvent.Reflect; pdfW = 1f; absCosDir = Math.Abs(localSampledDir.z); // The absCosSampledDir is used to compensate the other one used inside the integrator return kr / (absCosDir); } else return RgbSpectrum.ZeroSpectrum(); }
internal void Init(ref RayHit rh, ref RayData ray, ref Normal ng, ref Normal ns, ref UV texCoord, MaterialInfo mi, SurfaceTextureInfo texData, bool fromLight) { if (rh.Miss()) { throw new ArgumentException("RayHit missed geometry!"); } //if (HitPoint == null) //{ HitPoint = new HitPointInfo { Color = RgbSpectrum.Max(ref mi.Kd, ref mi.Ks), HitPoint = ray.Point(rh.Distance), TexCoord = texCoord, FromDirection = -ray.Dir, GeoNormal = ng, ShadingNormal = ns, FromLight = fromLight }; //} //else //{ // HitPoint.HitPoint = ray.Point(rh.Distance); // HitPoint.TexCoord = texCoord; // HitPoint.FromDirection = -ray.Dir; // HitPoint.GeoNormal = ng; // HitPoint.ShadingNormal = ns; // HitPoint.FromLight = fromLight; //}; this.MaterialInfo = mi; this.TexData = texData; if (Frame == null) this.Frame = new ONB(ref HitPoint.GeoNormal); else Frame.SetFromZ(ref HitPoint.GeoNormal); }
protected override RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event) { var kr = (RgbSpectrum)TexData.Gloss + 0.5f; var kt = (RgbSpectrum)(TexData.Transmittance??TexData.Diffuse) + 0.5f; bool isKtBlack = kt.IsBlack(); bool isKrBlack = kr.IsBlack(); _event = BsdfEvent.None; pdfW = 0f; absCosDir = 0f; localSampledDir = new Vector(); if (isKtBlack && isKrBlack) return RgbSpectrum.ZeroSpectrum(); bool entering = (CosTheta(ref localFixedDir) > 0f); float nc = TexData.PreviousMedium.IoR; float nt = TexData.Medium.IoR; float ntc = nt / nc; float eta = entering ? (nc / nt) : ntc; float costheta = CosTheta(ref localFixedDir); // Decide to transmit or reflect float threshold = isKrBlack ? 1f : (isKtBlack ? 0f : .5f); RgbSpectrum result; if (TexData.Event < threshold) { // Transmit // Compute transmitted ray direction float sini2 = SinTheta2(ref localFixedDir); float eta2 = eta * eta; float sint2 = eta2 * sini2; // Handle total internal reflection for transmission if (sint2 >= 1f) return RgbSpectrum.ZeroSpectrum(); float cost = MathLab.Sqrt(Math.Max(0f, 1f - sint2)) * (entering ? -1f : 1f); localSampledDir = new Vector(-eta * localFixedDir.x, -eta * localFixedDir.y, cost); absCosDir = Math.Abs(CosTheta(ref localSampledDir)); _event = BsdfEvent.Specular | BsdfEvent.Transmit; pdfW = threshold; if (!HitPoint.FromLight) result = (RgbSpectrum.UnitSpectrum() - FresnelCauchy_Evaluate(ntc, cost)) * eta2; else result = (RgbSpectrum.UnitSpectrum() - FresnelCauchy_Evaluate(ntc, costheta)); result *= kt; } else { // Reflect localSampledDir = new Vector(-localFixedDir.x, -localFixedDir.y, localFixedDir.z); absCosDir = Math.Abs(CosTheta(ref localSampledDir)); _event = BsdfEvent.Specular | BsdfEvent.Reflect; pdfW = 1f - threshold; result = kr * FresnelCauchy_Evaluate(ntc, costheta); } // The absCosSampledDir is used to compensate the other one used inside the integrator return result / (absCosDir); }
protected abstract RgbSpectrumInfo Evaluate(ref HitPointInfo HitPoint, ref Vector localLightDir, ref Vector localEyeDir, out BsdfEvent _event, out float directPdfW, out float reversePdfW);
protected abstract RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event);