It looks like you're new here. If you want to get involved, click one of these buttons!
Here's another bit of fun with shaders. In this one all the interesting stuff happens in the vertex shader. The mesh is divided into squares which "explode": they zoom off in different directions slowing rotating as they do. The catch is that you have to program in the full path of each square so you can't do a "step by step" solution of the ODE. This means that it is only practical to use this for ODEs that can be solved with closed form.
It also demonstrates how buffers work.
Second time through in the video then I didn't call the background
function. Rather firework-y in effect!
displayMode(FULLSCREEN)
function setup()
backingMode(RETAINED)
explosion = mesh()
local s = shader()
s.vertexProgram, s.fragmentProgram = expshader()
explosion.shader = s
explosion.texture = "Cargo Bot:Codea Icon"
explosion.shader.friction = .1
explosion.shader.factor = 10
local vels = explosion:buffer("velocity")
local origin = explosion:buffer("origin")
local angv = explosion:buffer("angvel")
local m,n = 20,20
vels:resize(m*n*6)
origin:resize(m*n*6)
angv:resize(m*n*6)
local w,h = 20,20
local xx,y = (WIDTH - n*w)/2, (HEIGHT - h*m)/2
explosion.shader.size = vec2(n*w,m*h)
explosion.shader.lr = vec2(xx - w/2,y - h/2)
local c = vec2(xx+n*w/2,y+m*h/2)
local cl = vec2(n*w,m*h):len()/2
local r,th,sf,x,df
sf = .3
df = math.random()
for i=1,m do
x = xx
for j = 1,n do
r = explosion:addRect(x,y,w,h)
explosion:setRectTex(r,(j-1)/n,(i-1)/m,1/n,1/m)
th = 2*noise(i*sf+df,j*sf+df)*math.pi
for k=1,6 do
vels[6*r-k+1] = 20*(2-(c:dist(vec2(x,y))/cl))^2
*vec4(math.cos(th),math.sin(th),0,0)
origin[6*r-k+1] = vec2(x,y)
angv[6*r-k+1] = vec2(th,0)
end
x = x + w
end
y = y + h
end
--startRecording()
end
function draw()
if ElapsedTime < 10 then
background(91, 90, 71, 255)
explosion.shader.time = math.max(0,ElapsedTime-2)
elseif ElapsedTime < 11 then
background(0, 0, 0, 255)
explosion.shader.time = 0
else
explosion.shader.time = math.max(0,ElapsedTime-12)
end
explosion:draw()
end
function touched(touch)
end
function expshader()
return [[
//
// The explosion vertex shader
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
uniform float time;
uniform vec2 size;
uniform vec2 lr;
uniform float friction;
uniform float factor;
lowp vec4 gravity = vec4(0.,-1.,0.,0.);
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
// These are vertex buffers: initial velocity of the square,
// angular velocity,
// centre of square
attribute vec4 velocity;
attribute vec2 angvel;
attribute vec2 origin;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
// ODE: x'' = -friction x' + gravity
// Solution: A exp(- friction * time) + B + time*gravity/friction
// Initial conditions:
// A = gravity/(friction*friction) - x'(0)/friction
// B = x(0) -A
void main()
{
//Pass the mesh color to the fragment shader
vColor = color;
vTexCoord = texCoord;
lowp vec4 pos;
lowp float angle = time*angvel.x;
highp vec4 A = gravity/(friction*friction) - velocity/friction;
highp vec4 B = vec4(origin,0.,0.) - A;
lowp mat2 rot = mat2(cos(angle), sin(angle), -sin(angle), cos(angle));
pos = (position - vec4(origin,0.,0.));
pos.xy = rot * pos.xy;
pos += exp(-factor*time*friction)*A + B + factor*time * gravity/friction;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * pos;
}
]],[[
//
// A basic fragment shader
//
//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;
void main()
{
//Sample the texture at the interpolated coordinate
lowp vec4 col = texture2D( texture, vTexCoord );
//Set the output color to the texture color
gl_FragColor = col;
}
]]
end
Comments
What means this "ODE"?
Hello @Marksolberg. ODE is ordinary differential equation. See this Wikipedia article for more information.
Wow ... Would you like to do a script for meta balls in 3D?
Awesome work! had to implement it right away in my WIP "snake on steroids" project:
EDIT: just saw that the video makes it all look awful... ^^
The "sparks" are also made with it.
Thanks for making it easy to put it in the shader lab for easy access.
Just one thing I haven't really managed to do is change the "coloring" of the mesh textures (in my case to make it transparent over time).
Does not work the way I usually do it with textured meshes and I am absolutely not sure if has to do with the shader code...
If you would be so kind to help me out, I'd really appreciate it.
First, I have to apologize for the following.
Ode to an ODE. (Well actually a limerick.)
There once was a female mathematician
Who had a sexual aberration
"It's not what you think"
She said with a wink
"He's no Ordinary Differential Equation!"
.@VanDread Here's an example with "trails":
I've now written it as a class to make it easy to use with different projects. It's part of my library: http://www.math.ntnu.no/~stacey/code/CodeLibrary. It has no dependencies so you can just grab the
Explosion.lua
file (remove theimport.library
bit at the start and the lastend
) and use as-is.Update your link, I think. it goes to your home page, but not to where your code is stored.
Ooops!
http://www.math.ntnu.no/~stacey/code/CodeaLibrary
@Andrew_Stacey - Could you please tell me how to make an explosion? I have the class copied into a project, but I don't understand how to use it [and I can't see the videos
Here's an example that I have:
In
setup
:Then in
draw
, I just haveexplosion:draw()
, and that's it!How I use it in a more complicated project is as follows:
setContext
).draw
method during its own draw method.For example, in my newer version of the Anagrams program, then when the word is guessed, the following code runs:
Thank you as always @Andrew_Stacey \^-^/ it's a beautiful effect. Is it available to use in any project (or rather, may I have your permission to use it)?
EDIT: I did all of that and it didn't work (for me at least)
@Monkeyman32123 You'll need to post some code for me to see. It's working for me with a simple example program so to figure out what's not working for you I need something to see.
As for using it, as far as possible I place all my code in the public domain (the only time I can't is when I've used someone else's code).
I tried to place it in my gyroship project (to explode when "youdead == true"... I can't really give you just a snippet as the project is large (but it is on github, and there is a "project beta" discussion about it)
Can you upload your attempt with the explosion to github? I downloaded what you have but there's jo explosion code there.
@Andrew_Stacey that is awesome thank you very much for sharing it. I'm having an issue if my fireworks project. Occasionally the shader shows active = true yet nothing is draw.
Gist - https://gist.github.com/briarfox/8cb3204825694ceeb6ff
@Briarfox - in a situation where a shader works intermittently, it's most probable that you have a problem with its inputs, because if a shader doesn't like something, it just doesn't work (which is your problem).
So I would carefully check all the shader parameters and make sure they are always valid each time they are set. The best may be to output them each time you start a firework, and then look at them carefully for any firework that didn't explode (and maybe compare with one that did explode).
@Ignatz Thanks, I figured it out. math.random(.1,1) was throwing a 0 out for firction which crashed it.
Fixed firework code here.
https://gist.github.com/briarfox/8cb3204825694ceeb6ff
@andrew_stacey I just wanted to set up an explosion in "setup" and then, when a certain variable becomes true, I want to begin and draw the explosion in the draw function (in main).
@Monkeyman32123 It is so much easier to debug with some actual code. Could you post your attempt somewhere?
In the "drawship" function I did this
@monkeyman32123 try this:
Here is a main tab that lets you play with all the explosion shader settings. This is only the main tab, grab the explosion shader from above.
@Monkeyman32123 You're missing a couple of selfs in that code.
I have it so that it sets up the explosion in setup, then activates it when you die, then draws it in the draw step....and it works...BUT it makes the explosion always in the place I set it to be in setup (obviously)...is there a way for me to keep setting up the explosion in setup but change it's location when you die before it draws? If I try to setup the explosion anywhere but in setup it causes massive lag spikes
Can't you wrap it in a translate?
Yeah, I literally just figured that out right before you commented XD
But thank you sir