You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/user-manual/graphics/shaders/glsl-specifics.md
+8-2Lines changed: 8 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -15,13 +15,13 @@ The following sections outline key aspects of writing GLSL shaders for PlayCanva
15
15
16
16
### Attributes
17
17
18
-
Attributes define per-vertex input data. They must be declared using the following syntax:
18
+
Attributes define per-vertex input data, and can only be used in the vertex shader. They must be declared using the following syntax:
19
19
20
20
```glsl
21
21
attribute vec2 aUv0;
22
22
```
23
23
24
-
The attribute name must match the name specified in the `attributes` property when creating the [ShaderMaterial][1].
24
+
The attribute names must match the names specified in the `attributes` property when creating the [ShaderMaterial][1].
25
25
26
26
:::note
27
27
@@ -39,6 +39,12 @@ uniform vec3 view_position;
39
39
40
40
The engine automatically sets appropriate uniform values when rendering.
41
41
42
+
:::note
43
+
44
+
Currently, our uniform system supports only simple types, including `float`, `int`, `uint`, as well as vectors and matrices (e.g., `vec4`, `mat4`). Structs are not supported at this time, so all uniform values must be declared as individual variables of basic types.
45
+
46
+
:::
47
+
42
48
### Varyings
43
49
44
50
Varyings are used to pass values from the vertex shader to the fragment shader. They must be declared using standard GLSL syntax:
Copy file name to clipboardExpand all lines: docs/user-manual/graphics/shaders/index.md
+29-17Lines changed: 29 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -11,30 +11,36 @@ To create an instance of `ShaderMaterial`, these are the steps:
11
11
12
12
Create a description of your shader:
13
13
14
-
```javascript
14
+
```javascript
15
15
constshaderDesc= {
16
-
uniqueName:'MyShader',
17
-
shaderLanguage:pc.SHADERLANGUAGE_GLSL,
18
-
vertexCode:`
19
-
// write your vertex shader source code
20
-
`,
21
-
fragmentCode:`
22
-
// write your fragment shader source code
23
-
`,
24
-
attributes: {
25
-
aPosition:pc.SEMANTIC_POSITION,
26
-
aUv0:pc.SEMANTIC_TEXCOORD0
27
-
}
28
-
};
16
+
uniqueName:'MyShader',
17
+
vertexGLSL:`
18
+
// write your vertex shader source code in GLSL language
19
+
`,
20
+
fragmentGLSL:`
21
+
// write your fragment shader source code in GLSL language
22
+
`,
23
+
vertexWGSL:`
24
+
// write your vertex shader source code in WGSL language
25
+
`,
26
+
fragmentWGSL:`
27
+
// write your fragment shader source code in WGSL language
28
+
`,
29
+
attributes: {
30
+
aPosition:pc.SEMANTIC_POSITION,
31
+
aUv0:pc.SEMANTIC_TEXCOORD0
32
+
}
33
+
};
34
+
29
35
```
30
36
31
37
Then create instances of your material, which you can use for rendering:
32
38
33
-
```javascript
39
+
```javascript
34
40
constmaterial=newpc.ShaderMaterial(shaderDesc);
35
41
```
36
42
37
-
The shader source code can be written in GLSL if you're targeting the WebGL2 or WebGPU platforms, or in WGSL if you're targeting WebGPU only.
43
+
The shader source code can be written in GLSL if you're targeting the WebGL2 or WebGPU platforms, or in WGSL if you're targeting WebGPU only, or both.
38
44
39
45
:::note
40
46
@@ -48,7 +54,9 @@ Before the shader is used, a preprocessing step is applied, allowing you to mana
48
54
49
55
This preprocessing step follows a typical C-like preprocessor structure, handling directives such as `#define`, `#if`, `#else`, `#endif`, and similar. This gives you fine-grained control over how the shader code is compiled and customized for different use cases.
50
56
51
-
### Material Shader Defines {#material-shader-defines}
57
+
You can also use a `#include` directive to include one of the registered shader chunks. For example: `#include "screenDepthPS"`
58
+
59
+
### Material Shader Defines
52
60
53
61
Shader defines can be set on a per-material basis, allowing dynamic customization of shader behavior. For example:
54
62
@@ -207,4 +215,8 @@ And Each created shader will be logged in the browser console, where you can ins
207
215
208
216
For further information, refer to the [ShaderMaterial API documentation](https://api.playcanvas.com/engine/classes/ShaderMaterial.html).
209
217
218
+
### Compute shaders
219
+
220
+
Compute shaders are currently supported by the engine when using WebGPU, but their integration is still evolving. Full documentation will be provided as the system matures and stabilizes. In the meantime, we recommend studying the available engine examples, which demonstrate how compute shaders can be written, dispatched, and used within the current framework.
Once an application's chunks have been updated to the latest API they must be flagged as such. For example, after updating a material's custom chunks to the latest engine release (say v1.55), specify this in the chunks object as follows:
18
+
Once an application's chunks have been updated to the latest API they must be flagged as such. For example, after updating a material's custom chunks to the latest engine release (say v2.8), specify this in the chunks object as follows:
Copy file name to clipboardExpand all lines: docs/user-manual/graphics/shaders/wgsl-specifics.md
+270-1Lines changed: 270 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -3,4 +3,273 @@ title: WGSL Specifics
3
3
sidebar_position: 2
4
4
---
5
5
6
-
Support for WGSL in the PlayCanvas engine is under active development. Detailed information on WGSL shader requirements and integration will be provided once the implementation is finalized.
6
+
WGSL shaders used by the PlayCanvas engine must satisfy certain requirements. These requirements allow the engine to correctly integrate shaders, ensuring they receive the necessary resources such as attributes, uniforms, and varyings.
7
+
8
+
The following sections outline key aspects of writing WGSL shaders for PlayCanvas.
9
+
10
+
### Simplified Shader Interface Syntax
11
+
12
+
In standard WGSL (WebGPU Shading Language), declaring uniforms, attributes, and varyings requires explicitly specifying a `@group` and `@binding` index for each resource. This can be verbose and error-prone, especially for common patterns.
13
+
14
+
To improve usability and streamline shader development, we adopt a simplified syntax similar to GLSL. In this model, you do not need to specify `@group` or `@binding` attributes manually—these are automatically assigned and managed by the engine based on a predefined layout.
Attributes define per-vertex input data, and can only be used in the vertex shader. They must be declared using the following syntax:
51
+
52
+
```wgsl
53
+
attribute aUv0: vec2f;
54
+
```
55
+
56
+
Internally, a `VertexInput` struct is automatically created and populated with all the attributes. Attributes can be accessed from the structure passed to the main function, but also in the global scope.
// access it using input passed to the main function
64
+
var myUv1 = input.aUv0;
65
+
66
+
// but also as a global variable (particularly useful inside other functions)
67
+
var myUv2 = aUv0;
68
+
}
69
+
```
70
+
71
+
As part of the `VertexInput` structure, and also in the global scope, these built-in attributes are automatically available:
72
+
73
+
```wgsl
74
+
vertexIndex: @builtin(vertex_index)
75
+
instanceIndex: @builtin(instance_index)
76
+
```
77
+
78
+
The attribute names must match the names specified in the `attributes` property when creating the [ShaderMaterial][1].
79
+
80
+
### Uniforms
81
+
82
+
Uniforms are used to pass *numerical resources* from the engine to the shader.
83
+
84
+
Uniforms are declared using this simplified syntax:
85
+
86
+
```wgsl
87
+
uniform view_position: vec3f;
88
+
uniform tints: array<vec3f, 4>;
89
+
uniform weights: array<f32, 8>;
90
+
```
91
+
92
+
Internally, uniforms are automatically placed in uniform buffers, and in the shader code are accessed using a `uniform.` prefix:
93
+
94
+
```wgsl
95
+
var pos = uniform.view_position;
96
+
var color = uniform.tints[2];
97
+
98
+
// f32 and vec2<> types used in an array are due to alignment requirements wrapped
99
+
// in an aligned structure, and the value is available as its `element` property.
100
+
// struct WrappedF32 { @size(16) element: f32 }
101
+
var weight = uniform.weights[3].element;
102
+
```
103
+
104
+
The engine automatically sets appropriate uniform values when rendering.
105
+
106
+
:::note
107
+
108
+
Currently, our uniform system supports only simple types, including `f32`, `i32`, `u32`, as well as vectors and matrices (e.g., `vec4f`, `mat4x4f`). Structs are not supported at this time, so all uniform values must be declared as individual variables of basic types.
109
+
110
+
:::
111
+
112
+
### Texture Resources
113
+
114
+
Texture resources are using simplified WGSL syntax, where specifying a `@group` and `@binding` index for each resource has to be omitted.
115
+
116
+
#### Sampling Textures
117
+
118
+
In WGSL, textures and samplers are treated as separate objects, unlike in GLSL, where those are combined.
119
+
120
+
When you want to sample a texture (i.e. retrieve filtered texel values), you must provide a texture object *directly followed* by a sampler.
121
+
122
+
```wgsl
123
+
// 2d texture with a sampler declaration
124
+
var diffuseMap: texture_2d<f32>;
125
+
var diffuseMapSampler: sampler;
126
+
127
+
// texture sampling
128
+
var texel = textureSample(diffuseMap, diffuseMapSampler, coords);
129
+
```
130
+
131
+
#### Fetching Textures
132
+
133
+
If you only need to read raw texel data (i.e., without filtering, mipmapping, or addressing modes), you can use `textureLoad` instead of `textureSample`. This is called non-filtered access, or simply texel fetching.
134
+
135
+
In such cases, no sampler is required or allowed. For example:
136
+
137
+
```wlsl
138
+
// cubemap texture without a sampler
139
+
var noSamplerMap: texture_cube<f32>;
140
+
141
+
// fetching the texel
142
+
let texel = textureLoad(noSamplerMap, coords, mipLevel);
143
+
```
144
+
145
+
#### Unfilterable Textures
146
+
147
+
WebGPU supports unfilterable float textures, which are typically used for specialized purposes such as sampling from depth textures, where filtering is not allowed. However, WGSL does not provide a distinct sample type in the syntax for declaring these unfilterable float textures. To address this limitation and enable proper bind group auto-generation based on shader declarations, we introduce a new sample type called `uff` (unfilterable-float).
148
+
149
+
Using `uff`, you can explicitly declare an unfilterable-float texture in the shader like this:
150
+
151
+
```wgsl
152
+
// declaration
153
+
var colorMap: texture_2d<uff>;
154
+
155
+
// sampling
156
+
let data: vec4f = textureLoad(colorMap, uv, 0);
157
+
```
158
+
159
+
This extension allows the engine to correctly interpret the texture’s sampling capabilities and bind it accordingly.
160
+
161
+
:::note
162
+
163
+
Support for `texture_external` is not available yet, and will be added in the future.
164
+
165
+
:::
166
+
167
+
### Storage Buffers
168
+
169
+
Storage buffers are GPU-accessible memory resources that allow shaders to read and write arbitrary data with random access. In WGSL, they are declared using `var<storage>` and are ideal for working with large or structured datasets such as particle systems, compute data, or dynamic geometry. Unlike uniforms, storage buffers support both read and write access (with appropriate access control).
170
+
171
+
Example of using storage buffer in Vertex Shader:
172
+
173
+
```wgsl
174
+
struct Particle {
175
+
position: vec3f,
176
+
velocity: vec3f,
177
+
}
178
+
179
+
// particle storage buffer in read-only mode
180
+
var<storage, read> particles: array<Particle>;
181
+
```
182
+
183
+
### Varyings
184
+
185
+
Varyings are used to pass values from the vertex shader to the fragment shader. Declare them in both vertex and fragment shader using this simplified syntax:
186
+
187
+
```wgsl
188
+
varying texCoord: vec2f;
189
+
```
190
+
191
+
Internally, those are parsed, and stored in `VertexOutput` structure in the vertex shader, as well as in `FragmentInput` structure in the fragment shader.
192
+
193
+
#### Vertex Shader
194
+
195
+
As part of the `VertexOutput` structure these built-in variables are automatically available:
The fragment shader is responsible for producing one or more color outputs, which are written to the render targets (color attachments) of the framebuffer.
248
+
249
+
The engine automatically provides a `FragmentOutput` structure, which includes a predefined set of vec4f fields: `color`, `color1`, `color2` and so on, covering all possible color attachments, up to the limit defined by `GraphicsDevice.maxColorAttachments`.
250
+
251
+
As part of the `FragmentOutput` structure these built-in variables are automatically available:
0 commit comments