The example link to shadertoy uses a reference to iTime
, i'm not sure if our draw handlers support the time variable (but it might!). I suspect you will not need that ultimately, and it can always be supplied at runtime.
The Blender openGL / shader docs are good enough to get you displaying GLSL shaders, but you will need to dig deeper using external resources if the information isn't extensive enough. Especially if the knowledge vacuum concerns the ins and outs of GLSL. A good place to start is https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/Draw_API#Examples
A snippet I like to use is pasted below. It lets you run, and rerun (on and on...) the code so you can see what small code changes do to the final output.
import bpy
import gpu
import bgl
import numpy as np
from random import random
from gpu_extras.batch import batch_for_shader
if hasattr(bpy, 'test_handler'):
bpy.types.SpaceView3D.draw_handler_remove(bpy.test_handler, 'WINDOW')
mesh = bpy.context.active_object.data
mesh.calc_loop_triangles()
vertices = np.empty((len(mesh.vertices), 3), 'f')
poly_indices = np.empty((len(mesh.loop_triangles), 3), 'i')
edge_indices = np.array(mesh.edge_keys)
mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
mesh.loop_triangles.foreach_get("vertices", np.reshape(poly_indices, len(mesh.loop_triangles) * 3))
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=poly_indices)
wire_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
wire_batch = batch_for_shader(shader, 'LINES', {"pos": vertices}, indices=edge_indices)
def draw():
bgl.glEnable(bgl.GL_DEPTH_TEST)
bgl.glEnable(bgl.GL_POLYGON_OFFSET_FILL)
bgl.glPolygonOffset(1.0, 1.0)
shader.bind()
shader.uniform_float("color", (0.3, 0.3, 0.3, 1.0))
batch.draw(shader)
bgl.glDisable(bgl.GL_POLYGON_OFFSET_FILL)
wire_shader.bind()
wire_shader.uniform_float("color", (1, 1, 0, 1))
wire_batch.draw(wire_shader)
bgl.glDisable(bgl.GL_DEPTH_TEST)
bpy.test_handler = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
In Sverchok we use GLSL shaders to display the meshes we create. It might be worth checking out the code of the viz
nodes.
for example in this node (VDMK3, viewer Draw Mk3) you'll see references to imported shaders. You'll get an idea how to pass variables.