0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unity RenderPrimitiveIndexedの動作について

Last updated at Posted at 2025-12-04

この記事の構成

基準となるコードを示します。この基準コードの当該関数の引数を変更することで、どのような動作をしているかを特定します。

基準コード

シェーダー(変更しない)

下の図のように、SV_VertexIDによってx座標とy座標を計算してフラグメントshaderに渡すだけのコードです。

インスタンスIDによって別インスタンスの描写は別の行にするようにもしています。インスタンス数を増やすことで上にコピーができるような感じになります。

こっちは変更しません。
image.png

Shader "Unlit/Test_PrimitiveQuad"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct appdata
            {
                uint index : SV_VertexID;
                uint instanceIndex: SV_InstanceID;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                float x = v.index / 2 *0.7;
                float y = v.index % 2 *0.7;
                y = y + v.instanceIndex;// インスタンスIDで行をずらす
                o.pos = float4(x,y,0,1);
                o.pos = UnityObjectToClipPos(o.pos);
                o.uv = float2(x,y);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = float4(1, 0, 0, 1);
                return col;
            }
            ENDCG
        }
    }
}

MonoBehaviour

using Unity.Collections;
using UnityEngine;

public class Test_PrimitiveQuad : MonoBehaviour
{
    public Material mat;
    RenderParams param;
    GraphicsBuffer indexBuffer;
    public static GraphicsBuffer MakeIndexBuffer()
    {
        GraphicsBuffer result = new GraphicsBuffer(GraphicsBuffer.Target.Index, 6, 2);
        NativeArray<ushort> cpuBuffer = new NativeArray<ushort>(6, Allocator.Temp);
        cpuBuffer[0] = 0;
        cpuBuffer[1] = 1;
        cpuBuffer[2] = 2;
        cpuBuffer[3] = 2;
        cpuBuffer[4] = 3;
        cpuBuffer[5] = 4;
        result.SetData(cpuBuffer);
        return result;
    }
    void Start()
    {
        param = new RenderParams(mat);
        indexBuffer = MakeIndexBuffer();
        param.worldBounds = new Bounds(Vector3.zero, 10000 * Vector3.one); // use tighter bounds
    }

    void Update()
    {
        Graphics.RenderPrimitivesIndexed(param, MeshTopology.Triangles, indexBuffer, 6, startIndex:0, instanceCount: 4);
    }
}

基準コードの結果

image.png

わかったこと

・インデックスバッファから三つずつ使用する。
・インデックスバッファの値がそのまま渡される

実験

範囲外のインデックスは0として実行する

基準コードでは[0][1][2] [3][4][5]の値のインデックスを使用していました。
startIndexが1だと[1][2][3] [4][5][6] としたいところですが、vertexCount = 6なので[6]は範囲外になり、[4][5]0というふうになります。

変更した部分

public static GraphicsBuffer MakeIndexBuffer()
    {
        GraphicsBuffer result = new GraphicsBuffer(GraphicsBuffer.Target.Index, 6, 2);
        NativeArray<ushort> cpuBuffer = new NativeArray<ushort>(6, Allocator.Temp);
        cpuBuffer[0] = 4;
        cpuBuffer[1] = 6;
        cpuBuffer[2] = 7;
        cpuBuffer[3] = 8;
        cpuBuffer[4] = 5;
        cpuBuffer[5] = 4;
        result.SetData(cpuBuffer);
        return result;
    }

    void Update()
    {
        Graphics.RenderPrimitivesIndexed(param, MeshTopology.Triangles, indexBuffer, 6, startIndex:1, instanceCount: 4);
    }

結果

右の三角形が([1] = 6,[2] = 7, [3] = 8)で、左が([4] = 5,[5] = 4,[6] = 0)の三角形です。
image.png

わからないこと

トロポジーをQuadにしても、三角形と変わりませんでした。四角形用のインデックスの指定方法もわかりません。これを特定する実験が増えたら追記するかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?