From 16173207ee280f13349dffc35515cf6caee207fe Mon Sep 17 00:00:00 2001 From: Benau Date: Thu, 15 Sep 2022 08:30:24 +0800 Subject: [PATCH] Add colorization support for gles2 driver --- .../shaders/irrlicht/COGLES2FixedPipeline.fsh | 67 +++++++++++++++++-- lib/irrlicht/include/SMaterial.h | 5 ++ .../Irrlicht/COGLES2FixedPipelineRenderer.cpp | 10 +++ src/graphics/central_settings.cpp | 3 +- src/graphics/material.cpp | 2 +- 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/data/shaders/irrlicht/COGLES2FixedPipeline.fsh b/data/shaders/irrlicht/COGLES2FixedPipeline.fsh index 09285e7f4..7297ef28c 100644 --- a/data/shaders/irrlicht/COGLES2FixedPipeline.fsh +++ b/data/shaders/irrlicht/COGLES2FixedPipeline.fsh @@ -13,11 +13,14 @@ precision mediump float; #define TransparentVertexAlpha 8 #define TransparentReflection2Layer 9 #define StkGrass 10 +#define StkBlend 11 /* Uniforms */ uniform int uMaterialType; +uniform float uHueChange; + uniform bool uTextureUsage0; //uniform bool uTextureUsage1; @@ -31,14 +34,48 @@ varying vec2 varTexCoord0; varying vec4 varVertexColor; varying float varEyeDist; +vec3 rgbToHsv(vec3 c) +{ + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsvToRgb(vec3 c) +{ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + vec4 renderSolid() { - vec4 Color = varVertexColor; - + vec4 Color = vec4(1.0, 1.0, 1.0, 1.0); if(uTextureUsage0) + { Color *= texture2D(uTextureUnit0, varTexCoord0); - - //Color.a = 1.0; + if (uHueChange > 0.0) + { + float f_hue_change = 0.66; + float mask = Color.a; + vec3 old_hsv = rgbToHsv(Color.rgb); + float mask_step = step(mask, 0.5); + float saturation = mask * 1.825; + vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(uHueChange, + max(old_hsv.y, saturation)), vec2(mask_step, mask_step)); + Color.rgb = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z)); + } + Color.a = 1.0; + } + else + { + Color = varVertexColor; + Color.a = 1.0; + } return Color; } @@ -97,7 +134,16 @@ vec4 renderTransparent() vec4 Color = vec4(1.0, 1.0, 1.0, 1.0); if(uTextureUsage0) + { Color *= texture2D(uTextureUnit0, varTexCoord0); + if (uHueChange > 0.0) + { + vec3 old_hsv = rgbToHsv(Color.rgb); + vec2 new_xy = vec2(uHueChange, old_hsv.y); + vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z)); + Color.rgb = vec3(new_color.r, new_color.g, new_color.b); + } + } return Color; } @@ -107,7 +153,16 @@ vec4 renderTransparentVertexColor() vec4 Color = varVertexColor; if(uTextureUsage0) + { Color *= texture2D(uTextureUnit0, varTexCoord0); + if (uHueChange > 0.0) + { + vec3 old_hsv = rgbToHsv(Color.rgb); + vec2 new_xy = vec2(uHueChange, old_hsv.y); + vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z)); + Color.rgb = vec3(new_color.r, new_color.g, new_color.b); + } + } return Color; } @@ -142,6 +197,10 @@ void main () discard; gl_FragColor = Color; } + else if(uMaterialType == StkBlend) + { + gl_FragColor = renderTransparentVertexColor(); + } else if(uMaterialType == TransparentVertexAlpha) { vec4 Color = renderTransparent(); diff --git a/lib/irrlicht/include/SMaterial.h b/lib/irrlicht/include/SMaterial.h index 5d79c204f..1510e9414 100644 --- a/lib/irrlicht/include/SMaterial.h +++ b/lib/irrlicht/include/SMaterial.h @@ -465,6 +465,11 @@ namespace video return m_render_info; } + const std::shared_ptr& getRenderInfo() const + { + return m_render_info; + } + void setRenderInfo(std::shared_ptr ri) { m_render_info = ri; diff --git a/lib/irrlicht/source/Irrlicht/COGLES2FixedPipelineRenderer.cpp b/lib/irrlicht/source/Irrlicht/COGLES2FixedPipelineRenderer.cpp index f7ea1a212..5b3cfacfd 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2FixedPipelineRenderer.cpp +++ b/lib/irrlicht/source/Irrlicht/COGLES2FixedPipelineRenderer.cpp @@ -14,6 +14,8 @@ #include "os.h" #include "COGLES2Driver.h" +#include "ge_render_info.hpp" + namespace irr { namespace video @@ -132,10 +134,18 @@ bool COGLES2FixedPipelineRenderer::OnRender(IMaterialRendererServices* service, case EMT_STK_GRASS: materialType = 10; break; + case EMT_ONETEXTURE_BLEND: + materialType = 11; + break; default: break; } + float hue_change = 0.0f; + if (Driver->getCurrentMaterial().getRenderInfo()) + hue_change = Driver->getCurrentMaterial().getRenderInfo()->getHue(); + IMaterialRendererServices::setPixelShaderConstant("uHueChange", &hue_change, 1); + IMaterialRendererServices::setPixelShaderConstant("uMaterialType", &materialType, 1); /* Transform Matrices Upload */ diff --git a/src/graphics/central_settings.cpp b/src/graphics/central_settings.cpp index 7f9268d2b..5e353fa87 100644 --- a/src/graphics/central_settings.cpp +++ b/src/graphics/central_settings.cpp @@ -502,7 +502,8 @@ bool CentralVideoSettings::isARBTextureBufferObjectUsable() const bool CentralVideoSettings::supportsColorization() const { - return isGLSL() || GE::getDriver()->getDriverType() == video::EDT_VULKAN; + return isGLSL() || GE::getDriver()->getDriverType() == video::EDT_VULKAN || + GE::getDriver()->getDriverType() == video::EDT_OGLES2; } #endif // !SERVER_ONLY diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 364b87a2a..a0ae72c63 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -970,7 +970,7 @@ std::function Material::getMaskImageMani() const ->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE"); // Material using alpha channel will be colorized as a whole - if (irr_driver->getVideoDriver()->getDriverType() == EDT_VULKAN && + if (CVS->supportsColorization() && !useAlphaChannel() && (!m_colorization_mask.empty() || m_colorization_factor > 0.0f || m_colorizable)) {