RWStructuredBuffer in Vertex shader?

Is it possible to use an RWStructuredBuffer in a vertex shader in Unity? Most I have read indicates it should be possible, but I am not having any success. Using a read-only StructuredBuffer does work.

Note that I am not using a Compute Shader. I create a ComputeBuffer on the CPU side and fill it with some vertex positions, then use DrawProcedural and read those vertex positions. Eventually I’d like to be able write back to the buffer when I get this working, but for now I’m simply reading data. StructuredBuffer works, RWStructuredBuffer does not.

Anyone know if this should work?

3 Likes

I’m also interested in this, +1

Basic template.

// https://github.com/przemyslawzaworski
// Set plane position (Y=0.0)
// Collider is generated from vertex shader, using RWStructuredBuffer to transfer data.

using UnityEngine;

public class rw_structured_buffer : MonoBehaviour
{
    public Material material;
    public GameObject plane;
    ComputeBuffer compute_buffer;
    Mesh mesh;
    Vector3[] data;

    void Start()
    {
        mesh = plane.GetComponent<Collider>().GetComponent<MeshFilter>().sharedMesh;
        data = mesh.vertices;
        compute_buffer = new ComputeBuffer(data.Length, sizeof(float)*3, ComputeBufferType.Default);
    }

    void Update()
    {
        Graphics.ClearRandomWriteTargets();
        material.SetPass(0);
        material.SetBuffer("data", compute_buffer);
        Graphics.SetRandomWriteTarget(1, compute_buffer,false);
        compute_buffer.GetData(data);
        if (data!=null && plane.GetComponent<Renderer>().isVisible && Time.frameCount % 2 == 0)
        {
            mesh.vertices = data;
            DestroyImmediate(plane.GetComponent<MeshCollider>());
            MeshCollider mesh_collider = plane.AddComponent<MeshCollider>();
            mesh_collider.sharedMesh = mesh;
        }
    }

    void OnDestroy()
    {
        compute_buffer.Dispose();
    }
}
//https://github.com/przemyslawzaworski
//Assign displacement map (R) to properties.

Shader "RW Structured Buffer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "black" {}
    }
    Subshader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vertex_shader
            #pragma fragment pixel_shader
            #pragma target 5.0

            sampler2D _MainTex;
            uniform RWStructuredBuffer<float3> data : register(u1);

            struct APPDATA
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                uint id : SV_VertexID;       
            };

            struct SHADERDATA
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            SHADERDATA vertex_shader (APPDATA IN)
            {
                SHADERDATA vs;
                IN.vertex.y = 0.0-tex2Dlod(_MainTex,float4(IN.uv,0,0)).r*(sin(_Time.g)*0.5+0.5);
                data[IN.id] = IN.vertex.xyz;
                vs.vertex = UnityObjectToClipPos(IN.vertex);
                vs.uv = IN.uv;
                return vs;
            }

            float4 pixel_shader (SHADERDATA ps) : SV_TARGET
            {
                return tex2D(_MainTex,ps.uv);
            }

            ENDCG
        }
    }
}
6 Likes

Unfortunately, the above solution doesn’t work on some GPUs.
First, code was executed on laptop with Intel integrated graphics card, it worked well, so I decided to publish it.
Today I tried to run code on NVIDIA GPU, but still I see pink color (by the way, there are no errors in debug console, so it strange).
Could someone try to run code in different machine to compare results ?

RWStructuredBuffer not working on vertex shader +1

Unity 2018.1.3f1
Windows 10 Editor 64 bits
intel HD Graphic 530

“This object is supported for the following types of shaders: Pixel, Compute”

1 Like

Issue has been solved.

RWStructuredBuffer is supported for all types of shaders in hardware with minimum D3D_FEATURE_LEVEL_11_1.
(minimum AMD Radeon HD 8000 or NVIDIA GeForce GTX 900 or Intel HD Graphics 5000/4x00 and Windows 8).
For hardware with D3D_FEATURE_LEVEL_11_0 is only supported for pixel and compute shaders.

So, now it explains, why my sample code works on the newest GPUs and not on NVIDIA GTX 660.
I have to upgrade graphics card.

So any compatible DX 11_1 rendering API should be able to read from a RWStructuredBuffer in the vertex and/or fragment shader?

Yes