public Color4 Render() { if (first) { float inertT = Scene.scene.Intersect(this, ref interTG, ref normal, ref interColor); interPos = origin + dir * inertT; // 交点坐标 first = false; } if (interTG == null) { return(Scene.AmbientColor); } Material mat = interTG.Material; if (mat.Surface == Surface.EMISSION) { return(interColor); } if (reflectNum > 0) { if (mat.Surface == Surface.DIFFUSE) // 漫反射 //if (interColor.ReflectRatio < 0.1f) { // return interColor; //} { if (Vector3.rand.NextDouble() < interColor.ReflectRatio * 3) // 反射率小的时候就降低渲染概率,比如纯黑的墙壁 { Ray diffRay = new Ray(interPos, Vector3.RandInUnitHemisphere(normal), reflectNum - 1); // 每次都不一样,局部变量 Color4 color4 = diffRay.Render(); if (color4.L > 0f) { reflColorSum += color4; reflColorNum++; reflColor = reflColorSum / reflColorNum; color = Color4.Mix(interColor, reflColor); } } } else if (mat.Surface == Surface.SPECULAR) // 镜面反射 { if (reflRay == null) { reflRay = new Ray(interPos, Vector3.Reflect(dir, normal), reflectNum - 1); } reflColor = reflRay.Render(); if (mat.RefrRatio > 0f) // 折射 { if (refrRay == null && fresnel != 1f) { if (Vector3.Refract(dir, normal, mat.RefrRatio, out Vector3 refrect)) { refrRay = new Ray(interPos, refrect, reflectNum - 1); fresnel = 1f - Mathf.Abs(dir * normal); } else { fresnel = 1f; // 全反射 } } if (refrRay != null) { refrColor = refrRay.Render(); color = Color4.Mix(interColor, reflColor * fresnel + refrColor * (1 - fresnel)); } else { color = Color4.Mix(interColor, reflColor); } } else { color = Color4.Mix(interColor, reflColor); } } } else { return(interColor); } return(color); }