Search Unity

RWStructuredBuffer in Vertex shader?

Discussion in 'Shaders' started by PsyDev, May 25, 2016.

  1. PsyDev

    PsyDev

    Joined:
    Sep 30, 2015
    Posts:
    31
    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?
     
    kilo32, Agent0023 and Assembler-Maze like this.
  2. Assembler-Maze

    Assembler-Maze

    Joined:
    Jan 6, 2016
    Posts:
    630
    I'm also interested in this, +1
     
  3. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Basic template.

    Code (CSharp):
    1. // https://github.com/przemyslawzaworski
    2. // Set plane position (Y=0.0)
    3. // Collider is generated from vertex shader, using RWStructuredBuffer to transfer data.
    4.  
    5. using UnityEngine;
    6.  
    7. public class rw_structured_buffer : MonoBehaviour
    8. {
    9.     public Material material;
    10.     public GameObject plane;
    11.     ComputeBuffer compute_buffer;
    12.     Mesh mesh;
    13.     Vector3[] data;
    14.  
    15.     void Start()
    16.     {
    17.         mesh = plane.GetComponent<Collider>().GetComponent<MeshFilter>().sharedMesh;
    18.         data = mesh.vertices;
    19.         compute_buffer = new ComputeBuffer(data.Length, sizeof(float)*3, ComputeBufferType.Default);
    20.     }
    21.  
    22.     void Update()
    23.     {
    24.         Graphics.ClearRandomWriteTargets();
    25.         material.SetPass(0);
    26.         material.SetBuffer("data", compute_buffer);
    27.         Graphics.SetRandomWriteTarget(1, compute_buffer,false);
    28.         compute_buffer.GetData(data);
    29.         if (data!=null && plane.GetComponent<Renderer>().isVisible && Time.frameCount % 2 == 0)
    30.         {
    31.             mesh.vertices = data;
    32.             DestroyImmediate(plane.GetComponent<MeshCollider>());
    33.             MeshCollider mesh_collider = plane.AddComponent<MeshCollider>();
    34.             mesh_collider.sharedMesh = mesh;
    35.         }
    36.     }
    37.  
    38.     void OnDestroy()
    39.     {
    40.         compute_buffer.Dispose();
    41.     }
    42. }
    Code (CSharp):
    1. //https://github.com/przemyslawzaworski
    2. //Assign displacement map (R) to properties.
    3.  
    4. Shader "RW Structured Buffer"
    5. {
    6.     Properties
    7.     {
    8.         _MainTex ("Texture", 2D) = "black" {}
    9.     }
    10.     Subshader
    11.     {
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vertex_shader
    16.             #pragma fragment pixel_shader
    17.             #pragma target 5.0
    18.  
    19.             sampler2D _MainTex;
    20.             uniform RWStructuredBuffer<float3> data : register(u1);
    21.  
    22.             struct APPDATA
    23.             {
    24.                 float4 vertex : POSITION;
    25.                 float2 uv : TEXCOORD0;
    26.                 uint id : SV_VertexID;      
    27.             };
    28.  
    29.             struct SHADERDATA
    30.             {
    31.                 float4 vertex : SV_POSITION;
    32.                 float2 uv : TEXCOORD0;
    33.             };
    34.  
    35.             SHADERDATA vertex_shader (APPDATA IN)
    36.             {
    37.                 SHADERDATA vs;
    38.                 IN.vertex.y = 0.0-tex2Dlod(_MainTex,float4(IN.uv,0,0)).r*(sin(_Time.g)*0.5+0.5);
    39.                 data[IN.id] = IN.vertex.xyz;
    40.                 vs.vertex = UnityObjectToClipPos(IN.vertex);
    41.                 vs.uv = IN.uv;
    42.                 return vs;
    43.             }
    44.  
    45.             float4 pixel_shader (SHADERDATA ps) : SV_TARGET
    46.             {
    47.                 return tex2D(_MainTex,ps.uv);
    48.             }
    49.  
    50.             ENDCG
    51.         }
    52.     }
    53. }
     
    ml785, ChrisHandzlik, haojiao and 3 others like this.
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    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 ?
     
  5. vincentchu_atalonventures

    vincentchu_atalonventures

    Joined:
    May 4, 2018
    Posts:
    16
    RWStructuredBuffer not working on vertex shader +1

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

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
  7. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    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.
     
  8. jjxtra

    jjxtra

    Joined:
    Aug 30, 2013
    Posts:
    1,464
    So any compatible DX 11_1 rendering API should be able to read from a RWStructuredBuffer in the vertex and/or fragment shader?
     
  9. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    Yes