Alright, you can try this before the release:
]add MakieCore#sd/shadertoy Makie#sd/shadertoy GLMakie#sd/shadertoy
using GLMakie, MetaGraphsNext, Graphs, NearestNeighbors
function graph_data_matrix(graph)
n = nv(graph)
data = Matrix{RGBf}(undef, n, 1)
for (i, v) in enumerate(vertices(graph))
pos = graph[Symbol("node$v")].pos
state = graph[Symbol("node$v")].state
data[i, 1] = RGBf(pos[1], pos[2], state)
end
data
end
shader_code = """
uniform int iPointCount;
uniform vec4 iBounds;
vec4 mainImage(in vec2 fragCoord) {
vec2 uv = fragCoord / iResolution.xy;
vec2 worldPos = vec2(
mix(iBounds.x, iBounds.z, uv.x),
mix(iBounds.y, iBounds.w, uv.y)
);
float minDist = 1e10;
float state = 0.0;
for (int i = 0; i < iPointCount; ++i) {
vec4 p = texelFetch(iChannel0, ivec2(i,0), 0);
float d = distance(worldPos, p.xy);
if (d < minDist) {
minDist = d;
state = p.z;
}
}
vec3 col = vec3(0.0);
if (state == 1.0) col = vec3(0.8, 0.52, 0.82);
else if (state == -1.0) col = vec3(1.0, 0.75, 0.43);
return vec4(col, 1.0);
}
"""
graph = create2DGrid(20, 20)
randomStates!(graph; states=[-1, 1])
texdata = graph_data_matrix(graph)
shadertoy(shader_code;
uniforms=Dict(
:iChannel0 => GLMakie.Sampler(texdata; minfilter=:nearest),
:iPointCount => nv(graph),
:iBounds => Vec4f(0, 0, 1, 1),
)
)
I also added another example:
To fill the whole window you can just do:
s = Scene()
shadertoy!(s, shader_code;
uniforms=Dict(
:iChannel0 => GLMakie.Sampler(texdata; minfilter=:nearest),
:iPointCount => nv(graph),
:iBounds => Vec4f(0, 0, 1, 1),
)
)
s
I still need to make updating the sampler easier (there seems to be a bug right now for the normal API), but you can animate it like this for now:
s = Scene()
sampler = GLMakie.Sampler(texdata; minfilter=:nearest)
pl = shadertoy!(s, shader_code;
uniforms=Dict(
:iChannel0 => sampler,
:iPointCount => nv(graph),
:iBounds => Vec4f(0, 0, 1, 1),
)
)
screen = display(s)
robj = GLMakie.plot2robjs(screen, pl)[1]
for i in 1:100
randomStates!(graph; states=[-1, 1])
texdata = graph_data_matrix(graph)
GLMakie.GLAbstraction.update!(robj[:iChannel0], texdata)
screen.requires_update = true
sleep(1/30)
end