Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Shadertoy and shader plot types #4025

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions GLMakie/assets/shader/shadertoy.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{GLSL_VERSION}}

{{SHADERTOY_INPUTS}}
{{TOY_SHADER}}

in vec2 f_uv;
layout (location = 0) out vec4 fragment_color;
layout (location = 1) out uvec2 fragment_groupid;

void main()
{
vec4 color = mainImage(f_uv * iResolution.xy);
if (color.a <= 0.0) discard;
fragment_color = color * 0.5;
}
11 changes: 11 additions & 0 deletions GLMakie/assets/shader/shadertoy.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{GLSL_VERSION}}

in vec2 vertices;
in vec2 uv;
out vec2 f_uv;
uniform mat4 projection, view, model;

void main(){
gl_Position = projection * view * vec4(vertices, 0, 1);
f_uv = uv;
}
122 changes: 122 additions & 0 deletions GLMakie/experiments/clouds.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
float noise(in vec3 x) {
vec3 p = floor(x);
vec3 f = fract(x);
f = f * f * (3.0 - 2.0 * f);
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
vec2 rg = texture(iChannel0, (uv + 0.5) / 256.0, -100).yx;
return -1.0 + 2.0 * mix(rg.x, rg.y, f.z);
}

float map5(in vec3 p) {
vec3 q = p - vec3(0.0, 0.1, 1.0) * iGlobalTime;
float f;
f = 0.50000 * noise(q);
q = q * 2.02;
f += 0.25000 * noise(q);
q = q * 2.03;
f += 0.12500 * noise(q);
q = q * 2.01;
f += 0.06250 * noise(q);
q = q * 2.02;
f += 0.03125 * noise(q);
return clamp(1.5 - p.y - 2.0 + 1.75 * f, 0.0, 1.0);
}

float map4(in vec3 p) {
vec3 q = p - vec3(0.0, 0.1, 1.0) * iGlobalTime;
float f;
f = 0.50000 * noise(q);
q = q * 2.02;
f += 0.25000 * noise(q);
q = q * 2.03;
f += 0.12500 * noise(q);
q = q * 2.01;
f += 0.06250 * noise(q);
return clamp(1.5 - p.y - 2.0 + 1.75 * f, 0.0, 1.0);
}
float map3(in vec3 p) {
vec3 q = p - vec3(0.0, 0.1, 1.0) * iGlobalTime;
float f;
f = 0.50000 * noise(q);
q = q * 2.02;
f += 0.25000 * noise(q);
q = q * 2.03;
f += 0.12500 * noise(q);
return clamp(1.5 - p.y - 2.0 + 1.75 * f, 0.0, 1.0);
}
float map2(in vec3 p) {
vec3 q = p - vec3(0.0, 0.1, 1.0) * iGlobalTime;
float f;
f = 0.50000 * noise(q);
q = q * 2.02;
f += 0.25000 * noise(q);
;
return clamp(1.5 - p.y - 2.0 + 1.75 * f, 0.0, 1.0);
}

vec3 sundir = normalize(vec3(-1.0, 0.0, -1.0));

vec4 integrate(in vec4 sum, in float dif, in float den, in vec3 bgcol, in float t) {
// lighting
vec3 lin = vec3(0.65, 0.68, 0.7) * 1.3 + 0.5 * vec3(0.7, 0.5, 0.3) * dif;
vec4 col = vec4(mix(1.15 * vec3(1.0, 0.95, 0.8), vec3(0.65), den), den);
col.xyz *= lin;
col.xyz = mix(col.xyz, bgcol, 1.0 - exp(-0.003 * t * t));
// front to back blending
col.a *= 0.4;
col.rgb *= col.a;
return sum + col * (1.0 - sum.a);
}

#define MARCH(STEPS,MAPLOD) for(int i=0; i<STEPS; i++) { vec3 pos = ro + t*rd; if( pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99 ) break; float den = MAPLOD( pos ); if( den>0.01 ) { float dif = clamp((den - MAPLOD(pos+0.3*sundir))/0.6, 0.0, 1.0 ); sum = integrate( sum, dif, den, bgcol, t ); } t += max(0.1,0.02*t); }

vec4 raymarch(in vec3 ro, in vec3 rd, in vec3 bgcol) {
vec4 sum = vec4(0.0);

float t = 0.0;

MARCH(30, map5);
MARCH(30, map4);
MARCH(30, map3);
MARCH(30, map2);

return clamp(sum, 0.0, 1.0);
}

mat3 setCamera(in vec3 ro, in vec3 ta, float cr) {
vec3 cw = normalize(ta - ro);
vec3 cp = vec3(sin(cr), cos(cr), 0.0);
vec3 cu = normalize(cross(cw, cp));
vec3 cv = normalize(cross(cu, cw));
return mat3(cu, cv, cw);
}

vec4 render(in vec3 ro, in vec3 rd) {
// background sky
float sun = clamp(dot(sundir, rd), 0.0, 1.0);
vec3 col = vec3(0.6, 0.71, 0.75) - rd.y * 0.2 * vec3(1.0, 0.5, 1.0) + 0.15 * 0.5;
col += 0.2 * vec3(1.0, .6, 0.1) * pow(sun, 8.0);

// clouds
vec4 res = raymarch(ro, rd, col);
col = col * (1.0 - res.w) + res.xyz;

// sun glare
col += 0.1 * vec3(1.0, 0.4, 0.2) * pow(sun, 3.0);

return vec4(col, 1.0);
}

vec4 mainImage(in vec2 fragCoord) {
vec2 p = (-iResolution.xy + 2.0 * gl_FragCoord.xy) / iResolution.y;
vec2 m = iMouse.xy / iResolution.xy;

// camera
vec3 ro = 4.0 * normalize(vec3(sin(3.0 * m.x), 0.4 * m.y, cos(3.0 * m.x)));
vec3 ta = vec3(0.0, -1.0, 0.0);
mat3 ca = setCamera(ro, ta, 0.0);
// ray
vec3 rd = ca * normalize(vec3(p.xy, 1.5));

return render(ro, rd);
}
78 changes: 78 additions & 0 deletions GLMakie/experiments/gpu-examples.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using CUDA

const N = 1024 # Number of particles
const dt = 0.01 # Time step
const G = 6.67430e-11 # Gravitational constant
const eps = 1e-3 # Softening factor to avoid singularity


# Struct to represent a particle
struct Particle
pos::CUDA.CuVector{Point3f}
vel::CUDA.CuVector{Vec3f}
mass::CUDA.CuVector{Float32}
end

# Initialize particles with random positions, velocities, and masses
function init_particles(n)
pos = CUDA.fill(Point3f(0.0f0, 0.0f0, 0.0f0), n)
vel = CUDA.fill(Vec3f(0.0f0, 0.0f0, 0.0f0), n)
mass = CUDA.fill(0.0f0, n)

for i in 1:n
pos[i] = rand(Point3f) .* 100
vel[i] = (rand(Vec3f) .- 0.5) .* 10
mass[i] = rand(Float32) * 10 + 1
end

Particle(pos, vel, mass)
end

# GPU kernel to calculate forces and update positions and velocities
function update_particles!(pos, mass, vel, dt, G, eps, N)
i = threadIdx().x + (blockIdx().x - 1) * blockDim().x
@inbounds if i <= N
force = Vec3f(0.0f0, 0.0f0, 0.0f0)
pos_i = pos[i]

for j in 1:N
if i != j
pos_j = pos[j]
diff = pos_j - pos_i
distSqr = sum(diff .* diff) + eps * eps
invDist = 1.0f0 / sqrt(distSqr)
invDist3 = invDist * invDist * invDist
mass_product = mass[i] * mass[j]
force += diff .* (G * mass_product * invDist3)
end
end

accel = force ./ mass[i]
vel[i] += accel .* dt
pos[i] += vel[i] .* dt
end
return
end

# Main simulation function
function run_simulation(particles, dt, G, eps, N)
threads = 256
blocks = ceil(Int, N / threads)
@cuda threads = threads blocks = blocks update_particles!(particles, dt, G, eps, N)
end

# Initialize particles
particles = init_particles(N)

# Number of simulation steps
steps = 100

# Run the simulation
run_simulation(particles, dt, steps, G, eps, N)

# Fetch the results from the GPU
positions = Array(pos)
println("Final positions of particles:")
for pos in positions
println(pos)
end
Loading
Loading