Skip to content

Commit

Permalink
Merge pull request #17 from Ancientkingg/1.21.3
Browse files Browse the repository at this point in the history
Update fancyPants to 1.21.3
  • Loading branch information
Ancientkingg authored Nov 18, 2024
2 parents 1408e44 + 2745b63 commit de0b74f
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 147 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# <u>Fancy Pants</u>

Fancy Pants is a 1.17 vanilla core shader that allows datapack developers to add custom armor to the game with custom coloured leather armor.
Fancy Pants is a 1.21.3 (For 1.17 please see older commits) vanilla core shader that allows datapack developers to add custom armor to the game with custom coloured leather armor.

If you want a more optimized version of fancy pants that supports far more armor textures use [lessfancypants](https://github.com/Godlander/lessfancypants).
<br>*Disclaimer: It does not support custom assignable colors and it does not support automatically animating armor.*
Expand Down
164 changes: 51 additions & 113 deletions assets/minecraft/shaders/core/rendertype_armor_cutout_no_cull.fsh
Original file line number Diff line number Diff line change
@@ -1,140 +1,78 @@
#version 150

#moj_import <fog.glsl>
#moj_import <light.glsl>

#define TEX_RES 16
#define ANIM_SPEED 50 // Runs every 24 seconds
#define IS_LEATHER_LAYER texelFetch(Sampler0, ivec2(0, 1), 0) == vec4(1) // If it's leather_layer_X.png texture
#moj_import <minecraft:fog.glsl>

uniform sampler2D Sampler0;

uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
uniform float GameTime;
uniform vec3 Light0_Direction;
uniform vec3 Light1_Direction;

in float vertexDistance;
in vec4 vertexColor;
in vec4 lightMapColor;
in vec4 overlayColor;
in vec2 texCoord0;
in vec2 texCoord1;
in vec4 normal;
flat in vec4 tint;
flat in vec3 vNormal;
flat in vec4 texel;

flat in float isLeatherLayer;
flat in float interpolClock;
flat in float h_offset;
flat in float emissivity;
flat in float isFirstArmor;

in vec2 nextFrameCoords;

out vec4 fragColor;

void main()
{
ivec2 atlasSize = textureSize(Sampler0, 0);
float armorAmount = atlasSize.x / (TEX_RES * 4.0);
float maxFrames = atlasSize.y / (TEX_RES * 2.0);

vec2 coords = texCoord0;
coords.x /= armorAmount;
coords.y /= maxFrames;

vec4 color;

if(IS_LEATHER_LAYER)
{
// Texture properties contains extra info about the armor texture, such as to enable shading
vec4 textureProperties = vec4(0);
vec4 customColor = vec4(0);

float h_offset = 1.0 / armorAmount;
vec2 nextFrame = vec2(0);
float interpolClock = 0;
vec4 vtc = vertexColor;

for (int i = 1; i < (armorAmount + 1); i++)
{
customColor = texelFetch(Sampler0, ivec2(TEX_RES * 4 * i + 0.5, 0), 0);
if (tint == customColor){

coords.x += (h_offset * i);
vec4 animInfo = texelFetch(Sampler0, ivec2(TEX_RES * 4 * i + 1.5, 0), 0);
animInfo.rgb *= animInfo.a * 255;
textureProperties = texelFetch(Sampler0, ivec2(TEX_RES * 4 * i + 2.5, 0), 0);
textureProperties.rgb *= textureProperties.a * 255;
if (animInfo != vec4(0))
{
// oh god it's animated
// animInfo = amount of frames, speed, interpolation (1||0)
// textureProperties = emissive, tint
// fract(GameTime * 1200) blinks every second so [0,1] every second
float timer = floor(mod(GameTime * ANIM_SPEED * animInfo.g, animInfo.r));
if (animInfo.b > 0)
interpolClock = fract(GameTime * ANIM_SPEED * animInfo.g);
float v_offset = (TEX_RES * 2.0) / atlasSize.y * timer;
nextFrame = coords;
coords.y += v_offset;
nextFrame.y += (TEX_RES * 2.0) / atlasSize.y * mod(timer + 1, animInfo.r);
}
break;
}
}
#define rougheq(a, b) (abs(a - b) < 0.1)

if (textureProperties.g == 1)
{
if (textureProperties.r > 1)
{
vtc = tint;
}
else if (textureProperties.r == 1)
{
if (texture(Sampler0, vec2(coords.x + h_offset, coords.y)).a != 0)
{
vtc = tint * texture(Sampler0, vec2(coords.x + h_offset, coords.y)).a;
}
}
void main() {
vec4 color = texture(Sampler0, texCoord0);

vec4 vertColor = vertexColor;

if (isLeatherLayer > 0.5) {

vec4 armor = mix(texture(Sampler0, texCoord0), texture(Sampler0, nextFrameCoords), interpolClock);

#ifdef ALPHA_CUTOUT
if (armor.a < ALPHA_CUTOUT) {
discard;
}
else if(textureProperties.g == 0)
{
if (textureProperties.r > 1)
{
vtc = vec4(1);
}
else if (textureProperties.r == 1)
{
if (texture(Sampler0, vec2(coords.x + h_offset, coords.y)).a != 0)
{
vtc = vec4(1) * texture(Sampler0, vec2(coords.x + h_offset, coords.y)).a;
}
else
{
vtc = minecraft_mix_light(Light0_Direction, Light1_Direction, vNormal, vec4(1)) * texel;
}
#endif

// If it's the first leather armor texture in the atlas (used for the vanilla leather texture, with no custom color specified)
if (isFirstArmor > 0.5) {
color = armor * vertColor * ColorModulator * lightMapColor;
} else { // If it's a custom armor texture (the actual item being leather)
bool isPartiallyEmissive = rougheq(emissivity, 1.0);
bool isEmissive = emissivity > 0.0;
float controlOpacity = texture(Sampler0, vec2(texCoord0.x + h_offset, texCoord0.y)).a;

if (!isEmissive) {
vertColor *= lightMapColor;
}
else
{
vtc = minecraft_mix_light(Light0_Direction, Light1_Direction, vNormal, vec4(1)) * texel;

if (isPartiallyEmissive) {
vertColor *= controlOpacity;
}

color = armor * vertColor * ColorModulator;
}
else
{
vtc = minecraft_mix_light(Light0_Direction, Light1_Direction, vNormal, vec4(1)) * texel;
} else {
#ifdef ALPHA_CUTOUT
if (color.a < ALPHA_CUTOUT) {
discard;
}
#endif

vec4 armor = mix(texture(Sampler0, coords), texture(Sampler0, nextFrame), interpolClock);
color *= vertColor * ColorModulator * lightMapColor;

// If it's the first leather texture in the atlas (used for the vanilla leather texture, with no custom color specified)
if (coords.x < (1 / armorAmount))
color = armor * vertexColor * ColorModulator;
else // If it's a custom texture
color = armor * vtc * ColorModulator;
#ifndef EMISSIVE
color *= lightMapColor;
#endif
}
else // If it's another vanilla armor, for example diamond_layer_1.png or diamond_layer_2.png
{
color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator;
}

if (color.a < 0.1)
discard;

fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}
}
24 changes: 10 additions & 14 deletions assets/minecraft/shaders/core/rendertype_armor_cutout_no_cull.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
{
"blend": {
"func": "add",
"srcrgb": "srcalpha",
"dstrgb": "1-srcalpha"
"vertex": "minecraft:core/rendertype_armor_cutout_no_cull",
"fragment": "minecraft:core/rendertype_armor_cutout_no_cull",
"defines": {
"values": {
"ALPHA_CUTOUT": "0.1"
},
"flags": [
"NO_OVERLAY"
]
},
"vertex": "rendertype_armor_cutout_no_cull",
"fragment": "rendertype_armor_cutout_no_cull",
"attributes": [
"Position",
"Color",
"UV0",
"UV1",
"UV2",
"Normal"
],
"samplers": [
{ "name": "Sampler0" },
{ "name": "Sampler2" }
Expand All @@ -27,6 +22,7 @@
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] },
{ "name": "GameTime", "type": "float", "count": 1, "values": [ 1.0 ] }
]
}
120 changes: 106 additions & 14 deletions assets/minecraft/shaders/core/rendertype_armor_cutout_no_cull.vsh
Original file line number Diff line number Diff line change
@@ -1,40 +1,132 @@
#version 150

#moj_import <light.glsl>
#moj_import <minecraft:light.glsl>
#moj_import <minecraft:fog.glsl>

in vec3 Position;
in vec4 Color;
in vec2 UV0;
in vec2 UV1;
in ivec2 UV1;
in ivec2 UV2;
in vec3 Normal;

uniform sampler2D Sampler0;
uniform sampler2D Sampler1;
uniform sampler2D Sampler2;

uniform mat4 ModelViewMat;
uniform mat4 ProjMat;
uniform mat4 TextureMat;
uniform int FogShape;

uniform vec3 Light0_Direction;
uniform vec3 Light1_Direction;

uniform float GameTime;

out float vertexDistance;
out vec4 vertexColor;
out vec4 lightMapColor;
out vec4 overlayColor;
out vec2 texCoord0;
out vec2 texCoord1;
out vec4 normal;
flat out vec4 tint;
flat out vec3 vNormal;
flat out vec4 texel;

flat out float isLeatherLayer;
flat out float interpolClock;
flat out float h_offset;
flat out float emissivity;
flat out float isFirstArmor;

out vec2 nextFrameCoords;

#define TEX_RES 16
#define ANIM_SPEED 50 // Runs every 24 seconds
#define IS_LEATHER_LAYER texelFetch(Sampler0, ivec2(0.0, 1.0), 0) == vec4(1.0) // If it's leather_layer_X.png texture

#define fetchTextureInfo(base, pixel) texelFetch(Sampler0, ivec2(TEX_RES * 4.0 * base + 0.5 + pixel, 0), 0)

void main() {
vNormal = Normal;
texel = texelFetch(Sampler2, UV2 / 16, 0);
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);

vertexDistance = length((ModelViewMat * vec4(Position, 1.0)).xyz);
vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color) * texelFetch(Sampler2, UV2 / 16, 0);
tint = Color;
vertexDistance = fog_distance(Position, FogShape);
vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color);
lightMapColor = texelFetch(Sampler2, UV2 / 16, 0);
overlayColor = texelFetch(Sampler1, UV1, 0);

texCoord0 = UV0;
texCoord1 = UV1;
normal = ProjMat * ModelViewMat * vec4(Normal, 0.0);

ivec2 atlasSize = textureSize(Sampler0, 0);
float armorAmount = atlasSize.x / (TEX_RES * 4.0);
float maxFrames = atlasSize.y / (TEX_RES * 2.0);

texCoord0.x /= armorAmount;
texCoord0.y /= maxFrames;

vec4 color;
vec4 tint = Color;

nextFrameCoords = UV0;
interpolClock = 0.0;
h_offset = 1.0 / armorAmount;
emissivity = 0.0;

// If it's a leather armor
isLeatherLayer = float(IS_LEATHER_LAYER);

if (isLeatherLayer > 0.5) {
// Texture properties contains extra info about the armor texture, such as to enable shading
vec4 textureProperties = vec4(0.0);

// Custom color is the color of the armor
vec4 colorMatch = vec4(0.0);

// Loop through all armors in the texture atlas
for (int i = 1; i < (armorAmount + 1); i++) {
// Check if the current armor is the one we're looking for
colorMatch = fetchTextureInfo(i, 0.0); // ~(0,0)
if (tint == colorMatch) {
texCoord0.x += (h_offset * i);

vec4 animInfo = fetchTextureInfo(i, 1.0); // ~(1,0)
animInfo.rgb *= animInfo.a * 255.0;

textureProperties = fetchTextureInfo(i, 2.0); // ~(2,0)
textureProperties.rgb *= textureProperties.a * 255.0;

// If the armor is animated
if (animInfo != vec4(0)) {
// oh god it's animated
// animInfo = rgb(amount of frames, speed, interpolation [1 or 0] )
// textureProperties = rgb(emissive, tint, N/A)
// fract(GameTime * 1200) blinks every second so [0,1] spans every second.
float timer = floor(mod(GameTime * ANIM_SPEED * animInfo.g, animInfo.r));

// If the animation is interpolated
interpolClock = fract(GameTime * ANIM_SPEED * animInfo.g) * ceil(animInfo.b);

float v_offset = (TEX_RES * 2.0) / atlasSize.y * timer;
nextFrameCoords = texCoord0;
texCoord0.y += v_offset;
nextFrameCoords.y += (TEX_RES * 2.0) / atlasSize.y * mod(timer + 1, animInfo.r);
}
break;
}
}

bool isTinted = textureProperties.g > 0;
bool isEmissive = textureProperties.r > 0;

isFirstArmor = float(texCoord0.x < (1 / armorAmount));
emissivity = textureProperties.r;

// If the armor is supposed to be the normal leather armor, return early and don't modify vertexColor.
if (isFirstArmor > 0.5) return;

if (isTinted && isEmissive) { // If the armor is tinted and emissive
vertexColor = tint;
} else if (isEmissive) { // If the armor is not tinted but is emissive
vertexColor = vec4(1.0);
} else if (!isTinted) { // If the armor is not tinted and not emissive
vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, vec4(1.0));
}
}
}
Loading

0 comments on commit de0b74f

Please sign in to comment.