跳到主要内容

片元阶段

gsplatModifyPS 在片元阶段定制最终颜色,每覆盖像素一次,允许效果在单元覆盖范围内平滑变化,逐单元顶点阶段无法做到这一点。

查看实时示例:每个单元绘制为自身颜色的圆环,并带高亮波。

查看实时示例

可覆盖函数​

只覆盖一个函数:

void modifySplatColor(vec2 gaussianUV, inout vec4 color);

它在前向通道、高斯衰减和不透明度抖动之后,预乘颜色与输出之前调用:

  • gaussianUV:片元在覆盖范围内的位置,中心为 (0,0),裁剪边缘长度为 1。dot(gaussianUV, gaussianUV) 是衰减使用的归一化半径平方。
  • color:rgb 为单元颜色,a 为最终片元 alpha。均可修改,alpha 影响混合权重,可自定义衰减或逐像素淡出。

可用输入​

代码块还可访问:

  • gl_FragCoord(GLSL)或 pcPosition(WGSL):片元在帧缓冲区中的像素位置。
  • screen_size:引擎提供的 vec4/vec4f,xy 为画布绘制缓冲区像素尺寸,zw 为倒数。与 viewport_size 的区别见内置 uniform。
  • 自行声明并通过材质参数驱动的 uniform 与纹理。

示例​

示例将每个单元绘制为自身颜色的圆环。gaussianUV 给出内部位置,fwidth 将要求的像素环宽转为覆盖范围单位,让任意缩放下屏幕宽度恒定:

uniform float uRingWidth;
uniform float uRingAlpha;

void modifySplatColor(vec2 gaussianUV, inout vec4 color) {
// distance from the splat center: 0 at center, 1 at the clipping edge
float radius = length(gaussianUV);

// ring of constant screen-space width at the splat edge - fwidth gives the
// change of radius per screen pixel, converting pixels to radius units
float radiusPerPixel = fwidth(radius);
float innerEdge = 1.0 - uRingWidth * radiusPerPixel;
float ring = smoothstep(innerEdge - radiusPerPixel, innerEdge, radius);
color.a = ring * uRingAlpha;
}

与顶点代码块相同,用 gsplatModifyPS 键应用,再通过材质参数驱动:

const sceneMat = app.scene.gsplat.material;

sceneMat.getShaderChunks('glsl').set('gsplatModifyPS', glslFragShader);
sceneMat.getShaderChunks('wgsl').set('gsplatModifyPS', wgslFragShader);
sceneMat.setParameter('uRingWidth', 1);
sceneMat.setParameter('uRingAlpha', 0.25);
sceneMat.update();

按每片元屏幕位置采样对齐纹理的效果,参见重新光照,它利用离屏代理网格光照调制单元。

另请参见​