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

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

shader ジオメトリシェーダbase

Shader "Custom/GeoBase" {
	Properties{
    [Enum(UnityEngine.Rendering.CullMode)]
		_Cull("Cull", Float) = 2                // Off
		[Enum(UnityEngine.Rendering.CompareFunction)]
		_ZTest("ZTest", Float) = 4              // LEqual
		[Enum(Off, 0, On, 1)]
		_ZWrite("ZWrite", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)]
		_SrcFactor("Src Factor", Float) = 5     // SrcAlpha
		[Enum(UnityEngine.Rendering.BlendMode)]
		_DstFactor("Dst Factor", Float) = 10    // OneMinusSrcAlpha
    //ステンシル
    _StencilRef("StencilRef",Float) = 0
    [Enum(UnityEngine.Rendering.StencilOp)]
    _StencilPass("StencilPass",Float) = 0
    //https://docs.unity3d.com/ScriptReference/Rendering.CompareFunction.html
    [Enum(UnityEngine.Rendering.CompareFunction)]
    _StencilComp("StencilComp",Float) = 0
	}
	SubShader{

		Tags{"Queue" = "Transparent" "RenderType" = "Transparent" "DisableBatching"="true"}
		//Blend SrcAlpha OneMinusSrcAlpha
		Cull [_Cull]
		ZTest [_ZTest]
		ZWrite [_ZWrite]
		Blend [_SrcFactor][_DstFactor]

    Stencil{
      Ref [_StencilRef]
      Comp [_StencilComp]
      Pass [_StencilPass]
    }
		Pass{
			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(3)]
			void geom(triangle appdata vg[3], inout TriangleStream<g2f> outStream,uint pid:SV_PrimitiveID){
    		[unroll]
    		for (int i = 0; i < 3; i++){
        	appdata v = vg[i];

        	g2f o = (g2f)0;
        	o.pos = UnityObjectToClipPos(v.vertex);
					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"
}
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{
			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(3)]
			void geom(triangle appdata vg[3], inout TriangleStream<g2f> outStream){
    		[unroll]
    		for (int i = 0; i < 3; i++){
        	appdata v = vg[i];
			/*
			GPU instancingがオンになっていると
			UNITY_VERTEX_INPUT_INSTANCE_IDがセットされた場所に
			uint instanceID : SV_InstanceID;
			がセットされる(実装的にはdefineで置換されている)
			*/
			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();
			}

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