Workbench: Reduce VRAM usage depending on mode

We exploit the fact that we are using the metallic workflow for material
and pass the metallic parameter instead of the specular color.

Pack the front facing bit in the color buffer only for matcap display.

Change buffer formats to use less bytes as possible.

Also don't request buffers that we won't use.

Saved 40MB on 2K screen on StudioLight + Shadows + Specular Lighting.

Includes several cleanups.
This commit is contained in:
Clément Foucault 2018-12-03 00:36:54 +01:00
parent 17a4323ef5
commit 24fd03d0c2
13 changed files with 129 additions and 120 deletions

View File

@ -61,13 +61,7 @@ void main()
#ifdef USE_CAVITY
float depth = texelFetch(depthBuffer, texel, 0).x;
vec3 position = get_view_space_from_depth(screenco, depth);
vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
if (diffuse_color.a == 0.0) {
normal_viewport = -normal_viewport;
}
vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg);
ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
#endif

View File

@ -19,9 +19,11 @@ float bayer_dither_noise() {
return dither_mat4x4[tx1.x][tx1.y];
}
#ifdef WORKBENCH_ENCODE_NORMALS
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
vec3 normal_decode(vec2 enc)
vec3 workbench_normal_decode(vec2 enc)
{
vec2 fenc = enc.xy * 4.0 - 2.0;
float f = dot(fenc, fenc);
@ -34,38 +36,18 @@ vec3 normal_decode(vec2 enc)
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
vec2 normal_encode(vec3 n)
vec2 workbench_normal_encode(vec3 n)
{
float p = sqrt(n.z * 8.0 + 8.0);
return vec2(n.xy / p + 0.5);
n.xy = clamp(n.xy / p + 0.5, 0.0, 1.0);
return n.xy;
}
void fresnel(vec3 I, vec3 N, float ior, out float kr)
{
float cosi = clamp(dot(I, N), -1.0, 1.0);
float etai = 1.0;
float etat = ior;
if (cosi > 0) {
etat = 1.0;
etai = ior;
}
// Compute sini using Snell's law
float sint = etai / etat * sqrt(max(0.0, 1.0 - cosi * cosi));
// Total internal reflection
if (sint >= 1) {
kr = 1;
}
else {
float cost = sqrt(max(0.0, 1.0 - sint * sint));
cosi = abs(cosi);
float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost));
float Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost));
kr = (Rs * Rs + Rp * Rp) / 2;
}
// As a consequence of the conservation of energy, transmittance is given by:
// kt = 1 - kr;
}
#else
/* Well just do nothing... */
# define workbench_normal_encode(a) (a)
# define workbench_normal_decode(a) (a)
#endif /* WORKBENCH_ENCODE_NORMALS */
float calculate_transparent_weight(float z, float alpha)
{

View File

@ -26,12 +26,10 @@ float calculate_curvature(usampler2D objectId, sampler2D normalBuffer, ivec2 tex
vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg;
vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg;
#ifdef WORKBENCH_ENCODE_NORMALS
normal_up = normal_decode(normal_up ).rg;
normal_down = normal_decode(normal_down ).rg;
normal_left = normal_decode(normal_left ).rg;
normal_right = normal_decode(normal_right).rg;
#endif
normal_up = workbench_normal_decode(normal_up ).rg;
normal_down = workbench_normal_decode(normal_down ).rg;
normal_left = workbench_normal_decode(normal_left ).rg;
normal_right = workbench_normal_decode(normal_right).rg;
float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r));

View File

@ -5,7 +5,7 @@ uniform mat4 ViewMatrixInverse;
uniform usampler2D objectId;
uniform sampler2D colorBuffer;
uniform sampler2D specularBuffer;
uniform sampler2D metallicBuffer;
uniform sampler2D normalBuffer;
/* normalBuffer contains viewport normals */
uniform sampler2D cavityBuffer;
@ -28,6 +28,7 @@ void main()
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
uint object_id = texelFetch(objectId, texel, 0).r;
/* TODO separate this into its own shader. */
#ifndef V3D_SHADING_OBJECT_OUTLINE
if (object_id == NO_OBJECT_ID) {
fragColor = vec4(background_color(world_data, uv_viewport.y), world_data.background_alpha);
@ -52,41 +53,42 @@ void main()
}
#endif /* !V3D_SHADING_OBJECT_OUTLINE */
vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
vec4 base_color = texelFetch(colorBuffer, texel, 0);
/* Do we need normals */
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
# ifdef WORKBENCH_ENCODE_NORMALS
vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
if (diffuse_color.a == 0.0) {
normal_viewport = -normal_viewport;
}
# else /* WORKBENCH_ENCODE_NORMALS */
vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
# endif /* WORKBENCH_ENCODE_NORMALS */
vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg);
#endif
vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix);
/* -------- SHADING --------- */
#ifdef V3D_LIGHTING_FLAT
vec3 shaded_color = diffuse_color.rgb;
vec3 shaded_color = base_color.rgb;
#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;
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 * diffuse_color.rgb;
vec3 shaded_color = matcap * base_color.rgb;
#elif defined(V3D_LIGHTING_STUDIO)
# ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
vec4 specular_data = texelFetch(specularBuffer, texel, 0);
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);
# else
vec4 specular_data = vec4(0.0);
float roughness = 0.0;
vec3 specular_color = vec3(0.0);
vec3 diffuse_color = base_color.rgb;
# endif
vec3 shaded_color = get_world_lighting(world_data,
diffuse_color.rgb, specular_data.rgb, specular_data.a,
diffuse_color, specular_color, roughness,
normal_viewport, I_vs);
#endif
@ -98,8 +100,6 @@ void main()
#ifdef V3D_SHADING_SHADOW
float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz);
/* The step function might be ok for meshes but it's
* clearly not the case for hairs. Do smoothstep in this case. */
float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor);
shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix);
#endif

View File

@ -9,8 +9,8 @@ uniform float alpha = 0.5;
uniform vec2 invertedViewportSize;
uniform vec4 viewvecs[3];
uniform vec4 materialDiffuseColor;
uniform vec4 materialSpecularColor;
uniform vec3 materialDiffuseColor;
uniform vec3 materialSpecularColor;
uniform float materialRoughness;
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
@ -40,7 +40,7 @@ void main()
discard;
}
#else
diffuse_color = materialDiffuseColor;
diffuse_color = vec4(materialDiffuseColor, 1.0);
#endif /* V3D_SHADING_TEXTURE_COLOR */
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
@ -62,7 +62,7 @@ void main()
#elif defined(V3D_LIGHTING_STUDIO)
vec3 shaded_color = get_world_lighting(world_data,
diffuse_color.rgb, materialSpecularColor.rgb, materialRoughness,
diffuse_color.rgb, materialSpecularColor, materialRoughness,
nor, I_vs);
#endif

View File

@ -1,7 +1,7 @@
uniform int object_id = 0;
uniform vec4 materialDiffuseColor;
uniform vec4 materialSpecularColor;
uniform vec3 materialDiffuseColor;
uniform float materialMetallic;
uniform float materialRoughness;
#ifdef V3D_SHADING_TEXTURE_COLOR
@ -23,9 +23,9 @@ flat in float hair_rand;
#endif
layout(location=0) out uint objectId;
layout(location=1) out vec4 diffuseColor;
layout(location=1) out vec4 colorRoughness;
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
layout(location=2) out vec4 specularColor;
layout(location=2) out float metallic;
#endif
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
# ifdef WORKBENCH_ENCODE_NORMALS
@ -39,41 +39,37 @@ void main()
{
objectId = uint(object_id);
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport;
n = normalize(n);
#endif
#ifdef V3D_SHADING_TEXTURE_COLOR
diffuseColor = texture(image, uv_interp);
if (diffuseColor.a < ImageTransparencyCutoff) {
colorRoughness = texture(image, uv_interp);
if (colorRoughness.a < ImageTransparencyCutoff) {
discard;
}
colorRoughness.a = materialRoughness;
#else
diffuseColor = vec4(materialDiffuseColor.rgb, 0.0);
colorRoughness = 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;
diffuseColor.rgb = clamp(diffuseColor.rgb - hair_color_variation, 0.0, 1.0);
colorRoughness = clamp(colorRoughness - hair_color_variation, 0.0, 1.0);
#endif
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
specularColor = vec4(materialSpecularColor.rgb, materialRoughness);
# ifdef HAIR_SHADER
specularColor.rgb = clamp(specularColor.rgb - hair_color_variation, 0.0, 1.0);
metallic = clamp(materialMetallic - hair_color_variation, 0.0, 1.0);
# else
metallic = materialMetallic;
# endif
#endif
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
# ifdef WORKBENCH_ENCODE_NORMALS
diffuseColor.a = float(gl_FrontFacing);
normalViewport = normal_encode(n);
# else /* WORKBENCH_ENCODE_NORMALS */
normalViewport = n;
# endif /* WORKBENCH_ENCODE_NORMALS */
# ifdef HAIR_SHADER
diffuseColor.a = 0.5;
# endif
#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport;
n = normalize(n);
normalViewport = workbench_normal_encode(n);
#endif
}

View File

@ -72,7 +72,7 @@ static struct {
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */
struct GPUTexture *specular_buffer_tx; /* ref only, not alloced */
struct GPUTexture *metallic_buffer_tx; /* ref only, not alloced */
struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
@ -377,20 +377,35 @@ void workbench_deferred_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]};
const GPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8UI;
const GPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
const GPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid);
e_data.object_id_tx = NULL;
e_data.color_buffer_tx = NULL;
e_data.composite_buffer_tx = NULL;
e_data.normal_buffer_tx = NULL;
e_data.cavity_buffer_tx = NULL;
e_data.metallic_buffer_tx = NULL;
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], id_tex_format, &draw_engine_workbench_solid);
e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
e_data.specular_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], comp_tex_format, &draw_engine_workbench_solid);
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
}
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),
GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.metallic_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
});
GPU_framebuffer_ensure_config(&fbl->cavity_fb, {
@ -455,7 +470,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
workbench_aa_create_pass(vedata, &e_data.color_buffer_tx);
}
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
if (CAVITY_ENABLED(wpd)) {
int state = DRW_STATE_WRITE_COLOR;
GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd));
psl->cavity_pass = DRW_pass_create("Cavity", state);
@ -493,7 +508,7 @@ static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl)
GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx),
GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.metallic_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
});
}
@ -530,11 +545,11 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
}
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
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, "specularBuffer", &e_data.specular_buffer_tx);
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);
@ -663,7 +678,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
workbench_material_copy(material, &material_template);
DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob);
workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true);
BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
}
@ -706,7 +721,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
shader);
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
workbench_material_shgroup_uniform(wpd, shgrp, material, ob);
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true);
}
}
}
@ -937,7 +952,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->ghost_resolve_pass);
}
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
if (CAVITY_ENABLED(wpd)) {
GPU_framebuffer_bind(fbl->cavity_fb);
DRW_draw_pass(psl->cavity_pass);
}

View File

@ -171,7 +171,8 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_bu
int previous_jitter_index = effect_info->jitter_index;
{
DRW_texture_ensure_fullscreen_2D(&txl->history_buffer_tx, GPU_RGBA16F, 0);
const GPUTextureFormat hist_buffer_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_RGBA8;
DRW_texture_ensure_fullscreen_2D(&txl->history_buffer_tx, hist_buffer_format, 0);
DRW_texture_ensure_fullscreen_2D(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
}

View File

@ -176,7 +176,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
}
workbench_material_shgroup_uniform(wpd, grp, material, ob);
workbench_material_shgroup_uniform(wpd, grp, material, ob, false);
material->shgrp = grp;
/* Depth */
@ -444,7 +444,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
psl->transparent_accum_pass,
shader);
DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
workbench_material_shgroup_uniform(wpd, shgrp, material, ob);
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false);
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
/* Hairs have lots of layer and can rapidly become the most prominent surface.
* So lower their alpha artificially. */

View File

@ -14,12 +14,15 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
{
/* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
copy_v4_fl4(data->diffuse_color, 0.8f, 0.8f, 0.8f, 1.0f);
copy_v4_fl4(data->specular_color, 0.05f, 0.05f, 0.05f, 1.0f); /* Dielectric: 5% reflective. */
data->roughness = 0.5; /* sqrtf(0.25f); */
copy_v3_fl3(data->diffuse_color, 0.8f, 0.8f, 0.8f);
copy_v3_v3(data->base_color, data->diffuse_color);
copy_v3_fl3(data->specular_color, 0.05f, 0.05f, 0.05f); /* Dielectric: 5% reflective. */
data->metallic = 0.0f;
data->roughness = 0.5f; /* sqrtf(0.25f); */
if (color_type == V3D_SHADING_SINGLE_COLOR) {
copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
copy_v3_v3(data->base_color, data->diffuse_color);
}
else if (color_type == V3D_SHADING_RANDOM_COLOR) {
uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
@ -30,17 +33,21 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
float hue = BLI_hash_int_01(hash);
float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
hsv_to_rgb_v(hsv, data->diffuse_color);
copy_v3_v3(data->base_color, data->diffuse_color);
}
else {
/* V3D_SHADING_MATERIAL_COLOR */
if (mat) {
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
copy_v3_v3(data->base_color, &mat->r);
mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
data->metallic = mat->metallic;
data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
}
else {
copy_v3_v3(data->base_color, &mat->r);
copy_v3_v3(data->diffuse_color, &mat->r);
}
}
@ -151,18 +158,24 @@ int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *i
}
void workbench_material_shgroup_uniform(
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob)
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob,
const bool use_metallic)
{
if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) {
GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f);
DRW_shgroup_uniform_texture(grp, "image", tex);
}
else {
DRW_shgroup_uniform_vec4(grp, "materialDiffuseColor", material->diffuse_color, 1);
DRW_shgroup_uniform_vec3(grp, "materialDiffuseColor", (use_metallic) ? material->base_color : material->diffuse_color, 1);
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
DRW_shgroup_uniform_vec4(grp, "materialSpecularColor", material->specular_color, 1);
if (use_metallic) {
DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
}
else {
DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
}
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
}
}
@ -170,8 +183,10 @@ void workbench_material_shgroup_uniform(
void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material)
{
dest_material->object_id = source_material->object_id;
copy_v4_v4(dest_material->diffuse_color, source_material->diffuse_color);
copy_v4_v4(dest_material->specular_color, source_material->specular_color);
copy_v3_v3(dest_material->base_color, source_material->base_color);
copy_v3_v3(dest_material->diffuse_color, source_material->diffuse_color);
copy_v3_v3(dest_material->specular_color, source_material->specular_color);
dest_material->metallic = source_material->metallic;
dest_material->roughness = source_material->roughness;
dest_material->ima = source_material->ima;
}

View File

@ -53,6 +53,7 @@
#define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP))
#define SSAO_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_SSAO) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
#define CURVATURE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_CURVATURE) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
#define CAVITY_ENABLED(wpd) (CURVATURE_ENABLED(wpd) || SSAO_ENABLED(wpd))
#define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
#define GHOST_ENABLED(psl) (!DRW_pass_is_empty(psl->ghost_prepass_pass) || !DRW_pass_is_empty(psl->ghost_prepass_hair_pass))
@ -219,8 +220,10 @@ typedef struct WORKBENCH_EffectInfo {
} WORKBENCH_EffectInfo;
typedef struct WORKBENCH_MaterialData {
float diffuse_color[4];
float specular_color[4];
float base_color[3];
float diffuse_color[3];
float specular_color[3];
float metallic;
float roughness;
int object_id;
int color_type;
@ -297,7 +300,8 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost);
int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
void workbench_material_shgroup_uniform(
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob);
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob,
const bool use_metallic);
void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material);
/* workbench_studiolight.c */

View File

@ -33,6 +33,8 @@ static bool drw_texture_format_supports_framebuffer(GPUTextureFormat format)
switch (format) {
/* Only add formats that are COMPATIBLE with FB.
* Generally they are multiple of 16bit. */
case GPU_R8:
case GPU_R8UI:
case GPU_R16F:
case GPU_R16I:
case GPU_R16UI:

View File

@ -178,8 +178,8 @@ static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat
}
else {
/* Integer formats */
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R8UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
BLI_assert(data_format == GPU_DATA_UNSIGNED_INT);
}
else {
@ -218,8 +218,8 @@ static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_fo
}
else {
/* Integer formats */
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
return GPU_DATA_UNSIGNED_INT;
}
else {
@ -260,7 +260,7 @@ static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormat
}
else {
/* Integer formats */
if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
*format_flag |= GPU_FORMAT_INTEGER;
switch (gpu_get_component_count(data_type)) {
@ -327,6 +327,7 @@ static uint gpu_get_bytesize(GPUTextureFormat data_type)
case GPU_R16:
return 2;
case GPU_R8:
case GPU_R8UI:
return 1;
default:
BLI_assert(!"Texture format incorrect or unsupported\n");
@ -360,6 +361,7 @@ static GLenum gpu_get_gl_internalformat(GPUTextureFormat format)
case GPU_RG16UI: return GL_RG16UI;
case GPU_R16: return GL_R16;
case GPU_R8: return GL_R8;
case GPU_R8UI: return GL_R8UI;
/* Special formats texture & renderbuffer */
case GPU_R11F_G11F_B10F: return GL_R11F_G11F_B10F;
case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;