下面举例说明了如何在直接使用 .mi 格式并使用分层着色器时进行分层。场景设置为棋盘格环境下的小玩具马,使用两个 mia_portal_light 作为“灯光卡”来照明。建议将具有物理真实性的灯光与分层着色器配合使用,而且在该场景下,入口灯光是一个很好的工具。
还请确保使用正确的线性颜色空间。此处的图像使用 2.2 gamma 进行校正,以便可以在标准计算机显示器上正常显示,并已通过 mia_exposure_photographic 进行色调映射。
下面是我们的测试场景,一开始使用的是蓝色染色的 mia_material
shader "mia" "mia_material" (
"diffuse" 0.1 0.1 1.0,
"reflectivity" 1.0,
"refr_ior" 1.4,
"brdf_fresnel" on,
"mode" 2 # Use all lights
)
material "HorseMaterial"
= "mia"
shadow = "mia"
photon = "mia"
end material
渲染效果如下所示:
现在,我们要使用分层着色器替换该 mia_material,首先构建一个相似的外观,然后做其他进一步的操作。
首先,我们创建最小节点集以提供简单的漫反射,节点集内包括:mila_material 节点、mila_layer 和 mila_diffuse_reflection:
# A default diffuse shader
shader "diffuse1" "mila_diffuse_reflection" ()
# Layers a single layer referring to our "diffuse1" shader above:
shader "my_layers1" "mila_layer" (
"layers" [
{
"shader" "diffuse1", # Our diffuse shader
"weight" 1, # Layer weight is 100% ...
"weight_tint" 1 1 1, # ...and weight tint is "white"
"on" on # ...and "on"
}
]
)
# The root node. Right now only accepts the layers above, and does nothing else
shader "root_node" "mila_material" (
"shader" "my_layers1"
)
# The material
material "HorseMaterial"
= "root_node"
shadow = "root_node"
photon = "root_node"
end material
渲染效果如下所示 - 漫反射的白色玩具马:
shader "diffuse1" "mila_diffuse_reflection" (
"tint" 0.1 0.1 1.0, # Added a color to our diffuse node
)
好的,现在我们需要反射率。如果复制层,但只是引用反射层,将会发生什么?
shader "reflection1" "mila_specular_reflection" () shader "diffuse1" "mila_diffuse_reflection" ( "tint" 0.1 0.1 1.0, # Added a color to our diffuse node ) shader "my_layers1" "mila_layer" ( "layers" [ { "shader" "reflection1", # Our new reflection shader "weight" 1, # Layer weight is 100% ... "weight_tint" 1 1 1, # ...and weight tint is "white" "on" on # ...and "on" }, { "shader" "diffuse1", # Our old diffuse shader "weight" 1, # (same as before) "weight_tint" 1 1 1, "on" on } ] )
看,这样就变成了完全反射!为什么?
这是因为我们层节点的 use_directional_weight 设置为默认值(关)并使用简单的权重层;mila_layer 着色器自上而下作用于各层,并且指定权重,使其余的权重(100% 减去覆盖层权重)传播到下面的层。由于我们的反射层是 100%,因此没有为下面的漫反射层剩下权重 (100% - 100% = 0%)。
如果我们将反射层权重设置为 50%,则顶层将获得 50% 的权重,下一层也获得 50% 的权重(即全部剩余的 50%):
"layers" [
{
"shader" "reflection1",
"weight" 0.5, # Changed weight to 0.5
"weight_tint" 1 1 1,
"on" on
},
...
现在我们将两个层按 50/50 的比例混合,由于顶层设置为 50%,剩下了 50%,剩下的这 50% 与下面的层的权重相乘(在本例中,仅指 100% 漫反射层的权重)。
实现 50/50 混合的另一种方法是用 mila_mix 替换 mila_layer。例如,将两个层上的权重设置回 100%,则混合的默认设置将为规格化而不是钳制。将两个权重设置为 1 会导致总和为 200%。规格化将把所有层上的权重下调一半(100%/200%),将每个层上使用的权重减少为 50%。这样渲染的效果与上述图像完全相同。
但是,由于我们最终要模拟涂层 - 就像 mia_material 所执行的操作一样,因此我们将使用 mila_layer,但现在启用“use_directional_weight”。我们将其设置如下:
"layers" [
{
"shader" "reflection1",
"weight" 1.0, # Returned to 1.0
"weight_tint" 1 1 1,
"use_directional_weight" on,
"directional_weight_mode" 0, # Turn on fresnel reflectivity
"ior" 1.4, # The fresnel index of refraction
"on" on
},
...
结果
……并且我们实际上已在某种程度上实现了与 mia_material 相同的效果。
让我们在 mia_material 无法遵循的场景中继续研究这一问题。
首先使对象更具“金属”质感,操作如下:
首先将反射着色器从默认值更改为:
shader "reflection1" "mila_glossy_reflection" (
"tint" 0.1 0.1 1.0, # Same as diffuse color
"roughness" 0.6" # Raise the roughness
)
然后更改层应用方式:
"layers" [
{
"shader" "reflection1",
"weight" 1.0,
"weight_tint" 1 1 1,
"use_directional_weight" on,
"directional_weight_mode" 1, # Switch to custom curve
"normal_reflectivity" 0.4, # Facing reflectivity
"grazing_reflectivity" 1.0, # Pretty much always 1.0,
"exponent" 5.0, # Pretty much always 5.0
"on" on
},
...
将得出以下渲染:
仍然没有 mia_material 无法实现的效果……但这只是金属光泽材质。如果我们要制作车漆呢?那么我们需要在顶层加上一层透明涂层。使用分层着色器……这项操作很琐碎。
我们来添加另一个反射着色器:只需将其堆在层上面即可:
# A default reflection shader shader "reflection1_coat" "mila_specular_reflection" () shader "reflection1" "mila_glossy_reflection" ( "tint" 0.1 0.1 1.0, "roughness" 0.6 ) shader "diffuse1" "mila_diffuse_reflection" ( "tint" 0.1 0.1 1.0, ) shader "my_layers1" "mila_layer" ( "layers" [ { "shader" "reflection1_coat", "weight" 1, "weight_tint" 1 1 1, "use_directional_weight" on, "directional_weight_mode" 0, "ior" 1.4, "on" off }, { "shader" "reflection1", "weight" 1.0, "weight_tint" 1 1 1, "use_directional_weight" on, "directional_weight_mode" 1, "normal_reflectivity" 0.4, "grazing_reflectivity" 1.0, "exponent" 5.0, "on" on }, { "shader" "diffuse1", "weight" 1, "weight_tint" 1 1 1, "on" on } ] )
获得的效果如下:
我们基本上重新制作了车漆。彩色漫反射层加上彩色光泽层,并且顶层有一个反射涂层。
再添加一个反射率层以使涂层层展现额外的光彩效果非常简单:
# Add another glossy shader shader "reflection1_coat2" "mila_glossy_reflection" ( "roughness" 0.2 ) ... "layers" [ { # Add it as another fresnel-weighted layer "shader" "reflection1_coat2", "weight" 1, "weight_tint" 1 1 1, "use_directional_weight" on, "directional_weight_mode" 0, "ior" 1.4, "on" on }, { ...
此效果略有不同,会在高光周围出现额外的光晕。
shader "top_material_diffuse" "mila_diffuse_reflection" ( "tint" 0.3 0.3 0.3 ) ... "layers" [ { "shader" "top_material_diffuse", "weight" 1.0, "weight_tint" = "noise_mask", # some texture mask "use_directional_weight" off, "on" on }, { ...
这使我们得到以下效果:
请注意,这会提高渲染速度 - 分层着色器足够智能,可以仅在只有漫反射灰色可见的点上执行漫反射灰色着色。如果材质已与简单的倍增和添加节点进行了最基本的混合,就无法实现上述效果了。
如果我们还有一个与遮罩纹理匹配的凹凸贴图,那么我们可以按照正常方式为灰色漫反射层应用此贴图,如下所示:
"layers" [
{
"shader" "top_material_diffuse",
"bump" = "noise_bump", # Some matching bump map
"weight" 1.0,
"weight_tint" = "noise_mask",
"use_directional_weight" off,
"on" on
},
{
...
现在对象上看起来像有灰泥。我们来试着使它看起来更像粘粘的灰色液体,实现方式如下:在灰色层上添加菲涅尔反射层;仅使用菲涅尔反射层,重用相同的遮罩和凹凸贴图:
# A default reflection shader shader "top_material_coat" "mila_specular_reflection" () ... "layers" [ { "shader" "top_material_coat", "bump" = "noise_bump", # Same bump map "weight" 1, "weight_tint" = "noise_mask", # Same mask "use_directional_weight" on, "directional_weight_mode" 0, "ior" 1.4, "on" on }, { ...
看!- 灰色的粘液:
当然,通过将漫反射顶层的颜色更改为红色,从而减小其权重,可以将它更改为草莓酱,效果可能如下:
shader "top_material_diffuse" "mila_diffuse_reflection" (
"tint" 0.2 0.02 0.02
)
...
...
{
"shader" "top_material_diffuse",
"bump" = "noise_bump",
"weight" 0.5,
"weight_tint" = "noise_mask",
"use_directional_weight" off,
"on" on
},
...
此更改会产生以下渲染:
请务必了解,mila_* 分层是逻辑分层,而不是物理分层,这意味着要显示更多的基础层,必须减小覆盖层的权重。不应使层本身透明。否则将会看到对象内部,而不会看到基础层!
如果我们对这一点进行测试,简单地将漫反射层换成默认透明度着色器,我们将看到以下效果:
shader "some_transparency" "mila_transparency" () ... ... { "shader" "some_transparency", # Swapped out diffuse for transparency "bump" = "noise_bump", "weight" 1.0, "weight_tint" = "noise_mask", "use_directional_weight" off, "on" on }, ...
……将得到以下效果:
请注意看它多么像玻璃,并且金属质感蓝漆部分仅呈斑点样式显示。这是因为透明度层在逻辑上位于蓝漆层之上,档期权重较高时,就会优先于蓝色层。
例如,这通常可以用作裁切透明度的功能。请注意,这与可见性的裁切不同。由于我们将在裁切斑点顶部看到薄玻璃脚架,因此我们仍将模拟几乎不可见的模型。
但是,mila_material 不具有材质的可见性输入,无法模拟对象可见性。换句话说,可以使用裁切不透明度贴图以控制是否应将此视为对象点击。通常卡片不透明度同样适用于树叶。深度缓冲区以及附加颜色窗口中的蒙版颜色也将正确写出。以下图像显示了差异。
shader "some_transparency" "mila_transparency" () ... ... { "shader" "top_material_coat", "bump" = "noise_bump", "weight" 1, "weight_tint" = "noise_mask", # Same mask "use_directional_weight" on, "directional_weight_mode" 0, "ior" 1.4, "on" off, # Turn off top coat ... "shader" "some_transparency" "bump" = "noise_bump", "weight" 1.0, "weight_tint" = "noise_mask", "use_directional_weight" off, "on" off, # Turn off transparency }, ... shader "root_node" "mila_material" ( "shader" "my_layers1", "visibility" = "inverted_noise_mask" #opacity rather than transparency )
到目前为止,我们使用了一个大层节点,只是堆叠所有对象。有时,使用多个层节点更为简单方便。比如,如果我们返回“蓝漆上的灰泥,从上面……
……它当前创建为以下一系列层(从上到下):
如果需要,我们可以将其分割为两个层节点,用于构建混合“灰泥”材质和“蓝漆”材质的第三个层节点。这将使组织更具逻辑性,并且您只需要应用遮罩和凹凸一次,而无需在多个层上应用。
下面是以层次方式制作的材质的完整列表:
# This is the complete "gray goop" material
shader "top_material_coat" "mila_specular_reflection" ()
shader "top_material_diffuse" "mila_diffuse_reflection" ( "tint" 0.3 0.3 0.3 )
shader "top_layers" "mila_layer" (
"layers" [
{
"shader" "top_material_coat",
"weight" 1,
"weight_tint" 1 1 1,
"use_directional_weight" on, "directional_weight_mode" 0,
"ior" 1.4,
"on" on
},
{
"shader" "top_material_diffuse",
"weight" 1.0,
"weight_tint" 1 1 1,
"use_directional_weight" off,
"on" on
}
]
)
# This is the complete "blue paint" material
shader "reflection1_coat2" "mila_glossy_reflection" ( "roughness" 0.4 )
shader "reflection1_coat" "mila_specular_reflection" ()
shader "reflection1" "mila_glossy_reflection" ( "tint" 0.1 0.1 1.0, "roughness" 0.6 )
shader "diffuse1" "mila_diffuse_reflection" ( "tint" 0.1 0.01 1.0 )
shader "paint_layers1" "mila_layer" (
"layers" [
{
"shader" "reflection1_coat2",
"weight" 1,
"weight_tint" 1 1 1,
"use_directional_weight" on,
"directional_weight_mode" 0,
"ior" 1.4,
"on" on
},
{
"shader" "reflection1_coat",
"weight" 1,
"weight_tint" 1 1 1,
"use_directional_weight" on,
"directional_weight_mode" 0,
"ior" 1.4,
"on" on
},
{
"shader" "reflection1",
"weight" 1.0,
"weight_tint" 1 1 1,
"use_directional_weight" on,
"directional_weight_mode" 1,
"normal_reflectivity" 0.4,
"grazing_reflectivity" 1.0,
"exponent" 5.0,
"on" on
},
{
"shader" "diffuse1",
"weight_tint" 1 1 1,
"weight" 1,
"on" on
}
]
)
# This layers the two different materials together to create
# "gray goop covered blue paint"
shader "my_layers1" "mila_layer" (
"layers" [
{
"shader" "top_layers",
"bump" = "noise_bump", # Bump ONLY goes here
"weight_tint" = "noise_mask", # Mask ONLY goes here
"weight" 1,
"on" on
},
{
"shader" "paint_layers1",
"weight_tint" 1 1 1,
"weight" 1,
"on" on
}
]
)
生成的渲染与上面的渲染相同: