Files
engine/docs/en/graphics/material/shaderAPI.mdx
shensi.zxd dd02420acc feat(core): GPU Instancing 自动合批(cherry-pick from galacean/engine#2957)
从 PR https://github.com/galacean/engine/pull/2957 (feat/gpu-instancing)
cherry-pick 69 个 commit 到 fix/shaderlab 分支,压缩为单次提交。

## 核心改动

### 新增文件
- `InstanceBuffer.ts` — UBO-based 实例数据管理,将多个 renderer 的
  worldMatrix/shaderData 打包到一个 UBO 中
- `VertexMergeBatcher.ts` — 替代旧 BatchUtils,统一 2D/3D 合批入口
- `ShaderBlockProperty.ts` — UBO block 属性描述
- `ShaderProgramMap.ts` — 替代旧 ShaderProgramPool,支持 instancing layout 缓存
- `ConstantBufferBindingPoint.ts` — UBO binding point 枚举

### 修改文件
- `MeshRenderer._canBatch/_batch` — 同 mesh+material+macros 自动合批判定
- `SkinnedMeshRenderer` — 标记不可 GPU instance
- `RenderQueue` — 按 material/primitive 排序(替代按距离排序),
  渲染时检测 instanced batch 并通过 InstanceBuffer 一次 draw
- `RenderElement` — 扁平化(移除 SubRenderElement),支持 instancedRenderers 列表
- `ShaderFactory` — UBO 布局计算、instancing GLSL 注入(RENDERER_GPU_INSTANCE macro)
- `ShaderPass` — 编译时检测 GPU instance macro,注入 UBO 声明
- `ShaderProgram` — 存储 instanceLayout
- `Renderer` — 移除 batched 相关字段

### 删除文件
- `BatchUtils.ts` → 替换为 `VertexMergeBatcher.ts`
- `SubRenderElement.ts` → 合并到 `RenderElement.ts`
- `ShaderProgramPool.ts` → 替换为 `ShaderProgramMap.ts`

## cherry-pick 冲突解决记录

fix/shaderlab 分支和 PR 基线 (dev/2.0) 的差异主要在以下文件:

1. **ShaderPass.ts** — fix/shaderlab 使用 `Shader._shaderLab._parseMacros`
   处理 ShaderLab 宏,而 PR 使用 `ShaderMacroProcessor.evaluate`(fix/shaderlab
   上不存在)。解决方式:保留 fix/shaderlab 的宏处理,加入 PR 的 instancing
   UBO 注入逻辑。
2. **Transform.glsl** — fix/shaderlab 已有 `camera_VPMat` 声明,PR 也添加了。
   解决方式:合并两边声明。
3. **UIRenderer.ts** — PR 将 `BatchUtils` 重命名为 `VertexMergeBatcher`,
   `batchFor2D` 重命名为 `batch`。fix/shaderlab 的 UI 包未同步。
   解决方式:手动更新 UI 包的 import 和调用。
4. **GLSLIfdefResolver.ts** — PR 早期 commit 新增此文件,后续 commit 删除。
   cherry-pick 后 ShaderPass.ts 残留了 import。解决方式:删除无用 import。

## 验证结果

CarParking 游戏 DrawCall 从 905 降至 ~80(同 mesh+material 的座椅、轮子等
自动合批)。
2026-04-23 17:26:31 +08:00

196 lines
7.4 KiB
Plaintext

---
title: Shader API
---
## Common API
The API is used as follows:
```glsl
#include "Common.glsl"
float f2 = pow2(0.5);
```
### Common
This module provides commonly used macros such as `PI`, and general-purpose functions like `gammaToLinear` and `pow2`. See the [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/Common.glsl) for details. ### Fog
Provides a fog effect function:
```glsl
vec4 fog(vec4 color, vec3 positionVS);
```
### Transform
Provides system variables for model space, view space, world space, and camera coordinates:
```glsl
mat4 renderer_ModelMat;
mat4 camera_ViewMat;
mat4 camera_ProjMat;
mat4 renderer_MVMat;
mat4 renderer_MVPMat;
mat4 renderer_NormalMat;
vec3 camera_Position;
vec3 camera_Forward;
vec4 camera_ProjectionParams;
```
### Light
Provides methods to access engine lighting information, including direct and indirect lighting:
```glsl
// Direct light
DirectLight getDirectLight(int index);
PointLight getPointLight(int index);
SpotLight getSpotLight(int index);
// Indirect light
EnvMapLight scene_EnvMapLight;
#ifdef SCENE_USE_SH
vec3 scene_EnvSH[9];
#endif
#ifdef SCENE_USE_SPECULAR_ENV
samplerCube scene_EnvSpecularSampler;
#endif
```
### Normal
Provides some common methods for normal calculation:
```glsl
// Normal after normal mapping in tangent space
vec3 getNormalByNormalTexture(mat3 tbn, sampler2D normalTexture, float normalIntensity, vec2 uv, bool isFrontFacing);
// Calculate tangent using derivatives, for models without pre-calculated tangents
mat3 getTBNByDerivatives(vec2 uv, vec3 normal, vec3 position, bool isFrontFacing);
```
### Shadow
Provides shadow-related functions. See the [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/Shadow.glsl) for details. ```glsl
// Get the cascade index of the shadow map, e.g., if the number of cascades is 4, it returns 0~3
int computeCascadeIndex(vec3 positionWS);
// Get the coordinate in the shadow map
vec3 getShadowCoord(vec3 positionWS);
// Get the shadow intensity, including sampling method and shadow attenuation
float sampleShadowMap(vec3 positionWS, vec3 shadowCoord);
```
### Skin
Provides skeletal animation calculation methods:
```glsl
mat4 getSkinMatrix(Attributes attributes);
```
### BlendShape
Provides blend shape calculation methods:
```glsl
void calculateBlendShape(Attributes attributes, inout vec4 position, inout vec3 normal, inout vec4 tangent);
```
## PBR API
Besides the general API, PBR also encapsulates APIs for various lighting models, such as `BSDF`. Users can reuse these APIs by using `#include` when extending other materials.
### AttributesPBR
Encapsulates all attribute variables required for PBR. See [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/AttributesPBR.glsl).
### VaryingsPBR
Encapsulates all varying variables required for PBR. See [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/VaryingsPBR.glsl).
### LightDirectPBR
Encapsulates direct light calculation based on the BSDF lighting model. See [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/LightDirectPBR.glsl). Generally, you can call it directly:
```glsl
// Evaluate direct lighting
evaluateDirectRadiance(varyings, surfaceData, bsdfData, shadowAttenuation, totalDiffuseColor, totalSpecularColor);
```
The following function overload macros are provided to cover the key calculations of the lighting model:
```glsl
#define FUNCTION_SURFACE_SHADING surfaceShading
#define FUNCTION_DIFFUSE_LOBE diffuseLobe
#define FUNCTION_SPECULAR_LOBE specularLobe
#define FUNCTION_CLEAR_COAT_LOBE clearCoatLobe
#define FUNCTION_SHEEN_LOBE sheenLobe
void surfaceShading(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 lightColor, inout vec3 totalDiffuseColor, inout vec3 totalSpecularColor);
void diffuseLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 attenuationIrradiance, inout vec3 diffuseColor);
void specularLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 specularColor);
float clearCoatLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 color, inout vec3 specularColor);
void sheenLobe(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 diffuseColor, inout vec3 specularColor);
```
### LightInDirectPBR
This encapsulates the calculation of [ambient light](/en/docs/graphics/light/ambient) based on the BSDF lighting model. See the [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/LightIndirectPBR.glsl) for details. Generally, you can call it directly:
```glsl
// IBL
evaluateIBL(varyings, surfaceData, bsdfData, totalDiffuseColor, totalSpecularColor);
```
The following function overload macros are provided to cover the key calculations of the lighting model:
```glsl
#define FUNCTION_DIFFUSE_IBL evaluateDiffuseIBL
#define FUNCTION_SPECULAR_IBL evaluateSpecularIBL
#define FUNCTION_CLEAR_COAT_IBL evaluateClearCoatIBL
#define FUNCTION_SHEEN_IBL evaluateSheenIBL
void evaluateDiffuseIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 diffuseColor);
void evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float radianceAttenuation, inout vec3 outSpecularColor);
float evaluateClearCoatIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 specularColor);
void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor);
```
### VertexPBR
Some methods required by the PBR vertex shader, such as obtaining the UV coordinates after TilingOffset, obtaining the world coordinates, normals, and tangents after bone and BS calculations, etc., please refer to the [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/VertexPBR.glsl).
```glsl showLineNumbers
VertexInputs vertexInputs = getVertexInputs(attributes);
gl_Position = renderer_MVPMat * vertexInputs.positionOS;
```
### BSDF
This is a key file for the PBR lighting model, encapsulating common calculation functions for BRDF, projection, refraction, etc., as well as the `SurfaceData` and `BSDFData` structures used in subsequent lighting model calculations. See [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/BSDF.glsl) for details.
### FragmentPBR
This file contains numerous variables passed from the CPU, such as metalness, roughness, and textures. It initializes the `SurfaceData` structure using `getSurfaceData`. See [source code](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/FragmentPBR.glsl) for details.
```glsl showLineNumbers
BSDFData bsdfData;
// Initialize the SurfaceData structure
SurfaceData surfaceData = getSurfaceData(varyings, aoUV, gl_FrontFacing);
// You can process the data in SurfaceData here
initBSDFData(surfaceData, bsdfData);
```
### Finally
Besides the functionality and usage of key APIs, the overall file organization can be referenced in the official website's [ForwardPassPBR](https://github.com/galacean/engine/blob/main/packages/shader/src/shaders/shadingPBR/ForwardPassPBR.glsl).