- 最后登录
- 2021-7-6
- 注册时间
- 2012-12-27
- 阅读权限
- 90
- 积分
- 76145
- 纳金币
- 53488
- 精华
- 316
|
先看一个简单的surface shader:- Shader "Custom/Diffuse Texture" {
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
- }
- SubShader {
- Tags { "RenderType"="Opaque" }
- LOD 200
- CGPROGRAM
- #pragma surface surf Lambert
- sampler2D _MainTex;
- struct Input {
- float2 uv_MainTex;
- };
- void surf (Input IN, inout SurfaceOutput o) {
- half4 c = tex2D (_MainTex, IN.uv_MainTex);
- o.Albedo = c.rgb;
- o.Alpha = c.a;
- }
- ENDCG
- }
- FallBack "Diffuse"
- }
复制代码 每段分析总结:
1.Properties{}
_Name("Display Name", type) = defaultValue[{options}]
_Name - 属性的名字,简单说就是变量名,在之后整个Shader代码中将使用这个名字来获取该属性的内容;
Display Name - 这个字符串将显示在Unity的材质编辑器中作为Shader的使用者可读的内容;
type - 这个属性的类型,可能的type所表示的内容有以下几种:
Color - 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;
2D - 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来;
Rect - 一个非2阶数大小的贴图;
Cube - 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;
Range(min, max) - 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);
Float - 任意一个浮点数;
Vector - 一个四维数;
defaultValue 定义了这个属性的默认值,
Color - 以0~1定义的rgba颜色,比如(1,1,1,1);
2D/Rect/Cube - 对于贴图来说,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者"white","black","gray","bump"中的一个
Float,Range - 某个指定的浮点数
Vector - 一个4维数,写为 (x,y,z,w)
{option}它只对2D,Rect或者Cube贴图有关 ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal
2.Tags{} Tags { "RenderType"="Opaque" } 告诉了系统应该在渲染非透明物体时调用我们
"RenderType" = "Transparent",表示渲染含有透明效果的物体时调用
"IgnoreProjector"="True"(不被Projectors影响)
"ForceNoShadowCasting"="True"(从不产生阴影)
"Queue"="xxx"(指定渲染顺序队列)
预定义的Queue有:
Background - 最早被调用的渲染,用来渲染天空盒或者背景
Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
Transparent - 以从后往前的顺序渲染透明物体
Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
3.LOD
LOD很简单,它是Level of Detail的缩写
4.#pragma surface surfaceFunction lightModel [optionalparams]
有3种类型的光照模型的原型我们可以选择:
1.half4 LightingName(SurfaceOutput s, half3 lightDir,half atten){} 在前置渲染不需要观察者方向的场合
2.half4 LightingName(SurfaeOutput s, half3 lightDir,half3 viewDir,half atten){} 在前置渲染需要观察者方向的场合
3.half4 LightingName_PressPass(SurfaceOutput s,half4 light){} Unity被配置成延迟渲染的时候需要的
5.sampler2D _MainTex
更简单地理解,sampler2D就是GLSL中的2D贴图的类型,相应的,还有sampler1D,sampler3D,samplerCube等等格式
6.写surface shader,我们先是:
1.在SubShader中用#pragma surface surf_func来定义要用到的方法;
2.上述方法第一个参数是一个struct Input,里面可以填上shader需要从外部送进来的数据,比如UV数据;
Unity运行的时候,会根据这个结构知道该给本shader喂哪些数据。Input中可以填的值:
float3 viewDir
float4 变量用COLOR这个语义关键词来后置修饰
float4 screenPos
float3 worldPos
float3 worldRefl
float3 worldNormal
除了这些值,用户可以让Unity喂入uv值,这个只要在对应的贴图的名字前面加上uv_这个前缀。
第二个参数是一个Unity预定义的结构,前面用inout修饰,表示这个结构是个输入输出都会用到的东西。
struct SurfaceOutput
{
fixed3 Albedo; //像素的颜色
fixed3 Normal; //像素的法向值
fixed3 Emission; //像素的发散颜色
half Specular; //像素的镜面高光
fixed Gloss; //像素的发光强度
fixed Alpha; //像素的透明度
}
|
|