diff --git a/types/three/OTHER_FILES.txt b/types/three/OTHER_FILES.txt index a1280323a..ca5bcb321 100644 --- a/types/three/OTHER_FILES.txt +++ b/types/three/OTHER_FILES.txt @@ -14,7 +14,6 @@ examples/jsm/effects/AsciiEffect.d.ts examples/jsm/effects/ParallaxBarrierEffect.d.ts examples/jsm/effects/PeppersGhostEffect.d.ts examples/jsm/effects/StereoEffect.d.ts -examples/jsm/environments/RoomEnvironment.d.ts examples/jsm/exporters/ColladaExporter.d.ts examples/jsm/exporters/DRACOExporter.d.ts examples/jsm/exporters/GLTFExporter.d.ts @@ -52,7 +51,6 @@ examples/jsm/loaders/FBXLoader.d.ts examples/jsm/loaders/GCodeLoader.d.ts examples/jsm/loaders/KMZLoader.d.ts examples/jsm/loaders/KTXLoader.d.ts -examples/jsm/loaders/LDrawLoader.d.ts examples/jsm/loaders/LogLuvLoader.d.ts examples/jsm/loaders/LottieLoader.d.ts examples/jsm/loaders/LUT3dlLoader.d.ts @@ -258,7 +256,6 @@ examples/jsm/shaders/VolumeShader.d.ts examples/jsm/shaders/WaterRefractionShader.d.ts examples/jsm/utils/BufferGeometryUtils.d.ts examples/jsm/utils/GeometryCompressionUtils.d.ts -examples/jsm/utils/RoughnessMipmapper.d.ts examples/jsm/utils/SceneUtils.d.ts examples/jsm/utils/ShadowMapViewer.d.ts examples/jsm/utils/SkeletonUtils.d.ts diff --git a/types/three/examples/jsm/geometries/ConvexGeometry.d.ts b/types/three/examples/jsm/geometries/ConvexGeometry.d.ts index caceab451..95e84d403 100644 --- a/types/three/examples/jsm/geometries/ConvexGeometry.d.ts +++ b/types/three/examples/jsm/geometries/ConvexGeometry.d.ts @@ -1,5 +1,5 @@ import { BufferGeometry, Vector3 } from '../../../src/Three'; export class ConvexGeometry extends BufferGeometry { - constructor(points: Vector3[]); + constructor(points?: Vector3[]); } diff --git a/types/three/examples/jsm/loaders/LDrawLoader.d.ts b/types/three/examples/jsm/loaders/LDrawLoader.d.ts index 38bca60be..ef13f035f 100644 --- a/types/three/examples/jsm/loaders/LDrawLoader.d.ts +++ b/types/three/examples/jsm/loaders/LDrawLoader.d.ts @@ -1,6 +1,11 @@ import { Loader, LoadingManager, Group, Material } from '../../../src/Three'; export class LDrawLoader extends Loader { + materials: Material[]; + materialsLibrary: Record; + fileMap: Record; + smoothNormals: boolean; + constructor(manager?: LoadingManager); load( @@ -10,6 +15,7 @@ export class LDrawLoader extends Loader { onError?: (event: ErrorEvent) => void, ): void; loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise; + preloadMaterials(url: string): Promise; setFileMap(fileMap: Record): void; setMaterials(materials: Material[]): void; diff --git a/types/three/examples/jsm/nodes/utils/ColorSpaceNode.d.ts b/types/three/examples/jsm/nodes/utils/ColorSpaceNode.d.ts index d7e77065c..97f86c978 100644 --- a/types/three/examples/jsm/nodes/utils/ColorSpaceNode.d.ts +++ b/types/three/examples/jsm/nodes/utils/ColorSpaceNode.d.ts @@ -10,7 +10,7 @@ export class ColorSpaceNode extends TempNode { nodeType: string; fromEncoding(encoding: number): void; - fromDecoding(encoding: number): void; + fromDecoding(): void; copy(source: ColorSpaceNode): this; static Nodes: { diff --git a/types/three/examples/jsm/utils/LDrawUtils.d.ts b/types/three/examples/jsm/utils/LDrawUtils.d.ts new file mode 100644 index 000000000..688b16b33 --- /dev/null +++ b/types/three/examples/jsm/utils/LDrawUtils.d.ts @@ -0,0 +1,5 @@ +import { Group, Object3D } from '../../../src/Three'; + +export namespace LDrawUtils { + function mergeObject(object: Object3D): Group; +} diff --git a/types/three/examples/jsm/utils/RoughnessMipmapper.d.ts b/types/three/examples/jsm/utils/RoughnessMipmapper.d.ts deleted file mode 100644 index 83f785f70..000000000 --- a/types/three/examples/jsm/utils/RoughnessMipmapper.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { WebGLRenderer, MeshStandardMaterial } from '../../../src/Three'; - -export class RoughnessMipmapper { - constructor(renderer: WebGLRenderer); - generateMipmaps(material: MeshStandardMaterial): void; - dispose(): void; -} diff --git a/types/three/src/constants.d.ts b/types/three/src/constants.d.ts index f61031fe6..201a367d5 100644 --- a/types/three/src/constants.d.ts +++ b/types/three/src/constants.d.ts @@ -148,13 +148,11 @@ export const FloatType: TextureDataType; export const HalfFloatType: TextureDataType; export const UnsignedShort4444Type: TextureDataType; export const UnsignedShort5551Type: TextureDataType; -export const UnsignedShort565Type: TextureDataType; export const UnsignedInt248Type: TextureDataType; // Pixel formats export enum PixelFormat {} export const AlphaFormat: PixelFormat; -export const RGBFormat: PixelFormat; export const RGBAFormat: PixelFormat; export const LuminanceFormat: PixelFormat; export const LuminanceAlphaFormat: PixelFormat; @@ -164,8 +162,9 @@ export const RedFormat: PixelFormat; export const RedIntegerFormat: PixelFormat; export const RGFormat: PixelFormat; export const RGIntegerFormat: PixelFormat; -export const RGBIntegerFormat: PixelFormat; export const RGBAIntegerFormat: PixelFormat; +export const _SRGBFormat: PixelFormat; // fallback for WebGL 1 +export const _SRGBAFormat: PixelFormat; // fallback for WebGL 1 // Internal Pixel Formats export type PixelFormatGPU = @@ -224,6 +223,7 @@ export type PixelFormatGPU = | 'RGB10_A2' | 'RGB10_A2UI' | 'SRGB8_ALPHA8' + | 'SRGB8' | 'DEPTH_COMPONENT16' | 'DEPTH_COMPONENT24' | 'DEPTH_COMPONENT32F' @@ -264,20 +264,6 @@ export const RGBA_ASTC_10x8_Format: CompressedPixelFormat; export const RGBA_ASTC_10x10_Format: CompressedPixelFormat; export const RGBA_ASTC_12x10_Format: CompressedPixelFormat; export const RGBA_ASTC_12x12_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_4x4_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_5x4_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_5x5_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_6x5_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_6x6_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_8x5_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_8x6_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_8x8_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_10x5_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_10x6_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_10x8_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_10x10_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_12x10_Format: CompressedPixelFormat; -export const SRGB8_ALPHA8_ASTC_12x12_Format: CompressedPixelFormat; // BPTC compressed texture formats export const RGBA_BPTC_Format: CompressedPixelFormat; diff --git a/types/three/src/extras/ImageUtils.d.ts b/types/three/src/extras/ImageUtils.d.ts index c5c148733..0fdae1d43 100644 --- a/types/three/src/extras/ImageUtils.d.ts +++ b/types/three/src/extras/ImageUtils.d.ts @@ -28,4 +28,6 @@ export namespace ImageUtils { onLoad?: (texture: Texture) => void, onError?: (message: string) => void, ): Texture; + + function sRGBToLinear(image: any): HTMLCanvasElement | { data: number[]; width: number; height: number }; } diff --git a/types/three/src/extras/PMREMGenerator.d.ts b/types/three/src/extras/PMREMGenerator.d.ts index e5a5fbdc2..49a5a8822 100644 --- a/types/three/src/extras/PMREMGenerator.d.ts +++ b/types/three/src/extras/PMREMGenerator.d.ts @@ -7,8 +7,8 @@ import { Scene } from '../scenes/Scene'; export class PMREMGenerator { constructor(renderer: WebGLRenderer); fromScene(scene: Scene, sigma?: number, near?: number, far?: number): WebGLRenderTarget; - fromEquirectangular(equirectangular: Texture): WebGLRenderTarget; - fromCubemap(cubemap: CubeTexture): WebGLRenderTarget; + fromEquirectangular(equirectangular: Texture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; + fromCubemap(cubemap: CubeTexture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; compileCubemapShader(): void; compileEquirectangularShader(): void; dispose(): void; diff --git a/types/three/src/materials/Material.d.ts b/types/three/src/materials/Material.d.ts index 675d6ae23..c445f7dd3 100644 --- a/types/three/src/materials/Material.d.ts +++ b/types/three/src/materials/Material.d.ts @@ -80,6 +80,11 @@ export class Material extends EventDispatcher { */ alphaToCoverage: boolean; + /** + * @default false + */ + alphaWrite: boolean; + /** * Blending destination. It's one of the blending mode constants defined in Three.js. Default is {@link OneMinusSrcAlphaFactor}. * @default THREE.OneMinusSrcAlphaFactor @@ -181,12 +186,6 @@ export class Material extends EventDispatcher { */ fog: boolean; - /** - * When this property is set to THREE.RGBFormat, the material is considered to be opaque and alpha values are ignored. - * @default THREE.RGBAFormat - */ - format: PixelFormat; - /** * Unique number of this material instance. */ diff --git a/types/three/src/math/Box3.d.ts b/types/three/src/math/Box3.d.ts index 4788fcb05..3c001361e 100644 --- a/types/three/src/math/Box3.d.ts +++ b/types/three/src/math/Box3.d.ts @@ -25,7 +25,7 @@ export class Box3 { setFromBufferAttribute(bufferAttribute: BufferAttribute): this; setFromPoints(points: Vector3[]): this; setFromCenterAndSize(center: Vector3, size: Vector3): this; - setFromObject(object: Object3D): this; + setFromObject(object: Object3D, precise?: boolean): this; clone(): this; copy(box: Box3): this; makeEmpty(): this; @@ -35,7 +35,7 @@ export class Box3 { expandByPoint(point: Vector3): this; expandByVector(vector: Vector3): this; expandByScalar(scalar: number): this; - expandByObject(object: Object3D): this; + expandByObject(object: Object3D, precise?: boolean): this; containsPoint(point: Vector3): boolean; containsBox(box: Box3): boolean; getParameter(point: Vector3, target: Vector3): Vector3; diff --git a/types/three/src/math/Color.d.ts b/types/three/src/math/Color.d.ts index 7b21cad45..a283bb695 100644 --- a/types/three/src/math/Color.d.ts +++ b/types/three/src/math/Color.d.ts @@ -7,6 +7,8 @@ export interface HSL { l: number; } +export function SRGBToLinear(c: number): number; + /** * Represents a color. See also {@link ColorUtils}. * diff --git a/types/three/src/renderers/webgl/WebGLUtils.d.ts b/types/three/src/renderers/webgl/WebGLUtils.d.ts index b5b82db22..0d3aafd53 100644 --- a/types/three/src/renderers/webgl/WebGLUtils.d.ts +++ b/types/three/src/renderers/webgl/WebGLUtils.d.ts @@ -1,5 +1,7 @@ +import { CompressedPixelFormat, TextureEncoding } from '../../constants'; + export class WebGLUtils { constructor(gl: WebGLRenderingContext | WebGL2RenderingContext, extensions: any, capabilities: any); - convert(p: any): void; + convert(p: CompressedPixelFormat, encoding?: TextureEncoding | null): void; } diff --git a/types/three/src/textures/CubeTexture.d.ts b/types/three/src/textures/CubeTexture.d.ts index b271ae66e..75958c05e 100644 --- a/types/three/src/textures/CubeTexture.d.ts +++ b/types/three/src/textures/CubeTexture.d.ts @@ -9,7 +9,7 @@ export class CubeTexture extends Texture { * @param [wrapT=THREE.ClampToEdgeWrapping] * @param [magFilter=THREE.LinearFilter] * @param [minFilter=THREE.LinearMipmapLinearFilter] - * @param [format=THREE.RGBFormat] + * @param [format=THREE.RGBAFormat] * @param [type=THREE.UnsignedByteType] * @param [anisotropy=1] * @param [encoding=THREE.LinearEncoding] diff --git a/types/three/src/textures/VideoTexture.d.ts b/types/three/src/textures/VideoTexture.d.ts index c61b4c26b..75d2de329 100644 --- a/types/three/src/textures/VideoTexture.d.ts +++ b/types/three/src/textures/VideoTexture.d.ts @@ -9,7 +9,7 @@ export class VideoTexture extends Texture { * @param [wrapT=THREE.ClampToEdgeWrapping] * @param [magFilter=THREE.LinearFilter] * @param [minFilter=THREE.LinearFilter] - * @param [format=THREE.RGBFormat] + * @param [format=THREE.RGBAFormat] * @param [type=THREE.UnsignedByteType] * @param [anisotropy=1] */ diff --git a/types/three/test/loaders/loaders-gltfloader.ts b/types/three/test/loaders/loaders-gltfloader.ts new file mode 100644 index 000000000..d91c15f9f --- /dev/null +++ b/types/three/test/loaders/loaders-gltfloader.ts @@ -0,0 +1,72 @@ +import * as THREE from 'three'; + +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'; + +let camera: THREE.PerspectiveCamera; +let scene: THREE.Scene; +let renderer: THREE.WebGLRenderer; + +init(); +render(); + +function init() { + const container = document.createElement('div'); + document.body.appendChild(container); + + camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); + camera.position.set(-1.8, 0.6, 2.7); + + scene = new THREE.Scene(); + + new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', texture => { + texture.mapping = THREE.EquirectangularReflectionMapping; + + scene.background = texture; + scene.environment = texture; + + render(); + + // model + + const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); + loader.load('DamagedHelmet.gltf', gltf => { + scene.add(gltf.scene); + + render(); + }); + }); + + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.toneMappingExposure = 1; + renderer.outputEncoding = THREE.sRGBEncoding; + container.appendChild(renderer.domElement); + + const controls = new OrbitControls(camera, renderer.domElement); + controls.addEventListener('change', render); // use if there is no animation loop + controls.minDistance = 2; + controls.maxDistance = 10; + controls.target.set(0, 0, -0.2); + controls.update(); + + window.addEventListener('resize', onWindowResize); +} + +function onWindowResize() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize(window.innerWidth, window.innerHeight); + + render(); +} + +// + +function render() { + renderer.render(scene, camera); +} diff --git a/types/three/test/loaders/loaders-ldrawloader.ts b/types/three/test/loaders/loaders-ldrawloader.ts new file mode 100644 index 000000000..cb4a53aa7 --- /dev/null +++ b/types/three/test/loaders/loaders-ldrawloader.ts @@ -0,0 +1,175 @@ +import * as THREE from 'three'; + +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment'; + +import { LDrawLoader } from 'three/examples/jsm/loaders/LDrawLoader'; +import { LDrawUtils } from 'three/examples/jsm/utils/LDrawUtils'; + +let container: HTMLDivElement; +let progressBarDiv: HTMLDivElement; + +let camera: THREE.PerspectiveCamera; +let scene: THREE.Scene; +let renderer: THREE.WebGLRenderer; +let controls: OrbitControls; + +let model: THREE.Group | null; + +const ldrawPath = 'models/ldraw/officialLibrary/'; + +const modelFileList = { + Car: 'models/car.ldr_Packed.mpd', + 'Lunar Vehicle': 'models/1621-1-LunarMPVVehicle.mpd_Packed.mpd', + 'Radar Truck': 'models/889-1-RadarTruck.mpd_Packed.mpd', + Trailer: 'models/4838-1-MiniVehicles.mpd_Packed.mpd', + Bulldozer: 'models/4915-1-MiniConstruction.mpd_Packed.mpd', + Helicopter: 'models/4918-1-MiniFlyers.mpd_Packed.mpd', + Plane: 'models/5935-1-IslandHopper.mpd_Packed.mpd', + Lighthouse: 'models/30023-1-Lighthouse.ldr_Packed.mpd', + 'X-Wing mini': 'models/30051-1-X-wingFighter-Mini.mpd_Packed.mpd', + 'AT-ST mini': 'models/30054-1-AT-ST-Mini.mpd_Packed.mpd', + 'AT-AT mini': 'models/4489-1-AT-AT-Mini.mpd_Packed.mpd', + Shuttle: 'models/4494-1-Imperial Shuttle-Mini.mpd_Packed.mpd', + 'TIE Interceptor': 'models/6965-1-TIEIntercep_4h4MXk5.mpd_Packed.mpd', + 'Star fighter': 'models/6966-1-JediStarfighter-Mini.mpd_Packed.mpd', + 'X-Wing': 'models/7140-1-X-wingFighter.mpd_Packed.mpd', + 'AT-ST': 'models/10174-1-ImperialAT-ST-UCS.mpd_Packed.mpd', +}; + +init(); +animate(); + +function init() { + container = document.createElement('div'); + document.body.appendChild(container); + + camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); + camera.position.set(150, 200, 250); + + // + + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.toneMapping = THREE.ACESFilmicToneMapping; + container.appendChild(renderer.domElement); + + // scene + + const pmremGenerator = new THREE.PMREMGenerator(renderer); + + scene = new THREE.Scene(); + scene.background = new THREE.Color(0xdeebed); + scene.environment = pmremGenerator.fromScene(new RoomEnvironment()).texture; + + controls = new OrbitControls(camera, renderer.domElement); + + // + + window.addEventListener('resize', onWindowResize); + + progressBarDiv = document.createElement('div'); + progressBarDiv.innerText = 'Loading...'; + progressBarDiv.style.fontSize = '3em'; + progressBarDiv.style.color = '#888'; + progressBarDiv.style.display = 'block'; + progressBarDiv.style.position = 'absolute'; + progressBarDiv.style.top = '50%'; + progressBarDiv.style.width = '100%'; + progressBarDiv.style.textAlign = 'center'; + + // load materials and then the model + + reloadObject(true); +} + +function reloadObject(resetCamera: boolean) { + if (model) { + scene.remove(model); + } + + model = null; + + updateProgressBar(0); + showProgressBar(); + + // only smooth when not rendering with flat colors to improve processing time + const lDrawLoader = new LDrawLoader(); + lDrawLoader.setPath(ldrawPath).load( + '', + group2 => { + if (model) { + scene.remove(model); + } + + model = group2; + + // Convert from LDraw coordinates: rotate 180 degrees around OX + model.rotation.x = Math.PI; + + scene.add(model); + + // Adjust camera and light + + const bbox = new THREE.Box3().setFromObject(model); + const size = bbox.getSize(new THREE.Vector3()); + const radius = Math.max(size.x, Math.max(size.y, size.z)) * 0.5; + + if (resetCamera) { + controls.target0.copy(bbox.getCenter(new THREE.Vector3())); + controls.position0.set(-2.3, 1, 2).multiplyScalar(radius).add(controls.target0); + controls.reset(); + } + + hideProgressBar(); + }, + onProgress, + onError, + ); +} + +function onWindowResize() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize(window.innerWidth, window.innerHeight); +} + +// + +function animate() { + requestAnimationFrame(animate); + render(); +} + +function render() { + renderer.render(scene, camera); +} + +function onProgress(xhr: ProgressEvent) { + if (xhr.lengthComputable) { + updateProgressBar(xhr.loaded / xhr.total); + + console.log(`${Math.round((xhr.loaded / xhr.total) * 100)}% downloaded`); + } +} + +function onError(error: unknown) { + const message = 'Error loading model'; + progressBarDiv.innerText = message; + console.log(message); + console.error(error); +} + +function showProgressBar() { + document.body.appendChild(progressBarDiv); +} + +function hideProgressBar() { + document.body.removeChild(progressBarDiv); +} + +function updateProgressBar(fraction: number) { + progressBarDiv.innerText = `Loading... ${Math.round(fraction * 100)}%`; +} diff --git a/types/three/test/utils/utils-webgl-portal.ts b/types/three/test/utils/utils-webgl-portal.ts index b0c60562d..dbeef1baa 100644 --- a/types/three/test/utils/utils-webgl-portal.ts +++ b/types/three/test/utils/utils-webgl-portal.ts @@ -78,7 +78,7 @@ function init() { leftPortalTexture = new THREE.WebGLRenderTarget(256, 256, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, - format: THREE.RGBFormat, + format: THREE.RGBAFormat, }); leftPortal = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({ map: leftPortalTexture.texture })); leftPortal.position.x = -30; @@ -89,7 +89,7 @@ function init() { rightPortalTexture = new THREE.WebGLRenderTarget(256, 256, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, - format: THREE.RGBFormat, + format: THREE.RGBAFormat, }); rightPortal = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({ map: rightPortalTexture.texture })); rightPortal.position.x = 30; diff --git a/types/three/tsconfig.json b/types/three/tsconfig.json index 26d75f449..b1bb4d392 100644 --- a/types/three/tsconfig.json +++ b/types/three/tsconfig.json @@ -35,10 +35,12 @@ "test/lines/lines-line2.ts", "test/loaders/loaders-gltfloader-extensions.ts", "test/loaders/loaders-gltfloader-plugin.ts", + "test/loaders/loaders-gltfloader.ts", "test/loaders/loaders-svgloader.ts", "test/loaders/loaders-tgaloader.ts", "test/loaders/loaders-mmdanimation.ts", "test/loaders/loaders-ifc.ts", + "test/loaders/loaders-ldrawloader.ts", "test/loaders/loaders-voxloader.ts", "test/loaders/loaders-obj-mtl.ts", "test/modifiers/modifiers-tessellation.ts",