Workbench Next Volumes #105501
|
@ -180,6 +180,7 @@ set(SRC
|
||||||
engines/workbench/workbench_state.cc
|
engines/workbench/workbench_state.cc
|
||||||
engines/workbench/workbench_transparent.c
|
engines/workbench/workbench_transparent.c
|
||||||
engines/workbench/workbench_volume.c
|
engines/workbench/workbench_volume.c
|
||||||
|
engines/workbench/workbench_volume_next.cc
|
||||||
engines/external/external_engine.c
|
engines/external/external_engine.c
|
||||||
engines/gpencil/gpencil_antialiasing.c
|
engines/gpencil/gpencil_antialiasing.c
|
||||||
engines/gpencil/gpencil_cache_utils.c
|
engines/gpencil/gpencil_cache_utils.c
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/** \name Volume shader base
|
/** \name Volume shader base
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_volume)
|
GPU_SHADER_CREATE_INFO(workbench_volume_common)
|
||||||
.vertex_in(0, Type::VEC3, "pos")
|
.vertex_in(0, Type::VEC3, "pos")
|
||||||
.fragment_out(0, Type::VEC4, "fragColor")
|
.fragment_out(0, Type::VEC4, "fragColor")
|
||||||
.sampler(0, ImageType::DEPTH_2D, "depthBuffer")
|
.sampler(0, ImageType::DEPTH_2D, "depthBuffer")
|
||||||
|
@ -16,27 +16,44 @@ GPU_SHADER_CREATE_INFO(workbench_volume)
|
||||||
.push_constant(Type::FLOAT, "stepLength")
|
.push_constant(Type::FLOAT, "stepLength")
|
||||||
.push_constant(Type::FLOAT, "densityScale")
|
.push_constant(Type::FLOAT, "densityScale")
|
||||||
.vertex_source("workbench_volume_vert.glsl")
|
.vertex_source("workbench_volume_vert.glsl")
|
||||||
.fragment_source("workbench_volume_frag.glsl")
|
.fragment_source("workbench_volume_frag.glsl");
|
||||||
.additional_info("draw_object_infos");
|
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_volume)
|
||||||
|
.additional_info("workbench_volume_common", "draw_object_infos");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_next_volume)
|
||||||
|
.define("WORKBENCH_NEXT")
|
||||||
|
.additional_info("workbench_volume_common", "draw_object_infos_new", "draw_view");
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Smoke variation
|
/** \name Smoke variation
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_volume_smoke)
|
GPU_SHADER_CREATE_INFO(workbench_volume_smoke_common)
|
||||||
.define("VOLUME_SMOKE")
|
.define("VOLUME_SMOKE")
|
||||||
.sampler(2, ImageType::FLOAT_3D, "flameTexture")
|
.sampler(2, ImageType::FLOAT_3D, "flameTexture")
|
||||||
.sampler(3, ImageType::FLOAT_1D, "flameColorTexture")
|
.sampler(3, ImageType::FLOAT_1D, "flameColorTexture")
|
||||||
.additional_info("draw_mesh", "draw_resource_id_varying");
|
.additional_info("draw_resource_id_varying");
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_volume_object)
|
GPU_SHADER_CREATE_INFO(workbench_volume_object_common)
|
||||||
.define("VOLUME_OBJECT")
|
.define("VOLUME_OBJECT")
|
||||||
.push_constant(Type::MAT4, "volumeTextureToObject")
|
.push_constant(Type::MAT4, "volumeTextureToObject")
|
||||||
/* FIXME(fclem): This overflow the push_constant limit. */
|
/* FIXME(fclem): This overflow the push_constant limit. */
|
||||||
.push_constant(Type::MAT4, "volumeObjectToTexture")
|
.push_constant(Type::MAT4, "volumeObjectToTexture")
|
||||||
.additional_info("draw_volume", "draw_resource_id_varying");
|
.additional_info("draw_resource_id_varying");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_volume_smoke)
|
||||||
|
.additional_info("workbench_volume_smoke_common", "draw_mesh");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_volume_object)
|
||||||
|
.additional_info("workbench_volume_object_common", "draw_volume");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_next_volume_smoke)
|
||||||
|
.additional_info("workbench_volume_smoke_common", "draw_modelmat_new");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_next_volume_object)
|
||||||
|
.additional_info("workbench_volume_object_common", "draw_volume_new");
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
@ -111,4 +128,10 @@ GPU_SHADER_CREATE_INFO(workbench_volume_slice)
|
||||||
|
|
||||||
WORKBENCH_VOLUME_SMOKE_VARIATIONS(workbench_volume, "workbench_volume")
|
WORKBENCH_VOLUME_SMOKE_VARIATIONS(workbench_volume, "workbench_volume")
|
||||||
|
|
||||||
|
#define WORKBENCH_NEXT_VOLUME_SMOKE_VARIATIONS(prefix, ...) \
|
||||||
|
WORKBENCH_VOLUME_INTERP_VARIATIONS(prefix##_smoke, "workbench_next_volume_smoke", __VA_ARGS__) \
|
||||||
|
WORKBENCH_VOLUME_INTERP_VARIATIONS(prefix##_object, "workbench_next_volume_object", __VA_ARGS__)
|
||||||
|
|
||||||
|
WORKBENCH_NEXT_VOLUME_SMOKE_VARIATIONS(workbench_next_volume, "workbench_next_volume")
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -209,6 +209,12 @@ vec4 volume_integration(vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max
|
||||||
/* accumulate and also take into account the transmittance from previous steps */
|
/* accumulate and also take into account the transmittance from previous steps */
|
||||||
final_scattering += final_transmittance * Lscat;
|
final_scattering += final_transmittance * Lscat;
|
||||||
final_transmittance *= Tr;
|
final_transmittance *= Tr;
|
||||||
|
|
||||||
|
if (final_transmittance <= 0.01) {
|
||||||
|
/* Early out */
|
||||||
|
final_transmittance = 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4(final_scattering, final_transmittance);
|
return vec4(final_scattering, final_transmittance);
|
||||||
|
|
|
@ -34,6 +34,7 @@ class Instance {
|
||||||
TransparentDepthPass transparent_depth_ps;
|
TransparentDepthPass transparent_depth_ps;
|
||||||
|
|
||||||
ShadowPass shadow_ps;
|
ShadowPass shadow_ps;
|
||||||
|
VolumePass volume_ps;
|
||||||
OutlinePass outline_ps;
|
OutlinePass outline_ps;
|
||||||
DofPass dof_ps;
|
DofPass dof_ps;
|
||||||
AntiAliasingPass anti_aliasing_ps;
|
AntiAliasingPass anti_aliasing_ps;
|
||||||
|
@ -75,6 +76,7 @@ class Instance {
|
||||||
transparent_depth_ps.sync(scene_state, resources);
|
transparent_depth_ps.sync(scene_state, resources);
|
||||||
|
|
||||||
shadow_ps.sync();
|
shadow_ps.sync();
|
||||||
|
volume_ps.sync(resources);
|
||||||
outline_ps.sync(resources);
|
outline_ps.sync(resources);
|
||||||
dof_ps.sync(resources);
|
dof_ps.sync(resources);
|
||||||
anti_aliasing_ps.sync(resources, scene_state.resolution);
|
anti_aliasing_ps.sync(resources, scene_state.resolution);
|
||||||
|
@ -85,6 +87,26 @@ class Instance {
|
||||||
resources.material_buf.push_update();
|
resources.material_buf.push_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot = 0)
|
||||||
|
{
|
||||||
|
switch (color_type) {
|
||||||
|
case V3D_SHADING_OBJECT_COLOR:
|
||||||
|
return Material(*ob_ref.object);
|
||||||
|
case V3D_SHADING_RANDOM_COLOR:
|
||||||
|
return Material(*ob_ref.object, true);
|
||||||
|
case V3D_SHADING_SINGLE_COLOR:
|
||||||
|
return scene_state.material_override;
|
||||||
|
case V3D_SHADING_VERTEX_COLOR:
|
||||||
|
return scene_state.material_attribute_color;
|
||||||
|
case V3D_SHADING_MATERIAL_COLOR:
|
||||||
|
if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, slot + 1)) {
|
||||||
|
return Material(*_mat);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return Material(*BKE_material_default_empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void object_sync(Manager &manager, ObjectRef &ob_ref)
|
void object_sync(Manager &manager, ObjectRef &ob_ref)
|
||||||
{
|
{
|
||||||
if (scene_state.render_finished) {
|
if (scene_state.render_finished) {
|
||||||
|
@ -138,9 +160,8 @@ class Instance {
|
||||||
if (md && BKE_modifier_is_enabled(scene_state.scene, md, eModifierMode_Realtime)) {
|
if (md && BKE_modifier_is_enabled(scene_state.scene, md, eModifierMode_Realtime)) {
|
||||||
FluidModifierData *fmd = (FluidModifierData *)md;
|
FluidModifierData *fmd = (FluidModifierData *)md;
|
||||||
if (fmd->domain) {
|
if (fmd->domain) {
|
||||||
#if 0 /* TODO(@pragma37): */
|
volume_ps.object_sync_modifier(manager, resources, scene_state, ob_ref, md);
|
||||||
workbench_volume_cache_populate(vedata, wpd->scene, ob, md, V3D_SHADING_SINGLE_COLOR);
|
|
||||||
#endif
|
|
||||||
if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
|
if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
|
||||||
return; /* Do not draw solid in this case. */
|
return; /* Do not draw solid in this case. */
|
||||||
}
|
}
|
||||||
|
@ -163,14 +184,16 @@ class Instance {
|
||||||
#if 0 /* TODO(@pragma37): */
|
#if 0 /* TODO(@pragma37): */
|
||||||
DRWShadingGroup *grp = workbench_material_hair_setup(
|
DRWShadingGroup *grp = workbench_material_hair_setup(
|
||||||
wpd, ob, CURVES_MATERIAL_NR, object_state.color_type);
|
wpd, ob, CURVES_MATERIAL_NR, object_state.color_type);
|
||||||
DRW_shgroup_curves_create_sub(ob, grp, NULL);
|
DRW_shgroup_curves_create_sub(ob, grp, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (ob->type == OB_VOLUME) {
|
else if (ob->type == OB_VOLUME) {
|
||||||
if (scene_state.shading.type != OB_WIRE) {
|
if (scene_state.shading.type != OB_WIRE) {
|
||||||
#if 0 /* TODO(@pragma37): */
|
volume_ps.object_sync_volume(manager,
|
||||||
workbench_volume_cache_populate(vedata, wpd->scene, ob, NULL, object_state.color_type);
|
resources,
|
||||||
#endif
|
scene_state,
|
||||||
|
ob_ref,
|
||||||
|
get_material(ob_ref, object_state.color_type).base_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,15 +227,7 @@ class Instance {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material mat;
|
Material mat = get_material(ob_ref, object_state.color_type, i);
|
||||||
|
|
||||||
if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) {
|
|
||||||
mat = Material(*_mat);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mat = Material(*BKE_material_default_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
has_transparent_material = has_transparent_material || mat.is_transparent();
|
has_transparent_material = has_transparent_material || mat.is_transparent();
|
||||||
|
|
||||||
::Image *image = nullptr;
|
::Image *image = nullptr;
|
||||||
|
@ -244,24 +259,7 @@ class Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch) {
|
if (batch) {
|
||||||
Material mat;
|
Material mat = get_material(ob_ref, object_state.color_type);
|
||||||
|
|
||||||
if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) {
|
|
||||||
mat = Material(*ob_ref.object);
|
|
||||||
}
|
|
||||||
else if (object_state.color_type == V3D_SHADING_RANDOM_COLOR) {
|
|
||||||
mat = Material(*ob_ref.object, true);
|
|
||||||
}
|
|
||||||
else if (object_state.color_type == V3D_SHADING_SINGLE_COLOR) {
|
|
||||||
mat = scene_state.material_override;
|
|
||||||
}
|
|
||||||
else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
|
|
||||||
mat = scene_state.material_attribute_color;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mat = Material(*BKE_material_default_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
has_transparent_material = has_transparent_material || mat.is_transparent();
|
has_transparent_material = has_transparent_material || mat.is_transparent();
|
||||||
|
|
||||||
draw_mesh(ob_ref,
|
draw_mesh(ob_ref,
|
||||||
|
@ -370,8 +368,7 @@ class Instance {
|
||||||
transparent_ps.draw(manager, view, resources, resolution);
|
transparent_ps.draw(manager, view, resources, resolution);
|
||||||
transparent_depth_ps.draw(manager, view, resources);
|
transparent_depth_ps.draw(manager, view, resources);
|
||||||
|
|
||||||
// volume_ps.draw_prepass(manager, view, resources.depth_tx);
|
volume_ps.draw(manager, view, resources);
|
||||||
|
|
||||||
outline_ps.draw(manager, resources);
|
outline_ps.draw(manager, resources);
|
||||||
dof_ps.draw(manager, view, resources, resolution);
|
dof_ps.draw(manager, view, resources, resolution);
|
||||||
anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx);
|
anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx);
|
||||||
|
|
|
@ -324,6 +324,52 @@ class ShadowPass {
|
||||||
bool force_fail_method);
|
bool force_fail_method);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VolumePass {
|
||||||
|
bool active_ = true;
|
||||||
|
|
||||||
|
PassMain ps_ = {"Volume"};
|
||||||
|
Framebuffer fb_ = {"Volume"};
|
||||||
|
|
||||||
|
Texture dummy_shadow_tx_ = {"Volume.Dummy Shadow Tx"};
|
||||||
|
Texture dummy_volume_tx_ = {"Volume.Dummy Volume Tx"};
|
||||||
|
Texture dummy_coba_tx_ = {"Volume.Dummy Coba Tx"};
|
||||||
|
|
||||||
|
GPUShader *shaders_[2 /*slice*/][2 /*coba*/][3 /*interpolation*/][2 /*smoke*/];
|
||||||
|
|
||||||
|
public:
|
||||||
|
void sync(SceneResources &resources);
|
||||||
|
|
||||||
|
void object_sync_volume(Manager &manager,
|
||||||
|
SceneResources &resources,
|
||||||
|
const SceneState &scene_state,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
float3 color);
|
||||||
|
|
||||||
|
void object_sync_modifier(Manager &manager,
|
||||||
|
SceneResources &resources,
|
||||||
|
const SceneState &scene_state,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
ModifierData *md);
|
||||||
|
|
||||||
|
void draw(Manager &manager, View &view, SceneResources &resources);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GPUShader *get_shader(bool slice, bool coba, int interpolation, bool smoke);
|
||||||
|
|
||||||
|
void draw_slice_ps(Manager &manager,
|
||||||
|
PassMain::Sub &ps,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
int slice_axis_enum,
|
||||||
|
float slice_depth);
|
||||||
|
|
||||||
|
void draw_volume_ps(Manager &manager,
|
||||||
|
PassMain::Sub &ps,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
int taa_sample,
|
||||||
|
float3 slice_count,
|
||||||
|
float3 world_size);
|
||||||
|
};
|
||||||
|
|
||||||
class OutlinePass {
|
class OutlinePass {
|
||||||
private:
|
private:
|
||||||
bool enabled_ = false;
|
bool enabled_ = false;
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "workbench_private.hh"
|
||||||
|
|
||||||
|
#include "BKE_volume.h"
|
||||||
|
#include "BKE_volume_render.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "DNA_fluid_types.h"
|
||||||
|
#include "DNA_modifier_types.h"
|
||||||
|
|
||||||
|
namespace blender::workbench {
|
||||||
|
|
||||||
|
void VolumePass::sync(SceneResources &resources)
|
||||||
|
{
|
||||||
|
active_ = false;
|
||||||
|
ps_.init();
|
||||||
|
ps_.bind_ubo(WB_WORLD_SLOT, resources.world_buf);
|
||||||
|
|
||||||
|
dummy_shadow_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(1));
|
||||||
|
dummy_volume_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(0));
|
||||||
|
dummy_coba_tx_.ensure_1d(GPU_RGBA8, 1, GPU_TEXTURE_USAGE_SHADER_READ, float4(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumePass::object_sync_volume(Manager &manager,
|
||||||
|
SceneResources &resources,
|
||||||
|
const SceneState &scene_state,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
float3 color)
|
||||||
|
{
|
||||||
|
Object *ob = ob_ref.object;
|
||||||
|
/* Create 3D textures. */
|
||||||
|
Volume *volume = static_cast<Volume *>(ob->data);
|
||||||
|
BKE_volume_load(volume, G.main);
|
||||||
|
const VolumeGrid *volume_grid = BKE_volume_grid_active_get_for_read(volume);
|
||||||
|
if (volume_grid == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRWVolumeGrid *grid = DRW_volume_batch_cache_get_grid(volume, volume_grid);
|
||||||
|
if (grid == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
active_ = true;
|
||||||
|
|
||||||
|
PassMain::Sub &sub_ps = ps_.sub(ob->id.name);
|
||||||
|
|
||||||
|
const bool use_slice = (volume->display.axis_slice_method == AXIS_SLICE_SINGLE);
|
||||||
|
|
||||||
|
sub_ps.shader_set(get_shader(use_slice, false, volume->display.interpolation_method, false));
|
||||||
|
|
||||||
|
const float density_scale = volume->display.density *
|
||||||
|
BKE_volume_density_scale(volume, ob->object_to_world);
|
||||||
|
|
||||||
|
sub_ps.bind_texture("depthBuffer", &resources.depth_tx);
|
||||||
|
sub_ps.bind_texture("densityTexture", grid->texture);
|
||||||
|
/* TODO: implement shadow texture, see manta_smoke_calc_transparency. */
|
||||||
|
sub_ps.bind_texture("shadowTexture", dummy_shadow_tx_);
|
||||||
|
sub_ps.push_constant("activeColor", color);
|
||||||
|
sub_ps.push_constant("densityScale", density_scale);
|
||||||
|
sub_ps.push_constant("volumeObjectToTexture", float4x4(grid->object_to_texture));
|
||||||
|
sub_ps.push_constant("volumeTextureToObject", float4x4(grid->texture_to_object));
|
||||||
|
|
||||||
|
if (use_slice) {
|
||||||
|
draw_slice_ps(
|
||||||
|
manager, sub_ps, ob_ref, volume->display.slice_axis, volume->display.slice_depth);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float3 world_size;
|
||||||
|
float4x4 texture_to_world = float4x4(ob->object_to_world) * float4x4(grid->texture_to_object);
|
||||||
|
math::normalize_and_get_size(float3x3(texture_to_world), world_size);
|
||||||
|
|
||||||
|
int3 resolution;
|
||||||
|
GPU_texture_get_mipmap_size(grid->texture, 0, resolution);
|
||||||
|
float3 slice_count = float3(resolution) * 5.0f;
|
||||||
|
|
||||||
|
draw_volume_ps(manager, sub_ps, ob_ref, scene_state.sample, slice_count, world_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumePass::object_sync_modifier(Manager &manager,
|
||||||
|
SceneResources &resources,
|
||||||
|
const SceneState &scene_state,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
ModifierData *md)
|
||||||
|
{
|
||||||
|
Object *ob = ob_ref.object;
|
||||||
|
|
||||||
|
FluidModifierData *modifier = reinterpret_cast<FluidModifierData *>(md);
|
||||||
|
FluidDomainSettings &settings = *modifier->domain;
|
||||||
|
|
||||||
|
if (!settings.fluid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_load = false;
|
||||||
|
if (settings.use_coba) {
|
||||||
|
DRW_smoke_ensure_coba_field(modifier);
|
||||||
|
can_load = settings.tex_field != nullptr;
|
||||||
|
}
|
||||||
|
else if (settings.type == FLUID_DOMAIN_TYPE_GAS) {
|
||||||
|
DRW_smoke_ensure(modifier, settings.flags & FLUID_DOMAIN_USE_NOISE);
|
||||||
|
can_load = settings.tex_density != nullptr || settings.tex_color != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!can_load) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
active_ = true;
|
||||||
|
|
||||||
|
PassMain::Sub &sub_ps = ps_.sub(ob->id.name);
|
||||||
|
|
||||||
|
const bool use_slice = settings.axis_slice_method == AXIS_SLICE_SINGLE;
|
||||||
|
|
||||||
|
sub_ps.shader_set(get_shader(use_slice, settings.use_coba, settings.interp_method, true));
|
||||||
|
|
||||||
|
if (settings.use_coba) {
|
||||||
|
const bool show_flags = settings.coba_field == FLUID_DOMAIN_FIELD_FLAGS;
|
||||||
|
const bool show_pressure = settings.coba_field == FLUID_DOMAIN_FIELD_PRESSURE;
|
||||||
|
const bool show_phi = ELEM(settings.coba_field,
|
||||||
|
FLUID_DOMAIN_FIELD_PHI,
|
||||||
|
FLUID_DOMAIN_FIELD_PHI_IN,
|
||||||
|
FLUID_DOMAIN_FIELD_PHI_OUT,
|
||||||
|
FLUID_DOMAIN_FIELD_PHI_OBSTACLE);
|
||||||
|
|
||||||
|
sub_ps.push_constant("showFlags", show_flags);
|
||||||
|
sub_ps.push_constant("showPressure", show_pressure);
|
||||||
|
sub_ps.push_constant("showPhi", show_phi);
|
||||||
|
sub_ps.push_constant("gridScale", settings.grid_scale);
|
||||||
|
|
||||||
|
if (show_flags) {
|
||||||
|
sub_ps.bind_texture("flagTexture", settings.tex_field);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sub_ps.bind_texture("densityTexture", settings.tex_field);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!show_flags && !show_pressure && !show_phi) {
|
||||||
|
sub_ps.bind_texture("transferTexture", settings.tex_coba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool use_constant_color = ((settings.active_fields & FLUID_DOMAIN_ACTIVE_COLORS) == 0 &&
|
||||||
|
(settings.active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET) != 0);
|
||||||
|
|
||||||
|
sub_ps.push_constant("activeColor",
|
||||||
|
use_constant_color ? float3(settings.active_color) : float3(1));
|
||||||
|
|
||||||
|
sub_ps.bind_texture("densityTexture",
|
||||||
|
settings.tex_color ? settings.tex_color : settings.tex_density);
|
||||||
|
sub_ps.bind_texture("flameTexture",
|
||||||
|
settings.tex_flame ? settings.tex_flame : dummy_volume_tx_);
|
||||||
|
sub_ps.bind_texture("flameColorTexture",
|
||||||
|
settings.tex_flame ? settings.tex_flame_coba : dummy_coba_tx_);
|
||||||
|
sub_ps.bind_texture("shadowTexture", settings.tex_shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_ps.push_constant("densityScale", 10.0f * settings.display_thickness);
|
||||||
|
sub_ps.bind_texture("depthBuffer", &resources.depth_tx);
|
||||||
|
|
||||||
|
if (use_slice) {
|
||||||
|
draw_slice_ps(manager, sub_ps, ob_ref, settings.slice_axis, settings.slice_depth);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float3 world_size;
|
||||||
|
BKE_object_dimensions_get(ob, world_size);
|
||||||
|
|
||||||
|
float3 slice_count = float3(settings.res) * std::max(0.001f, settings.slice_per_voxel);
|
||||||
|
|
||||||
|
draw_volume_ps(manager, sub_ps, ob_ref, scene_state.sample, slice_count, world_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumePass::draw(Manager &manager, View &view, SceneResources &resources)
|
||||||
|
{
|
||||||
|
if (!active_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||||
|
fb_.bind();
|
||||||
|
manager.submit(ps_, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
GPUShader *VolumePass::get_shader(bool slice, bool coba, int interpolation, bool smoke)
|
||||||
|
{
|
||||||
|
GPUShader *&shader = shaders_[slice][coba][interpolation][smoke];
|
||||||
|
|
||||||
|
if (shader == nullptr) {
|
||||||
|
std::string create_info_name = "workbench_next_volume";
|
||||||
|
create_info_name += (smoke) ? "_smoke" : "_object";
|
||||||
|
switch (interpolation) {
|
||||||
|
case VOLUME_DISPLAY_INTERP_LINEAR:
|
||||||
|
create_info_name += "_linear";
|
||||||
|
break;
|
||||||
|
case VOLUME_DISPLAY_INTERP_CUBIC:
|
||||||
|
create_info_name += "_cubic";
|
||||||
|
break;
|
||||||
|
case VOLUME_DISPLAY_INTERP_CLOSEST:
|
||||||
|
create_info_name += "_closest";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
create_info_name += (coba) ? "_coba" : "_no_coba";
|
||||||
|
create_info_name += (slice) ? "_slice" : "_no_slice";
|
||||||
|
shader = GPU_shader_create_from_info_name(create_info_name.c_str());
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumePass::draw_slice_ps(
|
||||||
|
Manager &manager, PassMain::Sub &ps, ObjectRef &ob_ref, int slice_axis_enum, float slice_depth)
|
||||||
|
{
|
||||||
|
float4x4 view_mat_inv;
|
||||||
|
DRW_view_viewmat_get(nullptr, view_mat_inv.ptr(), true);
|
||||||
|
|
||||||
|
const int axis = (slice_axis_enum == SLICE_AXIS_AUTO) ?
|
||||||
|
axis_dominant_v3_single(view_mat_inv[2]) :
|
||||||
|
slice_axis_enum - 1;
|
||||||
|
|
||||||
|
float3 dimensions;
|
||||||
|
BKE_object_dimensions_get(ob_ref.object, dimensions);
|
||||||
|
/* 0.05f to achieve somewhat the same opacity as the full view. */
|
||||||
|
float step_length = std::max(1e-16f, dimensions[axis] * 0.05f);
|
||||||
|
|
||||||
|
ps.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||||
|
ps.push_constant("slicePosition", slice_depth);
|
||||||
|
ps.push_constant("sliceAxis", axis);
|
||||||
|
ps.push_constant("stepLength", step_length);
|
||||||
|
|
||||||
|
ps.draw(DRW_cache_quad_get(), manager.resource_handle(ob_ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumePass::draw_volume_ps(Manager &manager,
|
||||||
|
PassMain::Sub &ps,
|
||||||
|
ObjectRef &ob_ref,
|
||||||
|
int taa_sample,
|
||||||
|
float3 slice_count,
|
||||||
|
float3 world_size)
|
||||||
|
{
|
||||||
|
double noise_offset;
|
||||||
|
BLI_halton_1d(3, 0.0, taa_sample, &noise_offset);
|
||||||
|
|
||||||
|
int max_slice = std::max({UNPACK3(slice_count)});
|
||||||
|
float step_length = math::length((1.0f / slice_count) * world_size);
|
||||||
|
|
||||||
|
ps.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_CULL_FRONT);
|
||||||
|
ps.push_constant("samplesLen", max_slice);
|
||||||
|
ps.push_constant("stepLength", step_length);
|
||||||
|
ps.push_constant("noiseOfs", float(noise_offset));
|
||||||
|
|
||||||
|
ps.draw(DRW_cache_cube_get(), manager.resource_handle(ob_ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::workbench
|
|
@ -126,6 +126,9 @@ GPU_SHADER_CREATE_INFO(draw_pointcloud)
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resource_id_uniform");
|
GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resource_id_uniform");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(draw_volume_new)
|
||||||
|
.additional_info("draw_modelmat_new", "draw_resource_handle_new");
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(draw_gpencil)
|
GPU_SHADER_CREATE_INFO(draw_gpencil)
|
||||||
.typedef_source("gpencil_shader_shared.h")
|
.typedef_source("gpencil_shader_shared.h")
|
||||||
.define("DRW_GPENCIL_INFO")
|
.define("DRW_GPENCIL_INFO")
|
||||||
|
|
Loading…
Reference in New Issue