你可以在Unity安装目录Editor/Data/CGIncludes/下找到内置的CgInclude文件。
在着色器对物体的渲染过程中它们各司其职,有些是处理阴影和光照的,有些是处理辅助函数的,有些是管理平台依赖关系的。
你可以访问http://docs.unity3d.com/Manual/SL-BuiltinIncludes.html来查找相关信息。
示例:使用Unity内置的Luminance()函数实现纹理灰度处理。
创建一个Sphere物体和Shader
Shader "Custom/LuminanceShader" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _DesatValue ("Desaturate", Range(0, 1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; fixed _DesatValue; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex); c.rgb = lerp(c.rgb, Luminance(c.rgb), _DesatValue); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
运行效果
EncodeFloatRGBA函数和DecodeFloatRGBA函数
EncodeFloatRGBA函数把一个在区间[0, 1]内的float值编码成一个float4类型的RGBA值。这些RGBA值虽然使用float4类型存储,但其每通道的值也是在区间[0, 1]内,通常在使用时会将其乘以255后取整。DecodeFloatRGBA函数则是EncodeFloatRGBA函数的逆操作。
算法说明:
示例: (编码)
F=0.45663996744297896742448066001961
R=(int)F*255=116 余 r1=0.443191697959636693242568305
G=(int)r1*255=113 余 r2=0.01388297970735677685491777502
B=(int)r2*255=3 余 r3=0.5401598253759780980040326310143
A=(int)r3*255=137 余 r4=0.74075547087441499102832090864
得,RGBA=(116, 113, 3, 137)
示例:(解码)
F=R/255+G/(255^2)+B/(255^3)+A/(255^4)=0.45663996726778701771019072456236
可以看出解码后的误差已经很小。
// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. 请注意,1.0将无法正确编码
// 函数中的算法已被Unity 3D工程师优化。
// 此算法的实现是为了充分利用着色器语言的并行计算性能,尽可能地把执行4次的递归操作压缩到一次的计算中实现。
inline float4 EncodeFloatRGBA( float v )
{
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
float kEncodeBit = 1.0/255.0;
float4 enc = kEncodeMul * v;
enc = frac (enc);
enc -= enc.yzww * kEncodeBit;
return enc;
}
// enc所存储的颜色值编码是已经规格化的,即已经除以255
inline float DecodeFloatRGBA( float4 enc )
{
float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
return dot( enc, kDecodeDot );
}