@aura3d/rendering 1.5.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/ArchitecturalLighting.d.ts +35 -0
- package/dist/ArchitecturalLighting.d.ts.map +1 -0
- package/dist/ArchitecturalLighting.js +162 -0
- package/dist/ArchitecturalLighting.js.map +1 -0
- package/dist/ArchitecturalMaterialCatalog.d.ts +1 -1
- package/dist/ArchitecturalMaterialCatalog.d.ts.map +1 -1
- package/dist/ArchitecturalMaterialCatalog.js +1 -1
- package/dist/ArchitecturalMaterialCatalog.js.map +1 -1
- package/dist/ArchitecturalMeasurement.d.ts +27 -0
- package/dist/ArchitecturalMeasurement.d.ts.map +1 -0
- package/dist/ArchitecturalMeasurement.js +112 -0
- package/dist/ArchitecturalMeasurement.js.map +1 -0
- package/dist/CanonicalProductScene.d.ts +13 -0
- package/dist/CanonicalProductScene.d.ts.map +1 -0
- package/dist/CanonicalProductScene.js +78 -0
- package/dist/CanonicalProductScene.js.map +1 -0
- package/dist/CascadedShadowMaps.d.ts +1 -1
- package/dist/CascadedShadowMaps.d.ts.map +1 -1
- package/dist/CascadedShadowMaps.js +1 -1
- package/dist/CascadedShadowMaps.js.map +1 -1
- package/dist/DepthPass.d.ts +1 -1
- package/dist/DepthPass.d.ts.map +1 -1
- package/dist/DepthPass.js +2 -2
- package/dist/DepthPass.js.map +1 -1
- package/dist/EnvironmentBackgroundPass.d.ts +1 -1
- package/dist/EnvironmentBackgroundPass.d.ts.map +1 -1
- package/dist/EnvironmentBackgroundPass.js +2 -2
- package/dist/EnvironmentBackgroundPass.js.map +1 -1
- package/dist/EnvironmentPlatform.js +2 -2
- package/dist/EnvironmentPlatform.js.map +1 -1
- package/dist/ForwardPass.d.ts +1 -1
- package/dist/ForwardPass.d.ts.map +1 -1
- package/dist/ForwardPass.js +24 -10
- package/dist/ForwardPass.js.map +1 -1
- package/dist/Geometry.d.ts +2 -0
- package/dist/Geometry.d.ts.map +1 -1
- package/dist/Geometry.js +15 -0
- package/dist/Geometry.js.map +1 -1
- package/dist/InstancedPBRMaterial.js +1 -1
- package/dist/InstancedPBRMaterial.js.map +1 -1
- package/dist/InstancedUnlitMaterial.js +1 -1
- package/dist/InstancedUnlitMaterial.js.map +1 -1
- package/dist/Material.js +2 -2
- package/dist/Material.js.map +1 -1
- package/dist/MaterialBinding.js +4 -4
- package/dist/MaterialBinding.js.map +1 -1
- package/dist/MaterialInstance.js +2 -2
- package/dist/MaterialInstance.js.map +1 -1
- package/dist/MorphUnlitMaterial.js +1 -1
- package/dist/MorphUnlitMaterial.js.map +1 -1
- package/dist/NormalMappedPBRMaterial.js +1 -1
- package/dist/NormalMappedPBRMaterial.js.map +1 -1
- package/dist/OceanSurface.d.ts +62 -0
- package/dist/OceanSurface.d.ts.map +1 -0
- package/dist/OceanSurface.js +240 -0
- package/dist/OceanSurface.js.map +1 -0
- package/dist/PBRMaterial.d.ts.map +1 -1
- package/dist/PBRMaterial.js +3 -3
- package/dist/PBRMaterial.js.map +1 -1
- package/dist/PortableShaderMaterial.d.ts +60 -0
- package/dist/PortableShaderMaterial.d.ts.map +1 -0
- package/dist/PortableShaderMaterial.js +223 -0
- package/dist/PortableShaderMaterial.js.map +1 -0
- package/dist/PostProcessPass.d.ts.map +1 -1
- package/dist/PostProcessPass.js +30 -6
- package/dist/PostProcessPass.js.map +1 -1
- package/dist/ProceduralTexture.d.ts +27 -0
- package/dist/ProceduralTexture.d.ts.map +1 -0
- package/dist/ProceduralTexture.js +336 -0
- package/dist/ProceduralTexture.js.map +1 -0
- package/dist/ProductTurntable.d.ts +96 -0
- package/dist/ProductTurntable.d.ts.map +1 -0
- package/dist/ProductTurntable.js +639 -0
- package/dist/ProductTurntable.js.map +1 -0
- package/dist/RenderDevice.d.ts +30 -0
- package/dist/RenderDevice.d.ts.map +1 -1
- package/dist/RenderDevice.js.map +1 -1
- package/dist/Renderer.d.ts +3 -2
- package/dist/Renderer.d.ts.map +1 -1
- package/dist/Renderer.js +23 -9
- package/dist/Renderer.js.map +1 -1
- package/dist/RendererPostprocessPlan.js +4 -4
- package/dist/RendererPostprocessPlan.js.map +1 -1
- package/dist/ScreenSpaceLineMaterial.js +1 -1
- package/dist/ScreenSpaceLineMaterial.js.map +1 -1
- package/dist/ShaderChunks.d.ts.map +1 -1
- package/dist/ShaderChunks.js +81 -19
- package/dist/ShaderChunks.js.map +1 -1
- package/dist/ShaderLibrary.d.ts +2 -78
- package/dist/ShaderLibrary.d.ts.map +1 -1
- package/dist/ShaderLibrary.js +127 -793
- package/dist/ShaderLibrary.js.map +1 -1
- package/dist/ShaderLibraryCore.d.ts +100 -0
- package/dist/ShaderLibraryCore.d.ts.map +1 -0
- package/dist/ShaderLibraryCore.js +800 -0
- package/dist/ShaderLibraryCore.js.map +1 -0
- package/dist/ShaderModule.d.ts +1 -1
- package/dist/ShaderModule.d.ts.map +1 -1
- package/dist/ShaderModule.js +4 -2
- package/dist/ShaderModule.js.map +1 -1
- package/dist/ShadowPass.d.ts +1 -1
- package/dist/ShadowPass.d.ts.map +1 -1
- package/dist/ShadowPass.js +6 -4
- package/dist/ShadowPass.js.map +1 -1
- package/dist/SkinnedLitMaterial.js +1 -1
- package/dist/SkinnedLitMaterial.js.map +1 -1
- package/dist/SkinnedUnlitMaterial.js +1 -1
- package/dist/SkinnedUnlitMaterial.js.map +1 -1
- package/dist/SpaceEnvironment.d.ts +54 -0
- package/dist/SpaceEnvironment.d.ts.map +1 -0
- package/dist/SpaceEnvironment.js +116 -0
- package/dist/SpaceEnvironment.js.map +1 -0
- package/dist/TerrainHeightfield.d.ts +60 -0
- package/dist/TerrainHeightfield.d.ts.map +1 -0
- package/dist/TerrainHeightfield.js +239 -0
- package/dist/TerrainHeightfield.js.map +1 -0
- package/dist/TextureBinding.d.ts +14 -0
- package/dist/TextureBinding.d.ts.map +1 -1
- package/dist/TextureBinding.js +17 -0
- package/dist/TextureBinding.js.map +1 -1
- package/dist/TexturedPBRMaterial.js +1 -1
- package/dist/TexturedPBRMaterial.js.map +1 -1
- package/dist/TexturedUnlitMaterial.js +1 -1
- package/dist/TexturedUnlitMaterial.js.map +1 -1
- package/dist/UnlitMaterial.js +1 -1
- package/dist/UnlitMaterial.js.map +1 -1
- package/dist/VegetationFixtures.d.ts +1 -1
- package/dist/VegetationFixtures.d.ts.map +1 -1
- package/dist/VegetationFixtures.js +1 -1
- package/dist/VegetationFixtures.js.map +1 -1
- package/dist/VegetationScatter.d.ts +68 -0
- package/dist/VegetationScatter.d.ts.map +1 -0
- package/dist/VegetationScatter.js +241 -0
- package/dist/VegetationScatter.js.map +1 -0
- package/dist/VoxelWorld.d.ts +51 -0
- package/dist/VoxelWorld.d.ts.map +1 -0
- package/dist/VoxelWorld.js +183 -0
- package/dist/VoxelWorld.js.map +1 -0
- package/dist/Weather.d.ts +44 -0
- package/dist/Weather.d.ts.map +1 -0
- package/dist/Weather.js +140 -0
- package/dist/Weather.js.map +1 -0
- package/dist/WebGL2Device.d.ts +22 -0
- package/dist/WebGL2Device.d.ts.map +1 -1
- package/dist/WebGL2Device.js +134 -23
- package/dist/WebGL2Device.js.map +1 -1
- package/dist/WebGPUDevice.d.ts +19 -2
- package/dist/WebGPUDevice.d.ts.map +1 -1
- package/dist/WebGPUDevice.js +188 -9
- package/dist/WebGPUDevice.js.map +1 -1
- package/dist/index.d.ts +25 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -19
- package/dist/index.js.map +1 -1
- package/dist/lean/LeanProductRenderer.d.ts +29 -0
- package/dist/lean/LeanProductRenderer.d.ts.map +1 -0
- package/dist/lean/LeanProductRenderer.js +38 -0
- package/dist/lean/LeanProductRenderer.js.map +1 -0
- package/dist/lean/LeanProductionRenderer.d.ts +38 -0
- package/dist/lean/LeanProductionRenderer.d.ts.map +1 -0
- package/dist/lean/LeanProductionRenderer.js +88 -0
- package/dist/lean/LeanProductionRenderer.js.map +1 -0
- package/dist/lean-runtime.d.ts +18 -0
- package/dist/lean-runtime.d.ts.map +1 -0
- package/dist/lean-runtime.js +13 -0
- package/dist/lean-runtime.js.map +1 -0
- package/dist/postprocess/EffectComposer.d.ts.map +1 -1
- package/dist/postprocess/EffectComposer.js +1 -3
- package/dist/postprocess/EffectComposer.js.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.js +5 -1
- package/dist/production-runtime/PBRHDRPipeline.js.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.d.ts +9 -0
- package/dist/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.js.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts +5 -0
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.js +53 -5
- package/dist/production-runtime/ProductionRuntimeRenderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts +10 -0
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.js +21 -2
- package/dist/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js +4 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/webgpu-device-entry.d.ts +25 -0
- package/dist/webgpu-device-entry.d.ts.map +1 -0
- package/dist/webgpu-device-entry.js +24 -0
- package/dist/webgpu-device-entry.js.map +1 -0
- package/dist/webgpu.d.ts +25 -0
- package/dist/webgpu.d.ts.map +1 -0
- package/dist/webgpu.js +24 -0
- package/dist/webgpu.js.map +1 -0
- package/package.json +11 -3
package/dist/WebGL2Device.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RenderDeviceError, } from "./RenderDevice.js";
|
|
2
2
|
import { Texture, isCompressedTextureFormat, isFloatColorTextureFormat } from "./Texture.js";
|
|
3
|
-
import { TextureBinding } from "./TextureBinding.js";
|
|
3
|
+
import { isTextureBinding, TextureBinding } from "./TextureBinding.js";
|
|
4
4
|
import {} from "./VertexFormat.js";
|
|
5
5
|
import { WebGL2StateCache } from "./WebGL2StateCache.js";
|
|
6
6
|
import { BLOOM_BRIGHT_LUT_HEIGHT, BLOOM_BRIGHT_LUT_WIDTH, BLOOM_COMPOSITE_LUT_SIZE, OUTLINE_BLEND_LUT_WIDTH, OUTLINE_LIMB_RADIX, createOutlineBlendLut, createOutlineGradientBound, createBloomBrightThresholdLut, createBloomCompositeLut } from "./postprocess/NativeLdrEffectLuts.js";
|
|
@@ -169,6 +169,16 @@ export class WebGL2Device {
|
|
|
169
169
|
maxVertexAttributes;
|
|
170
170
|
anisotropicFilteringExtension;
|
|
171
171
|
maxTextureAnisotropy;
|
|
172
|
+
/**
|
|
173
|
+
* WS-2.6 — subscribers for context loss and restoration.
|
|
174
|
+
*
|
|
175
|
+
* The device has tracked `contextLost` since before 1.6 and acted on it internally, but nothing
|
|
176
|
+
* could *observe* it: there was no callback, so a consumer could only poll `diagnostics()`. That is
|
|
177
|
+
* why the parity table listed context-loss recovery as a gap while the listeners existed — the
|
|
178
|
+
* device layer was never the gap, the absence of a public signal was.
|
|
179
|
+
*/
|
|
180
|
+
deviceLostListeners = new Set();
|
|
181
|
+
deviceRestoredListeners = new Set();
|
|
172
182
|
contextLostListener;
|
|
173
183
|
contextRestoredListener;
|
|
174
184
|
canvas;
|
|
@@ -196,6 +206,16 @@ export class WebGL2Device {
|
|
|
196
206
|
constructor(gl, canvas, errorCheckMode) {
|
|
197
207
|
this.errorCheckMode = errorCheckMode;
|
|
198
208
|
this.gl = gl;
|
|
209
|
+
// A browser returns the same WebGL2 context object after `webglcontextrestored`.
|
|
210
|
+
// The controller that owned it before the loss is disposed before a replacement
|
|
211
|
+
// device mounts, and Chromium can leave an INVALID_OPERATION from that stale
|
|
212
|
+
// resource teardown in the context's error queue. A fresh device must establish
|
|
213
|
+
// its own error boundary; otherwise its first valid uniform upload or presentation
|
|
214
|
+
// is blamed for an error produced by the previous owner.
|
|
215
|
+
for (let index = 0; index < 16 && gl.getError() !== gl.NO_ERROR; index += 1) {
|
|
216
|
+
// Drain only errors that predate this device. Normal frame/strict checks still
|
|
217
|
+
// report every error generated after construction.
|
|
218
|
+
}
|
|
199
219
|
this.maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
|
200
220
|
this.anisotropicFilteringExtension = gl.getExtension("EXT_texture_filter_anisotropic");
|
|
201
221
|
this.maxTextureAnisotropy = this.anisotropicFilteringExtension
|
|
@@ -230,15 +250,53 @@ export class WebGL2Device {
|
|
|
230
250
|
this.contextLost = true;
|
|
231
251
|
this.lastError = "CONTEXT_LOST";
|
|
232
252
|
this.frameActive = false;
|
|
253
|
+
// WS-2.6: notify subscribers. Errors in a listener must not prevent the others from running,
|
|
254
|
+
// nor leave the device in a half-notified state during an already-degraded condition.
|
|
255
|
+
for (const listener of [...this.deviceLostListeners]) {
|
|
256
|
+
try {
|
|
257
|
+
listener();
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// A listener that throws is the listener's problem; the device stays consistent.
|
|
261
|
+
}
|
|
262
|
+
}
|
|
233
263
|
});
|
|
234
264
|
this.contextRestoredListener = (() => {
|
|
235
265
|
this.contextLost = false;
|
|
236
266
|
this.lastError = null;
|
|
267
|
+
for (const listener of [...this.deviceRestoredListeners]) {
|
|
268
|
+
try {
|
|
269
|
+
listener();
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
// As above.
|
|
273
|
+
}
|
|
274
|
+
}
|
|
237
275
|
});
|
|
238
276
|
canvas.addEventListener("webglcontextlost", this.contextLostListener);
|
|
239
277
|
canvas.addEventListener("webglcontextrestored", this.contextRestoredListener);
|
|
240
278
|
}
|
|
241
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Subscribe to WebGL context loss. Returns an unsubscribe function.
|
|
282
|
+
*
|
|
283
|
+
* A lost context is not an error a caller can prevent — the browser reclaims GPU resources under
|
|
284
|
+
* memory pressure, on driver reset, or when a tab is backgrounded too long. What a caller can do is
|
|
285
|
+
* be told, so it can recreate resources rather than render nothing.
|
|
286
|
+
*/
|
|
287
|
+
onDeviceLost(listener) {
|
|
288
|
+
this.deviceLostListeners.add(listener);
|
|
289
|
+
return () => this.deviceLostListeners.delete(listener);
|
|
290
|
+
}
|
|
291
|
+
/** Subscribe to context restoration. Returns an unsubscribe function. */
|
|
292
|
+
onDeviceRestored(listener) {
|
|
293
|
+
this.deviceRestoredListeners.add(listener);
|
|
294
|
+
return () => this.deviceRestoredListeners.delete(listener);
|
|
295
|
+
}
|
|
296
|
+
/** True while the WebGL context is lost. Polling alternative to {@link onDeviceLost}. */
|
|
297
|
+
isDeviceLost() {
|
|
298
|
+
return this.contextLost;
|
|
299
|
+
}
|
|
242
300
|
createBuffer(usage, byteLength, initialData) {
|
|
243
301
|
this.assertAlive();
|
|
244
302
|
if (byteLength <= 0 || !Number.isInteger(byteLength)) {
|
|
@@ -574,13 +632,6 @@ export class WebGL2Device {
|
|
|
574
632
|
format: source.colorTexture.format
|
|
575
633
|
});
|
|
576
634
|
}
|
|
577
|
-
if (source.colorTexture.format !== "rgba8" && bloomPass) {
|
|
578
|
-
throw new RenderDeviceError("WebGL2 native LUT bloom accepts rgba8 input; HDR bloom must use the renderer float-bloom path before tone mapping.", "WEBGL_LDR_POSTPROCESS_FORMAT_UNSUPPORTED", {
|
|
579
|
-
targetId: source.id,
|
|
580
|
-
format: source.colorTexture.format,
|
|
581
|
-
pass: "bloom"
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
635
|
if (source.colorTexture.format !== "rgba8" && (depthOfFieldPass || motionBlurPass || ssaoPass || ssrPass || taaPass || outlinePass) && !tonePass) {
|
|
585
636
|
throw new RenderDeviceError("WebGL2 byte-kernel postprocess requires rgba8 input or a preceding tone-mapping pass.", "WEBGL_LDR_POSTPROCESS_FORMAT_UNSUPPORTED", {
|
|
586
637
|
targetId: source.id,
|
|
@@ -628,10 +679,11 @@ export class WebGL2Device {
|
|
|
628
679
|
const outlineOptions = outlinePass ? normalizeNativeOutlineOptions(outlinePass.options) : undefined;
|
|
629
680
|
const program = this.ensureLdrPostprocessProgram();
|
|
630
681
|
const vertexArray = this.ensurePresentationVertexArray();
|
|
682
|
+
const sourceIsHdr = source.colorTexture.format !== "rgba8";
|
|
631
683
|
const bloomResources = bloomOptions || depthOfFieldOptions || motionBlurOptions || ssaoOptions || ssrOptions || taaOptions || outlineOptions
|
|
632
|
-
? this.ensureBloomPingPongResources(source.width, source.height)
|
|
684
|
+
? this.ensureBloomPingPongResources(source.width, source.height, sourceIsHdr && Boolean(bloomOptions))
|
|
633
685
|
: undefined;
|
|
634
|
-
if (bloomOptions) {
|
|
686
|
+
if (bloomOptions && !sourceIsHdr) {
|
|
635
687
|
this.ensureBloomLutTextures(bloomOptions);
|
|
636
688
|
}
|
|
637
689
|
if (outlineOptions) {
|
|
@@ -650,7 +702,7 @@ export class WebGL2Device {
|
|
|
650
702
|
let ldrSourceHandle = source.colorHandle;
|
|
651
703
|
let temporarySourceIndex = -1;
|
|
652
704
|
if (bloomOptions && bloomResources) {
|
|
653
|
-
ldrSourceHandle = this.executeNativeBloomPasses(ldrSourceHandle, bloomResources, bloomOptions, vertexArray);
|
|
705
|
+
ldrSourceHandle = this.executeNativeBloomPasses(ldrSourceHandle, bloomResources, bloomOptions, vertexArray, sourceIsHdr);
|
|
654
706
|
temporarySourceIndex = 1;
|
|
655
707
|
}
|
|
656
708
|
if ((depthOfFieldOptions || motionBlurOptions || ssaoOptions || ssrOptions || taaOptions || outlineOptions) && bloomResources) {
|
|
@@ -1008,6 +1060,8 @@ export class WebGL2Device {
|
|
|
1008
1060
|
}
|
|
1009
1061
|
dispose() {
|
|
1010
1062
|
if (this.canvas && "removeEventListener" in this.canvas) {
|
|
1063
|
+
this.deviceLostListeners.clear();
|
|
1064
|
+
this.deviceRestoredListeners.clear();
|
|
1011
1065
|
if (this.contextLostListener)
|
|
1012
1066
|
this.canvas.removeEventListener("webglcontextlost", this.contextLostListener);
|
|
1013
1067
|
if (this.contextRestoredListener)
|
|
@@ -1223,9 +1277,9 @@ export class WebGL2Device {
|
|
|
1223
1277
|
this.restoreFullscreenPresentationState(previousState, outputWidth, outputHeight);
|
|
1224
1278
|
}
|
|
1225
1279
|
}
|
|
1226
|
-
ensureBloomPingPongResources(width, height) {
|
|
1280
|
+
ensureBloomPingPongResources(width, height, hdr = false) {
|
|
1227
1281
|
const current = this.bloomPingPongResources;
|
|
1228
|
-
if (current && current.width === width && current.height === height) {
|
|
1282
|
+
if (current && current.width === width && current.height === height && current.hdr === hdr) {
|
|
1229
1283
|
return current;
|
|
1230
1284
|
}
|
|
1231
1285
|
this.disposeBloomPingPongResources();
|
|
@@ -1255,7 +1309,7 @@ export class WebGL2Device {
|
|
|
1255
1309
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
1256
1310
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
1257
1311
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
1258
|
-
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA8, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
|
|
1312
|
+
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, hdr ? this.gl.RGBA16F : this.gl.RGBA8, width, height, 0, this.gl.RGBA, hdr ? this.gl.HALF_FLOAT : this.gl.UNSIGNED_BYTE, null);
|
|
1259
1313
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
|
|
1260
1314
|
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, texture, 0);
|
|
1261
1315
|
const status = this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER);
|
|
@@ -1271,6 +1325,7 @@ export class WebGL2Device {
|
|
|
1271
1325
|
const resources = {
|
|
1272
1326
|
width,
|
|
1273
1327
|
height,
|
|
1328
|
+
hdr,
|
|
1274
1329
|
textures: [textures[0], textures[1]],
|
|
1275
1330
|
framebuffers: [framebuffers[0], framebuffers[1]]
|
|
1276
1331
|
};
|
|
@@ -1412,10 +1467,10 @@ export class WebGL2Device {
|
|
|
1412
1467
|
this.gl.uniform1f(this.gl.getUniformLocation(program, "u_subpixelBlend"), numberOption(fxaaOptions, "subpixelBlend", 0.75));
|
|
1413
1468
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1414
1469
|
}
|
|
1415
|
-
executeNativeBloomPasses(sourceTexture, resources, options, vertexArray) {
|
|
1470
|
+
executeNativeBloomPasses(sourceTexture, resources, options, vertexArray, hdr) {
|
|
1416
1471
|
const brightLut = this.bloomBrightLutTexture;
|
|
1417
1472
|
const compositeLut = this.bloomCompositeLutTexture;
|
|
1418
|
-
if (!brightLut || !compositeLut) {
|
|
1473
|
+
if (!hdr && (!brightLut || !compositeLut)) {
|
|
1419
1474
|
throw new RenderDeviceError("WebGL2 bloom lookup textures were not initialized", "WEBGL_ALLOCATION_FAILED");
|
|
1420
1475
|
}
|
|
1421
1476
|
const [textureA, textureB] = resources.textures;
|
|
@@ -1426,9 +1481,12 @@ export class WebGL2Device {
|
|
|
1426
1481
|
this.gl.useProgram(brightProgram);
|
|
1427
1482
|
this.gl.bindVertexArray(vertexArray);
|
|
1428
1483
|
this.bindFullscreenTexture(0, sourceTexture);
|
|
1429
|
-
|
|
1484
|
+
if (brightLut)
|
|
1485
|
+
this.bindFullscreenTexture(1, brightLut);
|
|
1430
1486
|
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_source"), 0);
|
|
1431
1487
|
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_brightLut"), 1);
|
|
1488
|
+
this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1489
|
+
this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_threshold"), options.threshold);
|
|
1432
1490
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1433
1491
|
const blurProgram = this.ensureBloomBlurProgram();
|
|
1434
1492
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferB);
|
|
@@ -1438,6 +1496,7 @@ export class WebGL2Device {
|
|
|
1438
1496
|
this.gl.uniform2i(this.gl.getUniformLocation(blurProgram, "u_size"), resources.width, resources.height);
|
|
1439
1497
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), options.radius);
|
|
1440
1498
|
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 1);
|
|
1499
|
+
this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1441
1500
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1442
1501
|
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebufferA);
|
|
1443
1502
|
this.bindFullscreenTexture(0, textureB);
|
|
@@ -1448,10 +1507,13 @@ export class WebGL2Device {
|
|
|
1448
1507
|
this.gl.useProgram(compositeProgram);
|
|
1449
1508
|
this.bindFullscreenTexture(0, sourceTexture);
|
|
1450
1509
|
this.bindFullscreenTexture(1, textureA);
|
|
1451
|
-
|
|
1510
|
+
if (compositeLut)
|
|
1511
|
+
this.bindFullscreenTexture(2, compositeLut);
|
|
1452
1512
|
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_source"), 0);
|
|
1453
1513
|
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_blurred"), 1);
|
|
1454
1514
|
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_compositeLut"), 2);
|
|
1515
|
+
this.gl.uniform1i(this.gl.getUniformLocation(compositeProgram, "u_hdr"), hdr ? 1 : 0);
|
|
1516
|
+
this.gl.uniform1f(this.gl.getUniformLocation(compositeProgram, "u_intensity"), options.intensity);
|
|
1455
1517
|
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
1456
1518
|
return textureB;
|
|
1457
1519
|
}
|
|
@@ -1792,6 +1854,8 @@ precision highp float;
|
|
|
1792
1854
|
precision highp int;
|
|
1793
1855
|
uniform sampler2D u_source;
|
|
1794
1856
|
uniform sampler2D u_brightLut;
|
|
1857
|
+
uniform int u_hdr;
|
|
1858
|
+
uniform float u_threshold;
|
|
1795
1859
|
out vec4 outColor;
|
|
1796
1860
|
|
|
1797
1861
|
uvec4 byteTexel(sampler2D source, ivec2 coordinate) {
|
|
@@ -1800,6 +1864,12 @@ uvec4 byteTexel(sampler2D source, ivec2 coordinate) {
|
|
|
1800
1864
|
|
|
1801
1865
|
void main() {
|
|
1802
1866
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
1867
|
+
if (u_hdr == 1) {
|
|
1868
|
+
vec4 source = texelFetch(u_source, pixel, 0);
|
|
1869
|
+
float luma = dot(source.rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
1870
|
+
outColor = luma >= u_threshold ? source : vec4(0.0);
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1803
1873
|
uvec4 source = byteTexel(u_source, pixel);
|
|
1804
1874
|
uint colorIndex = (source.r << 16u) | (source.g << 8u) | source.b;
|
|
1805
1875
|
uint byteIndex = colorIndex >> 3u;
|
|
@@ -1834,6 +1904,7 @@ uniform sampler2D u_source;
|
|
|
1834
1904
|
uniform ivec2 u_size;
|
|
1835
1905
|
uniform int u_radius;
|
|
1836
1906
|
uniform int u_horizontal;
|
|
1907
|
+
uniform int u_hdr;
|
|
1837
1908
|
out vec4 outColor;
|
|
1838
1909
|
|
|
1839
1910
|
uvec4 sourceByte(ivec2 coordinate) {
|
|
@@ -1843,6 +1914,16 @@ uvec4 sourceByte(ivec2 coordinate) {
|
|
|
1843
1914
|
|
|
1844
1915
|
void main() {
|
|
1845
1916
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
1917
|
+
if (u_hdr == 1) {
|
|
1918
|
+
vec4 sum = vec4(0.0);
|
|
1919
|
+
for (int offset = -16; offset <= 16; offset += 1) {
|
|
1920
|
+
if (abs(offset) > u_radius) continue;
|
|
1921
|
+
ivec2 sampleCoordinate = pixel + (u_horizontal == 1 ? ivec2(offset, 0) : ivec2(0, offset));
|
|
1922
|
+
sum += texelFetch(u_source, clamp(sampleCoordinate, ivec2(0), u_size - ivec2(1)), 0);
|
|
1923
|
+
}
|
|
1924
|
+
outColor = sum / float(u_radius * 2 + 1);
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1846
1927
|
uvec4 sum = uvec4(0u);
|
|
1847
1928
|
for (int offset = -16; offset <= 16; offset += 1) {
|
|
1848
1929
|
if (abs(offset) > u_radius) {
|
|
@@ -1872,6 +1953,8 @@ precision highp int;
|
|
|
1872
1953
|
uniform sampler2D u_source;
|
|
1873
1954
|
uniform sampler2D u_blurred;
|
|
1874
1955
|
uniform sampler2D u_compositeLut;
|
|
1956
|
+
uniform int u_hdr;
|
|
1957
|
+
uniform float u_intensity;
|
|
1875
1958
|
out vec4 outColor;
|
|
1876
1959
|
|
|
1877
1960
|
uvec4 byteTexel(sampler2D source, ivec2 coordinate) {
|
|
@@ -1884,6 +1967,12 @@ float compositeChannel(uint source, uint blurred) {
|
|
|
1884
1967
|
|
|
1885
1968
|
void main() {
|
|
1886
1969
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
1970
|
+
if (u_hdr == 1) {
|
|
1971
|
+
vec4 source = texelFetch(u_source, pixel, 0);
|
|
1972
|
+
vec3 blurred = texelFetch(u_blurred, pixel, 0).rgb;
|
|
1973
|
+
outColor = vec4(source.rgb + blurred * u_intensity, source.a);
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1887
1976
|
uvec4 source = byteTexel(u_source, pixel);
|
|
1888
1977
|
uvec4 blurred = byteTexel(u_blurred, pixel);
|
|
1889
1978
|
outColor = vec4(
|
|
@@ -2238,8 +2327,28 @@ vec3 encodeColor(vec3 color) {
|
|
|
2238
2327
|
return u_outputColorSpace == 1 ? vec3(linearToSrgb(linear.r), linearToSrgb(linear.g), linearToSrgb(linear.b)) : linear;
|
|
2239
2328
|
}
|
|
2240
2329
|
|
|
2241
|
-
|
|
2242
|
-
|
|
2330
|
+
vec3 acesRrtAndOdtFit(vec3 value) {
|
|
2331
|
+
vec3 numerator = value * (value + 0.0245786) - 0.000090537;
|
|
2332
|
+
vec3 denominator = value * (0.983729 * value + 0.4329510) + 0.238081;
|
|
2333
|
+
return numerator / denominator;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
vec3 acesFilmic(vec3 color) {
|
|
2337
|
+
// Match current Three.js ACESFilmicToneMapping. ACES is a coupled RGB
|
|
2338
|
+
// transform; a scalar approximation shifts hue and washes saturated colors.
|
|
2339
|
+
const mat3 acesInput = mat3(
|
|
2340
|
+
vec3(0.59719, 0.07600, 0.02840),
|
|
2341
|
+
vec3(0.35458, 0.90834, 0.13383),
|
|
2342
|
+
vec3(0.04823, 0.01566, 0.83777)
|
|
2343
|
+
);
|
|
2344
|
+
const mat3 acesOutput = mat3(
|
|
2345
|
+
vec3(1.60475, -0.10208, -0.00327),
|
|
2346
|
+
vec3(-0.53108, 1.10813, -0.07276),
|
|
2347
|
+
vec3(-0.07367, -0.00605, 1.07602)
|
|
2348
|
+
);
|
|
2349
|
+
vec3 acesColor = acesInput * (color / 0.6);
|
|
2350
|
+
acesColor = acesRrtAndOdtFit(acesColor);
|
|
2351
|
+
return clamp(acesOutput * acesColor, 0.0, 1.0);
|
|
2243
2352
|
}
|
|
2244
2353
|
|
|
2245
2354
|
float filmic(float value) {
|
|
@@ -2279,7 +2388,7 @@ float toneMapChannel(float value) {
|
|
|
2279
2388
|
float exposed = max(0.0, value * u_exposure) / max(0.0001, u_whitePoint);
|
|
2280
2389
|
if (u_toneOperator == 0) return min(1.0, exposed);
|
|
2281
2390
|
if (u_toneOperator == 1) return exposed / (1.0 + exposed);
|
|
2282
|
-
if (u_toneOperator == 2) return
|
|
2391
|
+
if (u_toneOperator == 2) return exposed;
|
|
2283
2392
|
if (u_toneOperator == 3) return filmic(exposed);
|
|
2284
2393
|
if (u_toneOperator == 4) return uncharted2(exposed);
|
|
2285
2394
|
if (u_toneOperator == 5) return agx(exposed);
|
|
@@ -2289,7 +2398,9 @@ float toneMapChannel(float value) {
|
|
|
2289
2398
|
vec3 applyToneMapping(vec3 color) {
|
|
2290
2399
|
if (u_hasToneMapping == 0) return color;
|
|
2291
2400
|
vec3 decoded = decodeColor(color);
|
|
2292
|
-
vec3 mapped =
|
|
2401
|
+
vec3 mapped = u_toneOperator == 2
|
|
2402
|
+
? acesFilmic(max(vec3(0.0), decoded * u_exposure) / max(0.0001, u_whitePoint))
|
|
2403
|
+
: vec3(toneMapChannel(decoded.r), toneMapChannel(decoded.g), toneMapChannel(decoded.b));
|
|
2293
2404
|
return encodeColor(mapped);
|
|
2294
2405
|
}
|
|
2295
2406
|
|
|
@@ -2422,7 +2533,7 @@ void main() {
|
|
|
2422
2533
|
if (location === null) {
|
|
2423
2534
|
throw new RenderDeviceError("Material tried to bind a missing shader uniform", "MISSING_UNIFORM", { name });
|
|
2424
2535
|
}
|
|
2425
|
-
if (value
|
|
2536
|
+
if (isTextureBinding(value)) {
|
|
2426
2537
|
this.uploadTextureUniform(location, value, textureUnit);
|
|
2427
2538
|
textureUnit += 1;
|
|
2428
2539
|
}
|