Unity Shader 学习 MatCap
简介
MatCap全称MaterailCapture,纹理存储光照信息,通过法线的xy分量去采样MatCap纹理,得到在该方向法线的光照信息,性能好,但表现依靠于纹理制作的好坏。
实现
| 12
 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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 
 | Shader "Unlit/SimpleMatCapShader"{
 Properties
 {
 _MainTex ("Texture", 2D) = "white" {}
 _MatCap("MatCap", 2D) = "white" {}
 _MatCapFactor("MatCapFactor", Range(0,5)) = 1
 _EnvTex("EnvTex (CubeMap)", Cube) = "_SkyBox" {}
 _EnvFactor("EnvStrength", Range(0,1)) = 0.8
 }
 
 SubShader
 {
 Tags { "RenderType"="Opaque" }
 LOD 100
 
 Pass
 {
 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
 
 #include "UnityCG.cginc"
 
 struct appdata
 {
 float4 vertex : POSITION;
 float2 uv : TEXCOORD0;
 float3 normal : NORMAL;
 };
 
 struct v2f
 {
 float4 twoUv : TEXCOORD0;
 float4 vertex : SV_POSITION;
 float3 RefDir : TEXCOORD1;
 };
 
 sampler2D _MainTex;
 float4 _MainTex_ST;
 sampler2D _MatCap;
 half _MatCapFactor;
 samplerCUBE _EnvTex;
 half _EnvFactor;
 
 v2f vert (appdata v)
 {
 v2f o;
 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
 o.twoUv.xy = TRANSFORM_TEX(v.uv, _MainTex);
 
 o.twoUv.zw = UnityObjectToWorldNormal(v.normal).xy;
 o.twoUv.zw = o.twoUv.zw * 0.5 + 0.5;
 float3 wolrdN = UnityObjectToWorldNormal(v.normal);
 o.RefDir = reflect(-WorldSpaceViewDir(v.vertex), wolrdN);
 return o;
 }
 
 fixed4 frag (v2f i) : SV_Target
 {
 
 fixed4 col = tex2D(_MainTex, i.twoUv.xy);
 fixed4 mapCapCol = tex2D(_MatCap, i.twoUv.zw);
 fixed4 reflection = texCUBE(_EnvTex, i.RefDir);
 col.rgb = col.rgb * mapCapCol.rgb * _MatCapFactor + reflection.rgb * _EnvFactor;
 return col;
 }
 ENDCG
 }
 }
 }
 
 | 
问题和思考
- 为什么matcap的图是圆的? -  物体的法线归一化之后可能朝向各个方向(忽略背面),以顶点为原点,朝向各个方向,就会形成一个半圆。 
- 为什么直接就可以使用法线的xy就可以做uv呢? 
参考
[1] 尝试MatCap类型shader
[2] 对SSS Matcap贴图的研究 - Chain
[3] MatCaps - A huge library of MatCap textures in PNG and ZMT. - github
[4] Matcap Shader 详解【6】-平面渲染与更佳的反射// 需要学习一下
[5] matcap 的制作与渲染