EEVEE Next: Volumes #107176
|
@ -507,7 +507,7 @@ set(GLSL_SRC
|
|||
engines/eevee_next/shaders/eevee_volume_material_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_volume_material_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_volume_resolve_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_volume_scatter_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_volume_scatter_comp.glsl
|
||||
engines/eevee_next/shaders/eevee_volume_vert.glsl
|
||||
|
||||
engines/eevee_next/eevee_defines.hh
|
||||
|
|
|
@ -291,16 +291,19 @@ void Volumes::end_sync()
|
|||
transparent_pass_transmit_tx_ = integrated_transmit_tx_;
|
||||
|
||||
scatter_ps_.init();
|
||||
scatter_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
scatter_ps_.shader_set(inst_.shaders.static_shader_get(
|
||||
data_.use_lights ? VOLUME_SCATTER_WITH_LIGHTS : VOLUME_SCATTER));
|
||||
bind_volume_pass_resources(scatter_ps_);
|
||||
|
||||
scatter_ps_.bind_texture("volumeScattering", &prop_scattering_tx_);
|
||||
scatter_ps_.bind_texture("volumeExtinction", &prop_extinction_tx_);
|
||||
scatter_ps_.bind_texture("volumeEmission", &prop_emission_tx_);
|
||||
scatter_ps_.bind_texture("volumePhase", &prop_phase_tx_);
|
||||
scatter_ps_.draw_procedural(GPU_PRIM_TRIS, 1, data_.tex_size.z * 3);
|
||||
scatter_ps_.bind_texture("scattering_tx", &prop_scattering_tx_);
|
||||
scatter_ps_.bind_texture("extinction_tx", &prop_extinction_tx_);
|
||||
scatter_ps_.bind_texture("emission_tx", &prop_emission_tx_);
|
||||
scatter_ps_.bind_texture("phase_tx", &prop_phase_tx_);
|
||||
scatter_ps_.bind_image("out_scattering", &scatter_tx_);
|
||||
scatter_ps_.bind_image("out_transmittance", &transmit_tx_);
|
||||
|
||||
scatter_ps_.dispatch(math::divide_ceil(data_.tex_size, int3(VOLUME_GROUP_SIZE)));
|
||||
scatter_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
||||
|
||||
integration_ps_.init();
|
||||
integration_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
|
@ -328,13 +331,13 @@ void Volumes::draw_compute(View &view)
|
|||
|
||||
DRW_stats_group_start("Volumes");
|
||||
|
||||
inst_.manager->submit(world_ps_, view);
|
||||
|
||||
volumetric_fb_.ensure(GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_TEXTURE(prop_scattering_tx_),
|
||||
GPU_ATTACHMENT_TEXTURE(prop_extinction_tx_),
|
||||
GPU_ATTACHMENT_TEXTURE(prop_emission_tx_),
|
||||
GPU_ATTACHMENT_TEXTURE(prop_phase_tx_));
|
||||
|
||||
inst_.manager->submit(world_ps_, view);
|
||||
volumetric_fb_.bind();
|
||||
inst_.pipelines.volume.render(view);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ vec3 volume_scatter_light_eval(vec3 P, vec3 V, uint l_idx, float s_anisotropy)
|
|||
return vec3(0);
|
||||
}
|
||||
|
||||
vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, P, l_vector, volumeExtinction);
|
||||
vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, P, l_vector, extinction_tx);
|
||||
|
||||
return Li * vis * phase_function(-V, l_vector.xyz / l_vector.w, s_anisotropy);
|
||||
}
|
||||
|
@ -46,42 +46,52 @@ vec3 volume_scatter_light_eval(vec3 P, vec3 V, uint l_idx, float s_anisotropy)
|
|||
|
||||
void main()
|
||||
{
|
||||
ivec3 volume_cell = ivec3(ivec2(gl_FragCoord.xy), volume_geom_iface.slice);
|
||||
ivec3 froxel = ivec3(gl_GlobalInvocationID);
|
||||
|
||||
if (any(greaterThanEqual(froxel, volumes_buf.tex_size))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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) + volumes_buf.jitter) *
|
||||
volumes_buf.inv_tex_size);
|
||||
vec3 scattering = texelFetch(emission_tx, froxel, 0).rgb;
|
||||
vec3 transmittance = texelFetch(extinction_tx, froxel, 0).rgb;
|
||||
vec3 s_scattering = texelFetch(scattering_tx, froxel, 0).rgb;
|
||||
|
||||
vec3 volume_ndc = volume_to_ndc((vec3(froxel) + volumes_buf.jitter) * volumes_buf.inv_tex_size);
|
||||
vec3 vP = get_view_space_from_depth(volume_ndc.xy, volume_ndc.z);
|
||||
vec3 P = point_view_to_world(vP);
|
||||
vec3 V = cameraVec(P);
|
||||
|
||||
vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg;
|
||||
vec2 phase = texelFetch(phase_tx, froxel, 0).rg;
|
||||
float s_anisotropy = phase.x / max(1.0, phase.y);
|
||||
fclem marked this conversation as resolved
Outdated
|
||||
|
||||
/* Environment : Average color. */
|
||||
fclem marked this conversation as resolved
Outdated
Clément Foucault
commented
This comment is obsolete. This comment is obsolete.
|
||||
outScattering.rgb += irradiance_volumetric(P) * s_scattering * phase_function_isotropic();
|
||||
scattering += irradiance_volumetric(P) * s_scattering * phase_function_isotropic();
|
||||
|
||||
#ifdef VOLUME_LIGHTING
|
||||
|
||||
LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) {
|
||||
outScattering.rgb += volume_scatter_light_eval(P, V, l_idx, s_anisotropy) * s_scattering;
|
||||
scattering += volume_scatter_light_eval(P, V, l_idx, s_anisotropy) * s_scattering;
|
||||
}
|
||||
LIGHT_FOREACH_END
|
||||
|
||||
LIGHT_FOREACH_BEGIN_LOCAL (
|
||||
light_cull_buf, light_zbin_buf, light_tile_buf, gl_FragCoord.xy, vP.z, l_idx) {
|
||||
outScattering.rgb += volume_scatter_light_eval(P, V, l_idx, s_anisotropy) * s_scattering;
|
||||
/* TODO (Miguel Pozo): Simplify computation. Fix coord_scale first. */
|
||||
vec2 pixel = (vec2(froxel.xy) + vec2(0.5)) / vec2(volumes_buf.tex_size.xy) /
|
||||
volumes_buf.viewport_size_inv;
|
||||
|
||||
LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, pixel, vP.z, l_idx) {
|
||||
scattering += volume_scatter_light_eval(P, V, l_idx, s_anisotropy) * s_scattering;
|
||||
}
|
||||
LIGHT_FOREACH_END
|
||||
|
||||
#endif
|
||||
|
||||
/* Catch NaNs */
|
||||
if (any(isnan(outScattering)) || any(isnan(outTransmittance))) {
|
||||
outScattering = vec4(0.0);
|
||||
outTransmittance = vec4(1.0);
|
||||
if (any(isnan(scattering)) || any(isnan(transmittance))) {
|
||||
scattering = vec3(0.0);
|
||||
transmittance = vec3(1.0);
|
||||
}
|
||||
|
||||
imageStore(out_scattering, froxel, vec4(scattering, 1.0));
|
||||
imageStore(out_transmittance, froxel, vec4(transmittance, 1.0));
|
||||
}
|
|
@ -32,11 +32,6 @@ GPU_SHADER_CREATE_INFO(eevee_volume_base)
|
|||
.fragment_out(2, Type::VEC4, "volumeEmissive")
|
||||
.fragment_out(3, Type::VEC4, "volumePhase");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_base_comp)
|
||||
.additional_info("eevee_volume_lib")
|
||||
.define("STANDALONE")
|
||||
.define("VOLUMETRICS");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_clear)
|
||||
.additional_info("eevee_shared")
|
||||
.uniform_buf(VOLUMES_BUF_SLOT, "VolumesData", "volumes_buf")
|
||||
|
@ -48,57 +43,28 @@ GPU_SHADER_CREATE_INFO(eevee_volume_clear)
|
|||
.image(3, GPU_RG16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_phase")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter_common)
|
||||
.define("STANDALONE")
|
||||
.define("VOLUMETRICS")
|
||||
.define("VOLUME_SHADOW")
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter)
|
||||
.additional_info("draw_resource_id_varying")
|
||||
.additional_info("eevee_volume_lib")
|
||||
.compute_source("eevee_volume_scatter_comp.glsl")
|
||||
.local_group_size(VOLUME_GROUP_SIZE, VOLUME_GROUP_SIZE, VOLUME_GROUP_SIZE)
|
||||
.define("VOLUME_SHADOW")
|
||||
/* NOTE: Unique sampler IDs assigned for consistency between library includes,
|
||||
* and to avoid unique assignment collision validation error.
|
||||
* However, resources will be auto assigned locations within shader usage. */
|
||||
.sampler(17, ImageType::FLOAT_3D, "volumeScattering")
|
||||
.sampler(18, ImageType::FLOAT_3D, "volumeExtinction")
|
||||
.sampler(19, ImageType::FLOAT_3D, "volumeEmission")
|
||||
.sampler(20, ImageType::FLOAT_3D, "volumePhase")
|
||||
.fragment_out(0, Type::VEC4, "outScattering")
|
||||
.fragment_out(1, Type::VEC4, "outTransmittance")
|
||||
.vertex_source("eevee_volume_vert.glsl")
|
||||
.fragment_source("eevee_volume_scatter_frag.glsl")
|
||||
.vertex_out(eevee_volume_vert_geom_iface);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter)
|
||||
.additional_info("eevee_volume_scatter_common")
|
||||
.geometry_source("eevee_volume_geom.glsl")
|
||||
.geometry_out(eevee_volume_geom_frag_iface)
|
||||
.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3)
|
||||
.sampler(17, ImageType::FLOAT_3D, "scattering_tx")
|
||||
.sampler(18, ImageType::FLOAT_3D, "extinction_tx")
|
||||
.sampler(19, ImageType::FLOAT_3D, "emission_tx")
|
||||
.sampler(20, ImageType::FLOAT_3D, "phase_tx")
|
||||
.image(0, GPU_R11F_G11F_B10F, Qualifier::WRITE, ImageType::FLOAT_3D, "out_scattering")
|
||||
.image(1, GPU_R11F_G11F_B10F, Qualifier::WRITE, ImageType::FLOAT_3D, "out_transmittance")
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
Doesnt seems to be necessary. Merge with eevee_volume_resolve. Doesnt seems to be necessary. Merge with eevee_volume_resolve.
|
||||
.do_static_compilation(true);
|
||||
|
||||
#ifdef WITH_METAL_BACKEND
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter_no_geom)
|
||||
.additional_info("eevee_volume_scatter_common")
|
||||
.vertex_out(eevee_volume_geom_frag_iface)
|
||||
.metal_backend_only(true)
|
||||
.do_static_compilation(true)
|
||||
.auto_resource_location(true);
|
||||
#endif
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter_with_lights_common).define("VOLUME_LIGHTING");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter_with_lights)
|
||||
.additional_info("eevee_volume_scatter_with_lights_common")
|
||||
.additional_info("eevee_volume_scatter")
|
||||
.define("VOLUME_LIGHTING")
|
||||
.do_static_compilation(true);
|
||||
|
||||
#ifdef WITH_METAL_BACKEND
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_scatter_with_lights_no_geom)
|
||||
.additional_info("eevee_volume_scatter_with_lights_common")
|
||||
.additional_info("eevee_volume_scatter_no_geom")
|
||||
.metal_backend_only(true)
|
||||
.do_static_compilation(true)
|
||||
.auto_resource_location(true);
|
||||
#endif
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_volume_integration_common)
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
This should also output to the volume renderpasses. This should also output to the volume renderpasses.
Miguel Pozo
commented
I think we should actually get final (f12) rendering working first before looking into this? I think we should actually get final (f12) rendering working first before looking into this?
Clément Foucault
commented
Ok but then add a TODO here. Ok but then add a TODO here.
|
||||
.define("STANDALONE")
|
||||
.additional_info("eevee_volume_lib")
|
||||
|
|
Loading…
Reference in New Issue
This need a comment explaining why we divide by 2nd component.
To be honest I have no idea. Currently, only the first channel is ever written to.
It was like this in the current implementation so I left it there.
I assumed the second channel was intended to be used eventually.
It is used to store the number or phase that were written to it. This way we take the mean phase still using addive blending.
Oops! This should be solved now.