protected BaseProceduralTexture(int w, int h) { this.width = w; this.height = h; DUDV = new UV( 1f/Width, 1f/Height); }
/* \brief Illuminates a given point in the scene. * * Given a point and two random samples (e.g., for position on area lights), * this method returns direction from point to light, distance, * pdf of having chosen this direction (e.g., 1 / area). * Optionally also returns pdf of emitting particle in this direction, * and cosine from lights normal (helps with PDF of hitting the light, * but set to 1 for point lights). * * Returns radiance. */ public abstract RgbSpectrum Illuminate( ref SceneSphere aSceneSphere, ref Vector aReceivingPosition, ref UV aRndTuple, out Vector oDirectionToLight, out float oDistance, out float oDirectPdfW, out float oEmissionPdfW, out float oCosAtLight);
/* \brief Emits particle from the light. * * Given two sets of random numbers (e.g., position and direction on area light), * this method generates a position and direction for light particle, along * with the pdf. * * Can also supply pdf (w.r.t. area) of choosing this position when calling * Illuminate. Also provides cosine on the light (this is 1 for point lights etc.). * * Returns "energy" that particle carries */ public abstract RgbSpectrum Emit( ref SceneSphere aSceneSphere, ref UV aDirRndTuple, ref UV aPosRndTuple, out Vector oPosition, out Vector oDirection, out float oEmissionPdfW, out float oDirectPdfA, out float oCosThetaLight);
public RgbSpectrum Le(Vector dir) { float theta = Vector.SphericalTheta(ref dir); UV uv = new UV(Vector.SphericalPhi(ref dir) * MathLab.INVTWOPI + shiftU, theta * MathLab.INVPI + shiftV); return (RgbSpectrum) (gain //* SkyLight; * tex.Sample(uv.U, uv.V)); }
protected BaseBxdf(ref RayHit rh, ref RayData ray, ref Normal ng, ref Normal ns, ref UV texCoord, MaterialInfo mi, SurfaceTextureInfo texData, bool fromLight) { #if VERBOSE if (ng.Length > 1f || ns.Length > 1f) { Console.WriteLine("Normals in bsdf arent normalized"); } #endif this.Init(ref rh, ref ray, ref ng, ref ns, ref texCoord, mi, texData, fromLight); }
public void InterpolateTriUV(int currentTriangleIndex, float b1, float b2, out UV texCoord) { var triIndex = currentTriangleIndex; if (texCoords == null || texCoords.Count == 0) texCoord = new UV { U = b1, V = b2 }; else { var t0 = texCoords[triIndex][0]; var t1 = texCoords[triIndex][1]; var t2 = texCoords[triIndex][2]; float b0 = 1f - b1 - b2; // return t0 * b1 + t1 * b2 + t2 * b0; texCoord = new UV(t0.U*b0 + t1.U*b1 + t2.U*b2, t0.V*b0 + t1.V*b1 + t2.V*b2); } }
public void InterpolateTriUV(int currentTriangleIndex, float b1, float b2, out UV texCoord) { var texCoords = scene.GeoData.TexCoords; if (scene.GeoData.TexCoords == null || scene.Triangles[currentTriangleIndex].v0.TexCoordIndex < 0 || texCoords.Length < scene.Triangles[currentTriangleIndex].v0.TexCoordIndex) { texCoord = new UV { U = b1, V = b2 }; } else { var t0 = texCoords[scene.Triangles[currentTriangleIndex].v0.TexCoordIndex]; var t1 = texCoords[scene.Triangles[currentTriangleIndex].v1.TexCoordIndex]; var t2 = texCoords[scene.Triangles[currentTriangleIndex].v2.TexCoordIndex]; float b0 = 1f - b1 - b2; // return t0 * b1 + t1 * b2 + t2 * b0; texCoord = new UV(t0.x * b0 + t1.x * b1 + t2.x * b2, t0.y * b0 + t1.y * b1 + t2.y * b2); } }
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); }
public void InterpolateTriUV(int currentTriangleIndex, float b1, float b2, out UV texCoord) { var texCoords = TexCoords; if (TexCoords == null || Triangles[currentTriangleIndex].v0.TexCoordIndex < 0) texCoord = new UV { U = b1, V = b2 }; else { var t0 = texCoords[Triangles[currentTriangleIndex].v0.TexCoordIndex]; var t1 = texCoords[Triangles[currentTriangleIndex].v1.TexCoordIndex]; var t2 = texCoords[Triangles[currentTriangleIndex].v2.TexCoordIndex]; float b0 = 1f - b1 - b2; // return t0 * b1 + t1 * b2 + t2 * b0; texCoord = new UV(t0.x * b0 + t1.x * b1 + t2.x * b2, t0.y * b0 + t1.y * b1 + t2.y * b2); } }
public MatteLambertBrdf(ref RayHit rh, ref RayData ray, ref Normal ng, ref Normal ns, ref UV texCoord, MaterialInfo mi, SurfaceTextureInfo texData, bool fromLight) : base(ref rh, ref ray, ref ng, ref ns, ref texCoord, mi, texData, fromLight) { }
public override RgbSpectrum Illuminate( ref SceneSphere aSceneSphere, ref Vector aReceivingPosition, ref UV aRndTuple, out Vector oDirectionToLight, out float oDistance, out float oDirectPdfW, out float oEmissionPdfW, out float oCosAtLight) { UV uv = new UV(); MC.UniformSampleTriangle(aRndTuple.U, aRndTuple.V, ref uv.U, ref uv.V); Vector lightPoint = p0 + e1*uv.U + e2*uv.V; oDirectionToLight = lightPoint - aReceivingPosition; float distSqr = oDirectionToLight.Length; oDistance = MathLab.Sqrt(distSqr); oDirectionToLight = oDirectionToLight/oDistance; var invDir = -oDirectionToLight; var norm = mFrame.Normal(); float cosNormalDir = Vector.Dot(ref norm, ref invDir); // too close to, or under, tangent if (cosNormalDir < Consts.EPS_COSINE) { oCosAtLight = float.MinValue; oDirectPdfW = 0f; oEmissionPdfW = 0f; return RgbSpectrum.ZeroSpectrum(); } oDirectPdfW = mInvArea*distSqr/cosNormalDir; oCosAtLight = cosNormalDir; oEmissionPdfW = mInvArea*cosNormalDir*MathLab.INVPI; return mIntensity; }
public override RgbSpectrum Emit(ref SceneSphere aSceneSphere, ref UV aDirRndTuple, ref UV aPosRndTuple, out Vector oPosition, out Vector oDirection, out float oEmissionPdfW, out float oDirectPdfA, out float oCosThetaLight) { throw new NotImplementedException(); }
public override RgbSpectrum Illuminate(ref SceneSphere aSceneSphere, ref Vector aReceivingPosition, ref UV aRndTuple, out Vector oDirectionToLight, out float oDistance, out float oDirectPdfW, out float oEmissionPdfW, out float oCosAtLight) { throw new NotImplementedException(); }
public override RgbSpectrum Emit( ref SceneSphere aSceneSphere, ref UV aDirRndTuple, ref UV aPosRndTuple, out Vector oPosition, out Vector oDirection, out float oEmissionPdfW, out float oDirectPdfA, out float oCosThetaLight) { UV uv = new UV(); MC.UniformSampleTriangle(aPosRndTuple.U, aPosRndTuple.V, ref uv.U, ref uv.V); oPosition = p0 + e1*uv.U + e2*uv.V; Vector localDirOut = Utils.SampleCosHemisphereW(aDirRndTuple, out oEmissionPdfW); oEmissionPdfW *= mInvArea; // cannot really not emit the particle, so just bias it to the correct angle localDirOut.z = Math.Max(localDirOut.z, Consts.EPS_COSINE); oDirection = mFrame.ToWorld(ref localDirOut); oDirectPdfA = mInvArea; oCosThetaLight = localDirOut.z; return mIntensity*localDirOut.z; }
public SpecularReflectionBrdf(ref RayHit rh, ref RayData ray, ref Normal ng, ref Normal ns, ref UV texCoord, MaterialInfo mi, SurfaceTextureInfo texData, bool fromLight) : base(ref rh, ref ray, ref ng, ref ns, ref texCoord, mi, texData, fromLight) { }
private void EvalIntersectionAdvanced(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData ii, IntersectionOptions options) { ITriangleMesh mesh = null; #if VERBOSE try { #endif var currentTriangleIndex = (int)hit.Index; bool isLight = scene.IsLight(currentTriangleIndex); ii.Hit = hit; ii.isLight = isLight; mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); if (mesh == null) //|| mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase)) { //ii.Color = new RgbSpectrum(1f); //Debugger.Break(); throw new ApplicationException("Invalid triangle index " + currentTriangleIndex + " Mesh not found"); } var meshMat = mesh.MaterialID; ii.isVolume = scene.IsVolumeTriangle(currentTriangleIndex); ii.MMaterial = scene.MatLib.GetSurfMat(meshMat); var matInfo = scene.MaterialProvider.Get(meshMat); mesh.InterpolateTriUV(currentTriangleIndex, hit.U, hit.V, out ii.TexCoords); if (ii.isVolume) { var volumeMaterialInfo = vm.GetMaterialInfo(mesh.MaterialID); vmSampler.Sample(volumeMaterialInfo, ii.Hit.Distance, ref PathRay, out ii.VolumeData); //texSampler.SampleTexture(hit.U, hit.V, volumeMaterialInfo.Density, out ii.VolumeData.Density); //this.texSampler.SampleTexture(hit.U, hit.V, new NoiseTexture() ii.VolumeData.Density); //return; } mesh.InterpolateTriangleNormal((int)hit.Index, hit.U, hit.V, ref ii.Normal); //ii.Normal = scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize(); // ii.TexCoords = new UV(hit.U, hit.V); if (isLight) { if (!options.Has(IntersectionOptions.ResumeOnLight)) return; var color = scene.GetLightByIndex((int)hit.Index).Profile.Evaluate(hit.U, hit.V); ii.Color = options.Has(IntersectionOptions.ResolveSpectralDistributions) ? ColorFactory.ToRgb(ref color) : (RgbSpectrum)(RgbSpectrumInfo)color; } if (options.Has(IntersectionOptions.ResolvePartialDerivatives)) { var p1 = scene.Vertices[scene.Triangles[currentTriangleIndex].v0.VertexIndex]; var p2 = scene.Vertices[scene.Triangles[currentTriangleIndex].v1.VertexIndex]; var p3 = scene.Vertices[scene.Triangles[currentTriangleIndex].v2.VertexIndex]; var mt = scene.sceneData.GeoData.TexCoords; var uv1 = mt[scene.sceneData.Triangles[currentTriangleIndex].v0.TexCoordIndex]; var uv2 = mt[scene.sceneData.Triangles[currentTriangleIndex].v1.TexCoordIndex]; var uv3 = mt[scene.sceneData.Triangles[currentTriangleIndex].v2.TexCoordIndex]; float du1 = uv1.x - uv3.x; float du2 = uv2.x - uv3.x; float dv1 = uv1.y - uv3.y; float dv2 = uv2.y - uv3.y; Vector dp1 = Vector.Sub(ref p1, ref p3), dp2 = Vector.Sub(ref p2, ref p3); float determinant = du1 * dv2 - dv1 * du2; if (determinant.NearEqual(0f)) { // Handle zero determinant for triangle partial derivative matrix Vector e1 = p2 - p1; Vector e2 = p3 - p1; Vector.CoordinateSystem(Vector.Normalize(Vector.Cross(ref e2, ref e1)), out ii.DpDu, out ii.DpDv); } else { float invdet = 1f / determinant; ii.DpDu = (dv2 * dp1 - dv1 * dp2) * invdet; ii.DpDv = (-du2 * dp1 + du1 * dp2) * invdet; } } if (matInfo.Alpha is ConstTextureInfo) { ii.Alpha = (matInfo.Alpha as ConstTextureInfo).Color; } if (options.Has(IntersectionOptions.ResolveTextures)) { var diffuseTex = scene.Query(meshMat, TextureType.Diffuse); if (diffuseTex != null) { #if !TEXSAMP RgbSpectrumInfo cc = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V); #else RgbSpectrumInfo cc; texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, diffuseTex, out cc); #endif ii.Color = new RgbSpectrum(cc.c1, cc.c2, cc.c3); //ii.Color = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V); //ii.Color = diffuseTex.Sample(hit.U, hit.V); } else { ii.Color = RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd); } var bump = new Vector(0f); Vector v1, v2; Normal geoNormal = ii.Normal; Vector.CoordinateSystem(ref geoNormal, out v1, out v2); var bumpTex = scene.Query(meshMat, TextureType.Bump); if (bumpTex != null) { var map = bumpTex; var dudv = map.DUDV; RgbSpectrumInfo bs; #if TEXSAMP texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, bumpTex, out bs); #else bs = bumpTex.Sample(ii.TexCoords.U, ii.TexCoords.V); #endif float b0 = bs.Filter(); UV uvdu = new UV(ii.TexCoords.U + dudv.U, ii.TexCoords.V); #if TEXSAMP texSampler.SampleTexture(uvdu.U, uvdu.V, bumpTex, out bs); #else bs = bumpTex.Sample(uvdu.U, uvdu.V); #endif float bu = bs.Filter(); UV uvdv = new UV(ii.TexCoords.U, ii.TexCoords.V + dudv.V); #if TEXSAMP texSampler.SampleTexture(uvdv.U, uvdv.V, bumpTex, out bs); #else bs = bumpTex.Sample(uvdv.U, uvdv.V); #endif float bv = bs.Filter(); float scale = 1.0f; //bm->GetScale(); bump = new Vector(scale * (bu - b0), scale * (bv - b0), 1f); ii.Normal = new Normal( v1.x * bump.x + v2.x * bump.y + geoNormal.x * bump.z, v1.y * bump.x + v2.y * bump.y + geoNormal.y * bump.z, v1.z * bump.x + v2.z * bump.y + geoNormal.z * bump.z).Normalize(); } var nfScale = 2.0f; var nfIscale = 0.5f; var normTex = scene.Query(meshMat, TextureType.Normal); if (normTex != null) { RgbSpectrumInfo color; texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, normTex, out color); float x = nfScale * (color.c1 - nfIscale); float y = nfScale * (color.c2 - nfIscale); float z = nfScale * (color.c3 - nfIscale); ii.Normal = new Normal( v1.x * x + v2.x * y + geoNormal.x * z, v1.y * x + v2.y * y + geoNormal.y * z, v1.z * x + v2.z * y + geoNormal.z * z).Normalize(); } RgbSpectrumInfo reflectance = matInfo.Coefficients[3]; //(RgbSpectrumInfo) matInfo.SpecularReflectance; var reflTex = scene.Query(meshMat, TextureType.Reflection); if (reflTex != null) { texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, reflTex, out reflectance); } RgbSpectrumInfo alpha = null; var alphaTex = scene.Query(meshMat, TextureType.Alpha); if (alphaTex != null) { texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, alphaTex, out alpha); } var zero = new RgbSpectrum(0f); if (ii.TextureData == null) { ii.TextureData = new SurfaceTextureData() { T0 = 0.5f, Transmittance = matInfo.Ks, Exponent = matInfo.Exponent, Alpha = alpha != null ? (RgbSpectrum) alpha : zero, Diffuse = ii.Color, Roughness = bump, Bump = bump, Medium = MediumInfo.Glass, Specular = (RgbSpectrum) reflectance }; } else { ii.TextureData.T0 = 0.5f; ii.TextureData.Transmittance = matInfo.Ks; ii.TextureData.Exponent = matInfo.Exponent; ii.TextureData.Alpha = alpha != null ? (RgbSpectrum) alpha : zero; ii.TextureData.Diffuse = ii.Color; ii.TextureData.Roughness = bump; ii.TextureData.Bump = bump; ii.TextureData.Medium = MediumInfo.Glass; ii.TextureData.Specular = (RgbSpectrum) reflectance; } } else { ii.Color = //matInfo.Kd; RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd); ii.TextureData = new SurfaceTextureData() { T0 = 0.5f, Transmittance = matInfo.Ks, Exponent = matInfo.Exponent, //Alpha = matInfo.Ka, Diffuse = matInfo.Kd, //Roughness = bump, //Bump = bump, Medium = MediumInfo.Glass, Specular = matInfo.Ks }; } /* if (mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase)) { //ii.Color = new RgbSpectrum(1f); ii.Normal = -scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize(); //ii.ShadingNormal = ii.Normal; } */ ii.ShadingNormal = (Normal.Dot(ref PathRay.Dir, ref ii.Normal) > 0f) ? -ii.Normal : ii.Normal; if (options.Has(IntersectionOptions.ResolveSpectralDistributions)) { ii.Reflectance = ColorFactory.FromRgb(RgbSpectrum.Max(ref ii.Color, ref matInfo.Kd), SpectrumType.Reflectance); } //ii.ShadingNormal = ii.Normal; /* ii.Material = new DistributionBsdf(ii.Color.y(), ii.Color, new FresnelConductor(FresnelApproxEta(ref matInfo.Kd), FresnelApproxK(ref matInfo.Ks)) //new FresnelDielectric(1.5f, 1f) //new FresnelNoOP() ); new DistributionBsdf(bump.IsZero() ? ii.Color.Filter():bump.Avg(), ii.Color); * */ //new DistributionBsdf(bump.IsZero() ? ii.Color.Filter() : bump.Avg(), ii.Color); #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Surface sampling error"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); throw; } #endif }