Workbench: Smoke: Add support for Color Mappping for smoke debugging
authorClément Foucault <foucault.clem@gmail.com>
Tue, 9 Oct 2018 09:19:54 +0000 (11:19 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Tue, 9 Oct 2018 10:12:38 +0000 (12:12 +0200)
source/blender/blenkernel/intern/smoke.c
source/blender/blenloader/intern/readfile.c
source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
source/blender/draw/engines/workbench/workbench_volume.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/intern/gpu_draw.c
source/blender/makesdna/DNA_smoke_types.h

index 4f41a5514544a3a9c895c2bb524f0fcbabf545d7..f5dd7ef794bd12d66e2712ea9308ddd87bcef1cf 100644 (file)
@@ -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);
                }
index b63951b3eabca6794524c8ca347f5b4f4f8d901c..bae71fba0369ca943e6d54e3319a16f3336c6df6 100644 (file)
@@ -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;
index 0860660d8da7d6d3e0627bcd87ed01721b1f7a88..5b949a6d9521aa1f88565b9aee6f2036d4fa4f0f 100644 (file)
@@ -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)
index ba1d3d9ff5c8877de4a6f6245deea279b9273f32..b0c08a2dc2845e9fb16e006e21b0056bc055e07c 100644 (file)
@@ -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)
index 028756bc739bc58c76b3af9d9a25cc594721d581..008f4199b027fc3a5c11aaa0aa638fb069009c53 100644 (file)
@@ -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 */
index 911af3601d2762826aab81a86747c66419be72eb..a5ec595177b64b031cbeb2de12c48fc1e5e1ee8a 100644 (file)
@@ -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)
index a09f766fc02a8afdf98a4bff56d118c303f11736..b8ac0de00902a65b70550526c71abed048e55381 100644 (file)
@@ -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;