public override bool scatter(Ray rayIn, ref HitRecord hrec, ref ScatterRecord srec) { srec.is_specular = true; srec.pdf = null; //var origin = new Color32(1.0f, 1.0f, 1.0f); //var result_c=new Color32(origin.r*color.r,,); //srec.attenuation = new Color32(1.0f, 1.0f, 1.0f)*(color*color.a); srec.attenuation = color; //srec.attenuation.a = 1; Vector3 outward_normal; var reflected = Reflect(rayIn.direction, hrec.normal); var refracted = new Vector3(0); float ni_over_nt; float cosine; if (Vector3.Dot(rayIn.direction, hrec.normal) > 0) { outward_normal = -hrec.normal; ni_over_nt = ref_idx; cosine = ref_idx * Vector3.Dot(rayIn.direction, hrec.normal) / rayIn.direction.length(); } else { outward_normal = hrec.normal; ni_over_nt = 1.0f / ref_idx; cosine = -Vector3.Dot(rayIn.direction, hrec.normal) / rayIn.direction.length(); } var reflect_prob = Refract(rayIn.direction, outward_normal, ni_over_nt, ref refracted) ? Schlick(cosine, ref_idx) : 1.0f; srec.specular_ray = Random.Get() < reflect_prob ? new Ray(hrec.p, reflected) : new Ray(hrec.p, refracted); return(true); }
protected Vector3 GetRandomPointInUnitSphere() { var p = new Vector3(0); do { p = new Vector3(Random.Get(), Random.Get(), Random.Get()) * 2.0f - Vector3.one; }while (Vector3.Dot(p, p) >= 1); return(p.Normalized()); }
private void LinearScanner(object o) { var config = (ScannerConfig)o; for (var j = config.h - 1; j >= 0; j--) { for (var i = 0; i < config.w; i++) { var color = mode == Mode.Diffusing ? Diffusing(camera.CreateRay( (i + Random.Get()) * recip_width, (j + Random.Get()) * recip_height), world, 0) : NormalMap(camera.CreateRay( (i + Random.Get()) * recip_width, (j + Random.Get()) * recip_height), world); SetPixel(config.w - i - 1, config.h - j - 1, color); } } Form1.main.BeginInvoke(new Action(() => { Form1.main.SetSPP(); })); }
private void Scanner(object o) { var config = (ScannerConfig)o; for (; 0 < scaned[config.ID];) { if (STOP) { return; } if (scaned[config.ID] == SPP) { SetPixelPriview(config, Color32.White); } for (var h = config.h; h < config.h + block_size; h++) { if (h >= height) { continue; } for (var w = config.w; w < config.w + block_size; w++) { if (w >= width) { continue; } var id = h * width + w; var color = mode == Mode.Shaded ? DiffuseScanner.GetColor(Scene.main.camera.CreateRay( (width - w + Random.Get()) * recip_width, (height - h + Random.Get()) * recip_height, id), Scene.main.world, Scene.main.Important, 0).DeNaN() : NormalMapScanner.GetColor(Scene.main.camera.CreateRay( (width - w + Random.Get()) * recip_width, (height - h + Random.Get()) * recip_height, h * width + w), Scene.main.world); SetPixel(w, h, color); } } scaned[config.ID]--; if (scaned[config.ID] == 0) { FinishedChunks++; if (config.ID == divide_h * divide_h - 1) { FirstRound = true; } SetPixelPriview(config, Color32.Transparent); chunk_end?.Invoke(FinishedChunks); aliveBlocks.Remove(config.point); if (FinishedChunks == divide_w * divide_h) { MessageBox.Show("渲染完成", "渲染器"); } else if (FirstRound) { var h = aliveBlocks[0].y; var w = aliveBlocks[0].x; ThreadPool.QueueUserWorkItem(Scanner, new ScannerConfig(w * block_size, h * block_size, h * divide_w + w, aliveBlocks[0])); } } } }
public Ray CreateRay(float x, float y) { if (radius == 0f) { return(new Ray(position, lowLeftCorner + x * horizontal + y * vertical - position, time0 + Random.Get() * (time1 - time0))); } var rd = radius * GetRandomPointInUnitDisk(); var offset = rd.x * u + rd.y * v; return(new Ray(position + offset, lowLeftCorner + x * horizontal + y * vertical - position - offset, time0 + Random.Get() * (time1 - time0))); }
public static Vector3 GetRandomPointInUnitDisk() { var p = 2f * new Vector3(Random.Get(), Random.Get(), 0) - new Vector3(1, 1, 0); return(p.Normalized() * Random.Get()); }
public static LightSource GetRandom() => lights[(int)(Random.Get() * (lights.Count - 0.1f))];
public Vector3 GetRandomPointInUnitSphere() { var p = new Vector3(Random.Get(), Random.Get(), Random.Get()) * 2f - Vector3.one; return(p.Normalized() * Random.Get()); }