diff options
Diffstat (limited to 'doc/python_api/examples/gpu.10.py')
-rw-r--r-- | doc/python_api/examples/gpu.10.py | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/doc/python_api/examples/gpu.10.py b/doc/python_api/examples/gpu.10.py index a4db576ecc0..2f255b7127d 100644 --- a/doc/python_api/examples/gpu.10.py +++ b/doc/python_api/examples/gpu.10.py @@ -1,41 +1,65 @@ """ -Rendering the 3D View into a Texture ------------------------------------- +Custom Shader for dotted 3D Line +-------------------------------- -The scene has to have a camera for this example to work. -You could also make this independent of a specific camera, -but Blender does not expose good functions to create view and projection matrices yet. +In this example the arc length (distance to the first point on the line) is calculated in every vertex. +Between the vertex and fragment shader that value is automatically interpolated +for all points that will be visible on the screen. +In the fragment shader the ``sin`` of the arc length is calculated. +Based on the result a decision is made on whether the fragment should be drawn or not. """ import bpy -import bgl import gpu -from gpu_extras.presets import draw_texture_2d +from random import random +from mathutils import Vector +from gpu_extras.batch import batch_for_shader -WIDTH = 512 -HEIGHT = 256 +vertex_shader = ''' + uniform mat4 u_ViewProjectionMatrix; -offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) + in vec3 position; + in float arcLength; + out float v_ArcLength; -def draw(): - context = bpy.context - scene = context.scene + void main() + { + v_ArcLength = arcLength; + gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f); + } +''' + +fragment_shader = ''' + uniform float u_Scale; + + in float v_ArcLength; - view_matrix = scene.camera.matrix_world.inverted() + void main() + { + if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard; + gl_FragColor = vec4(1.0); + } +''' - projection_matrix = scene.camera.calc_matrix_camera( - context.evaluated_depsgraph_get(), x=WIDTH, y=HEIGHT) +coords = [Vector((random(), random(), random())) * 5 for _ in range(5)] - offscreen.draw_view3d( - scene, - context.view_layer, - context.space_data, - context.region, - view_matrix, - projection_matrix) +arc_lengths = [0] +for a, b in zip(coords[:-1], coords[1:]): + arc_lengths.append(arc_lengths[-1] + (a - b).length) - bgl.glDisable(bgl.GL_DEPTH_TEST) - draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT) +shader = gpu.types.GPUShader(vertex_shader, fragment_shader) +batch = batch_for_shader( + shader, 'LINE_STRIP', + {"position": coords, "arcLength": arc_lengths}, +) + + +def draw(): + shader.bind() + matrix = bpy.context.region_data.perspective_matrix + shader.uniform_float("u_ViewProjectionMatrix", matrix) + shader.uniform_float("u_Scale", 10) + batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') |