bool FrontEndCullingByArea(VSOutput v0, VSOutput v1, VSOutput v2) { if (context.frontEndCull == FrontEndCull.Off) { return(true); } if (context.cullMode == CullMode.None) { return(true); } //cull back Vector2 p0 = new Vector2(v0.position.X, v0.position.Y); Vector2 p1 = new Vector2(v1.position.X, v1.position.Y); Vector2 p2 = new Vector2(v2.position.X, v2.position.Y); //做了透射除法,Culling准确点 p0 *= 1 / v0.position.W; p1 *= 1 / v1.position.W; p2 *= 1 / v2.position.W; float area = Rasterizer.EdgeFunction(p0, p1, p2); //在Clip Space, area >= 0表示顺时针 if (context.winding == Winding.Clockwise) { return(area > 0); } return(area < 0); }
bool BackfaceCulling(VSOutput vScreen0, VSOutput vScreen1, VSOutput vScreen2) { if (context.cullMode == CullMode.None) { return(true); } if (context.frontEndCull == FrontEndCull.On) { return(true); } Vector2 p0 = new Vector2(vScreen0.posScreen.X, vScreen0.posScreen.Y); Vector2 p1 = new Vector2(vScreen1.posScreen.X, vScreen1.posScreen.Y); Vector2 p2 = new Vector2(vScreen2.posScreen.X, vScreen2.posScreen.Y); float area = Rasterizer.EdgeFunction(p0, p1, p2); if (context.winding == Winding.Clockwise) { return(area < 0); } //在Viewport Space, 由于Y轴向下, area > 0表示逆时针 return(area > 0); }