diff options
13 files changed, 129 insertions, 120 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl index b52d7d31e61..769d453bb18 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl @@ -61,13 +61,7 @@ void main() #ifdef USE_CAVITY float depth = texelFetch(depthBuffer, texel, 0).x; vec3 position = get_view_space_from_depth(screenco, depth); - - vec4 diffuse_color = texelFetch(colorBuffer, texel, 0); - vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg); - if (diffuse_color.a == 0.0) { - normal_viewport = -normal_viewport; - } - + vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); ssao_factors(depth, normal_viewport, position, screenco, cavity, edges); #endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 982c3821030..451d509eeee 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -19,9 +19,11 @@ float bayer_dither_noise() { return dither_mat4x4[tx1.x][tx1.y]; } +#ifdef WORKBENCH_ENCODE_NORMALS + /* From http://aras-p.info/texts/CompactNormalStorage.html * Using Method #4: Spheremap Transform */ -vec3 normal_decode(vec2 enc) +vec3 workbench_normal_decode(vec2 enc) { vec2 fenc = enc.xy * 4.0 - 2.0; float f = dot(fenc, fenc); @@ -34,38 +36,18 @@ vec3 normal_decode(vec2 enc) /* From http://aras-p.info/texts/CompactNormalStorage.html * Using Method #4: Spheremap Transform */ -vec2 normal_encode(vec3 n) +vec2 workbench_normal_encode(vec3 n) { float p = sqrt(n.z * 8.0 + 8.0); - return vec2(n.xy / p + 0.5); + n.xy = clamp(n.xy / p + 0.5, 0.0, 1.0); + return n.xy; } -void fresnel(vec3 I, vec3 N, float ior, out float kr) -{ - float cosi = clamp(dot(I, N), -1.0, 1.0); - float etai = 1.0; - float etat = ior; - if (cosi > 0) { - etat = 1.0; - etai = ior; - } - - // Compute sini using Snell's law - float sint = etai / etat * sqrt(max(0.0, 1.0 - cosi * cosi)); - // Total internal reflection - if (sint >= 1) { - kr = 1; - } - else { - float cost = sqrt(max(0.0, 1.0 - sint * sint)); - cosi = abs(cosi); - float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost)); - float Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost)); - kr = (Rs * Rs + Rp * Rp) / 2; - } - // As a consequence of the conservation of energy, transmittance is given by: - // kt = 1 - kr; -} +#else +/* Well just do nothing... */ +# define workbench_normal_encode(a) (a) +# define workbench_normal_decode(a) (a) +#endif /* WORKBENCH_ENCODE_NORMALS */ float calculate_transparent_weight(float z, float alpha) { diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl index 53315b8c132..d0281f6c85c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl @@ -26,12 +26,10 @@ float calculate_curvature(usampler2D objectId, sampler2D normalBuffer, ivec2 tex vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg; vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg; -#ifdef WORKBENCH_ENCODE_NORMALS - normal_up = normal_decode(normal_up ).rg; - normal_down = normal_decode(normal_down ).rg; - normal_left = normal_decode(normal_left ).rg; - normal_right = normal_decode(normal_right).rg; -#endif + normal_up = workbench_normal_decode(normal_up ).rg; + normal_down = workbench_normal_decode(normal_down ).rg; + normal_left = workbench_normal_decode(normal_left ).rg; + normal_right = workbench_normal_decode(normal_right).rg; float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r)); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl index e383d1b1939..96537c47f11 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl @@ -5,7 +5,7 @@ uniform mat4 ViewMatrixInverse; uniform usampler2D objectId; uniform sampler2D colorBuffer; -uniform sampler2D specularBuffer; +uniform sampler2D metallicBuffer; uniform sampler2D normalBuffer; /* normalBuffer contains viewport normals */ uniform sampler2D cavityBuffer; @@ -28,6 +28,7 @@ void main() vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; uint object_id = texelFetch(objectId, texel, 0).r; + /* TODO separate this into its own shader. */ #ifndef V3D_SHADING_OBJECT_OUTLINE if (object_id == NO_OBJECT_ID) { fragColor = vec4(background_color(world_data, uv_viewport.y), world_data.background_alpha); @@ -52,41 +53,42 @@ void main() } #endif /* !V3D_SHADING_OBJECT_OUTLINE */ - vec4 diffuse_color = texelFetch(colorBuffer, texel, 0); + vec4 base_color = texelFetch(colorBuffer, texel, 0); /* Do we need normals */ #ifdef NORMAL_VIEWPORT_PASS_ENABLED -# ifdef WORKBENCH_ENCODE_NORMALS - vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg); - if (diffuse_color.a == 0.0) { - normal_viewport = -normal_viewport; - } -# else /* WORKBENCH_ENCODE_NORMALS */ - vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb; -# endif /* WORKBENCH_ENCODE_NORMALS */ + vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); #endif vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix); /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = diffuse_color.rgb; + vec3 shaded_color = base_color.rgb; #elif defined(V3D_LIGHTING_MATCAP) + /* When using matcaps, the basecolor alpha is the backface sign. */ + normal_viewport = (base_color.a > 0.0) ? normal_viewport : -normal_viewport; bool flipped = world_data.matcap_orientation != 0; vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped); vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb; - vec3 shaded_color = matcap * diffuse_color.rgb; + vec3 shaded_color = matcap * base_color.rgb; #elif defined(V3D_LIGHTING_STUDIO) # ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - vec4 specular_data = texelFetch(specularBuffer, texel, 0); + float metallic = texelFetch(metallicBuffer, texel, 0).r; + float roughness = base_color.a; + vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic); + vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic); # else - vec4 specular_data = vec4(0.0); + float roughness = 0.0; + vec3 specular_color = vec3(0.0); + vec3 diffuse_color = base_color.rgb; # endif + vec3 shaded_color = get_world_lighting(world_data, - diffuse_color.rgb, specular_data.rgb, specular_data.a, + diffuse_color, specular_color, roughness, normal_viewport, I_vs); #endif @@ -98,8 +100,6 @@ void main() #ifdef V3D_SHADING_SHADOW float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz); - /* The step function might be ok for meshes but it's - * clearly not the case for hairs. Do smoothstep in this case. */ float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor); shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix); #endif 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 c00edb06100..d42b6bde791 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 @@ -9,8 +9,8 @@ uniform float alpha = 0.5; uniform vec2 invertedViewportSize; uniform vec4 viewvecs[3]; -uniform vec4 materialDiffuseColor; -uniform vec4 materialSpecularColor; +uniform vec3 materialDiffuseColor; +uniform vec3 materialSpecularColor; uniform float materialRoughness; #ifdef NORMAL_VIEWPORT_PASS_ENABLED @@ -40,7 +40,7 @@ void main() discard; } #else - diffuse_color = materialDiffuseColor; + diffuse_color = vec4(materialDiffuseColor, 1.0); #endif /* V3D_SHADING_TEXTURE_COLOR */ vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; @@ -62,7 +62,7 @@ void main() #elif defined(V3D_LIGHTING_STUDIO) vec3 shaded_color = get_world_lighting(world_data, - diffuse_color.rgb, materialSpecularColor.rgb, materialRoughness, + diffuse_color.rgb, materialSpecularColor, materialRoughness, nor, I_vs); #endif 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 5f622b00bca..ee968c4eb02 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,7 @@ uniform int object_id = 0; -uniform vec4 materialDiffuseColor; -uniform vec4 materialSpecularColor; +uniform vec3 materialDiffuseColor; +uniform float materialMetallic; uniform float materialRoughness; #ifdef V3D_SHADING_TEXTURE_COLOR @@ -23,9 +23,9 @@ flat in float hair_rand; #endif layout(location=0) out uint objectId; -layout(location=1) out vec4 diffuseColor; +layout(location=1) out vec4 colorRoughness; #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT -layout(location=2) out vec4 specularColor; +layout(location=2) out float metallic; #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED # ifdef WORKBENCH_ENCODE_NORMALS @@ -39,41 +39,37 @@ void main() { objectId = uint(object_id); -#ifdef NORMAL_VIEWPORT_PASS_ENABLED - vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport; - n = normalize(n); -#endif - #ifdef V3D_SHADING_TEXTURE_COLOR - diffuseColor = texture(image, uv_interp); - if (diffuseColor.a < ImageTransparencyCutoff) { + colorRoughness = texture(image, uv_interp); + if (colorRoughness.a < ImageTransparencyCutoff) { discard; } + colorRoughness.a = materialRoughness; #else - diffuseColor = vec4(materialDiffuseColor.rgb, 0.0); + colorRoughness = vec4(materialDiffuseColor, materialRoughness); #endif /* V3D_SHADING_TEXTURE_COLOR */ +#ifdef V3D_LIGHTING_MATCAP + /* Encode front facing in color alpha. */ + colorRoughness.a = float(gl_FrontFacing); +#endif + #ifdef HAIR_SHADER float hair_color_variation = hair_rand * 0.1; - diffuseColor.rgb = clamp(diffuseColor.rgb - hair_color_variation, 0.0, 1.0); + colorRoughness = clamp(colorRoughness - hair_color_variation, 0.0, 1.0); #endif #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - specularColor = vec4(materialSpecularColor.rgb, materialRoughness); # ifdef HAIR_SHADER - specularColor.rgb = clamp(specularColor.rgb - hair_color_variation, 0.0, 1.0); + metallic = clamp(materialMetallic - hair_color_variation, 0.0, 1.0); +# else + metallic = materialMetallic; # endif #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED -# ifdef WORKBENCH_ENCODE_NORMALS - diffuseColor.a = float(gl_FrontFacing); - normalViewport = normal_encode(n); -# else /* WORKBENCH_ENCODE_NORMALS */ - normalViewport = n; -# endif /* WORKBENCH_ENCODE_NORMALS */ -# ifdef HAIR_SHADER - diffuseColor.a = 0.5; -# endif -#endif /* NORMAL_VIEWPORT_PASS_ENABLED */ + vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport; + n = normalize(n); + normalViewport = workbench_normal_encode(n); +#endif } diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index fb9883d19c5..957f5b99614 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -72,7 +72,7 @@ static struct { struct GPUTexture *object_id_tx; /* ref only, not alloced */ struct GPUTexture *color_buffer_tx; /* ref only, not alloced */ struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */ - struct GPUTexture *specular_buffer_tx; /* ref only, not alloced */ + struct GPUTexture *metallic_buffer_tx; /* ref only, not alloced */ struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ @@ -377,20 +377,35 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) { const float *viewport_size = DRW_viewport_size_get(); const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; + const GPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8UI; const GPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F; const GPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_R11F_G11F_B10F; - e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid); + + e_data.object_id_tx = NULL; + e_data.color_buffer_tx = NULL; + e_data.composite_buffer_tx = NULL; + e_data.normal_buffer_tx = NULL; + e_data.cavity_buffer_tx = NULL; + e_data.metallic_buffer_tx = NULL; + + e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], id_tex_format, &draw_engine_workbench_solid); e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid); - e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid); - e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid); - e_data.specular_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid); e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], comp_tex_format, &draw_engine_workbench_solid); + if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) { + e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid); + } + if (CAVITY_ENABLED(wpd)) { + e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid); + } + if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) { + e_data.metallic_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R8, &draw_engine_workbench_solid); + } GPU_framebuffer_ensure_config(&fbl->prepass_fb, { GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), - GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx), + GPU_ATTACHMENT_TEXTURE(e_data.metallic_buffer_tx), GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), }); GPU_framebuffer_ensure_config(&fbl->cavity_fb, { @@ -455,7 +470,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) workbench_aa_create_pass(vedata, &e_data.color_buffer_tx); } - if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) { + if (CAVITY_ENABLED(wpd)) { int state = DRW_STATE_WRITE_COLOR; GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd)); psl->cavity_pass = DRW_pass_create("Cavity", state); @@ -493,7 +508,7 @@ static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl) GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx), GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), - GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx), + GPU_ATTACHMENT_TEXTURE(e_data.metallic_buffer_tx), GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), }); } @@ -530,11 +545,11 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) { DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx); } - if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) { + if (CAVITY_ENABLED(wpd)) { DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx); } if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) { - DRW_shgroup_uniform_texture_ref(grp, "specularBuffer", &e_data.specular_buffer_tx); + DRW_shgroup_uniform_texture_ref(grp, "metallicBuffer", &e_data.metallic_buffer_tx); } if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) { DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3); @@ -663,7 +678,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data( 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); + workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true); BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material); } @@ -706,7 +721,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o 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); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true); } } } @@ -937,7 +952,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->ghost_resolve_pass); } - if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) { + if (CAVITY_ENABLED(wpd)) { GPU_framebuffer_bind(fbl->cavity_fb); DRW_draw_pass(psl->cavity_pass); } diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c index 403338d55c4..929281daaf4 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_taa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c @@ -171,7 +171,8 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_bu int previous_jitter_index = effect_info->jitter_index; { - DRW_texture_ensure_fullscreen_2D(&txl->history_buffer_tx, GPU_RGBA16F, 0); + const GPUTextureFormat hist_buffer_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_RGBA8; + DRW_texture_ensure_fullscreen_2D(&txl->history_buffer_tx, hist_buffer_format, 0); DRW_texture_ensure_fullscreen_2D(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0); } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 3a5e592fa69..36f94a6929a 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -176,7 +176,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data( DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); } - workbench_material_shgroup_uniform(wpd, grp, material, ob); + workbench_material_shgroup_uniform(wpd, grp, material, ob, false); material->shgrp = grp; /* Depth */ @@ -444,7 +444,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O psl->transparent_accum_pass, shader); DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo); - workbench_material_shgroup_uniform(wpd, shgrp, material, ob); + workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false); 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. */ diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 19fb8efb812..1e969956d77 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -14,12 +14,15 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate { /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */ int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type; - copy_v4_fl4(data->diffuse_color, 0.8f, 0.8f, 0.8f, 1.0f); - copy_v4_fl4(data->specular_color, 0.05f, 0.05f, 0.05f, 1.0f); /* Dielectric: 5% reflective. */ - data->roughness = 0.5; /* sqrtf(0.25f); */ + 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.5f; /* sqrtf(0.25f); */ 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); } else if (color_type == V3D_SHADING_RANDOM_COLOR) { uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); @@ -30,17 +33,21 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate 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); } else { /* V3D_SHADING_MATERIAL_COLOR */ if (mat) { if (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); } } @@ -151,18 +158,24 @@ int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *i } void workbench_material_shgroup_uniform( - WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob) + WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob, + const bool use_metallic) { if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) { GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f); DRW_shgroup_uniform_texture(grp, "image", tex); } else { - DRW_shgroup_uniform_vec4(grp, "materialDiffuseColor", material->diffuse_color, 1); + DRW_shgroup_uniform_vec3(grp, "materialDiffuseColor", (use_metallic) ? material->base_color : material->diffuse_color, 1); } if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) { - DRW_shgroup_uniform_vec4(grp, "materialSpecularColor", material->specular_color, 1); + 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); } } @@ -170,8 +183,10 @@ void workbench_material_shgroup_uniform( void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material) { dest_material->object_id = source_material->object_id; - copy_v4_v4(dest_material->diffuse_color, source_material->diffuse_color); - copy_v4_v4(dest_material->specular_color, source_material->specular_color); + 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 0e27ed2ed53..1100b2aaca7 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -53,6 +53,7 @@ #define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP)) #define SSAO_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_SSAO) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH))) #define CURVATURE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_CURVATURE) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH))) +#define CAVITY_ENABLED(wpd) (CURVATURE_ENABLED(wpd) || SSAO_ENABLED(wpd)) #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) #define GHOST_ENABLED(psl) (!DRW_pass_is_empty(psl->ghost_prepass_pass) || !DRW_pass_is_empty(psl->ghost_prepass_hair_pass)) @@ -219,8 +220,10 @@ typedef struct WORKBENCH_EffectInfo { } WORKBENCH_EffectInfo; typedef struct WORKBENCH_MaterialData { - float diffuse_color[4]; - float specular_color[4]; + float base_color[3]; + float diffuse_color[3]; + float specular_color[3]; + float metallic; float roughness; int object_id; int color_type; @@ -297,7 +300,8 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost); int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair); void workbench_material_shgroup_uniform( - WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob); + WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob, + const bool use_metallic); void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material); /* workbench_studiolight.c */ diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c index 36882a87408..be6e66c339f 100644 --- a/source/blender/draw/intern/draw_manager_texture.c +++ b/source/blender/draw/intern/draw_manager_texture.c @@ -33,6 +33,8 @@ static bool drw_texture_format_supports_framebuffer(GPUTextureFormat format) switch (format) { /* Only add formats that are COMPATIBLE with FB. * Generally they are multiple of 16bit. */ + case GPU_R8: + case GPU_R8UI: case GPU_R16F: case GPU_R16I: case GPU_R16UI: diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index d5b33b88350..0944e5e4e44 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -178,8 +178,8 @@ static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat } else { /* Integer formats */ - if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { - if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R8UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { BLI_assert(data_format == GPU_DATA_UNSIGNED_INT); } else { @@ -218,8 +218,8 @@ static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_fo } else { /* Integer formats */ - if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { - if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { return GPU_DATA_UNSIGNED_INT; } else { @@ -260,7 +260,7 @@ static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormat } else { /* Integer formats */ - if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { + if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { *format_flag |= GPU_FORMAT_INTEGER; switch (gpu_get_component_count(data_type)) { @@ -327,6 +327,7 @@ static uint gpu_get_bytesize(GPUTextureFormat data_type) case GPU_R16: return 2; case GPU_R8: + case GPU_R8UI: return 1; default: BLI_assert(!"Texture format incorrect or unsupported\n"); @@ -360,6 +361,7 @@ static GLenum gpu_get_gl_internalformat(GPUTextureFormat format) case GPU_RG16UI: return GL_RG16UI; case GPU_R16: return GL_R16; case GPU_R8: return GL_R8; + case GPU_R8UI: return GL_R8UI; /* Special formats texture & renderbuffer */ case GPU_R11F_G11F_B10F: return GL_R11F_G11F_B10F; case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8; |