//裁剪前 public void DrawTriangle(VSOutput vClip0, VSOutput vClip1, VSOutput vClip2) { //Backface Culling if (!FrontEndCulling(vClip0, vClip1, vClip2)) { return; } context.statics.triangleCount += 1; //Clipping List <VSOutput> inputs = new List <VSOutput> { vClip0, vClip1, vClip2 }; List <VSOutput> outputs = Clipping.Clip(inputs, context); //输出结果是trianglefan if (outputs.Count < 3) { //全裁剪掉了 return; } //画Triangle Fan VSOutput v0 = outputs[0]; VSOutput vNDC0 = Rasterizer.PerspectiveDivide(v0); if (vNDC0 == null) { return; } VSOutput vScreen0 = rasterizer.ViewportTransform(vNDC0); for (int i = 1; i + 1 < outputs.Count; i += 1) { VSOutput v1 = outputs[i]; VSOutput v2 = outputs[i + 1]; VSOutput vNDC1 = Rasterizer.PerspectiveDivide(v1); VSOutput vNDC2 = Rasterizer.PerspectiveDivide(v2); if (vNDC1 == null || vNDC2 == null) { continue; } VSOutput vScreen1 = rasterizer.ViewportTransform(vNDC1); VSOutput vScreen2 = rasterizer.ViewportTransform(vNDC2); //检查Backface if (i == 1) { //由于裁剪前后的三角形都在同一个平面上,所以只要检查第一个就够了 if (!BackfaceCulling(vScreen0, vScreen1, vScreen2)) { return; } } context.statics.rasterTriCount += 1; rasterizer.RasterizeTriangle(vScreen0, vScreen1, vScreen2); } }
public void Test_BarycentricRasterizeTriangle() { context.clearColor = Color.White; Clear(); //假设n = 1, far = 2 //测试光栅化和插值 //第一个三角形,v0红色在中上,v1绿和v2蓝在中间的左右,v0在far plane, v1,v2在near plane VSOutput v0 = new VSOutput(); v0.position = new Vector4(0f, 1f, 1f, 2f); v0.color = new Vector4(1f, 0f, 0f, 1f); VSOutput v1 = new VSOutput(); v1.position = new Vector4(-0.5f, -0.5f, -1f, 1f); v1.color = new Vector4(0f, 1f, 0f, 1f); VSOutput v2 = new VSOutput(); v2.position = new Vector4(0.5f, -0.5f, -1f, 1f); v2.color = new Vector4(0f, 0f, 1f, 1f); v0 = Rasterizer.PerspectiveDivide(v0); v0 = rasterizer.ViewportTransform(v0); v1 = Rasterizer.PerspectiveDivide(v1); v1 = rasterizer.ViewportTransform(v1); v2 = Rasterizer.PerspectiveDivide(v2); v2 = rasterizer.ViewportTransform(v2); rasterizer.BarycentricRasterizeTriangle(v0, v1, v2); //测试depth test //第二个三角形,v0红在近平面,v1,v2在远 v0.position = new Vector4(-0.5f, 0.5f, -1f, 1f); v1.position = new Vector4(-2f, -1f, 1f, 2f); v2.position = new Vector4(0f, -2f, 1f, 2f); v0 = Rasterizer.PerspectiveDivide(v0); v0 = rasterizer.ViewportTransform(v0); v1 = Rasterizer.PerspectiveDivide(v1); v1 = rasterizer.ViewportTransform(v1); v2 = Rasterizer.PerspectiveDivide(v2); v2 = rasterizer.ViewportTransform(v2); rasterizer.BarycentricRasterizeTriangle(v0, v1, v2); //第三个三角形,v1绿在近,其他在远平面 v0.position = new Vector4(-2f, 0f, 1f, 2f); v1.position = new Vector4(-0.5f, -1f, -1f, 1f); v2.position = new Vector4(0f, -1f, 1f, 2f); v0 = Rasterizer.PerspectiveDivide(v0); v0 = rasterizer.ViewportTransform(v0); v1 = Rasterizer.PerspectiveDivide(v1); v1 = rasterizer.ViewportTransform(v1); v2 = Rasterizer.PerspectiveDivide(v2); v2 = rasterizer.ViewportTransform(v2); rasterizer.BarycentricRasterizeTriangle(v0, v1, v2); }