我将Phong阴影用作照明模型。尽管如此,镜面反射阴影会在光锥中产生渐变:



希望您能看到从左下角开始沿长方体扩展的渐变。

这里是产生这种镜面反射光的着色器代码:

vec3 viewDir = normalize(-FragPos);
vec3 lightDir = normalize(-light.direction);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);


顺便说一句,我在视图空间中进行照明计算。

有没有机会使照明更平滑?

评论

当您说“渐变”时,您是指颜色中可见的不连续点吗?我假设您不想要单色,而是想要一个平滑的渐变并且看不到任何条纹?

那正是我想要的。

在这种情况下,您是否要通过lightDir在视区中?

是的,我在视图空间中进行照明。

#1 楼

这是非常微妙的渐变的常见问题。问题在于,图像的每个分量显示为8位,并且在这种情况下,精度不够高,无法形成令眼睛平滑的渐变。

但是,基本计算是在着色器具有较高的精度(例如,float = 24个有效尾数),因此您可以应用抖动来改善图像的外观。

您可以通过添加少量随机噪声来实现此目的。着色器中每个像素的值。噪声可能来自纹理,该纹理填充有[0,1]中的随机灰度值,并以1:1比例映射到屏幕像素。在着色器中,将其重新映射到[-0.5 / 255,0.5 / 255]范围,并将其添加到输出颜色。

这里有一个Shadertoy演示了这一点。左侧没有抖动;右侧使用刚才描述的过程。如您所见,条带在右侧消失。



抖动有效地使您可以表示8位整数级之间的中间值。例如,着色器计算为82.3(255个中的一个)的区域通常会均匀地四舍五入为82,但是通过抖动,它会以随机混合的形式出现,其中70%的像素设置为82,而30%的像素设置为到83。在这种非常细微的高频噪声下,眼睛平均下来,几乎变得看不见。

评论


$ \ begingroup $
好招。我注意到您在Shadertoy中向像素坐标添加了.5,这是在纹理中击中像素中心而不是采样样本吗?
$ \ endgroup $
– russ
16 Sep 8'在6:23

$ \ begingroup $
@russ嗯,我实际上是从另一个Shadertoy复制粘贴了这一点的。 :D再看一遍,我认为实际上不需要.5。 fragCoord应该已经在像素中心上了。
$ \ endgroup $
–内森·里德(Nathan Reed)
16 Sep 8'在6:28

$ \ begingroup $
对于任何有兴趣的人,这也是一篇很好描述的文章,介绍如何实现抖动以避免色带。祝您编码愉快!
$ \ endgroup $
– enne87
2016年9月9日14:38在

$ \ begingroup $
您可以尝试执行实际的统计误差分布,而不仅仅是均匀地添加噪声,以获得更好的结果。 tannerhelland.com/4660/dithering-eleven-algorithms-source-code
$ \ endgroup $
–v.oddou
18年4月25日在7:38

$ \ begingroup $
@ v.oddou也许。我认为,错误扩散将需要额外的全屏传递,而不是添加可以在着色器中内联完成的噪声。
$ \ endgroup $
–内森·里德(Nathan Reed)
18年4月25日在15:55