Files
Main/Assets/Launcher/ExternalLibs/ShadowMap/ShadowMapScript.cs

373 lines
11 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Thousandto.Launcher.ExternalLibs;
/// <summary>
/// 创建一个产生实时阴影贴图的脚本
/// </summary>
public class ShadowMapScript : MonoBehaviour
{
#region
private const int CN_RESIZE_WIDTH = 1024;
private const int CN_RTSIZE_HEIGHT = 1024;
private const string DefaultShadowKeyWords = "_GONBEST_SHADOW_ON";
#endregion
#region
//是否支持阴影
private bool _supportShadow = false;
//支持的阴影贴图模式
private RenderTextureFormat _texFormat = RenderTextureFormat.ARGB32;
//阴影贴图深度值
private int _texDepth = 0;
//阴影开关
private bool _isEnable = false;
//阴影摄像机
private Camera _shadowMapCamera = null;
//矩阵
private Matrix4x4 _shadowViewProj = Matrix4x4.zero;
//阴影贴图
private RenderTexture _shadownMap = null;
//阴影shader
private Shader _depthShader = null;
//摄像机裁剪层
[SerializeField]
private LayerMask _Cameralayer = 1 << 28;
//可接受阴影的render
[SerializeField]
private Renderer[] _shadowRenderers = null;
//阴影强度
[SerializeField]
private float _shadowStrength = 0.7f;
//阴影视口大小
[SerializeField]
private float _viewPortSize = 3;
//是否使用深度处理
[SerializeField]
private bool _useDepth = false;
//是否需要刷新
[SerializeField]
private bool _refresh = false;
#endregion
#region //重载MonoBehaviour的系统函数
// Use this for initialization
void Awake()
{
//1.初始化
ResetShadowShaderParam();
//2.判断是否支持阴影
CheckSupportShadow();
//3.刷新摄像机
RefreshCamera();
}
private void OnEnable()
{
EnableEx();
RefreshCamera();
}
private void OnDisable()
{
DisableEx();
}
// Update is called once per frame
void Update()
{
if (_refresh)
{
_refresh = false;
if (_shadowMapCamera != null)
{
if (_useDepth)
{
_depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow_Depth");
if (_depthShader == null)
{
Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow_Depth");
}
}
else
{
_depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow");
if (_depthShader == null)
{
Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow");
}
}
_shadowMapCamera.SetReplacementShader(_depthShader, "RenderType");
}
}
this.Render();
}
private void OnValidate()
{
RefreshCamera();
}
private void OnDestroy()
{
ResetMaterial();
ReleaseRenderTexture();
if (_shadowMapCamera != null)
{
_shadowMapCamera.enabled = false;
}
}
#endregion
//刷新摄像机的值
private void RefreshCamera()
{
if (!_supportShadow)
return;
if (_shadowMapCamera == null)
{
_shadowMapCamera = gameObject.GetComponent<Camera>();
_shadowMapCamera.clearFlags = CameraClearFlags.Color;
_shadowMapCamera.backgroundColor = Color.black;
_shadowMapCamera.depth = -10f;
_shadowMapCamera.useOcclusionCulling = false;
_shadowMapCamera.orthographic = true;
_shadowMapCamera.enabled = true;
if (_useDepth)
{
_depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow_Depth");
}
else
{
_depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow");
}
if (_depthShader == null)
{
Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow");
}
_shadowMapCamera.SetReplacementShader(_depthShader, "RenderType");
;
}
if (_shadowMapCamera != null)
{
_shadowMapCamera.cullingMask = _Cameralayer;
_shadowMapCamera.orthographicSize = _viewPortSize;
}
}
//创建RenderTexture
private void CreateRenderTexture()
{
if (!_supportShadow)
return;
ReleaseRenderTexture();
if (!_useDepth) _texDepth = 0;
_shadownMap = RenderTexture.GetTemporary(CN_RESIZE_WIDTH, CN_RTSIZE_HEIGHT, _texDepth, _texFormat);
_shadownMap.name = "RenderTexture86";
_shadownMap.wrapMode = TextureWrapMode.Clamp;
if (_shadownMap.format != _texFormat)
{
_shadownMap.format = _texFormat;
}
_shadownMap.filterMode = FilterMode.Bilinear;
_shadownMap.antiAliasing = 1;
Graphics.Blit(Texture2D.blackTexture, _shadownMap);
_shadowMapCamera.targetTexture = _shadownMap;
_shadowMapCamera.RenderWithShader(_depthShader, "RenderType");
}
//释放RenderTexture
private void ReleaseRenderTexture()
{
if (_shadownMap != null)
{
RenderTexture.ReleaseTemporary(_shadownMap);
_shadownMap = null;
}
if (_shadowMapCamera != null)
_shadowMapCamera.targetTexture = null;
}
//判断是否支持阴影
private bool CheckSupportShadow()
{
_supportShadow = true;
if (_useDepth)
{
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
{
_texFormat = RenderTextureFormat.ARGB32;
}
else
{
_supportShadow = false;
Debug.LogError("阴影不生效,因为当前设备不支持RenderTexture的图片格式!");
}
}
else
{
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB565))
{
_texFormat = RenderTextureFormat.RGB565;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB4444))
{
_texFormat = RenderTextureFormat.ARGB4444;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB1555))
{
_texFormat = RenderTextureFormat.ARGB1555;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
{
_texFormat = RenderTextureFormat.ARGB32;
}
else
{
_supportShadow = false;
Debug.LogError("阴影不生效,因为当前设备不支持RenderTexture的图片格式!");
}
}
return _supportShadow;
}
//实时获取阴影摄像机的数据,并为Shader所需传递参数
public void Render()
{
if (!_supportShadow)
return;
if (!_isEnable)
return;
if (_depthShader == null)
return;
if (_shadowMapCamera == null)
return;
Matrix4x4 proj = _shadowMapCamera.projectionMatrix;
Matrix4x4 view = _shadowMapCamera.worldToCameraMatrix;
proj = GL.GetGPUProjectionMatrix(_shadowMapCamera.projectionMatrix, true);
if (_shadowRenderers != null)
{
for (int i = 0; i < _shadowRenderers.Length; ++i)
{
var render = _shadowRenderers[i];
if (render != null && render.sharedMaterial != null)
{
render.sharedMaterial.SetMatrix("_MyWorld2ShadowProj", proj * view);
render.sharedMaterial.SetTexture("_MyShadowMap", _shadownMap);
render.sharedMaterial.SetFloat("_ShadowIntensity", _shadowStrength);
}
}
}
}
//开启阴影
private void EnableEx()
{
_isEnable = true;
if (!_supportShadow) return;
ResetShadowShaderParam();
if (_shadowMapCamera != null)
_shadowMapCamera.enabled = true;
CreateRenderTexture();
if (_shadowRenderers != null)
{
for (int i = 0; i < _shadowRenderers.Length; ++i)
{
var render = _shadowRenderers[i];
if (render != null && render.sharedMaterial != null)
{
//Debug.LogError("Eanble:"+ render.name);
render.sharedMaterial.EnableKeyword(DefaultShadowKeyWords);
}
}
}
}
//关闭阴影
private void DisableEx()
{
_isEnable = false;
if (!_supportShadow) return;
ResetShadowShaderParam();
if (_shadowMapCamera != null)
_shadowMapCamera.enabled = false;
ReleaseRenderTexture();
if (_shadowRenderers != null)
{
for (int i = 0; i < _shadowRenderers.Length; ++i)
{
var render = _shadowRenderers[i];
if (render != null && render.sharedMaterial != null)
{
//Debug.LogError("Disable:" + render.name);
render.sharedMaterial.DisableKeyword(DefaultShadowKeyWords);
}
}
}
}
//重置一下阴影的shader参数
private void ResetShadowShaderParam()
{
if (_shadowRenderers != null)
{
for (int i = 0; i < _shadowRenderers.Length; ++i)
{
var render = _shadowRenderers[i];
if (render != null && render.sharedMaterial != null)
{
render.sharedMaterial.SetTexture("_MyShadowMap", Texture2D.blackTexture);
render.sharedMaterial.SetFloat("_ShadowIntensity", 1);
}
}
}
}
//重置一下阴影的shader参数
private void ResetMaterial()
{
if (_shadowRenderers != null)
{
for (int i = 0; i < _shadowRenderers.Length; ++i)
{
var render = _shadowRenderers[i];
if (render != null && render.sharedMaterial != null)
{
render.sharedMaterial.shader = render.sharedMaterial.shader;
}
}
}
}
}