diff options
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_volume.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_volume.c | 135 |
1 files changed, 120 insertions, 15 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index a3072b834bd..1eccc99d9e9 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -22,16 +22,20 @@ #include "workbench_private.h" -#include "BKE_object.h" -#include "BKE_fluid.h" +#include "DNA_fluid_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_force_types.h" +#include "DNA_volume_types.h" #include "BLI_rand.h" #include "BLI_dynstr.h" #include "BLI_string_utils.h" -#include "DNA_modifier_types.h" -#include "DNA_object_force_types.h" -#include "DNA_fluid_types.h" +#include "BKE_fluid.h" +#include "BKE_global.h" +#include "BKE_object.h" +#include "BKE_volume.h" +#include "BKE_volume_render.h" #include "GPU_draw.h" @@ -40,9 +44,11 @@ void workbench_volume_engine_init(WORKBENCH_Data *vedata) WORKBENCH_TextureList *txl = vedata->txl; if (txl->dummy_volume_tx == NULL) { - float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - txl->dummy_volume_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, pixel, NULL); - txl->dummy_coba_tx = GPU_texture_create_1d(1, GPU_RGBA8, pixel, NULL); + float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + txl->dummy_volume_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, zero, NULL); + txl->dummy_shadow_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, one, NULL); + txl->dummy_coba_tx = GPU_texture_create_1d(1, GPU_RGBA8, zero, NULL); } } @@ -54,10 +60,9 @@ void workbench_volume_cache_init(WORKBENCH_Data *vedata) vedata->stl->wpd->volumes_do = false; } -void workbench_volume_cache_populate(WORKBENCH_Data *vedata, - Scene *UNUSED(scene), - Object *ob, - ModifierData *md) +static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, + Object *ob, + ModifierData *md) { FluidModifierData *mmd = (FluidModifierData *)md; FluidDomainSettings *mds = mmd->domain; @@ -90,8 +95,7 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, const bool use_slice = (mds->slice_method == FLUID_DOMAIN_SLICE_AXIS_ALIGNED && mds->axis_slice_method == AXIS_SLICE_SINGLE); const bool cubic_interp = (mds->interp_method == VOLUME_INTERP_CUBIC); - - GPUShader *sh = workbench_shader_volume_get(use_slice, mds->use_coba, cubic_interp); + GPUShader *sh = workbench_shader_volume_get(use_slice, mds->use_coba, cubic_interp, true); if (use_slice) { float invviewmat[4][4]; @@ -162,6 +166,107 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(mmd)); } +static void workbench_volume_material_color(WORKBENCH_PrivateData *wpd, + Object *ob, + eV3DShadingColorType color_type, + float color[3]) +{ + Material *ma = BKE_object_material_get(ob, VOLUME_MATERIAL_NR); + WORKBENCH_UBO_Material ubo_data; + workbench_material_ubo_data(wpd, ob, ma, &ubo_data, color_type); + copy_v3_v3(color, ubo_data.base_color); +} + +static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, + Object *ob, + eV3DShadingColorType color_type) +{ + /* Create 3D textures. */ + Volume *volume = ob->data; + BKE_volume_load(volume, G.main); + VolumeGrid *volume_grid = BKE_volume_grid_active_get(volume); + if (volume_grid == NULL) { + return; + } + DRWVolumeGrid *grid = DRW_volume_batch_cache_get_grid(volume, volume_grid); + if (grid == NULL) { + return; + } + + WORKBENCH_PrivateData *wpd = vedata->stl->wpd; + WORKBENCH_TextureList *txl = vedata->txl; + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + wpd->volumes_do = true; + + /* Create shader. */ + GPUShader *sh = workbench_shader_volume_get(false, false, false, false); + + /* Compute color. */ + float color[3]; + workbench_volume_material_color(wpd, ob, color_type, color); + + /* Combined texture to object, and object to world transform. */ + float texture_to_world[4][4]; + mul_m4_m4m4(texture_to_world, ob->obmat, grid->texture_to_object); + + /* Compute world space dimensions for step size. */ + float world_size[3]; + mat4_to_size(world_size, texture_to_world); + abs_v3(world_size); + + /* Compute step parameters. */ + double noise_ofs; + BLI_halton_1d(3, 0.0, wpd->taa_sample, &noise_ofs); + float step_length, max_slice; + int resolution[3]; + GPU_texture_get_mipmap_size(grid->texture, 0, resolution); + float slice_ct[3] = {resolution[0], resolution[1], resolution[2]}; + mul_v3_fl(slice_ct, max_ff(0.001f, 5.0f)); + max_slice = max_fff(slice_ct[0], slice_ct[1], slice_ct[2]); + invert_v3(slice_ct); + mul_v3_v3(slice_ct, world_size); + step_length = len_v3(slice_ct); + + /* Compute density scale. */ + const float density_scale = volume->display.density; + + /* Set uniforms. */ + DRWShadingGroup *grp = DRW_shgroup_create(sh, vedata->psl->volume_ps); + DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); + DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slice); + DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length); + DRW_shgroup_uniform_float_copy(grp, "noiseOfs", noise_ofs); + DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT); + + DRW_shgroup_uniform_texture(grp, "densityTexture", grid->texture); + /* TODO: implement shadow texture, see manta_smoke_calc_transparency. */ + DRW_shgroup_uniform_texture(grp, "shadowTexture", txl->dummy_shadow_tx); + DRW_shgroup_uniform_vec3_copy(grp, "activeColor", color); + + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_float_copy(grp, "densityScale", density_scale); + + DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", grid->object_to_texture); + DRW_shgroup_uniform_mat4(grp, "volumeTextureToObject", grid->texture_to_object); + + DRW_shgroup_call(grp, DRW_cache_cube_get(), ob); +} + +void workbench_volume_cache_populate(WORKBENCH_Data *vedata, + Scene *UNUSED(scene), + Object *ob, + ModifierData *md, + eV3DShadingColorType color_type) +{ + if (md == NULL) { + workbench_volume_object_cache_populate(vedata, ob, color_type); + } + else { + workbench_volume_modifier_cache_populate(vedata, ob, md); + } +} + void workbench_volume_draw_pass(WORKBENCH_Data *vedata) { WORKBENCH_PassList *psl = vedata->psl; @@ -189,4 +294,4 @@ void workbench_volume_draw_finish(WORKBENCH_Data *vedata) GPU_free_smoke(mmd); } BLI_freelistN(&wpd->smoke_domains); -}
\ No newline at end of file +} |