mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-12 23:54:35 +00:00
Add a shadowmap shader
This commit is contained in:
parent
58c7c3c902
commit
6363c6cf58
6 changed files with 183 additions and 0 deletions
|
@ -952,6 +952,7 @@ set( FASTMATH_SOURCES
|
||||||
gl/shaders/gl_tonemapshader.cpp
|
gl/shaders/gl_tonemapshader.cpp
|
||||||
gl/shaders/gl_lensshader.cpp
|
gl/shaders/gl_lensshader.cpp
|
||||||
gl/shaders/gl_fxaashader.cpp
|
gl/shaders/gl_fxaashader.cpp
|
||||||
|
gl/shaders/gl_shadowmapshader.cpp
|
||||||
gl/system/gl_interface.cpp
|
gl/system/gl_interface.cpp
|
||||||
gl/system/gl_framebuffer.cpp
|
gl/system/gl_framebuffer.cpp
|
||||||
gl/system/gl_debug.cpp
|
gl/system/gl_debug.cpp
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "gl/shaders/gl_fxaashader.h"
|
#include "gl/shaders/gl_fxaashader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
#include "gl/shaders/gl_present3dRowshader.h"
|
#include "gl/shaders/gl_present3dRowshader.h"
|
||||||
|
#include "gl/shaders/gl_shadowmapshader.h"
|
||||||
#include "gl/stereo3d/gl_stereo3d.h"
|
#include "gl/stereo3d/gl_stereo3d.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"
|
||||||
|
@ -125,6 +126,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||||
mSSAOCombineShader = nullptr;
|
mSSAOCombineShader = nullptr;
|
||||||
mFXAAShader = nullptr;
|
mFXAAShader = nullptr;
|
||||||
mFXAALumaShader = nullptr;
|
mFXAALumaShader = nullptr;
|
||||||
|
mShadowMapShader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_LoadModels();
|
void gl_LoadModels();
|
||||||
|
@ -153,6 +155,7 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
mPresent3dCheckerShader = new FPresent3DCheckerShader();
|
mPresent3dCheckerShader = new FPresent3DCheckerShader();
|
||||||
mPresent3dColumnShader = new FPresent3DColumnShader();
|
mPresent3dColumnShader = new FPresent3DColumnShader();
|
||||||
mPresent3dRowShader = new FPresent3DRowShader();
|
mPresent3dRowShader = new FPresent3DRowShader();
|
||||||
|
mShadowMapShader = new FShadowMapShader();
|
||||||
m2DDrawer = new F2DDrawer;
|
m2DDrawer = new F2DDrawer;
|
||||||
|
|
||||||
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||||
|
@ -223,6 +226,7 @@ FGLRenderer::~FGLRenderer()
|
||||||
if (mTonemapPalette) delete mTonemapPalette;
|
if (mTonemapPalette) delete mTonemapPalette;
|
||||||
if (mColormapShader) delete mColormapShader;
|
if (mColormapShader) delete mColormapShader;
|
||||||
if (mLensShader) delete mLensShader;
|
if (mLensShader) delete mLensShader;
|
||||||
|
if (mShadowMapShader) delete mShadowMapShader;
|
||||||
delete mFXAAShader;
|
delete mFXAAShader;
|
||||||
delete mFXAALumaShader;
|
delete mFXAALumaShader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ class FPresent3DColumnShader;
|
||||||
class FPresent3DRowShader;
|
class FPresent3DRowShader;
|
||||||
class F2DDrawer;
|
class F2DDrawer;
|
||||||
class FHardwareTexture;
|
class FHardwareTexture;
|
||||||
|
class FShadowMapShader;
|
||||||
|
|
||||||
inline float DEG2RAD(float deg)
|
inline float DEG2RAD(float deg)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +124,7 @@ public:
|
||||||
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
||||||
FPresent3DColumnShader *mPresent3dColumnShader;
|
FPresent3DColumnShader *mPresent3dColumnShader;
|
||||||
FPresent3DRowShader *mPresent3dRowShader;
|
FPresent3DRowShader *mPresent3dRowShader;
|
||||||
|
FShadowMapShader *mShadowMapShader;
|
||||||
|
|
||||||
FLightBSP mLightBSP;
|
FLightBSP mLightBSP;
|
||||||
|
|
||||||
|
|
45
src/gl/shaders/gl_shadowmapshader.cpp
Normal file
45
src/gl/shaders/gl_shadowmapshader.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2016 Magnus Norddahl
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
#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_shadowmapshader.h"
|
||||||
|
|
||||||
|
void FShadowMapShader::Bind()
|
||||||
|
{
|
||||||
|
if (!mShader)
|
||||||
|
{
|
||||||
|
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 430);
|
||||||
|
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/shadowmap.fp", "", 430);
|
||||||
|
mShader.SetFragDataLocation(0, "FragColor");
|
||||||
|
mShader.Link("shaders/glsl/shadowmap");
|
||||||
|
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||||
|
}
|
||||||
|
mShader.Bind();
|
||||||
|
}
|
15
src/gl/shaders/gl_shadowmapshader.h
Normal file
15
src/gl/shaders/gl_shadowmapshader.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef __GL_SHADOWMAPSHADER_H
|
||||||
|
#define __GL_SHADOWMAPSHADER_H
|
||||||
|
|
||||||
|
#include "gl_shaderprogram.h"
|
||||||
|
|
||||||
|
class FShadowMapShader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Bind();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FShaderProgram mShader;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
116
wadsrc/static/shaders/glsl/shadowmap.fp
Normal file
116
wadsrc/static/shaders/glsl/shadowmap.fp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
|
||||||
|
in vec2 TexCoord;
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
struct GPUNode
|
||||||
|
{
|
||||||
|
vec4 plane;
|
||||||
|
int children[2];
|
||||||
|
int linecount[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUSeg
|
||||||
|
{
|
||||||
|
vec2 pos;
|
||||||
|
vec2 delta;
|
||||||
|
vec4 bSolid;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 2) buffer LightNodes
|
||||||
|
{
|
||||||
|
GPUNode bspNodes[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 3) buffer LightSegs
|
||||||
|
{
|
||||||
|
GPUSeg bspSegs[];
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Ray/BSP collision test. Returns 0 if the ray hit a line, 1 otherwise.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
float rayTest(vec2 from, vec2 to)
|
||||||
|
{
|
||||||
|
const int max_iterations = 50;
|
||||||
|
const float epsilon = 0.0000001;
|
||||||
|
|
||||||
|
// Avoid wall acne by adding some margin
|
||||||
|
vec2 margin = normalize(to - from);
|
||||||
|
to -= margin;
|
||||||
|
|
||||||
|
vec2 raydelta = to - from;
|
||||||
|
float raydist2 = dot(raydelta, raydelta);
|
||||||
|
vec2 raynormal = vec2(raydelta.y, -raydelta.x);
|
||||||
|
float rayd = dot(raynormal, from);
|
||||||
|
|
||||||
|
if (raydist2 < 1.0 || bspNodes.length() == 0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
int nodeIndex = bspNodes.length() - 1;
|
||||||
|
|
||||||
|
for (int iteration = 0; iteration < max_iterations; iteration++)
|
||||||
|
{
|
||||||
|
GPUNode node = bspNodes[nodeIndex];
|
||||||
|
int side = (dot(node.plane, vec4(from, 0.0, 1.0)) > 0.0) ? 1 : 0;
|
||||||
|
int linecount = node.linecount[side];
|
||||||
|
if (linecount < 0)
|
||||||
|
{
|
||||||
|
nodeIndex = node.children[side];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int startLineIndex = node.children[side];
|
||||||
|
|
||||||
|
// Ray/line test each line segment.
|
||||||
|
bool hit_line = false;
|
||||||
|
for (int i = 0; i < linecount; i++)
|
||||||
|
{
|
||||||
|
GPUSeg seg = bspSegs[startLineIndex + i];
|
||||||
|
|
||||||
|
float den = dot(raynormal, seg.delta);
|
||||||
|
if (abs(den) > epsilon)
|
||||||
|
{
|
||||||
|
float t_seg = (rayd - dot(raynormal, seg.pos)) / den;
|
||||||
|
if (t_seg >= 0.0 && t_seg <= 1.0)
|
||||||
|
{
|
||||||
|
vec2 seghitdelta = seg.pos + seg.delta * t_seg - from;
|
||||||
|
if (dot(raydelta, seghitdelta) > 0.0 && dot(seghitdelta, seghitdelta) < raydist2) // We hit a line segment.
|
||||||
|
{
|
||||||
|
if (seg.bSolid.x > 0.0) // segment line is one-sided
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
// We hit a two-sided segment line. Move to the other side and continue ray tracing.
|
||||||
|
from = from + seghitdelta + margin;
|
||||||
|
|
||||||
|
raydelta = to - from;
|
||||||
|
raydist2 = dot(raydelta, raydelta);
|
||||||
|
raynormal = vec2(raydelta.y, -raydelta.x);
|
||||||
|
rayd = dot(raynormal, from);
|
||||||
|
|
||||||
|
if (raydist2 < 1.0 || bspNodes.length() == 0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
nodeIndex = bspNodes.length() - 1;
|
||||||
|
|
||||||
|
hit_line = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hit_line)
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(rayTest(vec2(0.0, 0.0), vec2(1.0, 1.0));
|
||||||
|
}
|
Loading…
Reference in a new issue