Is there a way to set a variable in the fragment shader so that it can then be accessed through the light shader? Assuming that lighting is done on a per-pixel basis (default behavior), I would believe it to be possible.
For context, I’m trying to use a normal map to affect the geometry of a mesh but not its lighting (for stylized highlights for eyes). I am aware that this can be accomplished through other means, but the above would drastically simplify my workflow.
I am aware that I can do this by adding a separate mesh on top of the eye for the highlight, but I wanted to see if I could accomplish this with just shaders (possibly, by using another pass).
You don’t need a separate mesh. You can just add an additional shader pass on the same mesh. This would probably be the easiest way as it wouldn’t require manual lighting calculations.
To do exactly what you ask, you can either sample the normal map in the light() function and perturb the normal yourself, or to actually send something from fragment() to light() function you can abuse one of the built ins you don’t need, for example BACKLIGHT.
The main problem that I had with varying is that it stores the values on a per-vertex basis (no idea if there’s a way around that), whereas I’d want the values stored on a per-pixel basis.
After testing all of the above ideas, recomputing the normal map in the light shader yielded the best results. (Using the backlight had other issues, especially as it cannot be modified in the light shader.)
It should be per pixel if you don’t touch the varying in the vertex function. Just assign it in the fragment function and read it in the light function.
That said I’d still go with the additional shader pass approach. It requires the least effort to set up.
Originally, I tested a varying variable in the fragment shader (as that seemed to be the obvious solution at the time), and since the test mesh was low-poly, it was easy to tell that it was just interpolating the value throughout vertices. (It is possible that it was interpolating it on a per-pixel basis, but it definitely didn’t look like it, as it was lighting certain mesh polygons.) However, I can look into it again to see if I overlooked something else (possibly, a project setting or something else).