Render To Texel Baker
今天仔细研究了 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的更多相关文章
- React.render和reactDom.render的区别
刚开始学习react.js.发现网上的资料,有些是写着react.render,有些写着reactDom.render.觉得很奇怪就查阅了一下资料.解释如下: 这个是react最新版api,也就是0. ...
- XF custom render 各平台实现类
目前的XF还是非常简陋的,所以存在大量的自定义工作.一般情况下我们只是要需要派生原生的XF控件,然后在各平台下修改其呈现方法. 所以了解每个XF控件在不同平台上呈现使用的控件类是有所必须要的.以下别人 ...
- 塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考
最近在使用 MVC 开发的时候,遇到一个对我来说"奇怪的问题",就是使用 BundleTable 进行 CSS.JS 文件绑定,然后使用 Styles.Render.Scripts ...
- ReactJS分析之入口函数render
前言 在使用React进行构建应用时,我们总会有一个步骤将组建或者虚拟DOM元素渲染到真实的DOM上,将任务交给浏览器,进而进行layout和paint等步骤,这个函数就是React.render() ...
- Cesium原理篇:6 Render模块(3: Shader)
在介绍Renderer的第一篇,我就提到WebGL1.0对应的是OpenGL ES2.0,也就是可编程渲染管线.之所以单独强调这一点,算是为本篇埋下一个伏笔.通过前两篇,我们介绍了VBO和Textur ...
- Cesium原理篇:6 Render模块(4: FBO)
Cesium不仅仅提供了FBO,也就是Framebuffer类,而且整个渲染过程都是在FBO中进行的.FBO,中文就是帧缓冲区,通常都属于高级用法,但其实,如果你了解了它的基本原理后,用起来还是很简单 ...
- Cesium原理篇:6 Render模块(5: VAO&RenderState&Command)
VAO VAO(Vertext Array Object),中文是顶点数组对象.之前在<Buffer>一文中,我们介绍了Cesium如何创建VBO的过程,而VAO可以简单的认为是基于VBO ...
- render :template 和 render :parital
1 .这两个都可以在controller和view中使用,而且好像可以替换,只是用:template,rails不会自动加下划线,用:partial,rails会自动添加下划线.而且规范的做法,:te ...
- AngularJs中,如何在render完成之后,执行Js脚本
AngularJs是Google开源的前端JS框架.使用AngularJs, 我们能够容易地.健壮的开发出类似于Gmail一样的单页Web应用.AngularJs这个新兴的MVC前端框架,具有以下特点 ...
随机推荐
- 基础之 window-self-top-opener
今天我都在怀疑,很多项目还用不用iframe这个框架做页面布局. 如果你有兴趣想告诉我,请给我留言. 一. 说明 注:这里top和window.top等价,window是可以省略的,有得情况下不允许省 ...
- Sql解锁 数据库死锁检测
USE [DataBaseName]GO/****** Object: StoredProcedure [dbo].[sp_check_deadlock] Script Date: 07/04 ...
- A题笔记(2)
No. 1505 文件读相关 #include <fstream> #include <sstream> <fstream>支持文件的IO <sstream& ...
- 3.SQL*Plus命令
3.1SQL*Plus与数据库的交互 主要用来数据库查询和数据处理的工具. 3.2SQL*Plus运行环境设置 3.2.1SET命令概述 用户可以使用SET命令设置SQL*Plus的运行环境,SET命 ...
- Django练习项目之搭建博客
背景:自从今年回家过年后,来到公司给我转了试用,我的学习效率感觉不如从前,而且刚步入社会我总是想要怎么想明白想清楚一些事,这通常会花掉,消耗我大量的精力,因为我想把我的生活管理规划好了,而在it技术学 ...
- [jQuery] Cannot read property ‘msie’ of undefined错误的解决方法
最近把一个项目的jQuery升级到最新版,发现有些页面报错Cannot read property ‘msie’ of undefined.上jQuery网站上搜了一下,原因是$.browser这个a ...
- CSS3圆角(border-radius)
CSS3中的border-radius支持IE9+,chrome,firefox 2.3+,以及safari3.2+浏览器. border-radius可直接使用,无需加前缀(注意:firefox13 ...
- 关于DateTime和String转换的容易犯得错误
字符串转换成DateTime 在开发中,常常会有DataTime类型和String类型的互相转换的要求,比较常用的写法是var date = Convert.ToDateTime("2012 ...
- js 默认的参数、可变的参数、变量作用域
可以通过arguments对象来实现可变的参数 在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们. arguments是一个数组对象,可以通过下标来实别参数的位置 ...
- uboot移植之环境变量在NandFlash
一.概述 u-boot环境变量可以设置在Norflash上,也可以在NandFlash上. 倘若环境变量在NorFlash上,再假设S3C2440从NorFlash启动,是能正确从NorFlash上读 ...