PCSX2的impossible blend释疑
原文在此:
Explanation of impossible blend
http://pcsx2.net/developer-blog/268-explanation-impossible-blend.htmlhttp://pcsx2.net/developer-blog/268-explanation-impossible-blend.html
译者:我们很多人都用过PCSX2来玩PS2游戏,但可能很多人未必知道,PS2的模拟其实比很多其他硬件都要艰难。CPU方面由于EE/VU0/VU1自然不用多说,而GS方面,功能强大但和现代硬件不兼容的情况很多,偏偏很多游戏开发者(尤其是日系PS2游戏开发者)都喜欢摆弄一些稀奇古怪的效果,对模拟器开发人员来说就成为了一个大难题。老版本的PCSX2很多效果都不能在硬件模式下正确模拟,但新版解决了不少相关的问题。链接里就是PCSX2对PS2颜色混合模拟的官方解释。
---
颜色混合的目标是把两个颜色混合起来得到新的颜色。在现代的GPU上,混合公式一般是这么写的:
系数1 * 颜色1 +/- 系数2 * 颜色2
颜色1/颜色2 可能是源(fragment shader的计算结果)或者目标的颜色(帧缓冲里的保存数值)两者之一。
系数1/系数2可能是源或者目标的alpha值,1 - alpha,或者是一个常量。GPU会把系数clamp到0和1之间。
然而在PS2上,混合公式是这么写的:
(颜色1 - 颜色2) * 系数 + 颜色3
颜色1/2/3可能是源或者目标颜色,或者是0。
系数是源或者目标的alpha,或者是常量。
这给模拟器编写带来了两个问题:
1. PS2的系数值是被clamp到0和2之间的。还好这只在少数情境下出现。
(译注:最有名的例子之一,是FFX的重力魔法。当我了解了这个特效是如何实现之后,我深深崇拜想出这么用颜色混合的家伙。
这是个很普通的alpha blend,但由于alpha > 1,因此结果就从
SrcColor * SrcAlpha + DstColor * (1 - SrcAlpha)
变成了背景反色
SrcColor * SrcAlpha - DstColor * (SrcAlpha - 1)
错误的渲染结果是普通的alpha混合
正确的渲染结果,注意背景反色!
)
2. 如果颜色1/3是同一个源,那么公式就被转化为
颜色1 * (1 + 系数) - 颜色2 * 系数
看上去似乎能套在现代GPU的公式,然而1 + 系数意味着系数会大于1。在现代GPU下这个系数会被限制到1,无法正确模拟。(译注:这里的例子有很多,不过很多例子一般的玩家不一定能察觉。因为结果就是颜色比PS2要暗,但不至于很大的差别。)
PCSX2最近的更新把第二种情况给修正了。它使用的是在把混合公式直接塞到fragment shader里的方法。不过会有一个变数:fragment shader的执行比较慢(毕竟它相当于是在小CPU上执行的代码),所以现代GPU里都是并行乱序执行的。如果你一个draw call里塞入两个三角形,在计算的时候,第二个三角形的fragment shader可能会在第一个之前运算。然而颜色混合是按序执行的,如果乱序的话,渲染结果很可能就乱套了。不过,只要一次draw call渲染的物体本身没有自我覆盖,那么每个像素点只会被算一次fragment shader,那就不需要考虑执行顺序的问题了。
这就意味着,我们需要把一个n个三角面的draw call拆开成n个draw call。这么做的话性能损失就很大了,但在某些情形下这么干还是合理的。
另外一个要解决的问题就是如何访问目标像素的值。GPU是有纹理缓存(texture cache)的。纹理缓存是只读的,这样才不会有缓存一致性的问题。目标值可以被写入,但是下次读取的时候读取出来的值是错误的,这是因为缓存一致性被破坏。在进行fragment shader里混合的时候,纹理是只读的,但下一次draw call就被改变了。必须要有一个办法去invalidate 纹理缓存,而这在OpenGL 4.5里终于有函数去实现这个了。这样我们就能在fragment shader里进行颜色混合,而不会被GPU内核所限制住。
PCSX2的impossible blend释疑相关推荐
- Codeforces Round #487 (Div. 2) ---A.A Blend of Springtime
A. A Blend of Springtime time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Blender多米诺骨牌动画学习教程 The Impossible Domino Run in Blender
流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小:8.53 GB 含课程文件 |时长:8h 20 ...
- Expression Blend实例中文教程(2) - 界面快速入门
上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...
- maya表情blendshape_Maya的形状融合变形器Blend Shape | 学步园
Maya的形状融合变形器Blend Shape是制作面部表情动画的有力武器,它能通过使用一系列的目标形状物体(Target)使基础物体得到非常平顺.高精度的变形效果.它在角色动画的时候非常受用,尤其是 ...
- Expression Blend学习动画基础
原文:Expression Blend学习动画基础 什么是动画(Animation)? 动画就是时间+换面的组合,画面跟着时间变化.最常见的是flash的动画,还有GIF动态图片. 动画的主要元素 时 ...
- Microsoft Expression Blend 2 密钥,key
Microsoft Expression Blend 2 密钥,key,序列TJ2R3-WHW22-B848T-B78YJ-HHJWJ号
- Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(上)
2019独角兽企业重金招聘Python工程师标准>>> 本篇文章,最终效果图: 当然,不只是一个UI而已,如果只是一张图片,那专业的设计师能做出更出色的效果.在这里,它是具有许多事件 ...
- Expression Blend 4 激活码
Expression Blend 4 激活码: 6WDDQ-K7D4F-GQGF4-2VYBJ-8K6MB 转载于:https://www.cnblogs.com/canyuexingchen/p/3 ...
- Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...
原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...
最新文章
- ActiveMQ的消息存储和持久化
- 【Ansible 文档】【译文】模式
- iOS开发 贝塞尔曲线UIBezierPath(后记)
- gRPC客户端创建和调用原理解析
- selenium学习笔记(一)
- C、C++语言中参数的压栈顺序
- 版人人商城V3.7.6开源解密版小程序前端+后端+安装使用视频教程
- 天池大数据竞赛-河北高校邀请赛——二手车交易价格预测-初赛第22名
- Emulex FC HBA卡FW升级与驱动安装
- image.shape[] 和array.shape[]的含义
- docker之run/cmd/entrypoint的区别
- oracle密码解锁
- 配置fly.js请求
- CentOS 7输入startx无法启动图形化界面
- 喜欢计算机专业的理由英语作文,计算机专业英文自我评价范文
- DNS服务器原理介绍(一)
- OpenGL_10 3D空间中移动图像
- flv.js php,flv.js的使用详解
- Github报错——Failed to connect to github.com port 443: Timed out
- 如何使用bert做word embedding