Created
September 28, 2014 09:48
-
-
Save dermotbalson/f8cbbec0f64c7776e71c to your computer and use it in GitHub Desktop.
Simplex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--SimplexTest | |
function setup() | |
displayMode(OVERLAY) | |
parameter.integer("TileSize",100,1200,700,CreateTile) | |
--scale allows you to change the resolution of the noise | |
parameter.number("Scale",0.1,50,3,CreateTile) | |
parameter.color("Colour",color(50,130,185,200),CreateTile) | |
--tile colour | |
parameter.integer("Alpha",0,255,210,CreateTile) | |
--the offset just lets you start the noise somewhere else than at 0 | |
--if you think of noise as a landscape, it means you can move somewhere else | |
parameter.number("Offset",0,10,0,CreateTile) | |
parameter.number("FPS",0,60,60) | |
ready=true | |
CreateTile() | |
end | |
--creates mesh, draws it with a shader, and returns a seamless image | |
function CreateTile() | |
--ready variable just stops this function running until all parameters are set | |
if not ready then return end | |
local m=mesh() | |
local w,h=TileSize,TileSize | |
m:addRect(w/2,h/2,w,h) | |
m.shader=shader(SimplexShader2.v,SimplexShader2.f) | |
m.shader.scale=Scale | |
m.shader.offset=Offset | |
c=Colour | |
c.a=Alpha | |
m.shader.c=color(255) | |
local i=image(w,h) | |
setContext(i) | |
m:draw() | |
c=Colour | |
if Alpha>0 then | |
c.a=Alpha | |
fill(c) | |
rect(-5,-5,w+10,h+10) | |
end | |
setContext() | |
--set up tiling | |
mm=setupTiles(i,WIDTH,HEIGHT) | |
mm.pos=vec2(0,0) | |
end | |
function setupTiles(img,w,h) | |
local m=mesh() | |
m.texture=img | |
local v,t={},{} | |
--now calculate how many times the image is used along the x and z axes | |
--use these as the maximum texture settings | |
--the shader will just use the fractional part of the texture mapping | |
--(the shader only requires one line to change, to do this) | |
local x1,x2,y1,y2=0,w,0,h | |
local tw,th=w/img.width,h/img.height | |
local tx1,tx2,ty1,ty2=0,tw,0,th | |
v[1]=vec3(x1,y1,0) t[1]=vec2(tx1,ty1) | |
v[2]=vec3(x2,y1,0) t[2]=vec2(tx2,ty1) | |
v[3]=vec3(x2,y2,0) t[3]=vec2(tx2,ty2) | |
v[4]=vec3(x1,y2,0) t[4]=vec2(tx1,ty2) | |
v[5]=vec3(x1,y1,0) t[5]=vec2(tx1,ty1) | |
v[6]=vec3(x2,y2,0) t[6]=vec2(tx2,ty2) | |
m.vertices=v | |
m.texCoords=t | |
m.shader=shader(TileShader.vertexShader,TileShader.fragmentShader) | |
m:setColors(color(255)) | |
m.t=t | |
m.w,m.h=img.width,img.height | |
return m | |
end | |
function AdjustTilePosition(x,y) | |
local b=mm:buffer("texCoord") | |
for i=1,6 do | |
mm.t[i]=mm.t[i]+vec2(x/mm.w,y/mm.h) | |
b[i]=mm.t[i] | |
end | |
end | |
function draw() | |
background(220) | |
FPS=0.9*FPS+0.1/DeltaTime | |
AdjustTilePosition(2,2) | |
mm:draw() | |
end | |
SimplexShader2 = { | |
v = [[ | |
uniform mat4 modelViewProjection; | |
attribute vec4 position; | |
attribute vec4 color; | |
attribute vec2 texCoord; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
vColor = color; | |
vTexCoord = texCoord; | |
gl_Position = modelViewProjection * position; | |
} | |
]], | |
f = [[ | |
precision highp float; | |
//uniform lowp sampler2D texture; | |
uniform float offset; | |
uniform float scale; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
highp vec4 pParam = vec4(289.0, 34.0, 1.0, 7.0); | |
float permute(float x0,vec3 p) { | |
float x1 = mod(x0 * p.y, p.x); | |
return floor( mod( (x1 + p.z) *x0, p.x )); | |
} | |
vec2 permute(vec2 x0,vec3 p) { | |
vec2 x1 = mod(x0 * p.y, p.x); | |
return floor( mod( (x1 + p.z) *x0, p.x )); | |
} | |
vec3 permute(vec3 x0,vec3 p) { | |
vec3 x1 = mod(x0 * p.y, p.x); | |
return floor( mod( (x1 + p.z) *x0, p.x )); | |
} | |
vec4 permute(vec4 x0,vec3 p) { | |
vec4 x1 = mod(x0 * p.y, p.x); | |
return floor( mod( (x1 + p.z) *x0, p.x )); | |
} | |
//uniform vec4 pParam; | |
// Example constant with a 289 element permutation | |
//const vec4 pParam = vec4( 17.0*17.0, 34.0, 1.0, 7.0); | |
//-------- | |
float simplexNoise2(vec2 v) | |
{ | |
const vec2 C = vec2(0.211324865405187134, // (3.0-sqrt(3.0))/6.; | |
0.366025403784438597); // 0.5*(sqrt(3.0)-1.); | |
const vec3 D = vec3( 0., 0.5, 2.0) * 3.14159265358979312; | |
// First corner | |
vec2 i = floor(v + dot(v, C.yy) ); | |
vec2 x0 = v - i + dot(i, C.xx); | |
// Other corners | |
vec2 i1 = (x0.x > x0.y) ? vec2(1.,0.) : vec2(0.,1.) ; | |
// x0 = x0 - 0. + 0. * C | |
vec2 x1 = x0 - i1 + 1. * C.xx ; | |
vec2 x2 = x0 - 1. + 2. * C.xx ; | |
// Permutations | |
i = mod(i, pParam.x); | |
vec3 p = permute( permute( | |
i.y + vec3(0., i1.y, 1. ), pParam.xyz) | |
+ i.x + vec3(0., i1.x, 1. ), pParam.xyz); | |
// N points around a unit circle. | |
vec3 phi = D.z * mod(p,pParam.w) /pParam.w ; | |
vec4 a0 = sin(phi.xxyy+D.xyxy); | |
vec2 a1 = sin(phi.zz +D.xy); | |
vec3 g = vec3( dot(a0.xy, x0), dot(a0.zw, x1), dot(a1.xy, x2) ); | |
// mix | |
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.); | |
m = m*m ; | |
return 1.66666* 70.*dot(m*m, g); | |
} | |
void main() | |
{ | |
//create scaled copy of texture position | |
highp vec2 p = offset+scale*vec2(vTexCoord.x,vTexCoord.y); | |
//interpolate | |
float A = simplexNoise2(p); | |
float B = simplexNoise2(vec2(p.x+scale,p.y)); | |
float C = simplexNoise2(vec2(p.x,p.y+scale)); | |
float D = simplexNoise2(p+scale); | |
float xx = 1.0 - vTexCoord.x; | |
float yy = 1.0 - vTexCoord.y; | |
float AB = mix(A,B,xx); | |
float CD = mix(C,D,xx); | |
float u = mix(AB,CD,yy); | |
u=(u+1.0)/2.0; //because noise goes from -1 to +1, and we want it 0-1 | |
gl_FragColor = vec4(u,u,u,1.0); | |
} | |
]]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment