diff options
Diffstat (limited to 'source/blender/draw/modes/shaders')
9 files changed, 163 insertions, 40 deletions
diff --git a/source/blender/draw/modes/shaders/common_view_lib.glsl b/source/blender/draw/modes/shaders/common_view_lib.glsl index 20a54947db7..76089d1ae41 100644 --- a/source/blender/draw/modes/shaders/common_view_lib.glsl +++ b/source/blender/draw/modes/shaders/common_view_lib.glsl @@ -1,4 +1,5 @@ #define COMMON_VIEW_LIB +#define DRW_RESOURCE_CHUNK_LEN 512 /* keep in sync with DRWManager.view_data */ layout(std140) uniform viewBlock @@ -23,8 +24,77 @@ layout(std140) uniform viewBlock _world_clip_planes_calc_clip_distance(p, clipPlanes) #endif +uniform int resourceChunk; + +#ifdef GPU_VERTEX_SHADER +# ifdef GL_ARB_shader_draw_parameters +# define baseInstance gl_BaseInstanceARB +# else /* no ARB_shader_draw_parameters */ +uniform int baseInstance; +# endif + +# ifdef IN_PLACE_INSTANCES +/* When drawing instances of an object at the same position. */ +# define instanceId 0 +# elif defined(GPU_DEPRECATED_AMD_DRIVER) +/* A driver bug make it so that when using an attribute with GL_INT_2_10_10_10_REV as format, + * the gl_InstanceID is incremented by the 2 bit component of the attrib. + * Ignore gl_InstanceID then. */ +# define instanceId 0 +# else +# define instanceId gl_InstanceID +# endif + +# define resource_id (baseInstance + instanceId) + +/* Use this to declare and pass the value if + * the fragment shader uses the resource_id. */ +# define RESOURCE_ID_VARYING flat out int resourceIDFrag; +# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id; +# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id; +#endif + +/* If used in a fragment / geometry shader, we pass + * resource_id as varying. */ +#ifdef GPU_GEOMETRY_SHADER +# define RESOURCE_ID_VARYING \ + flat out int resourceIDFrag; \ + flat in int resourceIDGeom[]; + +# define resource_id resourceIDGeom +# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i]; +#endif + +#ifdef GPU_FRAGMENT_SHADER +flat in int resourceIDFrag; +# define resource_id resourceIDFrag +#endif + +#if !defined(GPU_INTEL) && !defined(GPU_DEPRECATED_AMD_DRIVER) && !defined(OS_MAC) +struct ObjectMatrices { + mat4 drw_modelMatrix; + mat4 drw_modelMatrixInverse; +}; + +layout(std140) uniform modelBlock +{ + ObjectMatrices drw_matrices[DRW_RESOURCE_CHUNK_LEN]; +}; + +# define ModelMatrix (drw_matrices[resource_id].drw_modelMatrix) +# define ModelMatrixInverse (drw_matrices[resource_id].drw_modelMatrixInverse) + +#else /* GPU_INTEL */ +/* Intel GPU seems to suffer performance impact when the model matrix is in UBO storage. + * So for now we just force using the legacy path. */ +/* Note that this is also a workaround of a problem on osx (amd or nvidia) + * and older amd driver on windows. */ uniform mat4 ModelMatrix; uniform mat4 ModelMatrixInverse; +#endif + +#define resource_handle (resourceChunk * DRW_RESOURCE_CHUNK_LEN + resource_id) /** Transform shortcuts. */ /* Rule of thumb: Try to reuse world positions and normals because converting though viewspace diff --git a/source/blender/draw/modes/shaders/object_color_axes_vert.glsl b/source/blender/draw/modes/shaders/object_color_axes_vert.glsl new file mode 100644 index 00000000000..239dec30c42 --- /dev/null +++ b/source/blender/draw/modes/shaders/object_color_axes_vert.glsl @@ -0,0 +1,35 @@ + +uniform mat4 ViewProjectionMatrix; +uniform vec3 screenVecs[3]; + +/* ---- Instantiated Attrs ---- */ +in float axis; /* position on the axis. [0.0-1.0] is X axis, [1.0-2.0] is Y, etc... */ +in vec2 screenPos; +in vec3 colorAxis; + +/* ---- Per instance Attrs ---- */ +in mat4 InstanceModelMatrix; +in vec4 color; + +flat out vec4 finalColor; + +void main() +{ + float draw_size = 4.0; + vec3 chosen_axis = InstanceModelMatrix[int(axis)].xyz; + vec3 loc = InstanceModelMatrix[3].xyz; + vec3 wpos = loc + chosen_axis * fract(axis) * draw_size; + vec3 spos = screenVecs[0].xyz * screenPos.x + screenVecs[1].xyz * screenPos.y; + /* Scale uniformly by axis length */ + spos *= length(chosen_axis) * draw_size; + + vec4 pos_4d = vec4(wpos + spos, 1.0); + gl_Position = ViewProjectionMatrix * pos_4d; + + finalColor.rgb = mix(colorAxis, color.rgb, color.a); + finalColor.a = 1.0; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(pos_4d.xyz); +#endif +} diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl index 7dfbf469adc..e33aa6cdcc1 100644 --- a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl +++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl @@ -37,9 +37,15 @@ void main() if (depthMode == DEPTH_BACK) { gl_FragDepth = 0.999999; +#ifdef USE_WIRE + gl_FragDepth -= 1e-5; +#endif } else if (depthMode == DEPTH_FRONT) { gl_FragDepth = 0.000001; +#ifdef USE_WIRE + gl_FragDepth -= 1e-5; +#endif } else if (depthMode == DEPTH_UNCHANGED) { gl_FragDepth = gl_FragCoord.z; diff --git a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl index d27d55c3fd6..144024a7d5d 100644 --- a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl +++ b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl @@ -1,18 +1,11 @@ -uniform mat4 ViewProjectionMatrix; - -uniform float sphere_size; uniform ivec3 grid_resolution; uniform vec3 corner; uniform vec3 increment_x; uniform vec3 increment_y; uniform vec3 increment_z; -uniform vec3 screen_vecs[2]; - -uniform int call_id; /* we don't want the builtin callId which would be 0. */ -uniform int baseId; -flat out uint finalId; +flat out int objectId; void main() { @@ -29,7 +22,8 @@ void main() gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0); gl_PointSize = 2.0f; - finalId = uint(baseId + call_id); + /* ID 0 is nothing (background) */ + objectId = resource_handle + 1; #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_calc_clip_distance(ws_cell_location); diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl index 7668a0c2c94..7b86d477a39 100644 --- a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl @@ -7,30 +7,9 @@ uniform usampler2D outlineId; uniform sampler2D outlineDepth; uniform sampler2D sceneDepth; -uniform int idOffsets[4]; - uniform float alphaOcclu; uniform vec2 viewportSize; -vec4 convert_id_to_color(int id) -{ - if (id == 0) { - return vec4(0.0); - } - if (id < idOffsets[1]) { - return colorActive; - } - else if (id < idOffsets[2]) { - return colorSelect; - } - else if (id < idOffsets[3]) { - return colorDupliSelect; - } - else { - return colorTransform; - } -} - void main() { ivec2 texel = ivec2(gl_FragCoord.xy); @@ -85,7 +64,24 @@ void main() const float epsilon = 3.0 / 8388608.0; bool occluded = (ref_depth > scene_depth + epsilon); - FragColor = convert_id_to_color(int(ref_id)); + /* WATCH: Keep in sync with outlineId of the prepass. */ + uint color_id = ref_id >> 14u; + if (ref_id == 0u) { + FragColor = vec4(0.0); + } + else if (color_id == 1u) { + FragColor = colorSelect; + } + else if (color_id == 2u) { + FragColor = colorDupliSelect; + } + else if (color_id == 3u) { + FragColor = colorActive; + } + else { + FragColor = colorTransform; + } + FragColor.a *= (occluded) ? alphaOcclu : 1.0; FragColor.a = (outline) ? FragColor.a : 0.0; } diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl index c3447456ea6..5d6c4881b5b 100644 --- a/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl @@ -1,10 +1,18 @@ -uniform int callId; -uniform int baseId; + +/* Should be 2 bits only [0..3]. */ +uniform int outlineId; + +flat in int objectId; /* using uint because 16bit uint can contain more ids than int. */ out uint outId; +/* Replace top 2 bits (of the 16bit output) by outlineId. + * This leaves 16K different IDs to create outlines between objects. + * SHIFT = (32 - (16 - 2)) */ +#define SHIFT 18u + void main() { - outId = uint(baseId + callId); + outId = (uint(outlineId) << 14u) | ((uint(objectId) << SHIFT) >> SHIFT); } diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl index 5a3eb38fb6b..b32913dcd60 100644 --- a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl +++ b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl @@ -2,12 +2,15 @@ layout(lines_adjacency) in; layout(line_strip, max_vertices = 2) out; -in vec4 pPos[]; in vec3 vPos[]; +in int objectId_g[]; + +flat out int objectId; void vert_from_gl_in(int v) { - gl_Position = pPos[v]; + gl_Position = gl_in[v].gl_Position; + objectId = objectId_g[v]; #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance); #endif diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl index e34afe95b5e..7740f9a4af2 100644 --- a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl +++ b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl @@ -1,16 +1,27 @@ in vec3 pos; -out vec4 pPos; +#ifdef USE_GEOM out vec3 vPos; +out int objectId_g; +# define objectId objectId_g +#else + +flat out int objectId; +#endif void main() { vec3 world_pos = point_object_to_world(pos); +#ifdef USE_GEOM vPos = point_world_to_view(world_pos); - pPos = point_world_to_ndc(world_pos); +#endif + gl_Position = point_world_to_ndc(world_pos); /* Small bias to always be on top of the geom. */ - pPos.z -= 1e-3; + gl_Position.z -= 1e-3; + + /* ID 0 is nothing (background) */ + objectId = resource_handle + 1; #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_calc_clip_distance(world_pos); diff --git a/source/blender/draw/modes/shaders/paint_face_vert.glsl b/source/blender/draw/modes/shaders/paint_face_vert.glsl index d135071c15c..af362f24a85 100644 --- a/source/blender/draw/modes/shaders/paint_face_vert.glsl +++ b/source/blender/draw/modes/shaders/paint_face_vert.glsl @@ -8,4 +8,4 @@ void main() #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_calc_clip_distance(world_pos); #endif -}
\ No newline at end of file +} |