simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:QuadのSubDivision Script 実装例

前置き

f:id:simplestar_tech:20200126194256p:plain
メッシュが細かければ、height 指定でこのような見た目が作れます

URP で Tessellation がいまだ用意されていない(調べた限り HDRP は可能)

Tesselation というのはこういうメッシュ細分化
ja.wikipedia.org

いますぐ平面のメッシュ細分化処理がほしい!

Mesh 操作の基本を確認

qiita.com

あ、作れる!

作った

        var subDivIndices = new int[6 * subDivCount * subDivCount];
        var subDivVerts = new Vector3[4 * subDivCount * subDivCount];
        var subDivUvs = new Vector2[4 * subDivCount * subDivCount];
        var edgeLength = 1.0f / subDivCount;
        for (int xIndex = 0; xIndex < subDivCount; xIndex++)
        {
            var offsetX = edgeLength * xIndex;
            for (int yIndex = 0; yIndex < subDivCount; yIndex++)
            {
                var offsetY = edgeLength * yIndex;
                var offsetIndex = subDivCount * xIndex + yIndex;

                var leftBottom = new Vector3(offsetX - 0.5f, offsetY - 0.5f);
                var rightBottom = leftBottom + new Vector3(edgeLength, 0);
                var leftUp = leftBottom + new Vector3(0, edgeLength);
                var rightUp = leftBottom + new Vector3(edgeLength, edgeLength);

                subDivVerts[4 * offsetIndex + 0] = leftBottom;
                subDivVerts[4 * offsetIndex + 1] = rightBottom;
                subDivVerts[4 * offsetIndex + 2] = leftUp;
                subDivVerts[4 * offsetIndex + 3] = rightUp;

                var uvLeftBottom = new Vector2(offsetX, offsetY);
                var uvRightBottom = uvLeftBottom + new Vector2(edgeLength, 0);
                var uvLeftUp = uvLeftBottom + new Vector2(0, edgeLength);
                var uvRightUp = uvLeftBottom + new Vector2(edgeLength, edgeLength);

                subDivUvs[4 * offsetIndex + 0] = uvLeftBottom;
                subDivUvs[4 * offsetIndex + 1] = uvRightBottom;
                subDivUvs[4 * offsetIndex + 2] = uvLeftUp;
                subDivUvs[4 * offsetIndex + 3] = uvRightUp;

                subDivIndices[6 * offsetIndex + 0] = 4 * offsetIndex + 0;
                subDivIndices[6 * offsetIndex + 1] = 4 * offsetIndex + 3;
                subDivIndices[6 * offsetIndex + 2] = 4 * offsetIndex + 1;
                subDivIndices[6 * offsetIndex + 3] = 4 * offsetIndex + 3;
                subDivIndices[6 * offsetIndex + 4] = 4 * offsetIndex + 0;
                subDivIndices[6 * offsetIndex + 5] = 4 * offsetIndex + 2;
            }
        }

        var subDivMesh = new Mesh();
        subDivMesh.name = "subDivMesh";
        subDivMesh.SetVertices(subDivVerts);
        subDivMesh.SetTriangles(subDivIndices, 0);
        subDivMesh.SetUVs(0, subDivUvs);
        subDivMesh.RecalculateBounds();
        subDivMesh.RecalculateNormals();
        subDivMesh.RecalculateTangents();

結果