- Home /
Graphic artefacts when using GrabPass with custom camera Rect (Aspect Ratio enforced)
Hi,
I am currently observing graphical artefacts when using a shader with GrabPass in conjonction with an aspect ratio enforcer for my main camera...
First of all the AspectRatioEnforcer script, attached to the main camera:
public class AspectRatioEnforcer : MonoBehaviour
{
/// <summary>
/// Additional "background" camera which allows setting a color for the
/// otherwise undefined "Letterbox" & "Pillarbox" zones
/// </summary>
private Camera backgroundCam;
public float targetAR;
private int lastScreenWidth = 0;
private int lastScreenHeight = 0;
void Update()
{
// Check the screen height and witdh & enforce aspect Ratio if they have
// changed
//-----------------------------------------------------------------------
if ((Screen.height != lastScreenHeight) || (Screen.width != lastScreenWidth))
{
lastScreenWidth = Screen.width;
lastScreenHeight = Screen.height;
EnforceAR();
}
}
/// <summary>
/// Forces the camera to use specified aspect ratio
/// </summary>
private void EnforceAR()
{
// Retrieve current window's AR & compare to target one
//-----------------------------------------------------------------------
float windowAR = (float)Screen.width / (float)Screen.height;
float scaleheight = windowAR / this.targetAR;
// If scaled height is less than current height, add letterbox
//-----------------------------------------------------------------------
if (scaleheight < 1.0f)
{
Rect rect = this.GetComponent<Camera>().rect;
rect.width = 1.0f;
rect.height = scaleheight;
rect.x = 0;
rect.y = (1.0f - scaleheight) / 2.0f;
this.GetComponent<Camera>().rect = rect;
}
// If scaled width is less than current width, add pillarbox
//-----------------------------------------------------------------------
else
{
float scalewidth = 1.0f / scaleheight;
Rect rect = this.GetComponent<Camera>().rect;
rect.height = 1.0f;
rect.width = scalewidth;
rect.x = (1.0f - scalewidth) / 2.0f;
rect.y = 0;
this.GetComponent<Camera>().rect = rect;
}
// Create background cam if it doesn't exist yet
//-----------------------------------------------------------------------
if (!backgroundCam)
{
backgroundCam = new GameObject("BackgroundCam", typeof(Camera)).GetComponent<Camera>();
backgroundCam.depth = -2;
backgroundCam.clearFlags = CameraClearFlags.SolidColor;
backgroundCam.backgroundColor = Color.green;
backgroundCam.cullingMask = 0;
}
}
And here a very simple shader that uses a grabPass and simply displays the color of the grabbed texture:
Shader "Custom/SimpleGrab"
{
Properties {}
SubShader
{
Tags { "RenderType" ="Opaque"
"Queue" ="Transparent"}
LOD 200
Lighting Off
GrabPass { }
Pass
{
Tags{"LightMode" = "Always"}
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
sampler2D _GrabTexture;
float4 _GrabTexture_TexelSize;
struct vertexInput
{
float4 position :POSITION;
float2 uv :TEXCOORD0;
};
struct vertexOutput
{
float4 pos :SV_POSITION;
float2 uv :TEXCOORD0;
float4 grabUV :TEXCOORD4;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.position);
output.uv = input.uv;
output.grabUV = ComputeGrabScreenPos(output.pos);
return output;
}
float4 frag(vertexOutput input):COLOR
{
return tex2D( _GrabTexture, float2(input.grabUV.x, input.grabUV.y));
}
// End CG programing
//-----------------------------------------------------------------------
ENDCG
}
And now the actual issue: - I am using an orthogonal camera looking at a white Rect (Quad with non-uniform scaling) with an Ellipse drawn on top of it - I put the exact same quad in front of it and apply the aforementioned shader => 90% of the time it is fine, but with some specific aspect ratios I get the following artefact: (Note: the pillar / Letterbox zones have been made green for debugging purposes, normaly they are white)
=> as you can see, there is a black, inconsistent line at the top of my main camera's rect... (sometimes it's on top, and sometimes on the side, it depends on current window's AR) => I think it has to do with the _GrabTexture not being resized properly when I resize the camera rect. I strongly suspect this because I repeatedly get the following error in the console: rect.width <= rt->GetGLWidth() && rect.height <= rt->GetGLHeight()
I can't find any way to configure the Texture targeted in the GrabPass, so I don't know if this is a missing feature, a known bug to be solved, or if I'm doing something wrong... I'll appreciate any help, thanks in advance!
To reproduce:
Main camera, orthogonal, @ (0, 0, -10), scale (1,1,1), rotation (0,0,0), size 5, depth -1
White background quad @ (0, 0, 0), scale (12.04, 10, 1)
Quad with shader @ (0, 0, -1), scale (12.04, 10, 1)
Target aspect ratio of the Aspect ratio enforcer: 1.204
Test Window size: 733 * 1056
No answer after almost 2 months...??? Can somebody please try to reproduce the problem as described? I'd appreciate any feedback, thxs!
I converted your answer into a comment, because your answer isn't an answer.
Your answer
Follow this Question
Related Questions
Editor GUI error 0 Answers
Editor Console window message no longer wraps... Help? Please? 1 Answer
Unable to create a Unity Project with HDRP. 0 Answers
I get errors when I start any project 0 Answers