希望您能看到从左下角开始沿长方体扩展的渐变。
这里是产生这种镜面反射光的着色器代码:
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);
顺便说一句,我在视图空间中进行照明计算。
有没有机会使照明更平滑?
#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
评论
当您说“渐变”时,您是指颜色中可见的不连续点吗?我假设您不想要单色,而是想要一个平滑的渐变并且看不到任何条纹?那正是我想要的。
在这种情况下,您是否要通过lightDir在视区中?
是的,我在视图空间中进行照明。