表面着色器
作者:追风剑情 发布于:2014-6-12 22:14 分类:Shader
不同于固定功能着色器,表面着色器和顶点片元着色器的实际着色器代码使用CG或HLSL编写的。
表面着色器必须像其他着色器一样放在CGPROGRAM和ENDCG中间,但它必须放在子着色器块中,不能放在通道中,表面着色器将在多个通道内编译自己,同时使用#pragma surface指令,以声明它是一个表面着色器,该指令如下:
#pragma surface 表面函数 光照模式 [ 可选参数 ]
表面函数
表明哪些CG函数中有表面着色器代码。这个函数的格式如下:
void surf(Input IN, inout SurfaceOutput o)
Input是自定义的输入结构体。Input结构体中包含所有纹理坐标和表面函数所需要的额外的自动变量。
光照模式
在光照模式中使用,内置的光照模式有Lambert(漫反射)和BlinnPhong(高光)。
可选参数
常用的可选参数如表所示。
表面着色器编译指令可选参数
可选参数 | 说明 |
alpha | Alpha混合模式,使用它可以写出用以渲染半透明效果的着色器 |
alphatest:VariableName | Alpha测试模式,使用它可以写出镂空效果的着色器。镂空大小的变量(VariableName)是一个float型的变量 |
vertex:VertexFunction | 自定义的顶点函数,VertexFunction为函数名 |
finalcolor:ColorFunction | 自定义的最终颜色函数,ColorFunction为函数名 |
exclude_path:prepass或exclude_path:forward | 使用指定的渲染路径,不需要生成通道 |
addshadow | 添加阴影投射并且集合通道。通常用于自定义顶点的修改,使阴影也能投射在任何过程的顶点动画上 |
dualforward | 在正向(forward)渲染路径中使用双重光照贴图(dual lightmaps) |
fullforwardshadows |
在正向(forward)渲染路径中支持所有阴影类型 |
decal:add | 添加贴花着色器 |
decal:blend | 混合半透明的贴花着色器 |
softvegetation | 使表面着色器仅能在Soft Vegetation打开时进行渲染 |
noambient | 不使用任何环境光照(ambient lighting)或者球面调和光照(spherical harmonics lights) |
novertexlights | 在正向渲染(Forward rendering)中不使用球面调和光照(spherical harmonics lights)或每顶点光照(per-vertex lights) |
nolightmap | 在这个着色器上禁用光照贴图(lightmap) |
nodirlightmap | 在这个着色器上禁用方向光照贴图(directional lightmaps) |
noforwardadd | 禁用正向渲染添加光照。这会使这个着色器支持一个完整的方向光和所有逐顶点/SH计算的光照 |
approxview | 当着色器有需要的时候,计算每个顶点,而不是每个像素的方向。这样更快,但是当摄像机接近表面时,视图方向不完全正确 |
halfasview | 在光照函数中传递进来的是half-direction向量,而不是视图方向向量。Half-direction计算且将每个顶点标准化。这样更快,但不完全正确 |
提示
可以在CGPROGRAM块中使用#pragma debug指令,然后编译器会产生许多注释的代码,可以在属性查看器中打开这些已编译好的着色器并查看它们。
表面着色器的输出结构体是内置定义好的,只需要在表面函数中写入相应的值即可,标准的表面着色器输出结构体如下:
struct SurfaceOutput {
half3 Albedo; //反射光颜色
half3 Normal; //法线
half3 Emission; //自发光,用于增强物体自身的亮度,使之看起来好像可以自己发光
half Specular; //镜面高光
half Gloss; //光泽度
half Alpha; //透明度
};
表面着色器的输入结构体Input包含有着色器所需要的纹理坐标和附加值。纹理坐标必须在纹理名称前面加上"uv",或者以"uv2"作为头命名来使用第二个纹理坐标集。附加值按需要加入Input中,常用的附加值如表所示。
表面着色器Input附加值
附加值 | 说明 |
float3 viewDir | 视图方向,为了计算视差、边缘光照等效果,Input需要包含视图方向 |
float4 with COLOR semantic | 每个顶点颜色的插值 |
float4 screenPos | 屏幕空间中的位置,为了获得反射效果,需要包含屏幕坐标 |
float3 worldPos | 世界坐标 |
float3 worldRefl | 世界空间中的反射向量,如果表面着色器不写入法线(o.Normal)参数,将包含这个参数 |
float3 worldNormal |
世界空间中的法线向量,如果表面着色器不写入法线(o.Normal)参数,将包含这个参数 |
float3 worldRefl;INTERNAL_DATA | 内部数据。如果表面着色写入了o.Normal,将包含世界反射向量。为了得到基于每个像素的法线贴图的反射向量需要使用世界反射向量(WorldReflectionVector(IN, o.Normal)) |
float3 worldNormal;INTERNAL_DATA |
内部数据。如果表面着色写入了o.Normal,将包含世界法线向量。为了得到基于每个像素的法线贴图的反射向量需要使用世界反射向量(WorldReflectionVector(IN, o.Normal)) |
着色器在属性块声明它的属性,如果想在CG代码中访问这些属性的话,需要在CG中声明一个与名字相同且类型对应的变量。ShaderLab的属性类型与CG变量类型的对应关系如下的列。
- Color和Vector属性对应float4类型。
- Range和Float属性对应float类型。
- Texture属性对应普通2D纹理的sampler2D类型。
- CUBE和RECT纹理对应samplerCUBE和samplerRECT类型。
下面的代码片段说明了CG中属性的声明:
//ShaderLab中声明的属性
_MyColor ("Some Color", Color) = (1,1,1,1)
_MyVector ("Some Vector", Vector) = (0,0,0,0)
_MyFloat ("My float", Float) = 0.5
_MyTexture ("Texture", 2D) = "white" { }
_MyCubemap ("Cubemap", CUBE) = "" { }
//CG中访问着色器属性时声明变量
float4 _MyColor;
float4 _MyVector;
float _MyFloat;
sampler2D _MyTexture;
samplerCUBE _MyCubemap;
提示
Unity中CG也接受uniform关键字,但这是不必要的。
下面建立一个简单的着色器,这个着色器仅仅设置了表面颜色为白色:
Shader "Example/Diffuse Simple" {
SubShader {
Tags { "RenderType" = "Opaque" } //设置替换渲染时的类型
CGPROGRAM
#pragma surface surf Lambert
struct Input { //设置输入结构体
float4 color : COLOR;
};
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = 1; //计算反射光颜色
}
ENDCG
}
Fallback "Diffuse" //降级时使用Diffuse着色器
}
下面的着色器使用了纹理,并且添加了法线贴图:
Shader "Example/Diffuse Bump" { Properties { _MainTex ("Texture", 2D) = "white" {} _BumpMap ("Bumpmap", 2D) = "bump" {} } SubShader { Tags {"RenderType" = "Opaque"} CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; sampler2D _MainTex;//声明sampler2D类型的样本对象 sampler2D _BumpMap; void surf (Input IN, inout SurfaceOutput o){ o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;//计算反射光颜色 o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));//计算法线 } ENDCG } Fallback "Diffuse" }
下面的着色器添加了细节纹理,并与基础纹理结合。细节纹理与基础纹理使用相同的UV。但是在材质球中平铺值通常是不同的。所以在输入结构中必须使用不同的UV坐标:
Shader "Example/ScreenPos" { Properties { _MainTex ("Texture", 2D) = "white" {} _Detail ("Detail", 2D) = "gray" {} } SubShader { Tags {"RenderType" = "Opaque"} CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float4 screenPos; }; sampler2D _MainTex;//声明sampler2D类型的样本对象 sampler2D _Detail; void surf (Input IN, input SurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; float2 screenUV = IN.screenPos.xy / IN.screenPos.w; screenUV *= float2(8, 6); o.Albedo *= tex2D (_Detail, screenUV).rgb *2;//计算反射光颜色 } ENDCG } Fallback "Diffuse" }
下面的着色器通过世界空间位置对对象进行切割,其中,被切割后所抛弃的像素形状是几乎与水平位置平行的环状。它是基于世界位置的像素通过使用CG语言的clip()函数实现:
Shader "Example/Slices" { Properties { _MainTex ("Texture", 2D) = "white" {} _BumpMap ("Bumpmap", 2D) = "bump" {} } SubShader { Tags {"RenderType" = "Opaque"} Cull Off CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float2 uv_BumpMap; float3 worldPos; }; sampler2D _MainTex; sampler2D _BumpMap; void surf (Input IN, inout SurfaceOutput o) { clip (frac((IN.worldPos.y + IN.worldPos.z*0.1)*0.5) - 0.5);//切割抛弃像素 o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;//计算反射光颜色 o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));//计算法线 } ENDCG } Fallback "Diffuse" //降级时使用"Diffuse"着色器 }
日历
最新文章
随机文章
热门文章
分类
存档
- 2024年11月(3)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号