イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

shader ジオメトリシェーダ、増やした頂点の面にテクスチャを貼る

f:id:arumogina:20190824180558p:plain


右側がジオメトリシェーダで増やした頂点の面

Shader "Custom/GeoBase" {
	Properties{
		_MainTex("MainTex",2D) = "white"{}
	}
	SubShader{
		Tags{"RenderType"="Opaque" "DisableBatching"="true"}
		//透明部分のあるテクスチャを使う場合
		//Tags{"Queue" = "Transparent" "RenderType" = "Transparent" "DisableBatching"="true"}
		//Blend SrcAlpha OneMinusSrcAlpha

		Pass{
			Cull Off
			CGPROGRAM
			#pragma vertex vert
			#pragma geometry geom
			#pragma fragment frag
			#pragma target 4.0
			//インスペクタに Enable GPU Instanceが追加される
			#pragma multi_compile_instancing

			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
				uint vid : SV_InstanceID;
			};

			struct g2f {
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			//SV_VertexID:頂点のid(こちらはGPU Instancingがオンになってなくても有効なはず)
			appdata vert(appdata v,uint vid : SV_VertexID){
				v.vid = vid;//GPU
				return v;
			}

			sampler2D _MainTex;
			float4 _MainTex_ST;

			[maxvertexcount(6)]
			void geom(triangle appdata vg[3], inout TriangleStream<g2f> outStream){
    		[unroll]
    		for (int i = 0; i < 3; i++){
        	appdata v = vg[i];
					UNITY_SETUP_INSTANCE_ID(v);
        	g2f o = (g2f)0;
        	o.pos = UnityObjectToClipPos(v.vertex);
					o.uv = TRANSFORM_TEX(v.uv, _MainTex);
        	outStream.Append(o);
    		}
				outStream.RestartStrip();
				for (int i = 0; i < 3; i++){
					appdata v = vg[i];
					UNITY_SETUP_INSTANCE_ID(v);
					float4 wpos = mul(unity_ObjectToWorld,v.vertex);
					wpos.x += 2;
					g2f o = (g2f)0;
					o.pos = mul(UNITY_MATRIX_VP,wpos);
					o.uv = TRANSFORM_TEX(v.uv, _MainTex);
					outStream.Append(o);
				}
    		outStream.RestartStrip();
			}

			float4 frag(g2f i) :SV_Target {
				return tex2D(_MainTex,i.uv);
			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}