Creator3D :太厉害了!3D模型原来可以这样显示在2DUI上

国庆,中秋收假了,菜鸟在这里给大家道声祝福:

同时可能不少人都已经知道,就在放假前,Creator3D 1.2.0 正式版 已经发布。菜鸟后边的自学demo也将全部用1.2.0,大家在打开demo时一定要注意版本奥。

前言

今天菜鸟分享一个小的技术点:3D模型应该怎样显示到2D的ui层上边。最近逛论坛经常看见有关于这个问题的帖子,正好菜鸟后边也要用到,那就提前研究一下。下边将实现的两种方式简单说明一下。

效果

咱们还是先来看看效果:

1.UIMeshRenderer 组件实现效果

刚接触1.2.0版本的人可能对这个比较陌生,在之前的版本他有另一个名字UIModel,在1.2.0版本改名成了UIMeshRenderer

2.RenderTexture 实现效果

正文

1.UIMeshRenderer实现方式

首先建议大家看一下UIMeshRenderer组件的官方文档,这种方式的实现基本上不涉及代码,但是有几个特别需要注意的问题,我大概说下

  • 1.菜鸟习惯将3d节点与2d的ui节点分开放,2d的ui节点默认在Canvas下。3d的节点会创建一个父节点放置,也就是统一放置到ModelContro下,类似于这样:
  • 2.添加MeshRenderer组件到3d模型节点,
    • 官方文档是这样说的
    添加方式是在层级管理器中选中带有或继承自 MeshRenderer 组件的节点,
    
    然后点击 属性检查器 下方的 添加组件 按钮,选择 UI/MeshRenderer即可
    
  • 3.添加了MeshRenderer组件后大家预览可能发现并没有效果
    • 接下来就是这种方式的需要注意的重点了:
    • 1:绑定了MeshRenderer组件的3d节点必须放在Canvas下,也就是2DUI层
    • 2:3d节点的大小,3d节点添加了MeshRenderer组件,并且放置到Canvas下,那么他的大小将不会按照3d节点在摄像机下的大小显示,而是按照3d节点相对Canvas的大小来显示,通常模型的大小需要缩放到在UI层下的实际预览大小
    • 3:材质,当大小和层级调整好以后你会发现模型是显示出来了,但是是黑的,如图:
    • 你已经到了最后一步了,大家的默认effect 应该是builtin-standard吧,只需要将其改为builtin-unlit就可以了

2.RenderTexture 实现方式

这种方式主要是通过代码来实现的,把 3D 相机照射的内容绘制到 UI 的精灵帧上
在菜鸟出demo的时候是国庆前,文档和API都还没有更新,还是之前版本的。1.2.0版本对部分参数进行了调整。现在好像API调整了,文档还是之前的,但是没啥影响。
下边咱们说一下重点:

  • 1.原理就是 把 3D 相机照射的内容绘制到 UI 的精灵帧上
  • 2.那么主要就是3d摄像机,需要创建一个摄像机,然后将你所需要显示在ui上的3d节点移动到摄像机的视觉范围内
  • 3.创建Sprite用来摄像机渲染出来的显示
  • 4.代码实现
const _colorAttachment = new GFXColorAttachment();
const _depthStencilAttachment = new GFXDepthStencilAttachment();
let renderTex = new RenderTexture();
renderTex.reset({
    width: 500,
    height: 700,
    passInfo: {
        colorAttachments: [_colorAttachment],
        depthStencilAttachment: _depthStencilAttachment,
    }
});

let spriteframe: SpriteFrame = this.camerSprite.spriteFrame;
let sp: SpriteFrame = new SpriteFrame();
sp.reset({
    originalSize: spriteframe.originalSize,
    rect: spriteframe.rect,
    offset: spriteframe.offset,
    isRotate: spriteframe.rotated,
    borderTop: spriteframe.insetTop,
    borderLeft: spriteframe.insetLeft,
    borderBottom: spriteframe.insetBottom,
    borderRight: spriteframe.insetRight,
});

this.camera.targetTexture = renderTex;
sp.texture = renderTex;
this.camerSprite.spriteFrame = sp;

//对比和之前版本的代码,两点调整:
//- 1.SpriteFrame 属性调整
//- 2.renderTex.reset 参数的调整
  • 5.在实现过程中可能会出现,本来只想显示指定的模型,但是会将摄像机的缓冲颜色也显示出来,如图:

    这里菜鸟是将摄像机的ClearColor的透明度直接调为0,

地址

  • 微信公众号:搬砖小菜鸟
  • 扫码关注公众号,发送"3d-in-ui"可获取源码
5赞

好文,我之前做的小游戏一开始用的第二种方法,后来改成第一种了,模型黑我用发光材质处理的,看了你的又学到了个方法。

:sunglasses::sunglasses:

这个非常实用

嗯嗯,在社区看见好几次有人问,研究研究,分享出来大家共同进步

mark mark

这个方式可以显示模型,骨骼动画显示的时候报错,有办法解决吗?

MARK.

mark :wink:

看看看看看看

看看这种

https://gitee.com/yeshao2069/CocosCreatorDemos/tree/v3.0.0/2DDemo/RenderTextureDemoForSkeletalAnimation