Workbench: GLSL performance + code style

- store normal in vec2
 - use rgba_8 for colorBuffer
This commit is contained in:
Jeroen Bakker 2018-04-25 11:54:02 +02:00
parent 83528feeed
commit 8f76d05fa5
4 changed files with 60 additions and 22 deletions

View File

@ -12,3 +12,24 @@ float bayer_dither_noise() {
ivec2 tx2 = ivec2(gl_FragCoord.xy) % 2;
return dither_mat4x4[tx1.x][tx1.y];
}
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
vec3 normal_decode(vec2 enc)
{
vec2 fenc = enc * 4.0 - 2.0;
float f = dot(fenc, fenc);
float g = sqrt(1.0 - f / 4.0);
vec3 n;
n.xy = fenc*g;
n.z = 1 - f / 2;
return n;
}
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
vec2 normal_encode(vec3 n)
{
float p = sqrt(n.z * 8.0 + 8.0);
return n.xy / p + 0.5;
}

View File

@ -1,9 +1,10 @@
out vec4 fragColor;
uniform usampler2D objectId;
uniform sampler2D depth;
uniform sampler2D diffuseColor;
uniform sampler2D normalViewport;
uniform sampler2D depthBuffer;
uniform sampler2D colorBuffer;
uniform sampler2D normalBuffer;
/* normalBuffer contains viewport normals */
uniform vec2 invertedViewportSize;
uniform vec3 objectOverlapColor = vec3(0.0);
@ -16,12 +17,12 @@ layout(std140) uniform world_block {
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
vec2 uvViewport = gl_FragCoord.xy * invertedViewportSize;
float depth = texelFetch(depth, texel, 0).r;
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
float depth = texelFetch(depthBuffer, texel, 0).r;
#ifndef V3D_DRAWOPTION_OBJECT_OVERLAP
if (depth == 1.0) {
fragColor = vec4(background_color(world_data, uvViewport.y), 0.0);
fragColor = vec4(background_color(world_data, uv_viewport.y), 0.0);
return;
}
#else /* !V3D_DRAWOPTION_OBJECT_OVERLAP */
@ -29,7 +30,7 @@ void main()
float object_overlap = calculate_object_overlap(objectId, texel, object_id);
if (object_id == NO_OBJECT_ID) {
vec3 background = background_color(world_data, uvViewport.y);
vec3 background = background_color(world_data, uv_viewport.y);
if (object_overlap == 0.0) {
fragColor = vec4(background, 0.0);
} else {
@ -39,10 +40,10 @@ void main()
}
#endif /* !V3D_DRAWOPTION_OBJECT_OVERLAP */
vec3 diffuse_color = texelFetch(diffuseColor, texel, 0).rgb;
vec3 diffuse_color = texelFetch(colorBuffer, texel, 0).rgb;
#ifdef V3D_LIGHTING_STUDIO
vec3 normal_viewport = texelFetch(normalViewport, texel, 0).rgb;
vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
vec3 diffuse_light = get_world_diffuse_light(world_data, normal_viewport);
vec3 shaded_color = diffuse_light * diffuse_color;

View File

@ -5,11 +5,11 @@ in vec3 normal_viewport;
out uint objectId;
out vec3 diffuseColor;
out vec3 normalViewport;
out vec2 normalViewport;
void main()
{
objectId = uint(object_id);
diffuseColor = object_color;
normalViewport = normal_viewport;
normalViewport = normal_encode(normal_viewport);
}

View File

@ -36,8 +36,8 @@ static struct {
struct GPUShader *composite_sh_cache[MAX_SHADERS];
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *diffuse_color_tx; /* ref only, not alloced */
struct GPUTexture *normal_viewport_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
int next_object_id;
} e_data = {NULL};
@ -100,6 +100,20 @@ static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
return str;
}
static char *workbench_build_prepass_frag(void)
{
char *str = NULL;
DynStr *ds = BLI_dynstr_new();
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl);
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return str;
}
static int get_shader_index(WORKBENCH_PrivateData *wpd)
{
return (wpd->drawtype_options << 2) + wpd->drawtype_lighting;
@ -112,10 +126,12 @@ static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
if (e_data.prepass_sh_cache[index] == NULL) {
char *defines = workbench_build_defines(wpd);
char *composite_frag = workbench_build_composite_frag(wpd);
e_data.prepass_sh_cache[index] = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, datatoc_workbench_prepass_frag_glsl, defines);
char *prepass_frag = workbench_build_prepass_frag();
e_data.prepass_sh_cache[index] = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, prepass_frag, defines);
e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
MEM_freeN(defines);
MEM_freeN(prepass_frag);
MEM_freeN(composite_frag);
MEM_freeN(defines);
}
wpd->prepass_sh = e_data.prepass_sh_cache[index];
@ -180,14 +196,14 @@ void workbench_materials_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]};
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_R_32U, &draw_engine_workbench_solid);
e_data.diffuse_color_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RGBA_32, &draw_engine_workbench_solid);
e_data.normal_viewport_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RGBA_32, &draw_engine_workbench_solid);
e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RGBA_8, &draw_engine_workbench_solid);
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RG_8, &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.diffuse_color_tx),
GPU_ATTACHMENT_TEXTURE(e_data.normal_viewport_tx),
GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
});
}
@ -243,13 +259,13 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
DRW_shgroup_uniform_texture_ref(grp, "depth", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "diffuseColor", &e_data.diffuse_color_tx);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
if (OBJECT_ID_PASS_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
}
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "normalViewport", &e_data.normal_viewport_tx);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
}
wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL);
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);