Esempio n. 1
0
    public IVertexOutputData Process(IVertexInputData input)
    {
        IVertexOutputData output = new VertexOutputData();

        output.clip       = MVP * input.vertex;
        output.viewNormal = N * input.normal;
        return(output);
    }
Esempio n. 2
0
 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);
 }
Esempio n. 3
0
    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);
    }
Esempio n. 4
0
    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());
    }