后处理 - 色调映射
就是将颜色值通过映射公式得到另一种颜色值,比如:将颜色值*0.8也算是映射公式
但这边介绍的映射公式可以得到一种电影校色的效果,至于原理,一般都是经验公式。
效果

c#代码
using UnityEngine; public class TonemappingEff : MonoBehaviour { public Shader m_Shader; public Material m_Material; void Start() { if (false == SystemInfo.supportsImageEffects) { Debug.LogWarning("This platform does not support image effects or render textures."); this.enabled = false; return; } if (null == m_Material) { if (null != m_Shader && m_Shader.isSupported) { m_Material = new Material(m_Shader); m_Material.hideFlags = HideFlags.DontSave; } } else if (m_Material.shader != m_Shader) { if (m_Shader.isSupported) //优先shader { m_Material = new Material(m_Shader); m_Material.hideFlags = HideFlags.DontSave; } } } void OnRenderImage(RenderTexture src, RenderTexture dest) { if (null != m_Material) { Graphics.Blit(src, dest, m_Material); } else { Graphics.Blit(src, dest); } } }
shader
Shader "My/PostEff/Tonemapping"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
//hdr颜色值, 用曲线函数映射到[0, 1]颜色范围内
float3 ACES_Tonemapping(float3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
float3 encode_color = saturate((x*(a*x + b)) / (x*(c*x + d) + e));
return encode_color;
}
fixed4 frag(v2f_img i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
half3 linear_color = pow(col.rgb, 2.2); //Gamma空间转换成线性空间
half3 encode_color = ACES_Tonemapping(linear_color);
col.rgb = pow(encode_color, 1 / 2.2); //线性空间转换为Gamma空间
return col;
}
ENDCG
}
}
}
颜色空间设置
菜单 -> File -> Builder Settings -> Player Settings -> Player页签

参考
Unity自定义后处理——Tonemapping色调映射_unity 的tonemapping-CSDN博客

浙公网安备 33010602011771号