本日はShader枠です。
先日に引き続きHex表現を使用したエフェクトを作成します。
昨日の状態まではオブジェクトの持つUV座標に依存してHex表現を行っていました。
これによってオブジェクトの持つUV情報によっては表現が破断するということが起こり得ます。
今回はUnityのワールド座標基準でHexをかけることでこの問題を解消していきます。
〇ワールド座標基準でエフェクトを書ける
Unityのワールド座標をShader内部で使用するには頂点シェーダー内で次のようにunityCG.cgincが提供するマクロであるunity_ObjectToWorldと頂点の行列を求めます。
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
この情報を格納するためにv2f構造体にworldPosを加えています。
struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 worldPos: TEXCOORD1; };
今回はHex自体はこれまで通りオブジェクトのUVに依存させその演出をUnityの座標で行うためにHexagon()メソッドに渡す処理までは前回と同様で行います。
fixed4 frag(v2f i) : SV_Target { float2 Hex; float2 HexUV; float HexPos; float2 HexIndex; Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex); fixed4 col = tex2D(_MainTex, i.uv); ・・・
エフェクトをかけるグラデーションであるStepHexのグラデーション(smoothstep)の値に昨日のi.uv.y(=UVのY座標)ではなくi.worldPos.yを使用することでUnityのワールド座標を使用することができます。
float StepHex = step(Hex, smoothstep( 0.8, 0,i.worldPos.y + _Power));
以上でワールド座標ベースのエフェクトに切り替わります。
同様に発行部もsmoothstepの値をi.worldPos.yを使用してUnityのワールド座標Y軸をベースに使用するようにします。
float3 emission = _EmissionColor.rgb*smoothstep( 0.8, 0,i.worldPos.y + _Power); emission *= 1-Hex.x; col.rgb += emission;
ここまで実装することで次のようにワールド座標基準でエフェクトをかけることができました。
〇コード全文
Shader "Unlit/HexShader(WorldPosition)" { Properties { _MainTex ("Texture", 2D) = "white" {} _Scale("Scale" ,float) = 0 _Power("Power",float) = 0 [HDR]_EmissionColor("Emission" ,color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 AlphaToMask On Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" #include "Hex.hlsl" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 worldPos: TEXCOORD1; }; sampler2D _MainTex; float4 _MainTex_ST; float _Scale; float _Power; float4 _EmissionColor; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; //worldPos o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target { float2 Hex; float2 HexUV; float HexPos; float2 HexIndex; Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex); fixed4 col = tex2D(_MainTex, i.uv); float StepHex = step(Hex, smoothstep( 0.8, 0,i.worldPos.y + _Power)); col*= 1- StepHex; float3 emission = _EmissionColor.rgb*smoothstep( 0.8, 0,i.worldPos.y + _Power); emission *= 1-Hex.x; col.rgb += emission; return col; } ENDCG } } }