Render to texture without a camera?

Is there a method to use a shader to render into a rendertexture without using a camera?

An example being I’m using a webcamtexture bringing in the feed from my webcam (not displaying it on screen yet). I want to pass the current frame from the webcam and the previous frame through a shader that would combine them in an interesting way into a new texture that I could then use.

I might be looking at it wrong, but that doesn’t seem to be what the Camera.renderWithShader feature is for.

I’m not sure if there is a limitation to this when not using pro, but you probably want to take a look at Graphics.Blit().

A camera is necessary to render anything. A camera contains things like the projection matrix, interaction with the modelview matrix, which includes translation of coordinate systems from the game world into the window space. It also deals with some other stuff. Unity has basically tied a camera to the backbuffer in the sense that you have to have at least one camera in the scene to render anything. So even if you are doing stuff in the background that’s not visible, if you want it to go to a rendertexture you either have to upload to the texture with the cpu over the graphics bus ie SetPixels(), or you need to use a camera to view the texture so that its fragments can be processed and thus render something. Even graphics.blit will need a camera to be able to know where to blit to. I would think?

I think you can do this using Graphics.SetRenderTarget() followed by Graphics.DrawTexture() or Graphics.Blit(). Blit() is probably simplest.

1 Like

@imaginaryhuman, he mentioned he is getting the texture feed from his webcam :slight_smile: Also, according to the Unity script reference, you can use Graphics.Blit() without the use of a camera. Personally only used it for the sake of image effects, so he should probably just have to try it out to see if it works.

Thanks guys. I’ll have to check that out and see how it works!

Looks like Graphics.Blit was the answer, thanks all! I was able to bring in a frame from the webcam and do some processing on it and output that to a rendertexture.

I’d +1 you all if there was such an option :stuck_out_tongue:

Is it possible to create a camera that only sees the Blit? So it’s in the scene but it doesn’t show the scene, as I want to completely wipe over what it’s looking at with the Blit.
Thanks,
Dave.

DaveHoskins, I think what you want is to only render some specific stuff to a texture and use that for something in regards to the actual scene? If that is the case, you should assign Layers to the objects you (don’t) want to show and create another camera that does so by setting the Culling Mask option. Look it up or play around to see how it works.

If anyone else is having trouble using Graphics.Blit(), it must be called from within OnPostRender() !

Thanks Rld_, and thanks SantosR!
Only from a OnPostRender? It only works with a camera as has been said, I guess.
It’s not as flexible as I’d hoped, all I wanted was to render a shader to a texture.

I can’t test this at the moment, but what you are saying SantosR is not true. Next to the fact that Unity states differently in their own examples, I use it for Image Effects in OnRenderImage().

Just try it out DaveHoskins.

Yes I have it working in ‘OnRenderImage(RenderTexture src, RenderTexture dest),’ which only gets called if I attach a camera to the object.
I set Clear Flags to ‘Don’t Clear’ and the Culling Mask to ‘Nothing’ so I’m not wasting time rendering the scene.
Can I safely ignore the ‘src’ and ‘dest’ and update my own RenderTexures? I’ve already seen that ‘src’ can be null, which is great news.

I’m new to shaders and rendering pipeline, so I might have done something wrong. However in my case having the Blit() called on a OnClick() or Update() didn’t work at all. (no visible changes)

Maybe it is shader dependent?

I just had time to try it out.

It seems that although you aren’t prohibited to use it where you want, you will only be able to use it to blit between textures if you aren’t using a shader/material. So yeah, in that case you will need to use it with a camera.

@DaveHoskins, the src and dest parameters passed are holding/will hold the information you need for image effects. If you don’t want to use them, you don’t have to, but the Blit() functions expects certain values which you likely can’t deny.

What is it exactly you are trying to achieve?

Hi Rld_, I’m using the GPU for procedural data acquisition. Basically making landscape height maps on the GPU and sending that data to the CPU.
The first frame has to make the entire local area so it would be nice to repeatedly call Blit/Read on all the landscape patches before starting. What I currently have working is a Queue of patches that need updating, and they are taken one at a time off the Queue in OnRenderImage, render them with a Blit, then grab them at the next patch rendering time. That bit works fine, so far.

In that case, you might not really need to use Blit, check out this thread: http://forum.unity3d.com/threads/232189-how-to-apply-output-of-shader-to-the-same-shader

I don’t quite understand, that thread you linked seems to be about sending data to another shader, not the CPU.
Anyway I have it all working now, and I can do multiple Blits in the code and grab the whole landscape in one go at the beginning.

I did find what appears to be a Unity bug though, the first time Camera.targetTexture gets set was in OnRenderImage, and it got completely ignored for that particular call. Which may be a problem in the future if I want to set different targets at different times. Can I not set this in OnRenderImage?
Thanks,
Dave.

In the unity DX11 examples, there is a code example that passes data from the GPU to the CPU in a direct compute code.

Thanks, I wanted Mac OSX OpenGL and AMD support as well, so it has to be some form of ReadPixels.