|
|
- /// author:Saber
- /// desc:角色相机泛光效果脚本
- /// 2020年2月21日优化:参考了catlikecoding的模糊思路优化逻辑提升效果,模糊rt使用局部摄像机获取到的画面进行处理
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- [ExecuteInEditMode]
- [RequireComponent(typeof(Camera))]
- public class RoleCameraBloom : MonoBehaviour
- {
- public RenderTexture cullRenderTexture; // 用来接收泛光相机的裁剪RT
- private ChangeShaderRender scr_script; // 泛光摄像机上的渲染脚本
- #region 泛光特效相关参数
- //模糊散值
- public Material bloomMaterial; // 泛光特效相关材质
- public bool render_bloom_effect = false; // 泛光特效关键参数,设置为true时会开始渲染泛光特效
-
- #endregion
- private bool isSupported; // 设备支持变量
- // 模糊摄像机获取到的画面依然需要做阈值处理,不过初始默认值为0
- [Range(0, 10)]
- public float threshold = 1;
- // 避免阈值附近的画面忽然点亮,这里设置一个软阈值处理阈值附近的颜色值的泛光效果
- [Range(0, 1)]
- public float softThreshold = 0.5f;
- [Range(0, 10)]
- public float intensity = 1;
- #region 渲染pass常量
- const int BoxDownPrefilterPass = 0; // 对泛光部分降采样的pass
- const int BoxDownPass = 1; // 降序采样pass
- const int BoxUpPass = 2; // 升序采样pass,最大限度利用到所有的像素颜色贡献
- const int ApplyBloomPass = 3; // 泛光颜色叠加pass
- const int DebugBloomPass = 4; // 测试pass,不叠加原颜色,只渲染泛光处理的效果
- #endregion
- [Range(1, 8)]
- public int iterations = 4; // 泛光迭代次数
- RenderTexture[] textures = new RenderTexture[8]; // 临时纹理链表
- RenderTexture currentDestination;
- RenderTexture currentSource;
- Vector4 filter; // 膝盖曲线过滤值
- public bool debug = false;
- // Start is called before the first frame update
- void Start()
- {
- // 检查平台支持,不支持则直接禁用
- isSupported = CheckSupport();
- this.enabled = isSupported;
- if(scr_script != null){
- scr_script.enabled = isSupported;
- }
- // 测试逻辑
- // TestLogic();
- }
- #region 测试逻辑
- private void TestLogic()
- {
- RenderTexture temp_render = new RenderTexture(1280, 600, 0);
- GameObject child = this.transform.GetChild(0).gameObject;
- Camera temp_camera = child.GetComponent<Camera>();
- child.AddComponent<ChangeShaderRender>();
- ChangeShaderRender temp_scr = child.GetComponent<ChangeShaderRender>();
- Shader shader = Shader.Find("SaberShader/BloomClipShader");
- temp_scr.target_shader = shader;
- SetBloomCameraData(temp_camera, temp_render, temp_scr);
- }
- #endregion
- private bool CheckSupport()
- {
- if (SystemInfo.supportsImageEffects == false)
- {
- Debug.LogWarning("当前平台不支持!");
- return false;
- }
- return true;
- }
- // Lua接口,将泛光摄像机和泛光摄像机输出的rt交给本类来控制
- public void SetBloomCameraData(Camera camera, RenderTexture rt, ChangeShaderRender change_shader_render){
- cullRenderTexture = rt;
- camera.targetTexture = cullRenderTexture;
- render_bloom_effect = true;
- scr_script = change_shader_render;
- // 效果运行与否还要看设备支不支持特效
- scr_script.enabled = isSupported;
- }
- // 正式渲染
- // 这个方法要注意在退出游戏的时候把渲染逻辑门关闭,一般情况下把render_bloom_effect置false
- void OnRenderImage(RenderTexture src, RenderTexture dest)
- {
- if (bloomMaterial != null && render_bloom_effect && cullRenderTexture != null)
- {
- // 膝盖曲线的值可以在这里预先算好
- float knee = threshold * softThreshold;
- filter.x = threshold;
- filter.y = filter.x - knee;
- filter.z = 2f * knee;
- filter.w = 0.25f / (knee + 0.00001f);
- bloomMaterial.SetVector("_Filter", filter);
- bloomMaterial.SetFloat("_Intensity", Mathf.GammaToLinearSpace(intensity));
- // 降低一次采样,将剧目摄像机的内容传递到临时的最终画面RT中
- int width = src.width / 4;
- int height = src.height / 4;
- currentDestination = textures[0] = RenderTexture.GetTemporary(width, height, 0, src.format);
- Graphics.Blit(cullRenderTexture, currentDestination, bloomMaterial, BoxDownPrefilterPass);
- currentSource = currentDestination;
-
- // 循环降采样,并将结果保存
- int i = 1;
- for (; i < iterations; i++) {
- width /= 2;
- height /= 2;
- if (height < 2) {
- break;
- }
- currentDestination = textures[i] =
- RenderTexture.GetTemporary(width, height, 0, src.format);
- Graphics.Blit(currentSource, currentDestination, bloomMaterial, BoxDownPass);
- currentSource = currentDestination;
- }
- // 再对降采样后的画面继续宁升采样,将每个像素的颜色平均出去
- for (i -= 2; i >= 0; i--) {
- currentDestination = textures[i];
- textures[i] = null;
- Graphics.Blit(currentSource, currentDestination, bloomMaterial, BoxUpPass);
- RenderTexture.ReleaseTemporary(currentSource);
- currentSource = currentDestination;
- }
-
- if (debug) {
- Graphics.Blit(currentSource, dest, bloomMaterial, DebugBloomPass);
- }
- else {
- bloomMaterial.SetTexture("_SourceTex", src);
- Graphics.Blit(currentSource, dest, bloomMaterial, ApplyBloomPass);
- }
- RenderTexture.ReleaseTemporary(currentSource);
- }
- else
- {
- Graphics.Blit(src, dest);
- }
- }
- public void ReleaseTempRes()
- {
- render_bloom_effect = false;
- if(scr_script != null)
- {
- scr_script.enabled = false;
- }
- }
- void OnDestroy(){
- ReleaseTempRes();
- }
- }
|