博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
低耦合度高效3d游戏渲染系统构建方案乱弹
阅读量:4614 次
发布时间:2019-06-09

本文共 3131 字,大约阅读时间需要 10 分钟。

3d 游戏系统的渲染机制是复杂的,这里只是以简洁的方式基于stage3d描述个人对于3d游戏渲染系统设计的看法和实践

游戏系统的性能在游戏系统或产品中占据绝对主导地位,我们的游戏相关的产品除了关注其可玩性,画面,更关注其性能。性能也可以说是前两者得以全面发挥的基石。游戏产品和别的软件产品的一个明显的区别是运算量大,也就是对同一硬件或者环境下,同一时间段内其能量消耗更大,所以我们要尽可能的提升程序本身的性能,实际就是提升能量利用率(好吧,这是另外一个话题,以后再说吧)。
提升性能的法则之一,就是尽量少的尽量有效的使用资源,这里讲的资源包含:系统外部静态资源(A),逻辑对象(B),内存/显存资源(C),这三大部分。这里B是关联和管理A与C的核心,也是我们程序系统直接"操作使用"的部分。B这个逻辑对象的产生,运行(运算),销毁,都会消耗能量,也就是会"消耗"系统的性能, 而且这个过程也是直接影响了A和C的性能。所以一个高效的渲染系统,必然有一个高效的程序系统来高效的运作逻辑对象的生命周期。因此,总的来讲,有一个大家都熟悉的总原则:能不创建就不创建,能不运行就不运行,能不销毁就不销毁。
但是,但是,在我们的系统运行中,怎么会没有很多的创建和销毁呢?更不可能没有大量的运行!
但是,但是,我们还得解决问题,构建力所能及的高效系统。
所以,低耦合度便是一种解决问题的策略。
低耦合度是让各个子系统,模块,对象,资源之间合理的降低耦合度,甚至如果有需要,在某些地方尽量低的降低耦合度。
合理的低耦合度可以达到的作用是:
    1.尽量在需要的时候才创建对应的属性,对象,资源等
    2.尽量在需要的时候才运行逻辑对象相关的算法
    3.尽量在需要的时候才销毁相关的对象活资源
做好上面这三条的目的是: 能不创建就不创建,能不运行就不运行,能不销毁就不销毁。
哈哈哈,似乎说了废话。但是你的系统是不是做到了这个设计目标?
镜头转到 stage3d 身上.
用stage3d as3 来设计渲染引擎有无数方式,现存的相关引擎也一大把。在这里就假定从无到有的我在来一遍。
个人在这个系统建立的时候把这个系统所要实现的东西分为:
    1.属性集合,例如各种将要传递给GPU的buffer,几何数据,动画,色彩,灯光等对象,我认为他们都是一个基本的数据集合,为的是向shader传递参数。这些对象不会和其他资源有直接的关联,这些对象大部分都被显示对象持有,作为显示对象的属性而存在。
    2.显示对象,显示对象是被渲染逻辑run()和render()的对象,持有属性集合(但是属性集合不会持有显示对象),显示对象会作为参数传递给shader。
    3.shader,我这里讲的shader是stage3d中的用于将各种必须的数据传递给显卡的管理对象,这类对象是渲染的关键。这类对象绝大部分情况下只从显示对象获取纯粹的数据,小部分情况是自带的数据例如某个shader节点会带有贴图数据,当然shader自带的数据只会存在于 shader 的某几个节点上。这里一个完整的shader是由若干个 shader node 组合而成的, 统一组合的shader只会构建一次AGAL代码, 每一个 shader node 自己会决定是否需要使用数据,使用什么样的数据。
以上是大体的设计规划。
在这个规划里,属性集可以轻易共享或组合,也可以轻易的和目标对象脱离。
在循环执行的流程当中,只执行必要的部分,其余的部分只会在创建或销毁的过程执行各一遍。
这里以漫反射灯光为例子做一个简要的介绍和展示,来说明上述的规划。
在漫反射的情况下,灯光大体分为:
    1.定向光(平行光)
    2.光强不会发生变化作用距离无限远的点光源
    3.光强会发生变化且有作用半径的点光源
    4.环境光
在我的灯光系统中,若干个不同类型的灯光组成一个灯光组,这个灯光组表示了这个显示对象被哪些灯光共同作用,在一个灯光组中只有一个环境光灯光对象。
以下代码创建一个 由三个灯光和一个环境光组成的灯光组 LightGroup对象:
        public static function createLightGroupB():LightGroup {
            //
            var groups:LightGroup = new LightGroup();
            // 初始化环境光,为亮度很低的蓝色
            groups.ambient.color.setColorEle(0.0, 0.0, 0.3);
            groups.ambient.strength = 1.0;
            // 光强会发生变化且有作用半径的点光源
            var lightSpot:SpotLight = null;
            lightSpot = new SpotLight();
            lightSpot.radius = 300;
            lightSpot.strength = 8;
            lightSpot.color.setColorEle(0.5,0,0);
            lightSpot.setPosByXYZ(55,-30,55);
            lightSpot.update();
            groups.addLight(lightSpot);
            // 光强会发生变化且有作用半径的点光源
            lightSpot = new SpotLight();
            lightSpot.radius = 35;
            lightSpot.strength = 4;
            lightSpot.color.setColorEle(0.0,0.5,0);
            lightSpot.setPosByXYZ(-55,-30,-55);
            lightSpot.update();
            groups.addLight(lightSpot);
            // 平行光
            var lightDirec:DirecLight = null;
            lightDirec = new DirecLight();
            lightDirec.strength = 0.5;
            lightDirec.setDirecByEndXYZ(100, 100, 100);
            lightDirec.color.setRGBFromUint(0xff00ff);
            lightDirec.update();
            groups.addLight(lightDirec);
            groups.update();
            return groups;
        }
以下代码是一个显示对象使用上面创建的灯光组:
        // 创建一个薄板(高度很小的盒子)
        var cubeM:Cube = createACube(1, 100, "test_cube");
        cubeM.lightGroup = createLightGroupB();
        // getRandTex()函数的作用是随机获取一张贴图
        cubeM.material = ShaderBuilder.createMaterial(getRandTex(), true);
        cubeM.sy = 0.2;
        EFRenderLayer.addToRoleLayer(cubeM);
请见flash示例(加载贴图可能会有点慢):

 

    在这个示例中 中间不动的薄板 就是使用上面创建的灯光组
    其他的显示对象包括天空盒使用的都是随机产生的10个点光源和一个环境光组成的一个灯光组
    如果看不合适请刷新页面, 每次刷新页面会看到不同的贴图效果
    flash支持鼠标左键点击拖动和滚轮操作
    此文是抛砖引玉, 期待更多的系统设计思想或规划,敬请多喷。

转载于:https://www.cnblogs.com/vilyLei/articles/4086636.html

你可能感兴趣的文章
pythonchallenge闯关 第13题
查看>>
个人介绍
查看>>
使用python动态特性时,让pycharm自动补全
查看>>
MySQL数据库免安装版配置
查看>>
你必知必会的SQL面试题
查看>>
html5 Canvas绘制时钟以及绘制运动的圆
查看>>
云推送注意(MSDN链接)
查看>>
Metro Style app :浏览器扩展
查看>>
linux的kernel是怎样工作的(TI_DM36X_ARM系统)(1)
查看>>
[luogu4310] 绝世好题 (递推)
查看>>
[luogu3203 HNOI2010] 弹飞绵羊 (分块)
查看>>
mui搜索框 搜索点击事件
查看>>
2016012003+陈琦+散列函数的应用及其安全性
查看>>
Android 状态栏通知Notification、NotificationManager详解
查看>>
UIApplicationDelegate协议
查看>>
Jmeter测试dubbo接口填坑
查看>>
[zz]GDB调试精粹及使用实例
查看>>
数据库的创建和删除
查看>>
最简单的三层实例【插入据
查看>>
设计模式学习笔记——Prototype原型模式
查看>>