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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-12-03 02:36:54 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-12-03 19:19:11 +0300
commit24fd03d0c2fc5f49bc3813afce7ac5d67fc762bd (patch)
tree4af65d73762c28ce003d425cb288d66bec226a3d
parent17a4323ef59570975b254da9936fde16969b1df0 (diff)
Workbench: Reduce VRAM usage depending on mode
We exploit the fact that we are using the metallic workflow for material and pass the metallic parameter instead of the specular color. Pack the front facing bit in the color buffer only for matcap display. Change buffer formats to use less bytes as possible. Also don't request buffers that we won't use. Saved 40MB on 2K screen on StudioLight + Shadows + Specular Lighting. Includes several cleanups.
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl8
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl40
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl34
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl8
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl46
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c41
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_taa.c3
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c31
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h10
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c2
-rw-r--r--source/blender/gpu/intern/gpu_texture.c12
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;