c++builder屏幕图像抓取_Unity Shader 屏幕后效果——颜色校正

屏幕后效果指的是,当前整个场景图已经渲染完成输出到屏幕后,再对输出的屏幕图像进行的操作。

在Unity中,一般过程通常是:

1.建立用于处理效果的shader和临时材质,给shader脚本传递需要控制的参数和变量

2.利用OnRenderImage函数抓取当前屏幕渲染纹理

OnRenderImage(RenderTexture source, RenderTexture destination){  }

第一个参数为处理前纹理,第二个为最终显示纹理

3.在OnRenderImage函数中调用Graphics.Blit方法对抓取的纹理进行具体的后期操作

Graphics.Blit(source, destination, material,-1);

material为需要处理的材质,-1为参数pass的默认值,表示对shader中所有的pass依次调用,这里也可以省略

为此,首先可以提前建立一个基类ScreenEffectBase,主要用于检查Shader并创建临时材质:

脚本如下:

using UnityEngine;[ExecuteInEditMode]//屏幕后处理效果主要是针对摄像机进行操作,需要绑定摄像机[RequireComponent(typeof(Camera))]public class ScreenEffectBase : MonoBehaviour{    public Shader shader;    private Material material;    protected Material Material    {        get        {            material = CheckShaderAndCreatMat(shader, material);            return material;        }    }    //用于检查并创建临时材质    private Material CheckShaderAndCreatMat(Shader shader, Material material)    {        Material nullMat = null;        if (shader != null)        {            if (shader.isSupported)            {                if (material && material.shader == shader){ }                else                {                    material = new Material(shader){ hideFlags = HideFlags.DontSave };                }                return material;            }        }        return nullMat;    }}

之后创建的屏幕后处理效果的控制脚本都可以继承自该基类,例如我们创建关于基本颜色校正的控制脚本:

using UnityEngine;public class ColorCorrectionCtrl : ScreenEffectBase{    private const string _Brightness = "_Brightness";    private const string _Saturation = "_Saturation";    private const string _Contrast = "_Contrast";    [Range(0, 3)]    public float brightness = 1.0f;    [Range(0, 3)]    public float saturation = 1.0f;    [Range(0, 3)]    public float contrast = 1.0f;    private void OnRenderImage(RenderTexture source, RenderTexture destination)    {        if (Material!=null)        {            Material.SetFloat(_Brightness, brightness);            Material.SetFloat(_Saturation, saturation);            Material.SetFloat(_Contrast, contrast);            Graphics.Blit(source, destination, Material);        }        else            Graphics.Blit(source, destination);    }}

其中,brightness,saturation,contrast分别为调整参数——亮度,饱和度和对比度,_Brightness,_Saturation,_Contrast为之后对应的shader中需要相应定义的属性参数。

这里利用构建的材质Material对shader的属性赋值并调用Graphics.Blit进行屏幕后效果的处理。

具体实现颜色校正的shader如下:

Shader "MyUnlit/ColorCorrection"{    Properties    {        //这里的参数主要用于展示在材质面板中进行调节,但因为这次是临时创建的材质,参数都已经放在了C#脚本中调整,因此相对应的参数都可以省略        _MainTex ("Texture", 2D) = "white" {}    }    SubShader    {        Tags { "RenderType"="Opaque" }        Pass        {            //OnRenderImage的调用可能会发生在渲染透明物体之前,为了不影响之后透明物体的渲染,需要:开启深度测试+双面渲染+关闭深度写入            ZTest always            Cull off            ZWrite off            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #pragma multi_compile_fog            #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float2 uv : TEXCOORD0;                UNITY_FOG_COORDS(1)                float4 vertex : SV_POSITION;            };            sampler2D _MainTex;            half _Brightness;            half _Saturation;            half _Contrast;            v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                //因为是临时创建的材质,这里不需要对纹理进行任何变换操作(无可操作的材质面板),直接传递即可,_MainTex_ST也不需要定义                o.uv = v.uv;                UNITY_TRANSFER_FOG(o,o.vertex);                return o;            }            fixed4 frag (v2f i) : SV_Target            {                fixed4 col = tex2D(_MainTex, i.uv);                //亮度计算直接叠加                fixed3 color = col.rgb*_Brightness;                //饱和度和灰度有关,先计算最低灰度系数下的图像,随后对原始的图像进行插值操作                fixed3 gray = fixed3(0.2125, 0.7154, 0.0721);                //点积得到最低灰度值,构成最低灰度图像                fixed minGray = dot(gray, col.rgb);                fixed3 grayColor = fixed3(minGray, minGray, minGray);                //对灰度图像和原始图像插值操作以得到最终系数的显示图像                color = lerp(grayColor, color, _Saturation);                //对比度效果类似,先计算最低对比度图像,即(0.5,0.5,0.5),随后插值操作                fixed3 minContrast = fixed3(0.5, 0.5, 0.5);                color = lerp(minContrast, color, _Contrast);                //得到所有处理完成后的图像颜色,但alpha保持不变                fixed4 finColor = fixed4(color, col.a);                UNITY_APPLY_FOG(i.fogCoord, finColor);                return finColor;            }            ENDCG        }    }    //关闭回调    fallback off}

效果如下(随便调的不用在意~):

c57368843db966d97c66f17b4c51f367.png

a428f739b984646a6a12281136a30b7d.png

161464546321486098349819b7503bb2.png

声明:发布此文是出于传递更多知识以供交流学习之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与我们联系,我们将及时更正、删除,谢谢。

作者:汐夜

来源:https://www.cnblogs.com/koshio0219/p/11131619.html 

More:【微信公众号】 u3dnotes

4f730caed3525ba3745c7b166b13f5cd.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值