示例和教程

常规分层示例

下面举例说明了如何在直接使用 .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_layermila_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
        }
    ]
)

生成的渲染与上面的渲染相同: