mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 07:12:36 +00:00
- added a few more texture coloring options to the shader.
Aside from adding an additive component it can now also do: - desaturation (not limited to the range of 0..1 so it can also be used for oversaturation by applying a negative number or negative saturation by going above 1.0. - invert the texture - apply a blend, including 3 special mode taken from EDuke32. Currently only the implementation is done, it is not exposed to UDMF yet.
This commit is contained in:
parent
41a9496bef
commit
3209d4ed23
7 changed files with 142 additions and 6 deletions
|
@ -138,6 +138,11 @@ bool FGLRenderState::ApplyShader()
|
||||||
activeShader->muClipSplit.Set(mClipSplit);
|
activeShader->muClipSplit.Set(mClipSplit);
|
||||||
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
||||||
activeShader->muAddColor.Set(mStreamData.uAddColor);
|
activeShader->muAddColor.Set(mStreamData.uAddColor);
|
||||||
|
activeShader->muBlendColor.Set(mStreamData.uBlendColor);
|
||||||
|
activeShader->muObjectBlendMode.Set(mStreamData.uObjectBlendMode);
|
||||||
|
activeShader->muObjectColorizeFactor.Set(mStreamData.uObjectColorizeFactor);
|
||||||
|
activeShader->muObjectDesaturationFactor.Set(mStreamData.uObjectDesaturationFactor);
|
||||||
|
activeShader->muObjectInvertColor.Set(mStreamData.uObjectInvertColor);
|
||||||
|
|
||||||
if (mGlowEnabled || activeShader->currentglowstate)
|
if (mGlowEnabled || activeShader->currentglowstate)
|
||||||
{
|
{
|
||||||
|
|
|
@ -242,10 +242,17 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
i_data += "uniform vec4 uObjectColor2;\n";
|
i_data += "uniform vec4 uObjectColor2;\n";
|
||||||
i_data += "uniform vec4 uDynLightColor;\n";
|
i_data += "uniform vec4 uDynLightColor;\n";
|
||||||
i_data += "uniform vec4 uAddColor;\n";
|
i_data += "uniform vec4 uAddColor;\n";
|
||||||
|
i_data += "uniform vec4 uBlendColor;\n";
|
||||||
i_data += "uniform vec4 uFogColor;\n";
|
i_data += "uniform vec4 uFogColor;\n";
|
||||||
i_data += "uniform float uDesaturationFactor;\n";
|
i_data += "uniform float uDesaturationFactor;\n";
|
||||||
i_data += "uniform float uInterpolationFactor;\n";
|
i_data += "uniform float uInterpolationFactor;\n";
|
||||||
|
|
||||||
|
i_data += "uniform float uObjectDesaturationFactor;\n";
|
||||||
|
i_data += "uniform float uObjectColorizeFactor;\n";
|
||||||
|
i_data += "uniform int uObjectBlendMode;\n";
|
||||||
|
i_data += "uniform int uObjectInvertColor;\n";
|
||||||
|
|
||||||
|
|
||||||
// Glowing walls stuff
|
// Glowing walls stuff
|
||||||
i_data += "uniform vec4 uGlowTopPlane;\n";
|
i_data += "uniform vec4 uGlowTopPlane;\n";
|
||||||
i_data += "uniform vec4 uGlowTopColor;\n";
|
i_data += "uniform vec4 uGlowTopColor;\n";
|
||||||
|
@ -536,6 +543,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
|
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
|
||||||
muSpecularMaterial.Init(hShader, "uSpecularMaterial");
|
muSpecularMaterial.Init(hShader, "uSpecularMaterial");
|
||||||
muAddColor.Init(hShader, "uAddColor");
|
muAddColor.Init(hShader, "uAddColor");
|
||||||
|
muBlendColor.Init(hShader, "uBlendColor");
|
||||||
|
muObjectDesaturationFactor.Init(hShader, "uObjectDesaturationFactor");
|
||||||
|
muObjectColorizeFactor.Init(hShader, "uObjectColorizeFactor");
|
||||||
|
muObjectBlendMode.Init(hShader, "uObjectBlendMode");
|
||||||
|
muObjectInvertColor.Init(hShader, "uObjectInvertColor");
|
||||||
muTimer.Init(hShader, "timer");
|
muTimer.Init(hShader, "timer");
|
||||||
|
|
||||||
lights_index = glGetUniformLocation(hShader, "lights");
|
lights_index = glGetUniformLocation(hShader, "lights");
|
||||||
|
|
|
@ -246,6 +246,7 @@ class FShader
|
||||||
FBufferedUniformPE muObjectColor;
|
FBufferedUniformPE muObjectColor;
|
||||||
FBufferedUniformPE muObjectColor2;
|
FBufferedUniformPE muObjectColor2;
|
||||||
FBufferedUniformPE muAddColor;
|
FBufferedUniformPE muAddColor;
|
||||||
|
FBufferedUniformPE muBlendColor;
|
||||||
FUniform4f muGlowBottomColor;
|
FUniform4f muGlowBottomColor;
|
||||||
FUniform4f muGlowTopColor;
|
FUniform4f muGlowTopColor;
|
||||||
FUniform4f muGlowBottomPlane;
|
FUniform4f muGlowBottomPlane;
|
||||||
|
@ -259,6 +260,11 @@ class FShader
|
||||||
FBufferedUniform2f muSpecularMaterial;
|
FBufferedUniform2f muSpecularMaterial;
|
||||||
FBufferedUniform1f muTimer;
|
FBufferedUniform1f muTimer;
|
||||||
|
|
||||||
|
FBufferedUniform1f muObjectDesaturationFactor;
|
||||||
|
FBufferedUniform1f muObjectColorizeFactor;
|
||||||
|
FBufferedUniform1i muObjectBlendMode;
|
||||||
|
FBufferedUniform1i muObjectInvertColor;
|
||||||
|
|
||||||
int lights_index;
|
int lights_index;
|
||||||
int modelmatrix_index;
|
int modelmatrix_index;
|
||||||
int normalmodelmatrix_index;
|
int normalmodelmatrix_index;
|
||||||
|
|
|
@ -158,11 +158,16 @@ struct StreamData
|
||||||
FVector4PalEntry uObjectColor2;
|
FVector4PalEntry uObjectColor2;
|
||||||
FVector4 uDynLightColor;
|
FVector4 uDynLightColor;
|
||||||
FVector4PalEntry uAddColor;
|
FVector4PalEntry uAddColor;
|
||||||
|
FVector4PalEntry uBlendColor;
|
||||||
FVector4PalEntry uFogColor;
|
FVector4PalEntry uFogColor;
|
||||||
float uDesaturationFactor;
|
float uDesaturationFactor;
|
||||||
float uInterpolationFactor;
|
float uInterpolationFactor;
|
||||||
float timer;
|
float timer;
|
||||||
int useVertexData;
|
int useVertexData;
|
||||||
|
float uObjectDesaturationFactor;
|
||||||
|
float uObjectColorizeFactor;
|
||||||
|
int uObjectBlendMode;
|
||||||
|
int uObjectInvertColor;
|
||||||
FVector4 uVertexColor;
|
FVector4 uVertexColor;
|
||||||
FVector4 uVertexNormal;
|
FVector4 uVertexNormal;
|
||||||
|
|
||||||
|
@ -236,6 +241,11 @@ public:
|
||||||
mStreamData.uAddColor = 0;
|
mStreamData.uAddColor = 0;
|
||||||
mStreamData.uObjectColor = 0xffffffff;
|
mStreamData.uObjectColor = 0xffffffff;
|
||||||
mStreamData.uObjectColor2 = 0;
|
mStreamData.uObjectColor2 = 0;
|
||||||
|
mStreamData.uBlendColor = 0;
|
||||||
|
mStreamData.uObjectDesaturationFactor = 0;
|
||||||
|
mStreamData.uObjectBlendMode = 0;
|
||||||
|
mStreamData.uObjectColorizeFactor = 1;
|
||||||
|
mStreamData.uObjectInvertColor = 0;
|
||||||
mSoftLight = 0;
|
mSoftLight = 0;
|
||||||
mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f;
|
mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f;
|
||||||
mLightParms[3] = -1.f;
|
mLightParms[3] = -1.f;
|
||||||
|
@ -445,6 +455,31 @@ public:
|
||||||
mStreamData.uAddColor = pe;
|
mStreamData.uAddColor = pe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetBlendColor(PalEntry pe)
|
||||||
|
{
|
||||||
|
mStreamData.uBlendColor = pe;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetColorizeFactor(float f)
|
||||||
|
{
|
||||||
|
mStreamData.uObjectColorizeFactor = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetObjectDesaturateFactor(float f)
|
||||||
|
{
|
||||||
|
mStreamData.uObjectDesaturationFactor = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetObjectInvert(bool on)
|
||||||
|
{
|
||||||
|
mStreamData.uObjectInvertColor = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetObjectBlendMode(int b)
|
||||||
|
{
|
||||||
|
mStreamData.uObjectBlendMode = b;
|
||||||
|
}
|
||||||
|
|
||||||
void SetFog(PalEntry c, float d)
|
void SetFog(PalEntry c, float d)
|
||||||
{
|
{
|
||||||
const float LOG2E = 1.442692f; // = 1/log(2)
|
const float LOG2E = 1.442692f; // = 1/log(2)
|
||||||
|
|
|
@ -175,6 +175,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
state.SetObjectColor(color1);
|
state.SetObjectColor(color1);
|
||||||
state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0));
|
state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0));
|
||||||
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
|
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
|
||||||
|
|
||||||
if (color1 != color2)
|
if (color1 != color2)
|
||||||
{
|
{
|
||||||
// Do gradient setup only if there actually is a gradient.
|
// Do gradient setup only if there actually is a gradient.
|
||||||
|
@ -243,6 +244,9 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
state.SetTextureMode(tmode);
|
state.SetTextureMode(tmode);
|
||||||
state.EnableGlow(false);
|
state.EnableGlow(false);
|
||||||
state.EnableGradient(false);
|
state.EnableGradient(false);
|
||||||
|
state.SetObjectDesaturateFactor(0);
|
||||||
|
state.SetObjectInvert(false);
|
||||||
|
state.SetObjectBlendMode(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -118,11 +118,16 @@ static const char *shaderBindings = R"(
|
||||||
vec4 uObjectColor2;
|
vec4 uObjectColor2;
|
||||||
vec4 uDynLightColor;
|
vec4 uDynLightColor;
|
||||||
vec4 uAddColor;
|
vec4 uAddColor;
|
||||||
|
vec4 uBlendColor;
|
||||||
vec4 uFogColor;
|
vec4 uFogColor;
|
||||||
float uDesaturationFactor;
|
float uDesaturationFactor;
|
||||||
float uInterpolationFactor;
|
float uInterpolationFactor;
|
||||||
float timer; // timer data for material shaders
|
float timer; // timer data for material shaders
|
||||||
int useVertexData;
|
int useVertexData;
|
||||||
|
float uObjectDesaturationFactor;
|
||||||
|
float uObjectColorizeFactor;
|
||||||
|
int uObjectBlendMode;
|
||||||
|
int uObjectInvertColor;
|
||||||
vec4 uVertexColor;
|
vec4 uVertexColor;
|
||||||
vec4 uVertexNormal;
|
vec4 uVertexNormal;
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,12 @@ float grayscale(vec4 color)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
vec4 desaturate(vec4 texel)
|
vec4 dodesaturate(vec4 texel, float factor)
|
||||||
{
|
{
|
||||||
if (uDesaturationFactor > 0.0)
|
if (factor != 0.0)
|
||||||
{
|
{
|
||||||
float gray = grayscale(texel);
|
float gray = grayscale(texel);
|
||||||
return mix (texel, vec4(gray,gray,gray,texel.a), uDesaturationFactor);
|
return mix (texel, vec4(gray,gray,gray,texel.a), factor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -67,6 +67,28 @@ vec4 desaturate(vec4 texel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Desaturate a color
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
vec4 desaturate(vec4 texel)
|
||||||
|
{
|
||||||
|
return dodesaturate(texel, uDesaturationFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Texture tinting code originally from JFDuke.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
const int Tex_Blend_Alpha = 1;
|
||||||
|
const int Tex_Blend_Screen = 2;
|
||||||
|
const int Tex_Blend_Overlay = 3;
|
||||||
|
const int Tex_Blend_Hardlight = 4;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// This function is common for all (non-special-effect) fragment shaders
|
// This function is common for all (non-special-effect) fragment shaders
|
||||||
|
@ -116,11 +138,58 @@ vec4 getTexel(vec2 st)
|
||||||
return texel;
|
return texel;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 1: desaturate according to the material's desaturation factor.
|
||||||
|
texel = dodesaturate(texel, uObjectDesaturationFactor);
|
||||||
|
|
||||||
|
// Step 2: Invert if requested
|
||||||
|
if (uObjectInvertColor != 0)
|
||||||
|
{
|
||||||
|
texel.rgb = vec3(1.0 - texel.r, 1.0 - texel.g, 1.0 - texel.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Apply additive color
|
||||||
texel.rgb += uAddColor.rgb;
|
texel.rgb += uAddColor.rgb;
|
||||||
|
|
||||||
|
// Step 4: Colorization, including gradient if set.
|
||||||
|
if (uObjectColor2.a == 0.0)
|
||||||
|
texel.rgb = clamp(texel.rgb * uObjectColor.rgb * uObjectColorizeFactor, 0.0, 1.0);
|
||||||
|
else
|
||||||
|
texel.rgb *= clamp(texel.rgb * mix(uObjectColor.rgb, uObjectColor2.rgb, gradientdist.z) * uObjectColorizeFactor, 0.0, 1.0);
|
||||||
|
texel.a *= uObjectColor.a; // note that the ObjectColor can have an alpha component.
|
||||||
|
|
||||||
|
// Step 5: Apply a blend. This may just be a translucent overlay or one of the blend modes present in current Build engines.
|
||||||
|
if (uObjectBlendMode != 0)
|
||||||
|
{
|
||||||
|
vec3 tcol = texel.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math.
|
||||||
|
vec4 tint = uBlendColor * 255.0;
|
||||||
|
|
||||||
if (uObjectColor2.a == 0.0) texel *= uObjectColor;
|
switch (uObjectBlendMode)
|
||||||
else texel *= mix(uObjectColor, uObjectColor2, gradientdist.z);
|
{
|
||||||
|
default:
|
||||||
|
tcol.b = tcol.b * (1.0 - uBlendColor.a) + tint.b * uBlendColor.a;
|
||||||
|
tcol.g = tcol.g * (1.0 - uBlendColor.a) + tint.g * uBlendColor.a;
|
||||||
|
tcol.r = tcol.r * (1.0 - uBlendColor.a) + tint.r * uBlendColor.a;
|
||||||
|
break;
|
||||||
|
// The following 3 are taken 1:1 from the Build engine
|
||||||
|
case Tex_Blend_Screen:
|
||||||
|
tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 256.0);
|
||||||
|
tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 256.0);
|
||||||
|
tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 256.0);
|
||||||
|
break;
|
||||||
|
case Tex_Blend_Overlay:
|
||||||
|
tcol.b = tcol.b < 128.0? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0);
|
||||||
|
tcol.g = tcol.g < 128.0? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0);
|
||||||
|
tcol.r = tcol.r < 128.0? (tcol.r * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.r)) / 128.0);
|
||||||
|
break;
|
||||||
|
case Tex_Blend_Hardlight:
|
||||||
|
tcol.b = tint.b < 128.0 ? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0);
|
||||||
|
tcol.g = tint.g < 128.0 ? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0);
|
||||||
|
tcol.r = tint.r < 128.0 ? (tcol.r * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.r)) / 128.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
texel.rgb = tcol / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
return desaturate(texel);
|
return desaturate(texel);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue