Why is Graphics.Blit with material not working consistently?
Hi
I am in need of creating a quick background blur below some popups in my UI project. After investigating a while, I have settled on using the AsyncGPUReadbackRequest
to get the data into the texture and a Frosted Glass shader (Unlit).
Because the background is going to be static anyway, I wanted to push it into the RenderTexture, apply shader while doing Graphics.Blit
.
Unfortunately, most of the time it looks like the shader does not use the input texture of Graphics.Blit
at all. My render texture looks like only some grey layer was applied to it. I've tried with different Unlit shaders, always the same - output looks like the main texture in shader was empty.
What strikes me, is that in a moment of frustration, I kept mashing the button i have created for testing the effect and.... once in a while it actually works and produces the desired output!
I am not sure why, the effect is not consistent at all. I'm using Unity 2018.2.16, I have also tried on .15 with the same effect.
I've searched for the answers online already, I came up with a lot mentioning that the shader has to be unlint (checked) and that it could be due to different formats of texture and the expected format of the shader. I think i am sure this is ok in my case, especially that once in a while it works just fine.
https://forum.unity.com/threads/graphics-blit-with-material-resulting-in-corrupted-output.41164/
The script I use for testing is super easy, maybe someone could have a look and point me to what I do wrong, I will be forever grateful.
The script has to be attached to the camera, and I just redirect the render texture to some output RawImage.
Thanks
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
public class ProcessImage : MonoBehaviour {
public bool willProcess = false;
public RawImage _outputImage;
public Material _shaderMaterial;
public Texture2D _texture;
Queue<AsyncGPUReadbackRequest> _requests = new Queue<AsyncGPUReadbackRequest>();
/// <summary>
/// Instantiate the textures
/// </summary>
void Start() {
_texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
}
/// <summary>
/// Check if any request is complete and if so process the texutre
/// </summary>
void Update() {
while (_requests.Count > 0) {
var req = _requests.Peek();
if (req.hasError) {
Debug.Log("GPU readback error detected.");
_requests.Dequeue();
} else if (req.done) {
// retrieve the buffer and direct it into the texture
var buffer = req.GetData<Color32>();
_texture.LoadRawTextureData(buffer);
_texture.Apply();
_requests.Dequeue();
// create a new Render Texture (this is testing only, in the end it will reuse existing one)
RenderTexture renderTexture = new RenderTexture(_texture.width, _texture.height, 1, RenderTextureFormat.ARGB32);
// copy the content of the texture to RenderTexture using shader
Graphics.Blit(_texture, renderTexture, _shaderMaterial);
// assign texture to the right place in the output image
_outputImage.texture = renderTexture;
Debug.Log("DONE");
} else {
break;
}
}
}
/// <summary>
/// Detect that processing should be performed
/// </summary>
/// <param name="src"></param>
/// <param name="dest"></param>
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (willProcess) {
Debug.Log("OnRenderImage");
willProcess = false;
// request the screen data
_requests.Enqueue(AsyncGPUReadback.Request(src));
}
Graphics.Blit(src, dest);
}
}
I have the same problem, did you found the solution? @$$anonymous$$rstn
Your answer
Follow this Question
Related Questions
Looking at a Chunk from Straight Down will not Render Blocks, but Looking at it from the Side does? 1 Answer
Get real colors like white or black 1 Answer
2D Mobile: How to mask a gameObject with another gameObject (with soft edges) 0 Answers
Is there a shader I could use to always render a material over another material? 0 Answers