Author Topic: Trying to understand position within a shader  (Read 2241 times)

tsaylor

  • Full Member
  • ***
  • Posts: 58
    • View Profile
Trying to understand position within a shader
« on: April 02, 2021, 10:39:45 AM »
I'm experimenting with writing my first shader, but I'm having a hard time using gl_FragCoord to determine the position within the image. Does anyone here have experience with this? I can set gl_FragColor and see results, but what I can't seem to do is pass values into the shader (say a position and a size), and then use those values relative to the current coordinate in gl_FragCoord. Basically I'm trying to color a specified set of pixels within the image, where those locations are provided by an AM layout. Is there a secret I'm missing? I can get the desired results in an online tool such as thebookofshaders.com, but using the same code (I think) in a shader called by AM does not give the same results. I suspect the difference lies in how the coordinates are used, but I don't know of any direct way to "debug" the shader and show those internal values at run time.

I can put together a test example if needed, but I was hoping someone here knows something about conversion between a "standard" GLSL fragment shader and an AM compatible shader. In case it matters, the object I'm assigning the shader to is a surface.

tsaylor

  • Full Member
  • ***
  • Posts: 58
    • View Profile
Re: Trying to understand position within a shader
« Reply #1 on: April 05, 2021, 10:08:52 PM »
I was able to track down my issues with this, and I'm beginning to understand it better. gl_FragCoord is indeed usable but I learned two important points, which I'll document here in case they are useful to others in the future:

  • The coordinate system is opposite to the normal AM screen coordinates. Within a shader (0,0) is bottom left instead of top left.
  • The coordinates are relative to the entire screen size. Normally this should not be an issue but in my case I am setting fe.layout.width and fe.layout.height to make the dimensions smaller because I'm testing different layout resolutions. This leaves some unused space on the screen edges, and those pixels still count.

For point 1, we can change the behavior by placing this line at the top of the shader code, switching to the AM style layout coordinates:

layout(origin_upper_left) in vec4 gl_FragCoord;

For point 2, I'm now passing a set of offset coordinates to the shader, and using them to shift the position and accommodate the extra screen edges. In my case this was like:

shader.set_param("fragmentOffset", -(ScreenWidth - flw) / 2, -(ScreenHeight - flh) / 2);

And then used in the shader like so:
vec2 position = gl_FragCoord.xy + fragmentOffset;
(then I use position instead of gl_FragCoord)