diff options
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_volume.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_volume.c | 148 |
1 files changed, 111 insertions, 37 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 7aa089d440f..c76f4a4c470 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -45,8 +45,10 @@ void workbench_volume_engine_init(WORKBENCH_Data *vedata) if (txl->dummy_volume_tx == NULL) { const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - txl->dummy_volume_tx = GPU_texture_create_3d("dummy_volume", 1, 1, 1, 1, GPU_RGBA8, zero); - txl->dummy_shadow_tx = GPU_texture_create_3d("dummy_shadow", 1, 1, 1, 1, GPU_RGBA8, one); + txl->dummy_volume_tx = GPU_texture_create_3d( + "dummy_volume", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, zero); + txl->dummy_shadow_tx = GPU_texture_create_3d( + "dummy_shadow", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, one); txl->dummy_coba_tx = GPU_texture_create_1d("dummy_coba", 1, 1, GPU_RGBA8, zero); } } @@ -70,8 +72,7 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); DRWShadingGroup *grp = NULL; - /* Don't try to show liquid domains here */ - if (!fds->fluid || !(fds->type == FLUID_DOMAIN_TYPE_GAS)) { + if (!fds->fluid) { return; } @@ -79,19 +80,41 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, if (fds->use_coba) { DRW_smoke_ensure_coba_field(fmd); } - else { + else if (fds->type == FLUID_DOMAIN_TYPE_GAS) { DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE); } + else { + return; + } if ((!fds->use_coba && (fds->tex_density == NULL && fds->tex_color == NULL)) || (fds->use_coba && fds->tex_field == NULL)) { return; } - const bool use_slice = (fds->slice_method == FLUID_DOMAIN_SLICE_AXIS_ALIGNED && - fds->axis_slice_method == AXIS_SLICE_SINGLE); - const bool cubic_interp = (fds->interp_method == VOLUME_INTERP_CUBIC); - GPUShader *sh = workbench_shader_volume_get(use_slice, fds->use_coba, cubic_interp, true); + const bool use_slice = (fds->axis_slice_method == AXIS_SLICE_SINGLE); + const bool show_phi = ELEM(fds->coba_field, + FLUID_DOMAIN_FIELD_PHI, + FLUID_DOMAIN_FIELD_PHI_IN, + FLUID_DOMAIN_FIELD_PHI_OUT, + FLUID_DOMAIN_FIELD_PHI_OBSTACLE); + const bool show_flags = (fds->coba_field == FLUID_DOMAIN_FIELD_FLAGS); + const bool show_pressure = (fds->coba_field == FLUID_DOMAIN_FIELD_PRESSURE); + eWORKBENCH_VolumeInterpType interp_type = WORKBENCH_VOLUME_INTERP_LINEAR; + + switch ((FLUID_DisplayInterpolationMethod)fds->interp_method) { + case FLUID_DISPLAY_INTERP_LINEAR: + interp_type = WORKBENCH_VOLUME_INTERP_LINEAR; + break; + case FLUID_DISPLAY_INTERP_CUBIC: + interp_type = WORKBENCH_VOLUME_INTERP_CUBIC; + break; + case FLUID_DISPLAY_INTERP_CLOSEST: + interp_type = WORKBENCH_VOLUME_INTERP_CLOSEST; + break; + } + + GPUShader *sh = workbench_shader_volume_get(use_slice, fds->use_coba, interp_type, true); if (use_slice) { float invviewmat[4][4]; @@ -106,6 +129,7 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, float step_length = max_ff(1e-16f, dim[axis] * 0.05f); grp = DRW_shgroup_create(sh, vedata->psl->volume_ps); + DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_float_copy(grp, "slicePosition", fds->slice_depth); DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis); DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length); @@ -132,8 +156,19 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, } if (fds->use_coba) { - DRW_shgroup_uniform_texture(grp, "densityTexture", fds->tex_field); - DRW_shgroup_uniform_texture(grp, "transferTexture", fds->tex_coba); + if (show_flags) { + DRW_shgroup_uniform_texture(grp, "flagTexture", fds->tex_field); + } + else { + DRW_shgroup_uniform_texture(grp, "densityTexture", fds->tex_field); + } + if (!show_phi && !show_flags && !show_pressure) { + DRW_shgroup_uniform_texture(grp, "transferTexture", fds->tex_coba); + } + DRW_shgroup_uniform_float_copy(grp, "gridScale", fds->grid_scale); + DRW_shgroup_uniform_bool_copy(grp, "showPhi", show_phi); + DRW_shgroup_uniform_bool_copy(grp, "showFlags", show_flags); + DRW_shgroup_uniform_bool_copy(grp, "showPressure", show_pressure); } else { static float white[3] = {1.0f, 1.0f, 1.0f}; @@ -192,11 +227,26 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, WORKBENCH_PrivateData *wpd = vedata->stl->wpd; WORKBENCH_TextureList *txl = vedata->txl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + DRWShadingGroup *grp = NULL; wpd->volumes_do = true; + const bool use_slice = (volume->display.axis_slice_method == AXIS_SLICE_SINGLE); + eWORKBENCH_VolumeInterpType interp_type = WORKBENCH_VOLUME_INTERP_LINEAR; + + switch ((VolumeDisplayInterpMethod)volume->display.interpolation_method) { + case VOLUME_DISPLAY_INTERP_LINEAR: + interp_type = WORKBENCH_VOLUME_INTERP_LINEAR; + break; + case VOLUME_DISPLAY_INTERP_CUBIC: + interp_type = WORKBENCH_VOLUME_INTERP_CUBIC; + break; + case VOLUME_DISPLAY_INTERP_CLOSEST: + interp_type = WORKBENCH_VOLUME_INTERP_CLOSEST; + break; + } /* Create shader. */ - GPUShader *sh = workbench_shader_volume_get(false, false, false, false); + GPUShader *sh = workbench_shader_volume_get(use_slice, false, interp_type, false); /* Compute color. */ float color[3]; @@ -206,36 +256,60 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, 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); + if (use_slice) { + float invviewmat[4][4]; + DRW_view_viewmat_get(NULL, invviewmat, true); + + const int axis = (volume->display.slice_axis == SLICE_AXIS_AUTO) ? + axis_dominant_v3_single(invviewmat[2]) : + volume->display.slice_axis - 1; + + float dim[3]; + BKE_object_dimensions_get(ob, dim); + /* 0.05f to achieve somewhat the same opacity as the full view. */ + float step_length = max_ff(1e-16f, dim[axis] * 0.05f); + + const float slice_position = volume->display.slice_depth; + + grp = DRW_shgroup_create(sh, vedata->psl->volume_ps); + DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); + DRW_shgroup_uniform_float_copy(grp, "slicePosition", slice_position); + DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis); + DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length); + DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT); + } + else { + /* 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); + + /* Set uniforms. */ + 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); + } /* Compute density scale. */ const float density_scale = volume->display.density * BKE_volume_density_scale(volume, ob->obmat); - /* 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); |