Trouble with a simple fragment shader

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Jugbot
Prole
Posts: 7
Joined: Mon Jun 24, 2019 9:54 pm

Trouble with a simple fragment shader

Hello I am trying to make a circle in the fragment shader but I cant seem to figure out how to properly pass world positions to the fragments. Currently I do it through a varying attribute.

Code: Select all

uniform int objects = 0;
uniform vec2 positions[50];
varying vec2 texPos;

#ifdef VERTEX
vec4 position(mat4 transform_projection, vec4 vertex_position)
{
// The order of operations matters when doing matrix multiplication.
texPos = (TransformMatrix*VertexPosition).xy;
return transform_projection * vertex_position;
}
#endif

#ifdef PIXEL
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords ) {
for (int i = 0; i < objects; i++) {
// vec2 screen_point = (vec4(positions[i],0 ,0) * ProjectionMatrix).xy;
// if (distance(screen_point, screen_coords) < radii[i])
// return vec4(distance(vec2(0,0), texPos)<1,0,0,1);
}
return vec4(distance(vec2(0,0), texPos)<1,0,0,1);
}
#endif

pgimeno
Party member
Posts: 1681
Joined: Sun Oct 18, 2015 2:58 pm

Re: Trouble with a simple fragment shader

You can transform world to screen in Lua and send it to the fragment shader as a uniform. Or if you want the computation made by the shader, send the transform to the shader as well.

Note that TransformMatrix may be an identity matrix, see caveat of TransformMatrix in Shader Variables.

Jugbot
Prole
Posts: 7
Joined: Mon Jun 24, 2019 9:54 pm

Re: Trouble with a simple fragment shader

Do you know how I can get the transform matrix to the shader (or the raw coordinates of the polygon I am drawing?)

pgimeno
Party member
Posts: 1681
Joined: Sun Oct 18, 2015 2:58 pm

Re: Trouble with a simple fragment shader

I'm not sure what your setup is, so I am just guessing here.

If you are trying to get the transform that you have modified through love.graphics.translate, love.graphics.rotate etc., well, to the best of my knowledge, you can't. You have to change strategy: create a Transform object with love.math.newTransform, and use the Transform object variations: Transform:translate, Transform:rotate etc. instead of the love.graphics ones. At the time of rendering, you can apply the transform with love.graphics.replaceTransform for drawing, and get the matrix with Transform:getMatrix for the shader.

raidho36
Party member
Posts: 1791
Joined: Mon Jun 17, 2013 12:00 pm

Re: Trouble with a simple fragment shader

You pretty much do what you commented out, and don't do what you left active. Your circle positions are world coordinates, and your custom transform is a worldview matrix from a virtual camera that's looking at the circles. Your circle positions should be 4-vectors though, and you can encode the radii in the w coordinate (which's normally unit but it can be played with and basically just scales the model).

If you want to simply render a circle, you should just use a circle texture stretched over a quad, it'll be faster that way. If you insist on using shaders, you can render a blank quad with a shader that renders an inscribed circle. Unless you want your circles to interact within the shader, you should render them separately, using batching or instancing. Even if interaction is required, it's usually possible to render them sequentially one by one.

Additionally, the for loop in shader might pretty easily fail on various GPUs, you should always unroll the loops; if you think that's too much work - you're SOL, it's either that or random failures for other people. Using branching (if-else) in shader should also be avoided, as it throttles the execution of code on its vector cores; in your case specifically you can use the "step", "smoothstep", "clamp" or "lerp" function to create black or white color depending on the distance.

Jugbot
Prole
Posts: 7
Joined: Mon Jun 24, 2019 9:54 pm

Re: Trouble with a simple fragment shader

So this was my endgoal (achieved!) for context

Basically I had to pass in camera coordinates from hump.camera