Workbench: Encode Roughness and metallic into 8bits

This reduces the bandwidth + vram usage of workbench even further.
This commit is contained in:
Clément Foucault 2018-12-03 14:51:30 +01:00
parent 223c1a107a
commit 0759480529
Notes: blender-bot 2023-02-14 08:39:23 +01:00
Referenced by issue #58733, Segmentation fault at start
4 changed files with 56 additions and 33 deletions

View File

@ -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

View File

@ -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,

View File

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

View File

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