今天仔细研究了 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. WCF学习笔记一(概述)

    WCF  Windows Communication Foundation 分布式通信框架.WCF是对现有分布式通信技术的整合.是各种分布式计算的集大成者.主要整合技术如下图: WCF的服务不能孤立的 ...

  2. (ASP页面查询等待提示效果)GridViewなどで検索中に「処理中メッセージ」を表示する方法(※他の長い時間処理も参照できる)

    原博客 http://ino1970.blog119.fc2.com/blog-entry-163.html GridViewなどで検索中に「処理中メッセージ」を表示する方法 「GridViewなどで ...

  3. java的集合框架之一

    java是一套很成熟的东西,很多商用的东西都喜欢用它,用的人多,稳定.不过一般也不怎么说起它,因为太常见了,私下里说,写java应用层得就像农民工,每一处都是搭积木,根据设计师的东西如何优雅地搭好积木 ...

  4. 利用SQL进行推理

    数据库环境:SQL SERVER 2008R2 有如下需求: Baker, Cooper, Fletcher, Miller and Smith住在一座房子的不同楼层.Baker 不住顶层.Coope ...

  5. Command 模式

    Command 模式通过将请求封装到一个对象(Command)中,并将请求的接受者存放具体的 ConcreteCommand 类中(Receiver)中,从而实现调用操作的对象和操作的具体实现 者之间 ...

  6. Linux系统性能分析工具

    1.  uptime 2.  htop 3. mpstat 4 . iostat 5. dstat 6. netstat 7. tcpdump 8. sar

  7. 按钮效果 css

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  8. shell 1变量注意点

    定义变量时,变量名不加美元符号($),如: variableName="value" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样. 删除变量 使用 un ...

  9. Ubuntu 误改/etc/sudoers 文件权限

    添加用户时不小心修改了/etc/sudoers 权限,结果不能sudo了,Ubuntu默认关闭root帐户,结果傻X了,无法改回了. 方法如下: 1.重启机器,开机按ESC,进入恢复模式 2.此时,磁 ...

  10. iOS 开发常用的一些工具

    http://www.itjhwd.com/ios-tool/ 通用工具 HomeBrew:OS X上非常出色的包管理工具. 源码控制 Git:分布式版本控制系统和源码管理系统,其优点是:快和简单易用 ...