Search code examples
c#unity-game-enginecompute-shader

How to fix computer shader errors in Unity


I am trying to make a life game in Unity but I get errors.

Compute shader (cs): Property (Result) at kernel index (1) is not set
UnityEngine.StackTraceUtility:ExtractStackTrace ()
CSTest:Update () (at Assets/Scripts/Pixel/CSTest.cs:43)

This is a script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CSTest : MonoBehaviour
{
    [SerializeField]
    Material graphBackgroundMat;

    [SerializeField]
    ComputeShader computeShader;

    [SerializeField]
    int Size = 256;
    int kernel;

    public bool Run = false;

    RenderTexture renderTexture;

    // Start is called before the first frame update
    void Start()
    {
        renderTexture = new RenderTexture(Size, Size / 2, 0, RenderTextureFormat.ARGB32);
        renderTexture.enableRandomWrite = true;
        renderTexture.filterMode = FilterMode.Point;
        renderTexture.Create();


        int initKernel = computeShader.FindKernel("Init");
        computeShader.SetTexture(initKernel, "Result", renderTexture);
        graphBackgroundMat.SetTexture("_MainTex", renderTexture);

        computeShader.Dispatch(initKernel, Mathf.CeilToInt(Size / 4), Mathf.CeilToInt(Size / 4), 1);

        kernel = computeShader.FindKernel("CSMain");
    }

     void Update()
    {
        if (Run) 
        {
            computeShader.Dispatch(kernel, Mathf.CeilToInt(Size / 4), Mathf.CeilToInt(Size / 4), 1);
        }
        
    }

    private void OnDestroy()
    {
        renderTexture.Release();
    }
}


This is a shader.

#pragma kernel Init
#pragma kernel CSMain

RWTexture2D<float4> Result;

float rand(float2 co) {
    return 0.5 + (frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453)) * 0.5;
}


[numthreads(4, 4, 1)]
void Init(uint3 id : SV_DispatchThreadID)
{
    float rnd = rand(id.xy);
    Result[id.xy] = rnd > .95 ? float4(1, 1, 1, 1) : float4(0, 0, 0, 0);
}


[numthreads(4, 4, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    int sum = 0;
    for (int x = -1; x <= 1; x++) {
        for (int y = -1; y <= 1; y++) {
            if (x == 0 && y == 0)
            {
                continue;
            }
            if (Result[id.xy + float2(x, y)].x > 0)
            {
                sum++;
            }
        }
    }

    if (Result[id.xy].x > 0)
    {
        Result[id.xy] = (sum == 2 || sum == 3) ? float4(1, 0, 0, 1) : float4(0, 0, 0, 1);
    }
    else
    {
        Result[id.xy] = (sum == 3) ? float4(1, 1, 0, 1) : float4(0, 0, 0, 1);
    }
}

When executed, a black-and-white dot is displayed, but the texture is not updated, and it seems that only Init() is called and CSMain() is not called.

1

The version of Unity is 2021.3.4f1 and the platform is Android. I don't know if I have the wrong shaders or the wrong script.

2

#pragma kernel directive and function names are correct, and texture property names are correct.


Solution

  • Because you only set the render texture to the init kernel, you need to set the texture to the main kernel too.

    computeShader.SetTexture(kernel, "Result", renderTexture);