96.ComputeShader的作用和基本结构

96.性能优化-GPU-着色器优化-ComputeShader-作用和基本结构


96.1 知识点

Compute Shader 的作用

Compute Shader(计算着色器)是一种在 GPU 上运行的通用计算程序,属于 GPGPU(General-Purpose GPU Computing)的一部分。它的核心目标是让开发者脱离渲染管线,直接利用 GPU 的并行计算能力处理任意类型的数据。

打个比方:CPU 像一个聪明的人,擅长处理复杂逻辑(”写策划案”);GPU 像一大群工人,擅长干重复、独立的活(”拧螺丝”)。Compute Shader 就是告诉 GPU 这群工人:每人负责一个任务,大家一起干,干完返回结果。例如要处理一张 512×512 的图片,CPU 需要逐像素依次处理,而 GPU 拥有数千个核心,可以同时处理数千个像素。

与普通 Shader 的区别: 普通 Shader 依赖渲染管线,用于渲染画面;Compute Shader 不依赖渲染管线,专门用于计算数据。

Compute Shader 的基本结构

创建文件

Create → Shader → Compute Shader,创建的文件后缀为 .compute,属于 HLSL 风格代码。

文件结构

基本结构包含:声明入口函数、声明输入输出资源、声明线程组内线程数量、书写核心计算逻辑。

创建后的默认内容:

// #kernel 指令声明计算着色器入口函数,单个文件可包含多个内核
#pragma kernel CSMain

// 可读写二维纹理,需在 Unity 中创建 enableRandomWrite=true 的 RenderTexture
RWTexture2D<float4> Result;

// 线程组配置:8×8×1 = 64 个线程,适合处理二维数据
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // id.xy 对应输出纹理的像素坐标,每个线程独立处理一个像素
    Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
}

C# 调用 Compute Shader 规则

调用流程分为以下步骤:

1. 获取 ComputeShader 引用: 在 C# 中声明 public ComputeShader computeShader; 并在 Inspector 中关联。

2. 查找入口函数索引:

int index = computeShader.FindKernel("CSMain");

3. 传递参数:.compute 文件中声明变量,在 C# 中通过 Set 系列方法传值。

.compute 文件中声明:

float f; // 由C#侧传入的参数

C# 中传值:

computeShader.SetFloat("f", 0.5f);

4. 启动计算: 指定线程组数量,GPU 开始并行执行:

computeShader.Dispatch(index, 64, 64, 1);

5. 获取结果: 将 GPU 计算完成的数据用于渲染或传回 CPU。

6. 释放资源。

后续课程会详细讲解数据回读与资源释放。


96.2 知识点代码

Lesson96_性能优化_GPU_着色器优化_ComputeShader_作用和基本结构.cs

using System.Collections.Generic;
using UnityEngine;

public class Lesson96_性能优化_GPU_着色器优化_ComputeShader_作用和基本结构 : MonoBehaviour
{
    public ComputeShader computeShader;

    void Start()
    {
        #region 知识点一 Compute Shader的作用

        //Compute Shader(计算着色器) 是让 GPU 帮你算东西的程序
        //是一种在 GPU 上运行的 通用计算程序
        //属于 GPGPU(通用GPU计算 - General-Purpose GPU Computing) 的一部分
        //它的核心目标是
        //让开发者脱离渲染管线
        //直接利用GPU的并行计算能力来处理计算任何类型的数据

        //举例说明
        //CPU 像一个聪明的人,会处理复杂的逻辑(比如“写策划案”)
        //GPU 像一大群工人,擅长干重复、独立的活(比如“拧螺丝”)
        //Compute Shader 就是告诉这群 GPU 工人:
        //每个人负责一个任务,大家一起干,干完告诉我结果
        //比如
        //我们想要计算一个512*512的图片,每个像素的颜色要变化一点
        //CPU一次只能处理一个像素,要一个一个像素依次处理
        //GPU有几千个核心,可以同时处理几千个像素
        //因此
        //Compute Shader就相当于是写给GPU的批量计算脚本
        //让GPU帮助我们批量的计算

        //注意:
        //Compute Shader不像普通Shader
        //它不依赖渲染管线
        //主要就是用来处理计算的
        //普通Shader是用来渲染画图的
        //Compute Shader是用来计算数据的

        #endregion

        #region 知识点二 Compute Shader的基本结构

        //1.创建Compute Shader文件
        //  Create —> Shader —> Compute Shader
        //  创建的文件后缀为 .compute,属于HLSL风格代码
        //2.Compute Shader文件 基本结构
        //  2-1.声明入口函数
        //  2-2.声明输入输出资源
        //  2-3.声明每个线程组内的线程数量
        //  2-4.声明入口函数类型
        //  2-5.书写核心计算逻辑

        #endregion

        #region 知识点三 C#调用Compute Shader规则

        //1.在C#代码中找到对应的ComputeShader文件
        
        //2.利用API找到入口函数索引
        //  FindKernel("入口函数名")
        int index = computeShader.FindKernel("CSMain");
        
        //3.传递相关参数
        //  Set...(入口函数索引, 参数..)
        computeShader.SetFloat("f", 0.5f);
        
        //4.启动计算
        //  Dispatch(入口函数索引, x线程组数, y线程组数, z线程组数)
        computeShader.Dispatch(index, 64, 64, 1);
        
        //5.使用GPU计算完成输出的数据渲染或者传回CPU
        
        //6.释放资源

        #endregion
    }
}

Lesson96_ComputeShader.compute

// 每个 #kernel 指令声明一个计算着色器入口函数
// 单个文件可包含多个内核,用于不同计算任务
#pragma kernel CSMain

// 计算着色器输出:可读写二维纹理
// 在Unity中需创建enableRandomWrite=true的RenderTexture并通过ComputeShader.SetTexture传递
RWTexture2D<float4> Result;

float f; // 32位浮点数,由C#通过SetFloat传入

// 线程组配置:每个线程组包含8x8x1=64个线程
// 适合处理二维数据,每个线程处理一个像素
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)  // 当前线程的全局唯一ID
                                              // id.xy对应输出纹理的像素坐标
{
    // 核心计算逻辑:每个线程独立执行
    
    // 示例:生成棋盘格测试图案
    // R通道:x和y的按位与结果,形成黑白相间
    // G通道:x低4位归一化,产生纵向渐变
    // B通道:y低4位归一化,产生横向渐变
    // A通道:固定为0
    Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏