render to target

Hi Folks,

Playing around with shaders and Unity…

Is there an example (either in the pro, or standard assets, or elsewhere) of how to render to a texture using a fragment shader? I’d like to be able to use a pass to temporarily render to a texture (similar to the Render Target in RenderMonkey).

Cheers,
Paul Mikulecky
Lost Pencil Animation Studios Inc.
http://www.lostpencil.com

Not quite sure what you’re looking for, but here are a couple of possibilities:

The shaders in the Glass Refraction example in the Pro Standard Assets use GrabPass… that grabs the current frame buffer behind the object getting rendered and sticks it in _GrabTexture for later use.

The Image Effects in the Pro Standard Assets show how to do screen space effects. Basically they use OnRenderImage() in MonoBehaviour.

You can also make a Render Texture asset in your Project view and simply drag and drop it onto the Target Texture property of a Camera.

Cheers,
-Jon

Hi Jon,

Thanks for the reply.

I don’t think that GrabPass is what I’m looking for… I basically want the output of the fragment shader to go into a texture for later use in another pass. For example, I want to render from a light position so that I can then use the depth information for creating a shadow map. In RenderMonkey you set it up so that when your fragment/pixel shader outputs the final color, instead of it going to the frame buffer, it goes to a temporary texture. You can then use that texture in other shader passes.

I’m not sure if the Image Effects scripts help. I haven’t taken a close look at them yet. But they don’t look like they would help since they seem to be creating an effect in ‘post’ - which would be too late for my case.

The RenderTexture asset may be a solution in that I could position a bogus camera to the same position as my light, render the depth information to a texture and then feed that into my shader… how I would go about doing that I’m not sure of yet…

Any suggestions would be most welcome.

Cheers,
Paul Mikulecky
Lost Pencil Animation Studios Inc.
http://www.lostpencil.com

That seems like what you’d want to do. One thing is that you don’t need to make an actual asset, you can make the RenderTexture at run time and size it however you wish.

http://unity3d.com/Documentation/ScriptReference/RenderTexture.RenderTexture.html

After you have created it, you can then set it to your “Bogus Camera”'s targetTexture:

http://unity3d.com/Documentation/ScriptReference/Camera.targetTexture.html

Now that camera will render into that texture instead of on the screen.

Give that camera a really low depth (lower than your Main Camera) so that it is rendered first.

http://unity3d.com/Documentation/ScriptReference/Camera.depth.html

Now you can assign that texture to whatever material you would like.

Something like this:

using UnityEngine;

[RequireComponent (typeof(Camera))]
public class OverrideMaterialsWithRenderTexture : MonoBehaviour
{
	private RenderTexture renderTexture;
	public Material[] materialsToAlter;
	public string textureNameToOverride = "_MainTex";
	public bool constrainToPowerOfTwo = true; // Most shaders want Power of Two textures
	
	void Start ()
	{
		renderTexture = new RenderTexture(Screen.width / 4, Screen.height / 4, 32); // can divide by two etc. for reduced quality
		renderTexture.isPowerOfTwo = constrainToPowerOfTwo;
		camera.targetTexture = renderTexture;
		camera.depth = -10; // You should make sure the camera is getting rendered before the main camera.
		foreach (Material material in materialsToAlter)
		{
			material.SetTexture(textureNameToOverride, renderTexture);
		}
	}
}

Now you could parent this “bogus camera” to a directional light or whatever and do your fancy stuff. I don’t know if you can get the depth buffer, I’ve never tried but I don’t know how, but hopefully this will get you going with something at least…

Good luck!
-Jon

Hi Jon,

Ahh, you are a scholar and a gentleman. Thanks for the boost! That helps a bunch.

Cheers,
Paul Mikulecky
Lost Pencil Animation Studios Inc.
http://www.lostpencil.com