后处理 - 色调映射

就是将颜色值通过映射公式得到另一种颜色值,比如:将颜色值*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博客

 

posted @ 2024-03-27 22:49  yanghui01  阅读(7)  评论(0编辑  收藏  举报