氷 - saitocastel1900/UnityShader GitHub Wiki
- 法線とviewのベクトルから内積を求めて、内積から透明度を設定している
- このままだと、輪郭が透明で中身が不透明になってしまうので、1-透明度で輪郭を不透明で中身を透明にしている
Shader "Unlit/IceUnlitShader"
{
Properties
{
_Color("Color",Color) = (1,1,1,1)
_AlphaMultiplier ("Alpha Multiplier", Float) = 1.5
}
SubShader
{
Tags
{
"RenderType"="Transparent"
"Queue"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _AlphaMultiplier;
half4 _Color;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 viewDir : TEXCOORD1;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize(UnityObjectToWorldNormal(v.normal));
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float alpha = 1 - abs(dot(i.viewDir, i.worldNormal));
alpha *= _AlphaMultiplier;
return fixed4(1, 1, 1, alpha);
}
ENDCG
}
}
}
- しかし、このままだと裏側も表示されてしまっているため汚い感じに...これは半透明なオブジェクトを描画するときにZバッファの書き込みを止めて、上書きの描画ができなくなったため。そのため、一度Zバッファを書き込んで、そのZバッファを基に上書き描画をできるようにする。参考
Shader "Unlit/IceUnlitShader"
{
Properties
{
_Color("Color",Color) = (1,1,1,1)
_AlphaMultiplier ("Alpha Multiplier", Float) = 1.5
}
SubShader
{
Pass
{
ZWrite ON
ColorMask 0
}
Pass
{
Tags
{
"LightMode" = "UniversalForward"
"RenderType"="Transparent"
"Queue"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
ZWrite OFF
Ztest LEqual
LOD 100
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _AlphaMultiplier;
half4 _Color;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 viewDir : TEXCOORD1;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize(UnityObjectToWorldNormal(v.normal));
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float alpha = 1 - abs(dot(i.viewDir, i.worldNormal));
alpha *= _AlphaMultiplier;
return fixed4(1, 1, 1, alpha);
}
ENDCG
}
}
}