ジオメトリシェーダ習作
code:geom
Shader "Unlit/Study"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex ("Albedo", 2D) = "white" {}
_Pow("Pow", float) = 1.0
}
SubShader
{
Tags { "Queue"="Geometry" "RenderType"="Opaque" "LightMode" = "ForwardBase" }
// LOD 100
Pass
{
CGPROGRAM
// make fog work
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
float _Pow;
struct v2g
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 vertex : TEXCOORD1;
};
struct g2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float light : TEXCOORD1;
};
v2g vert (appdata_full v)
{
v2g o;
o.vertex = v.vertex;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
// //---
void geom(triangle v2g IN3, inout TriangleStream<g2f> triStream) {
g2f o;
// 法線ベクトルの計算
float3 vecA = IN1.vertex - IN0.vertex; float3 vecB = IN2.vertex - IN0.vertex; float3 normal = cross(vecA, vecB);
normal = normalize(mul(normal, (float3x3) unity_WorldToObject));
// ライティングの計算
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
o.light = max(0., dot(normal, lightDir));
// UVの計算
o.uv = (IN0.uv + IN1.uv + IN2.uv) / 3; // メッシュ作成
float pow = sin(_Time.x * _Pow) + 1;
float3 lt = IN0.vertex + normal * pow; lt.x -=0.1; lt.y -= 0.1;
o.pos = UnityObjectToClipPos(lt);
triStream.Append(o);
float3 rt = IN0.vertex + normal * pow; rt.x -=0.1; rt.y += 0.1;
o.pos = UnityObjectToClipPos(rt);
triStream.Append(o);
float3 lb = IN0.vertex + normal * pow; lb.x +=0.1; lb.y -= 0.1;
o.pos = UnityObjectToClipPos(lb);
triStream.Append(o);
float3 rb = IN0.vertex + normal * pow; rb.x +=0.1; rb.y += 0.1;
o.pos = UnityObjectToClipPos(rb);
triStream.Append(o);
triStream.RestartStrip(); // さらに他の三角メッシュを作成する時に必要
// // // 四角形になるように頂点を生産
// // for(int x = 0; x < 2; x++)
// // {
// // for(int y = 0; y < 2; y++)
// // {
// // // 頂点座標を計算し、射影変換
// // o.pos = IN0.pos + float4(float2(x, y) * 0.5, 0, 0); // // o.pos = mul (UNITY_MATRIX_VP, o.pos);
// // // ストリームに頂点を追加
// // triStream.Append (o);
// // }
// // }
// // // トライアングルストリップを終了
// // triStream.RestartStrip();
}
// //---
fixed4 frag (g2f i) : COLOR
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb *= i.light * _Color;
// apply fog
// UNITY_APPLY_FOG(i.fogCoord, col);
return col;
// return fixed4(1, 0, 0, 1);
}
ENDCG
}
}
// Fallback "Diffuse"
}
// {
// Properties
// {
// _Color("Color", Color) = (1,1,1,1)
// _MainTex("Albedo", 2D) = "white" {}
// }
// SubShader
// {
// Tags{ "Queue"="Geometry" "RenderType"= "Opaque" "LightMode" = "ForwardBase" }
// Pass
// {
// CGPROGRAM
// //Geometry Shader ステージのときに呼び出される
// float4 _Color;
// sampler2D _MainTex;
// struct v2g
// {
// float4 pos : SV_POSITION;
// float2 uv : TEXCOORD0;
// float3 vertex : TEXCOORD1;
// };
// struct g2f
// {
// float4 pos : SV_POSITION;
// float2 uv : TEXCOORD0;
// float light : TEXCOORD1;
// };
// v2g vert(appdata_full v)
// {
// v2g o;
// o.vertex = v.vertex;
// o.pos = UnityObjectToClipPos(v.vertex);
// o.uv = v.texcoord;
// return o;
// }
// void geom(triangle v2g IN3, inout TriangleStream<g2f> triStream) // {
// g2f o;
// //法線ベクトルの計算(ライティングで使用)
// float3 vecA = IN1.vertex - IN0.vertex; // float3 vecB = IN2.vertex - IN0.vertex; // float3 normal = cross(vecA, vecB);
// normal = normalize(mul(normal, (float3x3) unity_WorldToObject));
// //ライティングの計算
// float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
// o.light = max(0., dot(normal, lightDir));
// o.uv = (IN0.uv + IN1.uv + IN2.uv) / 3; // //メッシュ作成
// for(int i = 0; i < 3; i++)
// {
// triStream.Append(o);
// }
// //tristream.RestartStrip();//さらに他の三角メッシュを作成する時に必要
// }
// half4 frag(g2f i) : COLOR
// {
// float4 col = tex2D(_MainTex, i.uv);
// col.rgb *= i.light * _Color;
// return col;
// }
// ENDCG
// }
// }
// // Fallback "Diffuse"
// }