mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Added lens distortion shader
This commit is contained in:
parent
43e577ce79
commit
6b9529d70f
11 changed files with 236 additions and 2 deletions
|
@ -1110,6 +1110,7 @@ set( FASTMATH_SOURCES
|
||||||
gl/shaders/gl_bloomshader.cpp
|
gl/shaders/gl_bloomshader.cpp
|
||||||
gl/shaders/gl_blurshader.cpp
|
gl/shaders/gl_blurshader.cpp
|
||||||
gl/shaders/gl_tonemapshader.cpp
|
gl/shaders/gl_tonemapshader.cpp
|
||||||
|
gl/shaders/gl_lensshader.cpp
|
||||||
gl/system/gl_interface.cpp
|
gl/system/gl_interface.cpp
|
||||||
gl/system/gl_framebuffer.cpp
|
gl/system/gl_framebuffer.cpp
|
||||||
gl/system/gl_menu.cpp
|
gl/system/gl_menu.cpp
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include "gl/shaders/gl_bloomshader.h"
|
#include "gl/shaders/gl_bloomshader.h"
|
||||||
#include "gl/shaders/gl_blurshader.h"
|
#include "gl/shaders/gl_blurshader.h"
|
||||||
#include "gl/shaders/gl_tonemapshader.h"
|
#include "gl/shaders/gl_tonemapshader.h"
|
||||||
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -95,6 +96,12 @@ CUSTOM_CVAR(Int, gl_bloom_kernel_size, 7, 0)
|
||||||
self = 7;
|
self = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CVAR(Bool, gl_lens, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
|
CVAR(Float, gl_lens_k, -0.15f, 0)
|
||||||
|
CVAR(Float, gl_lens_kcube, 0.15f, 0)
|
||||||
|
CVAR(Float, gl_lens_chromatic, 1.2f, 0)
|
||||||
|
|
||||||
EXTERN_CVAR(Float, vid_brightness)
|
EXTERN_CVAR(Float, vid_brightness)
|
||||||
EXTERN_CVAR(Float, vid_contrast)
|
EXTERN_CVAR(Float, vid_contrast)
|
||||||
|
|
||||||
|
@ -260,6 +267,70 @@ void FGLRenderer::TonemapScene()
|
||||||
glActiveTexture(activeTex);
|
glActiveTexture(activeTex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Apply lens distortion and place the result in the HUD/2D texture
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FGLRenderer::LensDistortScene()
|
||||||
|
{
|
||||||
|
if (gl_lens == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLint activeTex, textureBinding, samplerBinding;
|
||||||
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||||
|
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
||||||
|
{
|
||||||
|
glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding);
|
||||||
|
glBindSampler(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean blendEnabled, scissorEnabled;
|
||||||
|
glGetBooleanv(GL_BLEND, &blendEnabled);
|
||||||
|
glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled);
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
float k[4] =
|
||||||
|
{
|
||||||
|
gl_lens_k,
|
||||||
|
gl_lens_k * gl_lens_chromatic,
|
||||||
|
gl_lens_k * gl_lens_chromatic * gl_lens_chromatic,
|
||||||
|
0.0f
|
||||||
|
};
|
||||||
|
float kcube[4] =
|
||||||
|
{
|
||||||
|
gl_lens_kcube,
|
||||||
|
gl_lens_kcube * gl_lens_chromatic,
|
||||||
|
gl_lens_kcube * gl_lens_chromatic * gl_lens_chromatic,
|
||||||
|
0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
mBuffers->BindHudFB();
|
||||||
|
mBuffers->BindSceneTexture(0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
mLensShader->Bind();
|
||||||
|
mLensShader->InputTexture.Set(0);
|
||||||
|
mLensShader->LensDistortionCoefficient.Set(k);
|
||||||
|
mLensShader->CubicDistortionValue.Set(kcube);
|
||||||
|
mVBO->BindVBO();
|
||||||
|
mVBO->RenderScreenQuad();
|
||||||
|
|
||||||
|
if (blendEnabled)
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
if (scissorEnabled)
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||||
|
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
||||||
|
glBindSampler(0, samplerBinding);
|
||||||
|
glActiveTexture(activeTex);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Gamma correct while copying to frame buffer
|
// Gamma correct while copying to frame buffer
|
||||||
|
@ -357,6 +428,8 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||||
}
|
}
|
||||||
mBuffers->BindHudTexture(0);
|
mBuffers->BindHudTexture(0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
mVBO->BindVBO();
|
mVBO->BindVBO();
|
||||||
mVBO->RenderScreenQuad(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
mVBO->RenderScreenQuad(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,7 @@ void FGLRenderBuffers::BindSceneTextureFB()
|
||||||
|
|
||||||
void FGLRenderBuffers::BindHudFB()
|
void FGLRenderBuffers::BindHudFB()
|
||||||
{
|
{
|
||||||
if (gl_tonemap != 0)
|
if (gl_tonemap != 0 || gl_lens)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
|
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
|
||||||
else
|
else
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, mSceneTextureFB);
|
glBindFramebuffer(GL_FRAMEBUFFER, mSceneTextureFB);
|
||||||
|
@ -470,7 +470,7 @@ void FGLRenderBuffers::BindSceneTexture(int index)
|
||||||
void FGLRenderBuffers::BindHudTexture(int index)
|
void FGLRenderBuffers::BindHudTexture(int index)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + index);
|
glActiveTexture(GL_TEXTURE0 + index);
|
||||||
if (gl_tonemap != 0)
|
if (gl_tonemap != 0 || gl_lens)
|
||||||
glBindTexture(GL_TEXTURE_2D, mHudTexture);
|
glBindTexture(GL_TEXTURE_2D, mHudTexture);
|
||||||
else
|
else
|
||||||
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
|
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include "gl/shaders/gl_bloomshader.h"
|
#include "gl/shaders/gl_bloomshader.h"
|
||||||
#include "gl/shaders/gl_blurshader.h"
|
#include "gl/shaders/gl_blurshader.h"
|
||||||
#include "gl/shaders/gl_tonemapshader.h"
|
#include "gl/shaders/gl_tonemapshader.h"
|
||||||
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
#include "gl/textures/gl_texture.h"
|
#include "gl/textures/gl_texture.h"
|
||||||
#include "gl/textures/gl_translate.h"
|
#include "gl/textures/gl_translate.h"
|
||||||
|
@ -117,6 +118,7 @@ void FGLRenderer::Initialize()
|
||||||
mBloomCombineShader = new FBloomCombineShader();
|
mBloomCombineShader = new FBloomCombineShader();
|
||||||
mBlurShader = new FBlurShader();
|
mBlurShader = new FBlurShader();
|
||||||
mTonemapShader = new FTonemapShader();
|
mTonemapShader = new FTonemapShader();
|
||||||
|
mLensShader = new FLensShader();
|
||||||
mPresentShader = new FPresentShader();
|
mPresentShader = new FPresentShader();
|
||||||
|
|
||||||
// Only needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
// Only needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||||
|
@ -171,6 +173,7 @@ FGLRenderer::~FGLRenderer()
|
||||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||||
if (mBlurShader) delete mBlurShader;
|
if (mBlurShader) delete mBlurShader;
|
||||||
if (mTonemapShader) delete mTonemapShader;
|
if (mTonemapShader) delete mTonemapShader;
|
||||||
|
if (mLensShader) delete mLensShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -23,6 +23,7 @@ class FBloomExtractShader;
|
||||||
class FBloomCombineShader;
|
class FBloomCombineShader;
|
||||||
class FBlurShader;
|
class FBlurShader;
|
||||||
class FTonemapShader;
|
class FTonemapShader;
|
||||||
|
class FLensShader;
|
||||||
class FPresentShader;
|
class FPresentShader;
|
||||||
|
|
||||||
inline float DEG2RAD(float deg)
|
inline float DEG2RAD(float deg)
|
||||||
|
@ -90,6 +91,7 @@ public:
|
||||||
FBloomCombineShader *mBloomCombineShader;
|
FBloomCombineShader *mBloomCombineShader;
|
||||||
FBlurShader *mBlurShader;
|
FBlurShader *mBlurShader;
|
||||||
FTonemapShader *mTonemapShader;
|
FTonemapShader *mTonemapShader;
|
||||||
|
FLensShader *mLensShader;
|
||||||
FPresentShader *mPresentShader;
|
FPresentShader *mPresentShader;
|
||||||
|
|
||||||
FTexture *gllight;
|
FTexture *gllight;
|
||||||
|
@ -160,6 +162,7 @@ public:
|
||||||
void EndDrawScene(sector_t * viewsector);
|
void EndDrawScene(sector_t * viewsector);
|
||||||
void BloomScene();
|
void BloomScene();
|
||||||
void TonemapScene();
|
void TonemapScene();
|
||||||
|
void LensDistortScene();
|
||||||
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
||||||
void Flush() { CopyToBackbuffer(nullptr, true); }
|
void Flush() { CopyToBackbuffer(nullptr, true); }
|
||||||
|
|
||||||
|
|
|
@ -864,6 +864,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
if (FGLRenderBuffers::IsEnabled()) mBuffers->BlitSceneToTexture();
|
if (FGLRenderBuffers::IsEnabled()) mBuffers->BlitSceneToTexture();
|
||||||
BloomScene();
|
BloomScene();
|
||||||
TonemapScene();
|
TonemapScene();
|
||||||
|
LensDistortScene();
|
||||||
}
|
}
|
||||||
mDrawingScene2D = false;
|
mDrawingScene2D = false;
|
||||||
eye->TearDown();
|
eye->TearDown();
|
||||||
|
|
66
src/gl/shaders/gl_lensshader.cpp
Normal file
66
src/gl/shaders/gl_lensshader.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
** gl_lensshader.cpp
|
||||||
|
** Lens distortion with chromatic aberration shader
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2016 Magnus Norddahl
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
||||||
|
** covered by the terms of the GNU Lesser General Public License as published
|
||||||
|
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
** your option) any later version.
|
||||||
|
** 5. Full disclosure of the entire project's source code, except for third
|
||||||
|
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
#include "files.h"
|
||||||
|
#include "m_swap.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "gl/gl_functions.h"
|
||||||
|
#include "vectors.h"
|
||||||
|
#include "gl/system/gl_interface.h"
|
||||||
|
#include "gl/system/gl_framebuffer.h"
|
||||||
|
#include "gl/system/gl_cvars.h"
|
||||||
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
|
|
||||||
|
void FLensShader::Bind()
|
||||||
|
{
|
||||||
|
if (!mShader)
|
||||||
|
{
|
||||||
|
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/lensdistortion.vp", "", 330);
|
||||||
|
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/lensdistortion.fp", "", 330);
|
||||||
|
mShader.SetFragDataLocation(0, "FragColor");
|
||||||
|
mShader.Link("shaders/glsl/lensdistortion");
|
||||||
|
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||||
|
InputTexture.Init(mShader, "InputTexture");
|
||||||
|
LensDistortionCoefficient.Init(mShader, "k");
|
||||||
|
CubicDistortionValue.Init(mShader, "kcube");
|
||||||
|
}
|
||||||
|
mShader.Bind();
|
||||||
|
}
|
19
src/gl/shaders/gl_lensshader.h
Normal file
19
src/gl/shaders/gl_lensshader.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __GL_LENSSHADER_H
|
||||||
|
#define __GL_LENSSHADER_H
|
||||||
|
|
||||||
|
#include "gl_shaderprogram.h"
|
||||||
|
|
||||||
|
class FLensShader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Bind();
|
||||||
|
|
||||||
|
FBufferedUniform1i InputTexture;
|
||||||
|
FBufferedUniform4f LensDistortionCoefficient;
|
||||||
|
FBufferedUniform4f CubicDistortionValue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FShaderProgram mShader;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,5 +49,9 @@ EXTERN_CVAR(Float, gl_bloom_amount)
|
||||||
EXTERN_CVAR(Int, gl_bloom_kernel_size)
|
EXTERN_CVAR(Int, gl_bloom_kernel_size)
|
||||||
EXTERN_CVAR(Int, gl_tonemap)
|
EXTERN_CVAR(Int, gl_tonemap)
|
||||||
EXTERN_CVAR(Float, gl_exposure)
|
EXTERN_CVAR(Float, gl_exposure)
|
||||||
|
EXTERN_CVAR(Bool, gl_lens)
|
||||||
|
EXTERN_CVAR(Float, gl_lens_k)
|
||||||
|
EXTERN_CVAR(Float, gl_lens_kcube)
|
||||||
|
EXTERN_CVAR(Float, gl_lens_chromatic)
|
||||||
|
|
||||||
#endif // _GL_INTERN_H
|
#endif // _GL_INTERN_H
|
||||||
|
|
55
wadsrc/static/shaders/glsl/lensdistortion.fp
Normal file
55
wadsrc/static/shaders/glsl/lensdistortion.fp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
Original Lens Distortion Algorithm from SSontech
|
||||||
|
http://www.ssontech.com/content/lensalg.htm
|
||||||
|
|
||||||
|
If (u,v) are the coordinates of a feature in the undistorted perfect
|
||||||
|
image plane, then (u', v') are the coordinates of the feature on the
|
||||||
|
distorted image plate, ie the scanned or captured image from the
|
||||||
|
camera. The distortion occurs radially away from the image center,
|
||||||
|
with correction for the image aspect ratio (image_aspect = physical
|
||||||
|
image width/height), as follows:
|
||||||
|
|
||||||
|
r2 = image_aspect*image_aspect*u*u + v*v
|
||||||
|
f = 1 + r2*(k + kcube*sqrt(r2))
|
||||||
|
u' = f*u
|
||||||
|
v' = f*v
|
||||||
|
|
||||||
|
The constant k is the distortion coefficient that appears on the lens
|
||||||
|
panel and through Sizzle. It is generally a small positive or negative
|
||||||
|
number under 1%. The constant kcube is the cubic distortion value found
|
||||||
|
on the image preprocessor's lens panel: it can be used to undistort or
|
||||||
|
redistort images, but it does not affect or get computed by the solver.
|
||||||
|
When no cubic distortion is needed, neither is the square root, saving
|
||||||
|
time.
|
||||||
|
|
||||||
|
Chromatic Aberration example,
|
||||||
|
using red distord channel with green and blue undistord channel:
|
||||||
|
|
||||||
|
k = vec3(-0.15, 0.0, 0.0);
|
||||||
|
kcube = vec3(0.15, 0.0, 0.0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
in vec2 TexCoord;
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
uniform sampler2D InputTexture;
|
||||||
|
uniform vec4 k; // lens distortion coefficient
|
||||||
|
uniform vec4 kcube; // cubic distortion value
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 position = TexCoord - vec2(0.5);
|
||||||
|
|
||||||
|
float r2 = dot(position, position);
|
||||||
|
vec3 f = vec3(1.0) + r2 * (k.rgb + kcube.rgb * sqrt(r2));
|
||||||
|
|
||||||
|
vec3 x = f * position.x + 0.5;
|
||||||
|
vec3 y = f * position.y + 0.5;
|
||||||
|
|
||||||
|
vec3 c;
|
||||||
|
c.r = texture(InputTexture, vec2(x.r, y.r)).r;
|
||||||
|
c.g = texture(InputTexture, vec2(x.g, y.g)).g;
|
||||||
|
c.b = texture(InputTexture, vec2(x.b, y.b)).b;
|
||||||
|
|
||||||
|
FragColor = vec4(c, 1.0);
|
||||||
|
}
|
9
wadsrc/static/shaders/glsl/lensdistortion.vp
Normal file
9
wadsrc/static/shaders/glsl/lensdistortion.vp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
in vec4 PositionInProjection;
|
||||||
|
out vec2 TexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = PositionInProjection;
|
||||||
|
TexCoord = PositionInProjection.xy * 0.5 + 0.5;
|
||||||
|
}
|
Loading…
Reference in a new issue