Inlined a bunch of the shader stuff so it all fits in one file.
This commit is contained in:
parent
52599c02f2
commit
7d72317846
34
main.lua
34
main.lua
@ -26,20 +26,6 @@ function love.load()
|
||||
yOffset = 0
|
||||
t0 = love.timer.getTime()
|
||||
love.mouse.setCursor(love.mouse.getSystemCursor("hand"))
|
||||
|
||||
local data1,data2,data3 = {},{},{}
|
||||
for i=1,100000 do
|
||||
local x = math.random()*100000
|
||||
local y = math.random()*100000
|
||||
local z = math.random()*100000
|
||||
table.insert(data1, n1(x))
|
||||
table.insert(data2, n2(x,y))
|
||||
table.insert(data3, n3(x,y,z))
|
||||
end
|
||||
histogram1 = Histogram:fromList(data1,{pos={x=0,y=0},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram2 = Histogram:fromList(data2,{pos={x=0,y=H/3},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram3 = Histogram:fromList(data3,{pos={x=0,y=2*H/3},size={x=W/2,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
|
||||
end
|
||||
|
||||
function love.mousepressed()
|
||||
@ -104,15 +90,15 @@ function love.draw()
|
||||
|
||||
lg.setShader(s1)
|
||||
s1:send("range_min", xOffset)
|
||||
s1:send("range_max", xOffset+cw/SCALE)
|
||||
s1:send("range_max", xOffset+2*cw/SCALE)
|
||||
lg.draw(canv,W-cw,0)
|
||||
lg.setShader(s2)
|
||||
s2:send("range_min", {xOffset,yOffset})
|
||||
s2:send("range_max", {xOffset+cw/SCALE,yOffset+ch/SCALE})
|
||||
s2:send("range_max", {xOffset+2*cw/SCALE,yOffset+2*ch/SCALE})
|
||||
lg.draw(canv,W-cw,ch)
|
||||
lg.setShader(s3)
|
||||
s3:send("range_min", {xOffset,yOffset})
|
||||
s3:send("range_max", {xOffset+cw/SCALE,yOffset+ch/SCALE})
|
||||
s3:send("range_max", {xOffset+2*cw/SCALE,yOffset+2*ch/SCALE})
|
||||
s3:send('z', t)
|
||||
lg.draw(canv,W-cw,2*ch)
|
||||
lg.setShader(nil)
|
||||
@ -142,6 +128,20 @@ end
|
||||
function love.keypressed(key)
|
||||
if key == 'escape' then love.event.quit() end
|
||||
if key == 'r' then love.load() end
|
||||
if key == 'h' and not histogram1 then
|
||||
local data1,data2,data3 = {},{},{}
|
||||
for i=1,100000 do
|
||||
local x = math.random()*100000
|
||||
local y = math.random()*100000
|
||||
local z = math.random()*100000
|
||||
table.insert(data1, n1(x))
|
||||
table.insert(data2, n2(x,y))
|
||||
table.insert(data3, n3(x,y,z))
|
||||
end
|
||||
histogram1 = Histogram:fromList(data1,{pos={x=0,y=0},size={x=W/4,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram2 = Histogram:fromList(data2,{pos={x=0,y=H/3},size={x=W/4,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
histogram3 = Histogram:fromList(data3,{pos={x=0,y=2*H/3},size={x=W/4,y=H/3},xmin=0,xmax=1,numBuckets=30})
|
||||
end
|
||||
end
|
||||
|
||||
function love.mousemoved(x,y,dx,dy)
|
||||
|
119
noise.lua
119
noise.lua
@ -102,8 +102,33 @@ noise.make3d = function(resolution,random,decayFn)
|
||||
end
|
||||
end
|
||||
|
||||
local shader1d = [[
|
||||
#define TAU 6.283185307179586476925286766559005768394338798750211641949
|
||||
#define MAX_RESOLUTION 64
|
||||
extern int resolution;
|
||||
extern float sigma, range_min, range_max;
|
||||
extern float amplitudes[MAX_RESOLUTION];
|
||||
extern float offsets[MAX_RESOLUTION];
|
||||
|
||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
|
||||
{
|
||||
float x = mix(range_min,range_max,texture_coords.x);
|
||||
float noise = 0.;
|
||||
for (int i=0; i < resolution; i++) {
|
||||
float a = amplitudes[i];
|
||||
noise += a*cos(x/a + offsets[i]);
|
||||
}
|
||||
noise = noise/sigma;
|
||||
noise = .5 + .5*sign(noise)*sqrt(1.-exp(-4./TAU * noise*noise));
|
||||
return vec4(noise,noise,noise,1.);
|
||||
}
|
||||
]]
|
||||
|
||||
noise.make1dShader = function(resolution,random,decayFn)
|
||||
local shader = lg.newShader("noise1d.glsl")
|
||||
if resolution > 64 then
|
||||
error("Resolution cannot exceed 64")
|
||||
end
|
||||
local shader = lg.newShader(shader1d)
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,resolution,random)
|
||||
shader:send("sigma",sigma)
|
||||
@ -115,8 +140,38 @@ noise.make1dShader = function(resolution,random,decayFn)
|
||||
return shader
|
||||
end
|
||||
|
||||
local shader2d = [[
|
||||
#define TAU 6.283185307179586476925286766559005768394338798750211641949
|
||||
#define PHI 1.618033988749894848204586834365638117720309179805762862135
|
||||
#define MAX_RESOLUTION 64
|
||||
extern int resolution;
|
||||
extern float sigma;
|
||||
extern float amplitudes[MAX_RESOLUTION];
|
||||
extern vec2 offsets[MAX_RESOLUTION];
|
||||
extern vec2 range_min, range_max;
|
||||
|
||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
|
||||
{
|
||||
vec2 pos = mix(range_min,range_max,texture_coords);
|
||||
float noise = 0.;
|
||||
for (int i=0; i < resolution; i++) {
|
||||
float angle = mod(float(i)*PHI, 1.)*TAU;
|
||||
float u = pos.x*cos(angle) - pos.y*sin(angle);
|
||||
float v = pos.x*cos(angle+TAU/4.) - pos.y*sin(angle+TAU/4.);
|
||||
float a = amplitudes[i];
|
||||
noise += a*mix(cos(u/a + offsets[i].x), cos(v/a + offsets[i].y), .5);
|
||||
}
|
||||
noise = noise/sigma;
|
||||
noise = .5 + .5*sign(noise)*sqrt(1.-exp(-4./TAU * noise*noise));
|
||||
return vec4(noise,noise,noise,1.);
|
||||
}
|
||||
]]
|
||||
|
||||
noise.make2dShader = function(resolution,random,decayFn)
|
||||
local shader = lg.newShader("noise2d.glsl")
|
||||
if resolution > 64 then
|
||||
error("Resolution cannot exceed 64")
|
||||
end
|
||||
local shader = lg.newShader(shader2d)
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,2*resolution,random)
|
||||
sigma = sigma/sqrt(2)
|
||||
@ -133,8 +188,66 @@ noise.make2dShader = function(resolution,random,decayFn)
|
||||
return shader
|
||||
end
|
||||
|
||||
local shader3d = [[
|
||||
#define TAU 6.283185307179586476925286766559005768394338798750211641949
|
||||
#define PHI 1.618033988749894848204586834365638117720309179805762862135
|
||||
#define LOG_PHI 0.481211825059603447497758913424368423135184334385660519660
|
||||
#define SQRT5 2.236067977499789696409173668731276235440618359611525724270
|
||||
#define MAX_RESOLUTION 64
|
||||
extern int resolution;
|
||||
extern float sigma, z;
|
||||
extern float amplitudes[MAX_RESOLUTION];
|
||||
extern vec3 offsets[MAX_RESOLUTION];
|
||||
extern vec2 range_min, range_max;
|
||||
|
||||
// https://www.graphics.rwth-aachen.de/media/papers/jgt.pdf
|
||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
|
||||
{
|
||||
vec3 pos = vec3(mix(range_min,range_max,texture_coords), z);
|
||||
// Find the biggest fibonacci number F_n such that F_n < RESOLUTION
|
||||
int n = int(log((float(resolution)-1.)*SQRT5 + .5)/LOG_PHI);
|
||||
int dec = int(.5 + pow(PHI,n)/SQRT5); // F_n, using closed form Fibonacci
|
||||
int inc = int(.5 + dec/PHI); // F_(n-1)
|
||||
|
||||
float noise = 0.;
|
||||
for (int i=0, j=0; i<resolution; ++i) {
|
||||
if (j >= dec) {
|
||||
j -= dec;
|
||||
} else {
|
||||
j += inc;
|
||||
if (j >= resolution)
|
||||
j -= dec;
|
||||
}
|
||||
// Convert golden ratio sequence into polar coordinate unit vector
|
||||
float phi = mod(float(i)*PHI,1.)*TAU;
|
||||
float theta = acos(mix(-1.,1.,mod(float(j)*PHI,1.)));
|
||||
// Make an orthonormal basis, where n1 is from polar phi/theta,
|
||||
// n2 is roated 90 degrees along phi, and n3 is the cross product of the two
|
||||
vec3 n1 = vec3(sin(phi)*cos(theta), sin(phi)*sin(theta), cos(phi));
|
||||
vec3 n2 = vec3(sin(phi+TAU/4.)*cos(theta), sin(phi+TAU/4.)*sin(theta), cos(phi+TAU/4.));
|
||||
vec3 n3 = cross(n1,n2);
|
||||
// Convert pos from x/y/z coordinates to n1/n2/n3 coordinates
|
||||
float u = dot(n1, pos);
|
||||
float v = dot(n2, pos);
|
||||
float w = dot(n3, pos);
|
||||
// Pull the amplitude from the shuffled array index ("j"), not "i",
|
||||
// otherwise neighboring unit vectors will have similar amplitudes!
|
||||
float a = amplitudes[j];
|
||||
//float a = pow(mod(float(i+1)*(PHI-1.), 1.), .3);
|
||||
// Noise is the average of cosine of distance along each axis, shifted by offsets and scaled by amplitude.
|
||||
noise += a*(cos(u/a + offsets[i].x) + cos(v/a + offsets[i].y) + cos(w/a + offsets[i].z))/3.;
|
||||
}
|
||||
noise = noise/sigma;
|
||||
noise = .5 + .5*sign(noise)*sqrt(1.-exp(-4./TAU * noise*noise));
|
||||
return vec4(noise,noise,noise,1.);
|
||||
}
|
||||
]]
|
||||
|
||||
noise.make3dShader = function(resolution,random,decayFn)
|
||||
local shader = lg.newShader("noise3d.glsl")
|
||||
if resolution > 64 then
|
||||
error("Resolution cannot exceed 64")
|
||||
end
|
||||
local shader = lg.newShader(shader3d)
|
||||
resolution,random,decayFn = _defaultArgs(resolution,random,decayFn)
|
||||
local amplitudes,sigma,offsets = _amplitudesAndOffsets(decayFn,resolution,3*resolution,random)
|
||||
sigma = sigma/sqrt(3)
|
||||
|
@ -24,5 +24,5 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
|
||||
float x = mix(range_min,range_max,texture_coords.x);
|
||||
float n = noise1d(x);
|
||||
//return vec4(n,n,n,1.);
|
||||
return texture_coords.y > n ? vec4(1.,1.,1.,1.) : vec4(0.,0.,0.,1.);
|
||||
return texture_coords.y > (1.-n) ? vec4(1.,1.,1.,1.) : vec4(0.,0.,0.,1.);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user