-
Notifications
You must be signed in to change notification settings - Fork 116
New FAST renderer on clean WebGPU try: (webgpu.mcraft.fun) #120
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
base: next
Are you sure you want to change the base?
Changes from 250 commits
1396031
3cec6e4
558a9e2
095825d
d134f75
3e320e6
b5114be
c8b4651
790fa11
f70f940
d9e84df
cf945d8
f42bad6
b12c919
309608e
bbfd38f
a1e1670
b0e8f08
0f14d02
a66525d
37a7229
501c658
b722075
4f418bf
c15b405
5be5877
3675d3a
2f8da5b
7ddf77a
1fcf24c
64aabc3
0ce76ba
cca6cb2
97dd35c
93586a9
8e3cfe7
b642336
b1ab92f
bcc8f08
fc7bcd2
a0019df
bd3b06d
d8e6e7f
e749fbb
1b98622
bd24709
9621179
985de70
9d07572
36ff493
ca7e81d
79764b1
d444be9
d7cd9fd
6b7b858
ebf6681
7ba0df2
a310b5e
f06f0f9
63d0ca2
c2c384d
46838e8
cf97ed2
e0fd48a
7a8b6ad
fe0683a
81e470c
535fea6
64376ed
4caf2cd
6a7996a
ab51d95
8caa041
7d60bff
e316eea
e2f3286
bdf7164
2fb9b90
6e61ebe
f56cbcb
04c9fa0
e2d426d
db95d11
3710d0c
d045fe8
28758ca
0a184bc
0252acc
a9d957e
81adbf8
44d68ea
3553e05
97392fa
985b6fe
9164430
ac111a8
373b965
cb1af9e
d7fb417
b83e2cd
642c37d
2511a52
5526b4d
5e350c1
3bbad05
d763650
980327a
087b58c
79c40dc
fa5b492
2d080bf
9721dee
020ee27
c2e05fe
ef3f847
f91ca19
616d235
e3968b2
d1549fd
e676ac8
2c7e38a
71c13fe
d1d25ea
74a8271
44c337f
fa1daf6
0b90dc5
de20a94
f6e7b83
6a7b3c5
65f9c46
b12560a
f59ff5a
0a2430c
b0a2ffe
e820621
9af459c
c8d3087
9794847
912cf73
51561b6
3da0e68
36daed9
12df1f2
4fffd67
2ed8b82
8415f64
052f6e0
8a737c5
b1f9ccf
f095c13
a5f0c0e
03452de
c2bb7b4
37e7c04
89ebcc3
e4e53b9
a9b1d86
56757d7
b2cb1e0
1039448
311cb3b
aa2058c
ce9262e
2515af5
c4dea62
6b9b955
d2c0639
b39f47f
e34ebaa
97aa385
d41a9d2
a392da4
b6337a6
3a057b6
c5015cb
6421ff6
e53f7f4
37db5ff
b99d46e
335c84d
4e6d6ae
393eaa5
7245052
97ae5f2
4eb1353
96cd6b2
4c811a2
300c2ae
9ff04e7
23da795
39e54c8
b50de91
92aa80d
9000445
71d8e73
09d8aaa
069831c
1686acd
ea82415
af82c41
7dde3fe
5b3fde9
da06ea7
a9f30a8
23fd25f
67e5024
c89c42f
68b18bf
bf1ea0a
ea1dd5e
8904fbf
5661420
4939cc9
08d010b
d62464f
e756b04
a2195fa
fbe2641
43cdd21
afd4c4c
b27e7bd
57856e6
f7bb2ec
660776b
e36bf3e
4bc1c0d
5efb6e5
b15bc9d
4b68710
81874c9
bba7729
e1f3778
c6145f6
2967897
51b818e
792a195
6b642d0
746f90d
818fce1
7cc2664
96b1a81
fe590bf
809da7c
047dd32
4309bff
35f844e
451f291
d8d7f45
a5ad234
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
public-hoist-pattern=* | ||
ignore-workspace-root-check=true | ||
shell-emulator=true | ||
shell-emulator=false |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,25 @@ | |
"outFiles": [ | ||
"${workspaceFolder}/dist/**/*.js", | ||
// "!${workspaceFolder}/dist/**/*vendors*", | ||
"!${workspaceFolder}/dist/**/*mc-data*", | ||
"!**/node_modules/**" | ||
], | ||
"skipFiles": [ | ||
// "<node_internals>/**/*vendors*" | ||
"<node_internals>/**/*mc-data*" | ||
], | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix syntax error: missing comma There's a syntax error due to a missing comma after the closing bracket. "skipFiles": [
// "<node_internals>/**/*vendors*"
"<node_internals>/**/*mc-data*"
- ],
+ ],
🧰 Tools🪛 Biome (1.9.4)[error] 44-44: Expected a property but instead found '}'. Expected a property here. (parse) |
||
{ | ||
// not recommended as in most cases it will slower as it launches from extension host so it slows down extension host, not sure why | ||
"type": "chrome", | ||
"name": "Launch Chrome (playground)", | ||
"request": "launch", | ||
"url": "http://localhost:9090/", | ||
"pathMapping": { | ||
"/": "${workspaceFolder}/prismarine-viewer/dist" | ||
}, | ||
"outFiles": [ | ||
"${workspaceFolder}/prismarine-viewer/dist/**/*.js", | ||
// "!${workspaceFolder}/dist/**/*vendors*", | ||
"!**/node_modules/**" | ||
], | ||
"skipFiles": [ | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -25,10 +25,20 @@ | |||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
"label": "viewer server+esbuild", | ||||||||||||||||||||||||||||||||||
"label": "webgl-worker", | ||||||||||||||||||||||||||||||||||
"type": "shell", | ||||||||||||||||||||||||||||||||||
"command": "node buildWorkers.mjs -w", | ||||||||||||||||||||||||||||||||||
"problemMatcher": "$esbuild-watch", | ||||||||||||||||||||||||||||||||||
"presentation": { | ||||||||||||||||||||||||||||||||||
"reveal": "silent" | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
Comment on lines
+28
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added WebGL worker build task. The new WebGL worker task is a good addition for the WebGPU renderer implementation. However, there's a potential syntax error in the JSON structure. Fix the trailing comma issue at line 35: "presentation": {
"reveal": "silent"
- },
+ } This will resolve the parse error and ensure the tasks.json file is valid. 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 35-35: Expected a property but instead found '}'. Expected a property here. (parse) |
||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
"label": "viewer server+esbuild+workers", | ||||||||||||||||||||||||||||||||||
"dependsOn": [ | ||||||||||||||||||||||||||||||||||
"viewer-server", | ||||||||||||||||||||||||||||||||||
"viewer-esbuild" | ||||||||||||||||||||||||||||||||||
"viewer-esbuild", | ||||||||||||||||||||||||||||||||||
"webgl-worker" | ||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||
"dependsOrder": "parallel", | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
//@ts-check | ||
// main worker file intended for computing world geometry is built using prismarine-viewer/buildWorker.mjs | ||
import { build, context } from 'esbuild' | ||
import fs from 'fs' | ||
import path, { join } from 'path' | ||
import { polyfillNode } from 'esbuild-plugin-polyfill-node' | ||
import { mesherSharedPlugins } from './scripts/esbuildPlugins.mjs' | ||
import { fileURLToPath } from 'url' | ||
import { dynamicMcDataFiles } from './src/integratedServer/workerMcData.mjs' | ||
|
||
const watch = process.argv.includes('-w') | ||
|
||
const sharedAliases = { | ||
'three': './node_modules/three/src/Three.js', | ||
events: 'events', // make explicit | ||
buffer: 'buffer', | ||
'fs': './src/shims/fs.js', | ||
http: './src/shims/empty.ts', | ||
perf_hooks: './src/shims/perf_hooks_replacement.js', | ||
crypto: './src/shims/crypto.js', | ||
stream: 'stream-browserify', | ||
net: './src/shims/empty.ts', | ||
assert: 'assert', | ||
dns: './src/shims/empty.ts', | ||
'@azure/msal-node': './src/shims/empty.ts', | ||
'flying-squid/dist': 'flying-squid/src' | ||
} | ||
|
||
const result = await (watch ? context : build)({ | ||
bundle: true, | ||
platform: 'browser', | ||
// entryPoints: ['renderer/playground/webgpuRendererWorker.ts', 'src/worldSaveWorker.ts'], | ||
entryPoints: ['./renderer/playground/webgpuRendererWorker.ts'], | ||
outdir: 'renderer/dist/', | ||
sourcemap: watch ? 'inline' : 'external', | ||
minify: !watch, | ||
treeShaking: true, | ||
logLevel: 'info', | ||
alias: sharedAliases, | ||
plugins: [ | ||
{ | ||
name: 'writeOutput', | ||
setup (build) { | ||
build.onEnd(({ outputFiles }) => { | ||
fs.mkdirSync('renderer/public', { recursive: true }) | ||
fs.mkdirSync('dist', { recursive: true }) | ||
for (const file of outputFiles) { | ||
for (const dir of ['renderer/dist', 'dist']) { | ||
const baseName = path.basename(file.path) | ||
fs.mkdirSync(dir, { recursive: true }) | ||
fs.writeFileSync(path.join(dir, baseName), file.contents) | ||
} | ||
} | ||
}) | ||
} | ||
}, | ||
{ | ||
name: 'fix-dynamic-require', | ||
setup (build) { | ||
build.onResolve({ | ||
filter: /1\.14\/chunk/, | ||
}, async ({ resolveDir, path }) => { | ||
if (!resolveDir.includes('prismarine-provider-anvil')) return | ||
return { | ||
namespace: 'fix-dynamic-require', | ||
path, | ||
pluginData: { | ||
resolvedPath: `${join(resolveDir, path)}.js`, | ||
resolveDir | ||
}, | ||
} | ||
}) | ||
build.onLoad({ | ||
filter: /.+/, | ||
namespace: 'fix-dynamic-require', | ||
}, async ({ pluginData: { resolvedPath, resolveDir } }) => { | ||
const resolvedFile = await fs.promises.readFile(resolvedPath, 'utf8') | ||
return { | ||
contents: resolvedFile.replace("require(`prismarine-chunk/src/pc/common/BitArray${noSpan ? 'NoSpan' : ''}`)", "noSpan ? require(`prismarine-chunk/src/pc/common/BitArray`) : require(`prismarine-chunk/src/pc/common/BitArrayNoSpan`)"), | ||
resolveDir, | ||
loader: 'js', | ||
} | ||
}) | ||
} | ||
}, | ||
polyfillNode({ | ||
polyfills: { | ||
fs: false, | ||
dns: false, | ||
crypto: false, | ||
events: false, | ||
http: false, | ||
stream: false, | ||
buffer: false, | ||
perf_hooks: false, | ||
net: false, | ||
assert: false, | ||
}, | ||
}) | ||
], | ||
loader: { | ||
'.vert': 'text', | ||
'.frag': 'text', | ||
'.wgsl': 'text', | ||
}, | ||
mainFields: [ | ||
'browser', 'module', 'main' | ||
], | ||
keepNames: true, | ||
write: false, | ||
}) | ||
|
||
if (watch) { | ||
//@ts-ignore | ||
await result.watch() | ||
} | ||
|
||
const allowedBundleFiles = ['legacy', 'versions', 'protocolVersions', 'features'] | ||
|
||
const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url))) | ||
|
||
|
||
/** @type {import('esbuild').BuildOptions} */ | ||
const integratedServerBuildOptions = { | ||
bundle: true, | ||
banner: { | ||
js: `globalThis.global = globalThis;process = {env: {}, versions: {} };`, | ||
}, | ||
platform: 'browser', | ||
entryPoints: [path.join(__dirname, './src/integratedServer/worker.ts')], | ||
minify: !watch, | ||
logLevel: 'info', | ||
drop: !watch ? [ | ||
'debugger' | ||
] : [], | ||
sourcemap: 'linked', | ||
// write: false, | ||
// metafile: true, | ||
// outdir: path.join(__dirname, './dist'), | ||
outfile: './dist/integratedServer.js', | ||
define: { | ||
'process.env.BROWSER': '"true"', | ||
'process.versions.node': '"50.0.0"', | ||
}, | ||
alias: sharedAliases, | ||
plugins: [ | ||
...mesherSharedPlugins, | ||
{ | ||
name: 'custom-plugins', | ||
setup (build) { | ||
build.onResolve({ filter: /\.json$/ }, args => { | ||
const fileName = args.path.split('/').pop().replace('.json', '') | ||
if (args.resolveDir.includes('minecraft-data')) { | ||
if (args.path.replaceAll('\\', '/').endsWith('bedrock/common/protocolVersions.json')) { | ||
return | ||
} | ||
if (args.path.includes('bedrock')) { | ||
return { path: args.path, namespace: 'empty-file', } | ||
} | ||
if (dynamicMcDataFiles.includes(fileName)) { | ||
return { | ||
path: args.path, | ||
namespace: 'mc-data', | ||
} | ||
} | ||
if (!allowedBundleFiles.includes(fileName)) { | ||
return { path: args.path, namespace: 'empty-file', } | ||
} | ||
} | ||
}) | ||
build.onResolve({ | ||
filter: /external/, | ||
}, ({ path, importer }) => { | ||
importer = importer.split('\\').join('/') | ||
if (importer.endsWith('flying-squid/dist/lib/modules/index.js')) { | ||
return { | ||
path, | ||
namespace: 'empty-file-object', | ||
} | ||
} | ||
}) | ||
build.onLoad({ | ||
filter: /.*/, | ||
namespace: 'empty-file', | ||
}, () => { | ||
return { contents: 'module.exports = undefined', loader: 'js' } | ||
}) | ||
build.onLoad({ | ||
filter: /.*/, | ||
namespace: 'empty-file-object', | ||
}, () => { | ||
return { contents: 'module.exports = {}', loader: 'js' } | ||
}) | ||
build.onLoad({ | ||
namespace: 'mc-data', | ||
filter: /.*/, | ||
}, async ({ path }) => { | ||
const fileName = path.split(/[\\\/]/).pop().replace('.json', '') | ||
return { | ||
contents: `module.exports = globalThis.mcData["${fileName}"]`, | ||
loader: 'js', | ||
resolveDir: process.cwd(), | ||
} | ||
}) | ||
build.onResolve({ | ||
filter: /^esbuild-data$/, | ||
}, () => { | ||
return { | ||
path: 'esbuild-data', | ||
namespace: 'esbuild-data', | ||
} | ||
}) | ||
build.onLoad({ | ||
filter: /.*/, | ||
namespace: 'esbuild-data', | ||
}, () => { | ||
const data = { | ||
// todo always use latest | ||
tints: 'require("minecraft-data/minecraft-data/data/pc/1.16.2/tints.json")' | ||
} | ||
return { | ||
contents: `module.exports = {${Object.entries(data).map(([key, code]) => `${key}: ${code}`).join(', ')}}`, | ||
loader: 'js', | ||
resolveDir: process.cwd(), | ||
} | ||
}) | ||
|
||
build.onResolve({ | ||
filter: /minecraft-protocol$/, | ||
}, async (args) => { | ||
return { | ||
...await build.resolve('minecraft-protocol/src/index.js', { kind: args.kind, importer: args.importer, resolveDir: args.resolveDir }), | ||
} | ||
}) | ||
|
||
// build.onEnd(({ metafile, outputFiles }) => { | ||
// if (!metafile) return | ||
// fs.mkdirSync(path.join(__dirname, './dist'), { recursive: true }) | ||
// fs.writeFileSync(path.join(__dirname, './dist/metafile.json'), JSON.stringify(metafile)) | ||
// for (const outDir of ['../dist/', './dist/']) { | ||
// for (const outputFile of outputFiles) { | ||
// if (outDir === '../dist/' && outputFile.path.endsWith('.map')) { | ||
// // skip writing & browser loading sourcemap there, worker debugging should be done in playground | ||
// // continue | ||
// } | ||
// const writePath = path.join(__dirname, outDir, path.basename(outputFile.path)) | ||
// fs.mkdirSync(path.dirname(writePath), { recursive: true }) | ||
// fs.writeFileSync(writePath, outputFile.text) | ||
// } | ||
// } | ||
// }) | ||
} | ||
}, | ||
polyfillNode({ | ||
polyfills: { | ||
fs: false, | ||
dns: false, | ||
crypto: false, | ||
events: false, | ||
http: false, | ||
stream: false, | ||
buffer: false, | ||
perf_hooks: false, | ||
net: false, | ||
assert: false, | ||
}, | ||
}), | ||
], | ||
} | ||
|
||
if (watch) { | ||
const ctx = await context(integratedServerBuildOptions) | ||
await ctx.watch() | ||
} else { | ||
await build(integratedServerBuildOptions) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { cleanVisit, setOptions } from './shared' | ||
|
||
it('Loads & renders singleplayer', () => { | ||
cleanVisit('/?singleplayer=1') | ||
setOptions({ | ||
renderDistance: 2 | ||
}) | ||
// wait for .initial-loader to disappear | ||
cy.get('.initial-loader', { timeout: 20_000 }).should('not.exist') | ||
cy.window() | ||
.its('performance') | ||
.invoke('mark', 'worldLoad') | ||
|
||
cy.document().then({ timeout: 20_000 }, doc => { | ||
return new Cypress.Promise(resolve => { | ||
doc.addEventListener('cypress-world-ready', resolve) | ||
}) | ||
}).then(() => { | ||
const duration = cy.window() | ||
.its('performance') | ||
.invoke('measure', 'modalOpen') | ||
.its('duration') | ||
cy.log('Duration', duration) | ||
}) | ||
Comment on lines
+14
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify that 'cypress-world-ready' event is being dispatched. The test depends on a custom event 'cypress-world-ready' being dispatched, but there's no error handling if this event never fires. Consider adding a timeout to the Promise to prevent the test hanging indefinitely. 🏁 Script executed: #!/bin/bash
# Check if the cypress-world-ready event is being dispatched in the codebase
echo "Searching for where cypress-world-ready event is dispatched:"
rg -A 2 "dispatchEvent.*cypress-world-ready|CustomEvent.*cypress-world-ready" Length of output: 316 Robust Event Handling for 'cypress-world-ready'
This change will ensure that if the event is not fired within the expected time, the test fails gracefully rather than hanging indefinitely. |
||
}) |
Uh oh!
There was an error while loading. Please reload this page.