mercredi 14 octobre 2015

Taking a screenshot to a RenderTexture in Unity does not work with a custom vertex shader

I have a screenshot feature in my game. I also have a water reflection implemented like so:

A second camera is used to render only some of the GameObjects to a RenderTexture (using culling mask). The RenderTexture is put on a flipped plane so that I can "fake" the 2D reflection.

If I use a default/standard shader in the RenderTexture's (reflection plane) material, everything works fine. The screenshot is taken and it looks ok. But since I wanted to add a water ripple shader to the water reflection, I created a custom shader that does the trick. The problem is that when I take the screenshot through the game's main camera it seems the clear color of the separate Camera+RenderTexture is always white but it occurs only when I render the screenshot to a render texture after game has ended.

There's probably something going on here that I don't understand because I have little experience with rendering pipelines and shaders but I hope someone can shed light on this issue.

Here's the water reflection shader code:

Shader "RippleShader" {
Properties{
    _Color("Color", Color) = (1,1,1,1)
    _MainTex("Texture", 2D) = "white" {}
}
SubShader{
    Pass {
        Tags { "RenderType" = "Opaque"}
        LOD 200
        Cull Off
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

            float4 _Color;
            sampler2D _MainTex;

            struct appdata {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 pos : POSITION;
                float2 uv: TEXCOORD0;
            };

            v2f vert(appdata v) {
                v2f o;

                float angle = _Time.x * 100;
                v.vertex.x += sin(v.vertex.z * 2 + angle) * 0.05;

                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.texcoord;
                return o;
            }

            float4 frag(v2f i) : COLOR
            {
                half4 color = tex2D(_MainTex, i.uv);
                //color.a *= 0.3;
                return color;
            }

    ENDCG
    }
}
FallBack "Unlit"

}

Here's the screenshot code:

public void TakeScreenshot()
{
    int resWidth = screenshotRenderTexture.width;
    int resHeight = screenshotRenderTexture.height;
    Camera.main.targetTexture = screenshotRenderTexture;
    Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
    Camera.main.Render();
    RenderTexture.active = screenshotRenderTexture;
    screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
    Camera.main.targetTexture = null;
    RenderTexture.active = null; // JC: added to avoid errors
    byte[] bytes = screenShot.EncodeToPNG();
    string filename = Application.persistentDataPath + "/screenshot.png";
    System.IO.File.WriteAllBytes(filename, bytes);
    Debug.Log(string.Format("Took screenshot to: {0}", filename));
}





Aucun commentaire:

Enregistrer un commentaire