Unity ComputeShader 基础语法与使用教程

Unity ComputeShader 基础语法与使用教程

一、基础概念

ComputeShader 是 Unity 中利用 GPU 并行计算能力的工具,适用于大规模数据处理(如粒子模拟、图像处理、物理计算等)。其核心特点:

  • 独立于渲染管线:不依赖顶点/片元着色器,直接操作内存数据。
  • 并行计算:通过线程组(Thread Groups)实现多线程并行处理。
  • 数据驱动 :通过 ComputeBuffer 或 RWTexture2D 在 CPU/GPU 间传递数据。
二、基础语法
1. 创建 ComputeShader 文件

在 Unity 项目中右键点击 Assets → Create → Shader → Compute Shader ,生成 .compute 文件。

2. 核函数(Kernel)定义
  • 使用 #pragma kernel 声明核函数入口(可定义多个)。

  • 示例:

    复制代码
    `#pragma kernel ProcessData // 声明核函数名
    
    // 定义可读写纹理(输出目标)
    RWTexture2D<float4> Result;
    
    // 线程组配置:每个线程组包含 8x8x1 个线程
    [numthreads(8, 8, 1)]
    void ProcessData (uint3 id : SV_DispatchThreadID) {
        // id.xy 表示当前线程处理的纹理坐标
        Result[id.xy] = float4(1.0, 0.0, 0.0, 1.0); // 填充红色
    }`
    • [numthreads(x,y,z)]:定义线程组大小(通常为 8x8x1 或 256x1x1)。
    • SV_DispatchThreadID:全局线程索引,用于定位数据。
3. 数据类型与缓冲区
  • RWTexture2D<float4>:可读写纹理,用于图像处理。

  • RWStructuredBuffer<T> :结构化缓冲区,存储任意类型数据(如粒子位置、速度)。

    复制代码
    `struct Particle {
        float3 position;
        float3 velocity;
    };
    RWStructuredBuffer<Particle> Particles;`
三、C# 脚本调用流程
1. 初始化资源
  • 创建 RenderTexture(纹理输出) :

    复制代码
    `RenderTexture outputTexture = new RenderTexture(256, 256, 24);
    outputTexture.enableRandomWrite = true; // 允许 GPU 写入
    outputTexture.Create();`
  • 创建 ComputeBuffer(结构化数据) :

    复制代码
    `int particleCount = 100000;
    ComputeBuffer particleBuffer = new ComputeBuffer(particleCount, sizeof(float) * 6); // 3位置+3速度`
2. 调用 ComputeShader
  • 获取核函数索引 :

    复制代码
    `int kernelHandle = computeShader.FindKernel("ProcessData");`
  • 设置参数 :

    复制代码
    `computeShader.SetTexture(kernelHandle, "Result", outputTexture); // 传递纹理
    computeShader.SetBuffer(kernelHandle, "Particles", particleBuffer); // 传递缓冲区`
  • 计算线程组数量 :

    复制代码
    `uint threadGroupsX = Mathf.CeilToInt(256 / 8f); // 纹理宽度 / 线程组x维度
    uint threadGroupsY = Mathf.CeilToInt(256 / 8f); // 纹理高度 / 线程组y维度`
  • 启动计算 :

    复制代码
    `computeShader.Dispatch(kernelHandle, threadGroupsX, threadGroupsY, 1);`
3. 释放资源
复制代码
`void OnDestroy() {
    particleBuffer?.Release(); // 释放 ComputeBuffer
    outputTexture?.Release();  // 释放 RenderTexture
}`
四、完整示例:图像灰度化
1. ComputeShader 代码
复制代码
`#pragma kernel Grayscale
RWTexture2D<float4> InputOutput; // 输入输出共用同一纹理

[numthreads(8, 8, 1)]
void Grayscale (uint3 id : SV_DispatchThreadID) {
    float4 color = InputOutput[id.xy];
    float gray = dot(color.rgb, float3(0.299, 0.587, 0.114)); // 加权平均
    InputOutput[id.xy] = float4(gray, gray, gray, color.a);
}`
2. C# 脚本
复制代码
`using UnityEngine;

public class GrayscaleProcessor : MonoBehaviour {
    public ComputeShader computeShader;
    public RenderTexture inputTexture;

    void Start() {
        // 确保输入纹理可写
        inputTexture.enableRandomWrite = true;

        // 获取核函数
        int kernelHandle = computeShader.FindKernel("Grayscale");

        // 设置参数
        computeShader.SetTexture(kernelHandle, "InputOutput", inputTexture);

        // 计算线程组
        uint threadGroupsX = Mathf.CeilToInt(inputTexture.width / 8f);
        uint threadGroupsY = Mathf.CeilToInt(inputTexture.height / 8f);

        // 启动计算
        computeShader.Dispatch(kernelHandle, threadGroupsX, threadGroupsY, 1);
    }
}`
五、关键注意事项
  1. 线程组大小优化 :
    • 根据硬件调整 numthreads(如 NVIDIA GPU 擅长 32x1x1,AMD 擅长 16x16x1)。
    • 总线程数 = numthreads.x * numthreads.y * numthreads.z * Dispatch(x,y,z)。
  2. 数据传递性能 :
    • 避免每帧频繁调用 SetData/GetData,尽量在 GPU 端完成所有计算。
    • 使用 ComputeBuffer.SetCounterValue 实现动态数据扩容(如粒子系统)。
  3. 同步问题 :
    • GPU 计算是异步的,若需同步等待,使用 ComputeShader.WaitForCompletion()(慎用,可能卡顿)。
  4. 平台兼容性 :
    • 移动端需检查 SystemInfo.supportsComputeShader,部分低端设备不支持。
相关推荐
babywang012 小时前
Unity笔记--AssetBundle详解
unity·游戏引擎
淡海水13 小时前
01-04-认知篇-Unity内存全景
unity·c#·游戏引擎·.net·gc
598866753@qq.com1 天前
Codex与Unity
unity·游戏引擎
淡海水1 天前
01-03-认知篇-C#内存模型深度解析
unity·c#·游戏引擎·.net·gc
淡海水1 天前
16-02-C#常用数据结构源码-附录B-源码索引速查
unity·c#·游戏引擎·il2cpp
警醒与鞭策2 天前
【无标题】
android·unity·性能优化·游戏引擎·perforce
zhchyun20082 天前
【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(10)
ui·unity·游戏引擎
地狱为王2 天前
Unity使用NVIDIA的Audio2Face驱动口型
unity·游戏引擎
ebiobiz2 天前
STM32F4 Unity 单元测试与多次测试失败率统计详细步骤
stm32·unity·单元测试
淡海水2 天前
16-01-C#数据结构源码-附录A-术语表
unity·c#·游戏引擎·il2cpp