导航

material自动生成

Posted on 2008-07-31 11:15  icecoffee  阅读(1088)  评论(3编辑  收藏  举报

ogre手工编写材质脚本和shader太麻烦。而且他自带的material能处理的光照数量都是写死的。ogre处理的方式是这样的:比如说一个shader支持4个light
如果照在物体上的光不到四个就都传进去,其余的添上0。超过4个就只处理4个。还有一种方式就是,一个light一个pass最后加在一起。。。。
当然你想控制使用哪个灯光可以用moveobjectlistener控制。。还是不够专业。
而且就算为一个模型不同的光影状态写好了n个shader,在运行的时候怎么选择shader也是麻烦。
(哦,对了,上面说的全是使用shader的情况,使用固定管道的不再讨论之列)
想了又想,还是搞一个material的自动生成的东西吧,谁让我这么懒呢。
本来想重头写材质的系统,看了一下ogre的材质的接口,提供了足够多的东西,在ogre的材质上面直接写这一套东西应该没有问题。我感觉ogre虽然在功能上不
是最强的,但是接口上绝对是最方便的。方便扩展。方便使用它的任何功能。
首先想到的就是生成shader。
最开始想到的方案是这样的,写一个n长的shader。然后把每种情况用#define分开,在运行的时候选择不同的#define编译。仔细想一下,这和直接写无数个
shader没有什么区别啊,而且也不够灵活。比如用户要使用两张贴图相加的结果作为diffuse就麻烦了。
后来又想到几年前看过的一个东西,shaderworks不知道现在还有谁记得。。他把每个函数最为一个节点。把一个函数的输出和另一个函数的输入连在一起,这样
一个shader了逻辑关系就联成了一张图,再转化成shader的code再build就ok了。这样美术用编辑器在想选择的效果上面连一连线,然后引擎内部再加上光照的节
点,有几种情况就生成几个shader。哈哈,所有能想到的情况都解决了。最后我的material系统成型就是使用的这个思路。
当然在编写的时候遇到了很多细节,比如怎么把shader分类缓存,遇到同样的shader直接取出来,不再生成。
还有,shader不能超过多少个寄存器,超过了怎么split成2个shader。
还有,是生成hl还是asm,我选择的当然是hl,因为hl在build的时候api会做很多的优化,因为自动生成的东西难免会有垃圾在里面。
下面是材质系统在运行时的效果。

默认的没有任何参数,场景有两个光照。

使用一张贴图作为diffuse

加上一个normal

加上一个贴图作为自发光

再来一张贴图作为反射的强度