コード例 #1
0
    void DrawEntity(Entity entity)
    {
        Mesh      mesh            = entity.meshFilter.mesh;
        Transform objectTransform = entity.transform;
        Texture2D mainTex         = entity.mainTex;


        for (int i = 0; i < mesh.triangles.Length; i += 3)
        {
            int a_index = mesh.triangles[i];
            int b_index = mesh.triangles[i + 1];
            int c_index = mesh.triangles[i + 2];

            TriangleAttribute <Color>   colors = new TriangleAttribute <Color>(Color.red, Color.green, Color.blue);
            TriangleAttribute <Vector2> uvs    = new TriangleAttribute <Vector2>(mesh.uv[a_index], mesh.uv[b_index], mesh.uv[c_index]);

            Vector4 a = V4Point(mesh.vertices[a_index]);
            Vector4 b = V4Point(mesh.vertices[b_index]);
            Vector4 c = V4Point(mesh.vertices[c_index]);

            m_Transform m_objectTransform = new m_Transform();
            m_objectTransform.CopyFromTransform(objectTransform);

            a = m_objectTransform.TransformPoint(a);
            b = m_objectTransform.TransformPoint(b);
            c = m_objectTransform.TransformPoint(c);

            TriangleAttribute <Vector3> pos_worlds = new TriangleAttribute <Vector3>(a, b, c);
            TriangleAttribute <Vector3> normals    =
                new TriangleAttribute <Vector3>(
                    m_objectTransform.TransformDirection(mesh.normals[a_index]),
                    m_objectTransform.TransformDirection(mesh.normals[b_index]),
                    m_objectTransform.TransformDirection(mesh.normals[c_index]));

            m_Transform cam_t = new m_Transform();
            cam_t.CopyFromTransform(cam.transform);

            a = cam_t.InverseTransformPoint(a);
            b = cam_t.InverseTransformPoint(b);
            c = cam_t.InverseTransformPoint(c);

            Matrix4x4 p        = GetProjectionMatrix(cam);
            Matrix4x4 negetive = Matrix4x4.identity;
            negetive.m22 = -1;
            Matrix4x4 total = p * negetive;

            a = ClipSpaceToScreenSpace(total * V4Point(a), pixelWidth, pixelHeight);
            b = ClipSpaceToScreenSpace(total * V4Point(b), pixelWidth, pixelHeight);
            c = ClipSpaceToScreenSpace(total * V4Point(c), pixelWidth, pixelHeight);

            a.z = a.w;
            b.z = b.w;
            c.z = c.w;
            Triangle3D triangle = new Triangle3D(a, b, c);      //z值为摄像机空间z坐标
            DrawTriangle(colorBuffer, triangle, colors, uvs, pos_worlds, normals, mainTex);
        }
    }
コード例 #2
0
    public void DrawTriangle(Texture2D colorBuffer, Triangle3D t, TriangleAttribute <Color> colors, TriangleAttribute <Vector2> uvs, TriangleAttribute <Vector3> pos_worlds, TriangleAttribute <Vector3> normals, Texture2D mainTex)
    {
        Vector2 min = Vector2.Min(Vector2.Min(t.a, t.b), t.c);
        Vector2 max = Vector2.Max(Vector2.Max(t.a, t.b), t.c);

        Vector2Int min_int = ClampInScreenSpace(pixelWidth, pixelHeight, Vector2Int.FloorToInt(min));
        Vector2Int max_int = ClampInScreenSpace(pixelWidth, pixelHeight, Vector2Int.FloorToInt(max));

        t.a.z = 1 / t.a.z;
        t.b.z = 1 / t.b.z;
        t.c.z = 1 / t.c.z;

        colors.a *= t.a.z;
        colors.b *= t.b.z;
        colors.c *= t.c.z;

        uvs.a *= t.a.z;
        uvs.b *= t.b.z;
        uvs.c *= t.c.z;

        pos_worlds.a *= t.a.z;
        pos_worlds.b *= t.b.z;
        pos_worlds.c *= t.c.z;

        normals.a *= t.a.z;
        normals.b *= t.b.z;
        normals.c *= t.c.z;
        for (int y = min_int.y; y <= max_int.y; y++)
        {
            for (int x = min_int.x; x <= max_int.x; x++)
            {
                Vector2 p  = new Vector2(x + 0.5f, y + 0.5f);
                float   ab = EdgeTest(t.a, t.b, p);
                if (ab < 0)
                {
                    continue;
                }

                float bc = EdgeTest(t.b, t.c, p);
                if (bc < 0)
                {
                    continue;
                }

                float ca = EdgeTest(t.c, t.a, p);
                if (ca < 0)
                {
                    continue;
                }

                float area = EdgeTest(t.a, t.b, t.c);
                float w_a  = bc / area;
                float w_b  = ca / area;
                float w_c  = ab / area;

                float z = 1 / (w_a * t.a.z + w_b * t.b.z + w_c * t.c.z);

                if (!DepthTest(x, y, z / cam.farClipPlane))
                {
                    continue;
                }

                Color   color     = z * (colors.a * w_a + colors.b * w_b + colors.c * w_c);
                Vector2 uv        = z * (uvs.a * w_a + uvs.b * w_b + uvs.c * w_c);
                Vector3 pos_world = z * (pos_worlds.a * w_a + pos_worlds.b * w_b + pos_worlds.c * w_c);
                Vector3 normal    = z * (normals.a * w_a + normals.b * w_b + normals.c * w_c);

                Color col;
                if (chekerBoard)
                {
                    col = FragmentShader_ChckerBorad(uv, pos_world, normal, mainTex);
                }
                else
                {
                    col = FragmentShader_BlinnPhong(uv, pos_world, normal, mainTex);
                }

                colorBuffer.SetPixel(x, y, col);
            }
        }
    }