Skip to content

Instantly share code, notes, and snippets.

@GlueBalloon
Last active September 10, 2015 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GlueBalloon/67fd3f00b927257861e2 to your computer and use it in GitHub Desktop.
Save GlueBalloon/67fd3f00b927257861e2 to your computer and use it in GitHub Desktop.
Complex Shader Life
--# Main
displayMode(FULLSCREEN)
function setup()
showBuffer = true
readPixelCode = true
local w,h = WIDTH,HEIGHT
local w,h = 20,20
source = image(w,h)
target = image(w,h)
worldEngine = mesh()
local s = shader()
s.vertexProgram, s.fragmentProgram = worldEngineShader()
worldEngine.shader = s
worldEngine.texture = source
worldEngine:addRect(w/2,h/2,w,h)
-- Factor of 2 is for retina displays
worldEngine.shader.width = 2*w
worldEngine.shader.height = 2*h
worldEngine.shader.markerTurnA = true
local leftOfVisible = color(0, 0, 25, 255)
local belowLeftOfVisible = color(0,0,100,255)
local belowVisible = color(0,0,150,255)
local markerA = color(0, 0, 255, 255)
local markerB = color(0, 255,255, 255)
worldEngine.shader.leftOfVisible = leftOfVisible
worldEngine.shader.belowLeftOfVisible = belowLeftOfVisible
worldEngine.shader.belowVisible = belowVisible
worldEngine.shader.markerA = markerA
worldEngine.shader.markerB = markerB
local nf = 50 + 5*math.random()
local xd = math.random()
local yd = math.random()
for x = 1,w do
for y = 1,h do
if math.fmod(y,2) == 0 and math.fmod(x,2) == 1 then
source:set(x,y,color(10,255,0,255)) -- color for ground
elseif math.fmod(y,2) == 0 and math.fmod(x,2) == 0 then
source:set(x,y,leftOfVisible)
elseif math.fmod(y,2) == 1 and math.fmod(x,2) == 1 then
source:set(x,y,belowVisible)
elseif math.fmod(y,2) == 1 and math.fmod(x,2) == 0 then
source:set(x,y,belowLeftOfVisible)
end
if math.fmod(y,8) == 0 and math.fmod(x,12) == 0 then
source:set(x,y,markerA) -- color for initial creatures
elseif (y == 2 or y == 18) and math.fmod(x,16) == 0 then
source:set(x,y,markerB) -- color for initial creatures
end
end
end
visibleWorld = mesh()
visibleWorld:addRect(WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
s = shader()
s.vertexProgram, s.fragmentProgram = displayShader()
visibleWorld.shader = s
visibleWorld.texture = source
visibleWorld.shader.colour = color(36, 45, 69, 255)
visibleWorld.shader.alive = color(30, 164, 23, 255)
visibleWorld:setColors(255,255,255,255)
visibleWorld.shader.width = worldEngine.shader.width
visibleWorld.shader.height = worldEngine.shader.height
end
function draw()
background(56, 62, 61, 255)
noSmooth()
setContext(target)
worldEngine:draw()
setContext()
source, target = target, source
worldEngine.texture = source
visibleWorld.texture = source
visibleWorld:draw()
if showBuffer then
ortho()
viewMatrix(matrix())
sprite(target,170,170,320,320)
end
if worldEngine.shader.markerTurnA == true then
worldEngine.shader.markerTurnA = false
else
worldEngine.shader.markerTurnA = true
end
end
function touched(touch)
end
--# golShader
function worldEngineShader()
return [[
//
// A Game of Life shader, vertex section does almost nothing.
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
//Pass the everything to the fragment shader
vColor = color;
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]],
[[
// fragment shader, does the work.
//boilerplate:
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
//custom code:
// width and height of the texture for finding neighbours
uniform highp float width;
uniform highp float height;
lowp float colstep = .05;
highp float w = 1./width;
highp float h = 1./height;
uniform bool markerTurnA;
uniform highp vec4 leftOfVisible;
uniform highp vec4 belowLeftOfVisible;
uniform highp vec4 belowVisible;
uniform highp vec4 markerA;
uniform highp vec4 markerB;
highp vec2 above2 = vec2(0.,-4.);
highp vec2 aboveright2 = vec2(4.,-4.);
highp vec2 right2 = vec2(4.,0.);
highp vec2 belowright2 = vec2(4.,4.);
highp vec2 below2 = vec2(0.,4.);
highp vec2 belowleft2 = vec2(-4.,4.);
highp vec2 left2 = vec2(-4.,0.);
highp vec2 aboveleft2 = vec2(-4.,-4.);
//something mathy by Andrew Stacey, not sure what it does:
highp vec2 vfract(highp vec2 v) {
return vec2(fract(v.x),fract(v.y)); //fract(whatever) returns just the decimal part?
}
// get the color in vector direction
lowp vec4 colorAt(highp vec2 direction) {
lowp vec4 found = texture2D(texture,vfract(vTexCoord + vec2(w*direction.x,h*direction.y)));
return found;
}
//check for markers
lowp vec2 markerInRadius () {
highp vec4 thisColor = colorAt(above2);
if (thisColor == markerB || thisColor == markerA) {
return above2;
}
thisColor = colorAt(aboveright2);
if (thisColor == markerB || thisColor == markerA) {
return aboveright2;
}
thisColor = colorAt(right2);
if (thisColor == markerB || thisColor == markerA) {
return right2;
}
thisColor = colorAt(belowright2);
if (thisColor == markerB || thisColor == markerA) {
return belowright2;
}
thisColor = colorAt(below2);
if (thisColor == markerB || thisColor == markerA) {
return below2;
}
thisColor = colorAt(belowleft2);
if (thisColor == markerB || thisColor == markerA) {
return belowleft2;
}
thisColor = colorAt(left2);
if (thisColor == markerB || thisColor == markerA) {
return left2;
}
thisColor = colorAt(aboveleft2);
if (thisColor == markerB || thisColor == markerA) {
//return aboveleft2;
}
return vec2(0.,0.);
}
void main()
{
lowp vec4 col;
col = texture2D(texture,vTexCoord);
//colors defined
lowp vec4 ground = vec4(0.04,1.,0.,1.);
lowp vec4 livingThing = vec4(1.,0.,0.,1.);
lowp vec4 colorToLeft = colorAt(vec2(-2.,0.));
lowp vec4 colorTwoToLeft = colorAt(vec2(-4.,0.));
//check if there is a marker around
lowp vec2 markerAt = markerInRadius();
if (markerAt != vec2(0.,0.)) {
//get the color
lowp vec4 colorThere = colorAt(markerAt);
//if the position is to the left
if (markerAt == left2) {
//if it is a markerA on markerTurnA
if (colorThere == markerA && markerTurnA == true) {
//make this a markerB
col = markerB;
}
//else if the position is up and left
} else if (markerAt == belowleft2){
//if it is a markerB NOT on markerTurnA
if (colorThere == markerB && markerTurnA == false) {
//make this a markerA
col = markerA;
}
}
}
if (markerTurnA == true && col == markerA){
col = leftOfVisible;
} else if (markerTurnA == false && col == markerB){
col = leftOfVisible;
} else if (colorAt(vec2(-2.,0.)) == markerB || colorAt(vec2(-2.,0.)) == markerA){
col = livingThing;
} else if (col == livingThing){
col = ground;
}
//if this is markerTurnA...
if (true ==false){
if (markerTurnA == true){
//if the color two to the left is markerA...
if (colorTwoToLeft == markerA) {
//make this markerB
col = markerB;
//but if the color one to the left is markerA...
} else if (colorToLeft == markerA) {
//this should be alive
col = livingThing;
//but if it is already alive..
} else if (col == livingThing){
//un-alive it
col = ground;
//but if this itself is markerA...
} else if (col == markerA){
//code it as the leftOfVisible
col = leftOfVisible;
}
} else {
//if the color two to the left is markerB...
if (colorTwoToLeft == markerB) {
//make this markerA
col = markerA;
//but if the color one to the left is markerB...
} else if (colorToLeft == markerB) {
//this should be alive
col = livingThing;
//but if it is already alive..
} else if (col == livingThing){
//un-alive it
col = ground;
//but if this itself is markerB...
} else if (col == markerB){
//code it as the leftOfVisible
col = leftOfVisible;
}
}
}
//Set the output color to the texture color
gl_FragColor = col;
}
]]
end
--# golrShader
function displayShader()
return [[
//
// Rendering vertex shader, does almost nothing.
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
//Pass the everything to the fragment shader
vColor = color;
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]],[[
//
// Rendering fragment shader, interprets the raw GoL data.
//
//This is the raw data
uniform lowp sampler2D texture;
//Colours for rendering
uniform lowp vec4 colour;
uniform lowp vec4 alive;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
// width and height of the texture for finding neighbours
uniform highp float width;
uniform highp float height;
lowp float colstep = .05;
highp float w = 1./width;
highp float h = 1./height;
highp vec2 vfract(highp vec2 v)
{
return vec2(fract(v.x),fract(v.y)); //fract(whatever) returns just the decimal part?
}
// get the color in vector direction
lowp vec4 colorAt(highp vec2 direction)
{
lowp vec4 found = texture2D(texture,vfract(vTexCoord + vec2(w*direction.x,h*direction.y)));
return found;
}
void main()
{
//Sample the data at the interpolated coordinate
lowp vec4 col;
col = texture2D( texture, vTexCoord );
lowp float multiple = 80.;
lowp vec4 rightColor = colorAt(vec2(multiple*w,0.));
lowp vec4 upColor = colorAt(vec2(0.,multiple*h));
lowp vec4 upAndRightColor = colorAt(vec2(multiple*w,multiple*h));
if (col.r > 0.02) {
//leave as is
} else if (rightColor.r > 0.02 ){
col = rightColor;
} else if (upColor.r > 0.02) {
col = upColor;
} else if (upAndRightColor.r > 0.02) {
col = upAndRightColor;
}
//Set the output color
gl_FragColor = col;
}
]]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment