diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-02-29 20:09:07 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-02-29 20:28:58 +0300 |
commit | 76a7ea0b7137b08ec12fa5181d448865e4440f00 (patch) | |
tree | c5888bcac8206e82354e1530dfb1450ab3a4e21c | |
parent | 46f8367eaca30607ef9623ae8e020d0ae210bec4 (diff) |
Workbench: Refactor: Add matcap support
7 files changed, 59 insertions, 22 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 6478bc46333..c876dd4136a 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -263,6 +263,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_ghost_resolve_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_image_lib.glsl SRC) +data_to_c_simple(engines/workbench/shaders/workbench_matcap_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_material_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_curvature_lib.glsl SRC) 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 4af03d8b82e..5131b9dae06 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -122,17 +122,3 @@ vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat) return vec3(0.0, 0.0, 1.0); } } - -vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped) -{ - /* Quick creation of an orthonormal basis */ - float a = 1.0 / (1.0 + I.z); - float b = -I.x * I.y * a; - vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x); - vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y); - vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N)); - if (flipped) { - matcap_uv.x = -matcap_uv.x; - } - return matcap_uv * 0.496 + 0.5; -} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index 19f6ce5f14c..915a1596180 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -1,6 +1,7 @@ #pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(workbench_common_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_matcap_lib.glsl) #pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl) uniform sampler2D materialBuffer; @@ -12,25 +13,25 @@ out vec4 fragColor; void main() { + /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ + vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix); vec3 normal = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st)); vec4 mat_data = texture(materialBuffer, uvcoordsvar.st); - vec3 I_vs = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix); - vec3 base_color = mat_data.rgb; float roughness, metallic; workbench_float_pair_decode(mat_data.a, roughness, metallic); - vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic); - vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic); - #ifdef V3D_LIGHTING_MATCAP - fragColor.rgb = vec3(1.0); + /* When using matcaps, mat_data.a is the backface sign. */ + normal = (mat_data.a > 0.0) ? normal : -normal; + + fragColor.rgb = get_matcap_lighting(base_color, normal, I); #endif #ifdef V3D_LIGHTING_STUDIO - fragColor.rgb = get_world_lighting(diffuse_color, specular_color, roughness, normal, I_vs); + fragColor.rgb = get_world_lighting(base_color, roughness, metallic, normal, I); #endif #ifdef V3D_LIGHTING_FLAT diff --git a/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl new file mode 100644 index 00000000000..3aa37f1971d --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl @@ -0,0 +1,32 @@ + +#pragma BLENDER_REQUIRE(workbench_data_lib.glsl) + +vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped) +{ + /* Quick creation of an orthonormal basis */ + float a = 1.0 / (1.0 + I.z); + float b = -I.x * I.y * a; + vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x); + vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y); + vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N)); + if (flipped) { + matcap_uv.x = -matcap_uv.x; + } + return matcap_uv * 0.496 + 0.5; +} + +uniform sampler2D matcapDiffuseImage; +uniform sampler2D matcapSpecularImage; + +uniform bool useSpecular = false; + +vec3 get_matcap_lighting(vec3 base_color, vec3 N, vec3 I) +{ + bool flipped = world_data.matcap_orientation != 0; + vec2 uv = matcap_uv_compute(I, N, flipped); + + vec3 diffuse = textureLod(matcapDiffuseImage, uv, 0.0).rgb; + vec3 specular = textureLod(matcapSpecularImage, uv, 0.0).rgb; + + return diffuse * base_color + specular * float(useSpecular); +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index 58e8370537a..61e4bc06411 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -43,8 +43,11 @@ vec4 wrapped_lighting(vec4 NL, vec4 w) return clamp((NL + w) * denom, 0.0, 1.0); } -vec3 get_world_lighting(vec3 diffuse_color, vec3 specular_color, float roughness, vec3 N, vec3 I) +vec3 get_world_lighting(vec3 base_color, float roughness, float metallic, vec3 N, vec3 I) { + vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic); + vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic); + vec3 specular_light = world_data.ambient_color.rgb; vec3 diffuse_light = world_data.ambient_color.rgb; vec4 wrap = vec4(world_data.lights[0].diffuse_color_wrap.a, diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c index 07692abebcb..0a2a7733e56 100644 --- a/source/blender/draw/engines/workbench/workbench_opaque.c +++ b/source/blender/draw/engines/workbench/workbench_opaque.c @@ -126,6 +126,18 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data) DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_texture(grp, "materialBuffer", wpd->material_buffer_tx); DRW_shgroup_uniform_texture(grp, "normalBuffer", wpd->normal_buffer_tx); + + if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) { + BKE_studiolight_ensure_flag(wpd->studio_light, + STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE | + STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE); + bool use_spec = workbench_is_specular_highlight_enabled(wpd); + struct GPUTexture *diff_tx = wpd->studio_light->matcap_diffuse.gputexture; + struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture; + DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx); + DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", use_spec ? spec_tx : diff_tx); + DRW_shgroup_uniform_bool_copy(grp, "useSpecular", use_spec); + } DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } } diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c index 7a0883e632d..8f3dbb78ac2 100644 --- a/source/blender/draw/engines/workbench/workbench_shader.c +++ b/source/blender/draw/engines/workbench/workbench_shader.c @@ -48,6 +48,7 @@ extern char datatoc_workbench_shadow_debug_frag_glsl[]; extern char datatoc_workbench_cavity_lib_glsl[]; extern char datatoc_workbench_common_lib_glsl[]; extern char datatoc_workbench_image_lib_glsl[]; +extern char datatoc_workbench_matcap_lib_glsl[]; extern char datatoc_workbench_material_lib_glsl[]; extern char datatoc_workbench_data_lib_glsl[]; extern char datatoc_workbench_object_outline_lib_glsl[]; @@ -83,6 +84,7 @@ void workbench_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, workbench_image_lib); DRW_SHADER_LIB_ADD(e_data.lib, workbench_material_lib); DRW_SHADER_LIB_ADD(e_data.lib, workbench_data_lib); + DRW_SHADER_LIB_ADD(e_data.lib, workbench_matcap_lib); DRW_SHADER_LIB_ADD(e_data.lib, workbench_object_outline_lib); DRW_SHADER_LIB_ADD(e_data.lib, workbench_curvature_lib); DRW_SHADER_LIB_ADD(e_data.lib, workbench_world_light_lib); |