Skip to content

Instantly share code, notes, and snippets.

@cmdr2
Created July 24, 2025 09:34
Show Gist options
  • Select an option

  • Save cmdr2/1f45c053972f7506151c2061251d60d8 to your computer and use it in GitHub Desktop.

Select an option

Save cmdr2/1f45c053972f7506151c2061251d60d8 to your computer and use it in GitHub Desktop.
Uses a fragment shader to discard pixels outside the clipping volume (specified by a transform matrix, and local size)
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
VERT_SHADER = """
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
in vec2 texCoord;
in vec3 position;
out vec3 pos;
out vec2 texCoord_interp;
void main() {
pos = vec3(ModelMatrix * vec4(position, 1.0));
gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
texCoord_interp = texCoord;
}
"""
FRAG_SHADER = """
in vec3 pos;
in vec2 texCoord_interp;
out vec4 FragColor;
uniform mat4 StencilModelMatrixInverse;
uniform vec3 StencilBoundsLocal;
void main() {
vec3 pos_in_stencil_local = vec3(StencilModelMatrixInverse * vec4(pos, 1.0));
if (pos_in_stencil_local.x < 0 || pos_in_stencil_local.x > StencilBoundsLocal.x ||
pos_in_stencil_local.y < 0 || pos_in_stencil_local.y > StencilBoundsLocal.y ||
pos_in_stencil_local.z < 0 || pos_in_stencil_local.z > StencilBoundsLocal.z) {
discard;
}
FragColor = vec4(pos_in_stencil_local, 1.0);
}
"""
shader = gpu.types.GPUShader(VERT_SHADER, FRAG_SHADER)
W, H = 1, 1
O = 0
batch = batch_for_shader(
shader,
"TRIS",
{
"position": [(0 + O, 0, 0), (0 + O, H, 0), (W + O, H, 0), (W + O, H, 0), (W + O, 0, 0), (0 + O, 0, 0)],
# "texCoord": ((0, 0), (0, 1), (1, 1), (1, 1), (1, 0), (0, 0)),
},
)
from mathutils import Matrix, Vector
stencil_bounds_local = Vector((0.5, 0.5, 0.5))
stencil_model_matrix = Matrix.Translation((0.3, 0, 0))
def draw():
with gpu.matrix.push_pop():
matrix_local = Matrix.Translation((0.1, 0, 0))
gpu.matrix.multiply_matrix(matrix_local)
shader.bind()
shader.uniform_float("ModelMatrix", matrix_local)
shader.uniform_float("StencilModelMatrixInverse", stencil_model_matrix.inverted())
shader.uniform_float("StencilBoundsLocal", stencil_bounds_local)
batch.draw(shader)
bpy.types.SpaceView3D.draw_handler_add(draw, (), "WINDOW", "POST_VIEW")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment