예제 #1
0
        Vec3 Color(Ray r, Hitable world, int depth)
        {
            HitRecord rec = new HitRecord();

            if (depth > maxDepth)
            {
                return(depthColor);
            }

            if (!world.hit(r, 0.001, double.MaxValue, ref rec))
            {
                return(backgroundColor);
            }

            Vec3 reflectDir;
            Vec3 reflectColor;
            Vec3 refractDir;
            Vec3 refractColor;

            reflectDir   = Vec3.unitVector(Vec3.reflect(r.b, rec.normal));
            reflectColor = Color(new Ray(rec.p, reflectDir), world, depth + 1);

            refractDir = new Vec3();

            if (Vec3.refract(r.b, rec.normal, rec.material.ref_idx, ref refractDir))
            {
                refractDir = Vec3.unitVector(refractDir);
            }

            refractColor = Color(new Ray(rec.p, refractDir), world, depth + 1);

            double diffuseLightIntensity  = ambientLight;
            double specularLightIntensity = 0;

            for (int i = 0; i < lights.Count; i++)
            {
                Vec3      lightDir   = Vec3.unitVector(lights[i].position - rec.p);
                double    lightDist  = (lights[i].position - rec.p).length();
                Vec3      shadowOrig = rec.p;
                HitRecord shadowRec  = new HitRecord();

                if (world.hit(new Ray(shadowOrig, lightDir), 0.001, double.MaxValue, ref shadowRec) && (shadowRec.p - shadowOrig).length() < lightDist)
                {
                    continue;
                }

                diffuseLightIntensity  += lights[i].intensity * Math.Max(0.0, Vec3.dot(lightDir, rec.normal));
                specularLightIntensity += Math.Pow(Math.Max(0.0, Vec3.dot(-Vec3.reflect(-lightDir, rec.normal), r.b)), rec.material.specularExponent) * lights[i].intensity;
            }

            return(rec.material.diffuseColor * diffuseLightIntensity * rec.material.a0 + new Vec3(1, 1, 1) * specularLightIntensity * rec.material.a1 + reflectColor * rec.material.a2 + refractColor * rec.material.a3);
        }
예제 #2
0
    Color color(zRay r, Hitable world, int depth)
    {
        hit_record rec = new hit_record();

        if (world.hit(r, 0.0f, float.MaxValue, ref rec))
        {
            zRay    scattered   = new zRay();
            Vector3 attenuation = Vector3.zero;
            Color   emitted     = rec.mat.emitted();
            if (depth < maxDepth && rec.mat.scatter(r, rec, ref attenuation, ref scattered))
            {
                return(emitted + new Color(attenuation.x, attenuation.y, attenuation.z) * color(scattered, world, depth + 1));
            }
            else
            {
                return(emitted);
            }
        }
        else
        {
            //float t = 0.5f * (r.direction.normalized.y + 1f);
            //return (1f - t) * Color.white + t * new Color(0.5f, 0.7f, 1.0f);
            return(env_Color);
        }
    }
예제 #3
0
 public override bool hit(zRay r, float t_min, float t_max, ref hit_record rec)
 {
     if (box.hit(r, t_min, t_max))
     {
         hit_record left_rec = new hit_record(), right_rec = new hit_record();
         bool       hit_left  = left.hit(r, t_min, t_max, ref left_rec);
         bool       hit_right = right.hit(r, t_min, t_max, ref right_rec);
         if (hit_left && hit_right)
         {
             if (left_rec.t < right_rec.t)
             {
                 rec = left_rec;
             }
             else
             {
                 rec = right_rec;
             }
             return(true);
         }
         else if (hit_left)
         {
             rec = left_rec;
             return(true);
         }
         else if (hit_right)
         {
             rec = right_rec;
             return(true);
         }
         else
         {
             return(false);
         }
     }
     else
     {
         return(false);
     }
 }
예제 #4
0
        public bool hit(Ray r, double tMin, double tMax, ref HitRecord rec)
        {
            if (box.hit(r, tMin, tMax))
            {
                HitRecord leftRec   = new HitRecord();
                HitRecord rightRec  = new HitRecord();
                bool      hit_left  = left.hit(r, tMin, tMax, ref leftRec);
                bool      hit_right = right.hit(r, tMin, tMax, ref rightRec);

                if (hit_left && hit_right)
                {
                    if (leftRec.t < rightRec.t)
                    {
                        rec = leftRec;
                    }
                    else
                    {
                        rec = rightRec;
                    }

                    return(true);
                }
                else
                {
                    if (hit_left)
                    {
                        rec = leftRec;
                        return(true);
                    }
                    else if (hit_right)
                    {
                        rec = rightRec;
                        return(true);
                    }
                }
            }

            return(false);
        }