I am writing a shader that uses multiple shader passes. A texture created by the first pass is handed to the second pass by the GrabPass function and is further processed there.
Pass1 → GrabPass{“_TexturePass1”} → Pass2
In general, the shader seems to do what it is supposed to do. But sometimes it seems that Pass2 uses textures that have been not completely calculated. This is expressed by a short flash of the graphic with various errors.
Is there any option to prevent this problem? As an example - is there a function similar to glfinish() to hand only completely calculated textures to the GrabPass function?
Not possible. GrabPass will only ever grab the contents of the screen exactly as they after the previous pass has finished.
Note that due to batching and setpass optimizations this may be after other objects with the same shader have been renderer as well, and depending on your first pass’s setup may be intersecting with other objects in the world. I would suggest using the Frame Debugger window to step through. You should see your first pass render, then the grab pass, then your second pass. I would be very surprised if the issues you’re seeing don’t appear in the first pass before the grab pass, or are caused by something in the second pass regardless of what’s in the first.
However I wonder why you’re using a grab pass at all. Why not calculate the texture and do the processing in one pass?
I checked the render queue. Those values seem to be set correct.
I can also see the problem in the frame debugger. The first texture is rendered correctly. The second texture is a combination of a compressed version of the grabbed texture and the second texture. Normally the first texture should also not be compressed. Normally the multiplied version of the grabbed texture and the second texture is shown. The problem appears once each time starting the game or clicking anywhere in the unity editor.
The shader consists of multiple passes creating textures that are combined. Later on some passes could be disabled if they are not necessary. This is the main reason for the use of the GrabPass function. Is there a better alternative to reuse the resulting texture in a kind of second pass?
Sure, you could write a script to setup a render texture, set it as the active target, render the mesh with draw now, then pass that to your material(s).
Depending on the generated texture and what you’re trying to do you could use a custom render texture as well.
Thank you for you answer, bgolus. I already looked at this method, but I am looking for a way to hand the resulting texture if the previous pass internally in the shader. As any example I found the UNITY_FRAMEBUFFER_FETCH_AVAILABLE function. Is there any documentation how those framebuffer fetches work?