diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-05-31 02:45:41 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-09-13 18:32:18 +0300 |
commit | ce34a6b0d727bbde6ae373afa8ec6c42bc8980ce (patch) | |
tree | f8cc84f7e2038f2a81ac0141d79205f1df649e4e /source/blender/draw/engines | |
parent | f7e8b580989ec70d1cf8f15a11d4f09e6b36f407 (diff) |
DRW: Refactor to support draw call batching
Reviewers: brecht
Differential Revision: D4997
Diffstat (limited to 'source/blender/draw/engines')
20 files changed, 254 insertions, 274 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 712bcc43f52..2158d395d84 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -48,6 +48,9 @@ static struct { char *frag_shader_lib; char *vert_shader_str; char *vert_shadow_shader_str; + char *vert_background_shader_str; + char *vert_volume_shader_str; + char *geom_volume_shader_str; char *volume_shader_lib; struct GPUShader *default_prepass_sh; @@ -565,6 +568,15 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, e_data.vert_shadow_shader_str = BLI_string_joinN( datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl); + e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, + datatoc_background_vert_glsl); + + e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, + datatoc_volumetric_vert_glsl); + + e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, + datatoc_volumetric_geom_glsl); + e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, @@ -637,7 +649,7 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor wo, engine, options, - datatoc_background_vert_glsl, + e_data.vert_background_shader_str, NULL, e_data.frag_shader_lib, SHADER_DEFINES "#define PROBE_CAPTURE\n", @@ -657,7 +669,7 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor wo, engine, options, - datatoc_background_vert_glsl, + e_data.vert_background_shader_str, NULL, e_data.frag_shader_lib, SHADER_DEFINES "#define WORLD_BACKGROUND\n", @@ -680,8 +692,8 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World * wo, engine, options, - datatoc_volumetric_vert_glsl, - datatoc_volumetric_geom_glsl, + e_data.vert_volume_shader_str, + e_data.geom_volume_shader_str, e_data.volume_shader_lib, defines, true); @@ -741,8 +753,8 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material ma, engine, options, - datatoc_volumetric_vert_glsl, - datatoc_volumetric_geom_glsl, + e_data.vert_volume_shader_str, + e_data.geom_volume_shader_str, e_data.volume_shader_lib, defines, true); @@ -1338,6 +1350,24 @@ static void material_transparent(Material *ma, const float *spec_p = &ma->spec; const float *rough_p = &ma->roughness; + const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0); + + DRWState cur_state; + DRWState all_state = (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK | + DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL | + DRW_STATE_BLEND_CUSTOM); + + /* Depth prepass */ + if (use_prepass) { + *shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass); + + cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; + cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0; + + DRW_shgroup_state_disable(*shgrp_depth, all_state); + DRW_shgroup_state_enable(*shgrp_depth, cur_state); + } + if (ma->use_nodes && ma->nodetree) { static float error_col[3] = {1.0f, 0.0f, 1.0f}; static float compile_col[3] = {0.5f, 0.5f, 0.5f}; @@ -1394,30 +1424,13 @@ static void material_transparent(Material *ma, DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1); } - const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0); - - DRWState all_state = (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK | - DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL | - DRW_STATE_BLEND_CUSTOM); - - DRWState cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM; + cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM; cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL; cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0; /* Disable other blend modes and use the one we want. */ DRW_shgroup_state_disable(*shgrp, all_state); DRW_shgroup_state_enable(*shgrp, cur_state); - - /* Depth prepass */ - if (use_prepass) { - *shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass); - - cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; - cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0; - - DRW_shgroup_state_disable(*shgrp_depth, all_state); - DRW_shgroup_state_enable(*shgrp_depth, cur_state); - } } /* Return correct material or &defmaterial if slot is empty. */ @@ -1734,6 +1747,9 @@ void EEVEE_materials_free(void) MEM_SAFE_FREE(e_data.frag_shader_lib); MEM_SAFE_FREE(e_data.vert_shader_str); MEM_SAFE_FREE(e_data.vert_shadow_shader_str); + MEM_SAFE_FREE(e_data.vert_background_shader_str); + MEM_SAFE_FREE(e_data.vert_volume_shader_str); + MEM_SAFE_FREE(e_data.geom_volume_shader_str); MEM_SAFE_FREE(e_data.volume_shader_lib); DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_sh); DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_clip_sh); diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 882f2285296..9cf4a72dc31 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -415,6 +415,7 @@ static DRWShadingGroup *gpencil_shgroup_fill_create(GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob, + float (*obmat)[4], bGPdata *gpd, bGPDlayer *gpl, MaterialGPencilStyle *gp_style, @@ -428,6 +429,8 @@ static DRWShadingGroup *gpencil_shgroup_fill_create(GPENCIL_Data *vedata, /* e_data.gpencil_fill_sh */ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat); + DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1); /* set style type */ @@ -561,6 +564,7 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob, + float (*obmat)[4], bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, @@ -582,6 +586,8 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata, DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat); + /* avoid wrong values */ if ((gpd) && (gpd->pixfactor == 0.0f)) { gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; @@ -724,6 +730,7 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob, + float (*obmat)[4], bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, @@ -744,6 +751,8 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata, DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1); DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat); + /* avoid wrong values */ if ((gpd) && (gpd->pixfactor == 0.0f)) { gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; @@ -1568,6 +1577,9 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s); stl->storage->alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH; + float unit_mat[4][4]; + unit_m4(unit_mat); + /* if only one point, don't need to draw buffer because the user has no time to see it */ if (gpd->runtime.sbuffer_used > 1) { if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) { @@ -1576,6 +1588,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL, + unit_mat, gpd, NULL, NULL, @@ -1600,6 +1613,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, psl->drawing_pass, e_data->gpencil_point_sh, NULL, + unit_mat, gpd, NULL, NULL, @@ -1786,6 +1800,7 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, stroke_pass, e_data->gpencil_stroke_sh, ob, + obmat, gpd, gpl, gps, @@ -1794,23 +1809,26 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, elm->onion, scale, cache_ob->shading_type); - if ((do_onion) || (elm->onion == false)) { - DRW_shgroup_call_range_obmat(shgrp, cache->b_stroke.batch, obmat, start_stroke, len); - } - stl->storage->shgroup_id++; - start_stroke = elm->vertex_idx; /* set stencil mask id */ if (gpencil_is_stencil_required(gp_style)) { + if (stencil_id == 1) { + /* Clear previous stencils. */ + DRW_shgroup_clear_framebuffer(shgrp, GPU_STENCIL_BIT, 0, 0, 0, 0, 0.0f, 0x0); + } DRW_shgroup_stencil_mask(shgrp, stencil_id); stencil_id++; } else { /* Disable stencil for this type */ DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); - /* set stencil mask id as not used */ - DRW_shgroup_stencil_mask(shgrp, 0x0); } + + if ((do_onion) || (elm->onion == false)) { + DRW_shgroup_call_range(shgrp, cache->b_stroke.batch, start_stroke, len); + } + stl->storage->shgroup_id++; + start_stroke = elm->vertex_idx; break; } case eGpencilBatchGroupType_Point: { @@ -1820,6 +1838,7 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, stroke_pass, e_data->gpencil_point_sh, ob, + obmat, gpd, gpl, gps, @@ -1829,16 +1848,14 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, scale, cache_ob->shading_type); + /* Disable stencil for this type */ + DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); + if ((do_onion) || (elm->onion == false)) { - DRW_shgroup_call_range_obmat(shgrp, cache->b_point.batch, obmat, start_point, len); + DRW_shgroup_call_range(shgrp, cache->b_point.batch, start_point, len); } stl->storage->shgroup_id++; start_point = elm->vertex_idx; - - /* Disable stencil for this type */ - DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); - /* set stencil mask id as not used */ - DRW_shgroup_stencil_mask(shgrp, 0x0); break; } case eGpencilBatchGroupType_Fill: { @@ -1848,30 +1865,32 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, stroke_pass, e_data->gpencil_fill_sh, ob, + obmat, gpd, gpl, gp_style, stl->storage->shgroup_id, cache_ob->shading_type); + /* Disable stencil for this type */ + DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); + if ((do_onion) || (elm->onion == false)) { - DRW_shgroup_call_range_obmat(shgrp, cache->b_fill.batch, obmat, start_fill, len); + DRW_shgroup_call_range(shgrp, cache->b_fill.batch, start_fill, len); } stl->storage->shgroup_id++; start_fill = elm->vertex_idx; - - /* Disable stencil for this type */ - DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); - /* set stencil mask id as not used */ - DRW_shgroup_stencil_mask(shgrp, 0x0); break; } case eGpencilBatchGroupType_Edit: { if (stl->g_data->shgrps_edit_point) { const int len = elm->vertex_idx - start_edit; + + shgrp = DRW_shgroup_create_sub(stl->g_data->shgrps_edit_point); + DRW_shgroup_uniform_mat4(shgrp, "gpModelMatrix", obmat); /* use always the same group */ - DRW_shgroup_call_range_obmat( - stl->g_data->shgrps_edit_point, cache->b_edit.batch, obmat, start_edit, len); + DRW_shgroup_call_range( + stl->g_data->shgrps_edit_point, cache->b_edit.batch, start_edit, len); start_edit = elm->vertex_idx; } @@ -1880,9 +1899,12 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data, case eGpencilBatchGroupType_Edlin: { if (stl->g_data->shgrps_edit_line) { const int len = elm->vertex_idx - start_edlin; + + shgrp = DRW_shgroup_create_sub(stl->g_data->shgrps_edit_line); + DRW_shgroup_uniform_mat4(shgrp, "gpModelMatrix", obmat); /* use always the same group */ - DRW_shgroup_call_range_obmat( - stl->g_data->shgrps_edit_line, cache->b_edlin.batch, obmat, start_edlin, len); + DRW_shgroup_call_range( + stl->g_data->shgrps_edit_line, cache->b_edlin.batch, start_edlin, len); start_edlin = elm->vertex_idx; } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 9efae54b376..b2e8cef1db2 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -61,6 +61,8 @@ extern char datatoc_gpencil_edit_point_geom_glsl[]; extern char datatoc_gpencil_edit_point_frag_glsl[]; extern char datatoc_gpencil_blend_frag_glsl[]; +extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; + extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; @@ -221,7 +223,12 @@ static void GPENCIL_create_shaders(void) /* used for edit lines for edit modes */ if (!e_data.gpencil_line_sh) { - e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR); + e_data.gpencil_line_sh = DRW_shader_create_with_lib( + datatoc_gpencil_edit_point_vert_glsl, + NULL, + datatoc_gpu_shader_3D_smooth_color_frag_glsl, + datatoc_common_view_lib_glsl, + NULL); } /* used to filling during drawing */ @@ -279,6 +286,7 @@ static void GPENCIL_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh); DRW_SHADER_FREE_SAFE(e_data.gpencil_point_sh); DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_line_sh); DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh); DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh); DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh); @@ -834,76 +842,13 @@ static void gpencil_draw_pass_range(GPENCIL_FramebufferList *fbl, const bool do_antialiasing = ((!stl->storage->is_mat_preview) && (multi)); - DRWShadingGroup *shgrp = init_shgrp; - DRWShadingGroup *from_shgrp = init_shgrp; - DRWShadingGroup *to_shgrp = init_shgrp; - int stencil_tot = 0; - bool do_last = true; - if (do_antialiasing) { MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl); } - /* Loop all shading groups to separate by stencil groups. */ - while ((shgrp) && (shgrp != end_shgrp)) { - do_last = true; - /* Count number of groups using stencil. */ - if (DRW_shgroup_stencil_mask_get(shgrp) != 0) { - stencil_tot++; - } - - /* Draw stencil group and clear stencil bit. This is required because the number of - * shading groups can be greater than the limit of 255 stencil values. - * Only count as stencil if the shading group has an stencil value assigned. This reduces - * the number of clears because Dots, Fills and some Line strokes don't need stencil. - */ - if (stencil_tot == 255) { - DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : - psl->stroke_pass_2d, - from_shgrp, - to_shgrp); - /* Clear Stencil and prepare for next group. */ - if (do_antialiasing) { - GPU_framebuffer_clear_stencil(fbl->multisample_fb, 0x0); - } - else { - GPU_framebuffer_clear_stencil(fb, 0x0); - } - - /* Set new init group and reset. */ - do_last = false; - - shgrp = DRW_shgroup_get_next(shgrp); - if (shgrp) { - from_shgrp = to_shgrp = shgrp; - stencil_tot = 0; - if (shgrp != end_shgrp) { - continue; - } - else { - do_last = true; - break; - } - } - else { - /* No more groups. */ - break; - } - } - - /* Still below stencil group limit. */ - shgrp = DRW_shgroup_get_next(shgrp); - if (shgrp) { - to_shgrp = shgrp; - } - } - - /* Draw last pending groups. */ - if (do_last) { - DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d, - from_shgrp, - to_shgrp); - } + DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d, + init_shgrp, + end_shgrp); if (do_antialiasing) { MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl); diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 79bcffac512..27d537c9a20 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -390,6 +390,7 @@ struct DRWShadingGroup *gpencil_shgroup_stroke_create(struct GPENCIL_Data *vedat struct DRWPass *pass, struct GPUShader *shader, struct Object *ob, + float (*obmat)[4], struct bGPdata *gpd, struct bGPDlayer *gpl, struct bGPDstroke *gps, diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c index 7ee86bcc392..8ceecbb359d 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.c +++ b/source/blender/draw/engines/gpencil/gpencil_render.c @@ -308,6 +308,9 @@ void GPENCIL_render_to_image(void *vedata, DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, GPENCIL_render_cache); GPENCIL_cache_finish(vedata); + + DRW_render_instance_buffer_finish(); + GPENCIL_draw_scene(vedata); /* combined data */ diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl index a1cfb2ae4ae..f75322f90e2 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl @@ -1,4 +1,6 @@ +uniform mat4 gpModelMatrix; + in vec3 pos; in vec4 color; in float size; @@ -8,7 +10,7 @@ out float finalThickness; void main() { - gl_Position = point_object_to_ndc(pos); + gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz); finalColor = color; finalThickness = size; } diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl index eb452f4c660..263dc570423 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl @@ -1,4 +1,6 @@ +uniform mat4 gpModelMatrix; + in vec3 pos; in vec4 color; in vec2 texCoord; @@ -8,7 +10,7 @@ out vec2 texCoord_interp; void main(void) { - gl_Position = point_object_to_ndc(pos); + gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz); finalColor = color; texCoord_interp = texCoord; } diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl index ef8b361373f..87963c66858 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl @@ -6,6 +6,7 @@ uniform float pixfactor; uniform int viewport_xray; uniform int shading_type[2]; uniform vec4 wire_color; +uniform mat4 gpModelMatrix; in vec3 pos; in vec4 color; @@ -30,8 +31,8 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor); void main() { - gl_Position = point_object_to_ndc(pos); - finalprev_pos = point_object_to_ndc(prev_pos); + gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz); + finalprev_pos = point_world_to_ndc((gpModelMatrix * vec4(prev_pos, 1.0)).xyz); finalColor = color; if (keep_size == TRUE) { diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl index c7089f357f9..582b9a7f249 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl @@ -6,6 +6,7 @@ uniform float pixfactor; uniform int viewport_xray; uniform int shading_type[2]; uniform vec4 wire_color; +uniform mat4 gpModelMatrix; in vec3 pos; in vec4 color; @@ -28,7 +29,7 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor); void main(void) { - gl_Position = point_object_to_ndc(pos); + gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz); finalColor = color; if (keep_size == TRUE) { diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl index 505b4822ad6..abd8c1f6579 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl @@ -1,5 +1,6 @@ -uniform int object_id = 0; + layout(location = 0) out uint objectId; + uniform float ImageTransparencyCutoff = 0.1; #ifdef V3D_SHADING_TEXTURE_COLOR uniform sampler2D image; @@ -10,11 +11,10 @@ in vec2 uv_interp; void main() { #ifdef V3D_SHADING_TEXTURE_COLOR - vec4 diffuse_color = texture(image, uv_interp); - if (diffuse_color.a < ImageTransparencyCutoff) { + if (texture(image, uv_interp).a < ImageTransparencyCutoff) { discard; } #endif - objectId = uint(object_id); + objectId = uint(resource_id + 1) & 0xFFu; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index 3333dfeff38..f799ce41cb2 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -8,8 +8,7 @@ uniform float alpha = 0.5; uniform vec2 invertedViewportSize; uniform vec4 viewvecs[3]; -uniform vec3 materialDiffuseColor; -uniform vec3 materialSpecularColor; +uniform vec4 materialColorAndMetal; uniform float materialRoughness; uniform float shadowMultiplier = 0.5; @@ -42,17 +41,17 @@ layout(location = 1) out void main() { - vec4 diffuse_color; + vec4 base_color; #if defined(V3D_SHADING_TEXTURE_COLOR) - diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); - if (diffuse_color.a < ImageTransparencyCutoff) { + base_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); + if (base_color.a < ImageTransparencyCutoff) { discard; } #elif defined(V3D_SHADING_VERTEX_COLOR) - diffuse_color = vec4(vertexColor, 1.0); + base_color.rgb = vertexColor; #else - diffuse_color = vec4(materialDiffuseColor, 1.0); + base_color.rgb = materialColorAndMetal.rgb; #endif /* V3D_SHADING_TEXTURE_COLOR */ vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; @@ -64,7 +63,7 @@ void main() /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = diffuse_color.rgb; + vec3 shaded_color = base_color.rgb; #elif defined(V3D_LIGHTING_MATCAP) bool flipped = world_data.matcap_orientation != 0; @@ -75,11 +74,20 @@ void main() # else vec3 matcap_specular = vec3(0.0); # endif - vec3 shaded_color = matcap_diffuse * diffuse_color.rgb + matcap_specular; + vec3 shaded_color = matcap_diffuse * base_color.rgb + matcap_specular; #elif defined(V3D_LIGHTING_STUDIO) +# ifdef V3D_SHADING_SPECULAR_HIGHLIGHT + float metallic = materialColorAndMetal.a; + vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic); + vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic); +# else + vec3 specular_color = vec3(0.0); + vec3 diffuse_color = base_color.rgb; +# endif + vec3 shaded_color = get_world_lighting( - world_data, diffuse_color.rgb, materialSpecularColor, materialRoughness, nor, I_vs); + world_data, diffuse_color, specular_color, materialRoughness, nor, I_vs); #endif #ifdef V3D_SHADING_SHADOW diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index c673b2484de..b5f95f2dcf8 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -1,7 +1,5 @@ -uniform int object_id = 0; -uniform vec3 materialDiffuseColor; -uniform float materialMetallic; +uniform vec4 materialColorAndMetal; uniform float materialRoughness; uniform sampler2D image; @@ -48,7 +46,7 @@ void main() # elif defined(V3D_SHADING_VERTEX_COLOR) color.rgb = vertexColor; # else - color.rgb = materialDiffuseColor; + color.rgb = materialColorAndMetal.rgb; # endif # ifdef V3D_LIGHTING_MATCAP @@ -56,7 +54,7 @@ void main() metallic = float(gl_FrontFacing); roughness = 0.0; # else - metallic = materialMetallic; + metallic = materialColorAndMetal.a; roughness = materialRoughness; # endif @@ -64,7 +62,7 @@ void main() /* Add some variation to the hairs to avoid uniform look. */ float hair_variation = hair_rand * 0.1; color = clamp(color - hair_variation, 0.0, 1.0); - metallic = clamp(materialMetallic - hair_variation, 0.0, 1.0); + metallic = clamp(materialColorAndMetal.a - hair_variation, 0.0, 1.0); roughness = clamp(materialRoughness - hair_variation, 0.0, 1.0); # endif @@ -73,7 +71,7 @@ void main() #endif /* MATDATA_PASS_ENABLED */ #ifdef OBJECT_ID_PASS_ENABLED - objectId = uint(object_id); + objectId = uint(resource_id + 1) & 0xFFu; #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl index 7eb12dbdeb9..04dd9ab85bb 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl @@ -25,6 +25,10 @@ out vec2 uv_interp; out vec3 vertexColor; #endif +#ifdef OBJECT_ID_PASS_ENABLED +RESOURCE_ID_VARYING +#endif + /* From http://libnoise.sourceforge.net/noisegen/index.html */ float integer_noise(int n) { @@ -91,12 +95,18 @@ void main() #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED - normal_viewport = normal_object_to_view(nor); # ifndef HAIR_SHADER + normal_viewport = normal_object_to_view(nor); normal_viewport = normalize(normal_viewport); +# else + normal_viewport = normal_world_to_view(nor); # endif #endif +#ifdef OBJECT_ID_PASS_ENABLED + PASS_RESOURCE_ID +#endif + #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_calc_clip_distance(world_pos); #endif 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 4a9b0ae3b7d..c24c335189e 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -1,6 +1,4 @@ -uniform vec3 OrcoTexCoFactors[2]; - uniform sampler2D depthBuffer; uniform sampler3D densityTexture; @@ -216,13 +214,13 @@ void main() vs_ray_dir /= abs(vs_ray_dir.z); /* TODO(fclem) Precompute the matrix/ */ - vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0; + vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1].xyz * 2.0; ls_ray_dir = mat3(ModelMatrixInverse) * ls_ray_dir; vec3 ls_ray_ori = point_view_to_object(vs_ray_ori); vec3 ls_ray_end = point_view_to_object(vs_ray_end); - 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; + ls_ray_ori = (OrcoTexCoFactors[0].xyz + ls_ray_ori * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0; + ls_ray_end = (OrcoTexCoFactors[0].xyz + ls_ray_end * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0; /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */ 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 6f0bb56fafd..3542a1a91fc 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl @@ -1,10 +1,11 @@ -uniform vec3 OrcoTexCoFactors[2]; uniform float slicePosition; uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */ in vec3 pos; +RESOURCE_ID_VARYING + #ifdef VOLUME_SLICE in vec3 uvs; @@ -27,6 +28,8 @@ void main() #else vec3 final_pos = pos; #endif - final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1]; + final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0].xyz) / OrcoTexCoFactors[1].xyz; gl_Position = point_object_to_ndc(final_pos); + + PASS_RESOURCE_ID } diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 262ea7110a4..e41cba1d3bd 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -83,7 +83,6 @@ static struct { struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ SceneDisplay display; /* world light direction for shadows */ - int next_object_id; struct GPUUniformBuffer *sampling_ubo; struct GPUTexture *jitter_tx; @@ -147,6 +146,7 @@ static char *workbench_build_prepass_frag(void) { DynStr *ds = BLI_dynstr_new(); + BLI_dynstr_append(ds, datatoc_common_view_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl); @@ -330,7 +330,6 @@ static struct GPUTexture *create_jitter_texture(int num_samples) static void workbench_init_object_data(DrawData *dd) { WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd; - data->object_id = ((e_data.next_object_id++) & 0xff) + 1; data->shadow_bbox_dirty = true; } @@ -379,11 +378,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) workbench_effect_info_init(stl->effects); } - if (!e_data.next_object_id) { + if (!e_data.shadow_pass_sh) { WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; memset(sh_data->prepass_sh_cache, 0, sizeof(sh_data->prepass_sh_cache)); memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache)); - e_data.next_object_id = 1; #ifdef DEBUG_SHADOW_VOLUME const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl; #else @@ -868,18 +866,11 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_MaterialData *material; - WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure( - &ob->id, - &draw_engine_workbench_solid, - sizeof(WORKBENCH_ObjectData), - &workbench_init_object_data, - NULL); WORKBENCH_MaterialData material_template; const bool is_ghost = (ob->dtx & OB_DRAWXRAY); /* Solid */ workbench_material_update_data(wpd, ob, mat, &material_template, color_type); - material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1; material_template.color_type = color_type; material_template.ima = ima; material_template.iuser = iuser; @@ -899,8 +890,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat shader, (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass); workbench_material_copy(material, &material_template); DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF); - DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1); - workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp); + workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, interp); BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material); } return material; @@ -943,8 +933,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_hair_pass : psl->prepass_hair_pass, shader); DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF); - DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1); - workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, interp); } } } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 1cbc60ef858..890359e8fda 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -63,8 +63,6 @@ static struct { struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */ struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ - - int next_object_id; } e_data = {{{{NULL}}}}; /* Shaders */ @@ -98,6 +96,18 @@ static char *workbench_build_forward_vert(bool is_hair) return str; } +static char *workbench_build_forward_outline_frag(void) +{ + DynStr *ds = BLI_dynstr_new(); + + BLI_dynstr_append(ds, datatoc_common_view_lib_glsl); + BLI_dynstr_append(ds, datatoc_workbench_forward_depth_frag_glsl); + + char *str = BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return str; +} + static char *workbench_build_forward_transparent_accum_frag(void) { DynStr *ds = BLI_dynstr_new(); @@ -129,12 +139,6 @@ static char *workbench_build_forward_composite_frag(void) return str; } -static void workbench_init_object_data(DrawData *dd) -{ - WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd; - data->object_id = ((e_data.next_object_id++) & 0xff) + 1; -} - WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_Data *vedata, Object *ob, Material *mat, @@ -149,18 +153,11 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_ WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_MaterialData *material; - WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure( - &ob->id, - &draw_engine_workbench_solid, - sizeof(WORKBENCH_ObjectData), - &workbench_init_object_data, - NULL); WORKBENCH_MaterialData material_template; DRWShadingGroup *grp; /* Solid */ workbench_material_update_data(wpd, ob, mat, &material_template, color_type); - material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1; material_template.color_type = color_type; material_template.ima = ima; material_template.iuser = iuser; @@ -205,7 +202,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_ DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus); } - workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp); + workbench_material_shgroup_uniform(wpd, grp, material, ob, false, interp); material->shgrp = grp; /* Depth */ @@ -219,8 +216,6 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_ material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_sh, psl->object_outline_pass); } - material->object_id = engine_object_data->object_id; - DRW_shgroup_uniform_int(material->shgrp_object_outline, "object_id", &material->object_id, 1); if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) { DRW_shgroup_state_enable(material->shgrp_object_outline, DRW_STATE_CLIP_PLANES); } @@ -292,26 +287,30 @@ void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUSh char *defines_texture = workbench_material_build_defines(wpd, true, false, false); char *defines_hair = workbench_material_build_defines(wpd, false, true, false); char *forward_vert = workbench_build_forward_vert(false); + char *forward_frag = workbench_build_forward_outline_frag(); char *forward_hair_vert = workbench_build_forward_vert(true); + const char *define_id_pass = "#define OBJECT_ID_PASS_ENABLED\n"; + sh_data->object_outline_sh = GPU_shader_create_from_arrays({ .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL}, - .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines, NULL}, + .frag = (const char *[]){forward_frag, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines, define_id_pass, NULL}, }); sh_data->object_outline_texture_sh = GPU_shader_create_from_arrays({ .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL}, - .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines_texture, NULL}, + .frag = (const char *[]){forward_frag, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines_texture, define_id_pass, NULL}, }); sh_data->object_outline_hair_sh = GPU_shader_create_from_arrays({ .vert = (const char *[]){sh_cfg_data->lib, forward_hair_vert, NULL}, - .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines_hair, NULL}, + .frag = (const char *[]){forward_frag, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines_hair, define_id_pass, NULL}, }); MEM_freeN(forward_hair_vert); MEM_freeN(forward_vert); + MEM_freeN(forward_frag); MEM_freeN(defines); MEM_freeN(defines_texture); MEM_freeN(defines_hair); @@ -527,7 +526,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O DRWShadingGroup *shgrp = DRW_shgroup_hair_create( ob, psys, md, psl->transparent_accum_pass, shader); DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo); - workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, false, interp); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, interp); DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3); /* Hairs have lots of layer and can rapidly become the most prominent surface. * So lower their alpha artificially. */ @@ -551,7 +550,6 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; shgrp = DRW_shgroup_hair_create( ob, psys, md, vedata->psl->object_outline_pass, sh_data->object_outline_hair_sh); - DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1); } } } diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index e050877187e..c90604678db 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -44,20 +44,15 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, WORKBENCH_MaterialData *data, int color_type) { - copy_v3_fl3(data->diffuse_color, 0.8f, 0.8f, 0.8f); - copy_v3_v3(data->base_color, data->diffuse_color); - copy_v3_fl3(data->specular_color, 0.05f, 0.05f, 0.05f); /* Dielectric: 5% reflective. */ data->metallic = 0.0f; data->roughness = 0.632455532f; /* sqrtf(0.4f); */ data->alpha = wpd->shading.xray_alpha; if (color_type == V3D_SHADING_SINGLE_COLOR) { - copy_v3_v3(data->diffuse_color, wpd->shading.single_color); - copy_v3_v3(data->base_color, data->diffuse_color); + copy_v3_v3(data->base_color, wpd->shading.single_color); } else if (color_type == V3D_SHADING_ERROR_COLOR) { - copy_v3_fl3(data->diffuse_color, 0.8, 0.0, 0.8); - copy_v3_v3(data->base_color, data->diffuse_color); + copy_v3_fl3(data->base_color, 0.8, 0.0, 0.8); } else if (color_type == V3D_SHADING_RANDOM_COLOR) { uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); @@ -67,30 +62,24 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, float hue = BLI_hash_int_01(hash); float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE}; - hsv_to_rgb_v(hsv, data->diffuse_color); - copy_v3_v3(data->base_color, data->diffuse_color); + hsv_to_rgb_v(hsv, data->base_color); } else if (ELEM(color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_VERTEX_COLOR)) { - copy_v3_v3(data->diffuse_color, ob->color); - copy_v3_v3(data->base_color, data->diffuse_color); data->alpha *= ob->color[3]; + copy_v3_v3(data->base_color, ob->color); } else { /* V3D_SHADING_MATERIAL_COLOR or V3D_SHADING_TEXTURE_COLOR */ if (mat) { data->alpha *= mat->a; + copy_v3_v3(data->base_color, &mat->r); if (workbench_is_specular_highlight_enabled(wpd)) { - copy_v3_v3(data->base_color, &mat->r); - mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic); - mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic); - add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic)); data->metallic = mat->metallic; data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */ } - else { - copy_v3_v3(data->base_color, &mat->r); - copy_v3_v3(data->diffuse_color, &mat->r); - } + } + else { + copy_v3_fl(data->base_color, 0.8f); } } } @@ -160,34 +149,40 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, return str; } -uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost) +uint workbench_material_get_hash(WORKBENCH_MaterialData *mat, bool is_ghost) { - uint input[4]; - uint result; - float *color = material_template->diffuse_color; - input[0] = (uint)(color[0] * 512); - input[1] = (uint)(color[1] * 512); - input[2] = (uint)(color[2] * 512); - input[3] = material_template->object_id; - result = BLI_ghashutil_uinthash_v4_murmur(input); - - color = material_template->specular_color; - input[0] = (uint)(color[0] * 512); - input[1] = (uint)(color[1] * 512); - input[2] = (uint)(color[2] * 512); - input[3] = (uint)(material_template->roughness * 512); - result += BLI_ghashutil_uinthash_v4_murmur(input); - - result += BLI_ghashutil_uinthash((uint)(material_template->alpha * 512)); - result += BLI_ghashutil_uinthash((uint)is_ghost); - result += BLI_ghashutil_uinthash(material_template->color_type); - - /* add texture reference */ - if (material_template->ima) { - result += BLI_ghashutil_inthash_p_murmur(material_template->ima); - } - - return result; + union { + struct { + /* WHATCH: Keep in sync with View3DShading.color_type max value. */ + uchar color_type; + uchar diff_r; + uchar diff_g; + uchar diff_b; + + uchar alpha; + uchar ghost; + uchar metal; + uchar roughness; + + void *ima; + }; + /* HACK to ensure input is 4 uint long. */ + uint a[4]; + } input = {.color_type = (uchar)(mat->color_type), + .diff_r = (uchar)(mat->base_color[0] * 0xFF), + .diff_g = (uchar)(mat->base_color[1] * 0xFF), + .diff_b = (uchar)(mat->base_color[2] * 0xFF), + + .alpha = (uint)(mat->alpha * 0xFF), + .ghost = (uchar)is_ghost, + .metal = (uchar)(mat->metallic * 0xFF), + .roughness = (uchar)(mat->roughness * 0xFF), + + .ima = mat->ima}; + + BLI_assert(sizeof(input) == sizeof(uint) * 4); + + return BLI_ghashutil_uinthash_v4((uint *)&input); } int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd) @@ -315,35 +310,28 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob, - const bool use_metallic, const bool deferred, const int interp) { - if (!deferred || workbench_is_matdata_pass_enabled(wpd)) { - if (workbench_material_determine_color_type(wpd, material->ima, ob, false) == - V3D_SHADING_TEXTURE_COLOR) { - GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D); - DRW_shgroup_uniform_texture(grp, "image", tex); - DRW_shgroup_uniform_bool_copy( - grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL)); - DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST)); - } - else { - DRW_shgroup_uniform_vec3(grp, - "materialDiffuseColor", - (use_metallic) ? material->base_color : material->diffuse_color, - 1); - } + if (!(!deferred || workbench_is_matdata_pass_enabled(wpd))) { + return; + } - if (workbench_is_specular_highlight_enabled(wpd)) { - if (use_metallic) { - DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1); - } - else { - DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1); - } - DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1); - } + const bool use_highlight = workbench_is_specular_highlight_enabled(wpd); + const bool use_texture = (V3D_SHADING_TEXTURE_COLOR == workbench_material_determine_color_type( + wpd, material->ima, ob, false)); + if (use_texture) { + GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D); + DRW_shgroup_uniform_texture(grp, "image", tex); + DRW_shgroup_uniform_bool_copy( + grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL)); + DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST)); + } + + DRW_shgroup_uniform_vec4(grp, "materialColorAndMetal", material->base_color, 1); + + if (use_highlight) { + DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1); } if (WORLD_CLIPPING_ENABLED(wpd)) { @@ -354,10 +342,7 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd, void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material) { - dest_material->object_id = source_material->object_id; copy_v3_v3(dest_material->base_color, source_material->base_color); - copy_v3_v3(dest_material->diffuse_color, source_material->diffuse_color); - copy_v3_v3(dest_material->specular_color, source_material->specular_color); dest_material->metallic = source_material->metallic; dest_material->roughness = source_material->roughness; dest_material->ima = source_material->ima; diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index d880d5d58b5..f51da581827 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -281,13 +281,8 @@ typedef struct WORKBENCH_EffectInfo { } WORKBENCH_EffectInfo; typedef struct WORKBENCH_MaterialData { - float base_color[3]; - float diffuse_color[3]; - float specular_color[3]; - float alpha; - float metallic; - float roughness; - int object_id; + float base_color[3], metallic; + float roughness, alpha; int color_type; int interp; Image *ima; @@ -308,8 +303,6 @@ typedef struct WORKBENCH_ObjectData { float shadow_min[3], shadow_max[3]; BoundBox shadow_bbox; bool shadow_bbox_dirty; - - int object_id; } WORKBENCH_ObjectData; /* inline helper functions */ @@ -500,7 +493,6 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob, - const bool use_metallic, const bool deferred, const int interp); void workbench_material_copy(WORKBENCH_MaterialData *dest_material, diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 7ae9d90daff..e017661b6cd 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -27,6 +27,7 @@ #include "BLI_rand.h" #include "BLI_dynstr.h" +#include "BLI_string_utils.h" #include "DNA_modifier_types.h" #include "DNA_object_force_types.h" @@ -54,6 +55,7 @@ static struct { extern char datatoc_workbench_volume_vert_glsl[]; extern char datatoc_workbench_volume_frag_glsl[]; extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_gpu_shader_common_obinfos_lib_glsl[]; static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic) { @@ -78,12 +80,16 @@ static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic) char *defines = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); + char *libs = BLI_string_joinN(datatoc_common_view_lib_glsl, + datatoc_gpu_shader_common_obinfos_lib_glsl); + e_data.volume_sh[id] = DRW_shader_create_with_lib(datatoc_workbench_volume_vert_glsl, NULL, datatoc_workbench_volume_frag_glsl, - datatoc_common_view_lib_glsl, + libs, defines); + MEM_freeN(libs); MEM_freeN(defines); } |