diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 71c05c2c763..a99c183f6ef 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -539,17 +539,14 @@ set(GLSL_SRC engines/workbench/workbench_shader_shared.h intern/shaders/common_aabb_lib.glsl - intern/shaders/common_attribute_lib.glsl intern/shaders/common_colormanagement_lib.glsl intern/shaders/common_debug_draw_lib.glsl intern/shaders/common_debug_shape_lib.glsl intern/shaders/common_fullscreen_vert.glsl intern/shaders/common_fxaa_lib.glsl - intern/shaders/common_gpencil_lib.glsl intern/shaders/common_hair_lib.glsl intern/shaders/common_hair_refine_comp.glsl intern/shaders/common_intersect_lib.glsl - intern/shaders/common_pointcloud_lib.glsl intern/shaders/common_shape_lib.glsl intern/shaders/subdiv_custom_data_interp_comp.glsl intern/shaders/subdiv_ibo_lines_comp.glsl diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl index 880e571f5d4..66939fec363 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl @@ -7,9 +7,8 @@ VERTEX_SHADER_CREATE_INFO(eevee_clip_plane) VERTEX_SHADER_CREATE_INFO(eevee_geom_gpencil) +#include "draw_grease_pencil_lib.glsl" #include "draw_model_lib.glsl" -/* Grease pencil includes commmon_view_lib. */ -// #include "common_gpencil_lib.glsl" #include "eevee_attributes_gpencil_lib.glsl" #include "eevee_surf_lib.glsl" #include "eevee_velocity_lib.glsl" diff --git a/source/blender/draw/intern/shaders/common_attribute_lib.glsl b/source/blender/draw/intern/shaders/common_attribute_lib.glsl deleted file mode 100644 index dcb6d3968f4..00000000000 --- a/source/blender/draw/intern/shaders/common_attribute_lib.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-FileCopyrightText: 2022 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "gpu_glsl_cpp_stubs.hh" - -/* Prototype of functions to implement to load attributes data. - * Implementation changes based on object data type. */ - -#ifndef GPU_METAL /* MSL does not require prototypes. */ -vec3 attr_load_orco(vec4 orco); -vec4 attr_load_tangent(vec4 tangent); -vec4 attr_load_vec4(vec4 attr); -vec3 attr_load_vec3(vec3 attr); -vec2 attr_load_vec2(vec2 attr); -float attr_load_float(float attr); - -vec3 attr_load_orco(samplerBuffer orco); -vec4 attr_load_tangent(samplerBuffer tangent); -vec4 attr_load_vec4(samplerBuffer attr); -vec3 attr_load_vec3(samplerBuffer attr); -vec2 attr_load_vec2(samplerBuffer attr); -float attr_load_float(samplerBuffer attr); - -vec3 attr_load_orco(sampler3D orco); -vec4 attr_load_tangent(sampler3D tangent); -vec4 attr_load_vec4(sampler3D tex); -vec3 attr_load_vec3(sampler3D tex); -vec2 attr_load_vec2(sampler3D tex); -float attr_load_float(sampler3D tex); - -float attr_load_temperature_post(float attr); -vec4 attr_load_color_post(vec4 attr); -vec4 attr_load_uniform(vec4 attr, const uint attr_hash); -#endif diff --git a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl deleted file mode 100644 index b59dbd4f8f5..00000000000 --- a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl +++ /dev/null @@ -1,400 +0,0 @@ -/* SPDX-FileCopyrightText: 2022-2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "draw_model_lib.glsl" -#include "draw_view_lib.glsl" -#include "gpu_shader_math_matrix_lib.glsl" -#include "gpu_shader_math_vector_lib.glsl" -#include "gpu_shader_utildefines_lib.glsl" - -#ifndef DRW_GPENCIL_INFO -# error Missing additional info draw_gpencil -#endif - -#ifdef GPU_FRAGMENT_SHADER -float gpencil_stroke_round_cap_mask(vec2 p1, vec2 p2, vec2 aspect, float thickness, float hardfac) -{ - /* We create our own uv space to avoid issues with triangulation and linear - * interpolation artifacts. */ - vec2 line = p2.xy - p1.xy; - vec2 pos = gl_FragCoord.xy - p1.xy; - float line_len = length(line); - float half_line_len = line_len * 0.5; - /* Normalize */ - line = (line_len > 0.0) ? (line / line_len) : vec2(1.0, 0.0); - /* Create a uv space that englobe the whole segment into a capsule. */ - vec2 uv_end; - uv_end.x = max(abs(dot(line, pos) - half_line_len) - half_line_len, 0.0); - uv_end.y = dot(vec2(-line.y, line.x), pos); - /* Divide by stroke radius. */ - uv_end /= thickness; - uv_end *= aspect; - - float dist = clamp(1.0 - length(uv_end) * 2.0, 0.0, 1.0); - if (hardfac > 0.999) { - return step(1e-8, dist); - } - else { - /* Modulate the falloff profile */ - float hardness = 1.0 - hardfac; - dist = pow(dist, mix(0.01, 10.0, hardness)); - return smoothstep(0.0, 1.0, dist); - } -} -#endif - -vec2 gpencil_decode_aspect(int packed_data) -{ - float asp = float(uint(packed_data) & 0x1FFu) * (1.0 / 255.0); - return (asp > 1.0) ? vec2(1.0, (asp - 1.0)) : vec2(asp, 1.0); -} - -float gpencil_decode_uvrot(int packed_data) -{ - uint udata = uint(packed_data); - float uvrot = 1e-8 + float((udata & 0x1FE00u) >> 9u) * (1.0 / 255.0); - return ((udata & 0x20000u) != 0u) ? -uvrot : uvrot; -} - -float gpencil_decode_hardness(int packed_data) -{ - return float((uint(packed_data) & 0x3FC0000u) >> 18u) * (1.0 / 255.0); -} - -vec2 gpencil_project_to_screenspace(vec4 v, vec4 viewport_size) -{ - return ((v.xy / v.w) * 0.5 + 0.5) * viewport_size.xy; -} - -float gpencil_stroke_thickness_modulate(float thickness, vec4 ndc_pos, vec4 viewport_size) -{ - /* Modify stroke thickness by object and layer factors. */ - thickness = max(1.0, thickness * gpThicknessScale + gpThicknessOffset); - - if (gpThicknessIsScreenSpace) { - /* Multiply offset by view Z so that offset is constant in screen-space. - * (e.i: does not change with the distance to camera) */ - thickness *= ndc_pos.w; - } - else { - /* World space point size. */ - thickness *= gpThicknessWorldScale * ProjectionMatrix[1][1] * viewport_size.y; - } - return thickness; -} - -float gpencil_clamp_small_stroke_thickness(float thickness, vec4 ndc_pos) -{ - /* To avoid aliasing artifacts, we clamp the line thickness and - * reduce its opacity in the fragment shader. */ - float min_thickness = ndc_pos.w * 1.3; - thickness = max(min_thickness, thickness); - - return thickness; -} - -#ifdef GPU_VERTEX_SHADER - -int gpencil_stroke_point_id() -{ - return (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT; -} - -bool gpencil_is_stroke_vertex() -{ - return flag_test(gl_VertexID, GP_IS_STROKE_VERTEX_BIT); -} - -/** - * Returns value of gl_Position. - * - * To declare in vertex shader. - * in ivec4 ma, ma1, ma2, ma3; - * in vec4 pos, pos1, pos2, pos3, uv1, uv2, col1, col2, fcol1; - * - * All of these attributes are quad loaded the same way - * as GL_LINES_ADJACENCY would feed a geometry shader: - * - ma reference the previous adjacency point. - * - ma1 reference the current line first point. - * - ma2 reference the current line second point. - * - ma3 reference the next adjacency point. - * Note that we are rendering quad instances and not using any index buffer - *(except for fills). - * - * Material : x is material index, y is stroke_id, z is point_id, - * w is aspect & rotation & hardness packed. - * Position : contains thickness in 4th component. - * UV : xy is UV for fills, z is U of stroke, w is strength. - * - * - * WARNING: Max attribute count is actually 14 because OSX OpenGL implementation - * considers gl_VertexID and gl_InstanceID as vertex attribute. (see #74536) - */ -vec4 gpencil_vertex(vec4 viewport_size, - gpMaterialFlag material_flags, - vec2 alignment_rot, - /* World Position. */ - out vec3 out_P, - /* World Normal. */ - out vec3 out_N, - /* Vertex Color. */ - out vec4 out_color, - /* Stroke Strength. */ - out float out_strength, - /* UV coordinates. */ - out vec2 out_uv, - /* Screen-Space segment endpoints. */ - out vec4 out_sspos, - /* Stroke aspect ratio. */ - out vec2 out_aspect, - /* Stroke thickness (x: clamped, y: unclamped). */ - out vec2 out_thickness, - /* Stroke hardness. */ - out float out_hardness) -{ - int stroke_point_id = (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT; - - /* Attribute Loading. */ - vec4 pos = texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 0); - vec4 pos1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 0); - vec4 pos2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 0); - vec4 pos3 = texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 0); - ivec4 ma = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 1)); - ivec4 ma1 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 1)); - ivec4 ma2 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 1)); - ivec4 ma3 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 1)); - vec4 uv1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 2); - vec4 uv2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 2); - - vec4 col1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 0); - vec4 col2 = texelFetch(gp_col_tx, (stroke_point_id + 1) * 2 + 0); - vec4 fcol1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 1); - -# define thickness1 pos1.w -# define thickness2 pos2.w -# define strength1 uv1.w -# define strength2 uv2.w -/* Packed! need to be decoded. */ -# define hardness1 ma1.w -# define hardness2 ma2.w -# define uvrot1 ma1.w -# define aspect1 ma1.w - - vec4 out_ndc; - - if (gpencil_is_stroke_vertex()) { - bool is_dot = flag_test(material_flags, GP_STROKE_ALIGNMENT); - bool is_squares = !flag_test(material_flags, GP_STROKE_DOTS); - - /* Special Case. Stroke with single vert are rendered as dots. Do not discard them. */ - if (!is_dot && ma.x == -1 && ma2.x == -1) { - is_dot = true; - is_squares = false; - } - - /* Endpoints, we discard the vertices. */ - if (!is_dot && ma2.x == -1) { - /* We set the vertex at the camera origin to generate 0 fragments. */ - out_ndc = vec4(0.0, 0.0, -3e36, 0.0); - return out_ndc; - } - - /* Avoid using a vertex attribute for quad positioning. */ - float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */ - float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */ - - bool use_curr = is_dot || (x == -1.0); - - vec3 wpos_adj = transform_point(ModelMatrix, (use_curr) ? pos.xyz : pos3.xyz); - vec3 wpos1 = transform_point(ModelMatrix, pos1.xyz); - vec3 wpos2 = transform_point(ModelMatrix, pos2.xyz); - - vec3 T; - if (is_dot) { - /* Shade as facing billboards. */ - T = ViewMatrixInverse[0].xyz; - } - else if (use_curr && ma.x != -1) { - T = wpos1 - wpos_adj; - } - else { - T = wpos2 - wpos1; - } - T = safe_normalize(T); - - vec3 B = cross(T, ViewMatrixInverse[2].xyz); - out_N = normalize(cross(B, T)); - - vec4 ndc_adj = drw_point_world_to_homogenous(wpos_adj); - vec4 ndc1 = drw_point_world_to_homogenous(wpos1); - vec4 ndc2 = drw_point_world_to_homogenous(wpos2); - - out_ndc = (use_curr) ? ndc1 : ndc2; - out_P = (use_curr) ? wpos1 : wpos2; - out_strength = abs((use_curr) ? strength1 : strength2); - - vec2 ss_adj = gpencil_project_to_screenspace(ndc_adj, viewport_size); - vec2 ss1 = gpencil_project_to_screenspace(ndc1, viewport_size); - vec2 ss2 = gpencil_project_to_screenspace(ndc2, viewport_size); - /* Screen-space Lines tangents. */ - float line_len; - vec2 line = safe_normalize_and_get_length(ss2 - ss1, line_len); - vec2 line_adj = safe_normalize((use_curr) ? (ss1 - ss_adj) : (ss_adj - ss2)); - - float thickness = abs((use_curr) ? thickness1 : thickness2); - thickness = gpencil_stroke_thickness_modulate(thickness, out_ndc, viewport_size); - float clamped_thickness = gpencil_clamp_small_stroke_thickness(thickness, out_ndc); - - out_uv = vec2(x, y) * 0.5 + 0.5; - out_hardness = gpencil_decode_hardness(use_curr ? hardness1 : hardness2); - - if (is_dot) { - uint alignment_mode = material_flags & GP_STROKE_ALIGNMENT; - - /* For one point strokes use object alignment. */ - if (alignment_mode == GP_STROKE_ALIGNMENT_STROKE && ma.x == -1 && ma2.x == -1) { - alignment_mode = GP_STROKE_ALIGNMENT_OBJECT; - } - - vec2 x_axis; - if (alignment_mode == GP_STROKE_ALIGNMENT_STROKE) { - x_axis = (ma2.x == -1) ? line_adj : line; - } - else if (alignment_mode == GP_STROKE_ALIGNMENT_FIXED) { - /* Default for no-material drawing. */ - x_axis = vec2(1.0, 0.0); - } - else { /* GP_STROKE_ALIGNMENT_OBJECT */ - vec4 ndc_x = drw_point_world_to_homogenous(wpos1 + ModelMatrix[0].xyz); - vec2 ss_x = gpencil_project_to_screenspace(ndc_x, viewport_size); - x_axis = safe_normalize(ss_x - ss1); - } - - /* Rotation: Encoded as Cos + Sin sign. */ - float uv_rot = gpencil_decode_uvrot(uvrot1); - float rot_sin = sqrt(max(0.0, 1.0 - uv_rot * uv_rot)) * sign(uv_rot); - float rot_cos = abs(uv_rot); - /* TODO(@fclem): Optimize these 2 matrix multiply into one by only having one rotation angle - * and using a cosine approximation. */ - x_axis = mat2(rot_cos, -rot_sin, rot_sin, rot_cos) * x_axis; - x_axis = mat2(alignment_rot.x, -alignment_rot.y, alignment_rot.y, alignment_rot.x) * x_axis; - /* Rotate 90 degrees counter-clockwise. */ - vec2 y_axis = vec2(-x_axis.y, x_axis.x); - - out_aspect = gpencil_decode_aspect(aspect1); - - x *= out_aspect.x; - y *= out_aspect.y; - - /* Invert for vertex shader. */ - out_aspect = 1.0 / out_aspect; - - out_ndc.xy += (x * x_axis + y * y_axis) * viewport_size.zw * clamped_thickness; - - out_sspos.xy = ss1; - out_sspos.zw = ss1 + x_axis * 0.5; - out_thickness.x = (is_squares) ? 1e18 : (clamped_thickness / out_ndc.w); - out_thickness.y = (is_squares) ? 1e18 : (thickness / out_ndc.w); - } - else { - bool is_stroke_start = (ma.x == -1 && x == -1); - bool is_stroke_end = (ma3.x == -1 && x == 1); - - /* Mitter tangent vector. */ - vec2 miter_tan = safe_normalize(line_adj + line); - float miter_dot = dot(miter_tan, line_adj); - /* Break corners after a certain angle to avoid really thick corners. */ - const float miter_limit = 0.5; /* cos(60 degrees) */ - bool miter_break = (miter_dot < miter_limit); - miter_tan = (miter_break || is_stroke_start || is_stroke_end) ? line : - (miter_tan / miter_dot); - /* Rotate 90 degrees counter-clockwise. */ - vec2 miter = vec2(-miter_tan.y, miter_tan.x); - - out_sspos.xy = ss1; - out_sspos.zw = ss2; - out_thickness.x = clamped_thickness / out_ndc.w; - out_thickness.y = thickness / out_ndc.w; - out_aspect = vec2(1.0); - - vec2 screen_ofs = miter * y; - - /* Reminder: we packed the cap flag into the sign of strength and thickness sign. */ - if ((is_stroke_start && strength1 > 0.0) || (is_stroke_end && thickness1 > 0.0) || - (miter_break && !is_stroke_start && !is_stroke_end)) - { - screen_ofs += line * x; - } - - out_ndc.xy += screen_ofs * viewport_size.zw * clamped_thickness; - - out_uv.x = (use_curr) ? uv1.z : uv2.z; - } - - out_color = (use_curr) ? col1 : col2; - } - else { - out_P = transform_point(ModelMatrix, pos1.xyz); - out_ndc = drw_point_world_to_homogenous(out_P); - out_uv = uv1.xy; - out_thickness.x = 1e18; - out_thickness.y = 1e20; - out_hardness = 1.0; - out_aspect = vec2(1.0); - out_sspos = vec4(0.0); - - /* Flat normal following camera and object bounds. */ - vec3 V = drw_world_incident_vector(ModelMatrix[3].xyz); - vec3 N = drw_normal_world_to_object(V); - N *= OrcoTexCoFactors[1].xyz; - N = drw_normal_object_to_world(N); - out_N = safe_normalize(N); - - /* Decode fill opacity. */ - out_color = vec4(fcol1.rgb, floor(fcol1.a / 10.0) / 10000.0); - - /* We still offset the fills a little to avoid overlaps */ - out_ndc.z += 0.000002; - } - -# undef thickness1 -# undef thickness2 -# undef strength1 -# undef strength2 -# undef hardness1 -# undef hardness2 -# undef uvrot1 -# undef aspect1 - - return out_ndc; -} - -vec4 gpencil_vertex(vec4 viewport_size, - out vec3 out_P, - out vec3 out_N, - out vec4 out_color, - out float out_strength, - out vec2 out_uv, - out vec4 out_sspos, - out vec2 out_aspect, - out vec2 out_thickness, - out float out_hardness) -{ - return gpencil_vertex(viewport_size, - gpMaterialFlag(0u), - vec2(1.0, 0.0), - out_P, - out_N, - out_color, - out_strength, - out_uv, - out_sspos, - out_aspect, - out_thickness, - out_hardness); -} - -#endif diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl deleted file mode 100644 index 2f0e2c0d61d..00000000000 --- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-FileCopyrightText: 2020-2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "draw_model_lib.glsl" -#include "draw_view_lib.glsl" - -#ifdef POINTCLOUD_SHADER -# define COMMON_POINTCLOUD_LIB - -# ifndef DRW_POINTCLOUD_INFO -# error Ensure createInfo includes draw_pointcloud. -# endif - -int pointcloud_get_point_id() -{ -# ifdef GPU_VERTEX_SHADER - /* Remove shape indices. */ - return gl_VertexID >> 3; -# endif - return 0; -} - -mat3 pointcloud_get_facing_matrix(vec3 p) -{ - mat3 facing_mat; - facing_mat[2] = drw_world_incident_vector(p); - facing_mat[1] = normalize(cross(ViewMatrixInverse[0].xyz, facing_mat[2])); - facing_mat[0] = cross(facing_mat[1], facing_mat[2]); - return facing_mat; -} - -/* Returns world center position and radius. */ -void pointcloud_get_pos_and_radius(out vec3 outpos, out float outradius) -{ - int id = pointcloud_get_point_id(); - vec4 pos_rad = texelFetch(ptcloud_pos_rad_tx, id); - outpos = drw_point_object_to_world(pos_rad.xyz); - outradius = dot(abs(to_float3x3(ModelMatrix) * pos_rad.www), vec3(1.0 / 3.0)); -} - -/* Return world position and normal. */ -void pointcloud_get_pos_nor_radius(out vec3 outpos, out vec3 outnor, out float outradius) -{ - vec3 p; - float radius; - pointcloud_get_pos_and_radius(p, radius); - - mat3 facing_mat = pointcloud_get_facing_matrix(p); - - uint vert_id = 0u; -# ifdef GPU_VERTEX_SHADER - /* Mask point indices. */ - vert_id = uint(gl_VertexID) & ~(0xFFFFFFFFu << 3u); -# endif - - vec3 pos_inst = vec3(0.0); - - switch (vert_id) { - case 0: - pos_inst.z = 1.0; - break; - case 1: - pos_inst.x = 1.0; - break; - case 2: - pos_inst.y = 1.0; - break; - case 3: - pos_inst.x = -1.0; - break; - case 4: - pos_inst.y = -1.0; - break; - } - - outnor = facing_mat * pos_inst; - outpos = p + outnor * radius; - outradius = radius; -} - -/* Return world position and normal. */ -void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor) -{ - vec3 nor, pos; - float radius; - pointcloud_get_pos_nor_radius(pos, nor, radius); - outpos = pos; - outnor = nor; -} - -vec3 pointcloud_get_pos() -{ - vec3 outpos, outnor; - pointcloud_get_pos_and_nor(outpos, outnor); - return outpos; -} - -float pointcloud_get_customdata_float(const samplerBuffer cd_buf) -{ - int id = pointcloud_get_point_id(); - return texelFetch(cd_buf, id).r; -} - -vec2 pointcloud_get_customdata_vec2(const samplerBuffer cd_buf) -{ - int id = pointcloud_get_point_id(); - return texelFetch(cd_buf, id).rg; -} - -vec3 pointcloud_get_customdata_vec3(const samplerBuffer cd_buf) -{ - int id = pointcloud_get_point_id(); - return texelFetch(cd_buf, id).rgb; -} - -vec4 pointcloud_get_customdata_vec4(const samplerBuffer cd_buf) -{ - int id = pointcloud_get_point_id(); - return texelFetch(cd_buf, id).rgba; -} - -vec2 pointcloud_get_barycentric() -{ - /* TODO: To be implemented. */ - return vec2(0.0); -} -#endif