public override bool Render()
        {
            // Render scene
            var o = new Vector3F(0.0f, 0.0f, -5.0f);

            // Initialize timer
            var msecs = Environment.TickCount;

            // Render remaining lines
            for (var lineY = _currLine; lineY < (Height); lineY++)
            {
                _sx = _worldX1;

                // Render pixels for current line
                for (var lineX = 0; lineX < Width; lineX++)
                {
                    // Fire primary ray

                    var dir = new Vector3F(_sx, _sy, 0.0f) - o;
                    dir.Normalize();

                    var r = new Ray(o, dir);
                    var acc = Raytrace(r, 1);

                    var red = (int)(acc.X * 256);
                    var green = (int)(acc.Y * 256);
                    var blue = (int)(acc.Z * 256);

                    if (red > 255) red = 255;
                    if (green > 255) green = 255;
                    if (blue > 255) blue = 255;

                    PixelBuffer[_pPos++] = (uint)((red << 16) + (green << 8) + blue);
                    _sx += _deltaX;
                }
                _sy += _deltaY;

                // See if we've been working to long already
                if ((Environment.TickCount - msecs) > 100)
                {
                    // return control to windows so the screen gets updated
                    _currLine = lineY + 1;
                    return false;
                }
            }
            // all done
            return true;
        }
Beispiel #2
0
        public override IntersectionResult Intersect(Ray ray, ref float refDistance)
        {
            var tMin = float.NegativeInfinity;
            var tMax = float.PositiveInfinity;

            for (var i = 0; i < 3; i++)
            {
                var t1 = (Min[i] - ray.Origin[i]) / ray.Direction[i];
                var t2 = (Max[i] - ray.Origin[i]) / ray.Direction[i];

                tMin = Math.Max(tMin, Math.Min(t1, t2));
                tMax = Math.Min(tMax, Math.Max(t1, t2));
            }

            if (tMax >= tMin && tMax >= 0) return IntersectionResult.Hit;

            return IntersectionResult.Miss;
        }
Beispiel #3
0
        public override IntersectionResult Intersect(Ray ray, ref float refDistance)
        {
            var d = Vector3F.Dot(Normal, ray.Direction);

            if (Math.Abs(d) > Tolerance)
            {
                var distance = -(Vector3F.Dot(Normal, ray.Origin) + Distance) / d;
                if (distance > 0.0f)
                {
                    if (distance < refDistance)
                    {
                        refDistance = distance;

                        return IntersectionResult.Hit;
                    }
                }
            }

            return IntersectionResult.Miss;
        }
Beispiel #4
0
        public override IntersectionResult Intersect(Ray ray, ref float distance)
        {
            var vector = ray.Origin - Center;
            var b = -Vector3F.Dot(vector, ray.Direction);
            var det = (b * b) - Vector3F.Dot(vector, vector) + SquareRadius;
            var returnValue = IntersectionResult.Miss;

            if (det > 0)
            {
                det = (float)Math.Sqrt(det);

                var i1 = b - det;
                var i2 = b + det;

                if (i2 > 0.0f)
                {
                    if (i1 < 0.0f)
                    {
                        if (i2 < distance)
                        {
                            distance = i2;
                            returnValue = IntersectionResult.InPrimitive;
                        }
                    }
                    else
                    {
                        if (i1 < distance)
                        {
                            distance = i1;
                            returnValue = IntersectionResult.Hit;
                        }
                    }
                }
            }

            return returnValue;
        }
Beispiel #5
0
        protected override Color Raytrace(Ray ray, int depth)
        {
            var distance = MaxDistance;
            var acc = Color.Black;

            // Trace primary ray
            Primitive primitive = null;

            if (depth > MaxDepth) return Color.Black;

            foreach (var currentPrimitive in Scene.Primitives)
            {
                var res = currentPrimitive.Intersect(ray, ref distance);
                if (res != 0)
                {
                    primitive = currentPrimitive;
                }
            }

            // No hit, terminate ray
            if (primitive == null) return Color.Black;

            // Handle intersection
            if (primitive.IsLight)
            {
                // We hit a light, stop tracing
                return Color.White;
            }

            // Determine color at point of intersection
            var intersectionPoint = ray.Origin + ray.Direction * distance;

            // Trace lights
            foreach (var currentPrimitive in Scene.Primitives.Where(x => x.IsLight))
            {
                var light = currentPrimitive;

                // Calculate diffuse shading;
                var lightSource = ((SpherePrimitive)light).Center - intersectionPoint;
                lightSource.Normalize();

                var normal = primitive.GetNormal(intersectionPoint);
                if (primitive.Material.Diffuse > 0)
                {
                    // Check for normals facing away from the light (dot < 0)
                    var dot = normal.Dot(lightSource);
                    if (dot > 0)
                    {
                        var diff = dot * primitive.Material.Diffuse;

                        // Add diffuse component to ray color
                        acc += diff * primitive.Material.Color * light.Material.Color;
                    }
                }
            }

            // Calculate reflection
            var reflection = primitive.Material.Reflection;
            if (reflection > 0.0f)
            {
                var normal = primitive.GetNormal(intersectionPoint);
                var r = ray.Direction - 2.0f * ray.Direction.Dot(normal) * normal;
                if (depth < MaxDepth)
                {
                    var newRay = new Ray(intersectionPoint + r * Epsilon, r);
                    var reflectionColor = Raytrace(newRay, depth + 1);

                    acc += reflection * reflectionColor * primitive.Material.Color;
                }
            }

            return acc;
        }
        protected override Color Raytrace(Ray ray, int depth)
        {
            var distance = MaxDistance;

            // Depth too high, terminate ray
            if (depth >= MaxDepth) return Color.Black;

            Primitive primitive = null;

            foreach (var currentPrimitive in Scene.Primitives)
            {
                var res = currentPrimitive.Intersect(ray, ref distance);
                if (res != 0)
                {
                    primitive = currentPrimitive;
                }
            }

            // No hit, terminate ray
            if (primitive == null) return Color.Black;
            if (primitive.IsLight) return Color.White;

            var material = primitive.Material;
            var emittance = material.Color;

            var intersectionPoint = ray.Origin + ray.Direction * distance;
            var direction = primitive.GetNormal(intersectionPoint) + new Vector3F((float)_random.NextDouble());
            var newRay = new Ray(intersectionPoint, direction);

            var cosTheta = newRay.Direction.Dot(intersectionPoint);
            var brdf = 2 * material.Reflection * cosTheta;
            var reflected = Raytrace(newRay, depth + 1);

            return emittance + (brdf * reflected);
        }