跳到主要内容

高斯泼溅数据处理

GSplatProcessor 通过自定义着色器在 GPU 处理数据,从源纹理流读取并写入目标,支持绘画、选择、删除和变换。

备注

此功能基于渲染架构。

概览​

位置、旋转、缩放和颜色保存在纹理流,可通过数据格式添加自定义流。

处理器允许:

  • 用生成的加载函数读取源流。
  • 用生成的写函数写入目标流。
  • 在 GPU 并行处理全部单元。

适用于:

  • 按笔刷位置绘画。
  • 标记选择或删除。
  • 变换数据。
  • 自定义逐单元效果。

基本用法​

1. 创建处理器​

指定源、目标和逐单元处理代码:

const processor = new pc.GSplatProcessor(
app.graphicsDevice,
{ component: entity.gsplat }, // source
{ component: entity.gsplat, streams: ['customColor'] }, // destination
{
processGLSL: `
uniform vec4 uBrushSphere; // xyz = position, w = radius
uniform vec4 uBrushColor;

void process() {
vec3 center = getCenter();
float dist = distance(center, uBrushSphere.xyz);
if (dist < uBrushSphere.w) {
writeCustomColor(uBrushColor);
} else {
writeCustomColor(vec4(0.0));
}
}
`,
processWGSL: `
uniform uBrushSphere: vec4f;
uniform uBrushColor: vec4f;

fn process() {
let center = getCenter();
let dist = distance(center, uniform.uBrushSphere.xyz);
if (dist < uniform.uBrushSphere.w) {
writeCustomColor(uniform.uBrushColor);
} else {
writeCustomColor(vec4f(0.0));
}
}
`
}
);

2. 设置参数并执行​

设置 uniform,再执行处理:

// Set uniforms for the processing shader
processor.setParameter('uBrushSphere', [x, y, z, radius]);
processor.setParameter('uBrushColor', [1, 0, 0, 1]);

// Execute the processing pass
processor.process();

构造函数​

new pc.GSplatProcessor(device, source, destination, options)

参数:

参数类型说明
deviceGraphicsDevice图形设备
sourceGSplatProcessorBinding源绑定
destinationGSplatProcessorBinding目标绑定
options.processGLSLstringWebGL 必需的 GLSL
options.processWGSLstringWebGPU 必需的 WGSL

GSplatProcessorBinding​

{
resource?: GSplatResourceBase, // Direct resource reference
component?: GSplatComponent, // Component (resource resolved automatically)
streams?: string[] // Stream names to bind
}

使用实例流 GSPLAT_STREAM_INSTANCE 时,必须指定 component,访问对应纹理。

源未指定 streams 时,自动绑定格式流,提供 getCenter、getColor、getRotation、getScale。源目标不同资源时,可读取源全部流;同一资源时,正在写的流不可读。

目标必须提供 streams,指定写哪些流。

不同资源大小​

源和目标可有不同单元数。process() 对每个目标单元执行一次,当前目标索引为 splat.index:

void process() {
uint destIndex = splat.index; // Current destination splat index

// Calculate which source splat to read from
uint sourceIndex = destIndex * 2; // Example: sample every other splat
setSplat(sourceIndex);
vec3 srcPos = getCenter();

// Write to destination
writePosition(vec4(srcPos, 1.0));
}

也可用 WithIndex 直接读取任意源单元,不改变当前上下文。

因此支持:

  • 从大源复制到小目标,降采样。
  • 根据采样源生成目标。
  • 不同单元数之间映射。

着色器函数​

内置 uniform​

自动提供:

Uniform类型说明
srcNumSplatsuint源单元数
dstNumSplatsuint目标单元数

splat.index >= dstNumSplats 的填充像素自动跳过。

读取源​

未指定源流时提供:

函数返回说明
getCenter()vec3位置,必须先调用
getColor()vec4颜色
getRotation()vec4四元数
getScale()vec3缩放

读取其他索引​

默认读自身,通过 setSplat(index) 切换:

// GLSL - Read from neighbor splat
setSplat(neighborIndex);
vec3 neighborPos = getCenter();
vec4 neighborColor = getColor();

各加载函数也有 WithIndex 直接访问变体:

// GLSL - Read specific stream from another index
vec4 otherCenter = loadDataCenterWithIndex(neighborIndex);

适合比较或合并多个单元的算法。

写入目标​

每目标流生成 write{StreamName}(value)。

例如 customColor 生成 writeCustomColor(vec4 value)。

API​

setParameter(name, value)​

设置 uniform。

// Scalar
processor.setParameter('uRadius', 0.5);

// Vector (as array)
processor.setParameter('uBrushPos', [x, y, z]);

// Texture
processor.setParameter('uBrushTex', brushTexture);

getParameter(name)​

读取已设参数。

deleteParameter(name)​

删除参数。

process()​

执行通道,读源写目标。

destroy()​

释放全部 GPU 资源,使用结束时调用。

blendState​

设置混合状态,适合叠加绘画等累积效果:

processor.blendState = pc.BlendState.ADDBLEND;

用途​

绘画​

为笔刷半径内单元上色:

void process() {
vec3 center = getCenter();
float dist = distance(center, uBrushPos.xyz);
if (dist < uBrushRadius) {
float falloff = 1.0 - (dist / uBrushRadius);
writeCustomColor(uBrushColor * falloff);
} else {
writeCustomColor(vec4(0.0));
}
}

选择​

选择 AABB 内单元:

void process() {
vec3 center = getCenter();
bool inside = all(greaterThan(center, uSelectionMin)) &&
all(lessThan(center, uSelectionMax));
writeSelection(inside ? vec4(1.0) : vec4(0.0));
}

删除与可见性​

标为不可见:

void process() {
vec3 center = getCenter();
float visible = distance(center, uDeletePos) > uDeleteRadius ? 1.0 : 0.0;
writeVisible(vec4(visible));
}

实时示例​

  • Paint:笔刷绘画。
绘画示例
  • Editor:选择、删除和克隆。
编辑器示例

另请参见​