public TransparentMaterial(Vector3 Albedo, Medium Medium = null) { Properties.Add("albedo", new MaterialConstantNode(Albedo)); this.Medium = Medium; }
public TransparentMaterial(MaterialNode Albedo, Medium Medium = null) { Properties.Add("albedo", Albedo); this.Medium = Medium; }
private Vector3 Trace(Ray Ray) { Medium CurrentMedium = null; LobeType SampledLobe = LobeType.SpecularReflection; Vector3 FinalColor = Vector3.Zero; Vector3 Throughput = Vector3.One; for (int Bounce = 0; Bounce < MaxBounces; Bounce++) { //Raycast to nearest geometry, if any World.Raycast(Ray, out Shape Shape, out Vector3 Hit, out Vector3 Normal, out Vector2 UV); //Return skybox color if nothing hit if (Shape == null) { if (SkyBox == null) { FinalColor += Throughput * Vector3.One; } else { FinalColor += Throughput * SkyBox.GetColorAtUV(new Vector2(1 - (1.0 + Math.Atan2(Ray.Direction.Z, Ray.Direction.X) / MathHelper.Pi) * 0.5, 1 - Math.Acos(Ray.Direction.Y) / MathHelper.Pi)); } break; } //Volumetrics, slightly borken bool Scattered = false; if (CurrentMedium != null) { double MaxDistance = (Hit - Ray.Origin).Length(); double Distance = CurrentMedium.SampleDistance(MaxDistance); Vector3 Transmission = CurrentMedium.Transmission(Distance); Throughput *= Transmission; if (Distance < MaxDistance) { Scattered = true; Ray.Direction = CurrentMedium.SampleDirection(Ray.Direction); Ray.Origin = Hit + Ray.Direction * 0.001; } } //If no scattering event happened, do normal path tracing if (!Scattered) { //Area lights if (Shape.Material.HasProperty("emission")) { //Don't add emission to diffuse term if NEE is on, we already sample it directly if (SampledLobe == LobeType.SpecularReflection || !NEE) { FinalColor += Throughput * Shape.Material.GetProperty("emission", UV).Color; } break; } Vector3 ViewDirection = Vector3.Normalize(Ray.Origin - Hit); //Sample BSDF Shape.Material.Sample(ViewDirection, Normal, UV, out Vector3 SampleDirection, out SampledLobe); Shape.Material.PDF(ViewDirection, Normal, UV, SampleDirection, SampledLobe, out double PDF); Shape.Material.Evaluate(ViewDirection, Normal, UV, SampleDirection, SampledLobe, out Vector3 Attenuation); //Sample direct lighting if (NEE) { FinalColor += Throughput * SampleLight(Shape, Hit, ViewDirection, Normal, UV, SampleDirection, SampledLobe, Attenuation); } //Accumulate BSDF attenuation Throughput *= Attenuation / PDF; //If we entered a medium, update current medium if (SampledLobe == LobeType.SpecularTransmission || SampledLobe == LobeType.DiffuseTransmission) { CurrentMedium = Shape.Material.Medium; } //Set new ray direction to sampled ray Ray.Origin = Hit + SampleDirection * 0.001; Ray.Direction = SampleDirection; } //Russian roulette if (Bounce >= MinBounces) { double Prob = Math.Max(Throughput.X, Math.Max(Throughput.Y, Throughput.Z)); if (Util.Random.NextDouble() > Prob) { break; } Throughput *= 1.0 / Prob; } } return(FinalColor); }
public GlassMaterial(MaterialNode Albedo, MaterialNode RefractiveIndex, MaterialNode Roughness, MaterialNode Normal, Medium Medium = null) { Properties.Add("albedo", Albedo); Properties.Add("ior", RefractiveIndex); Properties.Add("roughness", Roughness); if (Normal != null) { Properties.Add("normal", Normal); } this.Medium = Medium; }
public GlassMaterial(Vector3 Albedo, double RefractiveIndex, double Roughness, Medium Medium = null) { Properties.Add("albedo", new MaterialConstantNode(Albedo)); Properties.Add("ior", new MaterialConstantNode(RefractiveIndex)); Properties.Add("roughness", new MaterialConstantNode(Roughness)); this.Medium = Medium; }
public Material(Medium Medium = null) { this.Medium = Medium; this.Properties = new Dictionary <string, MaterialNode>(); }