【Unity Shader】2D模型 3D模型混用的穿模问题(Spine在3D场景中出现前后穿模问题的解决办法)

20 篇文章 1 订阅
8 篇文章 1 订阅

问题描述:

在3D场景中使用Spine模型(2D), 因为Spine需要像Billboard类似的处理,永远是垂直与相机的, 所以一般情况下2D模型能正常显示且前后的阻挡关系也是没有问题的,如下图所示,一切都很美好.(这里用一个四边形,图中的福字表示2D模型)
在这里插入图片描述
可是如果后面蓝色的格子比较高,或者2D角色本身也比较高,那么就会出现模型穿插的问题,如下图所示:
在这里插入图片描述
如果吧2D模型竖立起来,前后关系肯定是没有问题的,所以也能避免模型穿插的问题,可是就没有Billboard效果,圆形的福字已经被压扁了,如下图:
在这里插入图片描述
所以现在的解决办法是,2D模型还是斜着放(不让这里的福压扁),而做深度检测的时候用竖立起来的那个模型所在的深度值(避免模型穿插问题,使前后关系看起来是正确的)

怎么才能既保证2D模型的正常显示(Billboard效果),又能有预期的前后遮挡关系(不穿模),鱼和熊掌是可以兼得的,解决思路来源:https://www.bilibili.com/video/BV1rr4y1c7wz

解决方案:

使用斜着的2D模型经过MVP变化后的结果进行渲染,但是在顶点变换的最后,需要用上面竖立时所处的深度值修改顶点的深度值,就能欺骗过VertShader与FragmentShader之间的深度检测环节,就可以达到预期想要的遮挡关系,防止前后穿模。

下面是将2D模型竖立起来,沿着2D模型的脚下旋转到垂直:
在这里插入图片描述
需要注意的是我们是从侧面来看,则是沿着ZY平面进行旋转的,所以需要先找到旋转的中心点(脚下),如这个四边形的旋转中心就是(z=0,y=-0.5),先将模型平移到旋转中心,然后进行ZY平面的旋转(角度和实际相机角度相关联),旋转结束后再做反向的平移操作即可, 而一般的spine模型制作应该都是将脚下的点设为锚点,所以也就可以省去旋转前后的两次平移操作。

完整的VertShader代码:

v2f vert (appdata v)
{
    v2f o;

    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);

    //在MVP变换之后再进行旋转操作,并修改顶点的Z值(深度)
    //弧度
    fixed radian = _angle / 180 * 3.14159;
    fixed cosTheta = cos(radian);
    fixed sinTheta = sin(radian);

    //旋转中心点(测试用的四边形, 正常的spine做的模型脚下旋转的点就是(0,0), 可以省去下面这一步已经旋转完成后的 +center操作)
    half2 center = half2(0, -0.5);
    v.vertex.zy -= center;

    half z = v.vertex.z * cosTheta - v.vertex.y * sinTheta;
    half y = v.vertex.z * sinTheta + v.vertex.y * cosTheta;
    v.vertex = half4(v.vertex.x, y, z, v.vertex.w);

    v.vertex.zy += center;

    float4 verticalClipPos = UnityObjectToClipPos(v.vertex);
    o.vertex.z = verticalClipPos.z / verticalClipPos.w * o.vertex.w ;

    return o;
}

最终效果(Game窗口)达到预期:
在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值