Ejemplo n.º 1
0
        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);
        }