- use a texture for the dither matrix

This commit is contained in:
Magnus Norddahl 2018-08-08 00:54:12 +02:00
parent 07c9db682d
commit 31addbc859
4 changed files with 41 additions and 22 deletions

View file

@ -176,6 +176,7 @@ void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma)
FGLDebug::PushGroup("CopyToBackbuffer");
FGLPostProcessState savedState;
savedState.SaveTextureBindings(2);
mBuffers->BindOutputFB();
IntRect box;
@ -198,6 +199,8 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
{
glViewport(box.left, box.top, box.width, box.height);
GLRenderer->mBuffers->BindDitherTexture(1);
glActiveTexture(GL_TEXTURE0);
if (ViewportLinearScale())
{

View file

@ -61,6 +61,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
ClearPipeline();
ClearEyeBuffers();
ClearShadowMap();
DeleteTexture(mDitherTexture);
}
void FGLRenderBuffers::ClearScene()
@ -559,6 +560,36 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye].handle);
}
void FGLRenderBuffers::BindDitherTexture(int texunit)
{
if (!mDitherTexture)
{
float halfstep = 1.0f / 65.0f;
float data[64] =
{
0.0f / 16.0f + halfstep * 1, 8.0f / 16.0f + halfstep * 1, 2.0f / 16.0f + halfstep * 1, 10.0f / 16.0f + halfstep * 1,
0.0f / 16.0f + halfstep * 3, 8.0f / 16.0f + halfstep * 3, 2.0f / 16.0f + halfstep * 3, 10.0f / 16.0f + halfstep * 3,
12.0f / 16.0f + halfstep * 1, 4.0f / 16.0f + halfstep * 1, 14.0f / 16.0f + halfstep * 1, 6.0f / 16.0f + halfstep * 1,
12.0f / 16.0f + halfstep * 3, 4.0f / 16.0f + halfstep * 3, 14.0f / 16.0f + halfstep * 3, 6.0f / 16.0f + halfstep * 3,
3.0f / 16.0f + halfstep * 1, 11.0f / 16.0f + halfstep * 1, 1.0f / 16.0f + halfstep * 1, 9.0f / 16.0f + halfstep * 1,
3.0f / 16.0f + halfstep * 3, 11.0f / 16.0f + halfstep * 3, 1.0f / 16.0f + halfstep * 3, 9.0f / 16.0f + halfstep * 3,
15.0f / 16.0f + halfstep * 1, 7.0f / 16.0f + halfstep * 1, 13.0f / 16.0f + halfstep * 1, 5.0f / 16.0f + halfstep * 1,
15.0f / 16.0f + halfstep * 3, 7.0f / 16.0f + halfstep * 3, 13.0f / 16.0f + halfstep * 3, 5.0f / 16.0f + halfstep * 3,
0.0f / 16.0f + halfstep * 4, 8.0f / 16.0f + halfstep * 4, 2.0f / 16.0f + halfstep * 4, 10.0f / 16.0f + halfstep * 4,
0.0f / 16.0f + halfstep * 2, 8.0f / 16.0f + halfstep * 2, 2.0f / 16.0f + halfstep * 2, 10.0f / 16.0f + halfstep * 2,
12.0f / 16.0f + halfstep * 4, 4.0f / 16.0f + halfstep * 4, 14.0f / 16.0f + halfstep * 4, 6.0f / 16.0f + halfstep * 4,
12.0f / 16.0f + halfstep * 2, 4.0f / 16.0f + halfstep * 2, 14.0f / 16.0f + halfstep * 2, 6.0f / 16.0f + halfstep * 2,
3.0f / 16.0f + halfstep * 4, 11.0f / 16.0f + halfstep * 4, 1.0f / 16.0f + halfstep * 4, 9.0f / 16.0f + halfstep * 4,
3.0f / 16.0f + halfstep * 2, 11.0f / 16.0f + halfstep * 2, 1.0f / 16.0f + halfstep * 2, 9.0f / 16.0f + halfstep * 2,
15.0f / 16.0f + halfstep * 4, 7.0f / 16.0f + halfstep * 4, 13.0f / 16.0f + halfstep * 4, 5.0f / 16.0f + halfstep * 4,
15.0f / 16.0f + halfstep * 2, 7.0f / 16.0f + halfstep * 2, 13.0f / 16.0f + halfstep * 2, 5.0f / 16.0f + halfstep * 2
};
mDitherTexture = Create2DTexture("DitherTexture", GL_R32F, 8, 8, data);
}
mDitherTexture.Bind(1, GL_NEAREST, GL_REPEAT);
}
//==========================================================================
//
// Shadow map texture and frame buffers

View file

@ -88,6 +88,8 @@ public:
void BindEyeTexture(int eye, int texunit);
void BindEyeFB(int eye, bool readBuffer = false);
void BindDitherTexture(int texunit);
void BindShadowMapFB();
void BindShadowMapTexture(int index);
@ -157,6 +159,8 @@ private:
PPGLFrameBuffer mShadowMapFB;
int mCurrentShadowMapSize = 0;
PPGLTexture mDitherTexture;
// Postprocess OpenGL objects
TMap<PPTextureName, PPGLTexture> GLTextures;
TMap<PPTextureName, PPGLFrameBuffer> GLTextureFBs;

View file

@ -3,6 +3,7 @@ in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D InputTexture;
layout(binding=1) uniform sampler2D DitherTexture;
vec4 ApplyGamma(vec4 c)
{
@ -17,30 +18,10 @@ vec4 ApplyGamma(vec4 c)
return vec4(val, c.a);
}
#define HALFSTEP 1./65.
float DitherMatrix[64] = float[](
0.0 / 16.0 + HALFSTEP * 1, 8.0 / 16.0 + HALFSTEP * 1, 2.0 / 16.0 + HALFSTEP * 1, 10.0 / 16.0 + HALFSTEP * 1,
0.0 / 16.0 + HALFSTEP * 3, 8.0 / 16.0 + HALFSTEP * 3, 2.0 / 16.0 + HALFSTEP * 3, 10.0 / 16.0 + HALFSTEP * 3,
12.0 / 16.0 + HALFSTEP * 1, 4.0 / 16.0 + HALFSTEP * 1, 14.0 / 16.0 + HALFSTEP * 1, 6.0 / 16.0 + HALFSTEP * 1,
12.0 / 16.0 + HALFSTEP * 3, 4.0 / 16.0 + HALFSTEP * 3, 14.0 / 16.0 + HALFSTEP * 3, 6.0 / 16.0 + HALFSTEP * 3,
3.0 / 16.0 + HALFSTEP * 1, 11.0 / 16.0 + HALFSTEP * 1, 1.0 / 16.0 + HALFSTEP * 1, 9.0 / 16.0 + HALFSTEP * 1,
3.0 / 16.0 + HALFSTEP * 3, 11.0 / 16.0 + HALFSTEP * 3, 1.0 / 16.0 + HALFSTEP * 3, 9.0 / 16.0 + HALFSTEP * 3,
15.0 / 16.0 + HALFSTEP * 1, 7.0 / 16.0 + HALFSTEP * 1, 13.0 / 16.0 + HALFSTEP * 1, 5.0 / 16.0 + HALFSTEP * 1,
15.0 / 16.0 + HALFSTEP * 3, 7.0 / 16.0 + HALFSTEP * 3, 13.0 / 16.0 + HALFSTEP * 3, 5.0 / 16.0 + HALFSTEP * 3,
0.0 / 16.0 + HALFSTEP * 4, 8.0 / 16.0 + HALFSTEP * 4, 2.0 / 16.0 + HALFSTEP * 4, 10.0 / 16.0 + HALFSTEP * 4,
0.0 / 16.0 + HALFSTEP * 2, 8.0 / 16.0 + HALFSTEP * 2, 2.0 / 16.0 + HALFSTEP * 2, 10.0 / 16.0 + HALFSTEP * 2,
12.0 / 16.0 + HALFSTEP * 4, 4.0 / 16.0 + HALFSTEP * 4, 14.0 / 16.0 + HALFSTEP * 4, 6.0 / 16.0 + HALFSTEP * 4,
12.0 / 16.0 + HALFSTEP * 2, 4.0 / 16.0 + HALFSTEP * 2, 14.0 / 16.0 + HALFSTEP * 2, 6.0 / 16.0 + HALFSTEP * 2,
3.0 / 16.0 + HALFSTEP * 4, 11.0 / 16.0 + HALFSTEP * 4, 1.0 / 16.0 + HALFSTEP * 4, 9.0 / 16.0 + HALFSTEP * 4,
3.0 / 16.0 + HALFSTEP * 2, 11.0 / 16.0 + HALFSTEP * 2, 1.0 / 16.0 + HALFSTEP * 2, 9.0 / 16.0 + HALFSTEP * 2,
15.0 / 16.0 + HALFSTEP * 4, 7.0 / 16.0 + HALFSTEP * 4, 13.0 / 16.0 + HALFSTEP * 4, 5.0 / 16.0 + HALFSTEP * 4,
15.0 / 16.0 + HALFSTEP * 2, 7.0 / 16.0 + HALFSTEP * 2, 13.0 / 16.0 + HALFSTEP * 2, 5.0 / 16.0 + HALFSTEP * 2
);
vec4 Dither(vec4 c, float colorscale)
{
ivec2 pos = ivec2(gl_FragCoord.xy) & 7;
float threshold = DitherMatrix[pos.x + (pos.y << 3)];
vec2 texSize = vec2(textureSize(DitherTexture, 0));
float threshold = texture(DitherTexture, gl_FragCoord.xy / texSize).r;
return vec4(floor(c.rgb * colorscale + threshold) / colorscale, c.a);
}