原文在此:

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释疑相关推荐

  1. 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 ...

  2. Blender多米诺骨牌动画学习教程 The Impossible Domino Run in Blender

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小:8.53 GB 含课程文件 |时长:8h 20 ...

  3. Expression Blend实例中文教程(2) - 界面快速入门

    上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...

  4. maya表情blendshape_Maya的形状融合变形器Blend Shape | 学步园

    Maya的形状融合变形器Blend Shape是制作面部表情动画的有力武器,它能通过使用一系列的目标形状物体(Target)使基础物体得到非常平顺.高精度的变形效果.它在角色动画的时候非常受用,尤其是 ...

  5. Expression Blend学习动画基础

    原文:Expression Blend学习动画基础 什么是动画(Animation)? 动画就是时间+换面的组合,画面跟着时间变化.最常见的是flash的动画,还有GIF动态图片. 动画的主要元素 时 ...

  6. Microsoft Expression Blend 2 密钥,key

    Microsoft Expression Blend 2 密钥,key,序列TJ2R3-WHW22-B848T-B78YJ-HHJWJ号

  7. Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(上)

    2019独角兽企业重金招聘Python工程师标准>>> 本篇文章,最终效果图: 当然,不只是一个UI而已,如果只是一张图片,那专业的设计师能做出更出色的效果.在这里,它是具有许多事件 ...

  8. Expression Blend 4 激活码

    Expression Blend 4 激活码: 6WDDQ-K7D4F-GQGF4-2VYBJ-8K6MB 转载于:https://www.cnblogs.com/canyuexingchen/p/3 ...

  9. Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...

    原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...

最新文章

  1. ActiveMQ的消息存储和持久化
  2. 【Ansible 文档】【译文】模式
  3. iOS开发 贝塞尔曲线UIBezierPath(后记)
  4. gRPC客户端创建和调用原理解析
  5. selenium学习笔记(一)
  6. C、C++语言中参数的压栈顺序
  7. 版人人商城V3.7.6开源解密版小程序前端+后端+安装使用视频教程
  8. 天池大数据竞赛-河北高校邀请赛——二手车交易价格预测-初赛第22名
  9. Emulex FC HBA卡FW升级与驱动安装
  10. image.shape[] 和array.shape[]的含义
  11. docker之run/cmd/entrypoint的区别
  12. oracle密码解锁
  13. 配置fly.js请求
  14. CentOS 7输入startx无法启动图形化界面
  15. 喜欢计算机专业的理由英语作文,计算机专业英文自我评价范文
  16. DNS服务器原理介绍(一)
  17. OpenGL_10 3D空间中移动图像
  18. flv.js php,flv.js的使用详解
  19. Github报错——Failed to connect to github.com port 443: Timed out
  20. 如何使用bert做word embedding

热门文章

  1. 机器人学习——姿态表达,ros通讯机制
  2. 线性方程组(七)- 线性无关
  3. easyui 合并列_Easyui DataGrid 合并单元格
  4. 什么是human synapsin promoter?
  5. php显示星期几,php怎么实现获取显示星期几
  6. (四)JNI学习之C语言基础,构造类型
  7. 【从0到1搭建LoRa物联网】3、国产LoRa终端ASR6505软硬件
  8. 【动态规划】引例--多起点,多终点的最短路径问题
  9. 白话讲懂wait notify 和park unpark的使用示例和区别
  10. How Linux Boots