private void btnTest_Click(object sender, EventArgs e) { //观察点位置 Point3D eye = new Point3D(0, 0, 0); //用于做显示的bmp--- Bitmap bmp = new Bitmap(200, 100); world = new World(); Random r = new Random(); //小球 Sphere sphere = new Sphere(new Point3D(0, 0, -1), 0.5);//球体位置 sphere.GloMaterial = new Lambert(new SColor(0.8, 0.3, 0.3)); world.AddGeoObj(sphere); //小球 Sphere sphere2 = new Sphere(new Point3D(1, 0, -1), 0.5);//球体位置 sphere2.GloMaterial = new Metal(new SColor(0.8, 0.6, 0.2), 0.5); world.AddGeoObj(sphere2); //小球 Sphere sphere3 = new Sphere(new Point3D(-1, 0, -1), 0.5);//球体位置 sphere3.GloMaterial = new Dielectrics(1.5); //sphere3.GloMaterial = new Metal(new SColor(0.8, 0.8, 0.8),0.5); world.AddGeoObj(sphere3); //底部大球 Sphere sphere4 = new Sphere(new Point3D(0, -100.5, -1), 100);//球体位置 sphere4.GloMaterial = new Lambert(new SColor(0.8, 0.8, 0.0)); world.AddGeoObj(sphere4); double step = 0.02; //采样点数量 int sp = 100; Point3D p; Vector3D dir; for (int i = 0; i < 200; i++) { for (int j = 0; j < 100; j++) { //颜色 SColor clr = new SColor(0, 0, 0); //随机采样 for (int s = 0; s < sp; s++) { //成像平面上的每个点的位置 p = new Point3D(-2 + step * (i + random()), 1 - step * (j + random()), -1); //起始光线的方向 dir = p - eye; dir.Normalize(); Ray primaryRay = new Ray(eye, dir); int depth = 0; //渲染。。。 clr += Render(primaryRay, depth); } // clr *= 1.0 / sp; clr = new SColor(Math.Sqrt(clr.R), Math.Sqrt(clr.G), Math.Sqrt(clr.B)); //渲染到bmp bmp.SetPixel(i, j, clr.GetRGB255Color()); } } picRt.BackgroundImage = bmp; }
public void Render() { //观察点 Point3D eye = new Point3D(0, 0, 4); World world = new World(); world.Bulid(); //环境光 SColor Ia = new SColor(1, 1, 1); Light light = new Light(); light.Lightcolor = new SColor(1, 1, 1); //光源亮度 light.Position = new Point3D(3, 2, 2); //光源 int hRes = 800; int vRes = 400; double hOffset = 4.0 / hRes; double vOffset = 2.0 / vRes; Bitmap bmp = new Bitmap(hRes, vRes); for (int i = 0; i < hRes; i++) { for (int j = 0; j < vRes; j++) { //成像平面上的每个点 Point3D p = new Point3D(-2 + i * hOffset, 1 - j * vOffset, 2); Vector3D dir = p - eye; Ray primaryRay = new Ray(eye, dir); ShadeRec sr;//击中点的记录 //求最近的交点信息 sr = world.HitAll(primaryRay); if (sr != null) { //交点到光源 Vector3D rayLight = light.Position - sr.Hitpoint; rayLight.Normalize(); Ray shadowRay = new Ray(sr.Hitpoint, rayLight); if (!world.ShadowHitAll(shadowRay)) { //bool isHit = sphere.Hit(primaryRay,sr); Vector3D L = light.Position - sr.Hitpoint;//入射光 L.Normalize(); //计算R:反射单位矢量 Vector3D R = 2.0 * (sr.Normal * L) * sr.Normal - L; R.Normalize(); Vector3D V = eye - sr.Hitpoint; V.Normalize(); double LN = L * sr.Normal; double VR = V * R; if (LN <= 0) { LN = 0; } if (VR <= 0) { VR = 0; } //环境光+Lambert漫反射+Phong镜面反射 //SColor Idiffuse = Ia * ka + Id * Kd * LN; //SColor Idiffuse = sphere.Mat.Matcolor * ka + Id * sphere.Mat.Kd * LN + Id * sphere.Mat.Ks * Math.Pow(VR, sphere.Mat.Ns); SColor Idiffuse = Ia * sr.HitObjMat.Ka + light.Lightcolor * sr.HitObjMat.Kd * LN + light.Lightcolor * sr.HitObjMat.Ks * Math.Pow(VR, sr.HitObjMat.Ns); SColor color = Idiffuse * sr.HitObjMat.Matcolor; //bmp.SetPixel(i, j, Idiffuse.GetRGB255Color()); double theta = Math.PI * trackBar1.Value / 180.0; double x = sr.Hitpoint.X * Math.Cos(theta) + sr.Hitpoint.Z * Math.Sin(theta); double z = -sr.Hitpoint.X * Math.Sin(theta) + sr.Hitpoint.Z * Math.Cos(theta); if (sr.HitObjMat.IsTexture) { sr.Hitpoint.X = x; sr.Hitpoint.Z = z; //纹理颜色 Color textureColor = texture.getColor(sr); //光照颜色 Color lightColor = color.GetRGB255Color(); //融合权重 double t = 0.7; //融合 Color blendColor = Color.FromArgb( (int)(textureColor.R * t + lightColor.R * (1 - t)), (int)(textureColor.G * t + lightColor.G * (1 - t)), (int)(textureColor.B * t + lightColor.B * (1 - t)) ); /*Color blendColor = Color.FromArgb( * (int)(textureColor.R * (lightColor.R /255 ), * (int)(textureColor.G * (lightColor.G /255 )), * (int)(textureColor.B * (lightColor.B /255 )) * );*/ bmp.SetPixel(i, j, blendColor); } else { bmp.SetPixel(i, j, color.GetRGB255Color()); } } else { bmp.SetPixel(i, j, Color.Black); } } else { bmp.SetPixel(i, j, Color.FromArgb(81, 74, 88)); } } } pic1.BackgroundImage = bmp; }