Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines')
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c178
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c11
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c7
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c27
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c31
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h5
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c290
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl68
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl46
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl64
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl8
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c87
22 files changed, 581 insertions, 276 deletions
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 2e3fdf37bdb..9dc8c8f2f34 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -112,7 +112,9 @@ static void basic_cache_populate(void *vedata, Object *ob)
{
BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
- if (!DRW_object_is_renderable(ob)) {
+ /* TODO(fclem) fix selection of smoke domains. */
+
+ if (!DRW_object_is_renderable(ob) || (ob->dt < OB_SOLID)) {
return;
}
@@ -125,7 +127,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 32de4266c82..bea7d000181 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -137,7 +137,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
}
if (DRW_object_is_renderable(ob) &&
- DRW_check_object_visible_within_active_context(ob))
+ DRW_object_is_visible_in_active_context(ob))
{
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index a458be040fc..7319572d7eb 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -628,12 +628,12 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
evli->radius = max_ff(0.001f, la->area_size);
}
else if (la->type == LA_AREA) {
- evli->sizex = max_ff(0.0001f, la->area_size * scale[0] * 0.5f);
+ evli->sizex = max_ff(0.003f, la->area_size * scale[0] * 0.5f);
if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
- evli->sizey = max_ff(0.0001f, la->area_sizey * scale[1] * 0.5f);
+ evli->sizey = max_ff(0.003f, la->area_sizey * scale[1] * 0.5f);
}
else {
- evli->sizey = max_ff(0.0001f, la->area_size * scale[1] * 0.5f);
+ evli->sizey = max_ff(0.003f, la->area_size * scale[1] * 0.5f);
}
}
else {
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 2d27bb8e705..38c2fb50f81 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1080,23 +1080,23 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
-#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) do { \
+#define ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata) do { \
if (is_sculpt_mode_draw) { \
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \
} \
else { \
if (oedata) { \
- DRW_shgroup_call_object_add_with_callback(shgrp, geom, ob, EEVEE_lightprobes_obj_visibility_cb, oedata); \
+ DRW_shgroup_call_object_add_with_callback(shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \
} \
else { \
- DRW_shgroup_call_object_add(shgrp, geom, ob); \
+ DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \
} \
} \
} while (0)
-#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) do { \
+#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, ma, geom, oedata) do { \
if (shgrp) { \
- ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \
+ ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata); \
} \
} while (0)
@@ -1498,95 +1498,97 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
*/
bool use_volume_material = (gpumat_array[0] && GPU_material_use_domain_volume(gpumat_array[0]));
- /* Get per-material split surface */
- char *auto_layer_names;
- int *auto_layer_is_srgb;
- int auto_layer_count;
- struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
- ob, gpumat_array, materials_len,
- &auto_layer_names,
- &auto_layer_is_srgb,
- &auto_layer_count);
- if (mat_geom) {
- for (int i = 0; i < materials_len; ++i) {
- if (mat_geom[i] == NULL) {
- continue;
- }
- EEVEE_ObjectEngineData *oedata = NULL;
- Material *ma = give_current_material(ob, i + 1);
-
- if (ma == NULL)
- ma = &defmaterial;
-
- /* Do not render surface if we are rendering a volume object
- * and do not have a surface closure. */
- if (use_volume_material &&
- (gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i])))
- {
- continue;
- }
+ if (ob->dt >= OB_SOLID) {
+ /* Get per-material split surface */
+ char *auto_layer_names;
+ int *auto_layer_is_srgb;
+ int auto_layer_count;
+ struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len,
+ &auto_layer_names,
+ &auto_layer_is_srgb,
+ &auto_layer_count);
+ if (mat_geom) {
+ for (int i = 0; i < materials_len; ++i) {
+ if (mat_geom[i] == NULL) {
+ continue;
+ }
+ EEVEE_ObjectEngineData *oedata = NULL;
+ Material *ma = give_current_material(ob, i + 1);
+
+ if (ma == NULL)
+ ma = &defmaterial;
+
+ /* Do not render surface if we are rendering a volume object
+ * and do not have a surface closure. */
+ if (use_volume_material &&
+ (gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i])))
+ {
+ continue;
+ }
- /* XXX TODO rewrite this to include the dupli objects.
- * This means we cannot exclude dupli objects from reflections!!! */
- if ((ob->base_flag & BASE_FROMDUPLI) == 0) {
- oedata = EEVEE_object_data_ensure(ob);
- oedata->ob = ob;
- oedata->test_data = &sldata->probes->vis_data;
- }
+ /* XXX TODO rewrite this to include the dupli objects.
+ * This means we cannot exclude dupli objects from reflections!!! */
+ if ((ob->base_flag & BASE_FROMDUPLI) == 0) {
+ oedata = EEVEE_object_data_ensure(ob);
+ oedata->ob = ob;
+ oedata->test_data = &sldata->probes->vis_data;
+ }
- /* Shading pass */
- ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata);
+ /* Shading pass */
+ ADD_SHGROUP_CALL(shgrp_array[i], ob, ma, mat_geom[i], oedata);
- /* Depth Prepass */
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
+ /* Depth Prepass */
+ ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, ma, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, ma, mat_geom[i], oedata);
- char *name = auto_layer_names;
- for (int j = 0; j < auto_layer_count; ++j) {
- /* TODO don't add these uniform when not needed (default pass shaders). */
- if (shgrp_array[i]) {
- DRW_shgroup_uniform_bool(shgrp_array[i], name, &auto_layer_is_srgb[j], 1);
- }
- if (shgrp_depth_array[i]) {
- DRW_shgroup_uniform_bool(shgrp_depth_array[i], name, &auto_layer_is_srgb[j], 1);
- }
- if (shgrp_depth_clip_array[i]) {
- DRW_shgroup_uniform_bool(shgrp_depth_clip_array[i], name, &auto_layer_is_srgb[j], 1);
+ char *name = auto_layer_names;
+ for (int j = 0; j < auto_layer_count; ++j) {
+ /* TODO don't add these uniform when not needed (default pass shaders). */
+ if (shgrp_array[i]) {
+ DRW_shgroup_uniform_bool(shgrp_array[i], name, &auto_layer_is_srgb[j], 1);
+ }
+ if (shgrp_depth_array[i]) {
+ DRW_shgroup_uniform_bool(shgrp_depth_array[i], name, &auto_layer_is_srgb[j], 1);
+ }
+ if (shgrp_depth_clip_array[i]) {
+ DRW_shgroup_uniform_bool(shgrp_depth_clip_array[i], name, &auto_layer_is_srgb[j], 1);
+ }
+ /* Go to next layer name. */
+ while (*name != '\0') { name++; }
+ name += 1;
}
- /* Go to next layer name. */
- while (*name != '\0') { name++; }
- name += 1;
- }
- /* Shadow Pass */
- if (ma->use_nodes && ma->nodetree && (ma->blend_method != MA_BM_SOLID)) {
- struct GPUMaterial *gpumat;
- switch (ma->blend_shadow) {
- case MA_BS_SOLID:
- EEVEE_lights_cache_shcaster_add(
- sldata, stl, mat_geom[i], ob);
- *cast_shadow = true;
- break;
- case MA_BS_CLIP:
- gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
- EEVEE_lights_cache_shcaster_material_add(
- sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold);
- *cast_shadow = true;
- break;
- case MA_BS_HASHED:
- gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true);
- EEVEE_lights_cache_shcaster_material_add(
- sldata, psl, gpumat, mat_geom[i], ob, NULL);
- *cast_shadow = true;
- break;
- case MA_BS_NONE:
- default:
- break;
+ /* Shadow Pass */
+ if (ma->use_nodes && ma->nodetree && (ma->blend_method != MA_BM_SOLID)) {
+ struct GPUMaterial *gpumat;
+ switch (ma->blend_shadow) {
+ case MA_BS_SOLID:
+ EEVEE_lights_cache_shcaster_add(
+ sldata, stl, mat_geom[i], ob);
+ *cast_shadow = true;
+ break;
+ case MA_BS_CLIP:
+ gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
+ EEVEE_lights_cache_shcaster_material_add(
+ sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold);
+ *cast_shadow = true;
+ break;
+ case MA_BS_HASHED:
+ gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true);
+ EEVEE_lights_cache_shcaster_material_add(
+ sldata, psl, gpumat, mat_geom[i], ob, NULL);
+ *cast_shadow = true;
+ break;
+ case MA_BS_NONE:
+ default:
+ break;
+ }
+ }
+ else {
+ EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
+ *cast_shadow = true;
}
- }
- else {
- EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
- *cast_shadow = true;
}
}
}
@@ -1617,7 +1619,7 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata,
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 80d8c066a44..e24142e3f71 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -163,7 +163,7 @@ void EEVEE_render_cache(
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
- if (DRW_check_object_visible_within_active_context(ob)) {
+ if (DRW_object_is_visible_in_active_context(ob)) {
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}
@@ -191,6 +191,12 @@ static void eevee_render_result_combined(
rect->xmin, rect->ymin,
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
4, 0, rp->rect);
+
+ /* Premult alpha */
+ int pixels_len = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
+ for (int i = 0; i < pixels_len * 4; i += 4) {
+ mul_v3_fl(rp->rect + i, rp->rect[i + 3]);
+ }
}
static void eevee_render_result_subsurface(
@@ -543,6 +549,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Post Process */
EEVEE_draw_effects(sldata, vedata);
+ /* XXX Seems to fix TDR issue with NVidia drivers on linux. */
+ glFinish();
+
RE_engine_update_progress(engine, (float)(render_samples++) / (float)tot_sample);
}
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 256838609a6..4fffa3f285c 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -46,6 +46,7 @@
#include "eevee_private.h"
#include "GPU_draw.h"
#include "GPU_texture.h"
+#include "GPU_material.h"
static struct {
char *volumetric_common_lib;
@@ -471,13 +472,13 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
- DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
-
/* If shader failed to compile or is currently compiling. */
- if (grp == NULL) {
+ if (GPU_material_status(mat) != GPU_MAT_SUCCESS) {
return;
}
+ DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
+
/* Making sure it's updated. */
invert_m4_m4(ob->imat, ob->obmat);
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
index 5f641c5d490..36c4562e137 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
@@ -75,10 +75,11 @@ vec3 light_volume(LightData ld, vec4 l_vector)
}
else if (ld.l_type == SUN) {
power = (4.0f * ld.l_radius * ld.l_radius * M_2PI) * (1.0 / 12.5); /* Removing area light power*/
- power *= M_2PI * 0.78; /* Matching cycles with point light. */
+ power *= M_PI * 0.5; /* Matching cycles. */
}
else {
power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 /10.0);
+ power *= M_2PI; /* Matching cycles with point light. */
}
/* OPTI: find a better way than calculating this on the fly */
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 40245810f42..8e7d16e60ba 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -414,7 +414,7 @@ GPUBatch *DRW_gpencil_get_fill_geom(Object *ob, bGPDstroke *gps, const float col
/* Calculate triangles cache for filling area (must be done only after changes) */
if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
- DRW_gpencil_triangulate_stroke_fill(gps);
+ DRW_gpencil_triangulate_stroke_fill(ob, gps);
ED_gpencil_calc_stroke_uv(ob, gps);
}
@@ -703,6 +703,7 @@ GPUBatch *DRW_gpencil_get_grid(Object *ob)
const float grid_h = gpd->grid.scale[1] * ED_scene_grid_scale(scene, &grid_unit);
const float space_w = (grid_w / gridlines);
const float space_h = (grid_h / gridlines);
+ const float offset[2] = { gpd->grid.offset[0], gpd->grid.offset[1] };
const uint vertex_len = 2 * (gridlines * 4 + 2);
@@ -722,34 +723,34 @@ GPUBatch *DRW_gpencil_get_grid(Object *ob)
const float line_w = a * space_w;
const float line_h = a * space_h;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w, -line_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], -line_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w, -line_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], -line_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w, +line_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], +line_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w, +line_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], +line_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w, -grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], -grid_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w, +grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], +grid_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w, -grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], -grid_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w, +grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], +grid_h + offset[1], axis);
idx++;
}
/* center lines */
if (do_center) {
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w, 0.0f, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], 0.0f + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w, 0.0f, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], 0.0f + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f, -grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], -grid_h + offset[1], axis);
idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f, +grid_h, axis);
+ set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], +grid_h + offset[1], axis);
idx++;
}
return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index f7823a2fced..03a6f7342ab 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -92,7 +92,7 @@ static bool gpencil_can_draw_stroke(
/* calc bounding box in 2d using flat projection data */
static void gpencil_calc_2d_bounding_box(
- const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], bool expand)
+ const float(*points2d)[2], int totpoints, float minv[2], float maxv[2])
{
minv[0] = points2d[0][0];
minv[1] = points2d[0][1];
@@ -115,14 +115,12 @@ static void gpencil_calc_2d_bounding_box(
maxv[1] = points2d[i][1];
}
}
- /* If not expanded, use a perfect square */
- if (expand == false) {
- if (maxv[0] > maxv[1]) {
- maxv[1] = maxv[0];
- }
- else {
- maxv[0] = maxv[1];
- }
+ /* use a perfect square */
+ if (maxv[0] > maxv[1]) {
+ maxv[1] = maxv[0];
+ }
+ else {
+ maxv[0] = maxv[1];
}
}
@@ -184,10 +182,12 @@ static void gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, floa
}
/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
-void DRW_gpencil_triangulate_stroke_fill(bGPDstroke *gps)
+void DRW_gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps)
{
BLI_assert(gps->totpoints >= 3);
+ bGPdata *gpd = (bGPdata *)ob->data;
+
/* allocate memory for temporary areas */
gps->tot_triangles = gps->totpoints - 2;
uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
@@ -204,7 +204,14 @@ void DRW_gpencil_triangulate_stroke_fill(bGPDstroke *gps)
float minv[2];
float maxv[2];
/* first needs bounding box data */
- gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv, false);
+ if (gpd->flag & GP_DATA_UV_ADAPTATIVE) {
+ gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv);
+ }
+ else {
+ ARRAY_SET_ITEMS(minv, -1.0f, -1.0f);
+ ARRAY_SET_ITEMS(maxv, 1.0f, 1.0f);
+ }
+
/* calc uv data */
gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv);
@@ -256,7 +263,7 @@ static void DRW_gpencil_recalc_geometry_caches(Object *ob, MaterialGPencilStyle
if ((gps->totpoints > 2) &&
((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)))
{
- DRW_gpencil_triangulate_stroke_fill(gps);
+ DRW_gpencil_triangulate_stroke_fill(ob, gps);
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 0b318bd974e..d854336cfd0 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -549,7 +549,7 @@ static void gpencil_add_draw_data(void *vedata, Object *ob)
void GPENCIL_cache_populate(void *vedata, Object *ob)
{
/* object must be visible */
- if (!DRW_check_object_visible_within_active_context(ob)) {
+ if (!DRW_object_is_visible_in_active_context(ob)) {
return;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index df051f4697b..b8844d3c3e9 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -73,6 +73,7 @@ typedef struct tGPencilObjectCache {
DRWShadingGroup *fx_pixel_sh;
DRWShadingGroup *fx_rim_sh;
DRWShadingGroup *fx_shadow_sh;
+ DRWShadingGroup *fx_glow_sh;
DRWShadingGroup *fx_swirl_sh;
DRWShadingGroup *fx_flip_sh;
DRWShadingGroup *fx_light_sh;
@@ -231,6 +232,8 @@ typedef struct GPENCIL_e_data {
struct GPUShader *gpencil_fx_blur_sh;
struct GPUShader *gpencil_fx_colorize_sh;
struct GPUShader *gpencil_fx_flip_sh;
+ struct GPUShader *gpencil_fx_glow_prepare_sh;
+ struct GPUShader *gpencil_fx_glow_resolve_sh;
struct GPUShader *gpencil_fx_light_sh;
struct GPUShader *gpencil_fx_pixel_sh;
struct GPUShader *gpencil_fx_rim_prepare_sh;
@@ -303,7 +306,7 @@ void DRW_gpencil_populate_buffer_strokes(
void DRW_gpencil_populate_multiedit(
struct GPENCIL_e_data *e_data, void *vedata,
struct Scene *scene, struct Object *ob, struct tGPencilObjectCache *cache_ob);
-void DRW_gpencil_triangulate_stroke_fill(struct bGPDstroke *gps);
+void DRW_gpencil_triangulate_stroke_fill(struct Object *ob, struct bGPDstroke *gps);
void DRW_gpencil_multisample_ensure(struct GPENCIL_Data *vedata, int rect_w, int rect_h);
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 41f0c601a13..8dc15472a20 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -130,7 +130,7 @@ static void GPENCIL_render_cache(
void *vedata, struct Object *ob,
struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
{
- if ((ob == NULL) || (DRW_check_object_visible_within_active_context(ob) == false)) {
+ if ((ob == NULL) || (DRW_object_is_visible_in_active_context(ob) == false)) {
return;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 9e04365fe1d..2165fb251dc 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -50,6 +50,8 @@ extern char datatoc_gpencil_fx_rim_prepare_frag_glsl[];
extern char datatoc_gpencil_fx_rim_resolve_frag_glsl[];
extern char datatoc_gpencil_fx_shadow_prepare_frag_glsl[];
extern char datatoc_gpencil_fx_shadow_resolve_frag_glsl[];
+extern char datatoc_gpencil_fx_glow_prepare_frag_glsl[];
+extern char datatoc_gpencil_fx_glow_resolve_frag_glsl[];
extern char datatoc_gpencil_fx_swirl_frag_glsl[];
extern char datatoc_gpencil_fx_wave_frag_glsl[];
@@ -208,7 +210,7 @@ static void DRW_gpencil_fx_blur(
}
}
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(
e_data->gpencil_fx_blur_sh,
@@ -236,7 +238,7 @@ static void DRW_gpencil_fx_colorize(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
@@ -269,7 +271,7 @@ static void DRW_gpencil_fx_flip(
fxd->flipmode += 1;
}
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
@@ -298,7 +300,7 @@ static void DRW_gpencil_fx_light(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
@@ -351,7 +353,7 @@ static void DRW_gpencil_fx_pixel(
fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
@@ -380,7 +382,7 @@ static void DRW_gpencil_fx_rim(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
/* prepare pass */
fx_shgrp = DRW_shgroup_create(
e_data->gpencil_fx_rim_prepare_sh,
@@ -431,8 +433,8 @@ static void DRW_gpencil_fx_rim(
/* Shadow FX */
static void DRW_gpencil_fx_shadow(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+ ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
if (fx == NULL) {
return;
@@ -446,7 +448,7 @@ static void DRW_gpencil_fx_shadow(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
/* prepare pass */
fx_shgrp = DRW_shgroup_create(
e_data->gpencil_fx_shadow_prepare_sh,
@@ -512,10 +514,71 @@ static void DRW_gpencil_fx_shadow(
fxd->runtime.fx_sh_c = fx_shgrp;
}
+/* Glow FX */
+static void DRW_gpencil_fx_glow(
+ ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
+{
+ if (fx == NULL) {
+ return;
+ }
+ GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ /* prepare pass */
+ fx_shgrp = DRW_shgroup_create(
+ e_data->gpencil_fx_glow_prepare_sh,
+ psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "glow_color", &fxd->glow_color[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "select_color", &fxd->select_color[0], 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "threshold", &fxd->threshold, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
+
+ /* blur pass */
+ fx_shgrp = DRW_shgroup_create(
+ e_data->gpencil_fx_blur_sh,
+ psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
+ DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
+
+ fxd->runtime.fx_sh_b = fx_shgrp;
+
+ /* resolve pass */
+ fx_shgrp = DRW_shgroup_create(
+ e_data->gpencil_fx_glow_resolve_sh,
+ psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowDepth", &e_data->temp_depth_tx_fx);
+
+ /* reuse field */
+ DRW_shgroup_uniform_int(fx_shgrp, "alpha_mode", &fxd->blur[1], 1);
+
+ fxd->runtime.fx_sh_c = fx_shgrp;
+}
+
/* Swirl FX */
static void DRW_gpencil_fx_swirl(
ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+ tGPencilObjectCache *cache)
{
if (fx == NULL) {
return;
@@ -531,7 +594,7 @@ static void DRW_gpencil_fx_swirl(
fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
@@ -562,7 +625,7 @@ static void DRW_gpencil_fx_wave(
WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass);
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
@@ -617,6 +680,13 @@ void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data)
e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen(
datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL);
}
+ if (!e_data->gpencil_fx_glow_prepare_sh) {
+ e_data->gpencil_fx_glow_prepare_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_glow_prepare_frag_glsl, NULL);
+
+ e_data->gpencil_fx_glow_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_glow_resolve_frag_glsl, NULL);
+ }
if (!e_data->gpencil_fx_swirl_sh) {
e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen(
datatoc_gpencil_fx_swirl_frag_glsl, NULL);
@@ -639,6 +709,8 @@ void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data)
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh);
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh);
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh);
}
@@ -659,8 +731,8 @@ void GPENCIL_create_fx_passes(GPENCIL_PassList *psl)
/* prepare fx shading groups */
void DRW_gpencil_fx_prepare(
- struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata,
- struct tGPencilObjectCache *cache)
+ GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
int ob_idx = cache->idx;
@@ -693,6 +765,9 @@ void DRW_gpencil_fx_prepare(
case eShaderFxType_Shadow:
DRW_gpencil_fx_shadow(fx, e_data, vedata, cache);
break;
+ case eShaderFxType_Glow:
+ DRW_gpencil_fx_glow(fx, e_data, vedata, cache);
+ break;
case eShaderFxType_Swirl:
DRW_gpencil_fx_swirl(fx, e_data, vedata, cache);
break;
@@ -718,8 +793,7 @@ static void gpencil_draw_fx_pass(
return;
}
- static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
+ const float clearcol[4] = {0.0f};
GPU_framebuffer_bind(fbl->temp_fb_b);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
@@ -743,9 +817,9 @@ static void gpencil_draw_fx_pass(
/* helper to manage gaussian blur passes */
static void draw_gpencil_blur_passes(
- struct GPENCIL_e_data *e_data,
- struct GPENCIL_Data *vedata,
- struct BlurShaderFxData *fxd)
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ BlurShaderFxData *fxd)
{
if (fxd->runtime.fx_sh == NULL) {
return;
@@ -782,19 +856,19 @@ static void draw_gpencil_blur_passes(
}
}
-static void draw_gpencil_rim_blur(
- struct GPENCIL_e_data *UNUSED(e_data),
- struct GPENCIL_Data *vedata,
- struct RimShaderFxData *fxd)
+/* blur intermediate pass */
+static void draw_gpencil_midpass_blur(
+ GPENCIL_Data *vedata,
+ ShaderFxData_Runtime *runtime)
{
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ const float clearcol[4] = {0.0f};
GPU_framebuffer_bind(fbl->temp_fb_b);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
DRW_draw_pass_subset(psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b);
+ runtime->fx_sh_b, runtime->fx_sh_b);
/* copy pass from b for ping-pong frame buffers */
GPU_framebuffer_bind(fbl->temp_fb_fx);
@@ -802,11 +876,40 @@ static void draw_gpencil_rim_blur(
DRW_draw_pass(psl->mix_pass_noblend);
}
+/* do blur of mid passes */
+static void draw_gpencil_do_blur(
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ ShaderFxData_Runtime *runtime,
+ int samples, int bx, int by, int blur[2])
+{
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ if ((samples > 0) && ((bx > 0) || (by > 0))) {
+ for (int x = 0; x < samples * 4; x++) {
+
+ /* horizontal */
+ blur[0] = bx;
+ blur[1] = 0;
+ draw_gpencil_midpass_blur(vedata, runtime);
+
+ /* Vertical */
+ blur[0] = 0;
+ blur[1] = by;
+ draw_gpencil_midpass_blur(vedata, runtime);
+
+ blur[0] = bx;
+ blur[1] = by;
+ }
+ }
+}
+
/* helper to draw RIM passes */
static void draw_gpencil_rim_passes(
- struct GPENCIL_e_data *e_data,
- struct GPENCIL_Data *vedata,
- struct RimShaderFxData *fxd)
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ RimShaderFxData *fxd)
{
if (fxd->runtime.fx_sh_b == NULL) {
return;
@@ -815,9 +918,7 @@ static void draw_gpencil_rim_passes(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- int bx = fxd->blur[0];
- int by = fxd->blur[1];
+ const float clearcol[4] = {0.0f};
/* prepare mask */
GPU_framebuffer_bind(fbl->temp_fb_fx);
@@ -827,26 +928,11 @@ static void draw_gpencil_rim_passes(
fxd->runtime.fx_sh, fxd->runtime.fx_sh);
/* blur rim */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- if ((fxd->samples > 0) && ((bx > 0) || (by > 0))) {
- for (int x = 0; x < fxd->samples; x++) {
-
- /* horizontal */
- fxd->blur[0] = bx;
- fxd->blur[1] = 0;
- draw_gpencil_rim_blur(e_data, vedata, fxd);
-
- /* Vertical */
- fxd->blur[0] = 0;
- fxd->blur[1] = by;
- draw_gpencil_rim_blur(e_data, vedata, fxd);
-
- fxd->blur[0] = bx;
- fxd->blur[1] = by;
- }
- }
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime,
+ fxd->samples,
+ fxd->blur[0], fxd->blur[1],
+ &fxd->blur[0]);
/* resolve */
GPU_framebuffer_bind(fbl->temp_fb_b);
@@ -864,32 +950,55 @@ static void draw_gpencil_rim_passes(
DRW_draw_pass(psl->mix_pass_noblend);
}
-/* blur shadow */
-static void draw_gpencil_shadow_blur(
- struct GPENCIL_e_data *UNUSED(e_data),
- struct GPENCIL_Data *vedata,
- struct ShadowShaderFxData *fxd)
+/* helper to draw SHADOW passes */
+static void draw_gpencil_shadow_passes(
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ ShadowShaderFxData *fxd)
{
+ if (fxd->runtime.fx_sh_b == NULL) {
+ return;
+ }
+
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ const float clearcol[4] = {0.0f};
+
+ /* prepare shadow */
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ DRW_draw_pass_subset(
+ psl->fx_shader_pass_blend,
+ fxd->runtime.fx_sh, fxd->runtime.fx_sh);
+
+ /* blur shadow */
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime,
+ fxd->samples,
+ fxd->blur[0], fxd->blur[1],
+ &fxd->blur[0]);
+ /* resolve */
GPU_framebuffer_bind(fbl->temp_fb_b);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
- DRW_draw_pass_subset(psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b);
+ DRW_draw_pass_subset(
+ psl->fx_shader_pass_blend,
+ fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
- /* copy pass from b for ping-pong frame buffers */
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ /* copy pass from b to a for ping-pong frame buffers */
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
DRW_draw_pass(psl->mix_pass_noblend);
}
-/* helper to draw SHADOW passes */
-static void draw_gpencil_shadow_passes(
- struct GPENCIL_e_data *e_data,
- struct GPENCIL_Data *vedata,
- struct ShadowShaderFxData *fxd)
+/* helper to draw GLOW passes */
+static void draw_gpencil_glow_passes(
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ GlowShaderFxData *fxd)
{
if (fxd->runtime.fx_sh_b == NULL) {
return;
@@ -898,42 +1007,29 @@ static void draw_gpencil_shadow_passes(
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- int bx = fxd->blur[0];
- int by = fxd->blur[1];
+ const float clearcol[4] = {0.0f};
- /* prepare shadow */
+ /* prepare glow */
GPU_framebuffer_bind(fbl->temp_fb_fx);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
DRW_draw_pass_subset(
psl->fx_shader_pass_blend,
fxd->runtime.fx_sh, fxd->runtime.fx_sh);
- /* blur shadow */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- if ((fxd->samples > 0) && ((bx > 0) || (by > 0))) {
- for (int x = 0; x < fxd->samples; x++) {
-
- /* horizontal */
- fxd->blur[0] = bx;
- fxd->blur[1] = 0;
- draw_gpencil_shadow_blur(e_data, vedata, fxd);
-
- /* Vertical */
- fxd->blur[0] = 0;
- fxd->blur[1] = by;
- draw_gpencil_shadow_blur(e_data, vedata, fxd);
-
- fxd->blur[0] = bx;
- fxd->blur[1] = by;
- }
- }
+ /* blur glow */
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime,
+ fxd->samples,
+ fxd->blur[0], fxd->blur[0],
+ &fxd->blur[0]);
/* resolve */
GPU_framebuffer_bind(fbl->temp_fb_b);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+
+ /* reuses blur field to keep alpha mode */
+ fxd->blur[1] = (fxd->flag & FX_GLOW_USE_ALPHA) ? 1 : 0;
+
DRW_draw_pass_subset(
psl->fx_shader_pass_blend,
fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
@@ -949,8 +1045,8 @@ static void draw_gpencil_shadow_passes(
/* apply all object fx effects */
void DRW_gpencil_fx_draw(
- struct GPENCIL_e_data *e_data,
- struct GPENCIL_Data *vedata, struct tGPencilObjectCache *cache)
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata, tGPencilObjectCache *cache)
{
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
@@ -1003,6 +1099,12 @@ void DRW_gpencil_fx_draw(
draw_gpencil_shadow_passes(e_data, vedata, fxd);
break;
}
+ case eShaderFxType_Glow:
+ {
+ GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
+ draw_gpencil_glow_passes(e_data, vedata, fxd);
+ break;
+ }
case eShaderFxType_Swirl:
{
SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
index c2bf1dbc1a7..c8bc5e1fe91 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
@@ -56,4 +56,7 @@ void main()
outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
FragColor = clamp(outcolor, 0, 1.0);
+
+ if (outcolor.a < 0.02f)
+ discard;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
new file mode 100644
index 00000000000..237cdf15627
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
@@ -0,0 +1,68 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+/* ******************************************************************* */
+/* create glow mask */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform vec3 glow_color;
+uniform vec3 select_color;
+uniform float threshold;
+uniform int mode;
+
+out vec4 FragColor;
+
+#define MODE_LUMINANCE 0
+#define MODE_COLOR 1
+
+/* calc luminance */
+float luma( vec3 color ) {
+ /* the color is linear, so do not apply tonemapping */
+ return (color.r + color.g + color.b) / 3.0;
+}
+
+bool check_color(vec3 color_a, vec3 color_b)
+{
+ /* need round the number to avoid precision errors */
+ if ((floor(color_a.r * 100) == floor(color_b.r * 100)) &&
+ (floor(color_a.g * 100) == floor(color_b.g * 100)) &&
+ (floor(color_a.b * 100) == floor(color_b.b * 100)))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void main()
+{
+ vec2 uv = vec2(gl_FragCoord.xy);
+
+ float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
+ vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0);
+ vec4 outcolor;
+
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+
+ if (mode == MODE_LUMINANCE) {
+ if (luma(src_pixel.rgb) < threshold) {
+ discard;
+ }
+ }
+ else if (mode == MODE_COLOR) {
+ if (!check_color(src_pixel.rgb, select_color.rgb)) {
+ discard;
+ }
+ }
+ else {
+ discard;
+ }
+
+ gl_FragDepth = stroke_depth;
+ FragColor = vec4(glow_color.rgb, 1.0);
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
new file mode 100644
index 00000000000..010c4ef4a88
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
@@ -0,0 +1,46 @@
+/* ******************************************************************* */
+/* Resolve GLOW pass */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform sampler2D glowColor;
+uniform sampler2D glowDepth;
+uniform int alpha_mode;
+
+out vec4 FragColor;
+
+void main()
+{
+ vec4 outcolor;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
+ vec4 glow_pixel= texelFetch(glowColor, uv.xy, 0);
+ float glow_depth = texelFetch(glowDepth, uv.xy, 0).r;
+
+ if (alpha_mode == 0) {
+ outcolor = src_pixel + glow_pixel;
+ }
+ else {
+ if ((src_pixel.a < 0.1) || (glow_pixel.a < 0.1)) {
+ outcolor = src_pixel + glow_pixel;
+ }
+ else {
+ outcolor = src_pixel;
+ }
+ }
+
+ if (src_pixel.a < glow_pixel.a) {
+ gl_FragDepth = glow_depth;
+ }
+ else {
+ gl_FragDepth = stroke_depth;
+ }
+
+ if (outcolor.a < 0.001) {
+ discard;
+ }
+
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
index 882b2cf59f1..df5248c7791 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
@@ -37,4 +37,7 @@ void main()
FragColor = outcolor;
gl_FragDepth = stroke_depth;
+
+ if (outcolor.a < 0.02f)
+ discard;
}
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 1f14e506dcf..5b949a6d952 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -3,9 +3,15 @@ uniform mat4 ProjectionMatrix;
uniform mat4 ModelMatrixInverse;
uniform mat4 ModelViewMatrixInverse;
uniform mat4 ModelMatrix;
+uniform vec3 OrcoTexCoFactors[2];
uniform sampler2D depthBuffer;
+
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. */
@@ -62,15 +68,35 @@ float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
{
- scattering = vec3(0.0);
- extinction = 1e-8;
+ 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 */
+
+ scattering = density.rgb * density.a * densityScale;
+ extinction = max(1e-4, dot(scattering, vec3(0.33333)));
- vec4 density = texture(densityTexture, ls_pos * 0.5 + 0.5);
- density.rgb /= density.a;
- density *= densityScale;
+ 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.0;
+#endif
+}
- scattering = density.rgb;
- extinction = max(1e-8, density.a);
+void eval_volume_step(inout vec3 Lscat, float extinction, float step_len, out float Tr)
+{
+ Lscat *= phase_function_isotropic();
+ /* Evaluate Scattering */
+ Tr = exp(-extinction * step_len);
+ /* integrate along the current step segment */
+ Lscat = (Lscat - Lscat * Tr) / extinction;
}
#define P(x) ((x + 0.5) * (1.0 / 16.0))
@@ -96,18 +122,15 @@ vec4 volume_integration(
vec3 ls_pos = ray_ori + ray_dir * ray_len;
vec3 Lscat;
- float s_extinction;
+ float s_extinction, Tr;
volume_properties(ls_pos, Lscat, s_extinction);
- /* Evaluate Scattering */
- float Tr = exp(-s_extinction * step_len);
- /* integrate along the current step segment */
- Lscat = (Lscat - Lscat * Tr) / s_extinction;
+ eval_volume_step(Lscat, s_extinction, step_len, Tr);
/* accumulate and also take into account the transmittance from previous steps */
final_scattering += final_transmittance * Lscat;
final_transmittance *= Tr;
}
- return vec4(final_scattering, 1.0 - final_transmittance);
+ return vec4(final_scattering, final_transmittance);
}
void main()
@@ -134,15 +157,11 @@ void main()
step_len = 1.0 / step_len;
vec3 Lscat;
- float s_extinction;
+ float s_extinction, Tr;
volume_properties(localPos, Lscat, s_extinction);
- /* Evaluate Scattering */
- float Tr = exp(-s_extinction * step_len);
- /* integrate along the current step segment */
- Lscat = (Lscat - Lscat * Tr) / s_extinction;
-
- fragColor = vec4(Lscat, 1.0 - Tr);
+ eval_volume_step(Lscat, s_extinction, step_len, Tr);
+ fragColor = vec4(Lscat, Tr);
#else
vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy);
bool is_persp = ProjectionMatrix[3][3] == 0.0;
@@ -156,10 +175,13 @@ void main()
vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
vs_ray_dir /= abs(vs_ray_dir.z);
- vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir;
+ vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz;
vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz;
+ ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0;
+ ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0;
+
/* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
index 90a22d9d02f..7ce21c3d5ca 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -1,5 +1,6 @@
uniform mat4 ModelViewProjectionMatrix;
+uniform vec3 OrcoTexCoFactors[2];
uniform float slicePosition;
uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
@@ -23,9 +24,10 @@ void main()
else {
localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0);
}
-
- gl_Position = ModelViewProjectionMatrix * vec4(localPos, 1.0);
+ vec3 final_pos = localPos;
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 final_pos = pos;
#endif
+ final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1];
+ gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 7fbe928d29e..a1345afcf11 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -649,7 +649,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
@@ -701,7 +701,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
- if (!DRW_check_object_visible_within_active_context(ob)) {
+ if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
return;
}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 0d4329c9699..cb11864df54 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -420,7 +420,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
@@ -487,7 +487,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
- if (!DRW_check_object_visible_within_active_context(ob)) {
+ if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
return;
}
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index ea4152486af..b0c08a2dc28 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -35,7 +35,11 @@
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};
extern char datatoc_workbench_volume_vert_glsl[];
@@ -47,21 +51,39 @@ 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);
+ e_data.dummy_coba_tex = GPU_texture_create_1D(1, GPU_RGBA8, pixel, NULL);
}
}
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);
}
void workbench_volume_cache_init(WORKBENCH_Data *vedata)
{
- vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | DRW_STATE_CULL_FRONT);
+ vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSMISSION | DRW_STATE_CULL_FRONT);
}
void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, ModifierData *md)
@@ -70,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) {
@@ -77,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);
@@ -99,41 +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_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 Flame rendering */
- /* 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_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 Flame rendering */
- /* 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)