From 0759480529c6d31271117ad2ae8083f6a0beb528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 3 Dec 2018 14:51:30 +0100 Subject: Workbench: Encode Roughness and metallic into 8bits This reduces the bandwidth + vram usage of workbench even further. --- .../workbench/shaders/workbench_common_lib.glsl | 27 ++++++++++++++++++++ .../shaders/workbench_deferred_composite_frag.glsl | 25 ++++++++++--------- .../workbench/shaders/workbench_prepass_frag.glsl | 29 +++++++++++----------- .../draw/engines/workbench/workbench_deferred.c | 8 +----- 4 files changed, 56 insertions(+), 33 deletions(-) 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 451d509eeee..b8c90162c51 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -49,6 +49,33 @@ vec2 workbench_normal_encode(vec3 n) # define workbench_normal_decode(a) (a) #endif /* WORKBENCH_ENCODE_NORMALS */ +/* Encoding into the alpha of a RGBA8 UNORM texture. */ +#define TARGET_BITCOUNT 8 +#define METALLIC_BITS 3 /* Metallic channel is less important. */ +#define ROUGHNESS_BITS (TARGET_BITCOUNT - METALLIC_BITS) +#define TOTAL_BITS (METALLIC_BITS + ROUGHNESS_BITS) + +/* Encode 2 float into 1 with the desired precision. */ +float workbench_float_pair_encode(float v1, float v2) +{ + const int total_mask = ~(0xFFFFFFFF << TOTAL_BITS); + const int v1_mask = ~(0xFFFFFFFF << ROUGHNESS_BITS); + const int v2_mask = ~(0xFFFFFFFF << METALLIC_BITS); + int iv1 = int(v1 * float(v1_mask)); + int iv2 = int(v2 * float(v2_mask)) << ROUGHNESS_BITS; + return float(iv1 | iv2) * (1.0 / float(total_mask)); +} + +void workbench_float_pair_decode(float data, out float v1, out float v2) +{ + const int total_mask = ~(0xFFFFFFFF << TOTAL_BITS); + const int v1_mask = ~(0xFFFFFFFF << ROUGHNESS_BITS); + const int v2_mask = ~(0xFFFFFFFF << METALLIC_BITS); + int idata = int(data * float(total_mask)); + v1 = float(idata & v1_mask) * (1.0 / float(v1_mask)); + v2 = float(idata >> ROUGHNESS_BITS) * (1.0 / float(v2_mask)); +} + float calculate_transparent_weight(float z, float alpha) { #if 0 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 6d2af8557d0..5a895ab65ec 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 @@ -4,8 +4,7 @@ uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrixInverse; uniform usampler2D objectId; -uniform sampler2D colorBuffer; -uniform sampler2D metallicBuffer; +uniform sampler2D materialBuffer; uniform sampler2D normalBuffer; /* normalBuffer contains viewport normals */ uniform sampler2D cavityBuffer; @@ -27,7 +26,8 @@ void main() ivec2 texel = ivec2(gl_FragCoord.xy); vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - vec4 base_color = texelFetch(colorBuffer, texel, 0); + vec4 material_data = texelFetch(materialBuffer, texel, 0); + vec3 base_color = material_data.rgb; /* Do we need normals */ #ifdef NORMAL_VIEWPORT_PASS_ENABLED @@ -38,27 +38,28 @@ void main() /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = base_color.rgb; + vec3 shaded_color = base_color; #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; + /* When using matcaps, the material_data.a is the backface sign. */ + float flipped_nor = material_data.a; + normal_viewport = (flipped_nor > 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 * base_color.rgb; + vec3 shaded_color = matcap * base_color; #elif defined(V3D_LIGHTING_STUDIO) # ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - 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); + float roughness, metallic; + workbench_float_pair_decode(material_data.a, roughness, metallic); + vec3 specular_color = mix(vec3(0.05), base_color, metallic); + vec3 diffuse_color = mix(base_color, vec3(0.0), metallic); # else float roughness = 0.0; vec3 specular_color = vec3(0.0); - vec3 diffuse_color = base_color.rgb; + vec3 diffuse_color = base_color; # endif vec3 shaded_color = get_world_lighting(world_data, 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 ee968c4eb02..b9b21d576cb 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -23,10 +23,7 @@ flat in float hair_rand; #endif layout(location=0) out uint objectId; -layout(location=1) out vec4 colorRoughness; -#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT -layout(location=2) out float metallic; -#endif +layout(location=1) out vec4 materialData; #ifdef NORMAL_VIEWPORT_PASS_ENABLED # ifdef WORKBENCH_ENCODE_NORMALS layout(location=3) out vec2 normalViewport; @@ -39,34 +36,38 @@ void main() { objectId = uint(object_id); + vec4 color_roughness; #ifdef V3D_SHADING_TEXTURE_COLOR - colorRoughness = texture(image, uv_interp); - if (colorRoughness.a < ImageTransparencyCutoff) { + color_roughness = texture(image, uv_interp); + if (color_roughness.a < ImageTransparencyCutoff) { discard; } - colorRoughness.a = materialRoughness; + color_roughness.a = materialRoughness; #else - colorRoughness = vec4(materialDiffuseColor, materialRoughness); + color_roughness = 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; - colorRoughness = clamp(colorRoughness - hair_color_variation, 0.0, 1.0); + color_roughness = clamp(color_roughness - hair_color_variation, 0.0, 1.0); #endif + float metallic; #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT # ifdef HAIR_SHADER metallic = clamp(materialMetallic - hair_color_variation, 0.0, 1.0); # else metallic = materialMetallic; # endif +#elif defined(V3D_LIGHTING_MATCAP) + /* Encode front facing in metallic channel. */ + metallic = float(gl_FrontFacing); + color_roughness.a = 0.0; #endif + materialData.rgb = color_roughness.rgb; + materialData.a = workbench_float_pair_encode(color_roughness.a, metallic); + #ifdef NORMAL_VIEWPORT_PASS_ENABLED vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport; n = normalize(n); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index c3eb3d82810..acea650b86a 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -422,9 +422,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) 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), @@ -574,7 +571,7 @@ void workbench_deferred_engine_free(void) static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp) { DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); - DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx); + DRW_shgroup_uniform_texture_ref(grp, "materialBuffer", &e_data.color_buffer_tx); if (OBJECT_OUTLINE_ENABLED(wpd)) { DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx); } @@ -584,9 +581,6 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG 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, "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); } -- cgit v1.2.3