unity gamma(伽马) linear(线性) 互转代码及问题处理

inline float GammaToLinearSpaceExact (float value)
{
        if (value <= 0.04045F)
            return value / 12.92F;
        else if (value < 1.0F)
            return pow((value + 0.055F)/1.055F, 2.4F);
        else
            return pow(value, 2.2F);
}
inline half3 GammaToLinearSpace (half3 sRGB)
{
        // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
        return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);

        // Precise version, useful for debugging.
        //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
}
 inline float LinearToGammaSpaceExact (float value)
 {
        if (value <= 0.0F)
             return 0.0F;
        else if (value <= 0.0031308F)
            return 12.92F * value;
        else if (value < 1.0F)
            return 1.055F * pow(value, 0.4166667F) - 0.055F;
        else
           return pow(value, 0.45454545F);
}
inline half3 LinearToGammaSpace (half3 linRGB)
{
        linRGB = max(linRGB, half3(0.h, 0.h, 0.h));
        // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
        return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);

        // Exact version, useful for debugging.
        //return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b))
}

 问题处理:

单个ui:Gamma图片在lines管线下显示Gamma管线下的效果(直接用这个shader)

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "UI/Default"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		
		_StencilComp ("Stencil Comparison", Float) = 8
		_Stencil ("Stencil ID", Float) = 0
		_StencilOp ("Stencil Operation", Float) = 0
		_StencilWriteMask ("Stencil Write Mask", Float) = 255
		_StencilReadMask ("Stencil Read Mask", Float) = 255

		_ColorMask ("Color Mask", Float) = 15
	}

	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}
		
		Stencil
		{
			Ref [_Stencil]
			Comp [_StencilComp]
			Pass [_StencilOp] 
			ReadMask [_StencilReadMask]
			WriteMask [_StencilWriteMask]
		}

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest [unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask [_ColorMask]

		Pass
		{
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				half2 texcoord  : TEXCOORD0;
			};
			
			fixed4 _Color;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.vertex = UnityObjectToClipPos(IN.vertex);
				OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
				OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;

			fixed4 frag(v2f IN) : SV_Target
			{
				half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
				clip (color.a - 0.01);
				//color.a = pow(color.a + 0.055, 2.4) / 1.13711896582;
				color.a = pow(color.a, 2.2);
				return color;
			}
		ENDCG
		}
	}
}

整个屏幕:所有ui都实现上述效果

这个脚本挂到主相机上,其上添加UI相机和材质球(shader在下面)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class GammaSpaceUI : MonoBehaviour
{
	public Camera UICamera;
	public Material UICompositeMaterial;

	private int uitex_id = Shader.PropertyToID("_UITex");

	void Awake()
	{
		UICamera.enabled = false;
	}

	void OnRenderImage(RenderTexture src, RenderTexture dst)
	{
		RenderTexture UIRenderTexture = RenderTexture.GetTemporary(src.width, src.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
		UICamera.targetTexture = UIRenderTexture;
		UICamera.Render();
		UICamera.targetTexture = null;

		UICompositeMaterial.SetTexture(uitex_id, UIRenderTexture);

		// GL.sRGBWrite used to avoid an additional conversion in the shader. Probably won't work on mobile.
	#if !UNITY_ANDROID && !UNITY_IOS
		GL.sRGBWrite = false;
	#endif

		Graphics.Blit(src, dst, UICompositeMaterial, 0);

	#if !UNITY_ANDROID && !UNITY_IOS
		GL.sRGBWrite = true;
	#endif

		RenderTexture.ReleaseTemporary(UIRenderTexture);
	}
}
Shader "Hidden/GammaSpaceUI"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _UITex ("Texture", 2D) = "black" {}
    }
    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

        #if defined(SHADER_API_METAL) || defined(SHADER_API_GLES3)
            #define MOBILE_USE_POST_CORRECTION 1
        #endif

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex, _UITex;

            half3 LinearToGammaSpace3(half3 col)
            {
                col.r = LinearToGammaSpaceExact(col.r);
                col.g = LinearToGammaSpaceExact(col.g);
                col.b = LinearToGammaSpaceExact(col.b);
                return col;
            }

            half3 GammaToLinearSpace3(half3 col)
            {
                col.r = GammaToLinearSpaceExact(col.r);
                col.g = GammaToLinearSpaceExact(col.g);
                col.b = GammaToLinearSpaceExact(col.b);
                return col;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb = LinearToGammaSpace3(col.rgb);
                fixed4 ui = tex2D(_UITex, i.uv);

                col.rgb = col.rgb * (1.0 - ui.a) + ui.rgb;

                // need conversion back to linear space if GL.sRGBWrite doesn't work on your platform (mobile)
            #if defined(MOBILE_USE_POST_CORRECTION)
                col.rgb = GammaToLinearSpace3(col.rgb);
            #endif
                return col;
            }
            ENDCG
        }
    }
}

你可能感兴趣的:(图形学/shader,数学/工作中用到,unity,unity,游戏引擎)