Home › Forums › GAMES在线课程(现代计算机图形学入门)讨论区 › 提高部分的解决方案 – 答案就在作业文档中
- This topic has 12 replies, 6 voices, and was last updated 4 years, 6 months ago by
sublimation.
-
AuthorPosts
-
-
看到大家在讨论交界处出现黑边的问题,那是因为我们超采样之后计算物体的颜色应该是这样的:
2*2 的采样:
4个在三角形中: 100% 物体颜色
3个在三角形中: 75% 物体颜色 + 25% 背景颜色
2个在三角形中: 50% 物体颜色 + 50% 背景颜色
…问题在于在三角形重合之处,我们的背景色可能是另一个三角形的颜色,比如像这样:
| 物体 | 背景 |
| —- | —- |
| 黄 | 绿 |
| 黄 | 绿 |那么颜色就应该是 1/2 * 黄 + 1/2 * 绿
最简单的解决办法已经写在了文档中:
对于像素内的每一个样本都需要维护它自己的深度值,即每一个像素都需要维护一个 sample list。
这个像素当然是指的屏幕像素,针对每一个屏幕像素,我们都需要维护 sample list,到时候用它来计算最终颜色。
请叫我活雷锋,不用谢
-
确实“黑边”并不是黑色,他是黄色和蓝色的混合,但是我现在很疑惑的是,就算每个像素都能维护了四个子采样点的深度,那着色时又要做什么操作呢?因为在我看来,MSAA的本质方法用的是模糊,所以在黄色三角形和蓝色三角形相交的地方必然会有蓝色和黄色互相模糊混合而产生的颜色(表现为深色),如果想要避免混合就不能使用模糊,也就不能使用抗锯齿了,哪怕只是在相交处禁用抗锯齿,我觉得这也不应该是最佳解决办法。所以请教一下,应该需要怎样的操作才能避免“颜色混合导致的变黑”。
This post has received 1 vote up. -
我把截图放进ps里看了下,
蓝色三角形的RGB值是(185,217,238)
绿色三角形的RGB值是(217,238,185)
两者的RGB值取平均是(201,227.5,211.5)
取1/4是(100.5,113.75,105.75)
但是实际上通过吸管工具得到的“黑线”的RGB值是(54,60,46)
这样就很奇怪了,实际上这个相交的点的颜色值不应该这么小才对
现在又对“黑线”的产生感到疑惑了,
如果有大佬知道希望能跟我解释一下,谢谢
如果有解决方案的话那就更好了-
黑边不是混叠是覆盖。。。。渲染过程是分离的,物体是一个一个渲染。先可以理解为渲染近的物体,再渲染远的物体(实际上这是一个比较随机的过程)。黑边的位置是前三角形的边缘,假设这个边缘有一半采样点在前三角内,一半在前三角外,那这个边缘pixel就采样了前三角的边缘梯度颜色。。。。随后开始渲染较远的三角形,在前三角重叠位置的边缘pixel,对后三角来说,有一半是能通过深度检测的(不被前三角遮挡)并且在后三角内(取后三角的颜色),另一半是被前三角遮挡不通过深度检测的(取背景黑色),这样又在这个边缘pixel获得了一个新的颜色值(这个值应该等于后三角的边缘梯度颜色)。。。。可以用吸管吸出看看两个值的确是相等的。。“黑边”是渲染后三角时用后三角的边缘颜色覆盖了实际上是前三角的一条边缘,只不过这两个浅纯色三角形之中视觉上看着更深而已。对pixel使用depth-buffer的话可以保证“黑边”位置不会被重复着色,而且逻辑上黑边位置就应该是前三角AA后的边缘梯度颜色,,,我之前在一篇帖子下回过一遍了,我觉得这种解释比较能讲通。话说着色是通过frame-buffer数组里存值的更新实现的,除非采样点是从frame-buffer里拿出颜色,否则默认不处理(取背景色黑)的话物体之间颜色是没有干扰混叠的
-
非常感谢!你的说法我理解了,但是我可不可以再问一句,就是,具体来说应该怎么实现呢?我看了你的回复以后我回去改了好久,但是还是得不到正确的答案,非常头疼,希望大神能指导一下。我的做法是把深度缓存的大小扩大四倍,保存每一个子采样点的深度,但是现在想想这样好像没必要,因为和扩大之前是几乎一样的,更何况我也没得到正确的结果。至于我在更之前的做法是直接检测每个像素的深度,也就是和使用反走样之前的做法一模一样。黑线现象的话我再次仔细用ps吸了下颜色,发现确实如你所说的,黑线其实就是其中一个三角形的边缘梯度颜色(在我这里是靠摄像机近的那个三角形的边缘梯度颜色),并不是我之前所说的“颜色叠加”。总之希望能够指点一下,实在不知道所说的维护子采样点的深度是什么意思,也不知道应该对每个子采样点应该做哪些操作。麻烦你了!
-
增加一个sample_depth_buf和一个sample_frame_buf试一下?都是四倍大
This post has received 1 vote up.-
谢谢!今早起来再看了一遍你相关的回答,我发现我之前对sample_depth_buf的维护有点问题,重新实现了一下就解决了,具体方法我开个帖子,总之非常感谢你提供的思路!
-
可否分享一下之前的错误?是代码实现的问题吗?因为一直在关注你的这个问题。我用了同样的做法却没有出现这个黑边,但是我觉得你的分析有点道理。不过多个颜色平均以后应该没有变深?谢谢啦~
-
This reply was modified 4 years, 6 months ago by
sublimation.
-
是的,是代码实现的问题,我分析下我的错误吧,我把我从错误到正确分为三个阶段,姑且分别叫做A、B、C阶段吧
A阶段:
这是第一次实现的MSAA,没有维护每一个子采样点的深度,子采样点只用来产生颜色,深度检测的话是以像素为单位的,而不是对子采样点做深度检测。因此在先渲染前三角形再渲染后三角形的前提下,前三角形的边缘是黑色和绿色(也就是前三角形颜色)的平均,这个结果是正确的,但是紧接着渲染后三角形的时候,因为我是以像素为单位进行深度检测的,所以哪怕检测对象是前三角形的边缘,它的深度也是大于后三角形的任何像素的,所以渲染后三角形的时候,在两个三角形相交的地方,也就是前三角形的边缘处,经过深度检测,产生的结果就是后三角形在相交处不渲染,也就是只留下了前三角形的边缘颜色(绿色和黑色的平均),所以会产生“黑边”
具体看图,A点是前三角形的边缘,是黑色和绿色的混合,B点是相交处,经过测量可见它们的RGB值是一样的,也就是说后三角形本来应该在相交处和前三角形边缘进行颜色叠加的,但它根本就不渲染,直接忽略了,留下的就是带黑色的前三角形边缘,根本原因就是之前提到的深度检测的问题B阶段:
进行改进,扩大了深度缓存到四倍,但是深度写入有问题,具体不好说,但总的来说从结果上就是当这个像素的深度大于缓存里对应的深度的时候,四个子采样点的深度都被同时写入这个像素的深度。这里很明显错了,因为既然深度检测是以子采样点为单位的,那么深度写入也要以子采样点为单位,不然扩大深度缓存就没有任何意义C阶段:
把深度写入进行改进,得到正确结果This post has received 1 vote up.Attachments:
You must be logged in to view attached files.
-
This reply was modified 4 years, 6 months ago by
-
-
-
-
-
-
明白了,感谢耐心解释。^^
-
rimon
Participant感谢大家的解释,按照上面提的思路实现了MSAA,请大家帮忙看下结果是否正确,因为我发现在三角形交界处仍然带了点黑边。
-
-
可能不太正确,交界处的黑色有点奇怪。这里应该融合两个三角形的颜色。
-
-
-
AuthorPosts
- You must be logged in to reply to this topic.