// 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; } } } }
// 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); }
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"); }
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); }
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"); }
public bool Fragment(Vec3f fragment, Vec3f bar, out Color color) { color = Color.White * (fragment.z / depth); return(false); }
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; }
// 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; }
public GouraudShader(Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize(); }
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; }
// 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; }
public GouraudShader6(Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base(model, viewPort, projection, modelView, lightDir) { }
public void SetRow(int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; }
public void SetColumn(int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; }
public static Vec2f Project2D(Vec3f v) { return(new Vec2f { x = v.x, y = v.y }); }
public static Vec4f Embed4D(Vec3f v, float fill = 1) { return(new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }); }
public static float Dot(Vec3f l, Vec3f r) { return(l.x * r.x + l.y * r.y + l.z * r.z); }
public bool Fragment(Vec3f fragment, Vec3f bar, out Color color) { color = Color.Black; return(false); }
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; }
public static Vec3f Transform(Matrix4 t, Vec3f v) { var v4d = Mult(t, Embed4D(v)); return(Project3D(v4d)); }
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"); }