本日は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
}
}
}