【发布时间】:2017-07-05 19:40:31
【问题描述】:
有什么方法可以检测具有一定数量顶点的物体是否撞击平面?如果是这样,我想将它以二进制(黑/白)的形式绘制到平面上,或者用它创建一个纹理。
而且我也不关心这是否只能通过光线投射或一些棘手的物理操作/着色器/等来创建。我只是想知道什么数学算法可以创建它。
干杯,迈克尔
【问题讨论】:
标签: unity3d geometry mask intersection plane
有什么方法可以检测具有一定数量顶点的物体是否撞击平面?如果是这样,我想将它以二进制(黑/白)的形式绘制到平面上,或者用它创建一个纹理。
而且我也不关心这是否只能通过光线投射或一些棘手的物理操作/着色器/等来创建。我只是想知道什么数学算法可以创建它。
干杯,迈克尔
【问题讨论】:
标签: unity3d geometry mask intersection plane
大多数游戏都会使用专门的着色器来实现这一点:
相交着色器查找深度等于(或几乎等于)第一次传递的深度的片段,然后对这些片段进行不同的着色。
A question on the Game Development Stack Exchange 更详细,包括屏幕截图和 WebGL 演示。
在你的情况下,这可能看起来像:
无论您是针对整个场景执行此操作,还是只是为了生成可以应用于其他对象的纹理,着色器原理都保持不变。
【讨论】:
您可以查看统一论坛上的类似主题:
论坛主题: https://forum.unity.com/threads/intersection-shader-cull-front-minus-cull-back.536812/
【讨论】:
自己编写着色器我偶然发现了这个问题很多次,因为谷歌图像搜索每次都会显示它。
我可能晚了 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
}
}
}
【讨论】: