Is the GraphicsBuffer API not supported in WebGL builds?

Hello! I’m trying to do some simple mesh deformation using Unity’s new GraphicsBuffers and a compute shader. I’m using Unity version 2021.2.13f1 and building for WebGL version 2. So far everything works in the editor but not in build version. Right after it finishes loading, it throws this error:

RuntimeError: index out of bounds
BufferManagerGLES::AcquireBuffer(unsigned long, DataBufferGLES::BufferUsage, bool)@http://localhost:64826/Build/Build.wasm:wasm-function[9427]:0x4255d6
GfxDeviceGLES::InitializeBufferInternal(GfxBuffer*, void const*, GfxUpdateBufferFlags)@http://localhost:64826/Build/Build.wasm:wasm-function[9340]:0x41aaa1
Mesh::CreateMesh()@http://localhost:64826/Build/Build.wasm:wasm-function[10544]:0x4bcb2e
...

From the error I’m guessing that the GraphicsBuffer API isn’t supported in WebGL builds. Still, I’ve wanted to ask and confirm if that is really the case. I know this is a relatively new feature, so I’ve tried to look up all limitations that apply to WebGL and shaders, but I haven’t found anything about GraphicsBuffers. Just to be sure, here is my simple compute shader:

#pragma kernel CSMain

float Time;
RWByteAddressBuffer Vertices;

[numthreads(1,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint y = id.x / 2;
    uint x = id.x % 2;

    uint rawId = id * 3 << 2;
    float3 pos = float3(x, y, sin(Time + id.x));

    Vertices.Store3(rawId, asuint(pos));
}

and the code that dispatches this shader (I’ve made attempts to fix it so it’s a bit messy):

using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ShaderDispatcher : MonoBehaviour
{
    [SerializeField] private Mesh mesh;
    [SerializeField] private ComputeShader shader;

    private MeshFilter _meshFilter;
    private GraphicsBuffer _vertexBuffer;

    private void Awake()
    {
        _meshFilter = GetComponent<MeshFilter>();
    }

    void Start()
    {
        mesh = new Mesh();

        mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
        mesh.indexBufferTarget  |= GraphicsBuffer.Target.Raw;
        mesh.SetVertexBufferParams(3, new VertexAttributeDescriptor(VertexAttribute.Position, dimension: 3, stream: 0));

        mesh.SetIndexBufferParams(
            3,
            IndexFormat.UInt32
        );

        mesh.SetIndexBufferData(new uint[] {0, 1, 2}, 0, 0, 3);

        mesh.subMeshCount = 1;
        mesh.SetSubMesh(
            0,
            new SubMeshDescriptor(0, 3),
            MeshUpdateFlags.DontRecalculateBounds | MeshUpdateFlags.DontValidateIndices
        );

        _vertexBuffer = mesh.GetVertexBuffer(0);
        _meshFilter.mesh = mesh;
    }

    private void Update()
    {
        shader.SetFloat("Time", Time.time);
        shader.SetBuffer(0, "Vertices", _vertexBuffer);
        shader.Dispatch(0, 3, 1, 1);
    }
}

Please, I would be grateful if anyone could confirm that is indeed the case, or pinpoint any mistakes or alternatives I could have made while writing this code. Thank you kind strangers!

Unfortunately GraphicsBuffers, ComputeBuffers and ComputeShaders will not be supported in WebGL builds.

WebGL has dropped any plans for expansion—including compute support—in favor of the upcoming WebGPU standard, which will act as WebGL’s successor: WebGL 2.0 Compute

Unity is following suit with their development: Early access to the new WebGPU backend

This a 2 years old thread. Might want to not necro old posts.

As long as there are Unity WebGL developers out there, and this thread still comes up top when googling “unity webgl graphicsbuffer”, it is relevant and worth answering.

If the topic is not for you, just move along.

4 Likes

Wow. I have long forgotten about this post and didn’t expect any reply. Thank you! I didn’t know WebGL had a successor, so at least I learned something new today.

For anyone who comes across this post: I don’t remember exactly how I solved this problem, but I think I used textures instead to pass vertex data to a vertex shader, which then displaced the vertices. I hope this helps!

1 Like