Пример #1
0
        public double3 RefractRay(Scene scene, Traceable traceable,
                                  IntersectData data, Ray ray, TraceData traceData,
                                  double3 n, double nDotRay,
                                  RefractionIndex refractionIndex, out bool traceDataExceed)
        {
            traceDataExceed = false;
            double criticalAngleCos = nDotRay <= 0 ? refractionIndex.CriticalInAngleCos : refractionIndex.CriticalOutAngleCos;

            if (Math.Abs(nDotRay) >= criticalAngleCos)
            {
                if (traceData.Refractions > 0)
                {
                    double  k            = nDotRay <= 0 ? refractionIndex.CoefficientIn : refractionIndex.CoefficientOut;
                    double3 f            = ray.l.RefractI(n, nDotRay, k);
                    double3 p            = traceable.Advance(data.P, f);
                    Ray     refractedRay = new Ray(p, f);
                    traceData = traceData.GetRefracted();
                    double3 color = scene.Trace(refractedRay, traceData);

                    return(RefractionAttenuation * color);
                }
                else
                {
                    TraceData.RefractionLimitExceedCount++;
                    traceDataExceed = true;

                    return(TraceData.RefractionLimitExceedColor);
                }
            }
            else
            {
                if (traceData.Reflections > 0)
                {
                    double3 r            = ray.l.ReflectI(n, nDotRay);
                    double3 p            = traceable.Advance(data.P, r);
                    Ray     reflectedRay = new Ray(p, r);
                    traceData = traceData.GetReflected();
                    double3 color = scene.Trace(reflectedRay, traceData);

                    return(RefractionAttenuation * color);
                }
                else
                {
                    TraceData.ReflectionLimitExceedCount++;
                    traceDataExceed = true;

                    return(TraceData.ReflectionLimitExceedColor);
                }
            }
        }
        public override double3 CalculateColor(Scene scene, Traceable traceable,
                                               IntersectData data, Ray ray, TraceData traceData)
        {
            double3 n                = traceable.GetNormal(data);
            double  nDotRay          = n & ray.l;
            double  criticalAngleCos = nDotRay <= 0 ? RefractionIndex.CriticalInAngleCos : RefractionIndex.CriticalOutAngleCos;

            if (Math.Abs(nDotRay) >= criticalAngleCos)
            {
                if (traceData.Refractions > 0)
                {
                    double  k            = nDotRay <= 0 ? RefractionIndex.CoefficientIn : RefractionIndex.CoefficientOut;
                    double3 f            = ray.l.RefractI(n, nDotRay, k);
                    double3 p            = traceable.Advance(data.P, f);
                    Ray     refractedRay = new Ray(p, f);
                    traceData = traceData.GetRefracted();
                    double3 color = scene.Trace(refractedRay, traceData);

                    return(RefractionAttenuation * color);
                }
                else
                {
                    TraceData.RefractionLimitExceedCount++;

                    return(TraceData.RefractionLimitExceedCount);
                }
            }
            else
            {
                if (traceData.Reflections > 0)
                {
                    double3 r            = ray.l.ReflectI(n, nDotRay);
                    double3 p            = traceable.Advance(data.P, r);
                    Ray     reflectedRay = new Ray(p, r);
                    traceData = traceData.GetReflected();
                    double3 color = scene.Trace(reflectedRay, traceData);

                    return(RefractionAttenuation * color);
                }
                else
                {
                    TraceData.ReflectionLimitExceedCount++;

                    return(TraceData.ReflectionLimitExceedColor);
                }
            }
        }
Пример #3
0
        public override double3 CalculateColor(Scene scene, Traceable traceable,
                                               IntersectData data, Ray ray, TraceData traceData)
        {
            double3 resultColor = double3.Zero;
            double3 n           = traceable.GetNormal(data);

            foreach (SpotLight light in scene.Lights)
            {
                double3 l        = light.Pos - data.P;
                double  distance = l.Length;
                l = l.Normalized;
                double nDotL = n & l;

                if (nDotL <= 0)
                {
                    continue;
                }

                double shadowEdgeAttenuation = 1;

                List <IntersectData> shadowIsecs = scene.Intersect(new Ray(traceable.Advance(data.P, l), l));

                if (shadowIsecs.Count > 0)
                {
                    IntersectData obstacleIsecData = shadowIsecs.OrderBy(shadowIsecData => (shadowIsecData.P - data.P).Length).First();

                    if ((obstacleIsecData.P - data.P).Length < distance)
                    {
                        double3 obstacleL = light.Pos - obstacleIsecData.P;
                        obstacleL = obstacleL.Normalized;
                        double3 obstacleN = obstacleIsecData.Object.GetNormal(obstacleIsecData);
                        double3 obstacleR = l.ReflectI(obstacleN);

                        shadowEdgeAttenuation = obstacleR & obstacleL;

                        if (shadowEdgeAttenuation <= 0)
                        {
                            continue;
                        }

                        shadowEdgeAttenuation = Math.Pow(shadowEdgeAttenuation, 3);
                    }
                }

                double3 diffuse = BaseColor ^ light.DiffuseColor * nDotL;

                double3 r        = l.Reflect(n, nDotL);
                double  rDotV    = Math.Max(0, (-ray.l) & r);
                double3 specular = Math.Pow(rDotV, SpecularPower) * light.SpecularColor;

                double attenuation = Math.Log(distance + light.AttenuationBase, light.AttenuationBase);

                resultColor += (diffuse + specular) * shadowEdgeAttenuation / attenuation;
            }

            return(resultColor + scene.AmbientColor);
        }
        public override double3 CalculateColor(Scene scene, Traceable traceable,
                                               IntersectData data, Ray ray, TraceData traceData)
        {
            if (traceData.Reflections > 0)
            {
                double3 n = traceable.GetNormal(data);
                double3 r = ray.l.ReflectI(n);
                double3 p = traceable.Advance(data.P, r);

                return(ReflectionAttenuation * scene.Trace(new Ray(p, r), traceData.GetReflected()));
            }
            else
            {
                TraceData.ReflectionLimitExceedCount++;

                return(TraceData.ReflectionLimitExceedColor);
            }
        }