ジオメトリシェーダ、サンプル pic.twitter.com/3ZapVt5VW2
— 光属性のアルモジナ(VRChat勢) (@arumogina) June 8, 2019
++参考
HoloLens で使える Near Clip 表現について解説してみた - 凹みTips
++コード
上記の参考サイトのコードをカスタム・補完したものです
Shader "Custom/GeoSample" { Properties { _Method("DestructionMethod", Float) = 0 _Destruction("Destruction Factor", Range(0.0, 10.0)) = 0.0 _UpFactor("Up Factor", Range(0.0, 10.0)) = 0.2 _PositionFactor("Position Factor", Range(0.0, 10.0)) = 0.2 _RotationFactor("Rotation Factor", Range(0.0, 10.0)) = 1.0 _ScaleFactor("Scale Factor", Range(0.0, 10.0)) = 1.0 _MainTex("Texture", 2D) = "white" {} } SubShader{ Pass{ CGPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #pragma multi_compile _METHOD_PROPERTY _METHOD_CAMERA #include "UnityCG.cginc" #define PI 3.1415926535 fixed _Destruction; fixed _PositionFactor; fixed _RotationFactor; fixed _UpFactor; fixed _ScaleFactor; fixed _AlphaFactor; fixed _StartDistance; fixed _EndDistance; uniform sampler2D _MainTex; uniform fixed4 _MainTex_ST; uniform uint _VID; struct appdata_t { float4 vertex : POSITION; float4 normal : NORMAL; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float2 vid : TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct g2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; appdata_t vert(appdata_t v,uint vid : SV_VertexID) { v.vid = vid; return v; } float rand(float2 co){ return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); } [maxvertexcount(3)] void geom(triangle appdata_t input[3], inout TriangleStreamstream){ // ポリゴンの中心を計算。 // ポリゴン単位で計算を行えるため、「ポリゴンの中心位置」も計算可能です。 float3 center = (input[0].vertex + input[1].vertex + input[2].vertex) / 3; // ポリゴンの辺ベクトルを計算し、ポリゴンの法線を計算する。 // 続いて、前のサンプルでもあった「ポリゴン法線」の計算です。 float3 vec1 = input[1].vertex - input[0].vertex; float3 vec2 = input[2].vertex - input[0].vertex; float3 normal = normalize(cross(vec1, vec2)); fixed destruction = _Destruction; fixed r = 2.0 * (rand(center.xy) - 0.5); fixed3 r3 = r.xxx; float3 up = float3(0, 1, 0); // コードをループじゃない状態に展開することを明示する(詳細は下の記事を参照) [unroll] for (int i = 0; i < 3; i++) { appdata_t v = input[i]; g2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // 以下では、各要素(位置、回転、スケール)に対して係数に応じて変化を与えます。 // center位置を起点にスケールを変化させます。 v.vertex.xyz = (v.vertex.xyz - center) * (1.0 - destruction * _ScaleFactor) + center + (up * _UpFactor); // center位置を起点に、乱数を用いて回転を変化させます。 float angle = rand((float)v.vid) * destruction * _RotationFactor * _Time.x*10; //X軸の回転行列 float3x3 rotate = float3x3(1,0,0,0,cos(angle),-sin(angle),0,sin(angle),cos(angle)); v.vertex.xyz = mul(rotate,(v.vertex.xyz - center)) + center; // 法線方向に位置を変化させます v.vertex.xyz += normal * destruction * _PositionFactor * r3; // 最後に、修正した頂点位置を射影変換しレンダリング用に変換します。 o.vertex = UnityObjectToClipPos(v.vertex); o.color = v.color; o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); stream.Append(o); } stream.RestartStrip(); } fixed4 frag(g2f i) : SV_Target{ fixed4 color = tex2D(_MainTex, i.texcoord); return color; } ENDCG } } }