ShaderLab
是一个针对 Galacean 引擎打造的 Shader
包装语言,它允许开发人员使用熟悉的 GLSL
语法编写自定义 Shader
,同时提供了额外的高级抽象和管理特性以增强开发效率。通过 ShaderLab
,开发者能够更便捷地定义材质属性、渲染配置和其他效果。尽管 ShaderLab
为着色器的编写引入了便利性,但它并不取代 GLSL
,而是与之兼容。开发者可以在 ShaderLab
框架内编写原生 GLSL
代码块,享受两者的结合优势。
ShaderLab
语法骨架如下:
Shader "ShaderName" {
...
Editor {
...
}
...
SubShader "SubShaderName" {
...
Pass "PassName" {
...
}
...
}
...
}
语法模块 | 描述 |
---|---|
Shader | ShaderLab 中通过 Shader 模块声明一个 Shader 对象,开发者可以在该模块中添加材质属性、绑定 Shader UI 脚本、声明全局变量等 |
Editor | 开发者通过 Editor 模块对材质 Inspector 面板进行定制 |
SubShader | 在 SubShader 中指定 Tag,添加 ShaderPass,使用 UsePass 指令 |
Pass | 开发者通过 Pass 模块声明 ShaderPass 对象 |
Shader "ShaderName" {
Editor {
Properties {
material_BaseColor("Main Color", Color) = (0, 0, 0, 1);
material_BaseTexture("Texture", Texture2D);
material_AlphaCutoff("Alpha Cutoff", Range(0, 1, 0.01)) = 0;
Header("Common"){
isTransparent("Transparent", Boolean) = false;
renderFace("Render Face", Enum(Front:0, Back:1, Double:2)) = 0;
blendMode("Blend Mode", Enum(Normal:0, Additive:1)) = 0;
}
}
UIScript "${uiScriptPath}";
}
SubShader "Default" {
UsePass "pbr/Default/ShadowCaster"
Pass "Pass0" {
DepthState {
WriteEnabled = depthWriteEnabled;
}
BlendState {
Enabled = blendEnabled;
SourceColorBlendFactor = sourceColorBlendFactor;
DestinationColorBlendFactor = destinationColorBlendFactor;
SourceAlphaBlendFactor = sourceAlphaBlendFactor;
DestinationAlphaBlendFactor = destinationAlphaBlendFactor;
}
RasterState{
CullMode = rasterStateCullMode;
}
RenderQueueType = renderQueueType;
struct Attributes {
vec3 POSITION;
vec2 TEXCOORD_0;
vec4 JOINTS_0;
vec4 WEIGHTS_0;
};
struct Varyings {
vec2 uv;
};
#include "Common.glsl"
#include "Skin.glsl"
#include "Transform.glsl"
vec4 material_BaseColor;
float material_AlphaCutoff;
sampler2D material_BaseTexture;
VertexShader = vert;
FragmentShader = frag;
Varyings vert(Attributes attr) {
Varyings v;
vec4 position = vec4(attr.POSITION, 1.0);
// Skin
#ifdef RENDERER_HAS_SKIN
mat4 skinMatrix = getSkinMatrix(attr);
position = skinMatrix * position;
#endif
gl_Position = renderer_MVPMat * position;
v.uv = attr.TEXCOORD_0;
return v;
}
void frag(Varyings v) {
vec4 baseColor = material_BaseColor;
#ifdef MATERIAL_HAS_BASETEXTURE
vec4 textureColor = texture2D(material_BaseTexture, v.uv);
#ifndef ENGINE_IS_COLORSPACE_GAMMA
textureColor = gammaToLinear(textureColor);
#endif
baseColor *= textureColor;
#endif
#ifdef MATERIAL_IS_ALPHA_CUTOFF
if( baseColor.a < material_AlphaCutoff ) {
discard;
}
#endif
gl_FragColor = baseColor;
#ifndef ENGINE_IS_COLORSPACE_GAMMA
gl_FragColor = linearToGamma(gl_FragColor);
#endif
}
}
}
}