This was originally asked by @sydd here. I was curious about it so I try to code it but It was closed/deleted before I could answer so here it is.
Question: How to reproduce/implement this 2D ray casting lighting effect in GLSL?
The effect itself cast rays from mouse position to every direction, accumulating background map alpha and colors affecting the pixels strength.
So the input should be:
Background map
Ok I created a test RGBA map as 2 images one containing RGB (on the left) and second with the alpha channel (on the right) so you can see them both. Of coarse they are combined to form single RGBA texture.
I blurred them both a bit to obtain better visual effects on the edges.
Ray casting
As this should run in GLSL we need to cast the rays somewhere. I decided to do it in fragment shader. So the algo is like this:
On Fragment shader per each fragment:
Vertex shader
// Vertex
#version 420 core
layout(location=0) in vec2 pos; // glVertex2f <-1,+1>
layout(location=8) in vec2 txr; // glTexCoord2f Unit0 <0,1>
out smooth vec2 t1; // texture end point <0,1>
void main()
{
t1=txr;
gl_Position=vec4(pos,0.0,1.0);
}
Fragment shader
// Fragment
#version 420 core
uniform float transmit=0.99;// light transmition coeficient <0,1>
uniform int txrsiz=512; // max texture size [pixels]
uniform sampler2D txrmap; // texture unit for light map
uniform vec2 t0; // texture start point (mouse position) <0,1>
in smooth vec2 t1; // texture end point, direction <0,1>
out vec4 col;
void main()
{
int i;
vec2 t,dt;
vec4 c0,c1;
dt=normalize(t1-t0)/float(txrsiz);
c0=vec4(1.0,1.0,1.0,1.0); // light ray strength
t=t0;
if (dot(t1-t,dt)>0.0)
for (i=0;i<txrsiz;i++)
{
c1=texture2D(txrmap,t);
c0.rgb*=((c1.a)*(c1.rgb))+((1.0f-c1.a)*transmit);
if (dot(t1-t,dt)<=0.000f) break;
if (c0.r+c0.g+c0.b<=0.001f) break;
t+=dt;
}
col=0.90*c0+0.10*texture2D(txrmap,t1); // render with ambient light
// col=c0; // render without ambient light
}
And Finally the result:
Animated 256 colors GIF:
The colors in GIF are slightly distorted due to 8 bit truncation. Also if the animation stops refresh page or open in decend gfx viewer instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With