VR – Eye Blink Effect with an unlit-cutout Shader in Unity

Short: I always wanted an EyeBlink effect in VR and now I created a simple method to simulate such a “Blink”.
A Texture with an alpha channel is needed. (I created one in Photoshop and one in Gimp – the samples are also attached to the post – and the Gimp Steps are documented in screenshots at the end of this post)
While the Gimp PNG has to be exported and I’m still a bit unsure if I exported it the right was – the Photoshop psd file is easier to handle. (Unity can use the psd file directly and the alpha channel was easier – but that’s my 2 cents and just a gut feeling)

The blink effect on a Cube (For better visibility – this is a nice demo / the Cutout Shader Settings are also visible in bottomLeft)

On a cube - demo

The shader and script on a simple cube.

This is the “Eyes shut” position of the Blink effect. The script and renderer and stuff are placed in the hierarchy next to the main camera to “override” the normal camera / VR view.

The c# sourcecode to test the blink on the shader:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Renderer))]
public class FadeOutEyeBlink : MonoBehaviour {

    //The script needs a renderer see also requireRenderer - Renderer is set in Start 
    public Renderer screenFadeRenderer;

    //Just a trigger bool (for Event Checkbox)
    public bool doFadeout = false;
    //Delay the fadeout... (Fade Effect does not immediately start - will wait after this delay)
    public float fadeoutAfterThisTime = 0.3f; 

    //Just a trigger bool (for Event Checkbox)
    public bool doFadein = false;
    //Delay the fadeout... (Fade Effect does not immediately start - will wait after this delay)
    public float fadeinAfterThisTime = 0.2f;

    //Check if IsFading effect is actually faded...
    public bool screenFading = false;

    //This is the value which will increased / decreased during the fade... It's here to see it in the Inspector
    public float fadeTimer;

    //Value the renderer should give to the cutout shader on Start.
    public float startFadeValue = 1f;

    //DE DEV Info: Animation / FadeIn / FadeOut dauert aktuell 1 Sekunde!
    //Aktuell ist das zu langsam für einen Wimpernschlag, der nur 100ms dauert https://de.wikipedia.org/wiki/Gr%C3%B6%C3%9Fenordnung_(Zeit)
    //Mit dem blinkSpeed nun einstellbar

    //Make slower with 0,3 value and increase speed to a very quick blink in case the value is very high like 50
    public float blinkSpeed = 16f;

    

    //initialization
    void Start () {
        //Get the Renderer from the Component this script is attached to.
        screenFadeRenderer = this.GetComponent<Renderer>();
        screenFadeRenderer.material.SetFloat("_Cutoff", startFadeValue);
    }

    //Events to start the Fade
    public void OnStartFadeIn()
    {
        doFadein = true;
    }
    //Events to start the Fade
    public void OnStartFadeOut()
    {
        doFadeout = true;
    }

    // Update check if the triggers are set to start the fades
    void Update () {
        //doFadeout and doFadein are triggers to start the animations
		if(doFadeout == true)
        {
            doFadeout = false;
            StartCoroutine(FadeScreenOut(fadeoutAfterThisTime));
        }
        if (doFadein == true)
        {
            doFadein = false;
            StartCoroutine(FadeScreenIn(fadeinAfterThisTime));
        }
    }
    //Fade In Method / Animation
    public IEnumerator FadeScreenIn(float delay)
    {
        yield return new WaitForSeconds(delay);
        if (screenFading == false)
        {
            screenFading = true;
            fadeTimer = 0f;
            while (fadeTimer <= 1f)
            {
                fadeTimer += Time.deltaTime * blinkSpeed;
                screenFadeRenderer.material.SetFloat("_Cutoff", fadeTimer);
                yield return new WaitForEndOfFrame();
            }
            screenFading = false;
        }
        else
        {
            yield break;
        }
    }

    //Fade Out Method / Animation
    public IEnumerator FadeScreenOut(float delay)
    {
        yield return new WaitForSeconds(delay);
        if (screenFading == false)
        {
            screenFading = true;
            fadeTimer = 1f;
            while (fadeTimer >= 0f)
            {
                fadeTimer -= Time.deltaTime * blinkSpeed;
                screenFadeRenderer.material.SetFloat("_Cutoff", fadeTimer);
                yield return new WaitForEndOfFrame();
            }
            screenFading = false;
        }
        else
        {
            yield break;
        }
    }
}

Steps to create the alpha channel in Gimp:

Gimp Step1

Create an alpha channel in Gimp – Step1

Gimp Step2

Create an alpha channel in Gimp – Step2

Gimp Step3

Create an alpha channel in Gimp Step3