예제 #1
0
 public RGBA_D Shade(Ray ray, Vector3D pos, uint subIdx, out Ray reflection, out Ray refraction,
                     ISceneManager scene)
 {
     if (shader != null)
         return shader.Shade(ray, pos, subIdx, this, scene, out reflection, out refraction);
     reflection = null;
     refraction = null;
     return RGBA_D.Empty;
 }
예제 #2
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;
        }
예제 #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();
        }
예제 #4
0
 public void QueueDispatch(Ray ray)
 {
     throw new System.NotImplementedException();
 }