Triplanar 节点
描述
Triplanar 是一种通过在世界空间中投影来生成 UV 并对纹理进行采样的方法。输入纹理被采样 3 次,在世界 x、y 和 z 轴的每一个轴中都采样一次,然后生成的信息被平面投影到模型上,并由法线或表面角度混合。生成的 UV 可以使用输入 Tile 进行缩放,并可以使用输入 Blend 控制最终的混合强度。Blend 控制法线影响每个平面样本混合的方式,应大于或等于 0。Blend 越大,最接近法线朝向的平面对样本的贡献越大。(最大混合指数在 17 到 158 之间,具体取决于平台和节点的精度。)无论法线方向如何,Blend 为 0 会使每个平面获得相等的权重。可以通过覆盖输入 Position和 Normal 来修改投影。这通常用于大型模型(例如地形,这种情况下手动创建 UV 坐标会有问题或性能不佳)的纹理。
可以使用 Type 下拉选单来切换输入纹理的预期类型。如果设置为 Normal,则法线将转换为世界空间,因此可以构造新的切线,然后在输出之前将其转换回切线空间。
如果在包含自定义函数节点或子图形的图形中使用此节点时遇到纹理采样错误,可以通过升级到 10.3 或更高版本来解决这些问题。
注意:此节点只能在片元着色器阶段中使用。
端口
名称 | 方向 | 类型 | 绑定 | 描述 |
---|---|---|---|---|
Texture | 输入 | Texture | 无 | 输入纹理值 |
Sampler | 输入 | 采样器状态 | 无 | 输入纹理采样器 |
Position | 输入 | 矢量 3 | 世界空间位置 | 片元位置 |
Normal | 输入 | 矢量 3 | 世界空间法线 | 片元法线 |
Tile | 输入 | Float | 无 | 生成的 UV 的平铺量 |
Blend | 输入 | Float | 无 | 不同样本之间的混合因子 |
Out | 输出 | 矢量 4 | 无 | 输出值 |
控件
名称 | 类型 | 选项 | 描述 |
---|---|---|---|
类型 | 下拉选单 | Default、Normal | 输入纹理的类型 |
生成的代码示例
以下示例代码表示此节点的一种可能结果。
Default
float3 Node_UV = Position * Tile;
float3 Node_Blend = pow(abs(Normal), Blend);
Node_Blend /= dot(Node_Blend, 1.0);
float4 Node_X = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.zy);
float4 Node_Y = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xz);
float4 Node_Z = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xy);
float4 Out = Node_X * Node_Blend.x + Node_Y * Node_Blend.y + Node_Z * Node_Blend.z;
Normal
float3 Node_UV = Position * Tile;
float3 Node_Blend = max(pow(abs(Normal), Blend), 0);
Node_Blend /= (Node_Blend.x + Node_Blend.y + Node_Blend.z ).xxx;
float3 Node_X = UnpackNormal(SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.zy));
float3 Node_Y = UnpackNormal(SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xz));
float3 Node_Z = UnpackNormal(SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xy));
Node_X = float3(Node_X.xy + Normal.zy, abs(Node_X.z) * Normal.x);
Node_Y = float3(Node_Y.xy + Normal.xz, abs(Node_Y.z) * Normal.y);
Node_Z = float3(Node_Z.xy + Normal.xy, abs(Node_Z.z) * Normal.z);
float4 Out = float4(normalize(Node_X.zyx * Node_Blend.x + Node_Y.xzy * Node_Blend.y + Node_Z.xyz * Node_Blend.z), 1);
float3x3 Node_Transform = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);
Out.rgb = TransformWorldToTangent(Out.rgb, Node_Transform);