当前位置: 首页 > news >正文

任天堂 64 缺乏加法混合效果?这项技术让特效无溢出伪影!

任天堂 64 上的加法混合效果各位是否曾疑惑为什么原版 PlayStation 上的爆炸和其他特效看起来比任天堂 64Nintendo 64上的要酷炫得多原因就在于加法混合additive blending或者更确切地说是 N64 缺乏这种效果。虽然 N64 实际上支持加法混合但在实际应用中却几乎无法使用。PlayStationPlayStationPSX支持 4 种不同的混合模式除了直接覆盖像素之外用于控制精灵sprite和几何图形如何与现有的帧缓冲区frame buffer进行混合0: (源颜色 目标颜色) / 21: 源颜色 目标颜色2: 目标颜色 - 源颜色3: 目标颜色 源颜色 / 4在《沉默轰炸机》中使用的是概念上最简单的模式源颜色 目标颜色。也就是说颜色会直接添加到帧缓冲区中现有的颜色上。| R | G | B || 源颜色精灵 | 171 | 42 | 226 || 目标颜色帧缓冲区 | 63 | 141 | 170 || 结果 | 234 | 183 | 255 |在场景上绘制精灵只会让画面变得更亮而不会变暗。这非常适合用于爆炸、等离子束和魔法咒语等特效。值得注意的是在这个例子中B 值相加为 396但 PSX 的图形处理器GPU会将其限制在 255 的最大值范围内。顺便提一下PSX 的 GPU 实际上只使用 16 位精度每个颜色分量为 5 位因此值的范围是 0 .. 31但原理是一样的。任天堂 64N64 的“现实显示处理器”Reality Display Processor简称 RDP一种固定功能的光栅化器有一种更灵活的方式来控制混合效果可配置的“颜色组合器”Color Combiner。这有点类似于 OpenGL 的 glBlendFunc() 函数。[Libdragon] 通过 RDPQ_BLENDER((P, A, Q, B)) 宏来实现这一功能该宏指示 RDP 执行 (P * A) (Q * B) 操作其中每个“插槽”可以是几种输入之一。使用这个宏来设置加法混合非常简单RDPQ_BLENDER(( IN_RGB, IN_ALPHA, MEMORY_RGB, ONE ))问题在于RDP 不会对结果进行限制。| R | G | B || 源颜色精灵 | 171 | 42 | 226 || 目标颜色帧缓冲区 | 63 | 141 | 170 || 结果 | 234 | 183 | 140 |^溢出了这样得到的输出效果并不理想。当然你可以选择在 N64 的向量协处理器“现实信号处理器”Reality Signal Processor简称 RSP上绘制这些特效。但如果你想进行旋转、缩放或任何实际的 3D 操作这很快就会变得复杂起来。而 RDP 更适合做这些事情显示本来就是它的职责虽然 RDP 可以绘制到 32 位缓冲区中但游戏很少这样做。几乎所有 N64 游戏最终输出都使用 16 位帧缓冲区。不过考虑到这一点想出了一个不同的方案让 RDP 绘制到一个 32 位的 RGBA 8888每个分量 8 位缓冲区中但将所有精灵限制在 16 位的 RGBA 5551每个颜色分量 5 位1 位透明度范围内。可以通过将 RGB 值除以 8或者右移 3 位来对资源进行预处理。这样做会让所有东西看起来太暗但反过来也为加法混合提供了很大的空间。当所有加法混合的精灵结果都小于 255 时不会发生溢出。更棒的是不需要离线进行图像预处理。可以在绘制时让颜色组合器为完成这个任务而且是免费的// 利用雾的透明度值以 1/8 的强度绘制所有颜色rdpq_set_fog_color(RGBA32(0, 0, 0, 256/8));rdpq_mode_blender(RDPQ_BLENDER(( IN_RGB, FOG_ALPHA, MEMORY_RGB, ONE )));那么如何将其恢复到正常亮度呢很简单使用 16 位帧缓冲区进行显示并将所有 32 位颜色“复制”到其中。只需要小心地将所有 8 位颜色分量限制在 5 位范围内。void cpu_rgba_8888_to_5551(uint32_t *rgba32_in, uint16_t *rgba16_out) {for (int i 0; i 320 * 240; i) {color_t c color_from_packed32(rgba32_in[i]);if (c.r 31) { c.r 31; }if (c.g 31) { c.g 31; }if (c.b 31) { c.b 31; }rgba16_out[i] (c.r 11) | (c.g 6) | (c.b 1) | 0x1;}}当然在 CPU 上执行这个操作成本非常高。对于一个 320×240 的帧大约需要 70 毫秒。但这正是 RSP 协处理器发挥优势的地方。现在问题变得简单多了。RSP 的 128 位向量指令可以一次处理 8 个像素。在 #N64Brew Discord 上的 HailToDodongo 的帮助下对 GPU 微代码进行了优化现在整个帧的处理时间约为 3.1 毫秒小知识在 N64 的语境中通常所说的“GPU 微代码”实际上是在 RSP 上运行的 MIPS 汇编代码或者就像最近开始称呼的那样MIPS 加汇编。现代的 N64 开发工具非常出色。虽然了解一些汇编知识会有帮助但不再需要手动编写 MIPS 汇编代码了。HailToDodongo 发明了一种类似 C 语言的语言 [RSPL]它可以直接编译成汇编代码。所以整个设置如下// 使用 16 位帧缓冲区初始化显示display_init(RESOLUTION_320x240, DEPTH_16_BPP, 3, GAMMA_NONE, FILTERS_DISABLED);// 创建一个 32 位的辅助渲染缓冲区并将其设置为渲染目标surface_t render32 surface_alloc(FMT_RGBA32, 320, 240);rdpq_set_color_image(render32);// 配置颜色组合器以 1/8 的强度绘制rdpq_set_fog_color(RGBA32(0, 0, 0, 256/8));rdpq_mode_blender(RDPQ_BLENDER((IN_RGB, FOG_ALPHA, MEMORY_RGB, ONE)));// 绘制包含大量加法混合精灵的场景render_scene();// 在 RSP 上启动从 32 位渲染缓冲区到 16 位帧缓冲区的转换rsp_rgba_8888_to_5551(render32-buffer, screen-buffer);// 显示 16 位帧缓冲区display_show(screen);这样就可以得到大量没有溢出伪影的加法混合精灵特效。当然大多数游戏一开始就使用 16 位帧缓冲区是有原因的N64 的内存吞吐量非常糟糕。与 16 位缓冲区相比绘制到 32 位缓冲区几乎需要两倍的时间因为 RDP 必须从存储在 RDRAM 中的帧缓冲区中来回传输两倍的数据。尽管如此这种技术的效果比预期的要好。对于某些应用来说它肯定足够好了。还看到了进一步优化的潜力比如只将需要加法混合的精灵绘制到 32 位缓冲区中甚至可以降低分辨率然后在 RSP 上将其与场景的其他 16 位缓冲区合并……提醒各位上述视频的简单演示项目可以在 GitHub 上找到。
http://www.zskr.cn/news/1298753.html

相关文章:

  • 3个免费技巧让模糊图片变高清:Upscayl AI图像放大终极指南
  • 在Adafruit Fruit Jam微控制器上移植运行经典游戏DOOM的完整指南
  • G-Helper终极教程:华硕笔记本轻量级性能控制神器
  • 智充兽AI车载快充:车载共享充电模式解析与行业应用研究
  • 新能源电网电磁暂态仿真方法【附仿真】
  • 基于Fruit Jam RP2350的世嘉创世纪模拟器:从硬件选型到游戏部署全指南
  • Reset Windows Update Tool:Windows系统更新的数字工程师
  • 告别激活烦恼:3分钟搞定Windows和Office的正版体验
  • 基于555与4013的锁存看门狗设计:嵌入式系统高可靠性的硬件守护方案
  • 从公式到代码:用vcftools实战解析Fst群体遗传分化
  • Ubuntu中ping命令安装与网络诊断全攻略
  • wifi扫描出来了
  • golang如何实现分布式幂等方案_golang分布式幂等方案实现教程.txt
  • 【PCL中Ptr释放问题 aligned_free 的2种解决方法】
  • 基于STM32单片机人体健康检测血糖检测监测无线蓝牙APP设计S312
  • 泳装行业的AI革命:那些抢先拥抱AIGC的品牌,悄悄拉开了什么差距?
  • 个人八股之会话技术
  • AD20实战:从零到一构建高效PCB设计工作流
  • 接口(interface)与抽象(abstract)函数
  • Spring Boot 多线程场景下 i18n 国际化失效问题排查与解决
  • 量子纠缠态构建:级联环协议与固态量子发射器应用
  • 研学基地怎么做会员?李经理用年卡模式让营收翻了一倍
  • AnisoAlign:各向异性模态对齐
  • 用1.44寸ST7735 TFT屏DIY一个桌面天气站(附STM32/Arduino完整项目代码)
  • 【作品集】OpenClaw-AgentOps企业级多智能体贵金属交易分析平台
  • SQL 函数
  • 【硬核安全】打破iOS绝对安全神话!腾讯ACE硬件级反作弊架构深度解析
  • 避坑指南:在Ubuntu 20.04上一步步搞定OpenCalib的lidar2camera模块(含Docker和源码两种方式)
  • C++中的大对象传递策略与接口成本控制
  • 探索Mod Assistant:Beat Saber模组管理工具的高效解决方案