跳到主要内容

工作缓冲区渲染

渲染操作绘制工作缓冲区的排序单元,可全局定制效果、读取复制阶段的自定义数据或修改全部单元外观。

备注

此功能基于渲染架构。

管线概览​

复制并排序后,渲染操作绘制结果:

不同于逐组件复制修改器,渲染修改器是全局的,影响工作缓冲区全部单元。

定制渲染操作​

在全局材质用 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。

例如:

流名加载函数
splatIdloadSplatId(), loadSplatIdWithIndex(index) → uvec4
customDataloadCustomData(), 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);

用途​

逐组件上色​

结合工作格式定制,可识别所属组件并应用独立颜色:

  1. 复制时写入组件 ID。
  2. 绘制时读取 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。
  • 从纹理查颜色。
  • 动画式逐组件染色。

另请参见​