Пример #1
0
 public Material()
 {
     Properties = new ShadingInfos
     {
         Ambient = DEFAULT_AMBIENT,
     };
 }
Пример #2
0
        private RTColor Shading(LocalGeo geo, ShadingInfos si, Ray camRay, Ray lightRay, RTColor lightCol)
        {
            float   nDotL   = RTVector.DotProduct(geo.Normal, lightRay.Vector);
            RTColor lambert = lightCol * si.Diffuse * (nDotL > 0 ? nDotL : 0.0f);

            RTVector half  = (lightRay.Vector - camRay.Vector.Normalize()).Normalize();
            float    nDotH = RTVector.DotProduct(geo.Normal, half);
            RTColor  phong = lightCol * si.Specular * (float)Math.Pow((nDotH > 0 ? nDotH : 0.0f), si.Shininess);

            float   r   = lightRay.Directional ? 0 : lightRay.TMax; // Dans le cas d'un point, le t max est la distance entre le point et la source
            RTColor res = (lambert + phong) / (Attenuation.Constant + Attenuation.Linear * r + Attenuation.Quadratic * (float)Math.Pow(r, 2));

            return(res);
        }
Пример #3
0
        public RTColor Trace(Ray ray, int depth)
        {
            RTColor res = new RTColor();

            float lastT = float.MaxValue;
            bool  shadow;

            // TODO: initialiser l'arbre autrepart
            // TODO: corriger la bounding box des spheres
            if (_tree == null)
            {
                _tree = new BBTree(Primitives);
            }
            IEnumerable <HitResult> hits = _tree.Hit(ray);

            //IList<HitResult> hits = Primitives.Select(p =>
            //{
            //    if (p.Intersect(ray, true, out LocalGeo geo, out float t))
            //    {
            //        return new HitResult { Primitive = p, Geo = geo, T = t };
            //    }

            //    return null;
            //}).Where(h => h != null).ToList();

            foreach (HitResult h in hits)
            {
                if (h.T < lastT)
                {
                    lastT = h.T;

                    ShadingInfos si = h.Primitive.GetShading(h.Geo);

                    // Ambient & emission
                    res = si.Emission + si.Ambient;

                    // Phong shading
                    foreach (ILight light in Lights)
                    {
                        shadow = false;
                        RTColor lightCol;
                        Ray     lightRay = light.GenerateRay(h.Geo, out lightCol);

                        foreach (IPrimitive pShadow in Primitives)
                        {
                            if (pShadow.Intersect(lightRay, false, out _, out _))
                            {
                                shadow = true;
                            }
                        }

                        if (!shadow)
                        {
                            res += Shading(h.Geo, si, ray, lightRay, lightCol);
                        }
                    }

                    // Reflection
                    if ((si.Specular.Red > 0 || si.Specular.Green > 0 || si.Specular.Blue > 0) && depth < MaxDepth)
                    {
                        Ray reflected = new Ray(h.Geo.Point, ray.Vector - 2.0f * RTVector.DotProduct(ray.Vector, h.Geo.Normal) * h.Geo.Normal, 1e-3f, float.MaxValue, false);
                        res += si.Specular * Trace(reflected, depth + 1);
                    }
                }
            }

            return(res);
        }