[3D游戏开发实践] Cocos Cyberpunk 源码解读-手把手教你新增一个后效Shader
Cocos Cyberpunk 是 Cocos 引擎官方团队以展示引擎重度 3D 游戏制作能力,提升社区学习动力而推出的完整开源 TPS 3D游戏,支持 Web, IOS, Android 多端发布。
本系列文章将从各个方面对源码进行解读,提升大家的学习效率。希望能够帮助大家在 3D 游戏开发的路上更进一步。
工程源码免费下载页面:
https://store.cocos.com/app/detail/4543
今天的内容相对比较简单,既适合年轻人把玩,也适合中老年娱乐,一定要看完哟。
上一篇文章,给大家分享了 如何将 Cocos Cyberpunk 中的自定义渲管线(CRP)搬到自己的项目中。
看着那 Bling Bling 的效果,很多朋友也是跃跃欲试,但刚准备动手就卡住了。于是跑过来问:
- 那个自定义管线的 Shader 怎么写啊?
- 那个渲染管线图是怎么连的啊?
- 我想自己增加一个效果,怎么整啊?
别急,这就安排!
谁让麒麟子这(是)么(个)好(专)说(业)话(托)呢。
大家可能发现了,虽然麒麟子的文章开头都会有一段用于缓和紧张的学习气氛的句子,但文章结构依然保持了 总-分-总 结构。
因这样的结构很适合用于分享学习内容。
如果还有更好的建议,欢迎随时告诉我,我会根据情况做调整。
话不多说,我们开始吧。
内容提要
想要在 Cocos Cyberpunk 的 CRP 中新增一个后期效果,只需要需要解决下面几个问题就好了:
- 新增什么后期效果
- 如何编写一个 Pass
- 如何将一个 Pass 加入到管线
接下来我们逐一搞定它们。
选择效果
Cocos Cyberpunk 中已经内置了 Bloom 和 TAA 两个出场率 90%+ 的后处理。如果还要加的话,应该还有:
- Lut
- Vignette
- DoF
- Motion Blur
- SSR
- SSAO
除了 Lut 和 Vignette 非常简单以外,其余的都很难搞。
列出来就是为了让大家看看。
这篇文章的目的,是演示添加一个后效效果的工作流程,所以没有必要搞得那么复杂,我们实现一个简单的效果就好了。
有了!我们可以实现一个让画面变灰的效果。
这个效果虽然简单,但可以作为玩家角色死亡时的画面变灰处理,以增强游戏氛围,实用价值也不小。
先来张效果图,避免观众流失了!
编写一个 Pass
资源目录
我们先来看看一个 Pass 涉及到哪些内容:
- pipeline/passes:相关脚本
- pipeline/resources/effects:相关 Shader
- pipeline/resources/materials:相关材质
Pass 代码
接下来,我们先忽略所有原理和细节,快速实现一个变灰效果,从而掌握流程。
1、从fxaa快速构建
我们新建一个 grayscale-pass.ts,然后将 fxaa.ts 中的内容复制过来。
2、修改代码内容
修改与类名相关的代码如下(逐行检查):
@ccclass('GrayscalePass')
export class GrayscalePass extends BasePass {_materialName = 'grayscale';...@property({ override: true })name = 'GrayscalePass';@property({ override: true })outputNames = ['GrayscalePassColor'];...rener(camera: renderer.scene.Camera, ppl: rendering.Pipeline){...passUtils.addRasterPass(width, height, 'post-process', `Camera_Grayscale_Pass${cameraID}`);...}
}
删除下面这些代码:
...
checkEnable () {return super.checkEnable() && !!HrefSetting.fxaa;
}
...
_offset = new Vec2
texSize = new Vec4
...
material.setProperty('texSize', this.texSize.set(width, height, 0, 0))
好了,我们的 grayscale-pass.ts 就制作好了。
Cocos Shader
接下来,我们制作让画面变灰的 Shader。
为了快速实现,我们还是先复制 pipeline/resources/fxaa.effect,改名为 grayscale.effect。
将 main 函数改为如下内容:
void main () {vec4 color = texture(inputTex,v_uv);float Y = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;fragColor = vec4(Y,Y,Y ,1.0);
}
为了 Shader 代码的整洁,我们删除掉用不上的部分:
#include <unpack>
#include <./chunks/fxaa>
...
uniform Params {vec4 texSize;
};
注意, in vec2 v_uv; 可别误删了,要留着。
好了,我们的Shader就准备好了
材质
材质是最简单的了,只需要在 Cocos Creator 中复制 pipeline/resources/fxaa.mtl,并改名为 grayscale。
然后把它的 effect 指定为 grayscale.effect 就可以了。
到这里, 一个 GrayscalePass 就制作完成啦。
加入新的 Pass
材质加载
1、双击 pipeline/resources/pipeline.prefab。
2、在属性面板中,找到 PipelineAssets 组件。
3、将 Materials 后面的数字加1(没有改过的话,应该是8,我们把它变成0),可以看到最下方空出来一个元素。
4、将 pipeline/resources/materials/grayscale.mtl 拖进去,保存 pipeline.prefab。
材质就会在 pipeline 启动的时候加载啦。
添加 GrayscalePass 到 Graph 数据
为了能够在 CRP Graph 中添加节点,我们需要先将 GrayscalePass 注册到 graph 数据里。
打开 pipeline/graph/nodes/pass.ts,在末尾追加一行代码:
createPassGraph(BasePass);
createPassGraph(BloomPass);
...
//GrayscalePass
createPassGraph(GrayscalePass);
添加节点
按照之前教过的方法
算了,再从头教一次吧。
打开 CRP Graph
- 新建一个空节点
- 将 pipeline/graph/pipeline-graph.ts 组件拖到这个节点上
- 勾选组件上的 Edit 复选框,就会弹出 RenderPipeline Graph 窗口
你可以看到下面这样的窗口:
添加 GrayscalePass
在窗口中点击右键,会弹出第一级菜单,选择 AddNode。
在弹出的新菜单中,选择 pipeline(最底部)。
接下来,在弹出的新菜单中选择 GrayscalePass(最底部)。
就能得到一个 GrayscalePass 节点了。
将它放入 main 管线中的适合位置即可。 这里麒麟子把它放在了 BloomPass 之前。
关掉这个窗口,回到编辑器,就可以看到画面变灰啦。
最后画个饼
今天的内容就到此结束了。
虽然我们没有对管线的细节和实现原理进行分析,但通过对 FXAA 的 借鉴,我们实现了一个让画面变灰的后处理效果 。
这就叫:站在巨人的肩膀上。
下一篇文章,我们会从原理出发,讲解自定义管线的设计。
后面的文章会陆续包含:前向管线、延迟管线、BLOOM、TAA、FSR 等讲解。
再后面的文章,会基于这个管线新增更多高级功能,包括但不限于:SSR、SSAO 等等。
当然,也有很多朋友在问原生开发相关的功能,恰好 Cocos Cyberpunk 在原生端也是做了非常多的优化和兼容性处理的,这一块的内容也会在后面的文章中进行分享,敬请期待。
相关文章:

[3D游戏开发实践] Cocos Cyberpunk 源码解读-手把手教你新增一个后效Shader
Cocos Cyberpunk 是 Cocos 引擎官方团队以展示引擎重度 3D 游戏制作能力,提升社区学习动力而推出的完整开源 TPS 3D游戏,支持 Web, IOS, Android 多端发布。 本系列文章将从各个方面对源码进行解读,提升大家的学习效率。希望能够帮助大家在 …...

构建产品帮助中心,促进SaaS企业的进步
长期来看,保留现有客户比获取新客户更为关键,因此建立良好的客户服务质量需要着重关注客户心理状态。 什么是 SaaS SaaS是软件即服务(Software as a Service)的缩写。它是一种软件交付模式,其中软件应用程序托管在云计…...
【Qt】Qt单元测试详解(四):Google Test
1、创建测试工程 【Qt】Qt单元测试详解(一):通过QtCreator创建测试工程 2、添加测试代码 2.1 默认生成的代码 1)项目工程pro include(gtest_dependency.pri)TEMPLATE = app CONFIG += console c++14 CONFIG -= app_bundle CONFIG += thread CONFIG -= qtHEADERS += \t…...

容器引擎Docker的常用命令
一.镜像相关命令 1.搜索镜像 可使用 docker search命令搜索存放在 Docker Hub中的镜像。执行该命令后, Docker就会在Docker Hub中搜索含有 java这个关键词的镜像仓库 docker search java以上列表包含五列,含义如下: NAME:镜像仓库名称。D…...

vue尚品汇商城项目-day01【3.项目路由的分析】
文章目录本人其他相关文章链接安装命令:cnpm install --save vue-router vue-router 前端所谓路由:kv键值对 key:URL(地址栏中的路径) value:相应的路由组件 注意:本项目是上中下结构 路由组件: Home首页路由组件、Search路由组件…...

详解--高级IO
文章目录前言一、五种IO模型阻塞IO非阻塞IO信号驱动IOIO多路转接:异步IO二、高级IO同步通信和异步通信阻塞 VS 非阻塞其他高级IO三、非阻塞IOfcntl实现函数SetNoBlock总结前言 理解五种IO模型的基本概念.重点是IO多路转接. 正文开始! 一、五种IO模型 IO: 等 数据拷贝 read/…...
Android自定义闹钟
google推荐方式3种: 一、AlarmManager setRepeating() 重复闹钟。1、Android 4.4(API 级别 19)开始,所有重复闹钟都是不精确的,延时2分钟左右。2、闹钟触发的待定 Intent。当您设置使用同一待定 Intent 的第二个闹钟…...

第02章_MySQL环境搭建
第02章_MySQL环境搭建 🏠个人主页:shark-Gao 🧑个人简介:大家好,我是shark-Gao,一个想要与大家共同进步的男人😉😉 🎉目前状况:23届毕业生,目前…...
java使用线程池和Future接口实现异步的实例
线程池可以提供线程的复用和管理,避免线程频繁创建和销毁的开销。而Future接口则可以获取异步任务的执行结果和状态,避免了阻塞等待异步任务完成的情况。下面是一个简单的示例代码: import java.util.concurrent.*;public class AsyncExample…...

cocosCreator 事件系统
概述: DOM的输入事件通过CCInputManager转化成cocos的输入事件,由CCEventManager 分发给监听器。 监听器在通过回调函数(begin/move/end/cancel)告知事件派发对象(eventTarget)派发事件。 重要类: event࿱…...
刷题_20:字符串反转 and 公共子串计算
一.字符串反转 题目链接: 字符串反转 题目描述: 接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000) 输入描述: 输入一行,为一个只包含小写字母的字符串…...

如何在 Linux 命令行中比较两个目录,我教你五个命令!
在 Linux 命令行中比较两个目录是一项常见的任务,特别是当你需要确保两个目录之间的文件完全相同时。在本文中,我们将介绍一些在 Linux 命令行中比较两个目录的方法。 方法一:使用 diff 命令比较两个目录 diff 命令可以比较两个文件或目录之…...

多元算力如何满足万千本土化场景需求,解析第四代至强核心加速器设计
作者 | 宋慧 出品 | CSDN 云计算 2023 年初,英特尔重磅发布了企业级芯片领域重要的产品——第四代英特尔 至强 可扩展处理器。当时报道中,我们就重点提到了其中重要的七大内置加速器,这也是英特尔为千行百业多种创新场景去提供算力支持的底气…...
SPI主模式切换为从模式
一、SPI主模式切换为从模式在SPI总线上,要将主设备转换为从设备或者将从设备转换为主设备,需要通过改变SPI控制寄存器的配置来实现。下面分别介绍SPI主模式切换为从模式的步骤:配置从设备的SPI控制寄存器首先需要配置从设备的SPI控制寄存器。…...

IMX6ULL学习笔记(21)——MMDC接口使用(DDR3测试)
一、MMDC简介 MMDC 接口与 STM32 的 FSMC 接口类似,只不过 MMDC 接口专用于外接 DDR,并且 MMDC 外部引脚不复用。MMDC 是一个多模的 DDR 控制器,可以连接 16 位宽的 DDR3/DDR3L、16 位宽的 LPDDR2。 MMDC 是一个可配置、高性能的 DDR 控制器。…...
机器学习——无监督学习
机器学习的分类一般分为下面几种类别:监督学习( supervised Learning )无监督学习( Unsupervised Learning )强化学习( Reinforcement Learning,增强学习)半监督学习( Semi-supervised Learning )深度学习(Deep Learning)Python Scikit-learn. http: // …...

python+opencv生成较真实的车牌号码图片
本文参考github代码:https://github.com/loveandhope/license-plate-generator 效果: 一、代码目录结构: background目录下存放各种背景图片 font目录下存放车牌中文、字符的ttf字体 images目录下存放蓝色底牌、新能源绿色底牌、污渍&#…...
3.26周报
周报 代码行数: 周一 581 周二 601 周三 615 周四 591 周五 570 周六 561 周日 577 遇到的问题: 项目启动很慢,要将近5分钟才能开启项目,对开发造成很大困扰。 断点打在奇怪的地方,造成启动缓慢。断点…...
从0开始学python -69
Python math 模块 Python math 模块提供了许多对浮点数的数学运算函数。 math 模块下的函数,返回值均为浮点数,除非另有明确说明。 如果你需要计算复数,请使用 cmath 模块中的同名函数。 要使用 math 函数必须先导入: import…...
HashMap中HashCode的实现原理
代码 static final int hash(Object key) {int h;return (key null) ? 0 : (h key.hashCode()) ^ (h >>> 16);}1. h >>> 16 是什么,有什么用? h是hashcode。h >>> 16是用来取出h的高16,(>>>是无符号右移) 如下展…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...