I’m trying to write a shader that works using screen-space pixels.
Namely, something akin to a horizontal fade out across each object.
Is there a way to access the pixel’s screen-space coordinate from within a fragment shader?
This documentation page’s Detail Texture in Screen Space is pretty much what I want, but it uses Unity Surface Shaders, and I can’t access clip() from there, and I need it for my shader.
You’re in luck! This is thankfully simple.
After a vertex has been multiplied by the modelviewprojection matrix (globally accessible in shaders as “UNITY_MATRIX_MVP”), its coordinates are in clip space. Clip space’s coordinates range from (-1,-1,-1) to (1,1,1) in OpenGL, where the z coordinate is the depth value that gets written to the depth buffer. The range of z is 0 and 1 in Direct3D, but you don’t have to care about this discrepancy, because for pixel positions, you’re only interested in the x and y coordinates.
The center of clip space is the center of the screen, i.e. x = -1 is the left side of the screen and x = 1 is the right, with y = -1 the bottom and y = 1 the top. So all you have to do is save the clip space vertex coordinate using one of the texture channels in your vertex shader, then access the same texture channel in the fragment shader’s input parameters. Then the rasterizer will have interpolated the pixel’s clip space coordinate for you.
Using that, you can convert the pixel clip space coordinate to screen space using the screen resolution. This other question has the code samples and the conversion formula, saving me the trouble of writing it here: