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

56 lines
2.1 KiB
C

// Perlin Fog
void fog( in Ray ray, inout vec3 i, float scale ) {
if ( ubo.fog.stepScale <= 0 || ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
#if FOG_RAY_MARCH
const float range = ubo.fog.range.y;
const vec3 boundsMin = vec3(-range,-range,-range) + ray.origin;
const vec3 boundsMax = vec3(range,range,range) + ray.origin;
const int numSteps = int(length(boundsMax - boundsMin) * ubo.fog.stepScale );
const vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, ray );
const float dstToBox = rayBoxInfo.x;
const float dstInsideBox = rayBoxInfo.y;
const float depth = surface.position.eye.z;
const float aperture = 0; // PI * 0.5;
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
// march
if ( 0 <= dstInsideBox && dstToBox <= depth ) {
float stepSize = dstInsideBox / numSteps;
float dstLimit = min( depth - dstToBox, dstInsideBox );
float totalDensity = 0;
float transmittance = 1;
float lightFactor = scale;
float coneDiameter = coneCoefficient * ray.distance;
float level = aperture > 0 ? log2( coneDiameter ) : 0;
float density = 0;
vec3 uvw;
ray.distance = dstToBox;
while ( ray.distance < dstLimit ) {
ray.distance += stepSize;
ray.position = ray.origin + ray.direction * ray.distance;
coneDiameter = coneCoefficient * ray.distance;
level = aperture > 0 ? log2( coneDiameter ) : 0;
uvw = ray.position * ubo.fog.densityScale * 0.001 + ubo.fog.offset * 0.01;
density = max(0, textureLod(samplerNoise, uvw, level).r - ubo.fog.densityThreshold) * ubo.fog.densityMultiplier;
if ( density > 0 ) {
density = exp(-density * stepSize * ubo.fog.absorbtion);
transmittance *= density;
lightFactor *= density;
if ( transmittance < 0.1 ) break;
}
}
i.rgb = mix(ubo.fog.color.rgb, i.rgb, transmittance );
}
#endif
#if FOG_BASIC
const vec3 color = ubo.fog.color.rgb;
const float inner = ubo.fog.range.x;
const float outer = ubo.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
}