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

liv*_*muk 4 opengl glsl opentk

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

是什么导致这些刺耳的梯度过渡?

在此输入图像描述

片段着色器:

#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);
}
Run Code Online (Sandbox Code Playgroud)

Fbo像素格式:

GL.TexImage2D(
    TextureTarget.Texture2D,
    0,
    PixelInternalFormat.Rgb32f,
    WindowWidth,
    WindowHeight,
    0,
    PixelFormat.Rgb,
    PixelType.Float,
    IntPtr.Zero )
Run Code Online (Sandbox Code Playgroud)

liv*_*muk 5

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

为了隐藏颜色条带,我实现了一种简单形式的有序抖动,使用这种拜耳矩阵算法生成8x8纹理.

在此输入图像描述

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

在此输入图像描述


Rip*_*pi2 2

通常显示器的每通道分辨率为 8 位。例如,红色强度从 0 到 255 变化。

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

如何对这 3 个像素进行平滑渐变?使用子像素渲染。
基本上,您“扩展”相邻像素之间的颜色步骤:向相邻像素添加少量其他通道,并稍微减少中心像素数量。