UnityShader

您所在的位置:网站首页 屏幕的饱和度怎么调整比例不变动 UnityShader

UnityShader

2024-07-12 23:55| 来源: 网络整理| 查看: 265

TargetTexture.png  

默认情况下OnRenderImage是在整个屏幕渲染完以后(也就是在不透明和透明物体之后都渲染完以后)调用,在一些特殊的情况下,我们需要在渲染完不透明物体的Pass(即渲染队列小于等于2500的pass,例如内置的 AlphaTest,Background,Geometry,等都在这个范围内)后立即就调用OnRenderImage,换句话说就是我们不希望将透明物体也包括在屏幕后处理中,这时我们需要在OnRenderImage函数前面添加[ImageEffectOpaque]属性来达到目的。

在OnRenderImage函数中我们通常通过Graphics.Blit函数对纹理进行处理,它有3种函数声明: Graphics.Blit(Texture src,RenderTexture dest); Graphics.Blit(Texture src,RenderTexture dest,Material mat ,int pass = -1); Graphics.Blit(Texture src,Material mat ,int pass = -1); src表示当前屏幕纹理或者上一步处理后得到的渲染纹理,dest表示目标渲染纹理,如果他的值为null,那么就会直接将处理后的纹理渲染到屏幕上面。mat是使用的材质,这个材质使用的shader将会对源纹理进行各种特效处理。而源纹理(src)将会被传递给shader中的_MainTex的纹理属性。pass的默认参数是-1,表示将会依次调用shader中的每个pass,否则,只会调用给定索引的pass。

三、实例

1、基类实现

在进行屏幕后处理前我们需要一系列的条件检测,例如当前平台是否支持渲染纹理和屏幕特效,是否支持当前使用的unity shader等。为此,我们创建一个用于屏幕后处理效果的基类(PostEffectsBase.cs),在实现屏幕效果时,我们只需要继承这个基类,再实现派生类中不同操作即可。 基类实现PostEffectsBase.cs:

using UnityEngine; using System.Collections; //在编辑器状态下执行该脚本 [ExecuteInEditMode] //刚需组件(Camera) [RequireComponent (typeof(Camera))] public class PostEffectsBase : MonoBehaviour { // 在Start()中调用 protected void CheckResources() { bool isSupported = CheckSupport(); if (isSupported == false) { NotSupported(); } } // 平台渲染纹理与屏幕特效支持检测 protected bool CheckSupport() { if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false) { Debug.LogWarning("This platform does not support image effects or render textures."); return false; } return true; } // 当不支持的时候,将脚本的enabled设置为false protected void NotSupported() { enabled = false; } protected void Start() { CheckResources(); } // 检测Material和Shader,在派生类中调用,绑定材质和shader protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) { if (shader == null) { return null; } if (shader.isSupported && material && material.shader == shader) return material; if (!shader.isSupported) { return null; } else { material = new Material(shader); material.hideFlags = HideFlags.DontSave; if (material) return material; else return null; } } }

2、调节亮度,饱和度,对比度

(1)创建脚本(BrightnessSaturationAndContrast.cs),继承基类,重写OnRenderImage函数

using UnityEngine; using System.Collections; public class BrightnessSaturationAndContrast : PostEffectsBase { //绑定的shader public Shader briSatConShader; private Material briSatConMaterial; public Material material { get { //调用基类的CheckShaderAndCreateMaterial方法绑定shader与Material briSatConMaterial = CheckShaderAndCreateMaterial(briSatConShader, briSatConMaterial); return briSatConMaterial; } } //亮度值 [Range(0.0f, 3.0f)] public float brightness = 1.0f; //饱和度 [Range(0.0f, 3.0f)] public float saturation = 1.0f; //对比度 [Range(0.0f, 3.0f)] public float contrast = 1.0f; //重写OnRenderImage方法 void OnRenderImage(RenderTexture src, RenderTexture dest) { if (material != null) { //设置shader中的各个值 material.SetFloat("_Brightness", brightness); material.SetFloat("_Saturation", saturation); material.SetFloat("_Contrast", contrast); //将源纹理通过material处理,复制到目标纹理中 Graphics.Blit(src, dest, material); } else { Graphics.Blit(src, dest); } } }

(2)编写Shader特效

Shader "Change Brightness Saturation And Contrast" { Properties { //Graphics.Blit函数传入的src _MainTex ("Source Texture", 2D) = "white" {} //亮度值 _Brightness ("Brightness", Float) = 1 //饱和度 _Saturation("Saturation", Float) = 1 //对比度 _Contrast("Contrast", Float) = 1 } SubShader { Pass { //关闭深度写入 ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" //CG中代码块中声明对应的变量 sampler2D _MainTex; half _Brightness; half _Saturation; half _Contrast; struct v2f { float4 pos : SV_POSITION; half2 uv: TEXCOORD0; }; //顶点着色器,坐标转换以及获取uv值 v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } //片元着色器 fixed4 frag(v2f i) : SV_Target { //纹理采样 fixed4 renderTex = tex2D(_MainTex, i.uv); // 亮度值调整 fixed3 finalColor = renderTex.rgb * _Brightness; // 该像素对应的亮度值 fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b; //使用该亮度值创建一个饱和度为0的颜色 fixed3 luminanceColor = fixed3(luminance, luminance, luminance); //将之前的颜色与该颜色进行插值运算,得到调整饱和度后的颜色 finalColor = lerp(luminanceColor, finalColor, _Saturation); // 创建一个对比度度为0的颜色 fixed3 avgColor = fixed3(0.5, 0.5, 0.5); //将之前的颜色与该颜色进行插值运算,得到调整对比度后的颜色 finalColor = lerp(avgColor, finalColor, _Contrast); //返回最终颜色 return fixed4(finalColor, renderTex.a); } ENDCG } } Fallback Off }

(3)返回unity编辑器,将ChangeBrightnessSaturationAndContrast.shader赋值给BrightnessSaturationAndContrast.cs脚本的briSatConShader变量,调整亮度值,饱和度,对比度的值,查看效果



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3