为什么大家都那么喜欢用Shader?

引言

哈喽大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。

前几天,在群里看到一条消息:

"有没有大佬有放大镜效果。"

字越少,需求越大。

看到这句话,我脑子里的第一反应也是:

上Shader。

刚想回复,我突然想到一个问题:

放大镜 明明可以用RenderTexture去实现,为什么第一反应是Shader

其实,不仅仅是放大镜。

  • 水波 ,用Shader

  • 溶解 ,用Shader

  • 流光 ,用Shader

  • 角色受击闪白 ,也用Shader

仿佛游戏开发里只要效果稍微神秘一点,最后都会收到同一张病历单:

建议Shader,早晚各一次,写完真机观察。

所以 本期文章,笔者不打算只给大家扔一份放大镜代码。(扔两份哈哈

我们 会在Cocos游戏开发 中分别用RenderTextureShader实现同一个效果,再顺便回答标题里的问题:

为什么大家都那么喜欢用Shader?它是真的香,还是看起来比较像大佬?

本文示例工程在文末获取,小伙伴们自行前往。

RenderTexture Shader

先别急着写代码,Shader到底是什么?

很多人 第一次听到Shader,脑子里出现的是绿色代码雨、复杂公式,以及一位凌晨两点还在调颜色的程序猿。

其实可以先把它理解得粗暴一点:

Shader是运行在GPU上的一段小程序,负责告诉GPU顶点放在哪里、像素最终是什么颜色。

在普通业务代码里,我们经常按对象处理:这个按钮隐藏,那个角色移动,这个弹窗打开。

Shader的思路不太一样。它更像是在说:

"所有经过这里的像素,都按这套规则处理。"

这也是 大家喜欢Shader的原因之一。

接下来直接实战。

实战一:RenderTexture,用相机拍

先看 不写Shader的方案。

正常情况下Camera把画面渲染到屏幕。但我们也可以让第二台Camera把结果渲染到一张纹理,这张纹理就是 RenderTexture

再把 RenderTexture放进一个圆形Mask,链路就变成:

1.为什么要准备隐藏副本?

捕获相机应该只看到需要放大的内容,不能看见放大镜自己。

否则镜片捕获镜片,镜片里又出现镜片,最后得到一个无限套娃效果。

所以示例中准备了:

  • Artwork:主相机正常显示的图片。

  • CaptureArtwork:放在独立Layer,只让捕获相机看到。

  • Lens:圆形MaskRenderTexture内容和镜框。

2.创建 RenderTexture

这里做了三件事:

  • 1. 创建一张256 x 256的纹理。

  • 2. 让捕获相机把结果画进去。

  • 3. 把纹理交给镜片Sprite显示。

3.如何控制放大倍数?

orthoHeight 越小,相机看到的范围越少。

假设 镜片直径是 220,放大倍数是 2,相机只捕获约 110 高度的内容,再把它铺满 220 的镜片,就得到了2倍放大。

4. 让相机跟随手指

先把触摸点转换到图片内部,再映射到隐藏副本的世界坐标,捕获相机就能找到对应位置。

手指松开后,我们同时隐藏镜片并停用捕获相机。

实战二:Shader,让像素自己走过来

RenderTexture 很万能,但为了放大一张静态Sprite,我们增加了副本、CameraLayerRenderTextureMask

也不是不能用,只是有点像为了挖一根葱,认真采购了一台挖掘机。

然而 Shader版只需要:

  • 原来的Sprite

  • 一个Material

  • 一段跟随触摸点更新参数的脚本。

这也是 Shader受欢迎的另一个原因:

当效果能用像素规则描述时,它往往可以减少额外的操作。

1. UV 是什么?

UV 可以理解为图片内部的坐标,范围通常是0~1

  • U表示水平方向,通常从左侧的0到右侧的1

  • V表示垂直方向,也在0~1范围内;具体上下方向可能因纹理来源而不同。

正常情况下 ,当前像素在什么UV,就去纹理的对应位置取颜色。

放大镜 要做的,是让镜片里的UV向圆心靠近:

假设 zoom = 2,原来距离圆心 0.2 的采样点,现在只去距离圆心 0.1 的位置取颜色。

更小的纹理范围被铺进同样大的圆里,视觉上自然就放大了。

2. 判断当前像素在不在镜片里

计算 当前UV到镜片中心的距离:

  • 小于半径:显示放大画面。
  • 大于半径:显示原画面。

3. 把原图和放大图混起来

圆外 使用 baseColor,圆内使用 magnifiedColor

再判断像素是否位于圆的边缘,混入一层金色,就有了镜框。

**至于镜柄,本示例没有做。**实战最重要的是讲清原理,不是让美术妹子看完以后顺手再提三个优化意见。

4. 脚本只负责传参数

四个数字 分别是镜片中心 x、中心 y、半径和放大倍数。

触摸移动时 更新圆心,Shader就会在新的位置重新计算。

所以Shader一定比RenderTexture 好吗?

当然不是。

其实 在放大镜这个效果中,Shader反而没有RenderTexture灵活。

我们需要根据具体游戏需求去,选择用什么样的技术栈:

优先选择 Shader

  • 放大单张图片、立绘或静态地图。
  • 效果主要是局部变色、扭曲、渐变或纹理采样变化。
  • 希望减少额外节点和相机。

优先选择 RenderTexture

  • 镜片里包含多个节点。
  • 需要看到角色动画、粒子、地图单位等动态内容。
  • 放大对象不是一张简单纹理。

最后再回答文章标题

为什么大家都那么喜欢用Shader?

笔者认为:

  • Shader在特定情况能更好地优化效果。

  • Shader在特定情况能更好地优化性能。

  • Shader在特定情况能更好地展示你的能力。

会用Shader很帅,但知道什么时候不用,更帅。

结语

问题来了:小伙伴们关于**"为什么大家都那么喜欢用Shader?"**有不同的见解吗?

欢迎在评论区探讨一下。

本文实例工程 可通过私信 发送"放大镜"获取。


我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助,也希望通过您能帮助到大家。

实不相瞒,想要个爱心 !请把该文章分享给你觉得有需要的其他小伙伴。谢谢!

推荐文章:

亿元Cocos小游戏实战合集2.0

亿元Cocos小游戏实战合集1.0

老板说最近这款游戏很火让我抄,可是我连玩都玩不明白...

这款值68亿的游戏,你不实战一下吗?安排!

小伙伴说我的拼图游戏用Mask不能合批...

俄罗斯方块谁不会做......啊?流沙版?

最近很火的一个拼图游戏,老板让我用Cocos3.8做一个...

老板说拼图游戏太卷了,让我用Cocos做个3d版本的...

敢不敢挑战用Cocos3.8复刻曾经很火的割绳子游戏?

相关推荐
Codebee1 小时前
OODER Studio设计工具导入体系深度解析
前端
weedsfly1 小时前
前端开发中的命令模式——从点餐退单到异步任务调度
前端·javascript·面试
慢功夫1 小时前
💡第四篇:编辑器内核, Monaco model、URI、dirty 状态和 tabs 是怎么协作的?
前端·visual studio code
小马过河R1 小时前
微前端实践:从概念、原理到 qiankun 落地
前端·人工智能·前端框架
用户059540174461 小时前
AI记忆存储一致性踩坑实录:每天手工回归200条对话,直到我用pytest+Redis搭建自动化验证
前端·css
weedsfly1 小时前
前端中的适配器模式 vs 外观模式
前端·javascript·面试
图扑软件1 小时前
其域创新 × 图扑软件|3DGS 高斯泼溅智慧钢厂实景孪生
前端·低代码·3d·编辑器·图形渲染·可视化
labixiong1 小时前
写给前端的 Generator 指南:从 yield 到 async/await 的完整进化
前端·javascript·前端框架
asdzx671 小时前
使用 Spire.WordJS 在 React 中实现在线 Word 文档编辑
前端·react.js·word