engine/bin/data/shaders/common/fog.h

57 lines
2.2 KiB
C

// Perlin Fog
void fog( in Ray ray, inout vec3 i, float scale ) {
if ( ubo.settings.fog.stepScale <= 0 || ubo.settings.fog.range.x == 0 || ubo.settings.fog.range.y == 0 ) return;
#if FOG_RAY_MARCH
if ( ubo.settings.fog.stepScale <= 0 || ubo.settings.fog.range.y <= 0 ) return;
const float range = ubo.settings.fog.range.y;
const vec3 boundsMin = ray.origin - vec3(range);
const vec3 boundsMax = ray.origin + vec3(range);
const vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, ray );
const float dstToBox = rayBoxInfo.x;
const float dstInsideBox = rayBoxInfo.y;
const float depth = surface.position.eye.z;
if ( dstInsideBox < 0 || dstToBox > depth ) return;
const float marchLimit = min( depth - dstToBox, dstInsideBox );
const int MAX_STEPS = 32;
const float stepSize = marchLimit / float(MAX_STEPS);
const vec3 stepVec = ray.direction * stepSize;
const float jitter = rand2(gl_GlobalInvocationID.xy);
const float densityScale = ubo.settings.fog.densityScale * 0.001;
const vec3 densityOffset = ubo.settings.fog.offset * 0.01;
const float densityThreshold = ubo.settings.fog.densityThreshold;
const float densityMult = ubo.settings.fog.densityMultiplier;
const float absorption = ubo.settings.fog.absorbtion;
vec3 currentPos = ray.origin + (ray.direction * (dstToBox + stepSize * jitter));
float transmittance = 1.0;
for ( uint j = 0; j < MAX_STEPS; ++j ) {
vec3 uvw = currentPos * densityScale + densityOffset;
float noiseVal = textureLod(samplerNoise, uvw, 0.0).r;
float density = max(0.0, noiseVal - densityThreshold) * densityMult;
if ( density > 0.0 ) {
float beer = exp(-density * stepSize * absorption);
transmittance *= beer;
if ( transmittance < 0.01 ) break;
}
currentPos += stepVec;
}
i.rgb = mix(ubo.settings.fog.color.rgb, i.rgb, transmittance );
#endif
#if FOG_BASIC
const vec3 color = ubo.settings.fog.color.rgb;
const float inner = ubo.settings.fog.range.x;
const float outer = ubo.settings.fog.range.y * scale;
const float distance = length(-surface.position.eye);
const float factor = clamp( (distance - inner) / (outer - inner), 0.0, 1.0 );
i.rgb = mix(i.rgb, color, factor);
#endif
}