DAY 21
0

## 目標

• 認識立方體貼圖(Cube Mapping)

## 立方體貼圖

from LearnOpenGL

Window -> Rendering -> Light Setting

``````Shader "Learning/Ch10/Skybox-cube" {
Properties {
_Tint ("Tint Color", Color) = (.5, .5, .5, .5)
// (1)
[Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
_Rotation ("Rotation", Range(0, 360)) = 0
[NoScaleOffset] _FrontTex ("Front [+Z]   (HDR)", 2D) = "grey" {}
[NoScaleOffset] _BackTex ("Back [-Z]   (HDR)", 2D) = "grey" {}
[NoScaleOffset] _LeftTex ("Left [+X]   (HDR)", 2D) = "grey" {}
[NoScaleOffset] _RightTex ("Right [-X]   (HDR)", 2D) = "grey" {}
[NoScaleOffset] _UpTex ("Up [+Y]   (HDR)", 2D) = "grey" {}
[NoScaleOffset] _DownTex ("Down [-Y]   (HDR)", 2D) = "grey" {}
}

// (2)
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Cull Off ZWrite Off

CGINCLUDE
#include "UnityCG.cginc"

// (3)
half4 _Tint;
half _Exposure;
float _Rotation;

// 水平旋轉整個場景
float3 RotateAroundYInDegrees (float3 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}

struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
// (4)
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
// (4)
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata_t v)
{
v2f o;
// (4)
UNITY_SETUP_INSTANCE_ID(v);
// (4)
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
o.vertex = UnityObjectToClipPos(rotated);
o.texcoord = v.texcoord;
return o;
}
half4 skybox_frag (v2f i, sampler2D smp, half4 smpDecode)
{
half4 tex = tex2D (smp, i.texcoord);
// (5)
half3 c = DecodeHDR (tex, smpDecode);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
ENDCG

Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _FrontTex;
half4 _FrontTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_FrontTex, _FrontTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _BackTex;
half4 _BackTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_BackTex, _BackTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _LeftTex;
half4 _LeftTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_LeftTex, _LeftTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _RightTex;
half4 _RightTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_RightTex, _RightTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _UpTex;
half4 _UpTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_UpTex, _UpTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _DownTex;
half4 _DownTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_DownTex, _DownTex_HDR); }
ENDCG
}
}
}
``````

1. 在變數前面加上這個 -> `[]`，想必在Unity中C#寫過的朋友一定知道，這個就是Attribute。[NoScaleOffset]表示不在面板顯示Tiling跟Offset的資訊，[Gamma]是將值指定為sRGB。
2. `PreviewType`表示在面板中，要怎麼顯示該Material，可以選擇"Plane"或"Skybox"，一般看到的Material會是以材質「球」的形式。
3. 之前的範例都是用`fixed``float``half`也是浮點數的一種，精確度高於`fixed`，低於`float`
4. 這些巨集是與GPU InstancingVR相關的，將他們註解掉也可以正常運作。
5. `DecodeHDR(tex, hdr)`解碼至HDR編碼，一般顏色為RGB，HDR為RGBM。

## 坑阿!

• Gamma
• GPU Instancing
• HDR
• VR(我應該會有很長的時間不會去碰這主題)