예제 #1
0
 protected virtual NearestIntersection GetIntersections(ColoredRay3D ray)
 {
     NearestIntersection intersections = new NearestIntersection();
     ray.End = ray.Start + (ray.End - ray.Start).Normalize();
     scene.Objects.GetIntersections(ray, intersections);
     return intersections;
 }
예제 #2
0
        protected override void Render(REScene scene, Camera3D camera, Canvas canvas)
        {
            double d = 2 * camera.FocusDistance * System.Math.Tan(camera.FOV / 2);
            double h = d / System.Math.Sqrt(camera.Ratio * camera.Ratio + 1);
            double w = h * camera.Ratio;

            double hFOV = 2 * System.Math.Atan(w / (2 * camera.FocusDistance));
            double vFOV = 2 * System.Math.Atan(h / (2 * camera.FocusDistance));

            double alpha0 = -hFOV / 2;
            double beta0 = -vFOV / 2;
            double dAlpha = hFOV / canvas.Width;
            double dBeta = vFOV / canvas.Height;

            double alpha = alpha0, beta = beta0;

            var ray = new ColoredRay3D();
            var dirZ = (float)camera.FocusDistance;
            for (int cy = 0; cy < canvas.Height; cy++) {
                var dirY = (float)(System.Math.Tan(beta) * camera.FocusDistance);
                for (int cx = 0; cx < canvas.Width; cx++) {
                    var dirX = (float)(System.Math.Tan(alpha) * camera.FocusDistance);

                    ray.Color = new PreciseColor(1.0f, 1.0f, 1.0f);
                    ray.Start = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z - (float)camera.FocusDistance);
                    ray.End = ray.Start + new Vector3D(dirX, dirY, dirZ);
                    PreciseColor color = ProcessRay(ray, scene, 0);
                    canvas[cx, cy] += color;
                    alpha += dAlpha;
                }
                alpha = alpha0;
                beta += dBeta;
            }
        }
예제 #3
0
        protected virtual PreciseColor ProcessRay(ColoredRay3D ray, REScene scene, int level)
        {
            NearestIntersection intersections = GetIntersections(ray, scene);
            var color = new PreciseColor();
            Vector3D dir = (ray.End - ray.Start).Normalize();
            Intersection intersection = intersections.Get();
            if (intersection != null) {
                if (intersection.Length > 0.05) {
                    Material material = intersection.Shape3D.Material;
                    color += material.DiffuseColor * material.AmbientIntensity;
                    RayTracingOptions options = GetRayTracingOptions(intersection.Shape3D);
                    if ((options & RayTracingOptions.Diffuse) > 0) {
                        color += GetDiffuseIllumination(intersection, scene);
                    }
                    if ((options & RayTracingOptions.Speculate) > 0) {

                        if (level < 5 && material.Shininess > 0.001) {
                            var reflected = ray;
                            Vector3D reflectedStart = ray.Start + dir * intersection.Length;
                            Vector3D reflectedEnd = reflectedStart + Math3D.GetReflectedVector(dir, intersection.Normal);
                            reflected.Start = reflectedStart;
                            reflected.End = reflectedEnd;
                            color += ProcessRay(reflected, scene, level + 1) * material.Shininess;
                        }
                    }
                }
            }
            return color;
        }
예제 #4
0
        public override PreciseColor GetDiffuseIllumination(Intersection intersection)
        {
            Material material = intersection.Shape3D.Material;
            Vector3D dir = position - intersection.Point;

            float distance = dir.Length;

            var ray = new ColoredRay3D { Start = intersection.Point, End = position };
            NearestIntersection intersections = GetIntersections(ray);
            bool shadowed = false;
            Intersection obstacle = intersections.Get();
            if (obstacle != null && obstacle.Length > 0.05 && obstacle.Length < distance) {
                shadowed = true;
            }

            if (!shadowed) {
                var diffuseColor = new PreciseColor(omni.Color.Red * material.DiffuseColor.Red,
                                            omni.Color.Green * material.DiffuseColor.Green,
                                            omni.Color.Blue * material.DiffuseColor.Blue);
                float diffuseIntensity = omni.Power * (1 - material.Shininess) * System.Math.Abs(Vector3D.Scalar(dir.Normalize(), intersection.Normal));
                diffuseIntensity /= dir.Length * dir.Length;

                Vector3D reflected = Math3D.GetReflectedVector((intersection.Point - position).Normalize(), intersection.Normal);
                float cosTeta = Vector3D.Scalar(reflected, (intersection.Ray.Start - intersection.Ray.End).Normalize());
                float specularIntensity = cosTeta < 0 ? 0 : omni.Power * material.Shininess * (float)System.Math.Pow(cosTeta, 200);
                if (intersection.Shape3D is RESphere) {
                    specularIntensity /= material.Shininess;
                }
                specularIntensity *= 0.05f;

                return diffuseColor * diffuseIntensity + material.SpecularColor * specularIntensity;
            }
            return new PreciseColor();
        }
예제 #5
0
 protected override void Render(REScene scene, Camera3D camera, Canvas canvas)
 {
     foreach (REBaseLight lightSource in scene.Lights) {
         var start = lightSource.Origin.CoordinateSystem.Position;
         var dir = new Vector3D(
             (float)(_rnd.NextDouble() * 2 - 1),
             (float)(_rnd.NextDouble() * 2 - 1),
             (float)(_rnd.NextDouble() * 2 - 1)
         ).Normalize();
         var ray = new ColoredRay3D {
             Color = new PreciseColor(1, 1, 1),
             Start = start,
             End = start + dir
         };
         ProcessRay(ray, scene, 0);
     }
 }
예제 #6
0
 public override void GetIntersections(ColoredRay3D ray, NearestIntersection intersections) {
     rectangle.GetIntersections(ray, intersections);
 }
예제 #7
0
 public override void GetIntersections(ColoredRay3D ray, NearestIntersection intersections) {
     RayEngineMath.GetIntersections(ray, this, intersections);
 }
예제 #8
0
 //TODO: Hide ray from params. Use its parameters instead.
 public abstract void GetIntersections(ColoredRay3D ray, NearestIntersection intersections);