mirror of
https://github.com/Eragon-Brisingr/UShaderLab.git
synced 2026-09-15 14:54:36 +00:00
Add README
This commit is contained in:
BIN
Docs/ExampleImage.png
Normal file
BIN
Docs/ExampleImage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
399
Docs/README_CN.md
Normal file
399
Docs/README_CN.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# UShaderLab 说明
|
||||
|
||||
[English](../README.md) | [中文](./README_CN.md)
|
||||
|
||||

|
||||
|
||||
UShaderLab 用来在 Unreal Engine 里用接近 HLSL 的文本语法编写材质。使用者编写 `.usl` 文件,插件会把它解析成材质图,并通过创建 ShaderLab Material Instance 暴露可调参数。
|
||||
|
||||
## 基本工作流
|
||||
|
||||
1. 在 `<Project>/Shaders` 或某个插件的 `<Plugin>/Shaders` 目录下创建 `.usl` 文件。
|
||||
2. 文件顶部#include "/Plugin/ShaderLab/ShaderLab.ush",便于 IDE 识别 DSL 宏和 `UE_` 内建函数。
|
||||
3. 用 `SL_SETTINGS` 描述材质设置,用 `SL_PROPERTY` 声明实例参数。
|
||||
4. 用 `SL_SURFACE`、`SL_UNLIT`、`SL_POSTPROCESS` 等入口编写材质主体。
|
||||
5. 在 Content Browser 里创建 `ShaderLab Material Instance`,选择对应的 ShaderLab 基材质。
|
||||
6. 在生成的实例上调参数,并把实例赋给网格、UI、后处理或其它承载对象。
|
||||
|
||||
推荐在编辑器控制台执行一次:
|
||||
|
||||
```text
|
||||
ShaderLab.IDE.Prepare
|
||||
```
|
||||
|
||||
它会为 `.usl`、`.uslfunc` 准备基础的 HLSL 识别和路径映射,让 IDE 补全更舒服。
|
||||
|
||||
> VSCode推荐安装[shader-validator](https://marketplace.visualstudio.com/items?itemName=antaalt.shader-validator)插件,已经支持该插件的补全
|
||||
|
||||
## 最小示例
|
||||
|
||||
下面是一个最简单的 Surface 材质:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
|
||||
SL_SETTINGS(Domain = Surface, BlendMode = Opaque)
|
||||
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 BaseColor = float3(0.8, 0.2, 0.1);
|
||||
|
||||
SL_PROPERTY(Category = "Surface", ClampMin = 0, ClampMax = 1)
|
||||
float Roughness = 0.5;
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = BaseColor;
|
||||
S.Roughness = Roughness;
|
||||
}
|
||||
```
|
||||
|
||||
文件名就是这个 ShaderLab 材质的名字来源。在内容浏览器**Material ▸ ShaderLab Material Instance**创建,选择器里选择它,然后在实例详情面板里调整 `BaseColor` 和 `Roughness`。
|
||||
|
||||
## 文件类型
|
||||
|
||||
`.usl` 是可生成材质的 ShaderLab 文件(理解为UMaterial)。一个 `.usl` 对应一个可被实例化的 ShaderLab 材质。
|
||||
|
||||
`.uslfunc` 是函数库文件(理解为UMaterialFunction)。它不能直接生成材质,只能被 `.usl` 或其它 `.uslfunc` 引入,用来复用函数和参数。
|
||||
|
||||
```hlsl
|
||||
#include "/Project/Lib/MyLibrary.uslfunc"
|
||||
```
|
||||
|
||||
路径通常使用虚拟 shader 路径,例如:
|
||||
|
||||
```text
|
||||
/Project/...
|
||||
/Plugin/<PluginName>/...
|
||||
/Engine/...
|
||||
```
|
||||
|
||||
## 常用设置
|
||||
|
||||
`SL_SETTINGS` 写在文件顶层,用来描述材质域、混合模式和常见材质设置。
|
||||
|
||||
```hlsl
|
||||
SL_SETTINGS(Domain = Surface, BlendMode = Masked, TwoSided = true, OpacityMaskClipValue = 0.4)
|
||||
```
|
||||
|
||||
常用 `Domain`:
|
||||
|
||||
- `Surface`:普通表面材质。
|
||||
- `PostProcess`:后处理材质。
|
||||
- `UI`:UI 材质。
|
||||
- `Decal`:贴花材质。
|
||||
- `Volume`:体积材质。
|
||||
- `LightFunction`:灯光函数材质。
|
||||
|
||||
常用 `BlendMode`:
|
||||
|
||||
- `Opaque`
|
||||
- `Masked`
|
||||
- `Translucent`
|
||||
- `Additive`
|
||||
- `Modulate`
|
||||
- `AlphaComposite`
|
||||
- `AlphaHoldout`
|
||||
|
||||
## 参数声明
|
||||
|
||||
输入参数主要有两类:`SL_PROPERTY` 声明材质实例上的可调参数,`SL_COLLECTION` 声明来自 Material Parameter Collection 的全局输入。
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 Tint = float3(1, 1, 1);
|
||||
|
||||
SL_PROPERTY(Category = "Surface", ClampMin = 0, ClampMax = 1)
|
||||
float Metallic = 0.0;
|
||||
|
||||
SL_PROPERTY(Category = "Textures", DefaultTexture = "white")
|
||||
Texture2D AlbedoTex;
|
||||
SamplerState AlbedoTexSampler;
|
||||
|
||||
SL_PROPERTY(Category = "Switches")
|
||||
#define UseTexture 1
|
||||
|
||||
SL_COLLECTION(Path = "/Game/YourFolder/MPC_Global", Parameter = "Wind")
|
||||
float3 Wind;
|
||||
```
|
||||
|
||||
常见类型对应关系:
|
||||
|
||||
- `float`:Scalar 参数。
|
||||
- `float3`:Color 参数。
|
||||
- `float4`:Vector 参数。
|
||||
- `Texture2D`、`TextureCube`:贴图参数。
|
||||
- `#define Name 0/1`:Static Bool 参数,可用于 `#if`。
|
||||
- `SL_COLLECTION(...) floatN Name;`:材质参数集合输入,不是实例旋钮。
|
||||
|
||||
常用 specifier:
|
||||
|
||||
- `Category`:实例面板里的分类。
|
||||
- `SortPriority`:排序优先级。
|
||||
- `ClampMin`、`ClampMax`:Scalar 滑条范围。
|
||||
- `DefaultTexture`:贴图默认值,可用 `white`、`black`、`grey`、`normal` 或资产路径。
|
||||
- `CustomPrimitiveData`:让 Scalar 或 Vector 从组件的 Custom Primitive Data 读取。
|
||||
|
||||
`SL_COLLECTION` 常用写法:
|
||||
|
||||
```hlsl
|
||||
SL_COLLECTION(Path = "/Game/YourFolder/MPC_Global", Parameter = "Wind")
|
||||
float3 Wind;
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.EmissiveColor = abs(Wind);
|
||||
}
|
||||
```
|
||||
|
||||
Static Bool 可以直接控制预处理分支:
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Switches")
|
||||
#define UseTexture 1
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
#if UseTexture
|
||||
S.DiffuseAlbedo = float3(1, 1, 1);
|
||||
#else
|
||||
S.DiffuseAlbedo = float3(0.2, 0.2, 0.2);
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
在材质实例里覆盖 Static Bool 后,会按对应排列重新编译。
|
||||
|
||||
## Surface 材质
|
||||
|
||||
普通表面材质最常用 `SL_SURFACE`。函数参数是 `inout FShaderLabSurface`,只需要填写你关心的字段,没写的字段会使用默认值。
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
float2 uv = UE_TextureCoordinate(0);
|
||||
S.DiffuseAlbedo = Texture2DSample(AlbedoTex, AlbedoTexSampler, uv).rgb * Tint;
|
||||
S.Roughness = Roughness;
|
||||
S.EmissiveColor = float3(0, 0, 0);
|
||||
}
|
||||
```
|
||||
|
||||
常用字段:
|
||||
|
||||
- `DiffuseAlbedo`
|
||||
- `F0`
|
||||
- `Roughness`
|
||||
- `Normal`
|
||||
- `EmissiveColor`
|
||||
- `Opacity`
|
||||
- `OpacityMask`
|
||||
- `Refraction`
|
||||
- `PixelDepthOffset`
|
||||
|
||||
如果需要在 body 里使用依赖材质上下文的变换函数,可以显式声明 `Parameters`:
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(FMaterialPixelParameters Parameters, inout FShaderLabSurface S)
|
||||
{
|
||||
float3 n = UE_TransformTangentVectorToWorld(Parameters, float3(0, 0, 1));
|
||||
S.Normal = n;
|
||||
}
|
||||
```
|
||||
|
||||
## 其它材质入口
|
||||
|
||||
除了 `SL_SURFACE`,还可以使用其它入口来表达不同类型的材质。
|
||||
|
||||
```hlsl
|
||||
SL_UNLIT()
|
||||
void Unlit(inout FShaderLabUnlit U)
|
||||
{
|
||||
U.EmissiveColor = float3(1, 0.5, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
常用入口:
|
||||
|
||||
- `SL_UNLIT`:无光照材质。
|
||||
- `SL_HAIR`:头发材质。
|
||||
- `SL_EYE`:眼睛材质。
|
||||
- `SL_WATER`:Single Layer Water。
|
||||
- `SL_CLEARCOAT`:清漆材质。
|
||||
- `SL_TOON`:卡通材质。
|
||||
- `SL_VOLUME`:体积材质,需要 `Domain = Volume`。
|
||||
- `SL_LIGHTFUNCTION`:灯光函数材质,需要 `Domain = LightFunction`。
|
||||
- `SL_POSTPROCESS`:后处理材质,需要 `Domain = PostProcess`。
|
||||
- `SL_UI`:UI 材质,需要 `Domain = UI`。
|
||||
|
||||
## 多层材质
|
||||
|
||||
多个 `SL_SLAB` 可以通过 `SL_FRONTMATERIAL` 组合成一个 Substrate 材质。
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Layer", ClampMin = 0, ClampMax = 1)
|
||||
float Mix = 0.5;
|
||||
|
||||
SL_SLAB()
|
||||
void Base(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = float3(0.1, 0.1, 0.1);
|
||||
S.Roughness = 0.8;
|
||||
}
|
||||
|
||||
SL_SLAB()
|
||||
void Coat(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = float3(0.8, 0.2, 0.1);
|
||||
S.Roughness = 0.2;
|
||||
}
|
||||
|
||||
SL_FRONTMATERIAL(HorizontalMix(Base, Coat, Mix))
|
||||
```
|
||||
|
||||
常用组合:
|
||||
|
||||
- `VerticalLayer(Top, Base, Thickness)`:上下层叠。
|
||||
- `HorizontalMix(Background, Foreground, Mix)`:横向混合。
|
||||
- `Add(A, B)`:相加。
|
||||
- `Weight(A, Weight)`:权重。
|
||||
- `Select(A, B, Threshold)`:选择。
|
||||
|
||||
混合因子可以是浮点字面量、Scalar 参数,或一个 `SL_VALUE`。
|
||||
|
||||
```hlsl
|
||||
SL_VALUE()
|
||||
float EdgeMask()
|
||||
{
|
||||
return saturate(UE_TextureCoordinate(0).x);
|
||||
}
|
||||
|
||||
SL_FRONTMATERIAL(HorizontalMix(Base, Coat, EdgeMask))
|
||||
```
|
||||
|
||||
## 顶点与插值
|
||||
|
||||
`SL_VERTEX` 用于输出顶点阶段数据,比如世界位置偏移。
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Vertex")
|
||||
float Offset = 10.0;
|
||||
|
||||
SL_VERTEX()
|
||||
void Vertex(inout FShaderLabVertex V)
|
||||
{
|
||||
V.WorldPositionOffset = float3(0, 0, Offset);
|
||||
}
|
||||
```
|
||||
|
||||
`SL_INTERPOLATOR` 用于在顶点阶段计算一个值,并在像素阶段读取。
|
||||
|
||||
```hlsl
|
||||
SL_INTERPOLATOR()
|
||||
float3 VertexNormalColor()
|
||||
{
|
||||
return abs(UE_VertexNormalWS());
|
||||
}
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = UE_Interpolator(VertexNormalColor);
|
||||
}
|
||||
```
|
||||
|
||||
插值器适合把顶点频率的结果带到像素阶段。不要把只适合像素阶段的采样逻辑放进 `SL_INTERPOLATOR`。
|
||||
|
||||
## 函数库 .uslfunc
|
||||
|
||||
`.uslfunc` 用来复用材质函数。库里可以声明 `SL_FUNCTION`,也可以声明自己的 `SL_PROPERTY`。当一个 `.usl` 引入库时,库里的参数会提升到这个材质实例上。
|
||||
|
||||
库文件:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
|
||||
SL_PROPERTY(Category = "Detail", ClampMin = 0, ClampMax = 1)
|
||||
float DetailStrength = 0.5;
|
||||
|
||||
SL_FUNCTION()
|
||||
float3 ApplyDetail(float3 color, float2 uv)
|
||||
{
|
||||
float stripes = frac(uv.x * 12.0);
|
||||
return lerp(color, color * stripes, DetailStrength);
|
||||
}
|
||||
```
|
||||
|
||||
材质文件:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
#include "/Project/Lib/Detail.uslfunc"
|
||||
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 BaseColor = float3(0.8, 0.8, 0.8);
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = ApplyDetail(BaseColor, UE_TextureCoordinate(0));
|
||||
}
|
||||
```
|
||||
|
||||
如果多个库里有同名参数,可以用 `SL_IMPORT` 给提升出来的参数加命名空间前缀。
|
||||
|
||||
```hlsl
|
||||
SL_IMPORT(Namespace = "Detail")
|
||||
#include "/Project/Lib/Detail.uslfunc"
|
||||
```
|
||||
|
||||
## 常用 UE_ 内建函数
|
||||
|
||||
ShaderLab 通过 `UE_` 前缀暴露常见的 UE 材质节点。它们可以在 `.usl` body 中像普通函数一样调用。
|
||||
|
||||
常用类别:
|
||||
|
||||
- UV:`UE_TextureCoordinate(0)`。
|
||||
- 时间:`UE_Time()`。
|
||||
- 几何数据:`UE_VertexNormalWS()`、`UE_PixelNormalWS()`、`UE_CameraVectorWS()`。
|
||||
- 对象和实例:对象位置、对象半径、Actor 位置、Custom Primitive Data。
|
||||
- 坐标变换:`UE_TransformVector...`、`UE_TransformPosition...`。
|
||||
- 噪声和旋转:`UE_Noise(...)`、`UE_RotateAboutAxis(...)`。
|
||||
- 场景纹理:`UE_SceneTexture(...)`、`UE_SceneDepth(...)`、`UE_CustomDepth(...)`、`UE_CustomStencil(...)`。
|
||||
- 距离场:`UE_DistanceToNearestSurface(...)`、`UE_DistanceFieldGradient(...)`。
|
||||
|
||||
示例:
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
float t = UE_Time();
|
||||
float2 uv = UE_TextureCoordinate(0);
|
||||
float3 normalColor = abs(UE_VertexNormalWS());
|
||||
S.EmissiveColor = normalColor * (0.5 + 0.5 * sin(t + uv.x * 6.28318));
|
||||
}
|
||||
```
|
||||
|
||||
## 材质实例与使用注意
|
||||
|
||||
ShaderLab 材质应该通过 `ShaderLab Material Instance` 使用。
|
||||
|
||||
Usage 不写在 `.usl` 里。把实例赋给静态网格、骨骼网格、粒子、UI 等对象时,按 UE 的材质实例规则设置或自动记录对应 usage。打包前需要确保实际使用到的 usage 已经在编辑器阶段确定。
|
||||
|
||||
`.usl` 和 `.uslfunc` 会从项目或插件的 `Shaders` 目录参与打包。材质实例引用的贴图、MPC、Profile 等资源仍应按正常 UE 资产规则存在于工程内容中。
|
||||
|
||||
## 实现思路
|
||||
|
||||
使用者可以把 UShaderLab 理解成三层:
|
||||
|
||||
- `.usl` 是材质源码。它保持接近 HLSL 的写法,用 `SL_` 宏补充材质设置、参数和入口信息。
|
||||
- 插件在编辑器里解析 `.usl`,把参数、Custom HLSL、Substrate BSDF 和必要的辅助节点组成 UE 材质图。
|
||||
- 最终给场景使用的是 ShaderLab Material Instance。实例保存参数覆盖,并负责拥有可渲染所需的编译结果。
|
||||
|
||||
静态开关 `#define` 会作为材质实例的 Static Bool 参数暴露。实例覆盖后,相关 `#if` 会按当前排列生效,所以可以把不同分支写成真正的编译期分支。
|
||||
|
||||
基材质主要是模板,日常使用时只需要创建和保存 ShaderLab Material Instance。
|
||||
399
README.md
Normal file
399
README.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# UShaderLab Guide
|
||||
|
||||
[English](./README.md) | [中文](./Docs/README_CN.md)
|
||||
|
||||

|
||||
|
||||
UShaderLab lets you write Unreal Engine materials in a text format that feels close to HLSL. You write `.usl` files, and the plugin parses them into material graphs with editable parameters exposed through ShaderLab Material Instances.
|
||||
|
||||
## Basic Workflow
|
||||
|
||||
1. Create a `.usl` file under `<Project>/Shaders` or a plugin's `<Plugin>/Shaders` directory.
|
||||
2. Add `#include "/Plugin/ShaderLab/ShaderLab.ush"` at the top so the IDE can recognize DSL macros and `UE_` intrinsics.
|
||||
3. Use `SL_SETTINGS` for material settings, and `SL_PROPERTY` for instance parameters.
|
||||
4. Write the material body with entries such as `SL_SURFACE`, `SL_UNLIT`, or `SL_POSTPROCESS`.
|
||||
5. In the Content Browser, create a `ShaderLab Material Instance` and choose the corresponding ShaderLab base material.
|
||||
6. Adjust parameters on the generated instance, then assign it to meshes, UI, post process volumes, or other supported targets.
|
||||
|
||||
It is recommended to run this once in the editor console:
|
||||
|
||||
```text
|
||||
ShaderLab.IDE.Prepare
|
||||
```
|
||||
|
||||
This prepares basic HLSL recognition and path mapping for `.usl` and `.uslfunc`, making IDE completion more useful.
|
||||
|
||||
> VSCode users are recommended to install the [shader-validator](https://marketplace.visualstudio.com/items?itemName=antaalt.shader-validator) extension. UShaderLab completion is already supported.
|
||||
|
||||
## Minimal Example
|
||||
|
||||
Here is a minimal Surface material:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
|
||||
SL_SETTINGS(Domain = Surface, BlendMode = Opaque)
|
||||
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 BaseColor = float3(0.8, 0.2, 0.1);
|
||||
|
||||
SL_PROPERTY(Category = "Surface", ClampMin = 0, ClampMax = 1)
|
||||
float Roughness = 0.5;
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = BaseColor;
|
||||
S.Roughness = Roughness;
|
||||
}
|
||||
```
|
||||
|
||||
The file name is used as the ShaderLab material name. Create an instance from **Material > ShaderLab Material Instance** in the Content Browser, choose this material in the picker, then edit `BaseColor` and `Roughness` in the instance details panel.
|
||||
|
||||
## File Types
|
||||
|
||||
`.usl` is a ShaderLab file that generates a material. You can think of it as a text-authored `UMaterial`. One `.usl` corresponds to one instantiable ShaderLab material.
|
||||
|
||||
`.uslfunc` is a function library file. You can think of it as a text-authored `UMaterialFunction`. It does not generate a material by itself. It can only be included by `.usl` or other `.uslfunc` files to share functions and parameters.
|
||||
|
||||
```hlsl
|
||||
#include "/Project/Lib/MyLibrary.uslfunc"
|
||||
```
|
||||
|
||||
Paths usually use virtual shader paths:
|
||||
|
||||
```text
|
||||
/Project/...
|
||||
/Plugin/<PluginName>/...
|
||||
/Engine/...
|
||||
```
|
||||
|
||||
## Common Settings
|
||||
|
||||
`SL_SETTINGS` is written at the top level and describes the material domain, blend mode, and common material settings.
|
||||
|
||||
```hlsl
|
||||
SL_SETTINGS(Domain = Surface, BlendMode = Masked, TwoSided = true, OpacityMaskClipValue = 0.4)
|
||||
```
|
||||
|
||||
Common `Domain` values:
|
||||
|
||||
- `Surface`: regular surface material.
|
||||
- `PostProcess`: post process material.
|
||||
- `UI`: UI material.
|
||||
- `Decal`: decal material.
|
||||
- `Volume`: volume material.
|
||||
- `LightFunction`: light function material.
|
||||
|
||||
Common `BlendMode` values:
|
||||
|
||||
- `Opaque`
|
||||
- `Masked`
|
||||
- `Translucent`
|
||||
- `Additive`
|
||||
- `Modulate`
|
||||
- `AlphaComposite`
|
||||
- `AlphaHoldout`
|
||||
|
||||
## Parameter Declarations
|
||||
|
||||
There are two main kinds of input parameters: `SL_PROPERTY` declares editable parameters on the material instance, while `SL_COLLECTION` declares global inputs from a Material Parameter Collection.
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 Tint = float3(1, 1, 1);
|
||||
|
||||
SL_PROPERTY(Category = "Surface", ClampMin = 0, ClampMax = 1)
|
||||
float Metallic = 0.0;
|
||||
|
||||
SL_PROPERTY(Category = "Textures", DefaultTexture = "white")
|
||||
Texture2D AlbedoTex;
|
||||
SamplerState AlbedoTexSampler;
|
||||
|
||||
SL_PROPERTY(Category = "Switches")
|
||||
#define UseTexture 1
|
||||
|
||||
SL_COLLECTION(Path = "/Game/YourFolder/MPC_Global", Parameter = "Wind")
|
||||
float3 Wind;
|
||||
```
|
||||
|
||||
Common type mapping:
|
||||
|
||||
- `float`: Scalar parameter.
|
||||
- `float3`: Color parameter.
|
||||
- `float4`: Vector parameter.
|
||||
- `Texture2D`, `TextureCube`: texture parameter.
|
||||
- `#define Name 0/1`: Static Bool parameter, usable in `#if`.
|
||||
- `SL_COLLECTION(...) floatN Name;`: Material Parameter Collection input, not an instance knob.
|
||||
|
||||
Common specifiers:
|
||||
|
||||
- `Category`: category in the instance details panel.
|
||||
- `SortPriority`: sorting priority.
|
||||
- `ClampMin`, `ClampMax`: Scalar slider range.
|
||||
- `DefaultTexture`: default texture, such as `white`, `black`, `grey`, `normal`, or an asset path.
|
||||
- `CustomPrimitiveData`: reads a Scalar or Vector from component Custom Primitive Data.
|
||||
|
||||
Common `SL_COLLECTION` usage:
|
||||
|
||||
```hlsl
|
||||
SL_COLLECTION(Path = "/Game/YourFolder/MPC_Global", Parameter = "Wind")
|
||||
float3 Wind;
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.EmissiveColor = abs(Wind);
|
||||
}
|
||||
```
|
||||
|
||||
Static Bool parameters can directly control preprocessor branches:
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Switches")
|
||||
#define UseTexture 1
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
#if UseTexture
|
||||
S.DiffuseAlbedo = float3(1, 1, 1);
|
||||
#else
|
||||
S.DiffuseAlbedo = float3(0.2, 0.2, 0.2);
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
When a Static Bool is overridden in a material instance, the corresponding permutation is recompiled.
|
||||
|
||||
## Surface Materials
|
||||
|
||||
Most regular surface materials use `SL_SURFACE`. The function takes `inout FShaderLabSurface`; fill only the fields you care about, and unspecified fields keep their defaults.
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
float2 uv = UE_TextureCoordinate(0);
|
||||
S.DiffuseAlbedo = Texture2DSample(AlbedoTex, AlbedoTexSampler, uv).rgb * Tint;
|
||||
S.Roughness = Roughness;
|
||||
S.EmissiveColor = float3(0, 0, 0);
|
||||
}
|
||||
```
|
||||
|
||||
Common fields:
|
||||
|
||||
- `DiffuseAlbedo`
|
||||
- `F0`
|
||||
- `Roughness`
|
||||
- `Normal`
|
||||
- `EmissiveColor`
|
||||
- `Opacity`
|
||||
- `OpacityMask`
|
||||
- `Refraction`
|
||||
- `PixelDepthOffset`
|
||||
|
||||
If a body needs transform helpers that depend on the material context, declare `Parameters` explicitly:
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(FMaterialPixelParameters Parameters, inout FShaderLabSurface S)
|
||||
{
|
||||
float3 n = UE_TransformTangentVectorToWorld(Parameters, float3(0, 0, 1));
|
||||
S.Normal = n;
|
||||
}
|
||||
```
|
||||
|
||||
## Other Material Entries
|
||||
|
||||
In addition to `SL_SURFACE`, other entries can express different material types.
|
||||
|
||||
```hlsl
|
||||
SL_UNLIT()
|
||||
void Unlit(inout FShaderLabUnlit U)
|
||||
{
|
||||
U.EmissiveColor = float3(1, 0.5, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
Common entries:
|
||||
|
||||
- `SL_UNLIT`: unlit material.
|
||||
- `SL_HAIR`: hair material.
|
||||
- `SL_EYE`: eye material.
|
||||
- `SL_WATER`: Single Layer Water.
|
||||
- `SL_CLEARCOAT`: clear coat material.
|
||||
- `SL_TOON`: toon material.
|
||||
- `SL_VOLUME`: volume material, requires `Domain = Volume`.
|
||||
- `SL_LIGHTFUNCTION`: light function material, requires `Domain = LightFunction`.
|
||||
- `SL_POSTPROCESS`: post process material, requires `Domain = PostProcess`.
|
||||
- `SL_UI`: UI material, requires `Domain = UI`.
|
||||
|
||||
## Layered Materials
|
||||
|
||||
Multiple `SL_SLAB` blocks can be combined into one Substrate material with `SL_FRONTMATERIAL`.
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Layer", ClampMin = 0, ClampMax = 1)
|
||||
float Mix = 0.5;
|
||||
|
||||
SL_SLAB()
|
||||
void Base(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = float3(0.1, 0.1, 0.1);
|
||||
S.Roughness = 0.8;
|
||||
}
|
||||
|
||||
SL_SLAB()
|
||||
void Coat(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = float3(0.8, 0.2, 0.1);
|
||||
S.Roughness = 0.2;
|
||||
}
|
||||
|
||||
SL_FRONTMATERIAL(HorizontalMix(Base, Coat, Mix))
|
||||
```
|
||||
|
||||
Common composition operators:
|
||||
|
||||
- `VerticalLayer(Top, Base, Thickness)`: layer one material over another.
|
||||
- `HorizontalMix(Background, Foreground, Mix)`: horizontal mix.
|
||||
- `Add(A, B)`: add.
|
||||
- `Weight(A, Weight)`: weight.
|
||||
- `Select(A, B, Threshold)`: select.
|
||||
|
||||
A mix factor can be a float literal, a Scalar parameter, or an `SL_VALUE`.
|
||||
|
||||
```hlsl
|
||||
SL_VALUE()
|
||||
float EdgeMask()
|
||||
{
|
||||
return saturate(UE_TextureCoordinate(0).x);
|
||||
}
|
||||
|
||||
SL_FRONTMATERIAL(HorizontalMix(Base, Coat, EdgeMask))
|
||||
```
|
||||
|
||||
## Vertex And Interpolator
|
||||
|
||||
`SL_VERTEX` outputs vertex-stage data, such as world position offset.
|
||||
|
||||
```hlsl
|
||||
SL_PROPERTY(Category = "Vertex")
|
||||
float Offset = 10.0;
|
||||
|
||||
SL_VERTEX()
|
||||
void Vertex(inout FShaderLabVertex V)
|
||||
{
|
||||
V.WorldPositionOffset = float3(0, 0, Offset);
|
||||
}
|
||||
```
|
||||
|
||||
`SL_INTERPOLATOR` computes a value in the vertex stage and reads it in the pixel stage.
|
||||
|
||||
```hlsl
|
||||
SL_INTERPOLATOR()
|
||||
float3 VertexNormalColor()
|
||||
{
|
||||
return abs(UE_VertexNormalWS());
|
||||
}
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = UE_Interpolator(VertexNormalColor);
|
||||
}
|
||||
```
|
||||
|
||||
Interpolators are useful for passing vertex-frequency results to the pixel stage. Do not put pixel-only sampling logic inside `SL_INTERPOLATOR`.
|
||||
|
||||
## Function Libraries .uslfunc
|
||||
|
||||
`.uslfunc` files are used to share material functions. A library can declare `SL_FUNCTION` and its own `SL_PROPERTY`. When a `.usl` includes the library, the library parameters are promoted onto that material instance.
|
||||
|
||||
Library file:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
|
||||
SL_PROPERTY(Category = "Detail", ClampMin = 0, ClampMax = 1)
|
||||
float DetailStrength = 0.5;
|
||||
|
||||
SL_FUNCTION()
|
||||
float3 ApplyDetail(float3 color, float2 uv)
|
||||
{
|
||||
float stripes = frac(uv.x * 12.0);
|
||||
return lerp(color, color * stripes, DetailStrength);
|
||||
}
|
||||
```
|
||||
|
||||
Material file:
|
||||
|
||||
```hlsl
|
||||
#include "/Plugin/ShaderLab/ShaderLab.ush"
|
||||
#include "/Project/Lib/Detail.uslfunc"
|
||||
|
||||
SL_PROPERTY(Category = "Surface")
|
||||
float3 BaseColor = float3(0.8, 0.8, 0.8);
|
||||
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
S.DiffuseAlbedo = ApplyDetail(BaseColor, UE_TextureCoordinate(0));
|
||||
}
|
||||
```
|
||||
|
||||
If multiple libraries contain parameters with the same name, use `SL_IMPORT` to add a namespace prefix to promoted parameters.
|
||||
|
||||
```hlsl
|
||||
SL_IMPORT(Namespace = "Detail")
|
||||
#include "/Project/Lib/Detail.uslfunc"
|
||||
```
|
||||
|
||||
## Common UE_ Intrinsics
|
||||
|
||||
ShaderLab exposes common UE material nodes through the `UE_` prefix. They can be called like regular functions inside a `.usl` body.
|
||||
|
||||
Common categories:
|
||||
|
||||
- UV: `UE_TextureCoordinate(0)`.
|
||||
- Time: `UE_Time()`.
|
||||
- Geometry data: `UE_VertexNormalWS()`, `UE_PixelNormalWS()`, `UE_CameraVectorWS()`.
|
||||
- Object and instance data: object position, object radius, actor position, Custom Primitive Data.
|
||||
- Coordinate transforms: `UE_TransformVector...`, `UE_TransformPosition...`.
|
||||
- Noise and rotation: `UE_Noise(...)`, `UE_RotateAboutAxis(...)`.
|
||||
- Scene textures: `UE_SceneTexture(...)`, `UE_SceneDepth(...)`, `UE_CustomDepth(...)`, `UE_CustomStencil(...)`.
|
||||
- Distance fields: `UE_DistanceToNearestSurface(...)`, `UE_DistanceFieldGradient(...)`.
|
||||
|
||||
Example:
|
||||
|
||||
```hlsl
|
||||
SL_SURFACE()
|
||||
void Surface(inout FShaderLabSurface S)
|
||||
{
|
||||
float t = UE_Time();
|
||||
float2 uv = UE_TextureCoordinate(0);
|
||||
float3 normalColor = abs(UE_VertexNormalWS());
|
||||
S.EmissiveColor = normalColor * (0.5 + 0.5 * sin(t + uv.x * 6.28318));
|
||||
}
|
||||
```
|
||||
|
||||
## Material Instances And Usage Notes
|
||||
|
||||
ShaderLab materials should be used through `ShaderLab Material Instance`.
|
||||
|
||||
Usage is not declared in `.usl`. When assigning an instance to static meshes, skeletal meshes, particles, UI, or other targets, use the normal UE material instance rules to set or record the corresponding usage. Before packaging, make sure the usages you actually need have been determined in the editor.
|
||||
|
||||
`.usl` and `.uslfunc` files under project or plugin `Shaders` directories participate in packaging. Textures, MPCs, Profiles, and other assets referenced by material instances should still exist as normal UE content assets.
|
||||
|
||||
## Implementation Idea
|
||||
|
||||
As a user, you can think of UShaderLab as three layers:
|
||||
|
||||
- `.usl` is the material source. It stays close to HLSL, with `SL_` macros for material settings, parameters, and entries.
|
||||
- In the editor, the plugin parses `.usl` and builds a UE material graph from parameters, Custom HLSL, Substrate BSDFs, and required helper nodes.
|
||||
- What you use in the scene is a ShaderLab Material Instance. The instance stores parameter overrides and owns the compiled result needed for rendering.
|
||||
|
||||
Static switches declared with `#define` are exposed as Static Bool parameters on the material instance. After an instance override, related `#if` branches are evaluated for that permutation, so different branches can be written as real compile-time branches.
|
||||
|
||||
The base material is mainly a template. In daily use, you only need to create and save ShaderLab Material Instances.
|
||||
@@ -3,9 +3,9 @@
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "UShaderLab",
|
||||
"Description": "Unity-ShaderLab-like text DSL that builds in-memory Substrate materials.",
|
||||
"Description": "HLSL-like text DSL that builds in-memory UMaterial.",
|
||||
"Category": "Rendering",
|
||||
"CreatedBy": "UShaderLab",
|
||||
"CreatedBy": "DuoXu",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
@@ -24,5 +24,6 @@
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SupportURL": ""
|
||||
}
|
||||
Reference in New Issue
Block a user