diff options
Diffstat (limited to 'source/blender/draw/engines/workbench')
11 files changed, 155 insertions, 142 deletions
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 abd8c1f6579..505b4822ad6 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,6 +1,5 @@ - +uniform int object_id = 0; layout(location = 0) out uint objectId; - uniform float ImageTransparencyCutoff = 0.1; #ifdef V3D_SHADING_TEXTURE_COLOR uniform sampler2D image; @@ -11,10 +10,11 @@ in vec2 uv_interp; void main() { #ifdef V3D_SHADING_TEXTURE_COLOR - if (texture(image, uv_interp).a < ImageTransparencyCutoff) { + vec4 diffuse_color = texture(image, uv_interp); + if (diffuse_color.a < ImageTransparencyCutoff) { discard; } #endif - objectId = uint(resource_id + 1) & 0xFFu; + objectId = uint(object_id); } 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 f799ce41cb2..3333dfeff38 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,7 +8,8 @@ uniform float alpha = 0.5; uniform vec2 invertedViewportSize; uniform vec4 viewvecs[3]; -uniform vec4 materialColorAndMetal; +uniform vec3 materialDiffuseColor; +uniform vec3 materialSpecularColor; uniform float materialRoughness; uniform float shadowMultiplier = 0.5; @@ -41,17 +42,17 @@ layout(location = 1) out void main() { - vec4 base_color; + vec4 diffuse_color; #if defined(V3D_SHADING_TEXTURE_COLOR) - base_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); - if (base_color.a < ImageTransparencyCutoff) { + diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); + if (diffuse_color.a < ImageTransparencyCutoff) { discard; } #elif defined(V3D_SHADING_VERTEX_COLOR) - base_color.rgb = vertexColor; + diffuse_color = vec4(vertexColor, 1.0); #else - base_color.rgb = materialColorAndMetal.rgb; + diffuse_color = vec4(materialDiffuseColor, 1.0); #endif /* V3D_SHADING_TEXTURE_COLOR */ vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; @@ -63,7 +64,7 @@ void main() /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = base_color.rgb; + vec3 shaded_color = diffuse_color.rgb; #elif defined(V3D_LIGHTING_MATCAP) bool flipped = world_data.matcap_orientation != 0; @@ -74,20 +75,11 @@ void main() # else vec3 matcap_specular = vec3(0.0); # endif - vec3 shaded_color = matcap_diffuse * base_color.rgb + matcap_specular; + vec3 shaded_color = matcap_diffuse * diffuse_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, specular_color, materialRoughness, nor, I_vs); + world_data, diffuse_color.rgb, materialSpecularColor, 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 b5f95f2dcf8..c673b2484de 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -1,5 +1,7 @@ +uniform int object_id = 0; -uniform vec4 materialColorAndMetal; +uniform vec3 materialDiffuseColor; +uniform float materialMetallic; uniform float materialRoughness; uniform sampler2D image; @@ -46,7 +48,7 @@ void main() # elif defined(V3D_SHADING_VERTEX_COLOR) color.rgb = vertexColor; # else - color.rgb = materialColorAndMetal.rgb; + color.rgb = materialDiffuseColor; # endif # ifdef V3D_LIGHTING_MATCAP @@ -54,7 +56,7 @@ void main() metallic = float(gl_FrontFacing); roughness = 0.0; # else - metallic = materialColorAndMetal.a; + metallic = materialMetallic; roughness = materialRoughness; # endif @@ -62,7 +64,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(materialColorAndMetal.a - hair_variation, 0.0, 1.0); + metallic = clamp(materialMetallic - hair_variation, 0.0, 1.0); roughness = clamp(materialRoughness - hair_variation, 0.0, 1.0); # endif @@ -71,7 +73,7 @@ void main() #endif /* MATDATA_PASS_ENABLED */ #ifdef OBJECT_ID_PASS_ENABLED - objectId = uint(resource_id + 1) & 0xFFu; + objectId = uint(object_id); #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 04dd9ab85bb..7eb12dbdeb9 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl @@ -25,10 +25,6 @@ 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) { @@ -95,18 +91,12 @@ void main() #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED -# ifndef HAIR_SHADER normal_viewport = normal_object_to_view(nor); +# ifndef HAIR_SHADER 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 c24c335189e..4a9b0ae3b7d 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -1,4 +1,6 @@ +uniform vec3 OrcoTexCoFactors[2]; + uniform sampler2D depthBuffer; uniform sampler3D densityTexture; @@ -214,13 +216,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].xyz * 2.0; + vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 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].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; + 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. */ 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 3542a1a91fc..6f0bb56fafd 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl @@ -1,11 +1,10 @@ +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; @@ -28,8 +27,6 @@ void main() #else vec3 final_pos = pos; #endif - final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0].xyz) / OrcoTexCoFactors[1].xyz; + final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1]; 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 e41cba1d3bd..262ea7110a4 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -83,6 +83,7 @@ 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; @@ -146,7 +147,6 @@ 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,6 +330,7 @@ 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; } @@ -378,10 +379,11 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) workbench_effect_info_init(stl->effects); } - if (!e_data.shadow_pass_sh) { + if (!e_data.next_object_id) { 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 @@ -866,11 +868,18 @@ 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; @@ -890,7 +899,8 @@ 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); - workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, interp); + DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1); + workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp); BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material); } return material; @@ -933,7 +943,8 @@ 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); - workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, interp); + DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp); } } } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 890359e8fda..1cbc60ef858 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -63,6 +63,8 @@ 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 */ @@ -96,18 +98,6 @@ 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(); @@ -139,6 +129,12 @@ 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, @@ -153,11 +149,18 @@ 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; @@ -202,7 +205,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, interp); + workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp); material->shgrp = grp; /* Depth */ @@ -216,6 +219,8 @@ 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); } @@ -287,30 +292,26 @@ 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 *[]){forward_frag, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines, define_id_pass, NULL}, + .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines, 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 *[]){forward_frag, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines_texture, define_id_pass, NULL}, + .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines_texture, 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 *[]){forward_frag, NULL}, - .defs = (const char *[]){sh_cfg_data->def, defines_hair, define_id_pass, NULL}, + .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, defines_hair, 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); @@ -526,7 +527,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, interp); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, 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. */ @@ -550,6 +551,7 @@ 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 c90604678db..e050877187e 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -44,15 +44,20 @@ 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->base_color, wpd->shading.single_color); + copy_v3_v3(data->diffuse_color, wpd->shading.single_color); + copy_v3_v3(data->base_color, data->diffuse_color); } else if (color_type == V3D_SHADING_ERROR_COLOR) { - copy_v3_fl3(data->base_color, 0.8, 0.0, 0.8); + copy_v3_fl3(data->diffuse_color, 0.8, 0.0, 0.8); + copy_v3_v3(data->base_color, data->diffuse_color); } else if (color_type == V3D_SHADING_RANDOM_COLOR) { uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); @@ -62,24 +67,30 @@ 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->base_color); + hsv_to_rgb_v(hsv, data->diffuse_color); + copy_v3_v3(data->base_color, data->diffuse_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_fl(data->base_color, 0.8f); + else { + copy_v3_v3(data->base_color, &mat->r); + copy_v3_v3(data->diffuse_color, &mat->r); + } } } } @@ -149,40 +160,34 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, return str; } -uint workbench_material_get_hash(WORKBENCH_MaterialData *mat, bool is_ghost) +uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost) { - 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); + 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; } int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd) @@ -310,28 +315,35 @@ 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))) { - return; - } - - 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 (!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 (use_highlight) { - DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1); + 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); + } } if (WORLD_CLIPPING_ENABLED(wpd)) { @@ -342,7 +354,10 @@ 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 f51da581827..d880d5d58b5 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -281,8 +281,13 @@ typedef struct WORKBENCH_EffectInfo { } WORKBENCH_EffectInfo; typedef struct WORKBENCH_MaterialData { - float base_color[3], metallic; - float roughness, alpha; + float base_color[3]; + float diffuse_color[3]; + float specular_color[3]; + float alpha; + float metallic; + float roughness; + int object_id; int color_type; int interp; Image *ima; @@ -303,6 +308,8 @@ 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 */ @@ -493,6 +500,7 @@ 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 e017661b6cd..7ae9d90daff 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -27,7 +27,6 @@ #include "BLI_rand.h" #include "BLI_dynstr.h" -#include "BLI_string_utils.h" #include "DNA_modifier_types.h" #include "DNA_object_force_types.h" @@ -55,7 +54,6 @@ 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) { @@ -80,16 +78,12 @@ 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, - libs, + datatoc_common_view_lib_glsl, defines); - MEM_freeN(libs); MEM_freeN(defines); } |