mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-03-02 12:03:56 +00:00
WaterBlock tiling to match T2/Torque, improve CLAUDE.md
This commit is contained in:
parent
bcf4f4a1a5
commit
aeda3ca8d5
940 changed files with 1207 additions and 337 deletions
112
src/file.vert
Normal file
112
src/file.vert
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#ifdef USE_FOG
|
||||
// Check runtime fog enabled uniform - allows toggling without shader recompilation
|
||||
if (fogEnabled) {
|
||||
// Fog disabled at runtime, skip all fog calculations
|
||||
} else {
|
||||
float dist = vFogDepth;
|
||||
|
||||
// Discard fragments at or beyond visible distance - matches Torque's behavior
|
||||
// where objects beyond visibleDistance are not rendered at all.
|
||||
// This prevents fully-fogged geometry from showing as silhouettes against
|
||||
// the sky's fog-to-sky gradient.
|
||||
if (dist >= fogFar) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Step 1: Calculate distance-based haze (quadratic falloff)
|
||||
// Since we discard at fogFar, haze never reaches 1.0 here
|
||||
float haze = 0.0;
|
||||
if (dist > fogNear) {
|
||||
float fogScale = 1.0 / (fogFar - fogNear);
|
||||
float distFactor = (dist - fogNear) * fogScale - 1.0;
|
||||
haze = 1.0 - distFactor * distFactor;
|
||||
}
|
||||
|
||||
// Step 2: Calculate fog volume contributions
|
||||
// Note: Per-volume colors are NOT used in Tribes 2 ($specialFog defaults to false)
|
||||
// All fog uses the global fogColor - see Tribes2_Fog_System.md for details
|
||||
float volumeFog = 0.0;
|
||||
|
||||
#ifdef USE_VOLUMETRIC_FOG
|
||||
{
|
||||
#ifdef USE_FOG_WORLD_POSITION
|
||||
float fragmentHeight = vFogWorldPosition.y;
|
||||
#else
|
||||
float fragmentHeight = cameraHeight;
|
||||
#endif
|
||||
|
||||
float deltaY = fragmentHeight - cameraHeight;
|
||||
float absDeltaY = abs(deltaY);
|
||||
|
||||
// Determine if we're going up (positive) or down (negative)
|
||||
if (absDeltaY > 0.01) {
|
||||
// Non-horizontal ray: ray-march through fog volumes
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int offset = i * 4;
|
||||
float volVisDist = allFogVolumes[offset + 0];
|
||||
float volMinH = allFogVolumes[offset + 1];
|
||||
float volMaxH = allFogVolumes[offset + 2];
|
||||
float volPct = allFogVolumes[offset + 3];
|
||||
|
||||
// Skip inactive volumes (visibleDistance = 0)
|
||||
if (volVisDist <= 0.0) continue;
|
||||
|
||||
// Calculate fog factor for this volume
|
||||
// From Torque: factor = (1 / (volumeVisDist * visFactor)) * percentage
|
||||
// where visFactor is smVisibleDistanceMod (a user quality pref, default 1.0)
|
||||
// Since we don't have quality settings, we use visFactor = 1.0
|
||||
float factor = (1.0 / volVisDist) * volPct;
|
||||
|
||||
// Find ray intersection with this volume's height range
|
||||
float rayMinY = min(cameraHeight, fragmentHeight);
|
||||
float rayMaxY = max(cameraHeight, fragmentHeight);
|
||||
|
||||
// Check if ray intersects volume height range
|
||||
if (rayMinY < volMaxH && rayMaxY > volMinH) {
|
||||
float intersectMin = max(rayMinY, volMinH);
|
||||
float intersectMax = min(rayMaxY, volMaxH);
|
||||
float intersectHeight = intersectMax - intersectMin;
|
||||
|
||||
// Calculate distance traveled through this volume using similar triangles:
|
||||
// subDist / dist = intersectHeight / absDeltaY
|
||||
float subDist = dist * (intersectHeight / absDeltaY);
|
||||
|
||||
// Accumulate fog: fog += subDist * factor
|
||||
volumeFog += subDist * factor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Near-horizontal ray: if camera is inside a volume, apply full fog for that volume
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int offset = i * 4;
|
||||
float volVisDist = allFogVolumes[offset + 0];
|
||||
float volMinH = allFogVolumes[offset + 1];
|
||||
float volMaxH = allFogVolumes[offset + 2];
|
||||
float volPct = allFogVolumes[offset + 3];
|
||||
|
||||
if (volVisDist <= 0.0) continue;
|
||||
|
||||
// If camera is inside this volume, apply fog for full distance
|
||||
if (cameraHeight >= volMinH && cameraHeight <= volMaxH) {
|
||||
float factor = (1.0 / volVisDist) * volPct;
|
||||
volumeFog += dist * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Step 3: Combine haze and volume fog
|
||||
// Torque's clamping: if (bandPct + hazePct > 1) hazePct = 1 - bandPct
|
||||
// This gives fog volumes priority over haze
|
||||
float volPct = min(volumeFog, 1.0);
|
||||
float hazePct = haze;
|
||||
if (volPct + hazePct > 1.0) {
|
||||
hazePct = 1.0 - volPct;
|
||||
}
|
||||
float fogFactor = hazePct + volPct;
|
||||
|
||||
// Apply fog using global fogColor (per-volume colors not used in Tribes 2)
|
||||
gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogFactor);
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue