Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 52 additions & 32 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions packages/dev/core/src/Engines/WebGPU/webgpuDrawContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ export class WebGPUDrawContext implements IDrawContext {
this._bufferManager.setRawData(this.indirectDrawBuffer, 0, this._indirectDrawData, 0, 20);
}

/**
* Setup or disable vertex pulling as needed.
* @param useVertexPulling Use vertex pulling or not
* @param webgpuPipelineContext The WebGPU pipeline context
* @param vertexBuffers The current vertex buffers
* @param indexBuffer The current index buffer
* @param overrideVertexBuffers The vertex buffers to override
*/
public setVertexPulling(
useVertexPulling: boolean,
webgpuPipelineContext: WebGPUPipelineContext,
Expand Down
94 changes: 94 additions & 0 deletions packages/dev/core/src/Materials/materialHelper.functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { MaterialFlags } from "./materialFlags";
import { Texture } from "./Textures/texture";
import type { CubeTexture } from "./Textures/cubeTexture";
import type { Color3 } from "core/Maths/math.color";
import type { Geometry } from "../Meshes/geometry";
import { Vector3 } from "core/Maths/math.vector";

// For backwards compatibility, we export everything from the pure version of this file.
export * from "./materialHelper.functions.pure";
Expand Down Expand Up @@ -598,6 +600,98 @@ export function GetFogState(mesh: AbstractMesh, scene: Scene) {
return scene.fogEnabled && mesh.applyFog && scene.fogMode !== Constants.FOGMODE_NONE;
}

/**
* Interface representing metadata for vertex pulling
*/
export interface IVertexPullingMetadata {
/**
* Offset in vertex buffer where data starts
*/
offset: number;

/**
* Stride between elements in the vertex buffer
*/
stride: number;

/**
* Type of the vertex buffer (e.g., float, int)
*/
type: number; // VertexBuffer type constant
}

// Store vertex pulling metadata per geometry
const _VertexPullingMetadataCache = new WeakMap<Geometry, Map<string, IVertexPullingMetadata>>();

/**
* Prepares vertex pulling uniforms for the given attributes and mesh
* @param geometry The geometry containing the vertex buffers
* @returns A map of attribute names to their metadata, or null if unavailable
*/
export function PrepareVertexPullingUniforms(geometry: Geometry): Nullable<Map<string, IVertexPullingMetadata>> {
if (!geometry) {
return null;
}
const vertexBuffers = geometry.getVertexBuffers();
if (!vertexBuffers) {
return null;
}

// Check cache first
let metadata = _VertexPullingMetadataCache.get(geometry);
if (!metadata) {
metadata = new Map<string, IVertexPullingMetadata>();
_VertexPullingMetadataCache.set(geometry, metadata);
} else {
// Return cached metadata if it exists and hasn't changed
let needsUpdate = false;
for (const vb in vertexBuffers) {
if (!metadata.has(vb)) {
needsUpdate = true;
break;
}
}
if (!needsUpdate) {
return metadata;
}
}

// Build or update metadata
for (const vb in vertexBuffers) {
const vertexBuffer = vertexBuffers[vb];
if (vertexBuffer) {
const offset = vertexBuffer.byteOffset;
const stride = vertexBuffer.byteStride;
const type = vertexBuffer.type;

metadata.set(vb, {
offset: offset,
stride: stride,
type: type,
});
}
}

return metadata;
}

/**
* Bind vertex pulling uniforms to the effect
* @param effect The effect to bind the uniforms to
* @param metadata The vertex pulling metadata
*/
export function BindVertexPullingUniforms(effect: Effect, metadata: Map<string, IVertexPullingMetadata>): void {
if (!metadata || !effect) {
return;
}

for (const [attribute, data] of metadata.entries()) {
const uniformName = `vp_${attribute}_info`;
// Pack into vec3: (offset, stride, type)
effect.setVector3(uniformName, new Vector3(data.offset, data.stride, data.type));
}
}

/**
* Helper used to prepare the list of defines associated with misc. values for shader compilation
* @param mesh defines the current mesh
Expand Down
16 changes: 15 additions & 1 deletion packages/dev/core/src/Materials/shaderMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ import {
BindMorphTargetParameters,
BindSceneUniformBuffer,
PrepareDefinesAndAttributesForMorphTargets,
PrepareVertexPullingUniforms,
BindVertexPullingUniforms,
PushAttributesForInstances,
} from "./materialHelper.functions";
import type { IVertexPullingMetadata } from "./materialHelper.functions";
import type { IColor3Like, IColor4Like, IVector2Like, IVector3Like, IVector4Like } from "core/Maths/math.like";
import type { InternalTexture } from "./Textures/internalTexture";

Expand Down Expand Up @@ -147,6 +150,7 @@ export class ShaderMaterial extends PushMaterial {
private _cachedWorldViewMatrix = new Matrix();
private _cachedWorldViewProjectionMatrix = new Matrix();
private _multiview = false;
private _vertexPullingMetadata: Map<string, IVertexPullingMetadata> | null = null;

/**
* @internal
Expand Down Expand Up @@ -909,12 +913,18 @@ export class ShaderMaterial extends PushMaterial {
defines.push("#define USE_VERTEX_PULLING");

const indexBuffer = renderingMesh.geometry?.getIndexBuffer();
if (indexBuffer) {
if (indexBuffer && !(renderingMesh as Mesh).isUnIndexed) {
defines.push("#define VERTEX_PULLING_USE_INDEX_BUFFER");
if (indexBuffer.is32Bits) {
defines.push("#define VERTEX_PULLING_INDEX_BUFFER_32BITS");
}
}

// Add vertex buffer metadata defines for proper stride/offset handling
const geometry = renderingMesh.geometry;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to use the new PrepareDefinesForVertexPullingMetadata function instead?

Also, I think we should pass stride and offset as a byte count instead of a float count, to more easily handle all type conversions we will have to support (for example, type of position could be a (u)byte, (u)short, (u)int, float, and for the integer types, they could be normalized or not - these are type conversions we will have to perform in the shader).

Another thing is that we should probably use uniforms and not defines to pass data, else we will basically generate a new shader for each mesh, as (at least) offset will be different for each mesh.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, good idea. I've changed to uniforms now.

if (geometry) {
this._vertexPullingMetadata = PrepareVertexPullingUniforms(geometry);
}
}

const drawWrapper = storeEffectOnSubMeshes ? subMesh._getDrawWrapper(undefined, true) : this._drawWrapper;
Expand Down Expand Up @@ -1085,6 +1095,10 @@ export class ShaderMaterial extends PushMaterial {
// Clip plane
BindClipPlane(effect, this, scene);

if (this._vertexPullingMetadata) {
BindVertexPullingUniforms(effect, this._vertexPullingMetadata);
}

// Misc
if (this._useLogarithmicDepth) {
BindLogDepth(storeEffectOnSubMeshes ? subMesh.materialDefines : effect.defines, effect, scene);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,9 @@ export class _IblShadowsVoxelRenderer {
* @param includedMeshes
*/
public updateVoxelGrid(includedMeshes: Mesh[]) {
if (this._voxelizationInProgress) {
return;
}
this._stopVoxelization();
this._includedMeshes = includedMeshes;
this._voxelizationInProgress = true;
Expand Down Expand Up @@ -738,6 +741,7 @@ export class _IblShadowsVoxelRenderer {
if (axis === 1) {
upDirection = new Vector3(1, 0, 0);
}
mrt.onBeforeRenderObservable.clear();
mrt.onBeforeRenderObservable.add(() => {
voxelMaterial.setMatrix("viewMatrix", Matrix.LookAtLH(cameraPosition, targetPosition, upDirection));
voxelMaterial.setMatrix("invWorldScale", this._invWorldScaleMatrix);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#if NUM_BONE_INFLUENCERS > 0
attribute matricesIndices : vec4<f32>;
attribute matricesWeights : vec4<f32>;
attribute matricesIndices : vec4f;
attribute matricesWeights : vec4f;
#if NUM_BONE_INFLUENCERS > 4
attribute matricesIndicesExtra : vec4<f32>;
attribute matricesWeightsExtra : vec4<f32>;
attribute matricesIndicesExtra : vec4f;
attribute matricesWeightsExtra : vec4f;
#endif

#ifndef BAKED_VERTEX_ANIMATION_TEXTURE
Expand Down
Loading
Loading