using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.ImageEffects;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Blur/Blur (Optimized) Stereo")]
public class BlurOptimizedStereo : PostEffectsBase
{
[Range(0, 2)]
public int downsample = 1;
public enum BlurType
{
StandardGauss = 0,
SgxGauss = 1,
}
[Range(0.0f, 10.0f)]
public float blurSize = 3.0f;
[Range(1, 4)]
public int blurIterations = 2;
public BlurType blurType = BlurType.StandardGauss;
public Shader blurShader = null;
private Material blurMaterial = null;
private Material bypassStereoMaterial = null;
private Shader bypassStereoShader = null;
public override bool CheckResources()
{
CheckSupport(false);
if(blurShader == null)
{
blurShader = Shader.Find("Hidden/FastBlur");
}
blurMaterial = CheckShaderAndCreateMaterial(blurShader, blurMaterial);
if (bypassStereoMaterial == null)
{
bypassStereoShader = Shader.Find("Hidden/BypassStereoImageEffectShader");
bypassStereoMaterial = new Material(bypassStereoShader);
}
if (!isSupported)
ReportAutoDisable();
return isSupported;
}
public void OnDisable()
{
if (blurMaterial)
DestroyImmediate(blurMaterial);
}
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (CheckResources() == false)
{
Graphics.Blit(source, destination);
return;
}
float widthMod = 1.0f / (1.0f * (1 << downsample));
blurMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod, -blurSize * widthMod, 0.0f, 0.0f));
source.filterMode = FilterMode.Bilinear;
int rtW = source.width >> downsample;
int rtH = source.height >> downsample;
// downsample
RenderTexture rt = RenderTexture.GetTemporary(rtW, rtH, 0, source.format);
rt.filterMode = FilterMode.Bilinear;
Graphics.Blit(source, rt, blurMaterial, 0);
var passOffs = blurType == BlurType.StandardGauss ? 0 : 2;
for (int i = 0; i < blurIterations; i++)
{
float iterationOffs = (i * 1.0f);
blurMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod + iterationOffs, -blurSize * widthMod - iterationOffs, 0.0f, 0.0f));
// vertical blur
RenderTexture rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, source.format);
rt2.filterMode = FilterMode.Bilinear;
Graphics.Blit(rt, rt2, blurMaterial, 1 + passOffs);
RenderTexture.ReleaseTemporary(rt);
rt = rt2;
// horizontal blur
rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, source.format);
rt2.filterMode = FilterMode.Bilinear;
Graphics.Blit(rt, rt2, blurMaterial, 2 + passOffs);
RenderTexture.ReleaseTemporary(rt);
rt = rt2;
}
Graphics.Blit(rt, destination, bypassStereoMaterial);
RenderTexture.ReleaseTemporary(rt);
}
}
Shader "Hidden/BypassStereoImageEffectShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//o.uv = v.uv;
o.uv = UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
#if UNITY_SINGLE_PASS_STEREO
if (unity_StereoEyeIndex == 0)//left eye
{
i.uv.x = i.uv.x * 0.5;
}
else//right eye
{
i.uv.x = i.uv.x * 0.5 + 0.5;
}
#endif
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
2018年12月20日 星期四
[Unity] fixed legacy blur effect from Unity Standard Assets for single pass stereo
https://assetstore.unity.com/packages/essentials/legacy-image-effects-83913
2018年12月4日 星期二
[Unity]Unity's coroutine can't be stopped if the IEnumerator call stack is too deep
Unity's coroutine can't be stopped if the IEnumerator call stack is too deep
In the following example, if Co3() is executed, then the coroutine can't be stopped by StopCoroutine()
In the following example, if Co3() is executed, then the coroutine can't be stopped by StopCoroutine()
public class TestCoroutine : MonoBehaviour {
private Coroutine coroutine;
// Use this for initialization
void Start () {
coroutine = StartCoroutine(Co1());
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.S))
{
if(coroutine != null)
{
StopCoroutine(coroutine);
Debug.LogError("Stop coroutine");
}
}
}
private IEnumerator Co1()
{
Debug.LogError("Co1 start");
yield return new WaitForSeconds(5);
Debug.LogError("Co1 end");
yield return Co2();
}
private IEnumerator Co2()
{
Debug.LogError("Co2 start");
float time = Time.time;
while(Time.time - time < 5)
{
yield return null;
}
Debug.LogError("Co2 end");
yield return Co3();
}
private IEnumerator Co3()
{
//coroutine can't be stopped by StopCoroutine if here is executed
Debug.LogError("Co3 start");
float time = Time.time;
while (Time.time - time < 5)
{
yield return null;
}
Debug.LogError("Co3 end");
}
}
訂閱:
意見 (Atom)