#include "shaders/scene/desaturate.glsl" vec4 ApplyTextureManipulation(vec4 texel, int blendflags); // Samples from the base texture according to gzdoom's texture mode. // In good gzdoom tradition it also does all kinds of unrelated garbage. vec4 getTexel(vec2 st) { vec4 texel = texture(tex, st); // Apply texture modes #if defined(TM_STENCIL) texel.rgb = vec3(1.0,1.0,1.0); #elif defined(TM_OPAQUE) texel.a = 1.0; #elif defined(TM_INVERSE) texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); #elif defined(TM_ALPHATEXTURE) float gray = grayscale(texel); texel = vec4(1.0, 1.0, 1.0, gray*texel.a); #elif defined(TM_CLAMPY) if (st.t < 0.0 || st.t > 1.0) { texel.a = 0.0; } #elif defined(TM_INVERTOPAQUE) texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, 1.0); #elif defined(TM_FOGLAYER) return texel; #endif #if defined(TEXF_ClampY) if (st.t < 0.0 || st.t > 1.0) { texel.a = 0.0; } #endif // Apply the texture modification colors. int blendflags = int(uTextureAddColor.a); // this alpha is unused otherwise if (blendflags != 0) { // only apply the texture manipulation if it contains something. texel = ApplyTextureManipulation(texel, blendflags); } // Apply the Doom64 style material colors on top of everything from the texture modification settings. // This may be a bit redundant in terms of features but the data comes from different sources so this is unavoidable. texel.rgb += uAddColor.rgb; if (uObjectColor2.a == 0.0) texel *= uObjectColor; else texel *= mix(uObjectColor, uObjectColor2, gradientdist.z); // Last but not least apply the desaturation from the sector's light. return desaturate(texel); } const int Tex_Blend_Alpha = 1; const int Tex_Blend_Screen = 2; const int Tex_Blend_Overlay = 3; const int Tex_Blend_Hardlight = 4; // Texture tinting code originally from JFDuke but with a few more options vec4 ApplyTextureManipulation(vec4 texel, int blendflags) { // Step 1: desaturate according to the material's desaturation factor. texel = dodesaturate(texel, uTextureModulateColor.a); // Step 2: Invert if requested if ((blendflags & 8) != 0) { texel.rgb = vec3(1.0 - texel.r, 1.0 - texel.g, 1.0 - texel.b); } // Step 3: Apply additive color texel.rgb += uTextureAddColor.rgb; // Step 4: Colorization, including gradient if set. texel.rgb *= uTextureModulateColor.rgb; // Before applying the blend the value needs to be clamped to [0..1] range. texel.rgb = clamp(texel.rgb, 0.0, 1.0); // Step 5: Apply a blend. This may just be a translucent overlay or one of the blend modes present in current Build engines. if ((blendflags & 7) != 0) { vec3 tcol = texel.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math. vec4 tint = uTextureBlendColor * 255.0; switch (blendflags & 7) { default: tcol.b = tcol.b * (1.0 - uTextureBlendColor.a) + tint.b * uTextureBlendColor.a; tcol.g = tcol.g * (1.0 - uTextureBlendColor.a) + tint.g * uTextureBlendColor.a; tcol.r = tcol.r * (1.0 - uTextureBlendColor.a) + tint.r * uTextureBlendColor.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 texel; }