在JMonkeyEngine3.x中实现自己的PBR材质。

事实上,从工作出来到现在,我都没有写过一篇技术文章。所以,写得不好请多关照。

关于为何要在JME3.X引擎中做这件事呢?主要是两个理由:

1.出于爱好。(我并非只专注于java,事实上我研究和做得最多的工作仍然是c/c++。u3d这些)

2.尝试优化移动端PBR,使用一张2D纹理代替6个面cubeMap和cubeMap lod采样。

好吧,不说太多废话。

我使用的是jme3.2.4稳定版。并使用自带的sdk进行场景编辑和材质编辑。

我使用的新的材质定义来编写我的材质。但是也可以很方便的转为旧的材质定义。

关于PBR的定义,实在轮不到我这个后辈来指指点点。这里只简单描述下大概。

实际上很多光照模型都由两部分组成,PBR描述下的材质也不例外,直接光照和间接光照。间接光照部分可以使用很复杂的全局光照技术来实现,大部分PBR材质使用环境纹理映射来粗糙模拟全局光照。

大部分real-time PBR材质使用的BRDF模型,都是cook-torrance

Cook-Torrance BRDFdiffusespecuarl分开:fr=kdflambert+ksfcook−torrance

Diffuse BRDF

可以选择简单的Lambert(Cook-Torrance使用兰伯特光照模型来计算)或Oren-Nayar。我的实现中使用Lambert光照模型:

Specular BRDF

这部分比较复杂,Cook-Torrance Specular BRDF:

fcook−torrance=DFG/4(ωo⋅n)(ωi⋅n)

在我的实现中,各个项依次是:

D项(法线分布函数):

G项(几何函数):

F项(菲涅尔方程):

JME3.x引擎的PBR材质库使用的是ue引擎在2013发布的pdf的计算方式,并且进行一些修改:

可以看到我的实现中各个项跟jme3.x自带的略有不同。

间接光照部分:

实时的间接光照部分在PBR中通常使用IBL的方式来粗糙模拟,当然,也可以通过复杂的全局光照技术实现。

Diffuse-间接光照部分:

没什么太多要做的,计算使用的BRDF模型是一样的,唯一不同的是光照信息从积分纹理中获取。通常卷积cubeMap积分纹理来获取Diffuse部分的间接光照。但对于移动端使用cubeMap作为纹理采样需要渲染6个面,开销稍微有点大:

作为补偿,我使用2D采样来替代:

texture2D( inIrradianceMap,n2uv(iNormal) )。

需要注意的是,由于积分纹理在计算中存储的光照信息远超过0-255,所以需要使用hdr来存储。通常作为渲染的hdr格式是radiance格式(rgbe)。如果光照信息没有正确保存下来,看起来会比正常的pbr暗。

Specular-间接光照部分

这部分在常规做法中分为两个部分,根据粗糙度计算预计分纹理和lut查表来完成,C-T Specular PBR IBL:

Lo(p,ωo)=∫Ω(kdcπ+ksDFG/4(ωo⋅n)(ωi⋅n))Li(p,ωi)n⋅ωidωi

Epic Games将这个公式拆为两个部分,这样可以单独进行计算:

Lo(p,ωo) = ∫ΩLi(p,ωi)dωi∗∫Ωfr(p,ωi,ωo)n⋅ωidωi

 ∫ΩLi(p,ωi)dωi用预过滤纹理实现,通常使用粗糙度来生成lod cubeMap使用。

∫Ωfr(p,ωi,ωo)n⋅ωid是镜面积分部分,Epic Games的做法是使用存储了用变化的粗糙度来预计算每一个法线和光源方向组合的BRDF的值来生成一张积分纹理用作查表。但也有直接使用拟合方程实现这个部分。

预过滤纹理:

LUT:

同样,我使用2D积分纹理代替Lod cubeMap,这样在移动端只存储一张纹理。并且使用拟合方程实现镜面积分部分。jme3.x同时支持使用lut查表和使用拟合方程。

2D预过滤纹理:

拟合方程:

完整的PBR:

jme3.x渲染:


我的实现:


由于积分纹理我在gpu计算然后读回cpu生成hdr,这个过程会把0-255的光照信息丢失,所以看起来间接光照部分比jme3.x的暗淡。当然这也是可以改进的。

吐槽:

1.本来我以为jme3.x的sdk不能在编辑阶段预览完整的pbr。其实是可以的(我就在想怎么可能连这个都不行。。)

2.目前我的实现除了有两个地方需要改善下就可以投入移动端使用,并且加入了骨骼动画,实例化渲染的支持。

3.jme3编辑器中可以编写中文注释的shader,但是在代码中运行会报错不识别符号导致shader编译失败。所以我把中文注释去掉了。。

需要改善的地方:

1.积分纹理的生成改善。

2.因为不使用lod cubeMap,所以模拟lod采样在低精度下会有误差,渲染出来就是有交缝点。

3.由于我在改善积分纹理生成部分,这部分的工程我是做成了一个工具。因为还有可以改善的地方,所以暂时不放出来。

由于我github账号已注销,所以源码放到了码云...

地址:https://gitee.com/JoyClm/SimpleMatTest.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容