Material Editor 01

正文


至少,目前,工程论文想要做一个Material Editor。

当然,对于别人商用Engine的Editor只有膜拜的份,也不指望咱这小身板子能搞出一个那么厉害的东西,不过至少模仿一下吧。

大概看了一下Robert L. Cook的那篇《Shade Tree》,结合曾经对RenderMonkey为数不多的使用以及“只见过猪跑”的Editor,大致有了一些认识,这里先记下来。

暂且不说各种Shader效果,这些东西准备最终定下来之后逐步学习,大致浏览了一下相关资料,内容还是很多的,特大一壶,以至于我有点担心能否喝的完……

这一篇不会很长,只说明一下Shade Tree到底是个什么东西。

Shade Tree

还是先上一张图,看着图好说话,该图片展示的是U3D的Strumpy Shader Editor:

U3D

先来说明一下图表示的意义:

每一个方框框代表一个“过程”节点,框的右边是输入,左边是输出,例如图中的 TexCUBE 节点,这个过程接收一个名为 Sampler 与 Normal 的参数,输出两个颜色 RGBA 和 A。(这里的输入输出原来左右写反了,原谅一下左撇子)

Master部分是最终结果,基本每个Shader都会有。

其实我个人更倾向于 TexCUBE 接受了两个“过程”作为参数,而并非只是两个运算结果,因为Sampler可以有2D,3D,Cube等多种类型;而Normal,则根据情况可以有Reflection,Refraction等类型;而对于一个Surafec来讲,法线作为其自身属性,单独分离出去给其他的“过程”并非一个好的方案。

我对上面的整个过程的理解如下(当然有可能是错误的,因为图片是随意找的……):

使用一个 SimpleWorldReflection 来计算反射(个人感觉应该是折射),纹理采样使用Cube采样来对Surface进行处理,得到Cube纹理的运算结果,然后这个运算结果呗传入到Master中,与Albedo和Alpha量来得到最终的结果。

追加:我找到了与这张图片相关的描述:第966楼。不想点链接的可以看下面,我始终以为Reflection有点不太合适,不过CG上要达到一个看起来一样或者差别很小的效果可以有多种手段,所以不必在此钻牛角,当然,我自己Shader玩的不好也有很大原因。

What you want to do (to start with) is sample the cube from the reflection vector of the
surface using the ‘Vertex Reflection’ node. In this example I have also made the alpha be
based on an alpha from a texture and set the blend mode to be srcalpha /
oneminussourcealpha (so you can configure the alpha from the texture), and also given the
windows a ‘blue’ hint in the albedo. It’s nothing amazing, but it’s a decent start for
some glass. You will need to set the queue to transparent if you want to use this shader
also.

如果把上面图中的Flow换个方式:

U3D Simple

再来看看《Shade Tree》中的图:

Shade tree for copper

是不是很相似?

Cook文中的图看起来更像是编译原理中的语法树,但其实是无妨的:一个的N元operation本身就可以抽象为一个接受N个参数的processor。

万幸自己最终还是选修了编译,虽然学的不算好,理论的东西终究没剩下多少,都还回去了。本科专业没这门课导致我很长时间对很多东西理解困难,包括这里的Shade Tree。

求解final color的过程实际上就是一个bottom-up的过程,这就不用多做解释了。

基本上Shade Tree的本质就是这些了,当然对于具体的效果,比如光照,大气,雾,阴影等效果需要具体的工程实现,这些会随着自己的逐渐深入慢慢写出来。

实现?

实现倒是有那么一点点的小想法,但总感觉不太对,后面要找点相关资料才行,先说说想法吧:

首先都要将一些基本的过程给拆开,成为比如前面的Reflection等一个个单独的单元,对于这些单独的单元有两种方式组合起来:

  • shade编译之后有链接的步骤,那么可以首先将需要的各个单元编译好,然后在编辑结束后将对应的单元连接起来。但是分的太细可能会导致片元过多,不太好。

  • 直接在编辑结束的时候生成一个大的Shader进行编译链接。不过这种方式可能会出现指令条数的超出限制。新的硬件不太清楚,但旧硬件是一定会出问题的。

或者将两者折中一下?比如所有的Sampler可以放到一个文件中编译,最后作为一个库连接过去。

结束


话说最近的一次写Shader代码都快一年了,况且本来就一般般……不过还是先笔记想法慢慢记:不怕慢差,就怕不干嘛。