Skip to content

Instantly share code, notes, and snippets.

@mao-test-h
Created October 13, 2018 13:11
Show Gist options
  • Save mao-test-h/35aab0c7ff1bb75f1c59b93c8acbb5bf to your computer and use it in GitHub Desktop.
Save mao-test-h/35aab0c7ff1bb75f1c59b93c8acbb5bf to your computer and use it in GitHub Desktop.
ジオメトリシェーダ―を用いて形状関係なしに強制的にドカベンロゴに塗り替えるシェーダー
Shader "Unlit/DokabenGeometry"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
}
Cull Off
Lighting Off
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
uint vid : SV_VertexID;
};
// vert → geom
struct v2g
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float2 vid : TEXCOORD1; // float2(SV_VertexID, 0)
};
// geom → frag
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
v2g vert(appdata data)
{
v2g o;
o.vertex = data.vertex;
o.uv = data.uv;
// geom側にSV_VertexIDを渡せないので代わりに使っていないUV2に入れる
o.vid = float2(data.vid, 0);
return o;
}
// 引数には1頂点のみを受け取る。
// →中で4頂点に増やし板ポリにしてTextureを貼るイメージ
[maxvertexcount(4)]
void geom(point v2g input[1], inout TriangleStream<v2f> outStream)
{
// 1頂点分のみロゴを生成(ここで塞き止めないと頂点分だけロゴが生まれる)
uint vid = input[0].vid;
if(vid != 0) return;
// ドカベンロゴデータ(頂点、UV)
float4 Vertices[4] = { float4(-2.4, 0.6, 0.0, 0.0), float4(2.4, 0.6, 0.0, 0.0), float4(-2.4, -0.6, 0.0, 0.0), float4(2.4, -0.6, 0.0, 0.0), };
float2 UVs[4] = { float2(0.0, 1.0), float2(1.0, 1.0), float2(0.0, 0.0), float2(1.0, 0.0), };
// コマ落ちアニメーションデータ(※目コピ)
float Animation[16] =
{
1,
0.9333333333333333,
0.8666666666666667,
0.8,
0.7333333333333333,
0.6666666666666666,
0.6,
0.5333333333333333,
0.4666666666666667,
0.4,
0.3333333333333333,
0.26666666666666666,
0.2,
0.13333333333333333,
0.06666666666666667,
0
};
// _SinTime0~1に正規化→0~15(コマ数分)の範囲にスケールして要素数として扱う
float normal = (_SinTime.w+1)/2;
// X軸に0~90度回転
float rot = Animation[round(normal*15)]*radians(90);
// 回転行列
float sinX = sin(rot);
float cosX = cos(rot);
float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);
for(int i = 0; i < 4; ++i)
{
v2f o;
// 回転軸を下端にする為に先ずは原点の位置に下端が来るように移動→回転行列を掛けた後に元の位置に戻す。
o.vertex = Vertices[i];
o.vertex.y += ((_MainTex_TexelSize.w/100)/2);
o.vertex.yz = mul(rotationMatrix, o.vertex.yz);
o.vertex.y -= ((_MainTex_TexelSize.w/100)/2);
o.vertex = UnityObjectToClipPos(o.vertex);
o.uv = UVs[i];
o.uv = TRANSFORM_TEX(o.uv, _MainTex);
outStream.Append(o);
}
outStream.RestartStrip();
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment