0%

Shader 学习文档 [三]

引子

Surface Shader

最简单的SurfaceShader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Shader "Custom/T_3_0" {

Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
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
}
}

表面处理函数从顶点处理函数(这里自动顶点处理)接收参数Input IN,输出SurfaceOutput o至光照模型(这里是Lambert)。
这里我们就做了三件事:

1. 通过uv取得了贴图对应uv的颜色c
2. 把c.rgb赋给o.Albedo
3. 把c.a赋给o.Alpha

这就完成了。之后让任一物体使用该Shader,则不管加什么光都能正确显示。真的很简单!

## 表面处理函数surf的输入及输出

### 输入

struct Input {
float2 uv_MainTex;
float3 viewDir;
float4 anyName:COLOR;
float4 screenPos;
float3 worldPos;
float3 worldRefl;
} ;

1
2
3
4
5
6
7
8
uv_MainTex: uv
viewDir: 入视角
screenPos:裁剪空间位置
worldPos:世界空间位置


### 输出


struct SurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half Specular;
half Gloss;
half Alpha;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Albedo:漫反射颜色
Normal: 法线
Emission:自发光颜色
Specular:镜面反射系数
Gloss:
Alpha:透明值

[参考](http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaders.html)

## Surface Shader参数

Surface Shader可以通过加参数实现额外的控制,例如加顶点处理函数,alpha混合等。
注意:
如果使用的光照模型是Unity自带的Lambert或者BlinnPhong:
alpha混合,alpha混合等功能必须使用Surface Shader参数。


### alpha混合
直接加参数Alpha即可

pragma surface surf BlinnPhong alpha

1
2
3
4
5
6

### alphatest

加入一个变量,这里起名为_Cutoff, 然后在#pragma surface结尾处加上alphatest:_Cutoff。
效果是alpha值大于_Cutoff时,才会输出颜色

Shader “Custom/T_3_0” {
Properties {
_MainTex (“Base (RGB)”, 2D) = “white” {}
_Cutoff (“Alpha cutoff”, Range(0,1)) = 0.5
}
SubShader {
CGPROGRAM

    #pragma surface surf Lambert alphatest:_Cutoff
    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
}  

}

1
2
3
4
5

### 顶点函数
例:臃肿的模型
实现方法,将顶点向法线方向延伸一段距离


Shader “Example/Normal Extrusion” {
Properties {
_MainTex (“Texture”, 2D) = “white” {}
_Amount (“Extrusion Amount”, Range(-1,1)) = 0.5
}
SubShader {
Tags { “RenderType” = “Opaque” }
CGPROGRAM

  #pragma surface surf Lambert vertex:vert
  struct Input {
      float2 uv_MainTex;
  };
  float _Amount;
  void vert (inout appdata_full v) {
      v.vertex.xyz += v.normal * _Amount;
  }
  sampler2D _MainTex;
  void surf (Input IN, inout SurfaceOutput o) {
      o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
  }
  ENDCG
} 
Fallback "Diffuse"

}

1
2
3
4
### finalcolor
finalcolor:ColorFunction
对颜色输出作最后的更改


Shader “Example/Tint Final Color” {
Properties {
_MainTex (“Texture”, 2D) = “white” {}
_ColorTint (“Tint”, Color) = (1.0, 0.6, 0.6, 1.0)
}
SubShader {
CGPROGRAM

  #pragma surface surf Lambert finalcolor:mycolor
  struct Input {
      float2 uv_MainTex;
  };
  fixed4 _ColorTint;
  void mycolor (Input IN, SurfaceOutput o, inout fixed4 color)
  {

//在这里对最后输出的颜色color进行修改
color *= _ColorTint;
}
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
}
```

更多的参数请参考文档

欢迎关注我的其它发布渠道