Workbench: Encode Roughness and metallic into 8bits
This reduces the bandwidth + vram usage of workbench even further.
This commit is contained in:
parent
223c1a107a
commit
0759480529
Notes:
blender-bot
2023-02-14 08:39:23 +01:00
Referenced by issue #58733, Segmentation fault at start
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue