Created
July 24, 2025 09:34
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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