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,部分低端设备不支持。
相关推荐
mxwin1 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
晚枫歌F1 天前
三层时间轮的实现
网络·unity·游戏引擎
咸鱼永不翻身1 天前
Lua脚本事件检查工具
unity·lua·工具
leo__5201 天前
单载波中继系统资源分配算法MATLAB仿真程序
算法·matlab·unity
努力长头发的程序猿2 天前
Unity使用ScriptableObject序列化资源
unity·游戏引擎
mxwin2 天前
Unity Shader 手写基于 PBR 的 URP Lit Shader 核心光照计算
unity·游戏引擎·shader
小贺儿开发2 天前
Unity3D 智能云端数字标牌系统
unity·阿里云·人机交互·视频·oss·广告·互动
魔士于安2 天前
Unity windows 同步 异步 打开文件文件夹工具
游戏·unity·游戏引擎·贴图·模型
魔士于安2 天前
unity lowpoly 风格 城市 建筑 道路 交通标志
游戏·unity·游戏引擎·贴图·模型
mxwin2 天前
Unity GPU Shader 性能优化指南
unity·游戏引擎·shader