Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
80 lines
2.9 KiB
GLSL
80 lines
2.9 KiB
GLSL
|
|
/* Based on Frosbite Unified Volumetric.
|
|
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
|
|
|
|
/* Step 2 : Evaluate all light scattering for each froxels.
|
|
* Also do the temporal reprojection to fight aliasing artifacts. */
|
|
|
|
uniform sampler3D volumeScattering;
|
|
uniform sampler3D volumeExtinction;
|
|
uniform sampler3D volumeEmission;
|
|
uniform sampler3D volumePhase;
|
|
|
|
uniform sampler3D historyScattering;
|
|
uniform sampler3D historyTransmittance;
|
|
|
|
flat in int slice;
|
|
|
|
layout(location = 0) out vec4 outScattering;
|
|
layout(location = 1) out vec4 outTransmittance;
|
|
|
|
void main()
|
|
{
|
|
ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice);
|
|
|
|
/* Emission */
|
|
outScattering = texelFetch(volumeEmission, volume_cell, 0);
|
|
outTransmittance = texelFetch(volumeExtinction, volume_cell, 0);
|
|
vec3 s_scattering = texelFetch(volumeScattering, volume_cell, 0).rgb;
|
|
vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz);
|
|
vec3 worldPosition = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z);
|
|
vec3 wdir = cameraVec;
|
|
|
|
vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg;
|
|
float s_anisotropy = phase.x / max(1.0, phase.y);
|
|
|
|
/* Environment : Average color. */
|
|
outScattering.rgb += irradiance_volumetric(worldPosition) * s_scattering *
|
|
phase_function_isotropic();
|
|
|
|
#ifdef VOLUME_LIGHTING /* Lights */
|
|
for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
|
|
|
|
LightData ld = lights_data[i];
|
|
|
|
vec4 l_vector;
|
|
l_vector.xyz = (ld.l_type == SUN) ? -ld.l_forward : ld.l_position - worldPosition;
|
|
l_vector.w = length(l_vector.xyz);
|
|
|
|
float Vis = light_visibility(ld, worldPosition, l_vector);
|
|
|
|
vec3 Li = light_volume(ld, l_vector) *
|
|
light_volume_shadow(ld, worldPosition, l_vector, volumeExtinction);
|
|
|
|
outScattering.rgb += Li * Vis * s_scattering *
|
|
phase_function(-wdir, l_vector.xyz / l_vector.w, s_anisotropy);
|
|
}
|
|
#endif
|
|
|
|
/* Temporal supersampling */
|
|
/* Note : this uses the cell non-jittered position (texel center). */
|
|
vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) * volInvTexSize.xyz);
|
|
vec3 wpos = get_world_space_from_depth(curr_ndc.xy, curr_ndc.z);
|
|
vec3 prev_ndc = project_point(pastViewProjectionMatrix, wpos);
|
|
vec3 prev_volume = ndc_to_volume(prev_ndc * 0.5 + 0.5);
|
|
|
|
if ((volHistoryAlpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) &&
|
|
all(lessThan(prev_volume, vec3(1.0)))) {
|
|
vec4 h_Scattering = texture(historyScattering, prev_volume);
|
|
vec4 h_Transmittance = texture(historyTransmittance, prev_volume);
|
|
outScattering = mix(outScattering, h_Scattering, volHistoryAlpha);
|
|
outTransmittance = mix(outTransmittance, h_Transmittance, volHistoryAlpha);
|
|
}
|
|
|
|
/* Catch NaNs */
|
|
if (any(isnan(outScattering)) || any(isnan(outTransmittance))) {
|
|
outScattering = vec4(0.0);
|
|
outTransmittance = vec4(1.0);
|
|
}
|
|
}
|