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);
        }
Beispiel #2
0
        public override double3 CalculateColor(Scene scene, Traceable traceable,
                                               IntersectData data, Ray ray, TraceData traceData)
        {
            double3        n = traceable.GetNormal(data);
            double         nDotRay = n & ray.l;
            bool           traceLimitExceed = false;
            double         red = 0, green = 0, blue = 0;
            ColorComponent?chroma = null;

            if (traceData.Properties.ContainsKey(RefractiveDispersiveMaterialProperties.Chroma))
            {
                chroma = ( ColorComponent )traceData.Properties [RefractiveDispersiveMaterialProperties.Chroma];
            }

            if (!chroma.HasValue || chroma == ColorComponent.Red)
            {
                red = RefractRay(scene, traceable, data, ray, new TraceData(traceData, RefractiveDispersiveMaterialProperties.Chroma, ColorComponent.Red),
                                 n, nDotRay, RedRefractionIndex, out traceLimitExceed).r;
            }

            if (traceLimitExceed)
            {
                red = 0;
            }

            if (!chroma.HasValue || chroma == ColorComponent.Green)
            {
                green = RefractRay(scene, traceable, data, ray, new TraceData(traceData, RefractiveDispersiveMaterialProperties.Chroma, ColorComponent.Green),
                                   n, nDotRay, GreenRefractionIndex, out traceLimitExceed).g;
            }

            if (traceLimitExceed)
            {
                green = 0;
            }

            if (!chroma.HasValue || chroma == ColorComponent.Blue)
            {
                blue = RefractRay(scene, traceable, data, ray, new TraceData(traceData, RefractiveDispersiveMaterialProperties.Chroma, ColorComponent.Blue),
                                  n, nDotRay, BlueRefractionIndex, out traceLimitExceed).b;
            }

            if (traceLimitExceed)
            {
                blue = 0;
            }

            double3 color = new double3(red, green, blue);

            return(color);
        }
        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);
                }
            }
        }
        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);
            }
        }
Beispiel #5
0
        public virtual double3 CalculateColor(Scene scene, Traceable traceable,
                                              IntersectData data, Ray ray, TraceData traceData)
        {
            return(traceable.GetNormal(data));
            //return	new double3 ( traceable.GetTexCoord ( data ), 1 );

            //// <Checker>
            //double2 texCoord = traceable.GetTexCoord ( data );
            //texCoord *= 20;
            //double3 evenColor = new double3 ( 0.8, 0.8, 0.8 );
            //double3 oddColor = new double3 ( 0.2, 0.2, 0.2 );

            //int x = ( int ) texCoord.x;
            //int y = ( int ) texCoord.y;
            //bool xIsEven = x % 2 == 0;
            //bool yIsEven = y % 2 == 0;

            //if ( xIsEven == yIsEven )
            //    return	evenColor;
            //else
            //    return	oddColor;
            //// </Checker>
        }