From 0207669d611d57c0c17bc2014767e2467aae5e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kapu=C5=9Bci=C5=84ski?= Date: Tue, 14 Dec 2021 21:54:19 +0100 Subject: [PATCH] Added optional triplanar mapping mode for the secondary texture --- src/graphics/core/renderers.h | 4 +++ src/graphics/engine/engine.cpp | 25 +++++++++++++++++ src/graphics/engine/engine.h | 8 ++++++ src/graphics/opengl/gl33objectrenderer.cpp | 12 +++++++++ src/graphics/opengl/gl33objectrenderer.h | 7 +++++ .../opengl/shaders/gl33/object_fs.glsl | 27 ++++++++++++++++++- .../opengl/shaders/gl33/object_vs.glsl | 5 +++- 7 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/graphics/core/renderers.h b/src/graphics/core/renderers.h index 73eac986..d4e23949 100644 --- a/src/graphics/core/renderers.h +++ b/src/graphics/core/renderers.h @@ -171,6 +171,10 @@ public: virtual void SetTransparency(TransparencyMode mode) = 0; virtual void SetPrimaryTextureEnabled(bool enabled) = 0; + //! Sets triplanar mode + virtual void SetTriplanarMode(bool enabled) = 0; + //! Sets triplanar scale + virtual void SetTriplanarScale(float scale) = 0; //! Sets amount of dirt (second texture) to apply virtual void SetDirty(float amount) = 0; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 1aedf0ff..8b86dd46 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -165,6 +165,8 @@ CEngine::CEngine(CApplication *app, CSystemUtils* systemUtils) m_render = true; m_renderInterface = true; m_screenshotMode = false; + m_triplanarMode = false; + m_triplanarScale = 0.2f; m_dirty = true; m_fog = true; m_secondTex = ""; @@ -2775,6 +2777,26 @@ int CEngine::GetMultiSample() return m_multisample; } +void CEngine::SetTriplanarMode(bool enabled) +{ + m_triplanarMode = enabled; +} + +bool CEngine::GetTriplanarMode() +{ + return m_triplanarMode; +} + +void CEngine::SetTriplanarScale(float scale) +{ + m_triplanarScale = scale; +} + +float CEngine::GetTriplanarScale() +{ + return m_triplanarScale; +} + void CEngine::SetDirty(bool mode) { m_dirty = mode; @@ -3474,6 +3496,9 @@ void CEngine::Draw3DScene() objectRenderer->SetAlphaScissor(0.0f); objectRenderer->SetShadowParams(m_shadowRegions, shadowParams); + objectRenderer->SetTriplanarMode(m_triplanarMode); + objectRenderer->SetTriplanarScale(m_triplanarScale); + bool transparent = false; for (int objRank = 0; objRank < static_cast(m_objects.size()); objRank++) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 8cea6914..ad1103a5 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -934,6 +934,12 @@ public: float GetHFovAngle(); //@} + void SetTriplanarMode(bool enabled); + bool GetTriplanarMode(); + + void SetTriplanarScale(float scale); + float GetTriplanarScale(); + //@{ //! Management of the global mode of contamination // NOTE: This is an user configuration setting @@ -1415,6 +1421,8 @@ protected: float m_tracePrecision; bool m_pauseBlurEnabled; + bool m_triplanarMode; + float m_triplanarScale; bool m_dirty; bool m_fog; float m_particleDensity; diff --git a/src/graphics/opengl/gl33objectrenderer.cpp b/src/graphics/opengl/gl33objectrenderer.cpp index 137d385f..93710a8b 100644 --- a/src/graphics/opengl/gl33objectrenderer.cpp +++ b/src/graphics/opengl/gl33objectrenderer.cpp @@ -81,6 +81,8 @@ CGL33ObjectRenderer::CGL33ObjectRenderer(CGL33Device* device) m_fogColor = glGetUniformLocation(m_program, "uni_FogColor"); m_color = glGetUniformLocation(m_program, "uni_Color"); m_primaryEnabled = glGetUniformLocation(m_program, "uni_PrimaryEnabled"); + m_triplanarMode = glGetUniformLocation(m_program, "uni_TriplanarMode"); + m_triplanarScale = glGetUniformLocation(m_program, "uni_TriplanarScale"); m_dirty = glGetUniformLocation(m_program, "uni_Dirty"); m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor"); @@ -325,6 +327,16 @@ void CGL33ObjectRenderer::SetPrimaryTextureEnabled(bool enabled) glUniform1f(m_primaryEnabled, enabled ? 1.0f : 0.0f); } +void CGL33ObjectRenderer::SetTriplanarMode(bool enabled) +{ + glUniform1i(m_triplanarMode, enabled ? 1 : 0); +} + +void CGL33ObjectRenderer::SetTriplanarScale(float scale) +{ + glUniform1f(m_triplanarScale, scale); +} + void CGL33ObjectRenderer::SetDirty(float amount) { glUniform1f(m_dirty, amount); diff --git a/src/graphics/opengl/gl33objectrenderer.h b/src/graphics/opengl/gl33objectrenderer.h index b983adb0..72e76b88 100644 --- a/src/graphics/opengl/gl33objectrenderer.h +++ b/src/graphics/opengl/gl33objectrenderer.h @@ -81,6 +81,11 @@ public: //! Sets transparency mode virtual void SetTransparency(TransparencyMode mode) override; virtual void SetPrimaryTextureEnabled(bool enabled) override; + + //! Sets triplanar mode + virtual void SetTriplanarMode(bool enabled) override; + //! Sets triplanar scale + virtual void SetTriplanarScale(float scale) override; //! Sets amount of dirt (second texture) to apply virtual void SetDirty(float amount) override; @@ -105,6 +110,8 @@ private: GLint m_fogColor = -1; GLint m_color = -1; GLint m_primaryEnabled = -1; + GLint m_triplanarMode = -1; + GLint m_triplanarScale = -1; GLint m_dirty = -1; GLint m_alphaScissor = -1; diff --git a/src/graphics/opengl/shaders/gl33/object_fs.glsl b/src/graphics/opengl/shaders/gl33/object_fs.glsl index b2b4b2a6..43bb3585 100644 --- a/src/graphics/opengl/shaders/gl33/object_fs.glsl +++ b/src/graphics/opengl/shaders/gl33/object_fs.glsl @@ -33,6 +33,8 @@ uniform sampler2D uni_SecondaryTexture; uniform vec4 uni_Color; uniform float uni_PrimaryEnabled; +uniform bool uni_TriplanarMode; +uniform float uni_TriplanarScale; uniform float uni_Dirty; uniform float uni_AlphaScissor; @@ -44,6 +46,8 @@ in VertexData vec2 TexCoord0; vec2 TexCoord1; vec3 Normal; + vec3 VertexCoord; + vec3 VertexNormal; vec3 Position; vec3 ShadowCoords[4]; } data; @@ -94,6 +98,17 @@ vec3 PBR(vec3 position, vec3 color, vec3 normal, float roughness, float metalnes return (diffuseBrdf + PI * specBrdf) * lightIntensity * uni_LightColor * NdL; } +vec3 Triplanar(vec3 position, vec3 normal) +{ + vec3 weights = normal * normal; + + vec3 sum = texture(uni_SecondaryTexture, position.yz).rgb * weights.x; + sum += texture(uni_SecondaryTexture, position.zx).rgb * weights.y; + sum += texture(uni_SecondaryTexture, position.xy).rgb * weights.z; + + return sum; +} + void main() { vec4 albedo = data.Color * uni_Color; @@ -102,7 +117,17 @@ void main() primary = mix(vec4(1.0), primary, uni_PrimaryEnabled); albedo *= primary; - vec3 dirty = texture(uni_SecondaryTexture, data.TexCoord1).rgb; + vec3 dirty = vec3(0.0); + + if (uni_TriplanarMode) + { + dirty = Triplanar(data.VertexCoord * uni_TriplanarScale, data.VertexNormal); + } + else + { + dirty = texture(uni_SecondaryTexture, data.TexCoord1).rgb; + } + dirty = mix(vec3(1.0), dirty, uni_Dirty); albedo.rgb *= dirty; diff --git a/src/graphics/opengl/shaders/gl33/object_vs.glsl b/src/graphics/opengl/shaders/gl33/object_vs.glsl index e49de0e3..dcc9db65 100644 --- a/src/graphics/opengl/shaders/gl33/object_vs.glsl +++ b/src/graphics/opengl/shaders/gl33/object_vs.glsl @@ -36,6 +36,8 @@ out VertexData vec2 TexCoord0; vec2 TexCoord1; vec3 Normal; + vec3 VertexCoord; + vec3 VertexNormal; vec3 Position; vec3 ShadowCoords[4]; } data; @@ -50,7 +52,8 @@ void main() data.TexCoord0 = in_TexCoord0; data.TexCoord1 = in_TexCoord1; data.Normal = mat3(uni_NormalMatrix) * in_Normal; - //data.Distance = abs(eyeSpace.z); + data.VertexCoord = in_VertexCoord.xyz; + data.VertexNormal = in_Normal; data.Position = position.xyz; data.ShadowCoords = ProjectShadows(position.xyz); }