Files
JJBB/Assets/Project/Script/Shader/BlackScreenEffect.cs
2024-08-23 15:49:34 +08:00

203 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using System.Collections;
public enum BlackType
{
ImmediatelyBlack,
PingPong,
EditCurve
}
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Black/BlackScreenCSharp")]
public class BlackScreenEffect : MonoBehaviour {
#region DataDeclaration
public Shader _blackScreenShader;
public float _TransTime = 1.0f;
static Material s_blackMaterial = null;
public bool _IsLoop = false;
public BlackType _BlackType = BlackType.ImmediatelyBlack;
public AnimationCurve _AnimationCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f, 0.0f, 1.0f), new Keyframe(1.0f, 1.0f, 1.0f, 1.0f));
private float timeCounter ;
private float timeCounterAnim;
private bool isPingPongSecRange = false;
private bool isEnd = false;
#endregion
#region DataCheck
private BlackType BlackTypeFuc
{
get
{
return _BlackType;
}
}
protected Material material
{
get
{
if (s_blackMaterial == null)
{
s_blackMaterial = new Material(_blackScreenShader);
s_blackMaterial.hideFlags = HideFlags.DontSave;
}
return s_blackMaterial;
}
}
private void InitData()
{
if (BlackTypeFuc == BlackType.PingPong)
{
timeCounter = _TransTime;
}
else if (BlackTypeFuc == BlackType.ImmediatelyBlack)
{
timeCounter = 0.0f;
}
else
{
timeCounter = 0.0f;
timeCounterAnim = 0.0f;
}
}
#endregion
#region MainFunc
//黑屏淡入淡出计算时间。
void BlackScreenTimeEvaluate()
{
//当type设置为pingpong时屏幕从亮到黑再到亮过程总时间为2*_TransTime。
if (BlackTypeFuc == BlackType.PingPong)
{
//从亮到暗
if (!isPingPongSecRange)
{
timeCounter -= Time.deltaTime;
if (timeCounter < 0.0f)
{
isPingPongSecRange = true;
}
}
//从暗到亮
else
{
timeCounter += Time.deltaTime;
if (timeCounter > _TransTime)
{
isPingPongSecRange = false;
timeCounter = _TransTime;
if (!_IsLoop)
{
enabled = false;
//isEnd = true;
}
}
}
}
//ImmediatelyBlack瞬间黑屏经过_TransTime的时间后变亮。
else if (BlackTypeFuc == BlackType.ImmediatelyBlack)
{
timeCounter += Time.deltaTime;
if (timeCounter > _TransTime)
{
if (!_IsLoop)
{
enabled = false;
isEnd = true;
}
else
{
timeCounter = 0.0f;
}
}
}
//EditCurve解决参数化问题时间的曲线变化随AnimationCurve编辑的曲线变动。
else
{
timeCounterAnim += Time.deltaTime;
timeCounter = _AnimationCurve.Evaluate(timeCounterAnim / _TransTime) * _TransTime;
if (timeCounterAnim > _TransTime)
{
if (!_IsLoop)
{
enabled = false;
isEnd = true;
}
else
{
timeCounterAnim = 0;
timeCounter = _AnimationCurve.Evaluate(0) * _TransTime;
}
}
}
material.SetFloat("_blackCount", timeCounter / _TransTime);
//无loop的时候若在上段代码把以下参数设置为0会导致闪屏问题。
if (isEnd)
{
timeCounterAnim = 0.0f;
timeCounter = 0.0f;
isEnd = false;
}
}
#endregion
#region MonoBehaviourField
// Use this for initialization
void Start()
{
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
// Disable if the shader can't run on the users graphics card
if (!_blackScreenShader || !material.shader.isSupported)
{
enabled = false;
return;
}
InitData();
}
protected void OnDisable()
{
if (s_blackMaterial)
{
Destroy(s_blackMaterial);
}
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
//source.filterMode = FilterMode.Bilinear;
BlackScreenTimeEvaluate();
int rtW = source.width;
int rtH = source.height;
//当前屏幕满分辨率作为buffer使用shader渲染后到目标屏幕并释放当前buffer。
RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
Graphics.Blit(source, buffer, material, 0);
Graphics.Blit(buffer, destination);
RenderTexture.ReleaseTemporary(buffer);
}
#endregion
}