Workbench: Smoke: Add support for Color Mappping for smoke debugging
This commit is contained in:
@@ -674,6 +674,8 @@ void smokeModifier_copy(const struct SmokeModifierData *smd, struct SmokeModifie
|
||||
tsds->vector_draw_type = sds->vector_draw_type;
|
||||
tsds->vector_scale = sds->vector_scale;
|
||||
|
||||
tsds->use_coba = sds->use_coba;
|
||||
tsds->coba_field = sds->coba_field;
|
||||
if (sds->coba) {
|
||||
tsds->coba = MEM_dupallocN(sds->coba);
|
||||
}
|
||||
|
||||
@@ -5169,6 +5169,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
smd->domain->tex_shadow = NULL;
|
||||
smd->domain->tex_flame = NULL;
|
||||
smd->domain->tex_flame_coba = NULL;
|
||||
smd->domain->tex_coba = NULL;
|
||||
smd->domain->tex_field = NULL;
|
||||
smd->domain->tex_velocity_x = NULL;
|
||||
smd->domain->tex_velocity_y = NULL;
|
||||
smd->domain->tex_velocity_z = NULL;
|
||||
|
||||
@@ -11,6 +11,7 @@ uniform sampler3D densityTexture;
|
||||
uniform sampler3D shadowTexture;
|
||||
uniform sampler3D flameTexture;
|
||||
uniform sampler1D flameColorTexture;
|
||||
uniform sampler1D transferTexture;
|
||||
|
||||
uniform int samplesLen = 256;
|
||||
uniform float stepLength; /* Step length in local space. */
|
||||
@@ -68,19 +69,25 @@ float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
|
||||
void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
|
||||
{
|
||||
vec3 co = ls_pos * 0.5 + 0.5;
|
||||
|
||||
#ifdef USE_COBA
|
||||
float val = texture(densityTexture, co).r;
|
||||
vec4 tval = texture(transferTexture, val) * densityScale;
|
||||
tval.rgb = pow(tval.rgb, vec3(2.2));
|
||||
scattering = tval.rgb * 1500.0;
|
||||
extinction = max(1e-4, tval.a * 50.0);
|
||||
#else
|
||||
float flame = texture(flameTexture, co).r;
|
||||
vec4 emission = texture(flameColorTexture, flame);
|
||||
|
||||
float shadows = texture(shadowTexture, co).r;
|
||||
vec4 density = texture(densityTexture, co); /* rgb: color, a: density */
|
||||
density.a *= densityScale;
|
||||
|
||||
scattering = density.rgb * density.a;
|
||||
scattering = density.rgb * density.a * densityScale;
|
||||
extinction = max(1e-4, dot(scattering, vec3(0.33333)));
|
||||
|
||||
scattering *= shadows * M_PI;
|
||||
/* 800 is arbitrary and here to mimic old viewport. TODO make it a parameter */
|
||||
scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0f;
|
||||
scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void eval_volume_step(inout vec3 Lscat, float extinction, float step_len, out float Tr)
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
|
||||
static struct {
|
||||
struct GPUShader *volume_sh;
|
||||
struct GPUShader *volume_coba_sh;
|
||||
struct GPUShader *volume_slice_sh;
|
||||
struct GPUShader *volume_slice_coba_sh;
|
||||
struct GPUTexture *dummy_tex;
|
||||
struct GPUTexture *dummy_coba_tex;
|
||||
} e_data = {NULL};
|
||||
@@ -49,9 +51,19 @@ void workbench_volume_engine_init(void)
|
||||
e_data.volume_sh = DRW_shader_create(
|
||||
datatoc_workbench_volume_vert_glsl, NULL,
|
||||
datatoc_workbench_volume_frag_glsl, NULL);
|
||||
e_data.volume_coba_sh = DRW_shader_create(
|
||||
datatoc_workbench_volume_vert_glsl, NULL,
|
||||
datatoc_workbench_volume_frag_glsl,
|
||||
"#define USE_COBA\n");
|
||||
e_data.volume_slice_sh = DRW_shader_create(
|
||||
datatoc_workbench_volume_vert_glsl, NULL,
|
||||
datatoc_workbench_volume_frag_glsl, "#define VOLUME_SLICE");
|
||||
datatoc_workbench_volume_frag_glsl,
|
||||
"#define VOLUME_SLICE\n");
|
||||
e_data.volume_slice_coba_sh = DRW_shader_create(
|
||||
datatoc_workbench_volume_vert_glsl, NULL,
|
||||
datatoc_workbench_volume_frag_glsl,
|
||||
"#define VOLUME_SLICE\n"
|
||||
"#define USE_COBA\n");
|
||||
|
||||
float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
e_data.dummy_tex = GPU_texture_create_3D(1, 1, 1, GPU_RGBA8, pixel, NULL);
|
||||
@@ -62,7 +74,9 @@ void workbench_volume_engine_init(void)
|
||||
void workbench_volume_engine_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.volume_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.volume_coba_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.volume_slice_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.volume_slice_coba_sh);
|
||||
DRW_TEXTURE_FREE_SAFE(e_data.dummy_tex);
|
||||
DRW_TEXTURE_FREE_SAFE(e_data.dummy_coba_tex);
|
||||
}
|
||||
@@ -78,6 +92,7 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
|
||||
SmokeDomainSettings *sds = smd->domain;
|
||||
WORKBENCH_PrivateData *wpd = vedata->stl->g_data;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
DRWShadingGroup *grp = NULL;
|
||||
|
||||
/* Don't show smoke before simulation starts, this could be made an option in the future. */
|
||||
if (!sds->fluid || CFRA < sds->point_cache[0]->startframe) {
|
||||
@@ -85,21 +100,26 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
|
||||
}
|
||||
|
||||
wpd->volumes_do = true;
|
||||
|
||||
if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
|
||||
if (sds->use_coba) {
|
||||
GPU_create_smoke_coba_field(smd);
|
||||
}
|
||||
else if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
|
||||
GPU_create_smoke(smd, 0);
|
||||
}
|
||||
else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
|
||||
GPU_create_smoke(smd, 1);
|
||||
}
|
||||
|
||||
if (sds->tex == NULL) {
|
||||
if ((!sds->use_coba && sds->tex == NULL) ||
|
||||
(sds->use_coba && sds->tex_field == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
|
||||
sds->axis_slice_method == AXIS_SLICE_SINGLE)
|
||||
{
|
||||
const bool use_slice = (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
|
||||
sds->axis_slice_method == AXIS_SLICE_SINGLE);
|
||||
|
||||
if (use_slice) {
|
||||
float invviewmat[4][4];
|
||||
DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
|
||||
|
||||
@@ -107,45 +127,46 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
|
||||
? axis_dominant_v3_single(invviewmat[2])
|
||||
: sds->slice_axis - 1;
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_slice_sh, vedata->psl->volume_pass);
|
||||
DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
|
||||
DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
|
||||
DRW_shgroup_uniform_texture(grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
|
||||
DRW_shgroup_uniform_texture(grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
|
||||
GPUShader *sh = (sds->use_coba) ? e_data.volume_slice_coba_sh : e_data.volume_slice_sh;
|
||||
grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
|
||||
DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
|
||||
DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis);
|
||||
DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
|
||||
BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
|
||||
|
||||
/* TODO COBA Rendering */
|
||||
|
||||
DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
|
||||
}
|
||||
else {
|
||||
int max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel;
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_sh, vedata->psl->volume_pass);
|
||||
GPUShader *sh = (sds->use_coba) ? e_data.volume_coba_sh : e_data.volume_sh;
|
||||
grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
|
||||
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
|
||||
DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
|
||||
DRW_shgroup_uniform_texture(grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
|
||||
DRW_shgroup_uniform_texture(grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
|
||||
DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
|
||||
DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slices);
|
||||
/* TODO FIXME : This step size is in object space but the ray itself
|
||||
* is NOT unit length in object space so the required number of subdivisions
|
||||
* is tricky to get. */
|
||||
DRW_shgroup_uniform_float_copy(grp, "stepLength", 8.0f / max_slices);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
|
||||
BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
|
||||
}
|
||||
|
||||
/* TODO COBA Rendering */
|
||||
if (sds->use_coba) {
|
||||
DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex_field);
|
||||
DRW_shgroup_uniform_texture(grp, "transferTexture", sds->tex_coba);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
|
||||
DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
|
||||
DRW_shgroup_uniform_texture(grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
|
||||
DRW_shgroup_uniform_texture(grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
|
||||
}
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
|
||||
DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
|
||||
|
||||
if (use_slice) {
|
||||
DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob);
|
||||
}
|
||||
|
||||
BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
|
||||
}
|
||||
|
||||
void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd)
|
||||
|
||||
@@ -103,6 +103,7 @@ void GPU_free_images_old(struct Main *bmain);
|
||||
void GPU_free_smoke(struct SmokeModifierData *smd);
|
||||
void GPU_free_smoke_velocity(struct SmokeModifierData *smd);
|
||||
void GPU_create_smoke(struct SmokeModifierData *smd, int highres);
|
||||
void GPU_create_smoke_coba_field(struct SmokeModifierData *smd);
|
||||
void GPU_create_smoke_velocity(struct SmokeModifierData *smd);
|
||||
|
||||
/* Delayed free of OpenGL buffers by main thread */
|
||||
|
||||
@@ -1088,9 +1088,35 @@ void GPU_free_smoke(SmokeModifierData *smd)
|
||||
if (smd->domain->tex_flame_coba)
|
||||
GPU_texture_free(smd->domain->tex_flame_coba);
|
||||
smd->domain->tex_flame_coba = NULL;
|
||||
|
||||
if (smd->domain->tex_coba)
|
||||
GPU_texture_free(smd->domain->tex_coba);
|
||||
smd->domain->tex_coba = NULL;
|
||||
|
||||
if (smd->domain->tex_field)
|
||||
GPU_texture_free(smd->domain->tex_field);
|
||||
smd->domain->tex_field = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_create_smoke_coba_field(SmokeModifierData *smd)
|
||||
{
|
||||
#ifdef WITH_SMOKE
|
||||
if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
|
||||
SmokeDomainSettings *sds = smd->domain;
|
||||
|
||||
if (!sds->tex_field) {
|
||||
sds->tex_field = create_field_texture(sds);
|
||||
}
|
||||
if (!sds->tex_coba) {
|
||||
sds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, sds->coba);
|
||||
}
|
||||
}
|
||||
#else // WITH_SMOKE
|
||||
smd->domain->tex_field = NULL;
|
||||
#endif // WITH_SMOKE
|
||||
}
|
||||
|
||||
void GPU_create_smoke(SmokeModifierData *smd, int highres)
|
||||
{
|
||||
#ifdef WITH_SMOKE
|
||||
|
||||
@@ -138,6 +138,8 @@ typedef struct SmokeDomainSettings {
|
||||
struct GPUTexture *tex_shadow;
|
||||
struct GPUTexture *tex_flame;
|
||||
struct GPUTexture *tex_flame_coba;
|
||||
struct GPUTexture *tex_coba;
|
||||
struct GPUTexture *tex_field;
|
||||
struct GPUTexture *tex_velocity_x;
|
||||
struct GPUTexture *tex_velocity_y;
|
||||
struct GPUTexture *tex_velocity_z;
|
||||
|
||||
Reference in New Issue
Block a user