Unity ComputeShader 基础语法与使用教程

Unity ComputeShader 基础语法与使用教程

一、基础概念

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

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

在 Unity 项目中右键点击 AssetsCreate → 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)]:定义线程组大小(通常为 8x8x1256x1x1)。
    • 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,部分低端设备不支持。
相关推荐
mxwin15 小时前
Unity Shader FLOWMAP岩浆流动制作案例
unity·游戏引擎·shader·uv
小贺儿开发15 小时前
【Arduino与Unity交互探究】01 摇杆模块
科技·unity·游戏引擎·arduino·串口通信·摇杆·硬件交互
Yasin Chen17 小时前
Unity TMP_SDF 分析(三)顶点着色器1
unity·游戏引擎·着色器
mxwin18 小时前
Unity Shader 使用 Noise 图 制作Shader 溶解效果
unity·游戏引擎
mxwin20 小时前
Unity Shader 用 Ramp 贴图实现薄膜干涉效果
unity·游戏引擎·贴图·shader·uv
魔士于安20 小时前
Unity星球资源,八大星球,带fps显示
游戏·unity·游戏引擎·贴图·模型
张老师带你学1 天前
unity资源,深空陨石,适合太空背景的游戏开发
游戏·unity·模型
鹿野素材屋1 天前
Unity动画幅度太大怎么办
unity·游戏引擎
垂葛酒肝汤1 天前
Unity Sprite Rect 越界问题笔记
笔记·unity·游戏引擎
平行云1 天前
数字孪生信创云渲染系列(一):混合信创与全国产化架构
unity·ue5·3dsmax·webgl·gpu算力·实时云渲染·像素流送