萌梦动作编辑器设计支持多渲染器的思想



  • 截止现在,萌梦动作编辑器只能支持OpenGL作为默认的渲染器进行渲染。我在和同行的交流过程中了解到,目前他们也在积极地将自己的软件向新型渲染器vulkan靠拢,对于我们做萌梦动作编辑器这款产品来说,支持vulkan的确会带来很多好处的,比如说咱们目前渲染的过程中还会出现一些卡顿,这个也有可能和OpenGL架构相关。如果换做vulkan,那么指令会得到进一步精简,运行速度可能会更快。但是作为这项研究的第一步,我们必须将现有OpenGL的调用从咱们骨骼动画等业务逻辑中剥离出来。形成独立的模块,这样在不同平台上可以选用不同类型的渲染器以便达到更好的效果。

    此外,萌梦动作编辑器面向的用户群是使用MikuMikuDance、MikuMikuMoving、nanoem等等的喜欢三维动画编辑器的初级用户,我们需要做的是积极地对接这部分的用户,满足他们的需求。而其中有一个点就是他们有较大一部分使用的是MikuMikuEffect,也就是制作渲染特效的插件。这个插件呢,是使用微软的HLSL编写的,而HLSL就需要Direct3D(通常是Direct3D 9),这就要求我们软件需要支持Direct3D进行渲染了。这也是我们此次支持多渲染器的目的之一。

    为了达成目的,我们设计了这样一个结构:我们定义的所有三维对象的基类名称叫做Entity,那么Entity采用了PIMPL设计模式(私有实现设计模式),在私有的实现里,我们将其数据的部分和渲染的部分剥离开来。渲染的部分单独写一个基类。这个基类叫做EntityRenderer,这里只负责搜集Entity实例的个数以及做抽象渲染流程。具体的实现呢,我们采用的是Qt的插件思想,插件里与OpenGL相关的类聚合起来,写成一个插件。具体来说,假设我使用OpenGL要渲染Entity,那么在插件里,我会写这样一个类:

    class OpenGLEntityRenderer: public EntityRenderer, protected QOpenGLFunctions
    {
    public:
        virtual void render( void ) { ... }
    };
    

    这样写的好处显而易见:将OpenGL相关的指令隔离到插件中,渲染模块完全不用依赖任何与OpenGL相关的内容。并且通过C++多态性,依然可以采用OpenGL渲染出和以前一样的渲染效果。

    实际操作中,我们还需要让EntityRenderer继承自Renderer接口来获得更抽象一层的方法,在插件中我们使用分布式抽象工厂方法来让渲染器根据需求获得——即传入具体渲染类名称字符串,即可返回相应的渲染器对象实例。有关分布式工厂方法,如果有需要的话,我会单独抽出时间写一篇长文给大家讲解。

    目前这一套方案已经成功地在我写的一个单元测试案例中得以实现。接下来就是推广之,将以前的渲染器都替换代码隔离并且成可以切换的实现方案。
    😝 😝 😝 😝 😝


 

最近的回复

  • @bladesero Blender 在角色建模和渲染这些方面的确比较强。😄

    我们的软件还在发展中呢。
    18da2116-2055-47c1-8317-1ccde17dfcc0-image.png

    阅读更多
  • untitled.jpg figure角色(WIP2).jpg
    TIM截图20190117184210.png
    使用的软件是blender,zbrush和substance painter

    阅读更多
  • 背景:如果需要qml显示循环list,一般是用3个ListView循环交替,实现伪循环,期间逻辑复杂,容易出错,PathView本身自带循环,所以考虑用PathView实现循环

    设计:PathView显示5条数据,按照垂直List一个个排好顺序,由于收尾移动时候会空白穿帮,所以用clip控制显示中间三条数据

    滚动控制:currentIndex,decrementCurrentIndex(),incrementCurrentIndex()

    代码:

    Item{ id: item1 property int myIndex: 0 property int onePageCount: 3 property real oneHeight: 72 property real oneWidth: 580 property int isCurrentListView: 1 //0,1,2 property bool isAdd: true //direction,down=true,up=false property int hightlightIndex: 0 property int currentIndexPathView: 0 //use this Item{ id: itemClip width: item1.oneWidth height: item1.oneHeight*3 clip: true PathView { id: listView1 width: item1.oneWidth model: listModelSpeedWarning delegate: delegeteLine pathItemCount: item1.onePageCount+2 interactive: false path: Path { startX: item1.oneWidth/2 startY: -item1.oneHeight/2 PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*0+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*0+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*1+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*1+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*2+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*2+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*3+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*3+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*4+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*4+item1.oneHeight/2 } } Component.onCompleted: { listView1.currentIndex = -1 } } } }

    问题:windows下测试,按住按键不松手,list滚动会卡住,松手后恢复正常,看来list不能滚动太快

    阅读更多
  • H

    @青山白云 只是为了替换GIF,不过目前已经解决加载问题

    阅读更多

关注我们

微博
QQ群











召唤伊斯特瓦尔