Я хотел бы начать с того, что мои познания в кодировании шейдеров довольно ограничены. Я знаю основы и со временем могу понять, как работает шейдер, но не более того.
Пожалуйста, взгляните на следующее изображение:

У меня есть 4 объекта в сцене выше. Земля (бежевая), один красный куб с левой стороны над землей, один красный куб с правой стороны наполовину над землей и наполовину под землей и стена (синяя) перед двумя кубами. Красные кубы отображаются только в том случае, если они находятся за стеной, поэтому, если я удалю стену, они станут невидимыми.
Чего я хотел бы добиться, так это чтобы красные кубы были видны за стеной, но не под землей. Таким образом, правильный куб должен отображать только верхнюю красную часть, а не нижнюю бежевую часть. Я предполагаю, что нижняя бежевая часть — это рендеринг земли за стеной в области, где за ней находится куб.
Вот 3 шейдера, которые я использую:
Кубики: https://pastebin.com/msuyi1zj
Shader "ZTest Shaders/Cube"
{
Properties
{
ObjectColor("Object Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags {
"Queue" = "Transparent+10"
}
Pass
{
ZWrite On
ZTest Greater
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
fixed4 color : COLOR;
float4 vertex : SV_POSITION;
};
uniform fixed4 ObjectColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = ObjectColor;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
Земля: https://pastebin.com/ttL45Gjm
Shader "ZTest Shaders/Ground"
{
Properties
{
ObjectColor("Object Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags {
"Queue" = "Transparent+15"
}
Pass
{
ZWrite On
ZTest Less
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
fixed4 color : COLOR;
float4 vertex : SV_POSITION;
};
uniform fixed4 ObjectColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = ObjectColor;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
Стена: https://pastebin.com/QcL0uY8j
Shader "ZTest Shaders/Wall"
{
Properties
{
ObjectColor("Object Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags {
"Queue" = "Transparent+5"
}
Pass
{
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
fixed4 color : COLOR;
float4 vertex : SV_POSITION;
};
uniform fixed4 ObjectColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = ObjectColor;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
Чтобы дать вам сценарий, в котором я бы использовал что-то подобное, представьте себе игру RTS, в которой вы хотите, чтобы юниты за стенами или другие объекты были видны, чтобы шейдер куба был похож на шейдер контура или силуэта. Теперь представьте, что вы также хотите, чтобы эти юниты спрятались, уйдя под землю. В настоящее время, если бы они ушли под землю, но также были бы за стеной, их было бы видно.
Заранее большое спасибо!
Если кто-то еще столкнется с этой проблемой, ответ был опубликован здесь: forum.unity.com/threads/…





Если кто-то еще столкнется с этой проблемой, ответ был опубликован здесь: https://forum.unity.com/threads/need-help-with-my-outline-shaders-visibility-behind-walls.718499/
Это обновленный шейдер:
Shader "ZTest Shaders/Cube"
{
Properties
{
ObjectColor("Object Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags {
"Queue" = "Transparent+10"
}
Pass
{
ZWrite On
ZTest Greater
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
fixed4 color : COLOR;
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD0;
};
uniform fixed4 ObjectColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = ObjectColor;
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if (i.worldPos.y < 0.0) discard;
return i.color;
}
ENDCG
}
}
}
Одной из идей может быть сравнение выходного цвета, и если он не красный, то ничего не выводить, но я не очень уверен, как это написать, чтобы это работало :(. Если вы посмотрите на pulciu.com/screenshot.jpg, правый куб, который наполовину выше земля и половина под ней, печатает верхнюю часть красной, и это все, что я хотел бы сохранить.