This is a first part of the Shader Create Info system could be.
A shader create info provides a way to define shader structure, resources
and interfaces. This makes for a quick way to provide backend agnostic
binding informations while also making shader variations easy to declare.
- Clear source input (only one file). Cleans up the GPU api since we can create a
shader from one descriptor
- Resources and interfaces are generated by the backend (much simpler than parsing).
- Bindings are explicit from position in the array.
- GPUShaderInterface becomes a trivial translation of enums and string copy.
- No external dependency to third party lib.
- Cleaner code, less fragmentation of resources in several libs.
- Easy to modify / extend at runtime.
- no parser involve, very easy to code.
- Does not hold any data, can be static and kept on disc.
- Could hold precompiled bytecode for static shaders.
This also includes a new global dependency system.
GLSL shaders can include other sources by using #pragma BLENDER_REQUIRE(...).
This patch already migrated several builtin shaders. Other shaders should be migrated
one at a time, and could be done inside master.
There is a new compile directive `WITH_GPU_SHADER_BUILDER` this is an optional
directive for linting shaders to increase turn around time.
What is remaining:
- pyGPU API {T94975}
- Migration of other shaders. This could be a community effort.
Reviewed By: jbakker
Maniphest Tasks: T94975
Differential Revision: https://developer.blender.org/D13360
102 lines
2.7 KiB
GLSL
102 lines
2.7 KiB
GLSL
|
|
/* Values in GPU_shader.h. */
|
|
#define GPU_KEYFRAME_SHAPE_DIAMOND (1 << 0)
|
|
#define GPU_KEYFRAME_SHAPE_CIRCLE (1 << 1)
|
|
#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1 << 2)
|
|
#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1 << 3)
|
|
#define GPU_KEYFRAME_SHAPE_INNER_DOT (1 << 4)
|
|
#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1 << 8)
|
|
#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1 << 9)
|
|
#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1 << 10)
|
|
#define GPU_KEYFRAME_SHAPE_SQUARE \
|
|
(GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL)
|
|
|
|
const float line_falloff = 1.0;
|
|
const float circle_scale = sqrt(2.0 / 3.1416);
|
|
const float square_scale = sqrt(0.5);
|
|
const float diagonal_scale = sqrt(0.5);
|
|
|
|
#ifndef USE_GPU_SHADER_CREATE_INFO
|
|
uniform mat4 ModelViewProjectionMatrix;
|
|
uniform vec2 ViewportSize = vec2(-1, -1);
|
|
uniform float outline_scale = 1.0;
|
|
|
|
in vec2 pos;
|
|
in float size;
|
|
in vec4 color;
|
|
in vec4 outlineColor;
|
|
in int flags;
|
|
|
|
flat out vec4 finalColor;
|
|
flat out vec4 finalOutlineColor;
|
|
|
|
flat out int finalFlags;
|
|
|
|
flat out vec4 radii;
|
|
flat out vec4 thresholds;
|
|
#endif
|
|
|
|
bool test(int bit)
|
|
{
|
|
return (flags & bit) != 0;
|
|
}
|
|
|
|
vec2 line_thresholds(float width)
|
|
{
|
|
return vec2(max(0, width - line_falloff), width);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
|
|
|
|
/* Align to pixel grid if the viewport size is known. */
|
|
if (ViewportSize.x > 0) {
|
|
vec2 scale = ViewportSize * 0.5;
|
|
vec2 px_pos = (gl_Position.xy + 1) * scale;
|
|
vec2 adj_pos = round(px_pos - 0.5) + 0.5;
|
|
gl_Position.xy = adj_pos / scale - 1;
|
|
}
|
|
|
|
/* Pass through parameters. */
|
|
finalColor = color;
|
|
finalOutlineColor = outlineColor;
|
|
finalFlags = flags;
|
|
|
|
if (!test(GPU_KEYFRAME_SHAPE_DIAMOND | GPU_KEYFRAME_SHAPE_CIRCLE |
|
|
GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL)) {
|
|
finalFlags |= GPU_KEYFRAME_SHAPE_DIAMOND;
|
|
}
|
|
|
|
/* Size-dependent line thickness. */
|
|
float half_width = (0.06 + (size - 10) * 0.04);
|
|
float line_width = half_width + line_falloff;
|
|
|
|
/* Outline thresholds. */
|
|
thresholds.xy = line_thresholds(line_width * outline_scale);
|
|
|
|
/* Inner dot thresholds. */
|
|
thresholds.zw = line_thresholds(line_width * 1.6);
|
|
|
|
/* Extend the primitive size by half line width on either side; odd for symmetry. */
|
|
float ext_radius = round(0.5 * size) + thresholds.x;
|
|
|
|
gl_PointSize = ceil(ext_radius + thresholds.y) * 2 + 1;
|
|
|
|
/* Diamond radius. */
|
|
radii[0] = ext_radius * diagonal_scale;
|
|
|
|
/* Circle radius. */
|
|
radii[1] = ext_radius * circle_scale;
|
|
|
|
/* Square radius. */
|
|
radii[2] = round(ext_radius * square_scale);
|
|
|
|
/* Min/max cutout offset. */
|
|
radii[3] = -line_falloff;
|
|
|
|
/* Convert to PointCoord units. */
|
|
radii /= gl_PointSize;
|
|
thresholds /= gl_PointSize;
|
|
}
|