-->

分類

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

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月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()

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");

    }
}