您的位置:首页 > 移动开发 > Unity3D

UnityShader高级篇——调整屏幕亮度、饱和度、对比度

2018-03-06 13:26 477 查看
1.此脚本挂在摄像机上using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BrightnessSaturationAndContrast : PostEffectsBase //继承自基类PostEffectsBase
{
//指定的Shader,对应名为BrightnessSaturationAndContrast的Shader
public Shader BriSatConShader;
//创建的材质
private Material _briSatConMaterial;

//访问材质
public Material Material
{
get
{
//使用CheckShaderAndCreateMaterial函数来得到对应的材质
_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函数来进行真正的特效处理
//src存储当前渲染的图像纹理,dest为经过处理后的目标渲染纹理
//通常情况下会在所有透明和不透明Pass执行完毕后被调用
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
//此函数被调用时会检查材质是否可用,可用就把参数传递给材质再调用Graphics.Blit进行处理
//否则直接把原图显示到屏幕上,不做任何处理
if (Material != null)
{
Material.SetFloat("_Brightness", Brightness);
Material.SetFloat("_Saturation", Saturation);
Material.SetFloat("_Contrast", Contrast);

//使用此函数来完成对渲染纹理的处理
//此函数会把第一个参数传递给Shader中名为_MainTex的属性,所以Shader中必须有_MainTex纹理
Graphics.Blit(src, dest, Material);
}
else
{
Graphics.Blit(src, dest);
}
}

}
2.此Shader传入上面的脚本Shader "Unity Shaders Book/Chapter 12/BrightnessSaturationAndContrast"
{
Properties
{
//由于Graphic.Blit方法,所以必须有_MainTex
_MainTex ("Base(RGB)", 2D) = "white" {}
//由于这些属性声明只是为了显示在面板中,但是对于屏幕特效来说,它们使用的材质都是临时创建的,这些值是直接从脚本中传递给Shader
//所以这些声明可以省略
//亮度
_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"

sampler2D _MainTex;
half _Brightness;
half _Saturation;
half _Contrast;

/*struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};*/

struct v2f
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};

//使用内置appdata_img结构体作为顶点着色器的输入,它只包含了图像处理时必需的顶点坐标和纹理坐标等变量
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);
//使用_Saturation和其上一步得到的颜色之间进行插值,得到希望的饱和度
finalColor = lerp(luminanceColor, finalColor, _Saturation);

//调整对比度
//创建一个对比度为0的颜色值,每个分量均为0.5
fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
//使用_Contrast在其和上一步得到的颜色之间进行插值
finalColor = lerp(avgColor, finalColor, _Contrast);

return fixed4(finalColor, renderTex.a);
}
ENDCG
}
}
//关闭Fallback
Fallback off
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐