I have a sampler2D from a GrabPass, I want to lower it resolution so that it cheaper to calculate in the next pass. I done a lot of research but all I found about this was done in C#, using RenderTexture. Can I do this directly in shader code?
You could use a command buffer to Blit() the screen onto a render texture and sample from that.
A Grab pass will copy each pixel of the screen, so the target texture must be the size of the screen. Blit() copies the screen using sampling (with a material), so it can be put into any sized texture.
Both Blit() and Grab Pass happen on the GPU, so there isn’t much overhead difference between one Blit and one Grab.That said, using command buffers would require some c# to set up.
Then how would I project the returned texture onto the object like a grabpass would? Where do I get the UV so that it displayed correctly?
No matter what the texture is, the UVs always go from (0,0) to (1,1), so you can use the same UVs you would use on the GrabPass texture (after all, the grab pass only gives you a texture sampler, you still pass in the UVs)
That said, when you use Blit(), the UVs are automatically set up to copy one texture into another and resize accordingly so that the original texture is shrunk or stretched to the exact size of the copy. You can use Blit() to make a texture that is smaller than your original, then call material.SetTexture() to use that smaller texture on any material you want.
The UVs in the copied texture will be the same as the original since they always go from (0, 0) to (1, 1)