public IVertexOutputData Process(IVertexInputData input) { IVertexOutputData output = new VertexOutputData(); output.clip = MVP * input.vertex; output.viewNormal = N * input.normal; return(output); }
private IVertexOutputData[] ClipPolygon(IVertexOutputData[] polygon) { for (int planeIndex = 0; planeIndex < 6; planeIndex++) { List <IVertexOutputData> vdatas = new List <IVertexOutputData>(); int vi = planeIndex / 2; int sign = planeIndex % 2 == 0 ? 1 : -1; for (int pointIndex = 0; pointIndex < polygon.Length; pointIndex++) { int index0 = pointIndex; int index1 = pointIndex == polygon.Length - 1 ? 0 : pointIndex + 1; IVertexOutputData v0 = polygon[index0]; IVertexOutputData v1 = polygon[index1]; Vector4 p0 = v0.clip; Vector4 p1 = v1.clip; Vector3 n0 = v0.viewNormal; Vector3 n1 = v1.viewNormal; float d0 = (p0[vi] + p0.w * sign) * p0.w; float d1 = (p1[vi] + p1.w * sign) * p1.w; float ds = d0 * d1; if (ds < 0) { // 边与裁剪面相交 float u = d0 / (d0 - d1); Vector4 p = p0 + (p1 - p0) * u; Vector3 n = n0 + (n1 - n0) * u; if (sign * d0 > 0) { vdatas.Add(v0); } IVertexOutputData data = new VertexOutputData(); data.clip = p; data.viewNormal = n; vdatas.Add(data); } else if (MathS.Abs(d0) < Threshold) { // p0点在裁剪面上 vdatas.Add(v0); } else if (sign * d0 > 0 && sign * d1 >= 0) { // 边完全位于裁剪面之内 vdatas.Add(v0); } } polygon = vdatas.ToArray(); } return(polygon); }
public IVertexOutputData Triangle(IVertexOutputData[] clips, Vector2[] screens, int[] pixel) { Vector2 center = new Vector2(pixel[0], pixel[1]); float a = MathS.Abs(Vector2.Cross(screens[1] - screens[0], screens[2] - screens[0]) * 0.5f); // 重心法求插值系数 float a0 = MathS.Abs(Vector2.Cross(screens[1] - screens[0], center - screens[0]) * 0.5f) / a; float a1 = MathS.Abs(Vector2.Cross(screens[2] - screens[1], center - screens[1]) * 0.5f) / a; float a2 = MathS.Abs(Vector2.Cross(screens[0] - screens[2], center - screens[2]) * 0.5f) / a; // 插值 IVertexOutputData lerp = new VertexOutputData(); lerp.clip = a0 * clips[0].clip + a1 * clips[1].clip + a2 * clips[2].clip; lerp.viewNormal = a0 * clips[0].viewNormal + a1 * clips[1].viewNormal + a2 * clips[2].viewNormal; return(lerp); }
public ITriangle[] Process(IDrawCall drawCall, ICamera camera) { // vertex shade vertexShade.MVP = camera.P * camera.V * drawCall.M; vertexShade.N = (camera.V * drawCall.M).Inverse().Transpose().Minor(3, 3); Vector4[] vertices = drawCall.vertices; Vector3[] normals = drawCall.normals; IVertexOutputData[] outputs = new VertexOutputData[vertices.Length]; for (int vIndex = 0; vIndex < vertices.Length; vIndex++) { IVertexInputData input = new VertexInputData(); input.vertex = vertices[vIndex]; input.normal = normals[vIndex]; outputs[vIndex] = vertexShade.Process(input); } // primitive assembly ITriangle[] primitives = primitiveAssemble.Process(outputs, drawCall.indices); Queue <ITriangle> triangles = new Queue <ITriangle>(); for (int pIndex = 0; pIndex < primitives.Length; pIndex++) { // back-face culling ITriangle t = cull.Process(primitives[pIndex]); if (t != null) { // clipping ITriangle[] ts = clip.Process(t); if (ts != null) { foreach (ITriangle each in ts) { triangles.Enqueue(each); } } } } return(triangles.ToArray()); }