Analogue of QuadRender
The engine is clearly missing a public analogue of QuadRender that would allow rendering not only a single quad, but also arbitrary primitives — points, lines, triangles, and so on. This would provide flexibility for drawing non-standard geometries without the need to manually create and manage custom buffers.
https://github.com/playcanvas/engine/blob/e48af3dd66f0a3e30f377eb386a391975bb250b4/src/scene/graphics/quad-render.js#L152
@mvaligursky
Example of bypass:
const primitive = {
type: pc.PRIMITIVE_POINTS,
base: 0,
baseVertex: 0,
count: 0,
indexed: false
}
export class PointsRenderPass extends pc.RenderPass {
count = 0;
shader: pcx.Shader;
vertexBuffer: pcx.VertexBuffer;
cullMode = pc.CULLFACE_NONE;
blendState = pc.BlendState.NOBLEND;
depthState = pc.DepthState.NODEPTH;
stencilFront = null;
stencilBack = null;
quadRender: pcx.QuadRender;
constructor(shader: pcx.Shader) {
super(shader.device);
this.quadRender = new pc.QuadRender(shader);
}
destroy(): void {
super.destroy();
this.quadRender.destroy();
}
execute() {
primitive.count = this.count;
// render state
const device = this.device as pcx.WebgpuGraphicsDevice;
device.setBlendState(this.blendState);
device.setCullMode(this.cullMode);
device.setDepthState(this.depthState);
device.setStencilState(this.stencilFront!, this.stencilBack!);
device.setVertexBuffer(this.vertexBuffer);
device.setShader(this.quadRender.shader);
if (device.supportsUniformBuffers) {
// not using view bind group
device.setBindGroup(pc.BINDGROUP_VIEW, device.emptyBindGroup);
// mesh bind group
const bindGroup = this.quadRender.bindGroup;
bindGroup.update();
device.setBindGroup(pc.BINDGROUP_MESH, bindGroup);
// dynamic uniform buffer bind group
const uniformBuffer = this.quadRender.uniformBuffer;
if (uniformBuffer) {
uniformBuffer.update(_dynamicBindGroup);
device.setBindGroup(pc.BINDGROUP_MESH_UB, _dynamicBindGroup.bindGroup, _dynamicBindGroup.offsets);
} else {
device.setBindGroup(pc.BINDGROUP_MESH_UB, device.emptyBindGroup);
}
}
// @ts-ignore
device.draw(primitive);
}
}
Do you have any ideas on how to perform point rendering directly into a texture on the GPU side, with the ability to ping-pong data between multiple textures for iterative computations?
const vertexCode =
`
attribute uvec2 aPointPos;
uniform highp usampler2D uInTexture;
highp vec2 getPosition(out uvec4 data) {
vec2 sz = vec2(textureSize(uInTexture, 0));
vec2 uv = (vec2(aPointPos) + 0.5) / sz;
highp vec2 xy = uv * 2.0 - 1.0;
data = texelFetch(uInTexture, ivec2(aPointPos), 0);
return xy;
}
flat varying uvec4 vData;
void main(void) {
uvec4 inData;
highp vec2 pixelCoord = getPosition(inData);
highp vec4 position = vec4(pixelCoord, 0.0, 1.0);
vData = inData;
// some changes
vData.z = 123u;
gl_PointSize = 1.0;
gl_Position = position;
}
`;
const fragmentCodePS =
`
flat varying uvec4 vData;
void main(void) {
pcFragColor0 = vData;
}
`;
Do you have any ideas on how to perform point rendering directly into a texture on the GPU side, with the ability to ping-pong data between multiple textures for iterative computations?
why not render a quad to that texture and update data per fragment in fragment shader?
Do you have any ideas on how to perform point rendering directly into a texture on the GPU side, with the ability to ping-pong data between multiple textures for iterative computations?
why not render a quad to that texture and update data per fragment in fragment shader?
The pixels that need to be updated can be located in completely different areas of the source texture, and the related data resides in a third texture. The update process must occur entirely on the GPU, without CPU involvement, which means a mechanism similar to a compute shader is required. This mechanism would take as input a list of pixel coordinates and output an updated texture. In other words, it’s a GPU-based selective pixel update procedure that modifies specified pixels only, using a list of indices as input and writing equivalent fragment-shader-based FBO approach.
The engine is clearly missing a public analogue of QuadRender that would allow rendering not only a single quad, but also arbitrary primitives — points, lines, triangles, and so on.
I think MeshInstance is exactly that.