From 0ddfb86c6770614d55d32f94ec6089c6581961ab Mon Sep 17 00:00:00 2001 From: BennyQBD Date: Sat, 21 Jun 2014 12:32:50 -0400 Subject: [PATCH] Included Experimental Shading system --- res/shaders/common.glh | 34 +++++++++++++ res/shaders/filter-fxaa.glsl | 76 +++++++++++++++++++++++++++++ res/shaders/filter-gausBlur7x1.glsl | 36 ++++++++++++++ res/shaders/filter-null.glsl | 24 +++++++++ res/shaders/forward-ambient.glsl | 47 ++++++++++++++++++ res/shaders/shadowMapGenerator.glsl | 24 +++++++++ src/renderingEngine.cpp | 10 ++-- src/shader.cpp | 76 ++++++++++++++++++++++------- src/shader.h | 5 +- 9 files changed, 308 insertions(+), 24 deletions(-) create mode 100644 res/shaders/common.glh create mode 100644 res/shaders/filter-fxaa.glsl create mode 100644 res/shaders/filter-gausBlur7x1.glsl create mode 100644 res/shaders/filter-null.glsl create mode 100644 res/shaders/forward-ambient.glsl create mode 100644 res/shaders/shadowMapGenerator.glsl diff --git a/res/shaders/common.glh b/res/shaders/common.glh new file mode 100644 index 0000000..ec461dc --- /dev/null +++ b/res/shaders/common.glh @@ -0,0 +1,34 @@ +#if (GLSL_VERSION >= 150) + #define DeclareFragOutput(locationNumber, type) out type outputLocation##locationNumber + #define SetFragOutput(locationNumber, val) outputLocation##locationNumber = val + + #define texture2D(tex, coord) texture(tex, coord) + + #if defined(VS_BUILD) + #define varying out + #elif defined(FS_BUILD) + #define varying in + #endif +#else + #define DeclareFragOutput(locationNumber) + #define SetFragOutput(locationNumber, val) gl_FragData[locationNumber] = val +#endif + +#if (GLSL_VERSION >= 400) + #define mad(a, b, c) fma(a, b, c) +#else + #define mad(a, b, c) (a * b + c) +#endif + +#define float2 vec2 +#define float3 vec3 +#define float4 vec4 +#define int2 ivec2 +#define int3 ivec3 +#define int4 ivec4 +#define bool2 bvec2 +#define bool3 bvec3 +#define bool4 bvec4 + +#define lerp(a, b, t) mix(a, b, t) +#define saturate(a) clamp(a, 0.0, 1.0) diff --git a/res/shaders/filter-fxaa.glsl b/res/shaders/filter-fxaa.glsl new file mode 100644 index 0000000..fe7c193 --- /dev/null +++ b/res/shaders/filter-fxaa.glsl @@ -0,0 +1,76 @@ +#include "common.glh" +// FXAA shader, GLSL code adapted from: +// http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA +// Whitepaper describing the technique: +// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf + +varying vec2 texCoord0; + +#if defined(VS_BUILD) +attribute vec3 position; +attribute vec2 texCoord; + +uniform mat4 T_MVP; + +void main() +{ + texCoord0 = texCoord; + gl_Position = T_MVP * vec4(position, 1.0); +} + +#elif defined(FS_BUILD) +uniform sampler2D R_filterTexture; +uniform vec3 R_inverseFilterTextureSize; +uniform float R_fxaaSpanMax; +uniform float R_fxaaReduceMin; +uniform float R_fxaaReduceMul; + +DeclareFragOutput(0, vec4); +void main() +{ + vec2 texCoordOffset = R_inverseFilterTextureSize.xy; + + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaTL = dot(luma, texture2D(R_filterTexture, texCoord0.xy + (vec2(-1.0, -1.0) * texCoordOffset)).xyz); + float lumaTR = dot(luma, texture2D(R_filterTexture, texCoord0.xy + (vec2(1.0, -1.0) * texCoordOffset)).xyz); + float lumaBL = dot(luma, texture2D(R_filterTexture, texCoord0.xy + (vec2(-1.0, 1.0) * texCoordOffset)).xyz); + float lumaBR = dot(luma, texture2D(R_filterTexture, texCoord0.xy + (vec2(1.0, 1.0) * texCoordOffset)).xyz); + float lumaM = dot(luma, texture2D(R_filterTexture, texCoord0.xy).xyz); + + vec2 dir; + dir.x = -((lumaTL + lumaTR) - (lumaBL + lumaBR)); + dir.y = ((lumaTL + lumaBL) - (lumaTR + lumaBR)); + + float dirReduce = max((lumaTL + lumaTR + lumaBL + lumaBR) * (R_fxaaReduceMul * 0.25), R_fxaaReduceMin); + float inverseDirAdjustment = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); + + dir = min(vec2(R_fxaaSpanMax, R_fxaaSpanMax), + max(vec2(-R_fxaaSpanMax, -R_fxaaSpanMax), dir * inverseDirAdjustment)); + + dir.x = dir.x * step(1.0, abs(dir.x)); + dir.y = dir.y * step(1.0, abs(dir.y)); + + //float dirStep = max(step(1.0, abs(dir.x)), step(1.0, abs(dir.y))); + //dir.x = dir.x * dirStep; + //dir.y = dir.y * dirStep; + + dir = dir * texCoordOffset; + + vec3 result1 = (1.0/2.0) * ( + texture2D(R_filterTexture, texCoord0.xy + (dir * vec2(1.0/3.0 - 0.5))).xyz + + texture2D(R_filterTexture, texCoord0.xy + (dir * vec2(2.0/3.0 - 0.5))).xyz); + + vec3 result2 = result1 * (1.0/2.0) + (1.0/4.0) * ( + texture2D(R_filterTexture, texCoord0.xy + (dir * vec2(0.0/3.0 - 0.5))).xyz + + texture2D(R_filterTexture, texCoord0.xy + (dir * vec2(3.0/3.0 - 0.5))).xyz); + + float lumaMin = min(lumaM, min(min(lumaTL, lumaTR), min(lumaBL, lumaBR))); + float lumaMax = max(lumaM, max(max(lumaTL, lumaTR), max(lumaBL, lumaBR))); + float lumaResult2 = dot(luma, result2); + + if(lumaResult2 < lumaMin || lumaResult2 > lumaMax) + SetFragOutput(0, vec4(result1, 1.0)); + else + SetFragOutput(0, vec4(result2, 1.0)); +} +#endif diff --git a/res/shaders/filter-gausBlur7x1.glsl b/res/shaders/filter-gausBlur7x1.glsl new file mode 100644 index 0000000..b28f883 --- /dev/null +++ b/res/shaders/filter-gausBlur7x1.glsl @@ -0,0 +1,36 @@ +#include "common.glh" + +varying vec2 texCoord0; + +#if defined(VS_BUILD) +attribute vec3 position; +attribute vec2 texCoord; + +uniform mat4 T_MVP; + +void main() +{ + gl_Position = T_MVP * vec4(position, 1.0); + texCoord0 = texCoord; +} + +#elif defined(FS_BUILD) +uniform vec3 R_blurScale; +uniform sampler2D R_filterTexture; + +DeclareFragOutput(0, vec4); +void main() +{ + vec4 color = vec4(0.0); + + color += texture2D(R_filterTexture, texCoord0 + (vec2(-3.0) * R_blurScale.xy)) * (1.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(-2.0) * R_blurScale.xy)) * (6.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(-1.0) * R_blurScale.xy)) * (15.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(0.0) * R_blurScale.xy)) * (20.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(1.0) * R_blurScale.xy)) * (15.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(2.0) * R_blurScale.xy)) * (6.0/64.0); + color += texture2D(R_filterTexture, texCoord0 + (vec2(3.0) * R_blurScale.xy)) * (1.0/64.0); + + SetFragOutput(0, color); +} +#endif diff --git a/res/shaders/filter-null.glsl b/res/shaders/filter-null.glsl new file mode 100644 index 0000000..0f4bd42 --- /dev/null +++ b/res/shaders/filter-null.glsl @@ -0,0 +1,24 @@ +#include "common.glh" + +varying vec2 texCoord0; + +#if defined(VS_BUILD) +attribute vec3 position; +attribute vec2 texCoord; + +uniform mat4 T_MVP; + +void main() +{ + gl_Position = T_MVP * vec4(position, 1.0); + texCoord0 = texCoord; +} +#elif defined(FS_BUILD) +uniform sampler2D R_filterTexture; + +DeclareFragOutput(0, vec4); +void main() +{ + SetFragOutput(0, texture2D(R_filterTexture, texCoord0)); +} +#endif diff --git a/res/shaders/forward-ambient.glsl b/res/shaders/forward-ambient.glsl new file mode 100644 index 0000000..85d01d1 --- /dev/null +++ b/res/shaders/forward-ambient.glsl @@ -0,0 +1,47 @@ +#include "common.glh" + +varying vec2 texCoord0; +varying vec3 worldPos0; +varying mat3 tbnMatrix; + +#if defined(VS_BUILD) +attribute vec3 position; +attribute vec2 texCoord; +attribute vec3 normal; +attribute vec3 tangent; + +uniform mat4 T_model; +uniform mat4 T_MVP; + +void main() +{ + gl_Position = T_MVP * vec4(position, 1.0); + texCoord0 = texCoord; + worldPos0 = (T_model * vec4(position, 1.0)).xyz; + + vec3 n = normalize((T_model * vec4(normal, 0.0)).xyz); + vec3 t = normalize((T_model * vec4(tangent, 0.0)).xyz); + t = normalize(t - dot(t, n) * n); + + vec3 biTangent = cross(t, n); + tbnMatrix = mat3(t, biTangent, n); +} +#elif defined(FS_BUILD) +#include "sampling.glh" + +uniform vec3 R_ambient; +uniform vec3 C_eyePos; +uniform sampler2D diffuse; +uniform sampler2D dispMap; + +uniform float dispMapScale; +uniform float dispMapBias; + +DeclareFragOutput(0, vec4); +void main() +{ + vec3 directionToEye = normalize(C_eyePos - worldPos0); + vec2 texCoords = CalcParallaxTexCoords(dispMap, tbnMatrix, directionToEye, texCoord0, dispMapScale, dispMapBias); + SetFragOutput(0, texture2D(diffuse, texCoords) * vec4(R_ambient, 1)); +} +#endif diff --git a/res/shaders/shadowMapGenerator.glsl b/res/shaders/shadowMapGenerator.glsl new file mode 100644 index 0000000..657676d --- /dev/null +++ b/res/shaders/shadowMapGenerator.glsl @@ -0,0 +1,24 @@ +#include "common.glh" + +#if defined(VS_BUILD) +attribute vec3 position; + +uniform mat4 T_MVP; + +void main() +{ + gl_Position = T_MVP * vec4(position, 1.0); +} +#elif defined(FS_BUILD) +DeclareFragOutput(0, vec4); +void main() +{ + float depth = gl_FragCoord.z; + + float dx = dFdx(depth); + float dy = dFdy(depth); + float moment2 = depth * depth + 0.25 * (dx * dx + dy * dy); + + SetFragOutput(0, vec4(depth, moment2, 0.0, 0.0)); +} +#endif diff --git a/src/renderingEngine.cpp b/src/renderingEngine.cpp index 1f458d4..535f102 100644 --- a/src/renderingEngine.cpp +++ b/src/renderingEngine.cpp @@ -24,11 +24,11 @@ RenderingEngine::RenderingEngine(const Window& window) : m_window(&window), m_tempTarget(window.GetWidth(), window.GetHeight(), 0, GL_TEXTURE_2D, GL_NEAREST, GL_RGBA, GL_RGBA, false, GL_COLOR_ATTACHMENT0), m_planeMaterial("renderingEngine_filterPlane", m_tempTarget, 1, 8), - m_defaultShader("forward-ambient"), - m_shadowMapShader("shadowMapGenerator"), - m_nullFilter("filter-null"), - m_gausBlurFilter("filter-gausBlur7x1"), - m_fxaaFilter("filter-fxaa"), + m_defaultShader("forward-ambient", true), + m_shadowMapShader("shadowMapGenerator", true), + m_nullFilter("filter-null", true), + m_gausBlurFilter("filter-gausBlur7x1", true), + m_fxaaFilter("filter-fxaa", true), m_altCameraTransform(Vector3f(0,0,0), Quaternion(Vector3f(0,1,0),ToRadians(180.0f))), m_altCamera(Matrix4f().InitIdentity(), &m_altCameraTransform) { diff --git a/src/shader.cpp b/src/shader.cpp index a042d52..3d8d983 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -16,6 +16,7 @@ //-------------------------------------------------------------------------------- std::map Shader::s_resourceMap; int ShaderData::s_supportedOpenGLLevel = 0; +std::string ShaderData::s_glslVersion = ""; //-------------------------------------------------------------------------------- // Forward declarations @@ -32,7 +33,7 @@ static void String_ReplaceAll(std::string* replaceIn, const std::string& replace //-------------------------------------------------------------------------------- // Constructors/Destructors //-------------------------------------------------------------------------------- -ShaderData::ShaderData(const std::string& fileName) +ShaderData::ShaderData(const std::string& fileName, bool useNewShaderSystem) { m_program = glCreateProgram(); @@ -51,27 +52,68 @@ ShaderData::ShaderData(const std::string& fileName) glGetIntegerv(GL_MINOR_VERSION, &minorVersion); s_supportedOpenGLLevel = majorVersion * 100 + minorVersion * 10; + + if(s_supportedOpenGLLevel >= 330) + { + std::ostringstream convert; + convert << s_supportedOpenGLLevel; + + s_glslVersion = convert.str(); + } + else if(s_supportedOpenGLLevel >= 320) + { + s_glslVersion = "150"; + } + else if(s_supportedOpenGLLevel >= 310) + { + s_glslVersion = "140"; + } + else if(s_supportedOpenGLLevel >= 300) + { + s_glslVersion = "130"; + } + else if(s_supportedOpenGLLevel >= 210) + { + s_glslVersion = "120"; + } + else if(s_supportedOpenGLLevel >= 200) + { + s_glslVersion = "110"; + } } - std::string vertexShaderText = LoadShader(fileName + ".vs"); - std::string fragmentShaderText = LoadShader(fileName + ".fs"); + std::string vertexShaderText; + std::string fragmentShaderText; - if(s_supportedOpenGLLevel >= 320) + if(!useNewShaderSystem) { - ConvertVertexShaderToGLSL150(&vertexShaderText); - ConvertFragmentShaderToGLSL150(&fragmentShaderText); + vertexShaderText = LoadShader(fileName + ".vs"); + fragmentShaderText = LoadShader(fileName + ".fs"); + + if(s_supportedOpenGLLevel >= 320) + { + ConvertVertexShaderToGLSL150(&vertexShaderText); + ConvertFragmentShaderToGLSL150(&fragmentShaderText); + } + } + else + { + std::string shaderText = LoadShader(fileName + ".glsl"); + + vertexShaderText = "#version 150\n#define VS_BUILD\n#define GLSL_VERSION " + s_glslVersion + "\n" + shaderText; + fragmentShaderText = "#version 150\n#define FS_BUILD\n#define GLSL_VERSION " + s_glslVersion + "\n" + shaderText; } AddVertexShader(vertexShaderText); - AddFragmentShader(fragmentShaderText); - - std::string attributeKeyword = s_supportedOpenGLLevel < 320 ? "attribute" : "in"; - AddAllAttributes(vertexShaderText, attributeKeyword); - - CompileShader(); - - AddShaderUniforms(vertexShaderText); - AddShaderUniforms(fragmentShaderText); + AddFragmentShader(fragmentShaderText); + + std::string attributeKeyword = s_supportedOpenGLLevel < 320 ? "attribute" : "in"; + AddAllAttributes(vertexShaderText, attributeKeyword); + + CompileShader(); + + AddShaderUniforms(vertexShaderText); + AddShaderUniforms(fragmentShaderText); } ShaderData::~ShaderData() @@ -84,7 +126,7 @@ ShaderData::~ShaderData() glDeleteProgram(m_program); } -Shader::Shader(const std::string& fileName) +Shader::Shader(const std::string& fileName, bool useNewShaderSystem) { m_fileName = fileName; @@ -96,7 +138,7 @@ Shader::Shader(const std::string& fileName) } else { - m_shaderData = new ShaderData(fileName); + m_shaderData = new ShaderData(fileName, useNewShaderSystem); s_resourceMap.insert(std::pair(fileName, m_shaderData)); } } diff --git a/src/shader.h b/src/shader.h index 62a13d4..9d17fe4 100644 --- a/src/shader.h +++ b/src/shader.h @@ -47,7 +47,7 @@ class UniformStruct class ShaderData : public ReferenceCounter { public: - ShaderData(const std::string& fileName); + ShaderData(const std::string& fileName, bool useNewShaderSystem); virtual ~ShaderData(); inline int GetProgram() const { return m_program; } @@ -69,6 +69,7 @@ class ShaderData : public ReferenceCounter void ConvertFragmentShaderToGLSL150(std::string* shaderText); static int s_supportedOpenGLLevel; + static std::string s_glslVersion; int m_program; std::vector m_shaders; std::vector m_uniformNames; @@ -79,7 +80,7 @@ class ShaderData : public ReferenceCounter class Shader { public: - Shader(const std::string& fileName = "basicShader"); + Shader(const std::string& fileName = "basicShader", bool useNewShaderSystem = false); Shader(const Shader& other); virtual ~Shader();