Skip to content

Commit 6a4d0af

Browse files
committed
New Terastalization effect.
1 parent 6ec70b8 commit 6a4d0af

2 files changed

Lines changed: 78 additions & 49 deletions

File tree

src/main/resources/shaders/experimental/animated.fs.glsl

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
in vec2 texCoord0;
44
in vec4 vertexColor;
55
in float vertexDistance;
6-
in vec3 fragNormal;
7-
in vec3 fragTangent;
8-
in vec3 fragBitangent;
6+
flat in vec3 fragNormal;
7+
flat in vec3 fragTangent;
8+
flat in vec3 fragBitangent;
99

1010
out vec4 outColor;
1111

@@ -322,60 +322,83 @@ mat3 getTBN() {
322322

323323
// ===== Tersaalization Effect =====
324324

325-
#define TERA_LIGHT_DIRECT vec3(0.3f, 0.9f, 0.0f)
326-
#define TERATYPE_TINT vec3(0.161, 0.502, 0.937)
325+
#define TERATYPE_TINT vec3(0.161, 0.502, 0.937)
327326

328-
#define FACET_RES 8.0
329-
#define SHIMMER_BANDS 5.0
330-
#define GAMMA_CORRECTION 1.4
331-
#define SHIMMER_STRENGTH 0.8
332-
#define IRIDESCENCE_STRENGTH 0.2
327+
#define FACET_RES 8.0
328+
#define SHIMMER_BANDS 5.0
329+
#define GAMMA_CORRECTION 1.4
330+
#define SHIMMER_STRENGTH 0.8
331+
#define IRIDESCENCE_STRENGTH 0.2
333332

334333
uniform bool tera;
335334

336335
in vec3 fragViewDir;
337336
in vec3 worldPos;
338337

339-
vec3 calculateTersaalizationEffect(
340-
vec3 baseColor
341-
) {
338+
vec3 calculateTersaalizationEffect(vec3 baseColor, vec2 uv) {
342339
mat3 TBN = getTBN();
343340

344-
vec3 N = TBN[2];
341+
vec3 T = normalize(TBN[0]);
342+
vec3 B = normalize(TBN[1]);
343+
vec3 N = normalize(TBN[2]);
345344
vec3 V = normalize(fragViewDir);
346345

347-
// Fresnel rim lighting
348-
float fresnel = pow(1.0 - max(dot(N, V), 0.0), 5.0);
346+
float NoV = clamp(dot(N, V), 0.0, 1.0);
347+
float edge = 1.0 - NoV;
349348

350-
// Directional lighting response
351-
float lightResponse = max(dot(N, TERA_LIGHT_DIRECT), 0.0);
349+
float fresnel = pow(edge, 3.5);
350+
float thickness = pow(edge, 1.6);
351+
float innerGlow = pow(edge, 1.2);
352352

353-
// Facet simulation via quantized normals
354-
vec3 faceted = normalize(floor(N * FACET_RES + 0.5) / FACET_RES);
355-
float facetResponse = pow(max(dot(faceted, V), 0.0), 6.0);
353+
vec3 facetN = normalize(round(N * FACET_RES) / FACET_RES);
354+
// Was pow(..., 8.0) – far too harsh
355+
float facetResponse = pow(max(dot(facetN, V), 0.0), 4.0);
356356

357-
// Composite shimmer signal
358-
float shimmer = fresnel * 0.5 + lightResponse * 0.3 + facetResponse * 0.8;
359-
shimmer = pow(clamp(shimmer, 0.0, 1.0), GAMMA_CORRECTION);
357+
float tView = abs(dot(T, V));
358+
float bView = abs(dot(B, V));
359+
float anisotropic = pow(max(tView, bView * 0.7), 2.0);
360+
361+
float shimmer = 0.0;
362+
shimmer += fresnel * 0.25;
363+
shimmer += thickness * 0.30;
364+
shimmer += innerGlow * 0.25;
365+
shimmer += facetResponse * 0.40;
366+
shimmer += anisotropic * 0.35;
360367

361-
// Posterization
362-
shimmer = floor(shimmer * SHIMMER_BANDS) / SHIMMER_BANDS;
368+
shimmer = pow(clamp(shimmer, 0.0, 1.0), GAMMA_CORRECTION);
363369

364-
// Micro-noise based on 3D direction
365-
float angleNoise = abs(sin(dot(N.xyz, vec3(12.9898, 78.233, 45.164)) * 43758.5453));
370+
float angleNoise = abs(sin(dot(N, vec3(12.9898, 78.233, 45.164)) * 43758.5453));
366371
shimmer += angleNoise * 0.02;
372+
shimmer = clamp(shimmer, 0.0, 1.0);
373+
374+
// Make the shell mask less picky
375+
float shellMask = clamp(facetResponse * 0.5 + thickness * 0.5, 0.0, 1.0);
376+
shellMask = smoothstep(0.08, 0.90, shellMask);
377+
378+
float baseLuma = dot(baseColor, vec3(0.2126, 0.7152, 0.0722));
379+
float highlightPreserve = 1.0 - smoothstep(0.80, 0.98, baseLuma);
380+
highlightPreserve = mix(0.50, 1.0, highlightPreserve);
367381

368-
// Optional iridescent variation
369-
vec3 iridescent = vec3(1.0, 0.9, 0.8) + vec3(0.05, -0.02, 0.03) * sin(shimmer * 20.0);
382+
shellMask *= highlightPreserve;
370383

371-
// Tint variation based on light response
372-
vec3 directionalTint = mix(TERATYPE_TINT, vec3(1.0), lightResponse);
384+
vec3 ambientTint = mix(TERATYPE_TINT, vec3(0.93, 0.98, 1.0), 0.5);
385+
vec3 specTint = mix(vec3(1.0), TERATYPE_TINT, 0.4);
373386

374-
// Final output
375-
return baseColor
376-
+ directionalTint * shimmer * SHIMMER_STRENGTH
377-
+ iridescent * shimmer * IRIDESCENCE_STRENGTH;
387+
vec3 addCrystal = ambientTint * shimmer * SHIMMER_STRENGTH;
388+
addCrystal += specTint * facetResponse * (IRIDESCENCE_STRENGTH * 0.8);
389+
390+
addCrystal *= shellMask;
391+
392+
float maxBase = max(max(baseColor.r, baseColor.g), baseColor.b);
393+
float headroom = 1.0 - maxBase;
394+
float intensityScale = 0.50 + headroom * 1.00;
395+
396+
addCrystal *= intensityScale;
397+
398+
vec3 result = baseColor + addCrystal;
399+
return clamp(result, 0.0, 1.0);
378400
}
401+
379402
//////////////////////////////////////
380403

381404
void main() {
@@ -388,7 +411,7 @@ void main() {
388411
outColor.rgb *= tint;
389412

390413
if(tera) {
391-
outColor.rgb = calculateTersaalizationEffect(outColor.rgb);
414+
outColor.rgb = calculateTersaalizationEffect(outColor.rgb, texCoord0);
392415
} else if (useLight) {
393416
outColor *= vertexColor;
394417
// Sample Minecraft's light level from the lightmap texture

src/main/resources/shaders/experimental/animated.vs.glsl

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ out vec4 vertexColor;
1515
out vec2 texCoord0;
1616
out vec3 fragViewDir;
1717
out vec3 worldPos;
18-
out vec3 fragNormal;
19-
out vec3 fragTangent;
20-
out vec3 fragBitangent;
18+
flat out vec3 fragNormal;
19+
flat out vec3 fragTangent;
20+
flat out vec3 fragBitangent;
2121

2222
uniform bool dynamicVertexColor;
2323

@@ -54,31 +54,37 @@ float fog_distance(mat4 modelViewMat, vec3 pos, int shape) {
5454
}
5555
}
5656

57-
vec4 getVertexColor() {
57+
vec4 getVertexColor(vec3 litNormal) {
5858
if(dynamicVertexColor) return vec4(1);
5959

6060
vec3 lightDir0 = normalize(Light0_Direction);
6161
vec3 lightDir1 = normalize(Light1_Direction);
62-
float light0 = max(0.0, dot(Light0_Direction, normals));
63-
float light1 = max(0.0, dot(Light1_Direction, normals));
62+
float light0 = max(0.0, dot(lightDir0, litNormal));
63+
float light1 = max(0.0, dot(lightDir1, litNormal));
6464
float lightAccum = min(1.0, (light0 + light1) * MINECRAFT_LIGHT_POWER + MINECRAFT_AMBIENT_LIGHT);
6565
return vec4(lightAccum, lightAccum, lightAccum, 1);
6666
}
6767

6868
void main() {
69+
mat4 boneTransform = getBoneTransform();
70+
mat4 modelTransform = modelMatrix * boneTransform;
6971
mat4 worldSpace = projectionMatrix * viewMatrix;
70-
mat4 modelTransform = modelMatrix * getBoneTransform();
72+
mat4 modelView = viewMatrix * modelTransform;
7173
vec4 worldPosition = modelTransform * vec4(positions, 1.0);
7274

73-
fragNormal = normalize(normalMatrix * normals);
74-
fragTangent = normalize(normalMatrix * tangents.xyz);
75+
mat3 boneMatrix = mat3(boneTransform);
76+
vec3 skinnedNormal = normalize(boneMatrix * normals);
77+
vec3 skinnedTangent = normalize(boneMatrix * tangents.xyz);
78+
79+
fragNormal = normalize(normalMatrix * skinnedNormal);
80+
fragTangent = normalize(normalMatrix * skinnedTangent);
7581
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
7682
fragBitangent = cross(fragNormal, fragTangent) * tangents.w;
7783

7884
texCoord0 = (texcoords * uvScale) + uvOffset;
79-
gl_Position = worldSpace * worldPosition;
80-
vertexDistance = fog_distance(worldSpace * modelTransform, positions, FogShape);
81-
vertexColor = getVertexColor();
85+
gl_Position = projectionMatrix * modelView * vec4(positions, 1.0);
86+
vertexDistance = fog_distance(modelView, positions, FogShape);
87+
vertexColor = getVertexColor(fragNormal);
8288

8389
fragViewDir = normalize(-(viewMatrix * worldPosition).xyz);
8490
worldPos = worldPosition.xyz;

0 commit comments

Comments
 (0)