From 9cf01d35be3a69aa162b4c5e24fe9a357f750aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 9 Oct 2018 11:19:54 +0200 Subject: Workbench: Smoke: Add support for Color Mappping for smoke debugging --- source/blender/blenkernel/intern/smoke.c | 2 + source/blender/blenloader/intern/readfile.c | 2 + .../workbench/shaders/workbench_volume_frag.glsl | 17 +++-- .../draw/engines/workbench/workbench_volume.c | 81 ++++++++++++++-------- source/blender/gpu/GPU_draw.h | 1 + source/blender/gpu/intern/gpu_draw.c | 26 +++++++ source/blender/makesdna/DNA_smoke_types.h | 2 + 7 files changed, 96 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 4f41a551454..f5dd7ef794b 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -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); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b63951b3eab..bae71fba036 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index 0860660d8da..5b949a6d952 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -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) diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index ba1d3d9ff5c..b0c08a2dc28 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -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) diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 028756bc739..008f4199b02 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -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 */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 911af3601d2..a5ec595177b 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1088,7 +1088,33 @@ 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) diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index a09f766fc02..b8ac0de0090 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -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; -- cgit v1.2.3