源战役客户端
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

153 行
6.3 KiB

/// 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();
}
}