public override void Sample_f(ShadePointInfo pt, float u0, float u1, float u2, out Vector vector, out float radiancePdf, out float pdf1, out BsdfEvent @event) { float c = 1f - Vector.Dot(ref pt.IncomingDirection, ref pt.ShadingNormal); float Re = R0 + (1f - R0) * c * c * c * c * c; float P = .25f + .5f * Re; if ((u2 < P && reflectionSpecularBounce)) {//onlySpecular || vector = MetalBrdf.GlossyReflection(ref pt.IncomingDirection, exponent, ref pt.ShadingNormal, u0, u1); pdf1 = P / Re; @event = BsdfEvent.Specular; radiancePdf = Re; } else { Vector dir = MC.CosineSampleHemisphere(u0, u1); pdf1 = dir.z * MathLab.INVPI; /* Vector v1, v2; * dir = Vector.CoordinateSystem(ref shadeN, out v1, out v2); dir = new Vector( v1.x * dir.x + v2.x * dir.y + shadeN.x * dir.z, v1.y * dir.x + v2.y * dir.y + shadeN.y * dir.z, v1.z * dir.x + v2.z * dir.y + shadeN.z * dir.z);*/ ONB fm = new ONB(ref pt.ShadingNormal); var wi = fm.ToWorld(ref dir);//pt.Frame float dp = Vector.Dot(ref pt.ShadingNormal, ref wi); // Using 0.0001 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { pdf1 = 0f; } pdf1 /= dp; float iRe = 1f - Re; pdf1 *= (1f - P) / iRe; @event = BsdfEvent.Glossy | BsdfEvent.Diffuse; vector = wi; radiancePdf = iRe; } }
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); }