工作缓冲区渲染
渲染操作绘制工作缓冲区的排序单元,可全局定制效果、读取复制阶段的自定义数据或修改全部单元外观。
备注
此功能基于渲染架构。
管线概览
复制并排序后,渲染操作绘制结果:
不同于逐组件复制修改器,渲染修改器是全局的,影响工作缓冲区全部单元。
定制渲染操作
在全局材质用 getShaderChunks() 设置 gsplatModifyVS:
const glslModifier = `
void modifySplatCenter(inout vec3 center) {}
void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter,
inout vec4 rotation, inout vec3 scale) {}
void modifySplatColor(vec3 center, inout vec4 color) {
// Apply global color grading
color.rgb = pow(color.rgb, vec3(0.8));
}
`;
const wgslModifier = `
fn modifySplatCenter(center: ptr<function, vec3f>) {}
fn modifySplatRotationScale(originalCenter: vec3f, modifiedCenter: vec3f,
rotation: ptr<function, vec4f>, scale: ptr<function, vec3f>) {}
fn modifySplatColor(center: vec3f, color: ptr<function, vec4f>) {
*color = vec4f(pow((*color).rgb, vec3f(0.8)), (*color).a);
}
`;
app.scene.gsplat.material.getShaderChunks('glsl').set('gsplatModifyVS', glslModifier);
app.scene.gsplat.material.getShaderChunks('wgsl').set('gsplatModifyVS', wgslModifier);
app.scene.gsplat.material.update();
修改函数
必须实现三个函数:
| 函数 | 用途 |
|---|---|
modifySplatCenter(inout vec3 center) | 修改位置 |
modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter, inout vec4 rotation, inout vec3 scale) | 修改旋转和缩放 |
modifySplatColor(vec3 center, inout vec4 color) | 根据工作缓冲数据修改颜色 |
modifySplatCenter 先执行,可读取额外流、保存全局变量或完成公共工作。
除顶点修改器外,还可用 gsplatModifyPS 逐像素定制,参见片元阶段。
移除修改器
恢复默认:
app.scene.gsplat.material.getShaderChunks('glsl').delete('gsplatModifyVS');
app.scene.gsplat.material.getShaderChunks('wgsl').delete('gsplatModifyVS');
app.scene.gsplat.material.update();
读取额外流
在工作格式添加流并复制写入后,可在绘制时通过加载函数读取。
每条生成 load{StreamName}(),例如 splatId 对应 loadSplatId():
const glslModifier = `
uniform sampler2D uColorLookup;
void modifySplatCenter(inout vec3 center) {}
void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter,
inout vec4 rotation, inout vec3 scale) {}
void modifySplatColor(vec3 center, inout vec4 color) {
// Read component ID written during copy
uint id = loadSplatId().r;
// Look up color from texture based on component ID
vec3 tintColor = texelFetch(uColorLookup, ivec2(int(id), 0), 0).rgb;
color.rgb *= tintColor;
}
`;
生成的加载函数
各流生成两个:
| 函数 | 说明 |
|---|---|
load{StreamName}() | 当前单元 |
load{StreamName}WithIndex(index) | 指定索引 |
返回类型依像素格式:
- 浮点,例如 RGBA32F、RGBA16F:vec4。
- 无符号整数,例如 R32U:uvec4。
- 有符号整数:ivec4。
例如:
| 流名 | 加载函数 |
|---|---|
splatId | loadSplatId(), loadSplatIdWithIndex(index) → uvec4 |
customData | loadCustomData(), loadCustomDataWithIndex(index) → vec4 |
从其他索引读取多个属性时,用 setSplat(index) 切换:
setSplat(otherIndex);
uint otherId = loadSplatId().r;
vec4 otherData = loadCustomData();
传入 uniform
全局材质通过 setParameter() 传值:
// Create a color lookup texture
const colorTexture = new pc.Texture(device, {
width: 256,
height: 1,
format: pc.PIXELFORMAT_RGBA32F,
// ... other options
});
// Pass texture to the render shader
app.scene.gsplat.material.setParameter('uColorLookup', colorTexture);
用途
逐组件上色
结合工作格式定制,可识别所属组件并应用独立颜色:
- 复制时写入组件 ID。
- 绘制时读取 ID,从纹理查颜色。
const glslModifier = `
uniform sampler2D uColorLookup;
uint componentId; // Global variable accessible by all modifier functions
void modifySplatCenter(inout vec3 center) {
// Read ID from work buffer (can be used in other functions)
componentId = loadSplatId().r;
}
void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter,
inout vec4 rotation, inout vec3 scale) {}
void modifySplatColor(vec3 center, inout vec4 color) {
// Look up color from texture based on component ID
vec3 tintColor = texelFetch(uColorLookup, ivec2(int(componentId), 0), 0).rgb;
color.rgb *= tintColor;
}
`;
实时示例
LOD Instances 演示:
LOD 实例示例
- 读取复制时写入的 ID。
- 从纹理查颜色。
- 动画式逐组件染色。