Files
blight/blight-assets/src/main/resources/Shaders/Voxel.frag
Mario c8f1dd9432 Animations-Import, Massenimport-Queue, Asset-Archivierung, Voxel-Refactor
- Animations-Import: GLB wird direkt vom Ursprungspfad geladen (kein Zwischenkopieren), J3O in clips/ gespeichert
- RetargetingSystem: Translations-Tracks im Full-Retarget-Pfad erhalten (Hips-Y für sit_down)
- AnimationLibrary: lädt nur J3O, Clip-Name wird bei applyTo() auf Library-Key umbenannt
- SharedInput: animPreviewAddAnimPath → ConcurrentLinkedQueue animImportQueue (Massenimport-Fix)
- EditorApp: archiveOriginal() archiviert Originaldateien nach assets/imported/<assettyp>/
- EditorApp: Animations-Unterknoten im Asset-Baum zeigen enthaltene Clip-Namen
- Neue Animations-Clips: sit_down, get_up_sitting, sitting, pickup, sprinting u.a.
- Voxel: VoxelChunkState entfernt, VoxelChunkNode/MarchingCubes überarbeitet
- Map: Voxel-Chunks bereinigt, Terrain-Chunks aktualisiert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 20:52:04 +02:00

113 lines
3.4 KiB
GLSL

uniform sampler2D m_TexFlat;
uniform sampler2D m_TexSteep;
uniform float m_TexScale;
#ifdef HAS_NM_FLAT
uniform sampler2D m_NormalMapFlat;
#endif
#ifdef HAS_NM_STEEP
uniform sampler2D m_NormalMapSteep;
#endif
in vec3 vWorldPos;
in vec3 vNormal;
out vec4 outColor;
#ifdef HAS_LIGHTDIR
uniform vec3 m_LightDir;
#endif
#ifdef HAS_SCENE_LIGHT
uniform vec3 m_SunColor;
uniform vec3 m_AmbientColor;
#endif
vec4 triplanar(sampler2D tex, vec2 uvX, vec2 uvY, vec2 uvZ, vec3 bw) {
return texture(tex, uvX) * bw.x
+ texture(tex, uvY) * bw.y
+ texture(tex, uvZ) * bw.z;
}
// Triplanare Normal-Map-Mischung (Whiteout-Blending, world-space Ausgabe).
// N = geometrische Weltoberflächen-Normale, bw = triplanare Gewichte.
vec3 triplanarNormal(sampler2D nmap, vec2 uvX, vec2 uvY, vec2 uvZ, vec3 bw, vec3 N) {
vec3 tnX = texture(nmap, uvX).rgb * 2.0 - 1.0;
vec3 tnY = texture(nmap, uvY).rgb * 2.0 - 1.0;
vec3 tnZ = texture(nmap, uvZ).rgb * 2.0 - 1.0;
// Reorientiertes Normal-Mapping (RNM / Whiteout): Tangent → World
tnX = vec3(tnX.xy + N.zy, abs(tnX.z) * N.x);
tnY = vec3(tnY.xy + N.xz, abs(tnY.z) * N.y);
tnZ = vec3(tnZ.xy + N.xy, abs(tnZ.z) * N.z);
return normalize(tnX.zyx * bw.x + tnY.xzy * bw.y + tnZ.xyz * bw.z);
}
void main() {
vec3 bw = pow(abs(vNormal), vec3(4.0));
bw /= (bw.x + bw.y + bw.z + 0.001);
vec2 uvX = vWorldPos.yz / m_TexScale;
vec2 uvY = vWorldPos.xz / m_TexScale;
vec2 uvZ = vWorldPos.xy / m_TexScale;
// Flach ab ~11° Gefälle (20% grade, normal.y≈0.98); alles andere Fels.
float flatBlend = smoothstep(0.94, 0.99, vNormal.y);
float steepBlend = 1.0 - flatBlend;
// Flat: reines XZ-UV wie das Terrain (uvY = worldPos.xz / texScale), kein Triplanar.
// Steep: Triplanar für alle nicht-flachen Flächen inkl. Decken und Tunnelwände.
vec4 col = texture(m_TexFlat, uvY) * flatBlend
+ triplanar(m_TexSteep, uvX, uvY, uvZ, bw) * steepBlend;
// Geometrie-Normale für Beleuchtung, ggf. durch Normal-Map ersetzt.
vec3 N = normalize(vNormal);
#if defined(HAS_NM_FLAT) || defined(HAS_NM_STEEP)
vec3 pertN = vec3(0.0);
float totalBlend = 0.0;
#ifdef HAS_NM_FLAT
if (flatBlend > 0.001) {
vec3 nmFlat = texture(m_NormalMapFlat, uvY).rgb * 2.0 - 1.0;
nmFlat = vec3(nmFlat.xy + N.xz, abs(nmFlat.z) * N.y);
pertN += normalize(nmFlat.xzy) * flatBlend;
totalBlend += flatBlend;
}
#endif
#ifdef HAS_NM_STEEP
if (steepBlend > 0.001) {
pertN += triplanarNormal(m_NormalMapSteep, uvX, uvY, uvZ, bw, N) * steepBlend;
totalBlend += steepBlend;
}
#endif
if (totalBlend > 0.001) {
N = normalize(pertN / totalBlend);
}
#endif
// Flache Voxel-Flächen Richtung (0,1,0) korrigieren, um Abweichungen der
// Marching-Cubes-Normalen auszugleichen und das Terrain-Lighting zu matchen.
N = normalize(mix(N, vec3(0.0, 1.0, 0.0), flatBlend));
#ifdef HAS_LIGHTDIR
vec3 lightDir = normalize(m_LightDir);
#else
vec3 lightDir = normalize(vec3(0.6, 1.0, 0.4));
#endif
float diff = max(dot(N, lightDir), 0.0);
#ifdef HAS_SCENE_LIGHT
vec3 light = m_AmbientColor + m_SunColor * diff;
#else
vec3 light = vec3(diff * 0.65 + 0.35);
#endif
const float BRIGHTNESS = 0.80;
#ifdef DEBUG_NO_LIGHT
outColor = vec4(col.rgb * BRIGHTNESS, col.a);
#else
outColor = vec4(col.rgb * light * BRIGHTNESS, col.a);
#endif
if (outColor.a < 0.1) discard;
}