使用OpenGL更平滑的渐变过渡?

时间:2018-07-17 15:32:30

标签: opengl glsl opentk

我正在使用以下着色器渲染skydome以模拟夜空。我的问题是颜色之间清晰可见的过渡。

是什么原因导致这些苛刻的梯度过渡?

enter image description here

片段着色器:

-O0

Fbo像素格式:

#version 330
in vec3 worldPosition;
layout(location = 0) out vec4 outputColor;

void main()
{
    float height = 0.007*(abs(worldPosition.y)-200);    
    vec4 apexColor = vec4(0,0,0,1);
    vec4 centerColor = vec4(0.159, 0.132, 0.1, 1);

    outputColor = mix(centerColor, apexColor, height);
}

2 个答案:

答案 0 :(得分:5)

正如Ripi2所解释的,24位颜色不能完美地表示渐变,并且可表示的颜色之间的不连续性在单一颜色的渐变上变得非常明显。

为隐藏色带,我实现了一种简单的有序抖动形式,并使用此bayer matrix algorithm生成了8x8纹理。

enter image description here

vec4 dither = vec4(texture2D(MyTexture0, gl_FragCoord.xy / 8.0).r / 32.0 - (1.0 / 128.0));
colourOut += dither;

enter image description here

答案 1 :(得分:2)

通常,监视器的每个通道分辨率为8位。例如,红色强度在0到255之间变化。

如果您的窗口水平尺寸为768像素,并且您希望在红色通道上具有完整的渐变,则每个颜色步长需要768/256 = 3像素。根据您的眼睛健康状况,您可能会看到条带。

如何在这3个像素上进行平滑渐变?使用sub-pixel渲染。
基本上,您可以在相邻像素之间“扩展”颜色步长:向相邻像素添加少量其他通道,并减少中心像素数量。