【Unity】カットアウトシェーダーにカラー・加算を追加する方法

unity-shader-cutout-addtive-color

前回の文字を描くようにアニメーションする方法をもう少し良くするべく、シェーダーを作成してみました。

min.hatenablog.jp

結果的には、ネットから探したシェーダーのほうがはるかに便利でしたが、徐々に勉強していきます。

スポンサーリンク

自作でカットアウト(透明・カラー・加算)

Shader "Unlit/Transparent Cutout Additive" {
Properties {
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
LOD 100
Blend SrcAlpha One
Pass {
Lighting Off
Alphatest Greater [_Cutoff]
SetTexture [_MainTex] { combine texture }
}
}
}
  • 一行追加Blend SrcAlpha Oneするだけで、加算になります

ちなみにアルファブレンドにする場合はBlend SrcAlpha OneMinusSrcAlphaを追加するだけです。

TintColorも追加

色も変化できるようにしてみます。

_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)

AlphaToMask True

ColorMask RGB カラーチャネルの書き込みを設定

        SetTexture [_MainTex]
{
Combine texture, texture
}
SetTexture [_MainTex] {
constantColor [_TintColor]
Combine previous * constant, previous * constant
} 

上記を加えてると

// Unlit alpha-cutout shader.
// - no lighting
// - no lightmap support
// - no per-material color
Shader "Unlit/Transparent Cutout Additive" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags {
"Queue"="AlphaTest"
"IgnoreProjector"="True"
"RenderType"="TransparentCutout"
}
Cull Off
LOD 100
Blend SrcAlpha One
AlphaToMask True
ColorMask RGB
Pass {
Lighting Off
Alphatest Greater [_Cutoff]
SetTexture [_MainTex]
{
Combine texture, texture
}
SetTexture [_MainTex] {
constantColor [_TintColor]
Combine previous * constant, previous * constant
}
}
}
}

f:id:min0124:20170910213918p:plain

これで加算とカラーを追加できました。

ただし、もともとの素材がアルファで強弱つけているので、最後にいくとだんだん薄くなってしまいます。

なので、別の方法で表現する必要がありそうです。

スポンサーリンク

カットアウト(透明・カラー・加算・マスク・他)

行き詰まって、検索してみたらやりたいことができるシェーダー見つけました。

f:id:min0124:20170910212712p:plain

Shader "Transparent/Cutout/Additive Cutout" {
Properties{
[HDR]_TintColor("Tint", Color) = (1,1,1,1)
_MainTex("Base (RGB) Trans (A)", 2D) = "grey" {}
_Cloud1Tex("Cloud 1 (RGB) Trans (A)", 2D) = "grey" {}
_Cloud2Tex("Cloud 2 (RGB) Trans (A)", 2D) = "grey" {}
//_CutTex("Cutout (A)", 2D) = "white" {}
_Cutoff("Alpha cutoff", Range(0,1)) = 0.5
_AlphaThreshold("Alpha threshold", Range(0,1)) = 0.01
_CutoffScroll("Cutoff Scroll Speed", Vector) = (0, 0, 0, 0)
_InvFade("Soft Factor", Range(0.01,3.0)) = 1.0
_Boost("Brightness Boost", Range(1, 20)) = 1.0
_ExternalAlpha("External Alpha", Range(0, 1)) = 1.0
//_AlphaPower("Alpha power", Range(1, 150)) = 1
}
SubShader{
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
Blend OneMinusDstColor One
Alphatest Greater[_Cutoff]
AlphaToMask True
ColorMask RGB
//ColorMask RGB
Cull Off
Lighting Off
ZWrite Off
//Fog{ Mode Off }
//Fog Off
//Cull off
CGPROGRAM
#pragma surface surf NoLighting nofog  //one one alpha// Blend One One
#pragma target 3.0
#pragma multi_compile _ SOFTPARTICLES_ON
sampler2D _MainTex;
sampler2D _Cloud1Tex;
sampler2D _Cloud2Tex;
fixed4 _TintColor;
float _Cutoff;
float _AlphaThreshold;
uniform float _ExternalAlpha = 1;
float4 _CutoffScroll;
float _InvFade;
float _Boost;
sampler2D_float _CameraDepthTexture;
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten)
{
fixed4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
float Remap(float value, float inMin, float inMax, float outMin, float outMax)
{
return outMin + (((value - inMin) / (inMax - inMin)) * (outMax - outMin));
}
struct Input
{
float2 uv_MainTex;
float2 uv_Cloud1Tex;
float2 uv_Cloud2Tex;
float4 color : COLOR;
float3 worldPos;
#ifdef SOFTPARTICLES_ON
float4 screenPos;
float eyeDepth;
#endif
};
#ifdef SOFTPARTICLES_ON
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
COMPUTE_EYEDEPTH(o.eyeDepth);
}
#endif
void surf(Input IN, inout SurfaceOutput o)
{
//Arrange scrolling into 2 separate vectors
float2 scrollOffsetCloud1;
float2 scrollOffsetCloud2;
float time;
time = _Time[0];// +IN.worldPos.y;
scrollOffsetCloud1.x = (time * _CutoffScroll.x);
scrollOffsetCloud1.y = (time * _CutoffScroll.y);
scrollOffsetCloud2.x = (time * _CutoffScroll.z);
scrollOffsetCloud2.y = (time * _CutoffScroll.w);
//Pull main texture...
fixed4 mainTexelColor = tex2D(_MainTex, IN.uv_MainTex);
mainTexelColor = mainTexelColor * _TintColor * IN.color;// *fixed4(1, 0, 0, 0);
//..Then get cloud texture and multiply
fixed4 cloud1TexelColor = tex2D(_Cloud1Tex, IN.uv_Cloud1Tex + scrollOffsetCloud1);
fixed4 cloud2TexelColor = tex2D(_Cloud2Tex, IN.uv_Cloud2Tex + scrollOffsetCloud2);
//MAGIC
fixed4 finalColor;
finalColor = mainTexelColor;
finalColor.a = (mainTexelColor.a * cloud1TexelColor.a * 2) * cloud2TexelColor.a * 2;
//Cutoff math
float ca = finalColor.a ;
float a = ca;
float progress = 1 - IN.color.a;
float thresh = _AlphaThreshold;
float fadeMin = clamp(_Cutoff - thresh, 0, 1);
float fadeMax = clamp(_Cutoff + thresh, 0, 1);
float currentAlpha = ca * (1 - progress) * _ExternalAlpha;;
a = clamp(Remap(currentAlpha, fadeMin, fadeMax, 0, 1), 0, 1);
float fade = 1;
#ifdef SOFTPARTICLES_ON
float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
float sceneZ = LinearEyeDepth(rawZ);
fade = saturate(_InvFade * (sceneZ - IN.screenPos.w));   //float partZ = IN.eyeDepth;
#endif
o.Alpha = a;
o.Albedo = clamp(finalColor.rgb * a * _Boost, 0, 1) * fade;
}
ENDCG
}
Fallback "Transparent/VertexLit"
}

コメント