Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various small improvements and validations to WebGPU rendering #4899

Merged
merged 1 commit into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/platform/graphics/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,7 @@ export const bindGroupNames = ['view', 'mesh'];
// map of engine TYPE_*** enums to their corresponding typed array constructors and byte sizes
export const typedArrayTypes = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array];
export const typedArrayTypesByteSize = [1, 1, 2, 2, 4, 4, 4];
export const vertexTypesNames = ['INT8', 'UINT8', 'INT16', 'UINT16', 'INT32', 'UINT32', 'FLOAT32'];

// map of typed array to engine TYPE_***
export const typedArrayToType = {
Expand Down
16 changes: 14 additions & 2 deletions src/platform/graphics/shader-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ class ShaderProcessor {
*
* @param {import('./graphics-device.js').GraphicsDevice} device - The graphics device.
* @param {object} shaderDefinition - The shader definition.
* @param {import('./shader.js').Shader} shader - The shader definition.
* @returns {object} - The processed shader data.
*/
static run(device, shaderDefinition) {
static run(device, shaderDefinition, shader) {

/** @type {Map<string, number>} */
const varyingMap = new Map();
Expand All @@ -90,11 +91,22 @@ class ShaderProcessor {
const outBlock = ShaderProcessor.processOuts(fragmentExtracted.outs);

// uniforms - merge vertex and fragment uniforms, and create shared uniform buffers
const uniforms = vertexExtracted.uniforms.concat(fragmentExtracted.uniforms);
// Note that as both vertex and fragment can declare the same uniform, we need to remove duplicates
const concatUniforms = vertexExtracted.uniforms.concat(fragmentExtracted.uniforms);
const uniforms = Array.from(new Set(concatUniforms));

// parse uniform lines
const parsedUniforms = uniforms.map(line => new UniformLine(line));

// validation - as uniforms go to a shared uniform buffer, vertex and fragment versions need to match
Debug.call(() => {
const map = new Map();
parsedUniforms.forEach((uni) => {
const existing = map.get(uni.name);
Debug.assert(!existing, `Vertex and fragment shaders cannot use the same uniform name with different types: '${existing}' and '${uni.line}'`, shader);
map.set(uni.name, uni.line);
});
});
const uniformsData = ShaderProcessor.processUniforms(device, parsedUniforms, shaderDefinition.processingOptions);

// VS - insert the blocks to the source
Expand Down
9 changes: 7 additions & 2 deletions src/platform/graphics/vertex-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { math } from '../../core/math/math.js';

import {
SEMANTIC_TEXCOORD0, SEMANTIC_TEXCOORD1, SEMANTIC_ATTR12, SEMANTIC_ATTR13, SEMANTIC_ATTR14, SEMANTIC_ATTR15,
SEMANTIC_COLOR, SEMANTIC_TANGENT, TYPE_FLOAT32, typedArrayTypesByteSize
SEMANTIC_COLOR, SEMANTIC_TANGENT, TYPE_FLOAT32, typedArrayTypesByteSize, vertexTypesNames, DEVICETYPE_WEBGPU
} from './constants.js';

/**
Expand Down Expand Up @@ -136,8 +136,13 @@ class VertexFormat {
for (let i = 0, len = description.length; i < len; i++) {
const elementDesc = description[i];

// align up the offset to elementSize (when vertexCount is specified only - case of non-interleaved format)
elementSize = elementDesc.components * typedArrayTypesByteSize[elementDesc.type];

// WebGPU has limited element size support (for example uint16x3 is not supported)
Debug.assert(graphicsDevice.deviceType !== DEVICETYPE_WEBGPU || [2, 4, 8, 12, 16].includes(elementSize),
`WebGPU does not support the format of vertex element ${elementDesc.semantic} : ${vertexTypesNames[elementDesc.type]} x ${elementDesc.components}`);

// align up the offset to elementSize (when vertexCount is specified only - case of non-interleaved format)
if (vertexCount) {
offset = math.roundUp(offset, elementSize);

Expand Down
4 changes: 2 additions & 2 deletions src/platform/graphics/webgpu/webgpu-render-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ class WebgpuRenderTarget {
const depthAttachment = this.renderPassDescriptor.depthStencilAttachment;
if (depthAttachment) {
depthAttachment.depthClearValue = renderPass.depthStencilOps.clearDepthValue;
depthAttachment.depthLoadOp = renderPass.depthStencilOps.clearDepth ? 'clear' : 'discard';
depthAttachment.depthLoadOp = renderPass.depthStencilOps.clearDepth ? 'clear' : 'load';
depthAttachment.depthStoreOp = renderPass.depthStencilOps.storeDepth ? 'store' : 'discard';
depthAttachment.depthReadOnly = false;

depthAttachment.stencilClearValue = renderPass.depthStencilOps.clearStencilValue;
depthAttachment.stencilLoadOp = renderPass.depthStencilOps.clearStencil ? 'clear' : 'discard';
depthAttachment.stencilLoadOp = renderPass.depthStencilOps.clearStencil ? 'clear' : 'load';
depthAttachment.stencilStoreOp = renderPass.depthStencilOps.storeStencil ? 'store' : 'discard';
depthAttachment.stencilReadOnly = false;
}
Expand Down
7 changes: 4 additions & 3 deletions src/platform/graphics/webgpu/webgpu-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class WebgpuShader {

process() {
// process the shader source to allow for uniforms
const processed = ShaderProcessor.run(this.shader.device, this.shader.definition);
const processed = ShaderProcessor.run(this.shader.device, this.shader.definition, this.shader);

// keep reference to processed shaders in debug mode
Debug.call(() => {
Expand All @@ -67,9 +67,10 @@ class WebgpuShader {
try {
return this.shader.device.glslang.compileGLSL(src, shaderType);
} catch (err) {
console.error(`Failed to transpile webgl ${shaderType} shader to WebGPU: [${err.message}]`, {
console.error(`Failed to transpile webgl ${shaderType} shader with id ${this.shader.id} to WebGPU: [${err.message}]`, {
processed: src,
original: originalSrc
original: originalSrc,
shader: this.shader
});
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/scene/shader-lib/chunks/lit/frag/refractionDynamic.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ void addRefraction() {
uv += vec2(1.0);
uv *= vec2(0.5);

// Grab pass texture is upside down.
// TODO: At some point we should create some macro.
#ifdef WEBGPU
uv.y = 1.0 - uv.y;
#endif

#ifdef SUPPORTS_TEXLOD
// Use IOR and roughness to select mip
float iorToRoughness = (1.0 - dGlossiness) * clamp((1.0 / material_refractionIndex) * 2.0 - 2.0, 0.0, 1.0);
Expand Down