Search Unity

Graphics.BlitTexture(RenderTexture, RenderTexture, Material) giving me a black screen

Discussion in 'General Graphics' started by Ayerbe, Apr 17, 2022.

  1. Ayerbe

    Ayerbe

    Joined:
    Apr 17, 2022
    Posts:
    5
    Hi, so I'm trying to create a circle around the player's FOV, where a blur effect is applied to everything outside of said circle. I figured I could achieve this by rendering the camera to a texture, then rendering the texture directly to the screen with a shader, which brought me to BlitTexture while passing a material. I tried implementing this using the following script in the object that contains the camera:

    void OnRenderImage(RenderTexture src, RenderTexture dest) {
    Graphics.Blit(src, render_texture);
    Graphics.Blit(render_texture, dest, material);
    }

    Where render_texture is just an empty texture, and material is a material whose texture is set to render_texture, and whose shader has the blur code. However, when I run this, all I get is a black screen.

    Notes:
    - If I remove the material as an argument, it renders just fine
    - When I look at the render_texture in the asset viewer, the camera is properly rendering to it
    - Likewise, if I look at the material in the asset viewer, the camera is properly rendering to that too, though I can't tell if the shader is being applied properly
    - If I change the code so that material is passed to the first Graphics.Blit call, both of the above two notes stop being the case
    - Originally I assumed it was an issue with my shader code, but if I change the material so it uses the default shader instead, nothing changes

    Can someone tell me what I'm doing wrong here? I've looked at a bunch of resources and can't find anything that was able to help.
     
  2. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,791
    Are you using built in?

    If you want to do just one thing, you don't need two Blits, just do Graphics.Blit(src, dest, material) and in the material have the shader that does the circular blur.
     
  3. Ayerbe

    Ayerbe

    Joined:
    Apr 17, 2022
    Posts:
    5
    I tried doing this and no dice, whether or not the material has a texture attached to it and whether or not the material is using my blur shader or the default one, this still resulted in a black screen.
     
  4. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,791
    And the script is attached to a camera?

    And does removing the material (and leaving only Graphics.Blit(src, dest)) make it work? (by work I mean, show stuff)

    If yes, then I can only assume that there is something wrong with the shader.

    Can you share the shader?
     
  5. Ayerbe

    Ayerbe

    Joined:
    Apr 17, 2022
    Posts:
    5
    The script and the camera are attached to the same object, and like I said, removing the material call does make it work. I know it's not something wrong with the shader because if I set the material to use the default shader, it still doesn't work. That being said, if it helps, here's the shader for reference. Ik it's scuffed but I was gonna clean it up once I got the rest of it working:

    Shader "Custom/Blur"
    {
    Properties {
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _Glossiness ("Smoothness", Range(0,1)) = 0.5
    _Metallic ("Metallic", Range(0,1)) = 0.0
    _Radius("Radius", Range(1, 1280)) = 1
    }

    SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 200

    CGPROGRAM
    #pragma surface surf Standard fullforwardshadows
    #pragma target 3.0

    sampler2D _MainTex;

    struct Input {
    float2 uv_MainTex;
    float4 uv_grab : TEXCOORD0;
    float4 proj;
    float4 screenPos;
    };

    half _Glossiness;
    half _Metallic;
    fixed4 _Color;
    float _Radius;

    UNITY_INSTANCING_BUFFER_START(Props)
    // put more per-instance properties here
    UNITY_INSTANCING_BUFFER_END(Props)

    void surf (Input IN, inout SurfaceOutputStandard o) {
    float2 coords = IN.screenPos.xy / IN.screenPos.w; //These coords are 0 to 1
    coords.x = (coords.x - 0.5) * 1280 * 2; //This puts them in -1280 to 1280
    coords.y = (coords.y - 0.5) * 720 * 2; //ditto for 720
    float4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    if ((coords.x * coords.x) + (coords.y * coords.y) >= (_Radius * _Radius)) {
    float2 offset = 1.0 / _ScreenParams.xy;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(offset.x, offset.y)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(-offset.x, offset.y)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(-offset.x, -offset.y)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(offset.x, -offset.y)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(offset.x, 0.0)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(-offset.x, 0.0)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(0.0, offset.y)) * _Color;
    c += tex2D(_MainTex, IN.uv_MainTex + float2(0.0, -offset.y)) * _Color;
    c /= 9;
    }
    o.Albedo = c.rgb;
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
    o.Alpha = c.a;
    }
    ENDCG
    }
    FallBack "Diffuse"
    }
     
  6. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,791
    Not sure about using a surface shader for a blit. Maybe try and find a blur post processing shader that is written as vert frag? There are many examples around.
     
  7. Ayerbe

    Ayerbe

    Joined:
    Apr 17, 2022
    Posts:
    5
    Like I said, using the standard Unity shader doesn't fix the issue, so I know the one that I'm using isn't the problem.
     
  8. Ayerbe

    Ayerbe

    Joined:
    Apr 17, 2022
    Posts:
    5
    Update: Messed around with some other stuff that wasn't the default and it's looking like there were some things that worked in there. I'll take it from here, thanks.