Color[] CreateColorForTestAntialiasing(int width, int height) { //视锥体的左下角、长宽和起始扫射点设定 Vector3 lowLeftCorner = new Vector3(-2, -1, -1); Vector3 horizontal = new Vector3(4, 0, 0); Vector3 vertical = new Vector3(0, 2, 0); Vector3 original = new Vector3(0, 0, 0); int l = width * height; HitableList hitableList = new HitableList(); hitableList.list.Add(new SimpleSphere(new Vector3(0, 0, -1), 0.5f)); hitableList.list.Add(new SimpleSphere(new Vector3(0, -100.5f, -1), 100f)); Color[] colors = new Color[l]; SimpleCamera camera = new SimpleCamera(original, lowLeftCorner, horizontal, vertical); float recip_width = 1f / width; float recip_height = 1f / height; for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { Color color = new Color(0, 0, 0); for (int s = 0; s < SAMPLE; s++) { Ray r = camera.CreateRay((i + _M.R()) * recip_width, (j + _M.R()) * recip_height); color += GetColorForTestAntialiasing(r, hitableList); } color *= SAMPLE_WEIGHT; color.a = 1f; colors[i + j * width] = color; } } return(colors); }
Color[] CreateColorForTestMetal(int width, int height) { //视锥体的左下角、长宽和起始扫射点设定 Vector3 lowLeftCorner = new Vector3(-4, -1, -1); Vector3 horizontal = new Vector3(8, 0, 0); Vector3 vertical = new Vector3(0, 2, 0); Vector3 original = new Vector3(0, 0, 0); int l = width * height; HitableList hitableList = new HitableList(); hitableList.list.Add(new Sphere(new Vector3(0, 0, -1), 0.5f, new Lambertian(new Color(0.3f, 0.3f, 0.3f)))); hitableList.list.Add(new Sphere(new Vector3(0, -100.5f, -1), 100f, new Lambertian(new Color(0.8f, 0.8f, 0.0f)))); hitableList.list.Add(new Sphere(new Vector3(-1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.8f, 0.8f), 0.3f))); //Metal 的带个参数是albedo 反照率 hitableList.list.Add(new Sphere(new Vector3(1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.8f, 0.8f), 0.0f))); // 设置fuzz为0 表示一个干净的镜面 Color[] colors = new Color[l]; //之前的视觉锥体变形比较厉害 现在把摄像机离远一点 //右手坐标系 屏幕的z轴是 -1 SimpleCamera camera = new SimpleCamera(original + new Vector3(0, 0, 3), lowLeftCorner, horizontal, vertical); float recip_width = 1f / width; float recip_height = 1f / height; // Debug.LogFormat("Hitable discriminant {0} {1}", recip_width, recip_height); for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { if (i % 10 == 0 && j % 10 == 0) { Debug.LogFormat("r u v {0} {1} {2} {3}", i, j, (i + _M.R()) * recip_width, (j + _M.R()) * recip_height); } Color color = new Color(0, 0, 0); for (int s = 0; s < SAMPLE / 10; s++) { // 光线的出发点就是摄像机 // (i + _M.R()) * recip_width 都是小范围发散光线 Ray r = camera.CreateRay((i + _M.R()) * recip_width, (j + _M.R()) * recip_height); color += GetColorForTestMetal(r, hitableList, 0); } color *= SAMPLE_WEIGHT * 10f; //为了使球体看起来更亮,改变gamma值 color = new Color(Mathf.Sqrt(color.r), Mathf.Sqrt(color.g), Mathf.Sqrt(color.b), 1f); color.a = 1f; colors[i + j * width] = color; } } return(colors); }
// 测试透明模型 // 传统右手坐标系 Z值越小 离人眼越近 // 之前调整参数 光源在 0 0 3 的位置 // 屏幕Z轴在 -3 的位置 Color[] CreateColorForTestDielectric(int width, int height) { // 透明材料(例如水,玻璃和钻石)是电介质。 当光线射到它们上时,它分裂为反射射线和折射(透射)射线。 //视锥体的左下角、长宽和起始扫射点设定 Vector3 lowLeftCorner = new Vector3(-2, -1, -3); Vector3 horizontal = new Vector3(4, 0, 0); Vector3 vertical = new Vector3(0, 2, 0); Vector3 original = new Vector3(0, 0, 0); int l = width * height; HitableList hitableList = new HitableList(); // 漫反射 中间的红色金属球 hitableList.list.Add(new Sphere(new Vector3(0, 0, -1), 0.5f, new Lambertian(new Color(0.8f, 0.3f, 0.3f)))); // 漫反射 //底部的绿色球 hitableList.list.Add(new Sphere(new Vector3(0, -100.5f, -1), 100f, new Lambertian(new Color(0.8f, 0.8f, 0.0f)))); // 右侧的金属球 hitableList.list.Add(new Sphere(new Vector3(1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.6f, 0.2f), 0f))); // 左侧透明球 hitableList.list.Add(new Sphere(new Vector3(-1, 0, -1), 0.5f, new Dielectirc(1.5f))); // 1.3 是水的折射率 玻璃折射率是1.5 Color[] colors = new Color[l]; // 为了减小形变 让摄像头离屏幕远一点 SimpleCamera camera = new SimpleCamera(original + new Vector3(0, 0, 3), lowLeftCorner, horizontal, vertical); float recip_width = 1f / width; float recip_height = 1f / height; for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { Color color = new Color(0, 0, 0); for (int s = 0; s < SAMPLE / 10; s++) { Ray r = camera.CreateRay((i + _M.R()) * recip_width, (j + _M.R()) * recip_height); color += GetColorForTestDielectric(r, hitableList, 0); } color *= SAMPLE_WEIGHT * 10f; //为了使球体看起来更亮,改变gamma值 color = new Color(Mathf.Sqrt(color.r), Mathf.Sqrt(color.g), Mathf.Sqrt(color.b), 1f); color.a = 1f; colors[i + j * width] = color; } } return(colors); }
Color[] CreateColorForTestAntialiasing(int width, int height) { // width height 是像素点单位400 200 // 视锥体的左下角、长宽和起始扫射点设定 Vector3 lowLeftCorner = new Vector3(-2, -1, -1); Vector3 horizontal = new Vector3(4, 0, 0); Vector3 vertical = new Vector3(0, 2, 0); Vector3 original = new Vector3(0, 0, 0); int l = width * height; HitableList hitableList = new HitableList(); //这样的球在偏右的位置 //hitableList.list.Add(new SimpleSphere(new Vector3(1, 0, -1), 0.5f)); hitableList.list.Add(new SimpleSphere(new Vector3(0, 0, -1), 0.5f)); hitableList.list.Add(new SimpleSphere(new Vector3(0, -100.5f, -1), 100f)); Color[] colors = new Color[l]; // 摄像头在0 0 0的位置 // 屏幕在 z轴 -1 的位置 // 传统的右手坐标系 SimpleCamera camera = new SimpleCamera(original + new Vector3(0, 0, 3), lowLeftCorner, horizontal, vertical); float recip_width = 1f / width; // 1/400 float recip_height = 1f / height; // 1/200 for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { Color color = new Color(0, 0, 0); // 每个像素点都再发射100条光线去采样计算 for (int s = 0; s < SAMPLE / 10; s++) { // _M.R() 生成0~1随机数 // 创建的ray 出发点在球心 也就是original //注意 !! CreateRay包含了vertical 和 horizontal 的尺寸计算 Ray r = camera.CreateRay((i + _M.R()) * recip_width, (j + _M.R()) * recip_height); //下面关闭抗锯齿的情形,就和第5版一样的 //Ray r = camera.CreateRay(i * recip_width, j * recip_height); color += GetColorForTestAntialiasing(r, hitableList); } color *= SAMPLE_WEIGHT * 10; color.a = 1f; colors[i + j * width] = color; } } return(colors); }
Color[] CreateColorForTestDielectric(int width, int height) { //视锥体的左下角、长宽和起始扫射点设定 Vector3 lowLeftCorner = new Vector3(-2, -1, -1); Vector3 horizontal = new Vector3(4, 0, 0); Vector3 vertical = new Vector3(0, 2, 0); Vector3 original = new Vector3(0, 0, 0); int l = width * height; HitableList hitableList = new HitableList(); hitableList.list.Add(new Sphere(new Vector3(0, 0, -1), 0.5f, new Lambertian(new Color(0.8f, 0.3f, 0.3f)))); hitableList.list.Add(new Sphere(new Vector3(0, -100.5f, -1), 100f, new Lambertian(new Color(0.8f, 0.8f, 0.0f)))); hitableList.list.Add(new Sphere(new Vector3(1, 0, -1), 0.5f, new Metal(new Color(0.8f, 0.6f, 0.2f), 0f))); hitableList.list.Add(new Sphere(new Vector3(-1, 0, -1), 0.5f, new Dielectirc(1.5f))); Color[] colors = new Color[l]; SimpleCamera camera = new SimpleCamera(original, lowLeftCorner, horizontal, vertical); float recip_width = 1f / width; float recip_height = 1f / height; for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { Color color = new Color(0, 0, 0); for (int s = 0; s < SAMPLE; s++) { Ray r = camera.CreateRay((i + _M.R()) * recip_width, (j + _M.R()) * recip_height); color += GetColorForTestDielectric(r, hitableList, 0); } color *= SAMPLE_WEIGHT; //为了使球体看起来更亮,改变gamma值 color = new Color(Mathf.Sqrt(color.r), Mathf.Sqrt(color.g), Mathf.Sqrt(color.b), 1f); color.a = 1f; colors[i + j * width] = color; } } return(colors); }