Unity功能记录(十一) ------ 实现3D模型遮罩效果

本文详细介绍了在Unity中实现遮罩效果的两种方法:一种是使用RenderTexture渲染成Sprite配合SpriteMask;另一种是利用Shader中的ColorMask属性。通过具体代码和步骤解析,展示了如何解决遮罩过程中的常见问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事情是这样的,之前呢,用Sprite Mask做了遮罩效果,但是,老板想要月球来回转动,就不能用图片转动,只能用UI了,那相应的,遮罩怎么办呢,老板也是神人,给我指了一条新的思路,就是将3D遮罩转化成2D遮罩,不过放在手机上卡成狗,幸好群里大佬ific指点了一下遮罩的shader,效果不错,在此将两种方法都分享出来~

一.使用RenderTexture渲染成Sprite,然后使用Sprite Mask进行遮罩

1.为要遮罩的模型单独创建layer,新建一个摄像机只看该层

 2.将摄像机的画面渲染到sprite上

public class MoonMask : MonoBehaviour {
    public Camera ModelMaskCamera;
    public Texture2D CamTexture;
    public RenderTexture renderTexture;
    public SpriteRenderer spriteRenderer;

    // Use this for initialization
    void Start () {
        //注意这里的第三个参数
        renderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
        ModelMaskCamera.targetTexture = renderTexture;
        ModelMaskCamera.Render();
        RenderTexture.active = renderTexture;
        spriteRenderer.transform.localPosition = new Vector3(-(float)Screen.width / 100, -(float)Screen.height/100,0);
        CamTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
    }
	
	// Update is called once per frame
	void Update ()
    {
            getScreenTexture();
    }
    void getScreenTexture()
    {
        Rect r = new Rect(0, 0, Screen.width, Screen.height);
        RenderTexture.active = renderTexture;
        CamTexture.ReadPixels(r, 0, 0);
        CamTexture.Apply();
        Sprite sprite = Sprite.Create(CamTexture, new Rect(0, 0, Screen.width, Screen.height), Vector2.zero);
        spriteRenderer.sprite = sprite;
    }
}

这里踩了挺多坑,因为摄像机看到的只有模型时会有残影出现,所以要在后面加一层背景,当时我不能加UI,因为加UI会覆盖在模型上面,透明度又不能设置为0,设置为0了残影还是会出现,不设置为0会影响模型显示效果

好吧,加了Sprite,使它的Z轴在模型后面,扩大摄像机的far值, 使其能看到该Sprite,但是神奇的是还是覆盖在模型上面,偶然发现将RenderTexture的Depth Buffer赋值为At least 16 bit depth或者At least 24 bit depth的时候能够让sprite显示在模型后面,虽然不知道什么原理~

上面代码中的第三个参数就是设置这个的 : 传16是At least 16 bit depth,传24是At least 24 bit depth

官方API : https://docs.unity3d.com/ScriptReference/RenderTexture-depth.html

3.遮罩实现

unity内置了sprite的遮罩 : 

被遮罩物体上:

 遮罩的原理 : 显示遮罩图片不透明部分与被遮罩图片的不透明部分相交部分

二.使用shader中的ColorMask属性进行遮罩

1.建立遮罩模型(比如我的需求是一块面板中间挖个洞)

2.新建一个shader,将下面代码赋值过去

Shader "DepthMask" {

	SubShader{
		// Render the mask after regular geometry, but before masked geometry and
		// transparent things.

		Tags {"Queue" = "Geometry-10" }

		// Turn off lighting, because it's expensive and the thing is supposed to be
		// invisible anyway.

		Lighting Off

		// Draw into the depth buffer in the usual way.  This is probably the default,
		// but it doesn't hurt to be explicit.

		ZTest LEqual
		ZWrite On

		// Don't draw anything into the RGBA channels. This is an undocumented
		// argument to ColorMask which lets us avoid writing to anything except
		// the depth buffer.

		ColorMask 0

		// Do nothing specific in the pass:

		Pass {}
	}
}

3.新建一个材质,选择该shader,并拖拽到遮罩模型上

4.将被遮罩物体作为该物体的子物体,并且Z轴在它之下 

 

用第二种方式时遇到了一些问题 :

出现黑色条纹,懵

找了好久发现原因有两个 :

1.更换了识别图,导致比例变小了

2. vuforia中也有一个重名的DepthMask shader

更改上面的shader名称,比如我改成了DepthMaskM

 

再次打包在手机上成功遮罩

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千喜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值