Fix #139565: PyGPU: Add builtin point shaders
This PR adds builtin shaders for drawing points. Using `FLAT_COLOR`, `SMOOTH_COLOR`, `UNIFORM_COLOR` can lead to undesired behavior on Metal and Vulkan backends. To ensure future compatibility this PR adds `POINT_FLAT_COLOR` and `POINT_UNIFORM_COLOR`. The point size can be set using `gpu.state.point_size_set`. Pull Request: https://projects.blender.org/blender/blender/pulls/139583
This commit is contained in:
parent
fd58d730b0
commit
c56a855b9f
@ -77,7 +77,8 @@ Typically multiple shaders are linked together into a *Program*.
|
||||
However, in the Blender Python API the term *Shader* refers to an OpenGL Program.
|
||||
Every :class:`gpu.types.GPUShader` consists of a vertex shader, a fragment shader and an optional geometry shader.
|
||||
For common drawing tasks there are some built-in shaders accessible from :class:`gpu.shader.from_builtin`
|
||||
with an identifier such as ``UNIFORM_COLOR`` or ``FLAT_COLOR``.
|
||||
with an identifier such as ``UNIFORM_COLOR`` or ``FLAT_COLOR``. There are specific builtin shaders for
|
||||
drawing triangles, lines and points.
|
||||
|
||||
Every shader defines a set of attributes and uniforms that have to be set in order to use the shader.
|
||||
Attributes are properties that are set using a vertex buffer and can be different for individual vertices.
|
||||
@ -140,6 +141,29 @@ To try these examples, just copy them into Blenders text editor and execute them
|
||||
To keep the examples relatively small, they just register a draw function that can't easily be removed anymore.
|
||||
Blender has to be restarted in order to delete the draw handlers.
|
||||
|
||||
3D Points with Single Color
|
||||
"""
|
||||
|
||||
import bpy
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)]
|
||||
shader = gpu.shader.from_builtin('POINT_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(shader, 'POINTS', {"pos": coords})
|
||||
|
||||
|
||||
def draw():
|
||||
shader.uniform_float("color", (1, 1, 0, 1))
|
||||
gpu.state.point_size_set(4.5)
|
||||
batch.draw(shader)
|
||||
|
||||
|
||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||
|
||||
|
||||
"""
|
||||
|
||||
3D Lines with Single Color
|
||||
--------------------------
|
||||
"""
|
||||
|
@ -505,6 +505,7 @@ set(GLSL_SRC
|
||||
shaders/gpu_shader_point_varying_color_frag.glsl
|
||||
shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl
|
||||
shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl
|
||||
shaders/gpu_shader_3D_point_flat_color_vert.glsl
|
||||
shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl
|
||||
shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl
|
||||
shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl
|
||||
|
@ -104,6 +104,8 @@ enum eGPUBuiltinShader {
|
||||
*/
|
||||
GPU_SHADER_3D_FLAT_COLOR,
|
||||
GPU_SHADER_3D_POLYLINE_FLAT_COLOR,
|
||||
GPU_SHADER_3D_POINT_FLAT_COLOR,
|
||||
|
||||
/**
|
||||
* Take a 3D position and color for each vertex with perspective correct interpolation.
|
||||
*
|
||||
@ -112,6 +114,7 @@ enum eGPUBuiltinShader {
|
||||
*/
|
||||
GPU_SHADER_3D_SMOOTH_COLOR,
|
||||
GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR,
|
||||
|
||||
/**
|
||||
* Take a single color for all the vertices and a 3D position for each vertex.
|
||||
*
|
||||
@ -120,6 +123,8 @@ enum eGPUBuiltinShader {
|
||||
*/
|
||||
GPU_SHADER_3D_UNIFORM_COLOR,
|
||||
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR,
|
||||
GPU_SHADER_3D_POINT_UNIFORM_COLOR,
|
||||
|
||||
/**
|
||||
* Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex.
|
||||
*
|
||||
|
@ -74,6 +74,10 @@ static const char *builtin_shader_create_info_name(eGPUBuiltinShader shader)
|
||||
return "gpu_shader_3D_point_varying_size_varying_color";
|
||||
case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA:
|
||||
return "gpu_shader_3D_point_uniform_size_uniform_color_aa";
|
||||
case GPU_SHADER_3D_POINT_FLAT_COLOR:
|
||||
return "gpu_shader_3D_point_flat_color";
|
||||
case GPU_SHADER_3D_POINT_UNIFORM_COLOR:
|
||||
return "gpu_shader_3D_point_uniform_color";
|
||||
case GPU_SHADER_2D_AREA_BORDERS:
|
||||
return "gpu_shader_2D_area_borders";
|
||||
case GPU_SHADER_2D_WIDGET_BASE:
|
||||
|
@ -31,6 +31,7 @@ set(SRC_GLSL_VERT
|
||||
gpu_shader_3D_normal_vert.glsl
|
||||
gpu_shader_3D_point_uniform_size_aa_vert.glsl
|
||||
gpu_shader_3D_point_varying_size_varying_color_vert.glsl
|
||||
gpu_shader_3D_point_flat_color_vert.glsl
|
||||
gpu_shader_3D_smooth_color_vert.glsl
|
||||
gpu_shader_display_fallback_vert.glsl
|
||||
gpu_shader_gpencil_stroke_vert.glsl
|
||||
|
@ -0,0 +1,21 @@
|
||||
/* SPDX-FileCopyrightText: 2016-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/gpu_shader_3D_flat_color_info.hh"
|
||||
|
||||
#include "gpu_shader_cfg_world_clip_lib.glsl"
|
||||
|
||||
VERTEX_SHADER_CREATE_INFO(gpu_shader_3D_flat_color)
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 pos_4d = float4(pos, 1.0f);
|
||||
gl_Position = ModelViewProjectionMatrix * pos_4d;
|
||||
gl_PointSize = size;
|
||||
finalColor = color;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance((clipPlanes.ClipModelMatrix * pos_4d).xyz);
|
||||
#endif
|
||||
}
|
@ -48,3 +48,29 @@ ADDITIONAL_INFO(gpu_shader_3D_point_uniform_size_uniform_color_aa)
|
||||
ADDITIONAL_INFO(gpu_clip_planes)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_flat_color)
|
||||
VERTEX_IN(0, float3, pos)
|
||||
VERTEX_IN(1, float4, color)
|
||||
VERTEX_OUT(flat_color_iface)
|
||||
FRAGMENT_OUT(0, float4, fragColor)
|
||||
PUSH_CONSTANT(float4x4, ModelViewProjectionMatrix)
|
||||
PUSH_CONSTANT(float, size)
|
||||
VERTEX_SOURCE("gpu_shader_3D_point_flat_color_vert.glsl")
|
||||
FRAGMENT_SOURCE("gpu_shader_flat_color_frag.glsl")
|
||||
ADDITIONAL_INFO(gpu_srgb_to_framebuffer_space)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_uniform_color)
|
||||
VERTEX_IN(0, float3, pos)
|
||||
VERTEX_OUT(flat_color_iface)
|
||||
FRAGMENT_OUT(0, float4, fragColor)
|
||||
PUSH_CONSTANT(float4x4, ModelViewProjectionMatrix)
|
||||
PUSH_CONSTANT(float4, color)
|
||||
PUSH_CONSTANT(float, size)
|
||||
VERTEX_SOURCE("gpu_shader_3D_point_flat_color_vert.glsl")
|
||||
FRAGMENT_SOURCE("gpu_shader_flat_color_frag.glsl")
|
||||
ADDITIONAL_INFO(gpu_srgb_to_framebuffer_space)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
@ -352,6 +352,33 @@ static PyObject *pygpu_batch_draw(BPyGPUBatch *self, PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit a warning when trying to draw points with a regular shader as it is too late to
|
||||
* automatically switch to a point shader. */
|
||||
if (py_shader && py_shader->is_builtin && self->batch->prim_type == GPU_PRIM_POINTS) {
|
||||
GPUShader *shader = py_shader->shader;
|
||||
if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR)) {
|
||||
PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"Calling GPUBatch.draw to draw points with "
|
||||
"GPU_SHADER_3D_FLAT_COLOR is deprecated. "
|
||||
"Use GPU_SHADER_3D_POINT_FLAT_COLOR instead.",
|
||||
1);
|
||||
}
|
||||
else if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR)) {
|
||||
PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"Calling GPUBatch.draw to draw points with "
|
||||
"GPU_SHADER_3D_SMOOTH_COLOR is deprecated. "
|
||||
"Use GPU_SHADER_3D_POINT_FLAT_COLOR instead.",
|
||||
1);
|
||||
}
|
||||
else if (shader == GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR)) {
|
||||
PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"Calling GPUBatch.draw to draw points with "
|
||||
"GPU_SHADER_3D_UNIFORM_COLOR is deprecated. "
|
||||
"Use GPU_SHADER_3D_POINT_SMOOTH_COLOR instead.",
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
if (const char *error = pygpu_shader_check_compatibility(self->batch)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, error);
|
||||
return nullptr;
|
||||
|
@ -59,7 +59,13 @@
|
||||
" :Uniforms: vec2 viewportSize, float lineWidth\n" \
|
||||
"``POLYLINE_UNIFORM_COLOR``\n" \
|
||||
" :Attributes: vec3 pos\n" \
|
||||
" :Uniforms: vec2 viewportSize, float lineWidth\n"
|
||||
" :Uniforms: vec2 viewportSize, float lineWidth\n" \
|
||||
"``POINT_FLAT_COLOR``\n" \
|
||||
" :Attributes: vec3 pos, vec4 color\n" \
|
||||
" :Uniforms: float size\n" \
|
||||
"``POLYLINE_UNIFORM_COLOR``\n" \
|
||||
" :Attributes: vec3 pos\n" \
|
||||
" :Uniforms: vec4 color, float size\n"
|
||||
|
||||
static const PyC_StringEnumItems pygpu_shader_builtin_items[] = {
|
||||
{GPU_SHADER_3D_FLAT_COLOR, "FLAT_COLOR"},
|
||||
@ -70,6 +76,8 @@ static const PyC_StringEnumItems pygpu_shader_builtin_items[] = {
|
||||
{GPU_SHADER_3D_POLYLINE_FLAT_COLOR, "POLYLINE_FLAT_COLOR"},
|
||||
{GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR, "POLYLINE_SMOOTH_COLOR"},
|
||||
{GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, "POLYLINE_UNIFORM_COLOR"},
|
||||
{GPU_SHADER_3D_POINT_FLAT_COLOR, "POINT_FLAT_COLOR"},
|
||||
{GPU_SHADER_3D_POINT_UNIFORM_COLOR, "POINT_UNIFORM_COLOR"},
|
||||
{0, nullptr},
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user