# BuildRayTracingAccelerationStructure

> Adds a command to build the RayTracingAccelerationStructure to be used in a ray tracing dispatch or when using inline ray tracing (ray queries).

## Definition

* **Type:** Method
* **Namespace:** [UnityEngine.Rendering](/engine/6000.0/script-reference/unityengine/rendering.md)
* **Assembly:** UnityEngine.CoreModule

## BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure)

Adds a command to build the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be used in a ray tracing dispatch or when using inline ray tracing (ray queries).

```csharp
public void BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure accelerationStructure)
```

### Parameters

**** (\[RayTracingAccelerationStructure]\(/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure)): The [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be generated.

### Remarks

To ensure that the acceleration structure is up to date, call this method before using the acceleration structure in ray tracing shaders (for example before a [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md) call) or when using inline ray tracing.

In the following example, the `Update` method uses a compute shader dispatch to modify the vertex positions of a mesh instance, then the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) is rebuilt.

```csharp
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;

public class RayTracingInstanceManager : MonoBehaviour
{
    public Material instanceMaterial;
    public ComputeShader vertexAnimationShader;
    public RayTracingShader rayTracingShader;

    private RayTracingAccelerationStructure rtas;
    private CommandBuffer cmd;
    private RenderTexture rayTracingOutput;
    private uint cameraWidth = 0;
    private uint cameraHeight = 0;
    private uint meshResolution = 32;
    private Mesh instanceMesh;

    void Start()
    {
        // Create command buffer
        cmd = new CommandBuffer();
        cmd.name = "Ray Tracing Setup";

        InitializeRayTracing();
    }

    private NativeArray<uint> CreateIndexArray(uint resolution)
    {
        uint indexCount = 2 * 3 * resolution * resolution;
        uint[] indices = new uint[indexCount];

        int index = 0;

        for (uint i = 0; i < resolution; i++)
        {
            for (uint j = 0; j < resolution; j++)
            {
                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;

                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;
                indices[index++] = i * (resolution + 1) + j + 1;
            }
        }

        return new NativeArray<uint>(indices, Allocator.Persistent);
    }

    struct Vertex
    {
        public Vector3 position;
    }

    private NativeArray<Vertex> CreateVertexArray(uint resolution)
    {
        uint vertexCount = (resolution + 1) * (resolution + 1);
        Vertex[] vertices = new Vertex[vertexCount];

        float invResolution = 1.0f / (float)resolution;
        float step = 2.0f * invResolution;
        int vertexIndex = 0;
        float posZ = -1.0f;

        for (uint z = 0; z <= resolution; z++)
        {
            float posX = -1.0f;

            for (uint x = 0; x <= resolution; x++)
            {
                vertices[vertexIndex].position = new Vector3(posX, 0, posZ);

                vertexIndex++;
                posX += step;
            }
            posZ += step;
        }

        return new NativeArray<Vertex>(vertices, Allocator.Temp);
    }

    void InitializeRayTracing()
    {
        // Set up acceleration structure
        RayTracingAccelerationStructure.Settings settings = new RayTracingAccelerationStructure.Settings
        {
            managementMode = RayTracingAccelerationStructure.ManagementMode.Manual,
            layerMask = -1
        };
        rtas = new RayTracingAccelerationStructure(settings);
        // Create base mesh on GPU
        instanceMesh = new Mesh();

        if (SystemInfo.supportsComputeShaders)
        {
            instanceMesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
            instanceMesh.indexBufferTarget |= GraphicsBuffer.Target.Raw;
        }

        using (NativeArray<Vertex> varray = CreateVertexArray(meshResolution))
        {
            instanceMesh.SetVertexBufferParams(varray.Length, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3));
            instanceMesh.SetVertexBufferData(varray, 0, 0, varray.Length);
        }

        using (NativeArray<uint> iarray = CreateIndexArray(meshResolution))
        {
            instanceMesh.SetIndexBufferParams(iarray.Length, IndexFormat.UInt32);
            instanceMesh.SetIndexBufferData(iarray, 0, 0, iarray.Length);
            instanceMesh.SetSubMesh(0, new SubMeshDescriptor(0, iarray.Length));
        }

        RayTracingMeshInstanceConfig gpuMeshInstance = new RayTracingMeshInstanceConfig(instanceMesh, 0, instanceMaterial);

        // Make the acceleration structure update every time we call RayTracingAccelerationStructure.Build or CommandBuffer.BuildRayTracingAccelerationStructure.
        gpuMeshInstance.dynamicGeometry = true;

        Matrix4x4 matrix = Matrix4x4.identity;
        matrix.SetTRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity, Vector3.one);

        rtas.AddInstance(gpuMeshInstance, matrix);
    }

    void CreateResources()
    {
        if (cameraWidth != Camera.main.pixelWidth || cameraHeight != Camera.main.pixelHeight)
        {
            if (rayTracingOutput != null)
                rayTracingOutput.Release();
            rayTracingOutput = new RenderTexture(Camera.main.pixelWidth, Camera.main.pixelHeight, 0, RenderTextureFormat.ARGBHalf);
            rayTracingOutput.enableRandomWrite = true;
            rayTracingOutput.Create();
            cameraWidth = (uint)Camera.main.pixelWidth;
            cameraHeight = (uint)Camera.main.pixelHeight;
        }
    }

    void Update()
    {
        if (vertexAnimationShader == null)
        {
            Debug.LogError("Error: Compute shader is missing. Assign a compute shader to the vertexAnimationShader property.");
            return;
        }

        GraphicsBuffer vertexBuffer = instanceMesh.GetVertexBuffer(0);
        cmd.SetComputeBufferParam(vertexAnimationShader, 0, "vertexBuffer", vertexBuffer);

        cmd.SetComputeFloatParam(vertexAnimationShader, "realtimeSinceStartup", Time.realtimeSinceStartup);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexCount", vertexBuffer.count);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexSizeInBytes", vertexBuffer.stride);

        if (vertexBuffer.stride % 4 != 0)
            Debug.Log("Vertex stride must be a multiple of 4.");

        uint kernelGroupSizeX, kernelGroupSizeY, kernelGroupSizeZ;
        vertexAnimationShader.GetKernelThreadGroupSizes(0, out kernelGroupSizeX, out kernelGroupSizeY, out kernelGroupSizeZ);

        int threadGroupsX = (int)(instanceMesh.vertexCount + kernelGroupSizeX - 1) / (int)kernelGroupSizeX;
        cmd.DispatchCompute(vertexAnimationShader, 0, threadGroupsX, 1, 1);

        vertexBuffer.Dispose();

        // Re-build acceleration to take into account modified mesh geometry.
        cmd.BuildRayTracingAccelerationStructure(rtas);
        // The command buffer will be executed in the next OnRenderImage
    }

    [ImageEffectOpaque]
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (!SystemInfo.supportsRayTracing || !rayTracingShader)
        {
            Debug.LogWarning("Warning: The Ray Tracing API is not supported by this GPU or by the current graphics API.");
            Graphics.Blit(src, dest);
            return;
        }
        CreateResources();
        cmd.SetRayTracingShaderPass(rayTracingShader, "Test");
        // Input
        cmd.SetRayTracingAccelerationStructure(rayTracingShader, Shader.PropertyToID("g_AccelStruct"), rtas);
        cmd.SetRayTracingMatrixParam(rayTracingShader, Shader.PropertyToID("g_InvViewMatrix"), Camera.main.cameraToWorldMatrix);
        cmd.SetGlobalVector(Shader.PropertyToID("g_CameraPos"), Camera.main.transform.position);
        // Output
        cmd.SetRayTracingTextureParam(rayTracingShader, Shader.PropertyToID("g_Output"), rayTracingOutput);
        // Execute the raytracing shader
        cmd.DispatchRays(rayTracingShader, "MainRayGenShader", cameraWidth, cameraHeight, 1);
        // Execute command buffer
        Graphics.ExecuteCommandBuffer(cmd);
        cmd.Clear();
        Graphics.Blit(rayTracingOutput, dest);
    }

    void OnDisable()
    {
        // Cleanup
        if (rtas != null)
        {
            rtas.Dispose();
            rtas = null;
        }
        if (instanceMesh != null)
        {
            DestroyImmediate(instanceMesh);
            instanceMesh = null;
        }
        if (cmd != null)
        {
            cmd.Release();
            cmd = null;
        }
        if (rayTracingOutput != null)
        {
            rayTracingOutput.Release();
            rayTracingOutput = null;
        }
    }
}
```

Additional Resources: [CommandBuffer.SetRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setraytracingaccelerationstructure.md), [CommandBuffer.SetGlobalRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setglobalraytracingaccelerationstructure.md), [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md), [RayTracingAccelerationStructure.Build](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure/build.md).

## BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure, Vector3)

Adds a command to build the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be used in a ray tracing dispatch or when using inline ray tracing (ray queries).

```csharp
public void BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure accelerationStructure, Vector3 relativeOrigin)
```

### Parameters

**** (\[RayTracingAccelerationStructure]\(/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure)): The [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be generated.**** (\[Vector3]\(/engine/6000.0/script-reference/unityengine/vector3)): The relative origin of ray tracing instances. The default value is [Vector3.zero](/engine/6000.0/script-reference/unityengine/vector3/zero.md). To use camera-relative ray-tracing, set this parameter to the position of the camera.

### Remarks

To ensure that the acceleration structure is up to date, call this method before using the acceleration structure in ray tracing shaders (for example before a [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md) call) or when using inline ray tracing.

In the following example, the `Update` method uses a compute shader dispatch to modify the vertex positions of a mesh instance, then the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) is rebuilt.

```csharp
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;

public class RayTracingInstanceManager : MonoBehaviour
{
    public Material instanceMaterial;
    public ComputeShader vertexAnimationShader;
    public RayTracingShader rayTracingShader;

    private RayTracingAccelerationStructure rtas;
    private CommandBuffer cmd;
    private RenderTexture rayTracingOutput;
    private uint cameraWidth = 0;
    private uint cameraHeight = 0;
    private uint meshResolution = 32;
    private Mesh instanceMesh;

    void Start()
    {
        // Create command buffer
        cmd = new CommandBuffer();
        cmd.name = "Ray Tracing Setup";

        InitializeRayTracing();
    }

    private NativeArray<uint> CreateIndexArray(uint resolution)
    {
        uint indexCount = 2 * 3 * resolution * resolution;
        uint[] indices = new uint[indexCount];

        int index = 0;

        for (uint i = 0; i < resolution; i++)
        {
            for (uint j = 0; j < resolution; j++)
            {
                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;

                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;
                indices[index++] = i * (resolution + 1) + j + 1;
            }
        }

        return new NativeArray<uint>(indices, Allocator.Persistent);
    }

    struct Vertex
    {
        public Vector3 position;
    }

    private NativeArray<Vertex> CreateVertexArray(uint resolution)
    {
        uint vertexCount = (resolution + 1) * (resolution + 1);
        Vertex[] vertices = new Vertex[vertexCount];

        float invResolution = 1.0f / (float)resolution;
        float step = 2.0f * invResolution;
        int vertexIndex = 0;
        float posZ = -1.0f;

        for (uint z = 0; z <= resolution; z++)
        {
            float posX = -1.0f;

            for (uint x = 0; x <= resolution; x++)
            {
                vertices[vertexIndex].position = new Vector3(posX, 0, posZ);

                vertexIndex++;
                posX += step;
            }
            posZ += step;
        }

        return new NativeArray<Vertex>(vertices, Allocator.Temp);
    }

    void InitializeRayTracing()
    {
        // Set up acceleration structure
        RayTracingAccelerationStructure.Settings settings = new RayTracingAccelerationStructure.Settings
        {
            managementMode = RayTracingAccelerationStructure.ManagementMode.Manual,
            layerMask = -1
        };
        rtas = new RayTracingAccelerationStructure(settings);
        // Create base mesh on GPU
        instanceMesh = new Mesh();

        if (SystemInfo.supportsComputeShaders)
        {
            instanceMesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
            instanceMesh.indexBufferTarget |= GraphicsBuffer.Target.Raw;
        }

        using (NativeArray<Vertex> varray = CreateVertexArray(meshResolution))
        {
            instanceMesh.SetVertexBufferParams(varray.Length, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3));
            instanceMesh.SetVertexBufferData(varray, 0, 0, varray.Length);
        }

        using (NativeArray<uint> iarray = CreateIndexArray(meshResolution))
        {
            instanceMesh.SetIndexBufferParams(iarray.Length, IndexFormat.UInt32);
            instanceMesh.SetIndexBufferData(iarray, 0, 0, iarray.Length);
            instanceMesh.SetSubMesh(0, new SubMeshDescriptor(0, iarray.Length));
        }

        RayTracingMeshInstanceConfig gpuMeshInstance = new RayTracingMeshInstanceConfig(instanceMesh, 0, instanceMaterial);

        // Make the acceleration structure update every time we call RayTracingAccelerationStructure.Build or CommandBuffer.BuildRayTracingAccelerationStructure.
        gpuMeshInstance.dynamicGeometry = true;

        Matrix4x4 matrix = Matrix4x4.identity;
        matrix.SetTRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity, Vector3.one);

        rtas.AddInstance(gpuMeshInstance, matrix);
    }

    void CreateResources()
    {
        if (cameraWidth != Camera.main.pixelWidth || cameraHeight != Camera.main.pixelHeight)
        {
            if (rayTracingOutput != null)
                rayTracingOutput.Release();
            rayTracingOutput = new RenderTexture(Camera.main.pixelWidth, Camera.main.pixelHeight, 0, RenderTextureFormat.ARGBHalf);
            rayTracingOutput.enableRandomWrite = true;
            rayTracingOutput.Create();
            cameraWidth = (uint)Camera.main.pixelWidth;
            cameraHeight = (uint)Camera.main.pixelHeight;
        }
    }

    void Update()
    {
        if (vertexAnimationShader == null)
        {
            Debug.LogError("Error: Compute shader is missing. Assign a compute shader to the vertexAnimationShader property.");
            return;
        }

        GraphicsBuffer vertexBuffer = instanceMesh.GetVertexBuffer(0);
        cmd.SetComputeBufferParam(vertexAnimationShader, 0, "vertexBuffer", vertexBuffer);

        cmd.SetComputeFloatParam(vertexAnimationShader, "realtimeSinceStartup", Time.realtimeSinceStartup);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexCount", vertexBuffer.count);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexSizeInBytes", vertexBuffer.stride);

        if (vertexBuffer.stride % 4 != 0)
            Debug.Log("Vertex stride must be a multiple of 4.");

        uint kernelGroupSizeX, kernelGroupSizeY, kernelGroupSizeZ;
        vertexAnimationShader.GetKernelThreadGroupSizes(0, out kernelGroupSizeX, out kernelGroupSizeY, out kernelGroupSizeZ);

        int threadGroupsX = (int)(instanceMesh.vertexCount + kernelGroupSizeX - 1) / (int)kernelGroupSizeX;
        cmd.DispatchCompute(vertexAnimationShader, 0, threadGroupsX, 1, 1);

        vertexBuffer.Dispose();

        // Re-build acceleration to take into account modified mesh geometry.
        cmd.BuildRayTracingAccelerationStructure(rtas);
        // The command buffer will be executed in the next OnRenderImage
    }

    [ImageEffectOpaque]
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (!SystemInfo.supportsRayTracing || !rayTracingShader)
        {
            Debug.LogWarning("Warning: The Ray Tracing API is not supported by this GPU or by the current graphics API.");
            Graphics.Blit(src, dest);
            return;
        }
        CreateResources();
        cmd.SetRayTracingShaderPass(rayTracingShader, "Test");
        // Input
        cmd.SetRayTracingAccelerationStructure(rayTracingShader, Shader.PropertyToID("g_AccelStruct"), rtas);
        cmd.SetRayTracingMatrixParam(rayTracingShader, Shader.PropertyToID("g_InvViewMatrix"), Camera.main.cameraToWorldMatrix);
        cmd.SetGlobalVector(Shader.PropertyToID("g_CameraPos"), Camera.main.transform.position);
        // Output
        cmd.SetRayTracingTextureParam(rayTracingShader, Shader.PropertyToID("g_Output"), rayTracingOutput);
        // Execute the raytracing shader
        cmd.DispatchRays(rayTracingShader, "MainRayGenShader", cameraWidth, cameraHeight, 1);
        // Execute command buffer
        Graphics.ExecuteCommandBuffer(cmd);
        cmd.Clear();
        Graphics.Blit(rayTracingOutput, dest);
    }

    void OnDisable()
    {
        // Cleanup
        if (rtas != null)
        {
            rtas.Dispose();
            rtas = null;
        }
        if (instanceMesh != null)
        {
            DestroyImmediate(instanceMesh);
            instanceMesh = null;
        }
        if (cmd != null)
        {
            cmd.Release();
            cmd = null;
        }
        if (rayTracingOutput != null)
        {
            rayTracingOutput.Release();
            rayTracingOutput = null;
        }
    }
}
```

Additional Resources: [CommandBuffer.SetRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setraytracingaccelerationstructure.md), [CommandBuffer.SetGlobalRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setglobalraytracingaccelerationstructure.md), [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md), [RayTracingAccelerationStructure.Build](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure/build.md).

## BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure, BuildSettings)

Adds a command to build the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be used in a ray tracing dispatch or when using inline ray tracing (ray queries).

```csharp
public void BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure accelerationStructure, RayTracingAccelerationStructure.BuildSettings buildSettings)
```

### Parameters

**** (\[RayTracingAccelerationStructure]\(/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure)): The [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) to be generated.**** (\[BuildSettings]\(/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure/buildsettings)): The [BuildSettings](/engine/6000.0/script-reference/unityeditor/build/content/buildsettings.md) to use.

### Remarks

To ensure that the acceleration structure is up to date, call this method before using the acceleration structure in ray tracing shaders (for example before a [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md) call) or when using inline ray tracing.

In the following example, the `Update` method uses a compute shader dispatch to modify the vertex positions of a mesh instance, then the [RayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure.md) is rebuilt.

```csharp
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;

public class RayTracingInstanceManager : MonoBehaviour
{
    public Material instanceMaterial;
    public ComputeShader vertexAnimationShader;
    public RayTracingShader rayTracingShader;

    private RayTracingAccelerationStructure rtas;
    private CommandBuffer cmd;
    private RenderTexture rayTracingOutput;
    private uint cameraWidth = 0;
    private uint cameraHeight = 0;
    private uint meshResolution = 32;
    private Mesh instanceMesh;

    void Start()
    {
        // Create command buffer
        cmd = new CommandBuffer();
        cmd.name = "Ray Tracing Setup";

        InitializeRayTracing();
    }

    private NativeArray<uint> CreateIndexArray(uint resolution)
    {
        uint indexCount = 2 * 3 * resolution * resolution;
        uint[] indices = new uint[indexCount];

        int index = 0;

        for (uint i = 0; i < resolution; i++)
        {
            for (uint j = 0; j < resolution; j++)
            {
                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;

                indices[index++] = i * (resolution + 1) + j;
                indices[index++] = (i + 1) * (resolution + 1) + j + 1;
                indices[index++] = i * (resolution + 1) + j + 1;
            }
        }

        return new NativeArray<uint>(indices, Allocator.Persistent);
    }

    struct Vertex
    {
        public Vector3 position;
    }

    private NativeArray<Vertex> CreateVertexArray(uint resolution)
    {
        uint vertexCount = (resolution + 1) * (resolution + 1);
        Vertex[] vertices = new Vertex[vertexCount];

        float invResolution = 1.0f / (float)resolution;
        float step = 2.0f * invResolution;
        int vertexIndex = 0;
        float posZ = -1.0f;

        for (uint z = 0; z <= resolution; z++)
        {
            float posX = -1.0f;

            for (uint x = 0; x <= resolution; x++)
            {
                vertices[vertexIndex].position = new Vector3(posX, 0, posZ);

                vertexIndex++;
                posX += step;
            }
            posZ += step;
        }

        return new NativeArray<Vertex>(vertices, Allocator.Temp);
    }

    void InitializeRayTracing()
    {
        // Set up acceleration structure
        RayTracingAccelerationStructure.Settings settings = new RayTracingAccelerationStructure.Settings
        {
            managementMode = RayTracingAccelerationStructure.ManagementMode.Manual,
            layerMask = -1
        };
        rtas = new RayTracingAccelerationStructure(settings);
        // Create base mesh on GPU
        instanceMesh = new Mesh();

        if (SystemInfo.supportsComputeShaders)
        {
            instanceMesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
            instanceMesh.indexBufferTarget |= GraphicsBuffer.Target.Raw;
        }

        using (NativeArray<Vertex> varray = CreateVertexArray(meshResolution))
        {
            instanceMesh.SetVertexBufferParams(varray.Length, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3));
            instanceMesh.SetVertexBufferData(varray, 0, 0, varray.Length);
        }

        using (NativeArray<uint> iarray = CreateIndexArray(meshResolution))
        {
            instanceMesh.SetIndexBufferParams(iarray.Length, IndexFormat.UInt32);
            instanceMesh.SetIndexBufferData(iarray, 0, 0, iarray.Length);
            instanceMesh.SetSubMesh(0, new SubMeshDescriptor(0, iarray.Length));
        }

        RayTracingMeshInstanceConfig gpuMeshInstance = new RayTracingMeshInstanceConfig(instanceMesh, 0, instanceMaterial);

        // Make the acceleration structure update every time we call RayTracingAccelerationStructure.Build or CommandBuffer.BuildRayTracingAccelerationStructure.
        gpuMeshInstance.dynamicGeometry = true;

        Matrix4x4 matrix = Matrix4x4.identity;
        matrix.SetTRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity, Vector3.one);

        rtas.AddInstance(gpuMeshInstance, matrix);
    }

    void CreateResources()
    {
        if (cameraWidth != Camera.main.pixelWidth || cameraHeight != Camera.main.pixelHeight)
        {
            if (rayTracingOutput != null)
                rayTracingOutput.Release();
            rayTracingOutput = new RenderTexture(Camera.main.pixelWidth, Camera.main.pixelHeight, 0, RenderTextureFormat.ARGBHalf);
            rayTracingOutput.enableRandomWrite = true;
            rayTracingOutput.Create();
            cameraWidth = (uint)Camera.main.pixelWidth;
            cameraHeight = (uint)Camera.main.pixelHeight;
        }
    }

    void Update()
    {
        if (vertexAnimationShader == null)
        {
            Debug.LogError("Error: Compute shader is missing. Assign a compute shader to the vertexAnimationShader property.");
            return;
        }

        GraphicsBuffer vertexBuffer = instanceMesh.GetVertexBuffer(0);
        cmd.SetComputeBufferParam(vertexAnimationShader, 0, "vertexBuffer", vertexBuffer);

        cmd.SetComputeFloatParam(vertexAnimationShader, "realtimeSinceStartup", Time.realtimeSinceStartup);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexCount", vertexBuffer.count);
        cmd.SetComputeIntParam(vertexAnimationShader, "vertexSizeInBytes", vertexBuffer.stride);

        if (vertexBuffer.stride % 4 != 0)
            Debug.Log("Vertex stride must be a multiple of 4.");

        uint kernelGroupSizeX, kernelGroupSizeY, kernelGroupSizeZ;
        vertexAnimationShader.GetKernelThreadGroupSizes(0, out kernelGroupSizeX, out kernelGroupSizeY, out kernelGroupSizeZ);

        int threadGroupsX = (int)(instanceMesh.vertexCount + kernelGroupSizeX - 1) / (int)kernelGroupSizeX;
        cmd.DispatchCompute(vertexAnimationShader, 0, threadGroupsX, 1, 1);

        vertexBuffer.Dispose();

        // Re-build acceleration to take into account modified mesh geometry.
        cmd.BuildRayTracingAccelerationStructure(rtas);
        // The command buffer will be executed in the next OnRenderImage
    }

    [ImageEffectOpaque]
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (!SystemInfo.supportsRayTracing || !rayTracingShader)
        {
            Debug.LogWarning("Warning: The Ray Tracing API is not supported by this GPU or by the current graphics API.");
            Graphics.Blit(src, dest);
            return;
        }
        CreateResources();
        cmd.SetRayTracingShaderPass(rayTracingShader, "Test");
        // Input
        cmd.SetRayTracingAccelerationStructure(rayTracingShader, Shader.PropertyToID("g_AccelStruct"), rtas);
        cmd.SetRayTracingMatrixParam(rayTracingShader, Shader.PropertyToID("g_InvViewMatrix"), Camera.main.cameraToWorldMatrix);
        cmd.SetGlobalVector(Shader.PropertyToID("g_CameraPos"), Camera.main.transform.position);
        // Output
        cmd.SetRayTracingTextureParam(rayTracingShader, Shader.PropertyToID("g_Output"), rayTracingOutput);
        // Execute the raytracing shader
        cmd.DispatchRays(rayTracingShader, "MainRayGenShader", cameraWidth, cameraHeight, 1);
        // Execute command buffer
        Graphics.ExecuteCommandBuffer(cmd);
        cmd.Clear();
        Graphics.Blit(rayTracingOutput, dest);
    }

    void OnDisable()
    {
        // Cleanup
        if (rtas != null)
        {
            rtas.Dispose();
            rtas = null;
        }
        if (instanceMesh != null)
        {
            DestroyImmediate(instanceMesh);
            instanceMesh = null;
        }
        if (cmd != null)
        {
            cmd.Release();
            cmd = null;
        }
        if (rayTracingOutput != null)
        {
            rayTracingOutput.Release();
            rayTracingOutput = null;
        }
    }
}
```

Additional Resources: [CommandBuffer.SetRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setraytracingaccelerationstructure.md), [CommandBuffer.SetGlobalRayTracingAccelerationStructure](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/setglobalraytracingaccelerationstructure.md), [CommandBuffer.DispatchRays](/engine/6000.0/script-reference/unityengine/rendering/commandbuffer/dispatchrays.md), [RayTracingAccelerationStructure.Build](/engine/6000.0/script-reference/unityengine/rendering/raytracingaccelerationstructure/build.md).
