public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample) { shadowIntegrator = new ShadowIntegrator(); Color returnColor = new Color(0, 0, 0); HitRecord record = objects.Intersect(ray); if (record != null) { if (!(record.Material is MirrorMaterial)) { returnColor.Append(shadowIntegrator.Integrate(ray, objects, lights, sampler, subPathSamples, lightSample)); } if (record.Material is MirrorMaterial && record.Material.Specular.R > 0 && record.Material.Specular.G > 0 && record.Material.Specular.B > 0) { returnColor.Append(Reflection(ray, record, 0, returnColor, objects, lights, sampler, subPathSamples, lightSample)); } } else { if (SkyBox.IsSkyBoxLoaded()) { returnColor = SkyBox.GetSkyBoxColor(ray); } } return(returnColor); }
/// <summary> /// Generates the Texture3D /// </summary> /// <param name="sourceTexture">The source texture asset</param> /// <returns>True if parameters were valid, false otherwise</returns> public bool GenerateVolumetricTexture(Texture2D sourceTexture) { if (AreParametersValid) { Texture3D volumetricTexture = new Texture3D(_referenceSize, _referenceSize, _referenceSize, sourceTexture.format, false); volumetricTexture.wrapMode = sourceTexture.wrapMode; volumetricTexture.wrapModeU = sourceTexture.wrapModeU; volumetricTexture.wrapModeV = sourceTexture.wrapModeV; volumetricTexture.wrapModeW = sourceTexture.wrapModeW; volumetricTexture.filterMode = sourceTexture.filterMode; volumetricTexture.mipMapBias = 0; volumetricTexture.anisoLevel = 0; Color[] colorArray = new Color[0]; switch (_readingOrder) { case Texture3DReadingOrderEnum.RowMajor: { for (int i = 0; i < HorizontalTilesCount; ++i) { for (int j = 0; j < VerticalTilesCount; ++j) { colorArray = colorArray.Append(sourceTexture.GetPixels(i * _referenceSize, j * _referenceSize, _referenceSize, _referenceSize)); } } } break; case Texture3DReadingOrderEnum.ColumnMajor: { for (int i = VerticalTilesCount - 1; i >= 0; --i) { for (int j = 0; j < HorizontalTilesCount; ++j) { colorArray = colorArray.Append(sourceTexture.GetPixels(j * _referenceSize, i * _referenceSize, _referenceSize, _referenceSize)); } } } break; } volumetricTexture.SetPixels(colorArray); volumetricTexture.Apply(); AssetDatabase.CreateAsset(volumetricTexture, System.IO.Directory.GetParent(AssetDatabase.GetAssetPath(sourceTexture)) + "\\" + sourceTexture.name + "_Texture3D.asset"); return(true); } return(false); }
public void Render() { if (sampler != null) { for (int i = 0; i < camera.ScreenWidth; i++) { for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads) { Color pixelColor = new Color(0, 0, 0); List <List <Sample> > subPathSamples = new List <List <Sample> >(); List <Sample> samples = sampler.CreateSamples(); List <LightSample> lightSamples = new List <LightSample>(); if (integrator is PathTraceIntegrator) { lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength); for (int s = 0; s < Constants.MaximalPathLength; s++) { subPathSamples.Add(sampler.CreateSamples()); } foreach (Sample sample in samples) { Ray ray = camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } else { lightSamples = sampler.GetLightSamples(); foreach (Sample sample in samples) { Ray ray = camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } pixelColor.VoidDiv(samples.Count); film.SetPixel(i, j, pixelColor); } } } else { for (int i = 0; i < camera.ScreenWidth; i++) { for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads) { Ray ray = camera.CreateRay(i, j); Color pixelColor = integrator.Integrate(ray, objects, lights, null, null, null); film.SetPixel(i, j, pixelColor); } } } ThreadDone(this, new EventArgs()); }
/// <summary> /// Generates the Texture3D composed out of the candidate textures (already handles NeedsToUpdateVolumeTexture parameter check) /// </summary> public void Generate() { if (NeedsToUpdateVolumeTexture) { if (_texturesList.Count > 0) { Color[] colorArray = new Color[0]; VolumeTexture = new Texture3D(_requiredSize, _requiredSize, _requiredSize * _texturesList.Count, _requiredTextureFormat, false); for (int i = 0; i < _texturesList.Count; ++i) { // TODO : DO WITH GRAPHICS.COPYTEXTURES NOW THAT TEXTURE3D COPY ACTUALLY WORKS colorArray = colorArray.Append(_texturesList[i].GetPixels()); } VolumeTexture.SetPixels(colorArray); VolumeTexture.Apply(); HasVolumeTexture = true; } else { VolumeTexture = null; HasVolumeTexture = false; } NeedsToUpdateVolumeTexture = false; RaiseTextureUpdatedEvent(); } }
private Color Reflection(Ray ray, HitRecord record, int noOfBounce, Color color, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample) { Color ks = record.Material.Specular; if (noOfBounce == Constants.MaximumRecursionDepth) { return(shadowIntegrator.Integrate(ray, objects, lights, sampler, subPathSamples, lightSample).Mult(ks)); } Ray reflectedRay = record.CreateReflectedRay(); HitRecord reflectRecord = objects.Intersect(reflectedRay); if (reflectRecord.HitObject != null) { if (reflectRecord.Material is MirrorMaterial) { Color c = Reflection(reflectedRay, reflectRecord, ++noOfBounce, color, objects, lights, sampler, subPathSamples, lightSample); c.Append(shadowIntegrator.Integrate(reflectedRay, objects, lights, sampler, subPathSamples, lightSample).Mult(ks)); return(c); } else { return(shadowIntegrator.Integrate(reflectedRay, objects, lights, sampler, subPathSamples, lightSample).Mult(ks)); } } else { if (SkyBox.IsSkyBoxLoaded()) { color = SkyBox.GetSkyBoxColor(ray); } } return(color); }
public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample) { HitRecord record = objects.Intersect(ray); Color returnColor = new Color(0, 0, 0); if (record != null) { foreach (ILight light in lights) { Vector3 lightDirection = light.GetLightDirection(record.IntersectionPoint); Vector3 hitPos = record.IntersectionPoint; Vector3 offset = record.RayDirection; offset = -offset; offset *= 0.001f; hitPos += offset; Ray shadowRay = new Ray(hitPos, lightDirection); HitRecord shadowHit = objects.Intersect(shadowRay); Vector3 distance = Vector3.Subtract(light.Position, hitPos); //DEBUGGING /*if (shadowHit != null && (shadowHit.Distance > distance.Length)) * { * returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint))); * }*/ returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint))); } } return(returnColor); }
public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample) { HitRecord record = objects.Intersect(ray); Color retColor = new Color(0, 0, 0); this.objects = objects; this.lights = lights; this.sampler = sampler; retColor.Append(GetShadeColor(record, 0)); return(retColor); }
private Color Shade(HitRecord record, LightSample sample) { Color pixelColor = new Color(0, 0, 0); if (record.Material is LambertMaterial || record.Material is BlinnPhongMaterial) { if (sample.LightColor.Power > 0 && IsVisible(record, sample)) { pixelColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor)); } } return(pixelColor); }
public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample) { Color returnColor = new Color(0, 0, 0); /* * Core Ray Tracing algorithm */ HitRecord record = objects.Intersect(ray); if (record != null && record.Distance > 0 && record.Distance < float.PositiveInfinity) { foreach (ILight light in lights) { returnColor.Append(record.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint))); } } return(returnColor); }
public void Render() { DepthOfFieldCamera cam = ((DepthOfFieldCamera)scene.Camera); for (int i = 0; i < scene.Film.Width; i++) { for (int j = 0; j < scene.Film.Height; j++) { Color pixelColor = new Color(0, 0, 0); List <Sample> appertureSamples = ((ISampler)Activator.CreateInstance(Constants.Sampler)).CreateSamples(); for (int s = 0; s < 24; s++) { Ray ray = cam.CreateRay(i, j, appertureSamples); pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, null, null, null)); } pixelColor.VoidDiv(24f); scene.Film.SetPixel(i, j, pixelColor); } } Tonemapper.SaveImage("C:\\Test\\" + scene.FileName, scene.Film); }
private Color GetShadeColor(HitRecord record, int currentDepth) { if (record != null && record.Distance > 0 && record.Distance < float.MaxValue) { if (record.Material is MirrorMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Mirror Objects { HitRecord mirrorRecord = objects.Intersect(record.CreateReflectedRay()); return(GetShadeColor(mirrorRecord, ++currentDepth).Mult(record.Material.Ks)); } if (record.Material is RefractiveMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Reflective Objects { float r = Reflectance(record); HitRecord reflectionHit = objects.Intersect(record.CreateReflectedRay()); Color reflectedColor = GetShadeColor(reflectionHit, ++currentDepth).Mult(record.Material.Ks); HitRecord refractedHit = objects.Intersect(CreateRefractedRay(record)); Color refractedColor = GetShadeColor(refractedHit, ++currentDepth).Mult(record.Material.Ks); Color retColor = reflectedColor.Mult(r); retColor.Append(refractedColor.Mult(1 - r)); return(retColor); } if (record.HitObject.Light != null && Constants.IsLightSamplingOn) { return(record.HitObject.Light.LightColor); } Color returnColor = new Color(0, 0, 0); foreach (ILight light in lights) { Color lightColor = new Color(0, 0, 0); if (Constants.IsLightSamplingOn && Constants.NumberOfLightSamples > 0) { List <LightSample> lightSamples = sampler.GetLightSamples(); for (int i = 0; i < Constants.NumberOfLightSamples; i++) { LightSample sample = lightSamples[(int)(random.NextDouble() * lightSamples.Count)]; lightSamples.Remove(sample); light.Sample(record, sample); if (IsVisible(record, sample) && sample.LightColor.Power > 0) { if (!(light is AreaLight)) { lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor)); } else { lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor).Div(sample.Pdf)); } } } returnColor.Append(lightColor.Div(Constants.NumberOfLightSamples)); } if (!(light is AreaLight) && IsVisible(record, light)) { returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint))); } } return(returnColor); } return(new Color(0, 0, 0)); }
public Color PathTrace(Ray ray, HitRecord record, List <List <Sample> > subPathSamples, LightSample lightSample) { float q = 0f; int depth = 0; Color pixelColor = new Color(0, 0, 0); Color alpha = new Color(1, 1, 1); bool isGeneratedFromRefraction = false; while (depth < Constants.MaximalPathLength) { if (record == null) { return(pixelColor); } //Select one light at random ILight light = Randomizer.PickRandomLight(lights); //Sample that light light.Sample(record, lightSample); if (isGeneratedFromRefraction && record.HitObject.Light != null) { isGeneratedFromRefraction = false; pixelColor.Append(record.HitObject.Light.LightColor); } pixelColor.Append(alpha.Mult(Shade(record, lightSample)).Div(lightSample.Pdf)); //Break with Russian roulette if (depth > 2) { q = 0.5f; if (random.NextDouble() <= q) { return(pixelColor); } } List <Sample> directionSamples = subPathSamples[depth]; //Create the next Ray if (record.Material is LambertMaterial || record.Material is BlinnPhongMaterial) { Sample directionSample = Randomizer.PickRandomSample(directionSamples); Vector3 direction = UniformHemisphereSample(directionSample.X, directionSample.Y, record.SurfaceNormal); record = scene.Intersect(new Ray(record.IntersectionPoint, direction)); if (record == null) { break; } alpha = alpha.Mult(record.Material.Diffuse.Div(1 - q)); } else if (record.Material is MirrorMaterial) { record = scene.Intersect(record.CreateReflectedRay()); isGeneratedFromRefraction = true; } else if (record.Material is RefractiveMaterial) { isGeneratedFromRefraction = true; float fresnel = Reflectance(record); //Pick refraction / reflection path with p=0.5 each if (random.NextDouble() < fresnel) { record = scene.Intersect(record.CreateReflectedRay()); alpha = alpha.Mult(fresnel); } else { record = scene.Intersect(record.CreateRefractedRay()); alpha = alpha.Mult(1 - fresnel); } } depth++; } return(pixelColor); }
public Color Shade(HitRecord record, Vector3 wi) { Color pixelColor = new Color(0, 0, 0); Vector3 normal = record.SurfaceNormal; normal.Normalize(); wi.Normalize(); float noiseCoefficient = 0f; switch (Noise) { case Noise.Turbulence: noiseCoefficient = Turbulence(record.IntersectionPoint); break; case Noise.Marble: noiseCoefficient = Marble(record.IntersectionPoint); break; case Noise.Bumb: noiseCoefficient = 1f; normal = Bump(record.IntersectionPoint, normal); break; case Noise.None: noiseCoefficient = 1f; break; default: noiseCoefficient = 1f; break; } if (BumpTexture != null) { Color displacementColor = BumpTexture.GetColorFromTexCoordinate(record.HitObject.GetTextudeCoordinates(record)); Vector3 displacementNormal = normal; displacementNormal.X = ((displacementColor.R * 2) - 1); displacementNormal.Y = ((displacementColor.G * 2) - 1); displacementNormal.Z = displacementColor.B; normal = (Vector3.Dot(displacementNormal, normal) < 0) ? -displacementNormal : displacementNormal; } float nDotL = Vector3.Dot(normal, wi); if (nDotL > 0) { Color diffuse; if (Constants.TextureMapping && ColorTexture != null && !(record.HitObject is Plane)) { diffuse = ColorTexture.GetColorFromTexCoordinate(record.HitObject.GetTextudeCoordinates(record)); } else { diffuse = Diffuse; } //add Diffuse Light pixelColor.Append(diffuse.Mult(nDotL).Mult(noiseCoefficient)); pixelColor.Append(pixelColor.Mult(1f - noiseCoefficient)); //Calculate the Blinn halfVector Vector3 h = wi; h = Vector3.Add(h, wi); h.Normalize(); float hDotN = Vector3.Dot(h, normal); if (hDotN > 0) { float pow = (float)Math.Pow(hDotN, Shininess); pixelColor.Append(Specular.Mult(pow)); } } pixelColor.Append(Ambient); pixelColor.Clamp(0f, 1f); return(pixelColor); }
public void Render() { stopwatch = new Stopwatch(); stopwatch.Reset(); if (Constants.NumberOfThreads == 1) //One Thread { stopwatch.Start(); ISampler sampler = (ISampler)Activator.CreateInstance(Constants.Sampler); if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0) { Console.WriteLine("Using Supersampling with: " + Constants.NumberOfSamples + " samples!"); for (int i = 0; i < scene.Film.Width; i++) { for (int j = 0; j < scene.Film.Height; j++) { Color pixelColor = new Color(0, 0, 0); List <List <Sample> > subPathSamples = new List <List <Sample> >(); List <LightSample> lightSamples = new List <LightSample>(); List <Sample> samples = sampler.CreateSamples(); if (scene.Integrator is PathTraceIntegrator) { lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength); for (int s = 0; s < Constants.MaximalPathLength; s++) { subPathSamples.Add(sampler.CreateSamples()); } foreach (Sample sample in samples) { Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } else { lightSamples = sampler.GetLightSamples(); foreach (Sample sample in samples) { Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y); pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples))); } } pixelColor.VoidDiv(samples.Count); scene.Film.SetPixel(i, j, pixelColor); } } } else { for (int i = 0; i < scene.Film.Width; i++) { for (int j = 0; j < scene.Film.Height; j++) { Ray ray = scene.Camera.CreateRay(i, j); Color color = scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, null, null, null); scene.Film.SetPixel(i, j, color); } } } stopwatch.Stop(); Debug.WriteLine("Finished rendering in: " + stopwatch.ElapsedMilliseconds + " ms."); Tonemapper.SaveImage("C:\\Test\\" + scene.FileName, scene.Film); } else //More than 1 thread { if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0) { Debug.WriteLine("Start rendering with: " + Constants.NumberOfThreads + " Threads"); stopwatch.Start(); finishedThreads = 0; for (int i = 0; i < Constants.NumberOfThreads; i++) { ISampler sampler = new StratifiedSampler(); MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights, scene.Camera, scene.Film); renderer.ThreadDone += HandleThreadDone; Thread t = new Thread(renderer.Render); t.Start(); } } else { stopwatch.Start(); finishedThreads = 0; for (int i = 0; i < Constants.NumberOfThreads; i++) { MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights, scene.Camera, scene.Film); renderer.ThreadDone += HandleThreadDone; Thread t = new Thread(renderer.Render); t.Start(); } } } }