From 30cb518c74e6622d2f810071a23f509049983313 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 27 Jun 2013 19:02:31 +0200 Subject: [PATCH] Added Alpha Test Former-commit-id: 59dc6ef8f1dbff49bb13cf452bf75326ad7a6257 --- include/Nazara/Renderer/Enums.hpp | 20 ++++++++------- include/Nazara/Renderer/Material.hpp | 6 +++++ src/Nazara/Renderer/GLSLShader.cpp | 1 + src/Nazara/Renderer/Material.cpp | 30 ++++++++++++++++++++++ src/Nazara/Renderer/ShaderBuilder.cpp | 37 +++++++++++++++++---------- 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 6ab59c4ad..2422b6d4f 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -150,15 +150,16 @@ enum nzShaderFlags nzShaderFlags_None = 0, nzShaderFlags_AlphaMapping = 0x001, - nzShaderFlags_Deferred = 0x002, - nzShaderFlags_DiffuseMapping = 0x004, - nzShaderFlags_EmissiveMapping = 0x008, - nzShaderFlags_FlipUVs = 0x010, - nzShaderFlags_Instancing = 0x020, - nzShaderFlags_Lighting = 0x040, - nzShaderFlags_NormalMapping = 0x080, - nzShaderFlags_ParallaxMapping = 0x100, - nzShaderFlags_SpecularMapping = 0x200 + nzShaderFlags_AlphaTest = 0x002, + nzShaderFlags_Deferred = 0x004, + nzShaderFlags_DiffuseMapping = 0x008, + nzShaderFlags_EmissiveMapping = 0x010, + nzShaderFlags_FlipUVs = 0x020, + nzShaderFlags_Instancing = 0x040, + nzShaderFlags_Lighting = 0x080, + nzShaderFlags_NormalMapping = 0x100, + nzShaderFlags_ParallaxMapping = 0x200, + nzShaderFlags_SpecularMapping = 0x400 }; enum nzShaderLanguage @@ -176,6 +177,7 @@ enum nzShaderUniform nzShaderUniform_CameraPosition, nzShaderUniform_LightCount, nzShaderUniform_MaterialAlphaMap, + nzShaderUniform_MaterialAlphaThreshold, nzShaderUniform_MaterialAmbient, nzShaderUniform_MaterialDiffuse, nzShaderUniform_MaterialDiffuseMap, diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index 7daa0ca53..d77cff43f 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -51,9 +51,11 @@ class NAZARA_API NzMaterial : public NzResource void Apply(const NzShader* shader) const; void Enable(nzRendererParameter renderParameter, bool enable); + void EnableAlphaTest(bool alphaTest); void EnableLighting(bool lighting); NzTexture* GetAlphaMap() const; + float GetAlphaThreshold() const; NzColor GetAmbientColor() const; const NzShader* GetCustomShader() const; nzRendererComparison GetDepthFunc() const; @@ -79,6 +81,7 @@ class NAZARA_API NzMaterial : public NzResource bool HasCustomShader() const; bool IsEnabled(nzRendererParameter renderParameter) const; + bool IsAlphaTestEnabled() const; bool IsLightingEnabled() const; bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); @@ -89,6 +92,7 @@ class NAZARA_API NzMaterial : public NzResource bool SetAlphaMap(const NzString& texturePath); void SetAlphaMap(NzTexture* map); + void SetAlphaThreshold(float alphaThreshold); void SetAmbientColor(const NzColor& ambient); void SetCustomShader(const NzShader* shader); void SetDepthFunc(nzRendererComparison depthFunc); @@ -138,7 +142,9 @@ class NAZARA_API NzMaterial : public NzResource NzTextureRef m_heightMap; NzTextureRef m_normalMap; NzTextureRef m_specularMap; + bool m_alphaTestEnabled; bool m_lightingEnabled; + float m_alphaThreshold; float m_shininess; static NzMaterial* s_defaultMaterial; diff --git a/src/Nazara/Renderer/GLSLShader.cpp b/src/Nazara/Renderer/GLSLShader.cpp index 990e5fdfe..5592aabe5 100644 --- a/src/Nazara/Renderer/GLSLShader.cpp +++ b/src/Nazara/Renderer/GLSLShader.cpp @@ -67,6 +67,7 @@ bool NzGLSLShader::Compile() CacheUniform(CameraPosition); CacheUniform(LightCount); CacheUniform(MaterialAlphaMap); + CacheUniform(MaterialAlphaThreshold); CacheUniform(MaterialAmbient); CacheUniform(MaterialDiffuse); CacheUniform(MaterialDiffuseMap); diff --git a/src/Nazara/Renderer/Material.cpp b/src/Nazara/Renderer/Material.cpp index 0055d2e6d..4287eefa4 100644 --- a/src/Nazara/Renderer/Material.cpp +++ b/src/Nazara/Renderer/Material.cpp @@ -42,6 +42,7 @@ NzMaterial::NzMaterial(NzMaterial&& material) void NzMaterial::Apply(const NzShader* shader) const { + int alphaThresholdLocation = shader->GetUniformLocation(nzShaderUniform_MaterialAlphaThreshold); int ambientColorLocation = shader->GetUniformLocation(nzShaderUniform_MaterialAmbient); int diffuseColorLocation = shader->GetUniformLocation(nzShaderUniform_MaterialDiffuse); int shininessLocation = shader->GetUniformLocation(nzShaderUniform_MaterialShininess); @@ -60,6 +61,9 @@ void NzMaterial::Apply(const NzShader* shader) const } } + if (alphaThresholdLocation != -1) + shader->SendFloat(alphaThresholdLocation, m_alphaThreshold); + if (ambientColorLocation != -1) shader->SendColor(ambientColorLocation, m_ambientColor); @@ -153,6 +157,15 @@ void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) m_states.parameters[renderParameter] = enable; } +void NzMaterial::EnableAlphaTest(bool alphaTest) +{ + m_alphaTestEnabled = alphaTest; + if (m_alphaTestEnabled) + m_shaderFlags |= nzShaderFlags_AlphaTest; + else + m_shaderFlags &= ~nzShaderFlags_AlphaTest; +} + void NzMaterial::EnableLighting(bool lighting) { m_lightingEnabled = lighting; @@ -167,6 +180,11 @@ NzTexture* NzMaterial::GetAlphaMap() const return m_alphaMap; } +float NzMaterial::GetAlphaThreshold() const +{ + return m_alphaThreshold; +} + NzColor NzMaterial::GetAmbientColor() const { return m_ambientColor; @@ -290,6 +308,11 @@ bool NzMaterial::IsEnabled(nzRendererParameter parameter) const return m_states.parameters[parameter]; } +bool NzMaterial::IsAlphaTestEnabled() const +{ + return m_alphaTestEnabled; +} + bool NzMaterial::IsLightingEnabled() const { return m_lightingEnabled; @@ -320,6 +343,8 @@ void NzMaterial::Reset() m_normalMap.Reset(); m_specularMap.Reset(); + m_alphaThreshold = 0.2f; + m_alphaTestEnabled = false; m_ambientColor = NzColor(128, 128, 128); m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); @@ -359,6 +384,11 @@ void NzMaterial::SetAlphaMap(NzTexture* map) m_shaderFlags &= ~nzShaderFlags_AlphaMapping; } +void NzMaterial::SetAlphaThreshold(float alphaThreshold) +{ + m_alphaThreshold = alphaThreshold; +} + void NzMaterial::SetAmbientColor(const NzColor& ambient) { m_ambientColor = ambient; diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index e381ad92a..2ba39acaf 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -77,6 +77,9 @@ namespace if (flags & nzShaderFlags_AlphaMapping) sourceCode += "uniform sampler2D MaterialAlphaMap;\n"; + if (flags & nzShaderFlags_AlphaTest) + sourceCode += "uniform float MaterialAlphaThreshold;\n"; + sourceCode += "uniform vec4 MaterialDiffuse;\n"; if (flags & nzShaderFlags_DiffuseMapping) @@ -128,6 +131,18 @@ namespace sourceCode += "void main()\n" "{\n"; + sourceCode += "float alpha = MaterialDiffuse.a"; + if (flags & nzShaderFlags_AlphaMapping) + sourceCode += '*' + textureLookupKW + "(MaterialAlphaMap, vTexCoord).r"; + + sourceCode += ";\n"; + + if (flags & nzShaderFlags_AlphaTest) + { + sourceCode += "if (alpha < MaterialAlphaThreshold)\n" + "discard;\n"; + } + if (flags & nzShaderFlags_Lighting) { sourceCode += "vec3 light = vec3(0.0, 0.0, 0.0);\n"; @@ -281,11 +296,6 @@ namespace sourceCode += ";\n"; - if (flags & nzShaderFlags_AlphaMapping) - sourceCode += "float alpha = " + textureLookupKW + "(MaterialAlphaMap, vTexCoord).r;\n"; - else - sourceCode += "float alpha = MaterialDiffuse.a;\n"; - if (flags & nzShaderFlags_EmissiveMapping) { sourceCode += "float intensity = light.r*0.3 + light.g*0.59 + light.b*0.11;\n" @@ -295,16 +305,15 @@ namespace else sourceCode += fragmentColorKW + " = vec4(lighting, alpha);\n"; } - else if (flags & nzShaderFlags_DiffuseMapping) - { - sourceCode += fragmentColorKW + " = MaterialDiffuse*"; - if (flags & nzShaderFlags_AlphaMapping) - sourceCode += "vec4(" + textureLookupKW + "(MaterialDiffuseMap, vTexCoord).rgb, " + textureLookupKW + "(MaterialAlphaMap, vTexCoord).r);\n"; - else - sourceCode += textureLookupKW + "(MaterialDiffuseMap, vTexCoord);\n"; - } else - sourceCode += fragmentColorKW + " = MaterialDiffuse;\n"; + { + sourceCode += fragmentColorKW + " = MaterialDiffuse"; + + if (flags & nzShaderFlags_DiffuseMapping) + sourceCode += "*vec4(" + textureLookupKW + "(MaterialDiffuseMap, vTexCoord).rgb, alpha);\n"; + + sourceCode += ";\n"; + } sourceCode += "}\n";