When does RenderTexture.active = myRT work?

Hello!

I've been trying again and again to make use of RenderTexture.active and it has never worked once so far.

I tried everything I could think of, using Pro assets and mainly ImageEffects as an example as well.

I tried using different ways to draw a quad to the render texture: Graphics.DrawTexture, Graphics.DrawMeshNow, GL (GL.QUADS), Graphics.Blit. Not once has there been anything drawn into the render texture, which remained completely black and transparent at all times.

This is the most stripped down version I've been trying to make work, in a scene bereft of all but the camera and this script attached to it:

using UnityEngine;
using System.Collections;

public class rdnTxtTst : MonoBehaviour
{
    private RenderTexture rndTxt = null;
    private Material mat = null;

    void Start( )
    {
        rndTxt = Resources.Load( "Textures/RenderTextures/RTtest" ) as RenderTexture;
        mat = new Material( Shader.Find( "DrawPinkAllOver" ) );
    }

    void OnPostRender( )
    {
        RenderTexture oldRndT = RenderTexture.active;
        RenderTexture.active = rndTxt;

        GL.PushMatrix( );
        GL.LoadOrtho( );
        for( int i = 0 ; i < mat.passCount ; i++ )
        {
            mat.SetPass( i );
            GL.Begin( GL.QUADS );

            GL.Vertex3( 0.0f, 0.0f, 0.1f );
            GL.Vertex3( 1.0f, 0.0f, 0.1f );
            GL.Vertex3( 1.0f, 1.0f, 0.1f );
            GL.Vertex3( 0.0f, 1.0f, 0.1f );

            GL.End( );
        }
        GL.PopMatrix( );

        RenderTexture.active = oldRndT;

        Graphics.DrawTexture( new Rect( 0.0f, 0.0f, Screen.width, Screen.height ), rndTxt );
    }
}

And the shader:

Shader "DrawPinkAllOver"
{
    Properties
    {
        _MainTex ("", 2D) = "white" {}
    }

    SubShader
    {
      Cull Off Lighting Off Fog { Color (0,0,0,0) }
   ColorMask RGBA

        Pass
        {
            Blend One Zero
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"

uniform sampler2D _MainTex;

half4 frag (v2f_img i) : COLOR
{
   half4 res = float4( 1.0, 0.0, 1.0, 1.0 );

   return res;
}
ENDCG
        }
    }
}

This version uses GL, but as I said, I won't get any better results using other ways to render a quad on the screen such as Graphics.DrawTexture

Whyyyyyyyyyyy? I'm desperate! Please help!

Thanks in advance.

I found out what the problem was:

`RenderTexture.active = rndTxt;`

this will apparently clean up matrix information (amongst other things).

So, instead of:

GL.PushMatrix( );
    GL.LoadOrtho( );
    for( int i = 0 ; i < mat.passCount ; i++ )
    {
        mat.SetPass( i );
        GL.Begin( GL.QUADS );

        GL.Vertex3( 0.0f, 0.0f, 0.1f );
        GL.Vertex3( 1.0f, 0.0f, 0.1f );
        GL.Vertex3( 1.0f, 1.0f, 0.1f );
        GL.Vertex3( 0.0f, 1.0f, 0.1f );

        GL.End( );
    }

you do

Graphics.DrawTexture(new Rect(-1.0f,-1.0f,2.0f,2.0f), some_texture);

that will render over the entire RT (the viewport's coordinates go from -1 to 1).

Also, bear in mind that DrawTexture expects pixel positions, so all parameters will be cast into ints internally. As a consequence, you can't give it things like

Graphics.DrawTexture(new Rect(-0.74984f,0.3494854.0f,0.16549f,0.23165f), some_texture);

as it all will be floored down to the nearest integer.

If like me you'd like to keep DrawTexture to use 'screen' coordinates (here, pixel positions) you'll have to rebuild a projection matrix yourself, something like that:

        Matrix4x4 pm = Matrix4x4.identity;
    pm[0, 0] = 2.0f / RT.width;
    pm[1, 1] = -2.0f / RT.height;
    pm[0, 3] = -1.0f;
    pm[1, 3] = 1.0f;

and pass it on to the vertex shader and multiply your vertices positions with it. And then you can use pixel positions in the Rect you pass to DrawTexture instead of -1,-1,2,2 .

First, you'll need to be using Pro. Render textures are one of the goodies explicitly left out of the freebie version. Second, check out the cubemapping scripts in the manual for examples of how to create a real-time cube texture. I believe there are very similar functions for rendering to traditional textures instead.

Now, if you're looking for a way to hack into the final ~screen buffer~ texture (what gets drawn to the window)... I'm still chewing on that one myself. Best solution I've found is to render a regular texture and slap it on a simple plane fit to the window. Wastes some VRAM, but meh.