Textures are flickering when camera is in motion
Can anyone Help? I have an issue for a racing game project. When my camera is in motion objects textures starts flickering. ex.... I have road and terrain surrounding it, when i start the race, its textures starts blinking or flickering. I have heard about z fighting, but in this case i don't think that's the problem because i don't have double side face for road, i didn't need that. I have tried changes for camera clipping plane, enable gpu instancing for shader, allowed hdr to camera, but none of these worked till yet.
Answer by dan_wipf · Apr 01, 2019 at 07:26 AM
have a look for anti alising
Edit:
Shader
Shader "FXAA" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float _ContrastThreshold, _RelativeThreshold;
float _SubpixelBlending;
struct VertexData {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct Interpolators {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
Interpolators VertexProgram (VertexData v) {
Interpolators i;
i.pos = UnityObjectToClipPos(v.vertex);
i.uv = v.uv;
return i;
}
float4 Sample (float2 uv) {
return tex2Dlod(_MainTex, float4(uv, 0, 0));
}
float SampleLuminance (float2 uv) {
#if defined(LUMINANCE_GREEN)
return Sample(uv).g;
#else
return Sample(uv).a;
#endif
}
float SampleLuminance (float2 uv, float uOffset, float vOffset) {
uv += _MainTex_TexelSize * float2(uOffset, vOffset);
return SampleLuminance(uv);
}
struct LuminanceData {
float m, n, e, s, w;
float ne, nw, se, sw;
float highest, lowest, contrast;
};
LuminanceData SampleLuminanceNeighborhood (float2 uv) {
LuminanceData l;
l.m = SampleLuminance(uv);
l.n = SampleLuminance(uv, 0, 1);
l.e = SampleLuminance(uv, 1, 0);
l.s = SampleLuminance(uv, 0, -1);
l.w = SampleLuminance(uv, -1, 0);
l.ne = SampleLuminance(uv, 1, 1);
l.nw = SampleLuminance(uv, -1, 1);
l.se = SampleLuminance(uv, 1, -1);
l.sw = SampleLuminance(uv, -1, -1);
l.highest = max(max(max(max(l.n, l.e), l.s), l.w), l.m);
l.lowest = min(min(min(min(l.n, l.e), l.s), l.w), l.m);
l.contrast = l.highest - l.lowest;
return l;
}
bool ShouldSkipPixel (LuminanceData l) {
float threshold =
max(_ContrastThreshold, _RelativeThreshold * l.highest);
return l.contrast < threshold;
}
float DeterminePixelBlendFactor (LuminanceData l) {
float filter = 2 * (l.n + l.e + l.s + l.w);
filter += l.ne + l.nw + l.se + l.sw;
filter *= 1.0 / 12;
filter = abs(filter - l.m);
filter = saturate(filter / l.contrast);
float blendFactor = smoothstep(0, 1, filter);
return blendFactor * blendFactor * _SubpixelBlending;
}
struct EdgeData {
bool isHorizontal;
float pixelStep;
float oppositeLuminance, gradient;
};
EdgeData DetermineEdge (LuminanceData l) {
EdgeData e;
float horizontal =
abs(l.n + l.s - 2 * l.m) * 2 +
abs(l.ne + l.se - 2 * l.e) +
abs(l.nw + l.sw - 2 * l.w);
float vertical =
abs(l.e + l.w - 2 * l.m) * 2 +
abs(l.ne + l.nw - 2 * l.n) +
abs(l.se + l.sw - 2 * l.s);
e.isHorizontal = horizontal >= vertical;
float pLuminance = e.isHorizontal ? l.n : l.e;
float nLuminance = e.isHorizontal ? l.s : l.w;
float pGradient = abs(pLuminance - l.m);
float nGradient = abs(nLuminance - l.m);
e.pixelStep =
e.isHorizontal ? _MainTex_TexelSize.y : _MainTex_TexelSize.x;
if (pGradient < nGradient) {
e.pixelStep = -e.pixelStep;
e.oppositeLuminance = nLuminance;
e.gradient = nGradient;
}
else {
e.oppositeLuminance = pLuminance;
e.gradient = pGradient;
}
return e;
}
#if defined(LOW_QUALITY)
#define EDGE_STEP_COUNT 4
#define EDGE_STEPS 1, 1.5, 2, 4
#define EDGE_GUESS 12
#else
#define EDGE_STEP_COUNT 10
#define EDGE_STEPS 1, 1.5, 2, 2, 2, 2, 2, 2, 2, 4
#define EDGE_GUESS 8
#endif
static const float edgeSteps[EDGE_STEP_COUNT] = { EDGE_STEPS };
float DetermineEdgeBlendFactor (LuminanceData l, EdgeData e, float2 uv) {
float2 uvEdge = uv;
float2 edgeStep;
if (e.isHorizontal) {
uvEdge.y += e.pixelStep * 0.5;
edgeStep = float2(_MainTex_TexelSize.x, 0);
}
else {
uvEdge.x += e.pixelStep * 0.5;
edgeStep = float2(0, _MainTex_TexelSize.y);
}
float edgeLuminance = (l.m + e.oppositeLuminance) * 0.5;
float gradientThreshold = e.gradient * 0.25;
float2 puv = uvEdge + edgeStep * edgeSteps[0];
float pLuminanceDelta = SampleLuminance(puv) - edgeLuminance;
bool pAtEnd = abs(pLuminanceDelta) >= gradientThreshold;
UNITY_UNROLL
for (int i = 1; i < EDGE_STEP_COUNT && !pAtEnd; i++) {
puv += edgeStep * edgeSteps[i];
pLuminanceDelta = SampleLuminance(puv) - edgeLuminance;
pAtEnd = abs(pLuminanceDelta) >= gradientThreshold;
}
if (!pAtEnd) {
puv += edgeStep * EDGE_GUESS;
}
float2 nuv = uvEdge - edgeStep * edgeSteps[0];
float nLuminanceDelta = SampleLuminance(nuv) - edgeLuminance;
bool nAtEnd = abs(nLuminanceDelta) >= gradientThreshold;
UNITY_UNROLL
for (int i = 1; i < EDGE_STEP_COUNT && !nAtEnd; i++) {
nuv -= edgeStep * edgeSteps[i];
nLuminanceDelta = SampleLuminance(nuv) - edgeLuminance;
nAtEnd = abs(nLuminanceDelta) >= gradientThreshold;
}
if (!nAtEnd) {
nuv -= edgeStep * EDGE_GUESS;
}
float pDistance, nDistance;
if (e.isHorizontal) {
pDistance = puv.x - uv.x;
nDistance = uv.x - nuv.x;
}
else {
pDistance = puv.y - uv.y;
nDistance = uv.y - nuv.y;
}
float shortestDistance;
bool deltaSign;
if (pDistance <= nDistance) {
shortestDistance = pDistance;
deltaSign = pLuminanceDelta >= 0;
}
else {
shortestDistance = nDistance;
deltaSign = nLuminanceDelta >= 0;
}
if (deltaSign == (l.m - edgeLuminance >= 0)) {
return 0;
}
return 0.5 - shortestDistance / (pDistance + nDistance);
}
float4 ApplyFXAA (float2 uv) {
LuminanceData l = SampleLuminanceNeighborhood(uv);
if (ShouldSkipPixel(l)) {
return Sample(uv);
}
float pixelBlend = DeterminePixelBlendFactor(l);
EdgeData e = DetermineEdge(l);
float edgeBlend = DetermineEdgeBlendFactor(l, e, uv);
float finalBlend = max(pixelBlend, edgeBlend);
if (e.isHorizontal) {
uv.y += e.pixelStep * finalBlend;
}
else {
uv.x += e.pixelStep * finalBlend;
}
return float4(Sample(uv).rgb, l.m);
}
ENDCG
SubShader {
Cull Off
ZTest Always
ZWrite Off
Pass { // 0 luminancePass
CGPROGRAM
#pragma vertex VertexProgram
#pragma fragment FragmentProgram
#pragma multi_compile _ GAMMA_BLENDING
float4 FragmentProgram (Interpolators i) : SV_Target {
float4 sample = tex2D(_MainTex, i.uv);
sample.rgb = saturate(sample.rgb);
sample.a = LinearRgbToLuminance(sample.rgb);
#if defined(GAMMA_BLENDING)
sample.rgb = LinearToGammaSpace(sample.rgb);
#endif
return sample;
}
ENDCG
}
Pass { // 1 fxaaPass
CGPROGRAM
#pragma vertex VertexProgram
#pragma fragment FragmentProgram
#pragma multi_compile _ LUMINANCE_GREEN
#pragma multi_compile _ LOW_QUALITY
#pragma multi_compile _ GAMMA_BLENDING
float4 FragmentProgram (Interpolators i) : SV_Target {
float4 sample = ApplyFXAA(i.uv);
#if defined(GAMMA_BLENDING)
sample.rgb = GammaToLinearSpace(sample.rgb);
#endif
return sample;
}
ENDCG
}
}
}
FXAA Script
using UnityEngine; using System;
[ExecuteInEditMode, ImageEffectAllowedInSceneView] public class FXAAEffect : MonoBehaviour {
const int luminancePass = 0;
const int fxaaPass = 1;
public enum LuminanceMode { Alpha, Green, Calculate }
public LuminanceMode luminanceSource;
[Range(0.0312f, 0.0833f)]
public float contrastThreshold = 0.0312f;
[Range(0.063f, 0.333f)]
public float relativeThreshold = 0.063f;
[Range(0f, 1f)]
public float subpixelBlending = 1f;
public Shader fxaaShader;
public bool lowQuality;
public bool gammaBlending;
[NonSerialized]
Material fxaaMaterial;
void OnRenderImage (RenderTexture source, RenderTexture destination) {
if (fxaaMaterial == null) {
fxaaMaterial = new Material(fxaaShader);
fxaaMaterial.hideFlags = HideFlags.HideAndDontSave;
}
fxaaMaterial.SetFloat("_ContrastThreshold", contrastThreshold);
fxaaMaterial.SetFloat("_RelativeThreshold", relativeThreshold);
fxaaMaterial.SetFloat("_SubpixelBlending", subpixelBlending);
if (lowQuality) {
fxaaMaterial.EnableKeyword("LOW_QUALITY");
}
else {
fxaaMaterial.DisableKeyword("LOW_QUALITY");
}
if (gammaBlending) {
fxaaMaterial.EnableKeyword("GAMMA_BLENDING");
}
else {
fxaaMaterial.DisableKeyword("GAMMA_BLENDING");
}
if (luminanceSource == LuminanceMode.Calculate) {
fxaaMaterial.DisableKeyword("LUMINANCE_GREEN");
RenderTexture luminanceTex = RenderTexture.GetTemporary(
source.width, source.height, 0, source.format
);
Graphics.Blit(source, luminanceTex, fxaaMaterial, luminancePass);
Graphics.Blit(luminanceTex, destination, fxaaMaterial, fxaaPass);
RenderTexture.ReleaseTemporary(luminanceTex);
}
else {
if (luminanceSource == LuminanceMode.Green) {
fxaaMaterial.EnableKeyword("LUMINANCE_GREEN");
}
else {
fxaaMaterial.DisableKeyword("LUMINANCE_GREEN");
}
Graphics.Blit(source, destination, fxaaMaterial, fxaaPass);
}
}
}
first have a look at the project settings => here have a look at the rendering settings, you need to enable the anti alising.
second post processing there should be an anti alising option in the PPS, that can smooth you’re desired result enormous! as well with other effects! blur,motion...
https://docs.unity3d.com/$$anonymous$$anual/PostProcessing-Stack.html
Okay I did that and temporal Anti aliasing(TAA) worked well but it almost doubled the tris of my scene, i working on android mobile game so cant afford that much load. Anything else you can suggest? And of course a big thanks for your response.
hm i think then it’s a general question, how can i get good looking stuff with excellent performance. => try to disable things to see what uses too much resources, id you work with terrain in a racing game, consider to use no wind, better billboard rendering, and what was in my $$anonymous$$d, is decreasing the texture size(standard it is 2048x2048)
Actually i am not working with terrain and there is no wind particles i have added. Without post processing effects, tris were under control but after adding it tris just got doubled. I think i need any mobile optimized pps for anti aliasing.
have you set anti aliasing to 2x? the lowest will mostly enough for a mobile game
Yes anti aliasing is 2x but the post process effect is making my game so much lower as tris increases...without it the game is much smoother
just fps wise. editor vs build there is mostlikely a diffrence, the editor consumes more resources than the built game
Thanks for your help, I tested the build on my mobile device but it is giving me so low fps around 4-5 fps and without temporal anti aliasing i am getting around 50-55 fps. Don't know how to deal with it.
ok. go back again a few steps.
you need post processing stack 2.0 from the package manager
add to your main camera the post processing layer component
ther you use the FXAA Anti aliasing mode. this is for $$anonymous$$obiles, toggle fast mode. that will improve your performance!
I already tried that but still it is taking too much load on my device and reducing fps down to 4-5 just like TAA.