diff --git a/src/_polyfill/uv1.ts b/src/_polyfill/uv1.ts new file mode 100644 index 0000000..ffb3949 --- /dev/null +++ b/src/_polyfill/uv1.ts @@ -0,0 +1,7 @@ +import { version } from "./constants"; + +/** uv2 renamed to uv1 in r125 + * + * https://github.com/mrdoob/three.js/pull/25943 +*/ +export const UV1 = version >= 125 ? 'uv1' : 'uv2' \ No newline at end of file diff --git a/src/exporters/ColladaExporter.ts b/src/exporters/ColladaExporter.ts index 17eee1e..549e557 100644 --- a/src/exporters/ColladaExporter.ts +++ b/src/exporters/ColladaExporter.ts @@ -14,6 +14,7 @@ import { Texture, } from 'three' import type { TypedArray, TypedArrayConstructors } from '../types/shared' +import { UV1 } from '../_polyfill/uv1' /** * https://github.com/gkjohnson/collada-exporter-js @@ -346,9 +347,9 @@ class ColladaExporter { } // serialize lightmap uvs - if ('uv1' in bufferGeometry.attributes) { + if (UV1 in bufferGeometry.attributes) { const uvName = `${meshid}-texcoord2` - gnode += this.getAttribute(bufferGeometry.attributes.uv1, uvName, ['S', 'T'], 'float') + gnode += this.getAttribute(bufferGeometry.attributes[UV1], uvName, ['S', 'T'], 'float') triangleInputs += `` } diff --git a/src/lines/LineSegments2.js b/src/lines/LineSegments2.js index 25354c9..370ce7e 100644 --- a/src/lines/LineSegments2.js +++ b/src/lines/LineSegments2.js @@ -12,6 +12,7 @@ import { } from 'three' import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry' import { LineMaterial } from '../lines/LineMaterial' +import { UV1 } from '../_polyfill/uv1' const _start = new Vector3() const _end = new Vector3() @@ -67,7 +68,7 @@ function raycastWorldUnits(lineSegments, intersects) { face: null, faceIndex: i, uv: null, - uv1: null, + [UV1]: null, }) } } @@ -187,7 +188,7 @@ function raycastScreenSpace(lineSegments, camera, intersects) { face: null, faceIndex: i, uv: null, - uv1: null, + [UV1]: null, }) } } diff --git a/src/loaders/ColladaLoader.js b/src/loaders/ColladaLoader.js index d7c1692..f79af8c 100644 --- a/src/loaders/ColladaLoader.js +++ b/src/loaders/ColladaLoader.js @@ -39,6 +39,7 @@ import { VectorKeyframeTrack, } from 'three' import { TGALoader } from '../loaders/TGALoader' +import { UV1 } from '../_polyfill/uv1' class ColladaLoader extends Loader { constructor(manager) { @@ -2025,7 +2026,7 @@ class ColladaLoader extends Loader { } if (color.array.length > 0) geometry.setAttribute('color', new Float32BufferAttribute(color.array, color.stride)) if (uv.array.length > 0) geometry.setAttribute('uv', new Float32BufferAttribute(uv.array, uv.stride)) - if (uv1.array.length > 0) geometry.setAttribute('uv1', new Float32BufferAttribute(uv1.array, uv1.stride)) + if (uv1.array.length > 0) geometry.setAttribute(UV1, new Float32BufferAttribute(uv1.array, uv1.stride)) if (skinIndex.array.length > 0) { geometry.setAttribute('skinIndex', new Float32BufferAttribute(skinIndex.array, skinIndex.stride)) diff --git a/src/loaders/FBXLoader.js b/src/loaders/FBXLoader.js index 0cdfda6..e171ec8 100644 --- a/src/loaders/FBXLoader.js +++ b/src/loaders/FBXLoader.js @@ -43,6 +43,7 @@ import { import { unzlibSync } from 'fflate' import { NURBSCurve } from '../curves/NURBSCurve' import { decodeText } from '../_polyfill/LoaderUtils' +import { UV1 } from '../_polyfill/uv1' /** * Loader loads FBX file and generates Group representing FBX scene. @@ -1274,6 +1275,7 @@ class GeometryParser { } buffers.uvs.forEach(function (uvBuffer, i) { + if (UV1 === 'uv2') i++; const name = i === 0 ? 'uv' : `uv${i}`; geo.setAttribute(name, new Float32BufferAttribute(buffers.uvs[i], 2)) diff --git a/src/loaders/LWOLoader.js b/src/loaders/LWOLoader.js index cfd2ed8..6ec856d 100644 --- a/src/loaders/LWOLoader.js +++ b/src/loaders/LWOLoader.js @@ -40,6 +40,7 @@ import { } from 'three' import { IFFParser } from './lwo/IFFParser.js' +import { UV1 } from '../_polyfill/uv1.ts' let _lwoTree @@ -148,6 +149,8 @@ class LWOTreeParser { const materials = this.getMaterials(geometry.userData.matNames, layer.geometry.type) + if (UV1 === 'uv2') this.duplicateUVs(geometry, materials) + if (layer.geometry.type === 'points') mesh = new Points(geometry, materials) else if (layer.geometry.type === 'lines') mesh = new LineSegments(geometry, materials) else mesh = new Mesh(geometry, materials) @@ -220,6 +223,23 @@ class LWOTreeParser { return m.name === name })[0] } + + // If the material has an aoMap, duplicate UVs + duplicateUVs(geometry, materials) { + let duplicateUVs = false + + if (!Array.isArray(materials)) { + if (materials.aoMap) duplicateUVs = true + } else { + materials.forEach(function (material) { + if (material.aoMap) duplicateUVs = true + }) + } + + if (!duplicateUVs) return + + geometry.setAttribute('uv2', new BufferAttribute(geometry.attributes.uv.array, 2)) + } } class MaterialParser { diff --git a/src/misc/ProgressiveLightmap.js b/src/misc/ProgressiveLightmap.js index 986355b..b117170 100644 --- a/src/misc/ProgressiveLightmap.js +++ b/src/misc/ProgressiveLightmap.js @@ -9,6 +9,7 @@ import { Mesh, } from 'three' import potpack from 'potpack' +import { UV1 } from '../_polyfill/uv1' /** * Progressive Light Map Accumulator, by [zalo](https://github.com/zalo/) @@ -52,16 +53,16 @@ class ProgressiveLightMap { shader.vertexShader = '#define USE_LIGHTMAP\n' + shader.vertexShader.slice(0, -1) + - ' gl_Position = vec4((uv1 - 0.5) * 2.0, 1.0, 1.0); }' + ` gl_Position = vec4((${UV1} - 0.5) * 2.0, 1.0, 1.0); }` // Fragment Shader: Set Pixels to average in the Previous frame's Shadows const bodyStart = shader.fragmentShader.indexOf('void main() {') shader.fragmentShader = - 'varying vec2 vuv1;\n' + + `varying vec2 v${UV1 === 'uv1' ? UV1 : 'Uv2'};\n` + shader.fragmentShader.slice(0, bodyStart) + ' uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n' + shader.fragmentShader.slice(bodyStart - 1, -1) + - `\nvec3 texelOld = texture2D(previousShadowMap, vuv1).rgb; + `\nvec3 texelOld = texture2D(previousShadowMap, v${UV1 === 'uv1' ? UV1 : 'Uv2'}).rgb; gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow); }` @@ -130,8 +131,8 @@ class ProgressiveLightMap { uv1.array[i + 1] = (uv1.array[i + 1] + box.y + padding) / dimensions.h } - objects[box.index].geometry.setAttribute('uv1', uv1) - objects[box.index].geometry.getAttribute('uv1').needsUpdate = true + objects[box.index].geometry.setAttribute(UV1, uv1) + objects[box.index].geometry.getAttribute(UV1).needsUpdate = true }) } diff --git a/src/modifiers/TessellateModifier.ts b/src/modifiers/TessellateModifier.ts index 7218623..05d240d 100644 --- a/src/modifiers/TessellateModifier.ts +++ b/src/modifiers/TessellateModifier.ts @@ -1,4 +1,5 @@ import { BufferGeometry, Color, Float32BufferAttribute, Vector2, Vector3 } from 'three' +import { UV1 } from '../_polyfill/uv1' /** * Break faces with edges longer than maxEdgeLength @@ -57,7 +58,7 @@ class TessellateModifier { const hasNormals = attributes.normal !== undefined const hasColors = attributes.color !== undefined const hasUVs = attributes.uv !== undefined - const hasUV1s = attributes.uv1 !== undefined + const hasUV1s = attributes[UV1] !== undefined let positions = attributes.position.array let normals = hasNormals ? attributes.normal.array : null @@ -238,7 +239,7 @@ class TessellateModifier { } if (hasUV1s) { - geometry2.setAttribute('uv1', new Float32BufferAttribute(uv1s2 as any, 2)) + geometry2.setAttribute(UV1, new Float32BufferAttribute(uv1s2 as any, 2)) } return geometry2