Маска пересечения единства
Есть ли способ определить, попадает ли объект с определенным количеством вершин в плоскость? Если это так, я хочу нарисовать его в двоичном виде (черный / белый) на плоскости или создать текстуру с ним.
И меня также не волнует, может ли это быть создано только с помощью радиопередач или некоторых хитрых физических операций / шейдеров / и т. Д. Мне просто интересно, какой математический алгоритм может создать это.
Вот пример того, чего я пытаюсь достичь:
Ура, Майкл
3 ответа
Большинство игр добиваются этого с помощью специализированных шейдеров:
- Первый проход отображает карту глубины для непрозрачных объектов в сцене
- Второй проход использует шейдер пересечения для прозрачных объектов
Шейдер пересечения ищет фрагменты, глубина которых равна (или почти равна) глубине от первого прохода, а затем по-разному окрашивает эти фрагменты.
Вопрос об обмене стеками в разработке игр более детален, включая скриншоты и демонстрацию WebGL.
В вашем случае это может выглядеть так:
- Сделать плоскость непрозрачной геометрией
- Визуализируйте другие объекты, используя шейдер пересечения
- Фрагменты, которые пересекают плоскость, нарисованы
- Фрагменты, которые не пересекают плоскость, отбрасываются
Независимо от того, делаете ли вы это для всей сцены или просто для создания текстуры, которую вы можете применить к какому-либо другому объекту, принципы шейдера в любом случае остаются прежними.
Написав шейдер самостоятельно, я много раз сталкивался с этим вопросом, потому что поиск изображений Google показывает его каждый раз.
Возможно, я опоздал на 4 года, но для всех остальных я написал шейдер, который делает именно то, что на картинке:
Шейдер для стены (ShaderOne)
Shader "Custom/ShaderOne"
{
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry"}
Pass {
Stencil {
Ref 2
Comp always
Pass replace
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(0.5,0.5,0.5,1);
}
ENDCG
}
}
}
Шейдер для объекта(ов) (ShaderTwo)
Shader "Custom/ShaderTwo"
{
SubShader {
Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Pass {
Stencil {
Ref 2
Comp equal
Pass IncrWrap
ZFail keep
}
ZTest less
Cull Front
ZWrite OFF
CGPROGRAM
#pragma vertex vert
#pragma fragment frag alpha
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(0,0,1,0.0);
}
ENDCG
}
Pass {
Stencil {
Ref 2
Comp equal
Pass keep
ZFail keep
}
ZTest less
Cull Back
ZWrite OFF
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(1,0,0,0.5);
}
ENDCG
}
}
}
Вы можете посмотреть аналогичную ветку на форуме Unity:
Тема на форуме:https://forum.unity.com/threads/intersection-shader-cull-front-minus-cull-back.536812/