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