56 lines
2.1 KiB
C
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
|
|
} |