d3d12龙书学习之MiniEngine的最小化实现(九) 龙书第13章 计算着色器 模糊,描边

本文介绍了在DirectX12中使用计算着色器实现水波纹、模糊效果和Sobel描边的详细步骤。讨论了计算着色器的`numthreads`、`dispatch`参数及其意义,并提供了代码示例。通过计算着色器,实现了水波纹的GPU计算和高斯模糊效果,以及Sobel边缘检测。文章还分享了如何调试HLSL着色器和代码的修改记录。
摘要由CSDN通过智能技术生成

前言

计算着色器是利用GPU来计算的一种着色器程序。本身不属于渲染管线。但因为是GPU编程中的一部分,所以可以读到显存中的各类数据。又因为GPU并发计算能力很强,所以可以把很多运算放到计算着色器中来做,这样可以显著提高我们程序的运行速度。

添加计算着色器相关的文件

在MiniEngine中,我们有渲染管线的上下文环境CommandContext
其中有两类。
图形上下文:GraphicsContext
计算上下文:ComputeContext

这俩分开,应该是有一定的用意,但由于我学的还不够深入,可能还没理解到。
缺点我倒是发现了。当GraphicsContext的输出要作为ComputeContext的输入时,我只能先让GraphicsContext执行结束后,才会执行ComputeContext。这种操作降低了效率。奇怪的是,我不等待结束,最后效果也是没问题的。我只能初步理解为显卡性能比较强。

这里添加好计算着色器所需要的类、文件。顺便我还把一些辅助类的文件添加了进来
整理之后的代码github:
https://github.com/mversace/DirectX12-MiniEngine-Dragon/tree/c3be3481ccee5ba141ab60a6bbcac1fadb5e7928

利用计算着色器计算输入向量的和

这一部分整体来说还是比较简单的。
直接看下shader的实现

struct Data
{
    float3 v1;
    float3 v2;
};

StructuredBuffer<Data> gInputA : register(t0);
StructuredBuffer<Data> gInputB : register(t1);
RWStructuredBuffer<Data> gOutput : register(u0);

// 总共有32个数据,所以这里每组分32*1个线程
[numthreads(32, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
    gOutput[DTid.x].v1 = gInputA[DTid.x].v1 + gInputB[DTid.x].v1;
    gOutput[DTid.x].v2 = gInputA[DTid.x].v2 + gInputB[DTid.x].v2;
}

numthreads的含义

这代表的是每个线程组内部在xyz方向上的分组。
对于本项目来说,两个输入都是32个数据,采用结构化的缓冲区StructuredBuffer,所以直接在x方向分组就可以了。
你当然也可以在y方向或者z方向分组,那么下边的代码就需要做对应的修改。
例如改成y方向分组也是可以的。

[numthreads(1, 32, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
    gOutput[DTid.y].v1 = gInputA[DTid.y].v1 + gInputB[DTid.y].v1;
    gOutput[DTid.y].v2 = gInputA[DTid.y].v2 + gInputB[DTid.y].v2;
}

对于程序上来说,总体跟渲染差别不大。

  1. 设置根签名
  2. 设置计算流水线
  3. 设置参数
  4. dispatch分组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值