Unity Compute Shader 入门

Compute Shader

  • 创建Shader
  • 设置参数
  • Dispatch()
  • 获取结果

参考

代码

  • ComputeNoise.cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;

    [ExecuteInEditMode]
    [RequireComponent(typeof(MeshRenderer))]
    public class ComputeNoise : MonoBehaviour
    {
    public int resolution = 512;
    public Color color = Color.white;
    [Range(0, 100)] public float seed;

    private ComputeShader m_computeShader;
    private Material m_material;
    private RenderTexture m_texture;

    void OnEnable()
    {
    m_material = new Material(Shader.Find("Unlit/Texture"));
    GetComponent<MeshRenderer>().material = m_material;

    CreateNoise();
    }

    private void CreateNoise()
    {
    if (!m_computeShader)
    {
    #if UNITY_EDITOR
    const string computeShaderFile = "Assets/Dev/Shader/Compute/NoiseTexture.compute";
    m_computeShader = AssetDatabase.LoadAssetAtPath<ComputeShader>(computeShaderFile);
    #endif
    }

    if (!m_computeShader.HasKernel("CSMain")) return;
    int id = m_computeShader.FindKernel("CSMain");

    bool bCreateNewTexture = false;
    if (m_texture == null)
    {
    bCreateNewTexture = true;
    }
    else if (m_texture.width != resolution || m_texture.enableRandomWrite == false)
    {
    bCreateNewTexture = true;
    m_texture.Release();
    }

    if (bCreateNewTexture)
    {
    m_texture = new RenderTexture(resolution, resolution, 24);
    m_texture.enableRandomWrite = true;
    m_texture.Create();
    }

    m_computeShader.SetTexture(id, "Result", m_texture);
    m_computeShader.SetVector("Color", color);
    m_computeShader.SetFloat("Seed", seed);

    m_computeShader.GetKernelThreadGroupSizes(id, out uint groupNumX, out uint groupNumY, out _);
    int numX = Mathf.CeilToInt(resolution / (float) groupNumX);
    int numY = Mathf.CeilToInt(resolution / (float) groupNumY);

    m_computeShader.Dispatch(id, numX, numY, 1);

    if (m_material) m_material.SetTexture("_MainTex", m_texture);
    }
    }
  • NoiseTexture.compute
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #pragma kernel CSMain

    float hash2d_value(float2 uv, float seed = 0)
    {
    uint x = (uint)uv.x << 4;
    uint y = (uint)uv.y << 6;
    return frac(sin(dot(uv, float2(12.9898 + seed + x * y, 78.233))) * 43758.5453);
    }

    RWTexture2D<float4> Result;
    float3 Color;
    float Seed;

    [numthreads(8,8,1)]
    void CSMain(uint3 id : SV_DispatchThreadID)
    {
    uint w, h;
    Result.GetDimensions(w, h);
    if (id.x < w && id.y < h)
    {
    float2 uv = id.xy / float2(w, h);

    float randValue = hash2d_value(uv, Seed);
    Result[id.xy] = float4(randValue * Color, 1);
    }
    }


Unity Compute Shader 入门
https://automask.github.io/wild/2022/06/28/lab/S_Unity_Shader_Compute/
作者
Kyle Zhou
发布于
2022年6月28日
许可协议