今天仔细研究了 Shaowgun 示例中那个金黄色雕像所使用的光照纹理烘焙工具:“Render To Texel Baker”。因为要在移动设备展现比较逼真的光照效果,但是实时使用法线贴图并大量用于场景建筑中,对于移动设备还是有些力不从心。于是原作者写了这个工具,使用法线贴图和多个光源来对模型的贴图进行光照烘焙并保存烘焙结果。

  作者直接读取模型的所有三角形,顶点,uv,法线和切线数据,以及提供的模型法线贴图(最终转换到世界坐标系,计算过程证明了我之前对于tbn矩阵相关计算的理解是正确的),然后针对每个三角形中的每个像素,都通过插值和权重来计算出这个像素的世界坐标位置和世界坐标法线,并分别将每个像素的位置和法线各自存编码储到纹理里面,纹理的大小都和提供的法线贴图相同。最后将这些所有的数据以及模型的主要贴图都赋给材质,运用多个光源和观察者的位置来多次渲染这张主贴图,每次一个光源,每个光源多个观察者位置,但是每个光源的光照强度都已经根据光源个数做了平均,这样最终的渲染结果是各个光源渲染效果的加权平均值。

  其中作者的有些算法比较有意思,比如每个三角形中某个像素的顶点位置如何根据三角形的三个顶点的权重来计算呢?作者根据面积来计算的,对于三角形abc的面积若为s,其中一点p,p点对于顶点a的权重ma为:三角形pbc面积/s,以此类推计算mb,mc,这样点p的位置vp为: a*ma+b*mb+c*mc。我并不知道dx和ogl里对每个像素的位置如何差值计算,是否就是使用的这个算法还要再去查阅资料,不过这个算法很有意思,三角形面积的计算使用的是“海伦公式”。

  对于每个三角形的uv坐标,作者找出u和v方向的最小和最大值,构成一个四边形,然后逐个像素遍历看该像素是否在三角形内才处理,判断是否在三角形内的方法也很简单,对三角形abc,任意一点p,如果向量pa,pb的夹角,pb,pc的夹角,pc,pa的夹角之和为360度,则p点在三角形内部,如果在外部,夹角之和是小于360度的。

  还有作者如何将世界坐标的位置编码到纹理里面也比较有意思,作者找出整个模型的所有顶点中的x,y,z的最大最小值,这样对于任意一点p,就可以作为最大最小值之间对于参数t的差值结果,即:p = slerp(min, max, t); 如此可知 0<= t <= 1,计算出t就可以直接写到纹理中。

  关于接口 void Graphics.Blit(source : Texture, dest : RenderTexture, mat : Material, pass : int = -1),开始始终不明白为何作者使用时第一个参数source使用的null,对于官方的说明:“Blit sets dest to be active render texture, sets source as _MainTex property on the material, and draws a full-screen quad.” 也没怎么看懂,尤其是 _MainTex 和 source 的关系,后来经过反复修改测试明白,source 这个参数不是直接就被拷贝到 dest 中,而是说,如果你填充了 source 参数,那么该接口会把你使用的材质 mat 中的 _MainTex 修改为 source。我将 mat 中的 _MainTex 设置为空,运行后 _MainTex 果然被自动设置为了 source,而当我把 mat 所使用的 shader 中的主纹理 _MainTex 的名称改成随意的名称比如 _MyTex,同时讲纹理设置为空后,运行 Blit,发现 _MyTex 丝毫未动并未被修改为 source,因为 Blit 没有找到 mat 中有名为 _MainTex 的纹理变量,修改失败同时所设置的 source 将无任何效果,所以也就明为了作者代码的含义:Blit(null, dst, mat, -1) 将 source 设置为 null 后该参数无效,mat 中的 _MainTex 不会被修改(其实在编辑器中已经手动指定了一张纹理)。

  对于烘焙所使用的 shader 没什么特别,里面跟一个 Bumped Specular 的 shader 没啥两样。当然你可以自己根据想要的效果扩展或重写。

  烘焙所使用的法线贴图导入格式作者要求是 ARGB32 (选择 Automatic TrueColor),我试验后发现,这个格式仅在编译目标是 PC&Mac 时是这样,我切换到 IOS 下,选择 Automatic TureColor 后,实际的格式变成了 RGBA32。

  最后无意中看到一个关于"_MainTex_ST"的问答帖子

  还有一点:pixel space - (0,0) is lower left.

  作者对于工具的使用建议:

  1.加入尽可能多的光源,同时使用多个观察者位置;

  2.对于烘焙完毕的纹理还可以拿到 PhotoShop 中修理调整;

  3.可以同时烘焙多个不同参数的目标,还可以对不同的烘培结果之间再次烘焙洪培混合,以及运行时动态调整 shader 中的颜色等参数,不断试验以便寻找到满意的结果。

  工具目前存在的问题:

  1.不支持多层 uv 和 阴影;

  2.目前仅包含一个 Bumped Specular 的 shader;

  3.目前仅支持点光源;

  4.有的模型烘焙起来可能需要的时间较长;

  5.烘焙完毕的纹理可能会产生缝隙(尤其是贴在模型上以后比较明显,我后面的例子中会看到)。

  最后附上一张我试验的结果:

  

  左:烘焙前;右:烘焙后

 

Render To Texel Baker的更多相关文章

  1. React.render和reactDom.render的区别

    刚开始学习react.js.发现网上的资料,有些是写着react.render,有些写着reactDom.render.觉得很奇怪就查阅了一下资料.解释如下: 这个是react最新版api,也就是0. ...

  2. XF custom render 各平台实现类

    目前的XF还是非常简陋的,所以存在大量的自定义工作.一般情况下我们只是要需要派生原生的XF控件,然后在各平台下修改其呈现方法. 所以了解每个XF控件在不同平台上呈现使用的控件类是有所必须要的.以下别人 ...

  3. 塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考

    最近在使用 MVC 开发的时候,遇到一个对我来说"奇怪的问题",就是使用 BundleTable 进行 CSS.JS 文件绑定,然后使用 Styles.Render.Scripts ...

  4. ReactJS分析之入口函数render

    前言 在使用React进行构建应用时,我们总会有一个步骤将组建或者虚拟DOM元素渲染到真实的DOM上,将任务交给浏览器,进而进行layout和paint等步骤,这个函数就是React.render() ...

  5. Cesium原理篇:6 Render模块(3: Shader)

    在介绍Renderer的第一篇,我就提到WebGL1.0对应的是OpenGL ES2.0,也就是可编程渲染管线.之所以单独强调这一点,算是为本篇埋下一个伏笔.通过前两篇,我们介绍了VBO和Textur ...

  6. Cesium原理篇:6 Render模块(4: FBO)

    Cesium不仅仅提供了FBO,也就是Framebuffer类,而且整个渲染过程都是在FBO中进行的.FBO,中文就是帧缓冲区,通常都属于高级用法,但其实,如果你了解了它的基本原理后,用起来还是很简单 ...

  7. Cesium原理篇:6 Render模块(5: VAO&RenderState&Command)

    VAO VAO(Vertext Array Object),中文是顶点数组对象.之前在<Buffer>一文中,我们介绍了Cesium如何创建VBO的过程,而VAO可以简单的认为是基于VBO ...

  8. render :template 和 render :parital

    1 .这两个都可以在controller和view中使用,而且好像可以替换,只是用:template,rails不会自动加下划线,用:partial,rails会自动添加下划线.而且规范的做法,:te ...

  9. AngularJs中,如何在render完成之后,执行Js脚本

    AngularJs是Google开源的前端JS框架.使用AngularJs, 我们能够容易地.健壮的开发出类似于Gmail一样的单页Web应用.AngularJs这个新兴的MVC前端框架,具有以下特点 ...

随机推荐

  1. doj常用包

    dojo.raise               抛出一个异常 dojo.errorToString将异常转换为字符串 dojo.render      系统环境对象 dojo.hostenv. ...

  2. 动态库DLL加载方式-静态加载和动态加载

    静态加载: 如果你有a.dll和a.lib,两个文件都有的话可以用静态加载的方式: message函数的声明你应该知道吧,把它的声明和下面的语句写到一个头文件中 #pragma comment(lib ...

  3. Access restriction:The type JPEGCodec is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\rt.jar

    解决方法: Project -> Properties -> libraries, 先remove掉JRE System Library,然后再Add Library重新加入. ===== ...

  4. html5 + css3 + zepto.js实现的微信广告宣传页

    最新学习html5 + css3, 参考微信的一个推广页写出一个实例巩固自己知识,自己已经将原实例打包到自己博客文件当中,但是不知道如何提供下载,如有需要的朋友可以联系我qq309666726

  5. 《转》前端性能优化----yahoo前端性能团队总结的35条黄金定律

    除了自己总结:1. 减少http请求,2.压缩并优化js/css/image 3.尽量静态页面,从简原则 4.代码规范(详见:个人知识体系思维导图) 从yahoo 新学到的: 网页内容 减少http请 ...

  6. 校省选赛第一场A题Cinema题解

    今天是学校省选的第一场比赛,0战绩收工,死死啃着A题来做,偏偏一直WA在TES1. 赛后,才发现,原来要freopen("input.txt","r",stdi ...

  7. vector 与 set区别

    注:本文内容摘自网络,准确性有待验证,现阶段仅供学习参考.尊重作品作者成果,原文链接 :http://blog.csdn.net/wxdcxp/article/details/5279618 首先,v ...

  8. 从外国html5网站上扒来一个鼠标经过的css3 效果,感觉很不错

    鼠标经过的时候,感觉有点像一张纸卷上去的感觉. 下面是代码 <div class="main-container types"> <div class=" ...

  9. 交叉编译tslib1.4

    cross-compiler: arm-linux-gcc V4.2.1 source code: tslib-1.4.tar.gz #tar zxvf tslib-1.4.tar.gz #./aut ...

  10. 转 C#开发微信门户及应用(1)--开始使用微信接口

    微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习下微信的相关开发,也就成为日常计划的重要事情之一了.本系列文章希望从一个循序渐进的角度上,全面介 ...