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

使用OpenGL实现更平滑的渐变过渡?,opengl,glsl,opentk,Opengl,Glsl,Opentk,我正在使用以下着色器渲染skydome以模拟夜空。我的问题是颜色之间清晰可见的过渡 是什么导致了这些严酷的渐变过渡 片段着色器: #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,

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

是什么导致了这些严酷的渐变过渡


片段着色器:

#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);
}
Fbo像素格式:

GL.TexImage2D(
    TextureTarget.Texture2D,
    0,
    PixelInternalFormat.Rgb32f,
    WindowWidth,
    WindowHeight,
    0,
    PixelFormat.Rgb,
    PixelType.Float,
    IntPtr.Zero )

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

如果您的窗口水平大小为768像素,并且您希望在红色通道上有一个完整的渐变,那么每个颜色步骤需要768/256=3像素。根据你的眼睛健康状况,你可能会看到眼圈

如何在这3个像素上进行平滑渐变?使用渲染。

基本上,您可以“扩展”相邻像素之间的颜色步长:向相邻像素添加少量其他通道,并稍微减少中心像素量。

如Ripi2所述,24位颜色无法完美地表示渐变,可表示颜色之间的不连续性在单一颜色的渐变上变得异常明显

为了隐藏色带,我实现了一种简单的有序抖动形式,并使用该方法生成8x8纹理


RGB32F的
RGB32F
格式与所有这些有什么关系?我想说的是,你没有看到该纹理中的带状,你只是在最终渲染(或blit)到最终帧缓冲区时看到它,它通常只有8位精度。@derhass I包含了像素格式信息,以防它与问题有关,考虑到我当时所知道的,这似乎是合理的。亚像素渲染用于消除混叠。我想你的意思是说,“德哈斯”这个词在这里会被使用。重点是使用相邻像素平滑渐变。Floyd-steinberg很难以并行方式实现。简单有序抖动(bayer)在GPU上运行良好,易于实现。如果您编辑borh问答并使用一些不接近黑色的图像(这可能是最难看到的故障),效果会更好。
vec4 dither = vec4(texture2D(MyTexture0, gl_FragCoord.xy / 8.0).r / 32.0 - (1.0 / 128.0));
colourOut += dither;