Exemplo n.º 1
0
        public RGBA_D Shade(Ray ray, Vector3D hitPoint, uint subIdx, IOpticalSceneObject obj,
                            ISceneManager scene, out Ray reflection, out Ray refraction)
        {
            RGBA_D color = RGBA_D.Empty;

            // needed?
            // normal.Normalize();

            Vector3D normal = obj.GetNormal(hitPoint, subIdx);

            //color.R = normal.X * 255;
            //color.G = normal.Y * 255;
            //color.B = normal.Z * 255;
            //color.A = 255;
            //refraction = null;
            //reflection = null;
            //return color;

            /*double len = (ray.Origin - hitPoint).Length();
             * len -= 2;
             * color.R = color.G = color.B = len * 42.5;*/

            foreach (Light light in scene.Lights)
            {
                Vector3D lv = light.Position - hitPoint;
                lv.Normalize();

                // deal with light ray first (diffuse)
                if (true)//ray.TraceRayToLight(hitPoint, light.Position))
                {
                    // light pixel
                    double   cost  = Vector3D.GetCosAngle(lv, normal);
                    Vector3D vRefl = Vector3D.Reflect(-lv, normal);
                    vRefl.Normalize();

                    double cosf    = Vector3D.GetCosAngle(ray.DirectionUV, vRefl);
                    double result1 = Math.Max(0, cost) * 255;
                    double result2 = Math.Pow(Math.Max(0, cosf), shininess) * 255;

                    double luminosity = light.LuminosityForPoint(hitPoint);

                    double r = ((clr.R * diffuse * light.Clr3D.X * result1) +
                                (light.Clr3D.X * result2)) * luminosity;
                    double g = ((clr.G * diffuse * light.Clr3D.Y * result1) +
                                (light.Clr3D.Y * result2)) * luminosity;
                    double b = ((clr.B * diffuse * light.Clr3D.Z * result1) +
                                (light.Clr3D.Z * result2)) * luminosity;

                    color.R += r;
                    color.G += g;
                    color.B += b;
                }
            }

            // add ambient
            double alpha = 1 - transmission;

            color.R += (diffuse * scene.Ambient.R + (clr.R * emmissive)) * 255;
            //color.R *= alpha;
            color.G += (diffuse * scene.Ambient.G + (clr.G * emmissive)) * 255;
            //color.G *= alpha;
            color.B += (diffuse * scene.Ambient.B + (clr.B * emmissive)) * 255;
            //color.B *= alpha;

            color.A = alpha * 255;

            // blend texture (if any)

            /*if (texture != null)
             * {
             *  Vector2D tCoord = obj.GetTexCoord(hitPoint, subIdx);
             *  // clamp for now
             *  if (tCoord.X < 0)
             *      tCoord.X = 0;
             *  if (tCoord.Y < 0)
             *      tCoord.Y = 0;
             *  if (tCoord.X > 1)
             *      tCoord.X = 1;
             *  if (tCoord.Y > 1)
             *      tCoord.Y = 1;
             *
             *  int tX = (int)(tCoord.X * (texture.Width - 1));
             *  int tY = (int)(tCoord.Y * (texture.Height - 1));
             *
             *  Color tClr = ((Bitmap)texture).GetPixel(tX, tY);
             *  color.R = (color.R + tClr.R) / 2;
             *  color.G = (color.G + tClr.G) / 2;
             *  color.B = (color.B + tClr.B) / 2;
             * }*/

            if (ray.Intensity > 0)
            {
                /*if (this.reflection > 0)
                 * {
                 *  Vector3D refl = Vector3D.Reflect(ray.DirectionUV, normal);
                 *  reflection = new Ray(hitPoint, refl, ray.Intensity * this.reflection, ray.Length, ray.MaxLength, ray.scene);
                 * }
                 * else*/
                reflection = null;

                /*if (transmission > 0)
                 *  refraction = new Ray(hitPoint, Vector3D.Normalize(Vector3D.Refract(1, 1.33, -ray.DirectionUV, normal)), ray.Intensity * transmission, ray.Length, ray.MaxLength, ray.scene);
                 * else*/
                refraction = null;
            }
            else
            {
                reflection = refraction = null;
            }

            ray.Intensity = 0;

            return(color);
        }
Exemplo n.º 2
0
        public static double GetCosAngle(Vector3D v1, Vector3D v2)
        {
            /* incident angle
            // inters pt (i)
            double ix, iy, iz;
            ix = px+t*vx;
            iy = py+t*vy;
            iz = pz+t*vz;

            // normal at i
            double nx, ny, nz;
            nx = ix - cx;
            ny = iy - cy;
            nz = iz - cz;
            */
            v1.Normalize();
            v2.Normalize();

            // cos(t) = (v.w) / (|v|.|w|)
            double n = (v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z);
            double d = (modv(v1) * modv(v2));

            if (Math.Abs(d) < 1.0E-10)
                return 0;
            return n / d;
        }
Exemplo n.º 3
0
        public void Trace()
        {
            // project into scene as inital rejection test
            if (scene.TestForContents(view, area, maxLength))
            {
                // sub-divide task area until all 4 are positive for matches
                if (!divide)
                {
                    // no divisions so run the task immediately
                    // just run all rays here for now
                    double xScale       = 0.5 / view.Area.Width;  //area.Width;
                    double yScale       = 0.5 / view.Area.Height; //area.Height;
                    double yIdx         = -0.25 + (xScale * 0.5) + (yScale * area.Top);
                    double filterShiftX = xScale * 0.5;
                    double filterShiftY = yScale * 0.5;

                    for (int y = area.Top; y < area.Bottom; y++)
                    {
                        double xIdx = -0.25 + (yScale * 0.5) + (xScale * area.Left);
                        for (int x = area.Left; x < area.Right; x++)
                        {
                            Vector3D offset = ((view.XUV * xIdx) + (view.YUV * yIdx));
                            Vector3D rayDir = offset + view.Direction;
                            rayDir.Normalize();
                            Ray    ray   = new Ray(view.Centre, rayDir, 1, 0, maxLength, scene);
                            RGBA_D value = ray.Trace(ray);

                            // do anti-alias pass/pixel
                            // TODO: Do more if on left and/or top edge
                            RGBA_D aaValue = RGBA_D.Empty;
                            if (frameData.AALayer != null)
                            {
                                offset = ((view.XUV * (xIdx + filterShiftX)) + (view.YUV * (yIdx + filterShiftY)));
                                rayDir = offset + view.Direction;
                                rayDir.Normalize();
                                ray     = new Ray(view.Centre, rayDir, 1, 0, maxLength, scene);
                                aaValue = ray.Trace(ray);

                                if (aaValue != RGBA_D.Empty)
                                {
                                    int index = ((y + 1) * (frameData.Width + 2)) + (x + 1);
                                    lock (frameData)
                                    {
                                        // pack to bytes
                                        float val = ((byte)aaValue.R | (byte)aaValue.G << 8 | (byte)aaValue.B << 16 | (byte)value.A << 24);
                                        frameData.AALayer[index] = val;
                                    }
                                }
                            }

                            value.Normalize();
                            aaValue.Normalize();

                            if (value != RGBA_D.Empty)
                            {
                                // write to frame buffer
                                int index = (y * frameData.Width) + x;
                                lock (frameData)
                                {
                                    // pack to bytes
                                    float val = ((byte)value.R | (byte)value.G << 8 | (byte)value.B << 16 | (byte)value.A << 24);
                                    frameData.Data[index] = val;
                                }
                            }

                            /*else
                             * {
                             *  int index = (y * frameData.Width) + x;
                             *  lock (frameData)
                             *  {
                             *      // pack to bytes
                             *      float val = ((byte)area.Left /2 | (byte)area.Top /2 << 8 | (byte)0 << 16 | (byte)255 << 24);
                             *      frameData.Data[index] = val;
                             *  }
                             * }*/
                            xIdx += xScale;
                        }
                        yIdx += yScale;
                    }

                    // pass AA area on to control

                    // just create group outline for now

                    /*for (int x = area.Left; x < area.Right; x++)
                     * {
                     *  lock (frameData)
                     *  {
                     *      // pack to bytes
                     *      frameData.Data[x] = (255 | (byte)0 << 255 | (byte)0 << 255 | (byte)255 << 24);
                     *  }
                     * }
                     * int index2 = view.Area.Width * (area.Height - 1);
                     * for (int x = area.Left; x < area.Right; x++)
                     * {
                     *  lock (frameData)
                     *  {
                     *      // pack to bytes
                     *      frameData.Data[index2 + x] = (255 | (byte)0 << 255 | (byte)0 << 255 | (byte)255 << 24);
                     *  }
                     * }*/

                    dispatch.RaysTraced(area.Width * area.Height);
                }
                else
                {
                    SubDivideTask(area, maxLength, 0);
                }
            }
            dispatch.ExecutionComplete();
        }