Skip to content

Commit 25effe0

Browse files
mvaligurskyMartin Valigursky
andauthored
Add WebGPU support to instancing-custom example - custom WGSL shader (#8186)
Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
1 parent 5989f00 commit 25effe0

4 files changed

Lines changed: 58 additions & 28 deletions

File tree

examples/src/examples/graphics/instancing-custom.example.mjs

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// @config DESCRIPTION This example demonstrates how to customize the shader handling the instancing of a StandardMaterial.
2+
import files from 'examples/files';
23
import { deviceType, rootPath } from 'examples/utils';
34
import * as pc from 'playcanvas';
45

@@ -96,34 +97,8 @@ assetListLoader.load(() => {
9697

9798
// and a custom instancing shader chunk, which will be used in case the mesh instance has instancing enabled
9899
material.shaderChunksVersion = '2.8';
99-
material.getShaderChunks(pc.SHADERLANGUAGE_GLSL).set('transformInstancingVS', `
100-
101-
// instancing attributes
102-
attribute vec3 aInstPosition;
103-
attribute float aInstScale;
104-
105-
// uniforms
106-
uniform float uTime;
107-
uniform vec3 uCenter;
108-
109-
// all instancing chunk needs to do is to implement getModelMatrix function, which returns a world matrix for the instance
110-
mat4 getModelMatrix() {
111-
112-
// we have world position in aInstPosition, but modify it based on distance from uCenter for some displacement effect
113-
vec3 direction = aInstPosition - uCenter;
114-
float distanceFromCenter = length(direction);
115-
float displacementIntensity = exp(-distanceFromCenter * 0.2) ; //* (1.9 + abs(sin(uTime * 1.5)));
116-
vec3 worldPos = aInstPosition - direction * displacementIntensity;
117-
118-
// create matrix based on the modified poition, and scale
119-
return mat4(
120-
vec4(aInstScale, 0.0, 0.0, 0.0),
121-
vec4(0.0, aInstScale, 0.0, 0.0),
122-
vec4(0.0, 0.0, aInstScale, 0.0),
123-
vec4(worldPos, 1.0)
124-
);
125-
}
126-
`);
100+
material.getShaderChunks(pc.SHADERLANGUAGE_GLSL).set('transformInstancingVS', files['transform-instancing.glsl.vert']);
101+
material.getShaderChunks(pc.SHADERLANGUAGE_WGSL).set('transformInstancingVS', files['transform-instancing.wgsl.vert']);
127102

128103
material.update();
129104

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
// instancing attributes
3+
attribute vec3 aInstPosition;
4+
attribute float aInstScale;
5+
6+
// uniforms
7+
uniform float uTime;
8+
uniform vec3 uCenter;
9+
10+
// all instancing chunk needs to do is to implement getModelMatrix function, which returns a world matrix for the instance
11+
mat4 getModelMatrix() {
12+
13+
// we have world position in aInstPosition, but modify it based on distance from uCenter for some displacement effect
14+
vec3 direction = aInstPosition - uCenter;
15+
float distanceFromCenter = length(direction);
16+
float displacementIntensity = exp(-distanceFromCenter * 0.2) ; //* (1.9 + abs(sin(uTime * 1.5)));
17+
vec3 worldPos = aInstPosition - direction * displacementIntensity;
18+
19+
// create matrix based on the modified poition, and scale
20+
return mat4(
21+
vec4(aInstScale, 0.0, 0.0, 0.0),
22+
vec4(0.0, aInstScale, 0.0, 0.0),
23+
vec4(0.0, 0.0, aInstScale, 0.0),
24+
vec4(worldPos, 1.0)
25+
);
26+
}
27+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
// instancing attributes
3+
attribute aInstPosition: vec3f;
4+
attribute aInstScale: f32;
5+
6+
// uniforms
7+
uniform uTime: f32;
8+
uniform uCenter: vec3f;
9+
10+
// all instancing chunk needs to do is to implement getModelMatrix function, which returns a world matrix for the instance
11+
fn getModelMatrix() -> mat4x4f {
12+
13+
// we have world position in aInstPosition, but modify it based on distance from uCenter for some displacement effect
14+
var direction: vec3f = aInstPosition - uniform.uCenter;
15+
var distanceFromCenter: f32 = length(direction);
16+
var displacementIntensity: f32 = exp(-distanceFromCenter * 0.2); //* (1.9 + abs(sin(uniform.uTime * 1.5)));
17+
var worldPos: vec3f = aInstPosition - direction * displacementIntensity;
18+
19+
// create matrix based on the modified poition, and scale
20+
return mat4x4f(
21+
vec4f(aInstScale, 0.0, 0.0, 0.0),
22+
vec4f(0.0, aInstScale, 0.0, 0.0),
23+
vec4f(0.0, 0.0, aInstScale, 0.0),
24+
vec4f(worldPos, 1.0)
25+
);
26+
}
27+

src/scene/shader-lib/programs/lit-shader.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class LitShader {
132132
userChunkMap.forEach((chunk, chunkName) => {
133133

134134
// extract attribute names from the used chunk
135+
Debug.assert(chunk);
135136
for (const a in builtinAttributes) {
136137
if (builtinAttributes.hasOwnProperty(a) && chunk.indexOf(a) >= 0) {
137138
this.attributes[a] = builtinAttributes[a];

0 commit comments

Comments
 (0)