예제 #1
0
        // lesson3
        public static void Triangle(Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer)
        {
            Vec3f t0 = coordinates [0];
            Vec3f t1 = coordinates [1];
            Vec3f t2 = coordinates [2];

            var pMax = new Vec2i {
                x = (int)Math.Max(0, Math.Max(t0.x, Math.Max(t1.x, t2.x))),
                y = (int)Math.Max(0, Math.Max(t0.y, Math.Max(t1.y, t2.y)))
            };
            var pMin = new Vec2i {
                x = (int)Math.Min(image.Width, Math.Min(t0.x, Math.Min(t1.x, t2.x))),
                y = (int)Math.Min(image.Height, Math.Min(t0.y, Math.Min(t1.y, t2.y)))
            };

            for (int x = pMin.x; x <= pMax.x; x++)
            {
                for (int y = pMin.y; y <= pMax.y; y++)
                {
                    var pixelCenter = new Vec2f {
                        x = x + 0.5f,
                        y = y + 0.5f
                    };
                    var bc = Barycentric(Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter);
                    if (bc.x < 0 || bc.y < 0 || bc.z < 0)
                    {
                        continue;
                    }

                    var z   = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z;
                    var u   = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z);
                    var v   = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z);
                    var idx = x + y * image.Width;
                    if (zbuffer [idx] < z)
                    {
                        zbuffer [idx] = z;

                        var color = texture [u, v];
                        image [x, y] = color * intensivity;
                    }
                }
            }
        }
예제 #2
0
        // lesson4
        public static Matrix4 LookAt(Vec3f eye, Vec3f center, Vec3f up)
        {
            var z = (eye - center).Normalize();
            var x = Cross(up, z).Normalize();
            var y = Cross(z, x).Normalize();

            var Minv = Matrix4.Identity();

            Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z;
            Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z;
            Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z;

            var Tr = Matrix4.Identity();

            Tr [0, 3] = -center.x;
            Tr [1, 3] = -center.y;
            Tr [2, 3] = -center.y;

            return(Minv * Tr);
        }
예제 #3
0
        public static void Execute(Model model, Image texture)
        {
            var image = new Image(width, height, Format.BGR);
            Func <Vec3f, Vec3f> map = v => new Vec3f {
                x = (int)Math.Round((v.x + 1) * (image.Width - 1) / 2, MidpointRounding.AwayFromZero),
                y = (int)Math.Round((v.y + 1) * (image.Height - 1) / 2, MidpointRounding.AwayFromZero),
                z = v.z
            };

            Func <Vec3f, Vec2f> uvMap = v => new Vec2f {
                x = v.x * (texture.Width - 1),
                y = v.y * (texture.Height - 1)
            };

            var zbuffer = InitZBuffer(image);
            var uv      = new Vec2f [3];

            foreach (var face in model.Faces)
            {
                for (int i = 0; i < 3; i++)
                {
                    var vIndex = face.Vertices [i];
                    world [i]  = model.Vertices [vIndex];
                    screen [i] = map(world [i]);

                    var tIndex = face.Textures [i];
                    uv [i] = uvMap(model.Textures [tIndex]);
                }

                Vec3f n = Cross(world [2] - world [0], world [1] - world [0]).Normalize();

                var intensivity = Dot(n, light_dir);
                if (intensivity > 0)
                {
                    Triangle(image, screen, texture, uv, intensivity, zbuffer);
                }
            }

            image.VerticalFlip();
            image.WriteToFile("texture-head.tga");
        }
예제 #4
0
        public bool Fragment(Vec3f fragment, Vec3f bar, out Color color)
        {
            var uv = CalcUV(varyingU, varyingV, bar);
            var n  = Transform(uniformMIT, Normal(normalMap, uv)).Normalize();
            var l  = Transform(uniformM, lightDir).Normalize();

            var r = (n * (2 * Dot(n, l)) - l).Normalize();

            var diff     = Math.Max(0f, Dot(n, l));
            var specular = Math.Pow(Math.Max(0f, r.z), Specular(specularMap, uv) + 15);

            color = GetColor(texture, uv);

            int v = 0;

            for (int i = 0; i < 4; i++)
            {
                v = (v << 8) | (byte)Math.Min(255, (int)(5 + color [i] * (diff + 1.3f * specular)));
            }
            color = new Color(v, color.format);

            return(false);
        }
예제 #5
0
        static void ProjectionListing()
        {
            var image = new Image(width, height, Format.BGR);

            var camera = new Vec3f {
                z = 3
            };
            var projection = Projection(-1 / camera.z);
            var viewPort   = Viewport(width / 8, height / 8, width * 3 / 4, height * 3 / 4);

            var zbuffer = InitZBuffer(image);

            foreach (var face in headModel.Faces)
            {
                for (int i = 0; i < 3; i++)
                {
                    var vIndex = face.Vertices [i];
                    world [i]  = headModel.Vertices [vIndex];
                    screen [i] = map(world [i]);

                    var tIndex = face.Textures [i];
                    uv [i] = uvMap(headModel.Textures [tIndex]);
                }

                var n = Cross(world [2] - world [0], world [1] - world [0]).Normalize();

                var intensivity = Dot(n, light_dir);
                if (intensivity > 0)
                {
                    Triangle(image, screen, headTexture, uv, intensivity, zbuffer);
                }
            }

            image.VerticalFlip();
            image.WriteToFile("project-head.tga");
        }
예제 #6
0
 public bool Fragment(Vec3f fragment, Vec3f bar, out Color color)
 {
     color = Color.White * (fragment.z / depth);
     return(false);
 }
예제 #7
0
        public ShadowShader(Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Matrix4 uniformShadow, Vec3f lightDir, Image texture, Image normalMap, Image specularMap, float[] shadowbuffer, int width)
        {
            this.model        = model;
            this.lightDir     = lightDir.Normalize();
            this.texture      = texture;
            this.normalMap    = normalMap;
            this.specularMap  = specularMap;
            this.shadowbuffer = shadowbuffer;
            this.width        = width;

            uniformM           = projection * modelView;
            uniformMIT         = TransposeInverse(uniformM);
            transformation     = viewport * uniformM;
            this.uniformShadow = uniformShadow;
        }
예제 #8
0
        // use this commit for 6bis lesson:
        // https://github.com/xamarin/private-samples/commit/ddad38f7787d5e9c065afc91547730ad38e51fd1#diff-8603c43660c04f4d430053b29c80ed15R253
        public TangentShader(Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap)
        {
            this.model    = model;
            this.lightDir = lightDir.Normalize();
            this.texture  = texture;

            // do not need for starting poing
            this.normalMap = normalMap;
            // this.specularMap = specularMap;

            uniformM       = projection * modelView;
            uniformMIT     = TransposeInverse(uniformM);
            transformation = viewport * uniformM;
        }
예제 #9
0
 public GouraudShader(Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir)
 {
     this.model     = model;
     transformation = viewPort * projection * modelView;
     this.lightDir  = lightDir.Normalize();
 }
예제 #10
0
        public NormalMapShader(Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap)
        {
            this.model     = model;
            this.lightDir  = lightDir.Normalize();
            this.texture   = texture;
            this.normalMap = normalMap;

            uniformM       = projection * modelView;
            uniformMIT     = TransposeInverse(uniformM);
            transformation = viewport * uniformM;
        }
예제 #11
0
        // lesson6
        public static void UpdateVarayingUV(Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV)
        {
            var vt = model.GetUV(face, nthvert);

            varyingU [nthvert] = vt.x;
            varyingV [nthvert] = vt.y;
        }
예제 #12
0
 public GouraudShader6(Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir)
     : base(model, viewPort, projection, modelView, lightDir)
 {
 }
예제 #13
0
 public void SetRow(int row, Vec3f v)
 {
     this [row, 0] = v.x;
     this [row, 1] = v.y;
     this [row, 2] = v.z;
 }
예제 #14
0
 public void SetColumn(int col, Vec3f v)
 {
     this [0, col] = v.x;
     this [1, col] = v.y;
     this [2, col] = v.z;
 }
예제 #15
0
 public static Vec2f Project2D(Vec3f v)
 {
     return(new Vec2f {
         x = v.x, y = v.y
     });
 }
예제 #16
0
 public static Vec4f Embed4D(Vec3f v, float fill = 1)
 {
     return(new Vec4f {
         x = v.x, y = v.y, z = v.z, h = fill
     });
 }
예제 #17
0
 public static float Dot(Vec3f l, Vec3f r)
 {
     return(l.x * r.x + l.y * r.y + l.z * r.z);
 }
예제 #18
0
 public bool Fragment(Vec3f fragment, Vec3f bar, out Color color)
 {
     color = Color.Black;
     return(false);
 }
예제 #19
0
 public TextureShader(Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture)
 {
     this.model     = model;
     transformation = viewPort * projection * modelView;
     this.lightDir  = lightDir.Normalize();
     this.texture   = texture;
 }
예제 #20
0
        public static Vec3f Transform(Matrix4 t, Vec3f v)
        {
            var v4d = Mult(t, Embed4D(v));

            return(Project3D(v4d));
        }
예제 #21
0
        static void AmbientListing()
        {
            var rnd           = new Random();
            var screen_coords = new Vec4f [3];

            var frame        = new Image(width, height, Format.BGR);
            var shadowbuffer = InitZBuffer(frame);
            var zbuffer      = InitZBuffer(frame);

            var total = new Image(1024, 1024, Format.BGR);
            var occl  = new Image(1024, 1024, Format.BGR);

            const int nrenders = 1;

            for (int iter = 1; iter <= nrenders; iter++)
            {
                for (int i = 0; i < shadowbuffer.Length; i++)
                {
                    shadowbuffer [i] = 0;
                    zbuffer [i]      = 0;
                }

                var vUp = new Vec3f {
                    x = (float)rnd.NextDouble(),
                    y = (float)rnd.NextDouble(),
                    z = (float)rnd.NextDouble()
                };
                var spLocation = RandPointOnUnitSphere();
                spLocation.y = Math.Abs(spLocation.y);

                frame.Clear();
                var mvM     = LookAt(spLocation, center, vUp);
                var pM      = Projection(0);
                var zshader = new ZShader(diabloModel, viewPort, pM, mvM);
                foreach (var face in diabloModel.Faces)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        screen_coords [i] = zshader.Vertex(face, i);
                    }
                    Triangle(frame, screen_coords, zshader, shadowbuffer);
                }
                //frame.VerticalFlip ();
                //frame.WriteToFile ("framebuffer.tga");

                occl.Clear();
                var shader = new OcclusionShader(diabloModel, viewPort, pM, mvM, occl, shadowbuffer, frame.Width);
                foreach (var face in diabloModel.Faces)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        screen_coords [i] = shader.Vertex(face, i);
                    }
                    Triangle(frame, screen_coords, shader, zbuffer);
                }

                for (int i = 0; i < total.Width; i++)
                {
                    for (int j = 0; j < total.Height; j++)
                    {
                        float prev = total [i, j] [0];
                        float curr = occl [i, j] [0];
                        var   val  = (byte)((prev * (iter - 1) + curr) / iter + 0.5f);
                        total [i, j] = new Color(val, val, val);
                    }
                }
            }

            total.VerticalFlip();
            total.WriteToFile("total-occlusion.tga");
        }