[Bf-blender-cvs] [0759480529c] blender2.8: Workbench: Encode Roughness and metallic into 8bits

Clément Foucault noreply at git.blender.org
Mon Dec 3 17:19:29 CET 2018


Commit: 0759480529c6d31271117ad2ae8083f6a0beb528
Author: Clément Foucault
Date:   Mon Dec 3 14:51:30 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB0759480529c6d31271117ad2ae8083f6a0beb528

Workbench: Encode Roughness and metallic into 8bits

This reduces the bandwidth + vram usage of workbench even further.

===================================================================

M	source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
M	source/blender/draw/engines/workbench/workbench_deferred.c

===================================================================

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);
 	}



More information about the Bf-blender-cvs mailing list