[基础] Unity Shader:自定义cginc文件与内置cginc文件

包含文件(include file)是类似于C++中头文件的一种文件,在Unity中,这种包含文件的后缀名是.cginc,我们可以通过创建包含文件来保存我们的自定义函数,这样可以非常有利于我们的代码管理,同时,Unity也提供了很多内置的包含文件,了解这些文件中常用的函数对我们编写shader是非常有必要的。

1. 自定义cginc文件

在编写Shader时,我们可以使用#include指令来引入cginc文件。在Unity编辑器里无法直接创建这些文件,只能通过资源管理器打开我们存放Shader的文件夹,手动创建一个后缀名为.cginc的文件,最好是再创建一个文件夹专门存放这些cginc文件,方便管理。

我在Shader文件夹中,创建了一个名为MyCginc的文件夹,里面存放了我自己写的MyFuncs.cginc文件,该文件内容如下:

void setRedColor(out fixed4 color)
{
    color = fixed4(1, 0, 0, 1);
}

void setGreenColor(out fixed4 color)
{
    color = fixed4(0, 1, 0, 1);
}

void setBlueColor(out fixed color)
{
    color = fixed4(0, 0, 1, 1);
}

然后,我们可在Shader代码中调用这些函数:

#include "MyCginc/MyFuncs.cginc" // 引入自定义cginc文件

float4 vert(float4 v: POSITION): SV_POSITION
{
    return UnityObjectToClipPos(v);
}

fixed4 frag(): SV_Target
{
    fixed4 color;
    setRedColor(color); // 调用自定义cginc文件里的函数
    return color;
}

2. 常用的内置cginc文件

这些内置文件都是由Unity提供的,它们都存放在一个名为CGIncludes文件夹里。在Mac上,他们的位置是:/Applications/Unity/Unity.app/Contents/CGIncludes;在Windows上,它们的位置是:Unity安装路径/Editor/Data/CGIncludes。

下表列出了常用的内置文件以及它们的用途:

文件名描述
UnityCG.cginc包含了最常使用的帮助函数、宏和结构体等
UnityShaderVariables.cginc在编译Unity Shader时,会被自动包含进来。包含了许多内置的全局变量,如UNITY_MATRIX_MVP等
Lighting.cginc包含了各种内置的光照模型,如果编写的是Surface Shader的话,会自动包含进来
HLSLSupport.cginc在编译Unity Shader时,会被自动包含进来。声明了很多用于跨平台编译的宏和定义

 3. 常用的内置结构体

UnityCG.cginc
名称描述包含的变量
appdata_base可用于顶点着色器的输入顶点位置、顶点法线、第一组纹理坐标
appdata_tan可用于顶点着色器的输入顶点位置、顶点切线、顶点法线、第一组纹理坐标
appdata_full可用于顶点着色器的输入顶点位置、顶点切线、顶点法线、四组(或更多)纹理坐标
appdata_img可用于顶点着色器的输入顶点位置、第一组纹理坐标
v2f_img可用于顶点着色器的输出裁剪空间中的位置、纹理坐标

4. 常用的内置函数

UnityCG.cginc
函数名描述
float3 WorldSpaceViewDir(float4 v)输入一个模型空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向
float3 ObjSpaceViewDir(float4 v)输入一个模型空间中的顶点位置,返回模型空间中从该点到摄像机的观察方向
float3 WorldSpaceLightDir(float4 v)仅可用于向前渲染中。输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化
float3 ObjSpaceLightDir(float4 v)仅可用于向前渲染中。输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。没有被归一化
float3 UnityObjectToWorlNormal(float3 norm)把法线方向从模型空间转换到世界空间中
float3 UnityObjectToWorldDir(float3 dir)把方向矢量从模型空间变换到世界空间中
float3 UnityWorldToObjectDir(float3 dir)把方向矢量从世界空间变换到模型空间中

5. 常用的全局变量

UnityCG.cginc
_Timefloat4x自游戏开始以来经过的总秒数(不包括暂停时间)
y它在每一帧中从0平滑过渡到1,然后再回到0
z自游戏启动以来经过的帧数
w自游戏启动以来经过的固定(FixedUpdate)帧数

UNITY_LIGHTMODEL_AMBIENT

fixed4环境光照颜色(梯度环境情况下的天空颜色)。旧版变量
_WorldSpaceLightPos0float3当前平行光的方向,方向是从光源到照射的方向
Lighting.cginc

_LightColor0

fixed3环境光照颜色

  • 35
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Projective Texture Mapping 是一种常用的 Shader 技术,可以用来在 Unity 中实现纹理投影效果。它的原理是通过将投影纹理映射到场景物体上,并基于物体的表面法线和光照方向来计算出光照效果,从而实现物体表面的投影纹理效果。 以下是一个简单的 Projective Texture Mapping 的 Shader 示例: ```shader Shader "Custom/ProjectiveTextureMapping" { Properties { _MainTex ("Texture", 2D) = "white" {} _ProjTex ("Projection Texture", 2D) = "white" {} _Intensity ("Intensity", Range(0,1)) = 1 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 projPos : TEXCOORD0; float3 worldNormal : TEXCOORD1; float4 vertex : SV_POSITION; }; sampler2D _MainTex; sampler2D _ProjTex; float _Intensity; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.projPos = ComputeGrabScreenPos(o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // 计算纹理坐标 float2 projCoord = i.projPos.xy / i.projPos.w; projCoord = 0.5 * (projCoord + 1.0); // 计算投影纹理颜色 fixed4 projColor = tex2D(_ProjTex, projCoord); // 计算漫反射光照 float3 worldNormal = normalize(i.worldNormal); float3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); float intensity = _Intensity * max(0, dot(worldNormal, worldLightDir)); // 计算最终颜色并返回 fixed4 texColor = tex2D(_MainTex, i.uv); fixed4 finalColor = lerp(texColor, projColor, intensity); return finalColor; } ENDCG } } } ``` 这个 Shader 的主要实现思路是,将投影纹理的颜色和物体表面原有的颜色进行插值计算,插值的比例根据光照方向和表面法线来计算。其中,ComputeGrabScreenPos() 函数用于将物体的顶点坐标转换为屏幕坐标,从而计算出纹理坐标。在 Pass 中的 vert 函数中,通过 UnityObjectToWorldNormal() 函数将物体的法线转换为世界坐标系下的法线,从而能够正确计算出光照效果。 使用这个 Shader,将它添加到一个材质中,并将这个材质应用到需要投影纹理的物体上,就可以实现 Projective Texture Mapping 技术了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值