ris-framework 0.2.0-dev.14 → 0.2.0-dev.16
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/CHANGELOG.md +39 -2
- package/README.md +8 -6
- package/dist/api/IFramework.d.ts +1 -1
- package/dist/api/IFramework.d.ts.map +1 -1
- package/dist/api/_export.d.ts +3 -0
- package/dist/api/_export.d.ts.map +1 -1
- package/dist/api/camera/CameraTransformUtilities.d.ts +65 -0
- package/dist/api/camera/CameraTransformUtilities.d.ts.map +1 -0
- package/dist/api/camera/ICamera.d.ts +36 -2
- package/dist/api/camera/ICamera.d.ts.map +1 -1
- package/dist/api/camera/OrbitCamera.d.ts +22 -14
- package/dist/api/camera/OrbitCamera.d.ts.map +1 -1
- package/dist/api/camera/OrthographicCamera.d.ts +33 -11
- package/dist/api/camera/OrthographicCamera.d.ts.map +1 -1
- package/dist/api/camera/PerspectiveCamera.d.ts +32 -18
- package/dist/api/camera/PerspectiveCamera.d.ts.map +1 -1
- package/dist/api/content/ContentManager.d.ts.map +1 -1
- package/dist/api/lights/AmbientLight.d.ts +7 -2
- package/dist/api/lights/AmbientLight.d.ts.map +1 -1
- package/dist/api/lights/DirectionalLight.d.ts +18 -4
- package/dist/api/lights/DirectionalLight.d.ts.map +1 -1
- package/dist/api/lights/ILight.d.ts +18 -0
- package/dist/api/lights/ILight.d.ts.map +1 -0
- package/dist/api/lights/PointLight.d.ts +17 -4
- package/dist/api/lights/PointLight.d.ts.map +1 -1
- package/dist/api/lights/_export.d.ts +1 -0
- package/dist/api/lights/_export.d.ts.map +1 -1
- package/dist/api/material/ForwardBlinnPhongMaterial.d.ts +2 -2
- package/dist/api/material/ForwardBlinnPhongMaterial.d.ts.map +1 -1
- package/dist/api/material/IMaterial.d.ts +7 -0
- package/dist/api/material/IMaterial.d.ts.map +1 -1
- package/dist/api/material/IMaterialFactory.d.ts +3 -2
- package/dist/api/material/IMaterialFactory.d.ts.map +1 -1
- package/dist/api/material/IUnlitMaterialDescriptor.d.ts +16 -0
- package/dist/api/material/IUnlitMaterialDescriptor.d.ts.map +1 -0
- package/dist/api/material/MaterialFactory.d.ts +3 -2
- package/dist/api/material/MaterialFactory.d.ts.map +1 -1
- package/dist/api/material/SpriteMaterial.d.ts +3 -0
- package/dist/api/material/SpriteMaterial.d.ts.map +1 -1
- package/dist/api/material/UnlitMaterial.d.ts +5 -12
- package/dist/api/material/UnlitMaterial.d.ts.map +1 -1
- package/dist/api/material/_export.d.ts +1 -1
- package/dist/api/material/_export.d.ts.map +1 -1
- package/dist/api/meshes/IRenderableMesh.d.ts +3 -14
- package/dist/api/meshes/IRenderableMesh.d.ts.map +1 -1
- package/dist/api/meshes/RenderableMesh.d.ts +5 -20
- package/dist/api/meshes/RenderableMesh.d.ts.map +1 -1
- package/dist/api/rendering/IGraphicsDevice.d.ts +2 -2
- package/dist/api/rendering/IGraphicsDevice.d.ts.map +1 -1
- package/dist/api/rendering/IRenderer.d.ts +6 -4
- package/dist/api/rendering/IRenderer.d.ts.map +1 -1
- package/dist/api/rendering/_export-rendering.d.ts +1 -0
- package/dist/api/rendering/_export-rendering.d.ts.map +1 -1
- package/dist/api/rendering/primitive/IPrimitiveStateDescriptor.d.ts +24 -0
- package/dist/api/rendering/primitive/IPrimitiveStateDescriptor.d.ts.map +1 -0
- package/dist/api/rendering/primitive/_export.d.ts +1 -1
- package/dist/api/rendering/primitive/_export.d.ts.map +1 -1
- package/dist/api/rendering/render-pipelines/IMainRenderTargetRenderPipeline.d.ts +5 -0
- package/dist/api/rendering/render-pipelines/IMainRenderTargetRenderPipeline.d.ts.map +1 -1
- package/dist/api/rendering/texture/ITextureDescriptor.d.ts +5 -1
- package/dist/api/rendering/texture/ITextureDescriptor.d.ts.map +1 -1
- package/dist/api/rendering/texture/ITextureFactory.d.ts +3 -1
- package/dist/api/rendering/texture/ITextureFactory.d.ts.map +1 -1
- package/dist/api/rendering/texture/TextureUtilities.d.ts +7 -0
- package/dist/api/rendering/texture/TextureUtilities.d.ts.map +1 -1
- package/dist/api/scene/ISceneObject.d.ts +12 -0
- package/dist/api/scene/ISceneObject.d.ts.map +1 -0
- package/dist/api/scene/Scene.d.ts +17 -6
- package/dist/api/scene/Scene.d.ts.map +1 -1
- package/dist/api/scene/node/Node.d.ts +26 -0
- package/dist/api/scene/node/Node.d.ts.map +1 -0
- package/dist/api/scene/node/TransformNode.d.ts +46 -0
- package/dist/api/scene/node/TransformNode.d.ts.map +1 -0
- package/dist/core/material/UnlitMaterialDescriptorUtilities.d.ts +17 -0
- package/dist/core/material/UnlitMaterialDescriptorUtilities.d.ts.map +1 -0
- package/dist/core/rendering/AGraphicsDevice.d.ts +2 -2
- package/dist/core/rendering/AGraphicsDevice.d.ts.map +1 -1
- package/dist/core/rendering/ARenderer.d.ts +5 -2
- package/dist/core/rendering/ARenderer.d.ts.map +1 -1
- package/dist/core/rendering/primitive/PrimitiveStateDescriptorUtilities.d.ts +15 -0
- package/dist/core/rendering/primitive/PrimitiveStateDescriptorUtilities.d.ts.map +1 -0
- package/dist/core/rendering/texture/TextureDescriptorUtilities.d.ts +2 -2
- package/dist/core/rendering/texture/TextureDescriptorUtilities.d.ts.map +1 -1
- package/dist/index.js +704 -272
- package/dist/webgl/WebGlGraphicsDevice.d.ts +2 -2
- package/dist/webgl/WebGlGraphicsDevice.d.ts.map +1 -1
- package/dist/webgl/lights/WebGlLightsBuffer.d.ts.map +1 -1
- package/dist/webgl/primitive/WebGlPrimitiveState.d.ts +3 -3
- package/dist/webgl/primitive/WebGlPrimitiveState.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts +8 -0
- package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/texture/WebGlTextureFactory.d.ts +1 -1
- package/dist/webgl/texture/WebGlTextureFactory.d.ts.map +1 -1
- package/dist/webgl/utilities/WebGlTextureUtilities.d.ts.map +1 -1
- package/dist/webgpu/WebGpuGraphicsDevice.d.ts +2 -2
- package/dist/webgpu/WebGpuGraphicsDevice.d.ts.map +1 -1
- package/dist/webgpu/primitive/WebGpuPrimitiveState.d.ts +2 -2
- package/dist/webgpu/primitive/WebGpuPrimitiveState.d.ts.map +1 -1
- package/dist/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.d.ts +5 -0
- package/dist/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.d.ts.map +1 -1
- package/dist/webgpu/texture/WebGpuTextureFactory.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/Framework.ts +1 -1
- package/src/api/IFramework.ts +1 -1
- package/src/api/_export.ts +3 -0
- package/src/api/camera/CameraTransformUtilities.ts +182 -0
- package/src/api/camera/ICamera.ts +42 -2
- package/src/api/camera/OrbitCamera.ts +71 -38
- package/src/api/camera/OrthographicCamera.ts +71 -28
- package/src/api/camera/PerspectiveCamera.ts +69 -33
- package/src/api/content/ContentManager.ts +9 -5
- package/src/api/lights/AmbientLight.ts +8 -2
- package/src/api/lights/DirectionalLight.ts +30 -5
- package/src/api/lights/ILight.ts +22 -0
- package/src/api/lights/PointLight.ts +26 -5
- package/src/api/lights/_export.ts +1 -0
- package/src/api/material/ForwardBlinnPhongMaterial.ts +2 -2
- package/src/api/material/IMaterial.ts +8 -0
- package/src/api/material/IMaterialFactory.ts +3 -2
- package/src/api/material/IUnlitMaterialDescriptor.ts +18 -0
- package/src/api/material/MaterialFactory.ts +4 -3
- package/src/api/material/SpriteMaterial.ts +4 -0
- package/src/api/material/UnlitMaterial.ts +11 -18
- package/src/api/material/_export.ts +1 -1
- package/src/api/meshes/IRenderableMesh.ts +3 -18
- package/src/api/meshes/RenderableMesh.ts +15 -45
- package/src/api/rendering/IGraphicsDevice.ts +2 -2
- package/src/api/rendering/IRenderer.ts +6 -4
- package/src/api/rendering/_export-rendering.ts +2 -1
- package/src/api/rendering/primitive/IPrimitiveStateDescriptor.ts +27 -0
- package/src/api/rendering/primitive/_export.ts +1 -1
- package/src/api/rendering/render-pipelines/IMainRenderTargetRenderPipeline.ts +6 -0
- package/src/api/rendering/texture/ITextureDescriptor.ts +6 -1
- package/src/api/rendering/texture/ITextureFactory.ts +3 -1
- package/src/api/rendering/texture/TextureUtilities.ts +16 -0
- package/src/api/scene/ISceneObject.ts +13 -0
- package/src/api/scene/Scene.ts +52 -11
- package/src/api/scene/node/Node.ts +54 -0
- package/src/api/scene/node/TransformNode.ts +88 -0
- package/src/core/material/UnlitMaterialDescriptorUtilities.ts +21 -0
- package/src/core/rendering/AGraphicsDevice.ts +2 -2
- package/src/core/rendering/ARenderer.ts +23 -5
- package/src/core/rendering/primitive/PrimitiveStateDescriptorUtilities.ts +22 -0
- package/src/core/rendering/texture/TextureDescriptorUtilities.ts +3 -2
- package/src/webgl/WebGlGraphicsDevice.ts +2 -3
- package/src/webgl/lights/WebGlLightsBuffer.ts +21 -8
- package/src/webgl/primitive/WebGlPrimitiveState.ts +8 -6
- package/src/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.ts +14 -0
- package/src/webgl/texture/WebGlTextureFactory.ts +27 -16
- package/src/webgl/utilities/WebGlTextureUtilities.ts +10 -4
- package/src/webgpu/WebGpuGraphicsDevice.ts +3 -3
- package/src/webgpu/primitive/WebGpuPrimitiveState.ts +7 -5
- package/src/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.ts +6 -0
- package/src/webgpu/texture/WebGpuTextureFactory.ts +1 -1
- package/dist/api/material/ICameraMaterial.d.ts +0 -18
- package/dist/api/material/ICameraMaterial.d.ts.map +0 -1
- package/dist/api/rendering/primitive/PrimitiveStateDescriptor.d.ts +0 -24
- package/dist/api/rendering/primitive/PrimitiveStateDescriptor.d.ts.map +0 -1
- package/src/api/material/ICameraMaterial.ts +0 -22
- package/src/api/rendering/primitive/PrimitiveStateDescriptor.ts +0 -27
|
@@ -195,6 +195,7 @@ export class TextureUtilities {
|
|
|
195
195
|
[TextureFormat.BC7_RGBA_UNORM]: KtxTranscodeFormat.BC7_RGBA,
|
|
196
196
|
[TextureFormat.ETC2_RGBA8_UNORM]: KtxTranscodeFormat.ETC2_RGBA,
|
|
197
197
|
[TextureFormat.PVRTC_4BPPV1_RGBA] : KtxTranscodeFormat.PVRTC1_4_RGBA,
|
|
198
|
+
[TextureFormat.PVRTC_4BPPV1_RGB] : KtxTranscodeFormat.PVRTC1_4_RGB,
|
|
198
199
|
// Basis transcodes to the same blocks for sRGB; only the GPU format differs.
|
|
199
200
|
[TextureFormat.RGBA_8_UNORM_SRGB]: KtxTranscodeFormat.RGBA32,
|
|
200
201
|
[TextureFormat.ASTC_4X4_RGBA_SRGB]: KtxTranscodeFormat.ASTC_4X4_RGBA,
|
|
@@ -343,4 +344,19 @@ export class TextureUtilities {
|
|
|
343
344
|
public static isSrgbFormat(textureFormat: TextureFormat) : boolean {
|
|
344
345
|
return this._srgbFormats.includes(textureFormat);
|
|
345
346
|
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Returns the requested format if it is the file's format or its sRGB/linear variant.
|
|
350
|
+
* @param fileFormat The format the data is stored in.
|
|
351
|
+
* @param requested The explicitly requested format.
|
|
352
|
+
* @throws If the requested format cannot reinterpret the data.
|
|
353
|
+
*/
|
|
354
|
+
public static resolveExplicitFormat(fileFormat: TextureFormat, requested: TextureFormat): TextureFormat {
|
|
355
|
+
if (requested == fileFormat
|
|
356
|
+
|| requested == TextureUtilities.convertToSrgbVariant(fileFormat)
|
|
357
|
+
|| requested == TextureUtilities.convertToLinearVariant(fileFormat)) {
|
|
358
|
+
return requested;
|
|
359
|
+
}
|
|
360
|
+
throw new Error(`Texture format ${requested} is not compatible with the file's format ${fileFormat}; only its sRGB or linear variant can be used.`);
|
|
361
|
+
}
|
|
346
362
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type {TransformNode} from "./node/TransformNode.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An object that can be placed in a scene: it has a transform.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface ISceneObject {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The transform node.
|
|
11
|
+
*/
|
|
12
|
+
transform: TransformNode;
|
|
13
|
+
}
|
package/src/api/scene/Scene.ts
CHANGED
|
@@ -5,13 +5,14 @@ import type {IDisposable} from "../core/IDisposable.ts";
|
|
|
5
5
|
import type {IFramework} from "../IFramework.ts";
|
|
6
6
|
import type {IRenderableMesh} from "../meshes/IRenderableMesh.ts";
|
|
7
7
|
import {SceneMesh} from "./SceneMesh.ts";
|
|
8
|
-
import {isCameraMaterial} from "../material/ICameraMaterial.ts";
|
|
9
8
|
import {isLightsMaterial} from "../material/ILightsMaterial.ts";
|
|
10
9
|
import type {GameTime} from "../time/GameTime.ts";
|
|
11
10
|
import type {ICamera} from "../camera/ICamera.ts";
|
|
11
|
+
import type {ISceneObject} from "./ISceneObject.ts";
|
|
12
|
+
import {TransformNode} from "./node/TransformNode.ts";
|
|
12
13
|
|
|
13
|
-
/** Anything a scene can hold: a mesh, a light (ambient, directional, point) or a camera. */
|
|
14
|
-
export type SceneItem = IRenderableMesh | SceneMesh | AmbientLight | DirectionalLight | PointLight | ICamera;
|
|
14
|
+
/** Anything a scene can hold: a mesh, a scene object, a light (ambient, directional, point) or a camera. */
|
|
15
|
+
export type SceneItem = IRenderableMesh | SceneMesh | ISceneObject | AmbientLight | DirectionalLight | PointLight | ICamera;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* The scene. Lights and cameras given a scene in their constructor add themselves through {@link add};
|
|
@@ -22,6 +23,7 @@ export type SceneItem = IRenderableMesh | SceneMesh | AmbientLight | Directional
|
|
|
22
23
|
export class Scene implements IDisposable {
|
|
23
24
|
|
|
24
25
|
private readonly _sceneMeshes: SceneMesh[] = [];
|
|
26
|
+
private readonly _nodes: ISceneObject[] = [];
|
|
25
27
|
private readonly _directionalLights: DirectionalLight[] = [];
|
|
26
28
|
private readonly _pointLights: PointLight[] = [];
|
|
27
29
|
|
|
@@ -71,6 +73,11 @@ export class Scene implements IDisposable {
|
|
|
71
73
|
return this._sceneMeshes;
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
/** The scene objects (anything with a transform, including root meshes), in the order they were added. */
|
|
77
|
+
public get nodes(): readonly ISceneObject[] {
|
|
78
|
+
return this._nodes;
|
|
79
|
+
}
|
|
80
|
+
|
|
74
81
|
/** The root meshes in this scene, in the order they were added. */
|
|
75
82
|
public get meshes(): readonly IRenderableMesh[] {
|
|
76
83
|
return this._sceneMeshes.map(s => s.mesh);
|
|
@@ -103,9 +110,13 @@ export class Scene implements IDisposable {
|
|
|
103
110
|
* Adds a mesh, a light or a camera. Adding an item that is already in the scene does nothing.
|
|
104
111
|
* - Renderable mesh or {@link SceneMesh}: drawn by {@link render}; its materials get the scene camera and lights.
|
|
105
112
|
* A mesh is wrapped in a `SceneMesh`, so {@link dispose} also disposes its materials.
|
|
106
|
-
*
|
|
113
|
+
* The mesh is also added to {@link nodes}.
|
|
114
|
+
* - {@link ISceneObject} (anything with a `transform`): added to {@link nodes}; {@link update} updates its transform.
|
|
115
|
+
* - Lights are also added to {@link nodes} (they are scene objects).
|
|
116
|
+
* - Ambient light: added to {@link ambientLights} (use {@link activeAmbientLight} to make it the lit one).
|
|
107
117
|
* - Directional / point light: added to {@link directionalLights} / {@link pointLights}.
|
|
108
|
-
* - Camera: becomes the scene {@link camera}.
|
|
118
|
+
* - Camera: becomes the scene {@link camera} and is added to {@link nodes} (cameras are scene objects).
|
|
119
|
+
* Checked before the generic scene object case.
|
|
109
120
|
* Constructors given a scene (lights, the perspective camera) call this themselves.
|
|
110
121
|
* @param item The item to add.
|
|
111
122
|
* @throws Error when all slots for a light kind are in use (3 directional, 5 point), or for an unsupported item.
|
|
@@ -113,10 +124,15 @@ export class Scene implements IDisposable {
|
|
|
113
124
|
public add(item: SceneItem): void {
|
|
114
125
|
if (item instanceof AmbientLight) {
|
|
115
126
|
this._addAmbientLight(item);
|
|
127
|
+
this._addNode(item);
|
|
116
128
|
} else if (item instanceof DirectionalLight || item instanceof PointLight) {
|
|
117
129
|
this._addLight(item);
|
|
130
|
+
this._addNode(item);
|
|
118
131
|
} else if (Scene._isCamera(item)) {
|
|
119
132
|
this.camera = item;
|
|
133
|
+
if (Scene._isSceneObject(item)) {
|
|
134
|
+
this._addNode(item);
|
|
135
|
+
}
|
|
120
136
|
} else if (item instanceof SceneMesh || Scene._isMesh(item)) {
|
|
121
137
|
const mesh = item instanceof SceneMesh ? item.mesh : item;
|
|
122
138
|
if (!this._sceneMeshes.some(s => s.mesh === mesh)) {
|
|
@@ -124,8 +140,11 @@ export class Scene implements IDisposable {
|
|
|
124
140
|
this._sceneMeshes.push(sceneMesh);
|
|
125
141
|
this._bind(sceneMesh);
|
|
126
142
|
}
|
|
143
|
+
this._addNode(mesh);
|
|
144
|
+
} else if (Scene._isSceneObject(item)) {
|
|
145
|
+
this._addNode(item);
|
|
127
146
|
} else {
|
|
128
|
-
throw new Error("Scene.add: expected a mesh, an AmbientLight, DirectionalLight, PointLight or a camera.");
|
|
147
|
+
throw new Error("Scene.add: expected a mesh, a scene object, an AmbientLight, DirectionalLight, PointLight or a camera.");
|
|
129
148
|
}
|
|
130
149
|
}
|
|
131
150
|
|
|
@@ -133,7 +152,7 @@ export class Scene implements IDisposable {
|
|
|
133
152
|
* Removes a mesh (or scene mesh), a light or a camera. The mesh and its materials are not disposed.
|
|
134
153
|
* Removing the active camera clears {@link camera}.
|
|
135
154
|
* @param item The item to remove.
|
|
136
|
-
* @returns True when the item was in the scene
|
|
155
|
+
* @returns True when the item was in the scene.
|
|
137
156
|
* @throws Error when removing the active ambient light (set another {@link activeAmbientLight} first), or for an unsupported item.
|
|
138
157
|
*/
|
|
139
158
|
public remove(item: SceneItem): boolean {
|
|
@@ -141,16 +160,19 @@ export class Scene implements IDisposable {
|
|
|
141
160
|
if (item === this._activeAmbientLight) {
|
|
142
161
|
throw new Error("Scene.remove: cannot remove the active ambient light; set scene.activeAmbientLight to another light first.");
|
|
143
162
|
}
|
|
163
|
+
Scene._removeFrom(this._nodes, item);
|
|
144
164
|
return Scene._removeFrom(this.ambientLights, item);
|
|
145
165
|
}
|
|
146
166
|
if (item instanceof DirectionalLight || item instanceof PointLight) {
|
|
167
|
+
Scene._removeFrom(this._nodes, item);
|
|
147
168
|
return item instanceof DirectionalLight
|
|
148
169
|
? Scene._removeFrom(this._directionalLights, item)
|
|
149
170
|
: Scene._removeFrom(this._pointLights, item);
|
|
150
171
|
}
|
|
151
172
|
if (Scene._isCamera(item)) {
|
|
173
|
+
const wasNode = Scene._removeFrom(this._nodes, item);
|
|
152
174
|
if (item !== this._activeCamera) {
|
|
153
|
-
return
|
|
175
|
+
return wasNode;
|
|
154
176
|
}
|
|
155
177
|
this._activeCamera = undefined;
|
|
156
178
|
return true;
|
|
@@ -158,13 +180,17 @@ export class Scene implements IDisposable {
|
|
|
158
180
|
if (item instanceof SceneMesh || Scene._isMesh(item)) {
|
|
159
181
|
const mesh = item instanceof SceneMesh ? item.mesh : item;
|
|
160
182
|
const index = this._sceneMeshes.findIndex(s => s.mesh === mesh);
|
|
183
|
+
Scene._removeFrom(this._nodes, mesh);
|
|
161
184
|
if (index < 0) {
|
|
162
185
|
return false;
|
|
163
186
|
}
|
|
164
187
|
this._sceneMeshes.splice(index, 1);
|
|
165
188
|
return true;
|
|
166
189
|
}
|
|
167
|
-
|
|
190
|
+
if (Scene._isSceneObject(item)) {
|
|
191
|
+
return Scene._removeFrom(this._nodes, item);
|
|
192
|
+
}
|
|
193
|
+
throw new Error("Scene.remove: expected a mesh, a scene object, an AmbientLight, DirectionalLight, PointLight or a camera.");
|
|
168
194
|
}
|
|
169
195
|
|
|
170
196
|
/**
|
|
@@ -220,6 +246,17 @@ export class Scene implements IDisposable {
|
|
|
220
246
|
&& "projectionViewBuffer" in camera && "viewMatrix" in camera && typeof camera.updateBuffers === "function";
|
|
221
247
|
}
|
|
222
248
|
|
|
249
|
+
/** Scene objects have a TransformNode as transform. */
|
|
250
|
+
private static _isSceneObject(item: unknown): item is ISceneObject {
|
|
251
|
+
return typeof item === "object" && item !== null && (item as Partial<ISceneObject>).transform instanceof TransformNode;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private _addNode(node: ISceneObject): void {
|
|
255
|
+
if (!this._nodes.includes(node)) {
|
|
256
|
+
this._nodes.push(node);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
223
260
|
/** Renderable meshes have render() and sub meshes. */
|
|
224
261
|
private static _isMesh(item: unknown): item is IRenderableMesh {
|
|
225
262
|
const mesh = item as Partial<IRenderableMesh> | null;
|
|
@@ -227,12 +264,15 @@ export class Scene implements IDisposable {
|
|
|
227
264
|
}
|
|
228
265
|
|
|
229
266
|
/**
|
|
230
|
-
* Updates the scene: assigns {@link camera}, the active ambient light and the light lists to the mesh materials.
|
|
267
|
+
* Updates the scene: updates the transforms of {@link nodes}, assigns {@link camera}, the active ambient light and the light lists to the mesh materials.
|
|
231
268
|
* Each lights material uploads its lights buffer when drawn, only if the lights changed.
|
|
232
269
|
* @param _time The game time.
|
|
233
270
|
* @public
|
|
234
271
|
*/
|
|
235
272
|
update(_time: GameTime): void {
|
|
273
|
+
for (const node of this._nodes) {
|
|
274
|
+
node.transform.update(_time);
|
|
275
|
+
}
|
|
236
276
|
for (const sceneMesh of this._sceneMeshes) {
|
|
237
277
|
this._bind(sceneMesh);
|
|
238
278
|
}
|
|
@@ -266,7 +306,7 @@ export class Scene implements IDisposable {
|
|
|
266
306
|
}
|
|
267
307
|
for (const material of sceneMesh.materials) {
|
|
268
308
|
// The setter rebinds buffers, so skip when unchanged.
|
|
269
|
-
if (
|
|
309
|
+
if (material.camera !== camera) {
|
|
270
310
|
material.camera = camera;
|
|
271
311
|
}
|
|
272
312
|
}
|
|
@@ -293,5 +333,6 @@ export class Scene implements IDisposable {
|
|
|
293
333
|
sceneMesh.dispose();
|
|
294
334
|
}
|
|
295
335
|
this._sceneMeshes.length = 0;
|
|
336
|
+
this._nodes.length = 0;
|
|
296
337
|
}
|
|
297
338
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A node in a hierarchy. A node has at most one parent; use {@link addChild} and {@link removeChild}
|
|
3
|
+
* to change the hierarchy (they keep `parent` and `children` in sync).
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export class Node {
|
|
7
|
+
|
|
8
|
+
private readonly _children: Node[] = [];
|
|
9
|
+
private _parent?: Node;
|
|
10
|
+
|
|
11
|
+
/** The child nodes of this node. */
|
|
12
|
+
public get children(): readonly Node[] {
|
|
13
|
+
return this._children;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The parent node of this node, if any. */
|
|
17
|
+
public get parent(): Node | undefined {
|
|
18
|
+
return this._parent;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Adds a child. It is removed from its previous parent first. Adding an existing child does nothing.
|
|
23
|
+
* @param child The child to add.
|
|
24
|
+
* @throws Error when adding the node to itself or to one of its descendants.
|
|
25
|
+
*/
|
|
26
|
+
public addChild(child: Node): void {
|
|
27
|
+
if (child._parent === this) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (let n: Node | undefined = this; n; n = n._parent) {
|
|
31
|
+
if (n === child) {
|
|
32
|
+
throw new Error("Node.addChild: a node cannot be added to itself or to one of its descendants.");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
child._parent?.removeChild(child);
|
|
36
|
+
child._parent = this;
|
|
37
|
+
this._children.push(child);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Removes a child.
|
|
42
|
+
* @param child The child to remove.
|
|
43
|
+
* @returns True when it was a child of this node.
|
|
44
|
+
*/
|
|
45
|
+
public removeChild(child: Node): boolean {
|
|
46
|
+
const index = this._children.indexOf(child);
|
|
47
|
+
if (index < 0) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
this._children.splice(index, 1);
|
|
51
|
+
child._parent = undefined;
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {mat4, quat, vec3} from "gl-matrix";
|
|
2
|
+
import type {GameTime} from "../../time/GameTime.ts";
|
|
3
|
+
import {Node} from "./Node.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The node responsible for transformations in the world.
|
|
7
|
+
*
|
|
8
|
+
* The matrices are computed lazily: reading {@link modelMatrix} recomputes them when position, rotation or scale
|
|
9
|
+
* changed (also through in-place edits), so {@link update} does not have to be called before the first render.
|
|
10
|
+
* When the parent is a `TransformNode`, {@link modelMatrix} is the world matrix `parent.modelMatrix * localMatrix`.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export class TransformNode extends Node {
|
|
14
|
+
|
|
15
|
+
private readonly _rotationQuat = quat.create();
|
|
16
|
+
private readonly _localMatrix = mat4.create();
|
|
17
|
+
private readonly _worldMatrix = mat4.create();
|
|
18
|
+
// Cached copies to detect in-place edits; NaN forces the first computation.
|
|
19
|
+
private readonly _lastPosition = vec3.fromValues(NaN, NaN, NaN);
|
|
20
|
+
private readonly _lastRotation = vec3.create();
|
|
21
|
+
private readonly _lastScale = vec3.create();
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The constructor.
|
|
25
|
+
*/
|
|
26
|
+
public constructor() {
|
|
27
|
+
super();
|
|
28
|
+
|
|
29
|
+
this.position = vec3.fromValues(0, 0, 0);
|
|
30
|
+
this.rotation = vec3.fromValues(0, 0, 0);
|
|
31
|
+
this.scale = vec3.fromValues(1, 1, 1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Position relative to the parent (the world, without one). Defaults to the origin. In-place edits are detected. */
|
|
35
|
+
public position: vec3;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Euler rotation in radians, applied in Y, X, Z order (yaw, pitch, roll): `R = Ry * Rx * Rz`.
|
|
39
|
+
* Defaults to (0, 0, 0). In-place edits are detected.
|
|
40
|
+
*/
|
|
41
|
+
public rotation: vec3;
|
|
42
|
+
|
|
43
|
+
/** Scale. Defaults to (1, 1, 1). In-place edits are detected. */
|
|
44
|
+
public scale: vec3;
|
|
45
|
+
|
|
46
|
+
/** The local matrix `T * R * S`, recomputed only when position, rotation or scale changed. */
|
|
47
|
+
public get localMatrix(): mat4 {
|
|
48
|
+
if (!vec3.exactEquals(this._lastPosition, this.position)
|
|
49
|
+
|| !vec3.exactEquals(this._lastRotation, this.rotation)
|
|
50
|
+
|| !vec3.exactEquals(this._lastScale, this.scale)) {
|
|
51
|
+
vec3.copy(this._lastPosition, this.position);
|
|
52
|
+
vec3.copy(this._lastRotation, this.rotation);
|
|
53
|
+
vec3.copy(this._lastScale, this.scale);
|
|
54
|
+
const q = quat.identity(this._rotationQuat);
|
|
55
|
+
quat.rotateY(q, q, this.rotation[1]);
|
|
56
|
+
quat.rotateX(q, q, this.rotation[0]);
|
|
57
|
+
quat.rotateZ(q, q, this.rotation[2]);
|
|
58
|
+
mat4.fromRotationTranslationScale(this._localMatrix, q, this.position, this.scale);
|
|
59
|
+
}
|
|
60
|
+
return this._localMatrix;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The model (world) matrix: {@link localMatrix}, or `parent.modelMatrix * localMatrix` when the parent is a
|
|
65
|
+
* `TransformNode`. Always the same matrix object for a node without a parent transform.
|
|
66
|
+
*/
|
|
67
|
+
public get modelMatrix(): mat4 {
|
|
68
|
+
const parent = this.parent;
|
|
69
|
+
if (parent instanceof TransformNode) {
|
|
70
|
+
return mat4.multiply(this._worldMatrix, parent.modelMatrix, this.localMatrix);
|
|
71
|
+
}
|
|
72
|
+
return this.localMatrix;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Updates the node and its transform children, recomputing the matrices if needed.
|
|
77
|
+
* Called by `Scene.update` for scene nodes; optional otherwise.
|
|
78
|
+
* @param gameTime The {@link GameTime}
|
|
79
|
+
*/
|
|
80
|
+
public update(gameTime: GameTime): void {
|
|
81
|
+
void this.modelMatrix;
|
|
82
|
+
for (const child of this.children) {
|
|
83
|
+
if (child instanceof TransformNode) {
|
|
84
|
+
child.update(gameTime);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type {IUnlitMaterialDescriptor} from "../../api/material/IUnlitMaterialDescriptor.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An unlit material descriptor with every field present. `undefined` means "use the default":
|
|
5
|
+
* the pipeline's default primitive state, and no camera (a placeholder projection view buffer).
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export type ResolvedUnlitMaterialDescriptor = { [K in keyof Required<IUnlitMaterialDescriptor>]: IUnlitMaterialDescriptor[K] };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fills in the defaults for every missing field of an unlit material descriptor.
|
|
12
|
+
* @param desc The descriptor, possibly partial or missing.
|
|
13
|
+
* @returns A new descriptor with the defaults applied.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function resolveUnlitMaterialDescriptor(desc?: IUnlitMaterialDescriptor): ResolvedUnlitMaterialDescriptor {
|
|
17
|
+
return {
|
|
18
|
+
primitiveState: desc?.primitiveState,
|
|
19
|
+
camera: desc?.camera,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type IBlendState,
|
|
9
9
|
type IPrimitiveState,
|
|
10
10
|
type IGraphicsDevice, SwapChainDescriptor, type RenderPassDescriptor, SamplerFilter, MipMapSamplerFilter,
|
|
11
|
-
type ISwapChain, type IRenderPass, type
|
|
11
|
+
type ISwapChain, type IRenderPass, type IPrimitiveStateDescriptor
|
|
12
12
|
} from "../../api/index.ts";
|
|
13
13
|
import {PowerPreferenceType} from "../../api/rendering/PowerPreference.ts";
|
|
14
14
|
|
|
@@ -103,7 +103,7 @@ export abstract class AGraphicsDevice implements IGraphicsDevice {
|
|
|
103
103
|
public abstract createBlendState(descriptor: BlendStateDescriptor): IBlendState;
|
|
104
104
|
|
|
105
105
|
/** @inheritdoc */
|
|
106
|
-
public abstract createPrimitiveState(descriptor?:
|
|
106
|
+
public abstract createPrimitiveState(descriptor?: IPrimitiveStateDescriptor): IPrimitiveState;
|
|
107
107
|
|
|
108
108
|
/** @inheritDoc */
|
|
109
109
|
public abstract setupDebugCallback(): void;
|
|
@@ -36,6 +36,7 @@ export abstract class ARenderer implements ITempRenderer {
|
|
|
36
36
|
private _swapChainRequiresResize: boolean = false;
|
|
37
37
|
private _mainRenderPassDirty = true;
|
|
38
38
|
private _clearColor: Color = Color.lightPink();
|
|
39
|
+
private _colorSpace: ColorSpace;
|
|
39
40
|
|
|
40
41
|
protected _mainRenderTargetRequiresResize: boolean = false;
|
|
41
42
|
protected _swapChain: ISwapChain = null!;
|
|
@@ -46,6 +47,7 @@ export abstract class ARenderer implements ITempRenderer {
|
|
|
46
47
|
protected _mainRenderTargetPipeline?: IMainRenderTargetRenderPipeline;
|
|
47
48
|
protected _renderConfiguration: IRendererConfiguration;
|
|
48
49
|
|
|
50
|
+
|
|
49
51
|
/** @inheritdoc */
|
|
50
52
|
public get graphicsDevice(): IGraphicsDevice {
|
|
51
53
|
return this._graphicsDevice;
|
|
@@ -67,10 +69,27 @@ export abstract class ARenderer implements ITempRenderer {
|
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/** @inheritdoc */
|
|
70
|
-
public
|
|
72
|
+
public get preferredTextureFormat(): TextureFormat {
|
|
73
|
+
return this._colorSpace == ColorSpace.SRGB ? TextureFormat.RGBA_8_UNORM_SRGB : TextureFormat.RGBA_8_UNORM;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** @inheritDoc */
|
|
77
|
+
public get colorSpace(): ColorSpace {
|
|
78
|
+
return this._colorSpace;
|
|
79
|
+
}
|
|
71
80
|
|
|
72
81
|
/** @inheritDoc */
|
|
73
|
-
public
|
|
82
|
+
public set colorSpace(colorSpace: ColorSpace) {
|
|
83
|
+
if (colorSpace == this._colorSpace) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this._colorSpace = colorSpace;
|
|
87
|
+
if (this._mainRenderTargetPipeline) {
|
|
88
|
+
this._mainRenderTargetPipeline.colorSpace = colorSpace;
|
|
89
|
+
// The main render target's format follows the color space, so recreate it on the next frame.
|
|
90
|
+
this._mainRenderTargetRequiresResize = true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
74
93
|
|
|
75
94
|
/** @inheritdoc */
|
|
76
95
|
public get preferredDepthStencilFormat(): TextureFormat {
|
|
@@ -111,9 +130,7 @@ export abstract class ARenderer implements ITempRenderer {
|
|
|
111
130
|
this._windowManager = framework.windowManager;
|
|
112
131
|
this._currentBackBufferSize[0] = this._windowManager.canvas.width;
|
|
113
132
|
this._currentBackBufferSize[1] = this._windowManager.canvas.height;
|
|
114
|
-
this.
|
|
115
|
-
this.preferredTextureFormat = configuration.textureColorSpace == ColorSpace.SRGB
|
|
116
|
-
? TextureFormat.RGBA_8_UNORM_SRGB : TextureFormat.RGBA_8_UNORM;
|
|
133
|
+
this._colorSpace = configuration.textureColorSpace;
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
backend: RenderingBackend = RenderingBackend.WEB_GL;
|
|
@@ -192,6 +209,7 @@ export abstract class ARenderer implements ITempRenderer {
|
|
|
192
209
|
this._mainRenderTargetPipeline = this._framework
|
|
193
210
|
.renderPipelineFactory
|
|
194
211
|
.createMainFrameBufferPipeline(this._mainRenderTarget);
|
|
212
|
+
this._mainRenderTargetPipeline.colorSpace = this._colorSpace;
|
|
195
213
|
|
|
196
214
|
this._createMainRenderPass();
|
|
197
215
|
this._mainRenderTargetRequiresResize = false;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {CullMode, FrontFace, type IPrimitiveStateDescriptor, PrimitiveTopology} from "../../../api/index.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A primitive state descriptor with all defaults applied.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export type ResolvedPrimitiveStateDescriptor = Required<IPrimitiveStateDescriptor>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Fills in the defaults for every missing field of a primitive state descriptor:
|
|
11
|
+
* TRIANGLE_LIST topology, BACK culling and CCW front face.
|
|
12
|
+
* @param desc The descriptor, possibly partial or missing.
|
|
13
|
+
* @returns A new descriptor with the defaults applied.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function resolvePrimitiveStateDescriptor(desc?: IPrimitiveStateDescriptor): ResolvedPrimitiveStateDescriptor {
|
|
17
|
+
return {
|
|
18
|
+
topology: desc?.topology ?? PrimitiveTopology.TRIANGLE_LIST,
|
|
19
|
+
cullFace: desc?.cullFace ?? CullMode.BACK,
|
|
20
|
+
frontFace: desc?.frontFace ?? FrontFace.CCW,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {type ITextureDescriptor, TextureFormat, TextureUsage} from "../../../api/index.ts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* A texture descriptor with all defaults applied. Only `data` and `
|
|
4
|
+
* A texture descriptor with all defaults applied. Only `data`, `blockSize` and `preferredColorSpace` stay optional.
|
|
5
5
|
* @internal
|
|
6
6
|
*/
|
|
7
7
|
export type ResolvedTextureDescriptor =
|
|
8
|
-
Required<Omit<ITextureDescriptor, "data" | "blockSize">> & Pick<ITextureDescriptor, "data" | "blockSize">;
|
|
8
|
+
Required<Omit<ITextureDescriptor, "data" | "blockSize" | "preferredColorSpace">> & Pick<ITextureDescriptor, "data" | "blockSize" | "preferredColorSpace">;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Fills in the defaults for every missing field of a texture descriptor.
|
|
@@ -23,5 +23,6 @@ export function resolveTextureDescriptor(desc?: ITextureDescriptor): ResolvedTex
|
|
|
23
23
|
data: desc?.data,
|
|
24
24
|
generateMipmaps: desc?.generateMipmaps ?? false,
|
|
25
25
|
blockSize: desc?.blockSize,
|
|
26
|
+
preferredColorSpace: desc?.preferredColorSpace,
|
|
26
27
|
};
|
|
27
28
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type ISampler,
|
|
16
16
|
type ISwapChain,
|
|
17
17
|
type IWindowManager,
|
|
18
|
-
|
|
18
|
+
type IPrimitiveStateDescriptor,
|
|
19
19
|
RenderPassDescriptor,
|
|
20
20
|
SwapChainDescriptor
|
|
21
21
|
} from "../api/index.ts";
|
|
@@ -125,8 +125,7 @@ export class WebGlGraphicsDevice extends AGraphicsDevice {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/** @inheritdoc */
|
|
128
|
-
public createPrimitiveState(descriptor?:
|
|
129
|
-
descriptor = descriptor ?? new PrimitiveStateDescriptor();
|
|
128
|
+
public createPrimitiveState(descriptor?: IPrimitiveStateDescriptor): IPrimitiveState {
|
|
130
129
|
return new WebGlPrimitiveState(this._gl, descriptor);
|
|
131
130
|
}
|
|
132
131
|
}
|
|
@@ -11,6 +11,9 @@ import {
|
|
|
11
11
|
type LightsBufferDescriptor,
|
|
12
12
|
DEFAULT_DIRECTIONAL_LIGHTS_COUNT,
|
|
13
13
|
} from "../../api/index.ts";
|
|
14
|
+
import {vec3} from "gl-matrix";
|
|
15
|
+
|
|
16
|
+
const _v = vec3.create();
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* The WebGL lights buffer. Owns a std140 uniform buffer for the `LightsBuffer` block.
|
|
@@ -191,10 +194,15 @@ export class WebGlLightsBuffer implements LightsBuffer {
|
|
|
191
194
|
this._writeColor(offset, light?.color, light?.intensity ?? 0);
|
|
192
195
|
this._data[offset + 3] = 0;
|
|
193
196
|
|
|
194
|
-
// vec3 direction
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
197
|
+
// vec3 direction (world space, from the transform)
|
|
198
|
+
if (light) {
|
|
199
|
+
light.getDirection(_v);
|
|
200
|
+
} else {
|
|
201
|
+
vec3.zero(_v);
|
|
202
|
+
}
|
|
203
|
+
this._data[offset + 4] = _v[0];
|
|
204
|
+
this._data[offset + 5] = _v[1];
|
|
205
|
+
this._data[offset + 6] = _v[2];
|
|
198
206
|
this._data[offset + 7] = 0;
|
|
199
207
|
}
|
|
200
208
|
|
|
@@ -209,10 +217,15 @@ export class WebGlLightsBuffer implements LightsBuffer {
|
|
|
209
217
|
// An empty slot keeps constant at 1 so the shader never divides by zero.
|
|
210
218
|
this._data[offset + 3] = light ? light.constant : 1;
|
|
211
219
|
|
|
212
|
-
// vec3 position, float linear
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
220
|
+
// vec3 position (world space, from the transform), float linear
|
|
221
|
+
if (light) {
|
|
222
|
+
light.getPosition(_v);
|
|
223
|
+
} else {
|
|
224
|
+
vec3.zero(_v);
|
|
225
|
+
}
|
|
226
|
+
this._data[offset + 4] = _v[0];
|
|
227
|
+
this._data[offset + 5] = _v[1];
|
|
228
|
+
this._data[offset + 6] = _v[2];
|
|
216
229
|
this._data[offset + 7] = light ? light.linear : 0;
|
|
217
230
|
|
|
218
231
|
// float quadratic, then padding to the 16-byte struct size
|
|
@@ -2,9 +2,10 @@ import {
|
|
|
2
2
|
CullMode,
|
|
3
3
|
type FrontFace,
|
|
4
4
|
type IPrimitiveState,
|
|
5
|
-
type
|
|
5
|
+
type IPrimitiveStateDescriptor,
|
|
6
6
|
type PrimitiveTopology
|
|
7
7
|
} from "../../api/index.ts";
|
|
8
|
+
import {resolvePrimitiveStateDescriptor} from "../../core/rendering/primitive/PrimitiveStateDescriptorUtilities.ts";
|
|
8
9
|
import { WebGlConverter } from "../utilities/WebGlConverter.ts";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -19,12 +20,13 @@ export class WebGlPrimitiveState implements IPrimitiveState {
|
|
|
19
20
|
/**
|
|
20
21
|
* The constructor.
|
|
21
22
|
* @param _gl The WebGL2 Rendering Context.
|
|
22
|
-
* @param descriptor The descriptor of the primitive state.
|
|
23
|
+
* @param descriptor The descriptor of the primitive state; missing fields use the defaults.
|
|
23
24
|
*/
|
|
24
|
-
public constructor(_gl: WebGL2RenderingContext, descriptor
|
|
25
|
-
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
25
|
+
public constructor(_gl: WebGL2RenderingContext, descriptor?: IPrimitiveStateDescriptor) {
|
|
26
|
+
const resolved = resolvePrimitiveStateDescriptor(descriptor);
|
|
27
|
+
this.topology = resolved.topology;
|
|
28
|
+
this.cullFace = resolved.cullFace;
|
|
29
|
+
this.frontFace = resolved.frontFace;
|
|
28
30
|
|
|
29
31
|
this._cullingEnabled = this.cullFace != CullMode.NONE;
|
|
30
32
|
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type ITexture2D,
|
|
14
14
|
TextureFormat
|
|
15
15
|
} from "../../api/index.ts";
|
|
16
|
+
import {ColorSpace} from "../../api/rendering/enums.ts";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* The WebGL implementation of the main render target render pipeline.
|
|
@@ -24,6 +25,7 @@ export class WebGlMainRenderTargetRenderPipeline extends AWebGlRenderPipeline im
|
|
|
24
25
|
private _mainRenderTarget: WebGlTexture2D = null!;
|
|
25
26
|
|
|
26
27
|
private _colorConversionUniformLocation: WebGLUniformLocation = null!;
|
|
28
|
+
/** The shader's `u_colorConversion`: 1 encodes linear to sRGB on output, 0 passes through. */
|
|
27
29
|
private _colorSpaceValue = 0;
|
|
28
30
|
|
|
29
31
|
/**
|
|
@@ -40,6 +42,18 @@ export class WebGlMainRenderTargetRenderPipeline extends AWebGlRenderPipeline im
|
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The color space. With SRGB the main render target is sRGB (sampled back as linear) and the shader
|
|
47
|
+
* encodes to sRGB for the screen; with LINEAR the values are passed through. Takes effect on the next frame.
|
|
48
|
+
*/
|
|
49
|
+
public get colorSpace(): ColorSpace {
|
|
50
|
+
return this._colorSpaceValue == 1 ? ColorSpace.SRGB : ColorSpace.LINEAR;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public set colorSpace(value: ColorSpace) {
|
|
54
|
+
this._colorSpaceValue = value == ColorSpace.SRGB ? 1 : 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
43
57
|
/** @inheritDoc */
|
|
44
58
|
public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2;
|
|
45
59
|
|