private void Working() { RTMath.ThreadInitRnd(); for (int i = 0; i < pIndex; ++i) { if (IsDestroied) { return; } Item item = items[i]; Color color = Color.black; for (int s = 0; s < numSamples; ++s) { float u = (item.i + RTMath.Rnd01()) / canvasWidth; float v = (item.j + RTMath.Rnd01()) / canvasHeight; RTRay ray = cam.GetRay(u, v); color += renderer.GetColor(ray, 0); } color /= numSamples; item.finalColor = color; items[i] = item; } status = STATUS_COMPLETE; }
public override bool Scatter(RTRay ray, HitRecord hit, out Color attenuation, out RTRay scattered) { attenuation = new Color(1, 1, 1); Vector3 outwardN; float ni_over_nt; Vector3 refracted; float reflect_prob; float cosine; if (Vector3.Dot(ray.direction, hit.n) > 0) { outwardN = -hit.n; ni_over_nt = refractiveIndex; cosine = Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude; } else { outwardN = hit.n; ni_over_nt = 1.0f / refractiveIndex; cosine = -Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude; } if (RTMath.Refract(ray.direction, outwardN, ni_over_nt, out refracted)) { reflect_prob = RTMath.schlick(cosine, refractiveIndex); } else { reflect_prob = 1.0f; } if (RTMath.Rnd01() < reflect_prob) { scattered = new RTRay().Set(hit.p, RTMath.Reflect(ray.direction, hit.n)); } else { scattered = new RTRay().Set(hit.p, refracted); } return(true); }
protected override void Awake() { base.Awake(); numSamples = 5; isScreenSize = true; ppmTexture.sRGB = true; scene = new HitableList(); scene.list.Add(new RTSphere().Set(new Vector3(0, -1000, 0), 1000).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(0.5f, 0.5f, 0.5f)))); for (int a = -11; a < 11; ++a) { for (int b = -11; b < 11; ++b) { float rnd = RTMath.Rnd01(); Vector3 center = new Vector3(a + 0.9f * rnd, 0.2f, b + 0.9f * rnd); if ((center - new Vector3(4, 0.2f, 0)).magnitude > 0.9f) { if (rnd < 0.6f) { scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(RTMath.Rnd01(), RTMath.Rnd01(), RTMath.Rnd01())))); } else if (rnd < 0.9f) { scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Metal().SetAlbedo <Metal>(new Color(0.5f * (1 + RTMath.Rnd01()), 0.5f * (1 + RTMath.Rnd01()), 0.5f * (1 + RTMath.Rnd01()))).SetFuzz(0.5f * RTMath.Rnd01()))); } else { scene.list.Add(new RTSphere().Set(center, 0.2f).SetMaterial <RTSphere>(new Dielectric().SetRefractiveIndex(1.5f))); } } } } scene.list.Add(new RTSphere().Set(new Vector3(0, 1, 0), 1).SetMaterial <RTSphere>(new Dielectric().SetRefractiveIndex(1.5f))); scene.list.Add(new RTSphere().Set(new Vector3(-4, 1, 0), 1).SetMaterial <RTSphere>(new Lambertian().SetAlbedo <Lambertian>(new Color(0.4f, 0.2f, 0.1f)))); scene.list.Add(new RTSphere().Set(new Vector3(4, 1, 0), 1).SetMaterial <RTSphere>(new Metal().SetAlbedo <Metal>(new Color(0.7f, 0.6f, 0.5f)).SetFuzz(0.0f))); }
protected virtual void Start() { int canvasWidth = isScreenSize ? Screen.width : 200; int canvasHeight = isScreenSize ? Screen.height : 100; cam = CreateCamera(canvasWidth, canvasHeight); ppmTexture.Init(canvasWidth, canvasHeight); renderingTasksManager = new RenderingTasksManager(); int pixelIndex = 0; RenderingTask task = null; int itemsCount = 0; for (int j = 0; j < ppmTexture.Height; ++j) { for (int i = 0; i < ppmTexture.Width; ++i) { if (multiThreadRendering) { if (itemsCount == 0) { task = new RenderingTask(); task.Init(this, cam, ppmTexture.Width, ppmTexture.Height, numSamples); renderingTasksManager.AddTask(task, RenderingTaskCompleteCB); } task.AddItem(i, j, pixelIndex); ++itemsCount; if (itemsCount == RenderingTask.SIZE) { itemsCount = 0; } ++pixelIndex; } else { Color color = Color.black; for (int s = 0; s < numSamples; ++s) { float u = (i + RTMath.Rnd01()) / ppmTexture.Width; float v = (j + RTMath.Rnd01()) / ppmTexture.Height; RTRay ray = cam.GetRay(u, v); color += GetColor(ray, 0); } color /= numSamples; ppmTexture.WriteAPixel(color); } } } if (!multiThreadRendering) { ppmTexture.Complete(); RenderingComplete(); } else { renderingTasksManager.Start(); } }