Cull Off
, подробнее про куллинг можно почитать здесь. Нужную вам прозрачность можно получить с помощью alpha:fade
, если говорить про surface-шейдеры, с другими шейдерами будет немного сложнее. Ниже обычный шаблон шейдера, который я немного подчистил и добавил две недостающие инструкции.Shader "Custom/NewSurfaceShader"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
// Выключаем куллинг, чтобы меш рисовался с двух сторон
Cull Off
CGPROGRAM
// По с равнению со стандартным шаблоном в конце добавилось "alpha:fade" для получения прозрачности
#pragma surface surf Standard fullforwardshadows alpha:fade
#pragma target 3.0
struct Input
{
float2 uv_MainTex;
};
fixed4 _Color;
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
void surf(Input IN, inout SurfaceOutputStandard o)
{
fixed4 color = tex2D (_MainTex, IN.uv_MainTex)*_Color;
o.Albedo = color.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = color.a;
}
ENDCG
}
FallBack "Diffuse"
}
Shader "Projector/Multiply"
{
Properties
{
_ShadowTex("Cookie", 2D) = "gray" {}
_FalloffTex("FallOff", 2D) = "white" {}
// Добавляем свойство
_MaskTex("Mask", 2D) = "white" {}
}
Subshader
{
Tags {"Queue"="Transparent"}
Pass
{
ZWrite Off
ColorMask RGB
Blend DstColor Zero
Offset -1, -1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct v2f
{
float4 uvShadow : TEXCOORD0;
float4 uvFalloff : TEXCOORD1;
UNITY_FOG_COORDS(2)
float4 pos : SV_POSITION;
};
float4x4 unity_Projector;
float4x4 unity_ProjectorClip;
v2f vert (float4 vertex : POSITION)
{
v2f o;
o.pos = UnityObjectToClipPos(vertex);
o.uvShadow = mul(unity_Projector, vertex);
o.uvFalloff = mul(unity_ProjectorClip, vertex);
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
sampler2D _ShadowTex;
sampler2D _FalloffTex;
// Добавляем переменную, чтобы использовать текстуру внутри прохода
sampler2D _MaskTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 texS = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
texS.a = 1.0 - texS.a;
fixed4 texF = tex2Dproj(_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
fixed4 res = lerp(fixed4(1, 1, 1, 0), texS, texF.a);
// Сэмплируем текстуру
fixed4 mask = tex2Dproj(_MaskTex, UNITY_PROJ_COORD(i.uvShadow));
// Применяем маску
res *= mask;
UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1, 1, 1, 1));
return res;
}
ENDCG
}
}
}
fixed4 frag (v2f i) : SV_Target
{
float2 uvShadow = UNITY_PROJ_COORD(i.uvShadow);
float2 uvFalloff = UNITY_PROJ_COORD(i.uvFalloff);
return fixed4(uvShadow, 0.0, 1.0);
//return fixed4(uvFalloff, 0.0, 1.0);
}
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = _Color;
// Металличность и гладкость указываем либо здесь, либо внутри условия
if(abs(IN.worldNormal.z)>0.5)
{
o.Albedo *= tex2D (_MainTex, IN.uv_MainTex).rgb;
// Применяем диффузную текстуру, карту нормалей и тому подобное
...
}
}
// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.
inline float4 EncodeFloatRGBA( float v )
{
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
float kEncodeBit = 1.0/255.0;
float4 enc = kEncodeMul * v;
enc = frac (enc);
enc -= enc.yzww * kEncodeBit;
return enc;
}
inline float DecodeFloatRGBA( float4 enc )
{
float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
return dot( enc, kDecodeDot );
}