@needle-tools/engine 4.6.2 → 4.7.0-next.2756168
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/dist/needle-engine.bundle-C2wJAuPf.min.js +1604 -0
- package/dist/{needle-engine.bundle-DGcStTA7.js → needle-engine.bundle-S0N_qbSh.js} +8713 -8443
- package/dist/{needle-engine.bundle-DmYMLdWP.umd.cjs → needle-engine.bundle-lLDHlwZU.umd.cjs} +213 -184
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/engine_context.js +3 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.d.ts +5 -3
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +124 -117
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/NodeMaterialConverter.d.ts +10 -0
- package/lib/engine-components/export/usdz/extensions/NodeMaterialConverter.js +452 -0
- package/lib/engine-components/export/usdz/extensions/NodeMaterialConverter.js.map +1 -0
- package/lib/engine-components/postprocessing/Effects/BloomEffect.js +0 -3
- package/lib/engine-components/postprocessing/Effects/BloomEffect.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +43 -11
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/postprocessing/utils.d.ts +1 -0
- package/lib/engine-components/postprocessing/utils.js.map +1 -1
- package/package.json +2 -2
- package/plugins/vite/alias.js +48 -38
- package/src/engine/engine_context.ts +3 -2
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +155 -142
- package/src/engine-components/export/usdz/extensions/NodeMaterialConverter.ts +532 -0
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +0 -2
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +50 -12
- package/src/engine-components/postprocessing/utils.ts +1 -0
- package/dist/needle-engine.bundle-D0XWaCQs.min.js +0 -1575
|
@@ -32,7 +32,8 @@ import {
|
|
|
32
32
|
Vector3,
|
|
33
33
|
Vector4,
|
|
34
34
|
WebGLRenderer,
|
|
35
|
-
WebGLRenderTarget
|
|
35
|
+
WebGLRenderTarget
|
|
36
|
+
} from 'three';
|
|
36
37
|
import * as fflate from 'three/examples/jsm/libs/fflate.module.js';
|
|
37
38
|
|
|
38
39
|
import { VERSION } from "../../../engine/engine_constants.js";
|
|
@@ -42,6 +43,9 @@ import { BehaviorExtension } from '../../api.js';
|
|
|
42
43
|
import type { IUSDExporterExtension } from './Extension.js';
|
|
43
44
|
import type { AnimationExtension } from './extensions/Animation.js';
|
|
44
45
|
import type { PhysicsExtension } from './extensions/behavior/PhysicsExtension.js';
|
|
46
|
+
import {buildNodeMaterial} from './extensions/NodeMaterialConverter.js';
|
|
47
|
+
|
|
48
|
+
type MeshPhysicalNodeMaterial = import("three/src/materials/nodes/MeshPhysicalNodeMaterial.js").default;
|
|
45
49
|
|
|
46
50
|
function makeNameSafe( str ) {
|
|
47
51
|
// Remove characters that are not allowed in USD ASCII identifiers
|
|
@@ -148,7 +152,7 @@ class USDObject {
|
|
|
148
152
|
get isDynamic() { return this._isDynamic; }
|
|
149
153
|
private set isDynamic( value ) { this._isDynamic = value; }
|
|
150
154
|
geometry: BufferGeometry | null;
|
|
151
|
-
material: MeshStandardMaterial | MeshBasicMaterial | Material | null;
|
|
155
|
+
material: MeshStandardMaterial | MeshBasicMaterial | Material | MeshPhysicalNodeMaterial | null;
|
|
152
156
|
camera: PerspectiveCamera | OrthographicCamera | null;
|
|
153
157
|
parent: USDObject | null;
|
|
154
158
|
skinnedMesh: SkinnedMesh | null;
|
|
@@ -180,7 +184,7 @@ class USDObject {
|
|
|
180
184
|
return empty;
|
|
181
185
|
}
|
|
182
186
|
|
|
183
|
-
constructor( id, name, transform: USDObjectTransform | null = null, mesh: BufferGeometry | null = null, material: MeshStandardMaterial | MeshBasicMaterial | Material | null = null, camera: PerspectiveCamera | OrthographicCamera | null = null, skinnedMesh: SkinnedMesh | null = null, animations: AnimationClip[] | null = null ) {
|
|
187
|
+
constructor( id, name, transform: USDObjectTransform | null = null, mesh: BufferGeometry | null = null, material: MeshStandardMaterial | MeshBasicMaterial | MeshPhysicalNodeMaterial | Material | null = null, camera: PerspectiveCamera | OrthographicCamera | null = null, skinnedMesh: SkinnedMesh | null = null, animations: AnimationClip[] | null = null ) {
|
|
184
188
|
|
|
185
189
|
this.uuid = id;
|
|
186
190
|
this.name = makeNameSafe( name );
|
|
@@ -847,14 +851,16 @@ function traverse( object: Object3D, parentModel: USDObject, context: USDZExport
|
|
|
847
851
|
}
|
|
848
852
|
|
|
849
853
|
if ( (object instanceof Mesh || object instanceof SkinnedMesh) &&
|
|
850
|
-
material &&
|
|
854
|
+
material && typeof material === 'object' &&
|
|
851
855
|
(material instanceof MeshStandardMaterial ||
|
|
852
|
-
material instanceof MeshBasicMaterial ||
|
|
856
|
+
material instanceof MeshBasicMaterial ||
|
|
857
|
+
// material instanceof MeshPhysicalNodeMaterial ||
|
|
858
|
+
(material as any).isMeshPhysicalNodeMaterial ||
|
|
853
859
|
(material instanceof Material && material.type === "MeshLineMaterial"))) {
|
|
854
860
|
|
|
855
861
|
const name = getObjectId( object );
|
|
856
862
|
const skinnedMeshObject = object instanceof SkinnedMesh ? object : null;
|
|
857
|
-
model = new USDObject( object.uuid, name, transform, geometry, material, undefined, skinnedMeshObject, object.animations );
|
|
863
|
+
model = new USDObject( object.uuid, name, transform, geometry, material as any, undefined, skinnedMeshObject, object.animations );
|
|
858
864
|
|
|
859
865
|
} else if ( object instanceof PerspectiveCamera || object instanceof OrthographicCamera ) {
|
|
860
866
|
|
|
@@ -1966,6 +1972,137 @@ ${array.join( '' )}
|
|
|
1966
1972
|
/** Slot of the exported texture. Some slots (e.g. normal, opacity) require additional processing. */
|
|
1967
1973
|
declare type MapType = 'diffuse' | 'normal' | 'occlusion' | 'opacity' | 'roughness' | 'emissive' | 'metallic' | 'transmission';
|
|
1968
1974
|
|
|
1975
|
+
function texName(tex: Texture) {
|
|
1976
|
+
// If we have a source, we only want to use the source's id, not the texture's id
|
|
1977
|
+
// to avoid exporting the same underlying data multiple times.
|
|
1978
|
+
return makeNameSafe(tex.name) + '_' + (tex.source?.id ?? tex.id);
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
function buildTexture( texture: Texture, mapType: MapType, quickLookCompatible: boolean, textures: TextureMap, material, usedUVChannels, color: Color | undefined = undefined, opacity: number | undefined = undefined ) {
|
|
1982
|
+
|
|
1983
|
+
const name = texName(texture);
|
|
1984
|
+
// File names need to be unique; so when we're baking color and/or opacity into a texture we need to keep track of that.
|
|
1985
|
+
// TODO This currently results in textures potentially being exported multiple times that are actually identical!
|
|
1986
|
+
// const colorHex = color ? color.getHexString() : undefined;
|
|
1987
|
+
// const colorId = ( color && colorHex != 'ffffff' ? '_' + color.getHexString() : '' );
|
|
1988
|
+
const id = name + ( opacity !== undefined && opacity !== 1.0 ? '_' + opacity : '' );
|
|
1989
|
+
|
|
1990
|
+
// Seems neither QuickLook nor usdview support scale/bias on .a values, so we need to bake opacity multipliers into
|
|
1991
|
+
// the texture. This is not ideal.
|
|
1992
|
+
const opacityIsAppliedToTextureAndNotAsScale = quickLookCompatible && opacity !== undefined && opacity !== 1.0;
|
|
1993
|
+
const scaleToApply = opacityIsAppliedToTextureAndNotAsScale ? new Vector4(1, 1, 1, opacity) : undefined;
|
|
1994
|
+
|
|
1995
|
+
// Treat undefined opacity as 1
|
|
1996
|
+
if (opacity === undefined)
|
|
1997
|
+
opacity = 1.0;
|
|
1998
|
+
|
|
1999
|
+
// When we're baking opacity into the texture, we shouldn't apply it as scale as well – so we set it to 1.
|
|
2000
|
+
if (opacityIsAppliedToTextureAndNotAsScale)
|
|
2001
|
+
opacity = 1.0;
|
|
2002
|
+
|
|
2003
|
+
// sanitize scaleToApply.w === 0 - this isn't working right now, seems the PNG can't be read back properly.
|
|
2004
|
+
if (scaleToApply && scaleToApply.w <= 0.05) scaleToApply.w = 0.05;
|
|
2005
|
+
|
|
2006
|
+
textures[ id ] = { texture, scale: scaleToApply };
|
|
2007
|
+
|
|
2008
|
+
const uv = texture.channel > 0 ? 'st' + texture.channel : 'st';
|
|
2009
|
+
usedUVChannels.add(texture.channel);
|
|
2010
|
+
|
|
2011
|
+
const isRGBA = formatsWithAlphaChannel.includes( texture.format );
|
|
2012
|
+
|
|
2013
|
+
const WRAPPINGS = {
|
|
2014
|
+
1000: 'repeat', // RepeatWrapping
|
|
2015
|
+
1001: 'clamp', // ClampToEdgeWrapping
|
|
2016
|
+
1002: 'mirror' // MirroredRepeatWrapping
|
|
2017
|
+
};
|
|
2018
|
+
|
|
2019
|
+
const repeat = texture.repeat.clone();
|
|
2020
|
+
const offset = texture.offset.clone();
|
|
2021
|
+
const rotation = texture.rotation;
|
|
2022
|
+
|
|
2023
|
+
// rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot
|
|
2024
|
+
const xRotationOffset = Math.sin(rotation);
|
|
2025
|
+
const yRotationOffset = Math.cos(rotation);
|
|
2026
|
+
|
|
2027
|
+
// texture coordinates start in the opposite corner, need to correct
|
|
2028
|
+
offset.y = 1 - offset.y - repeat.y;
|
|
2029
|
+
|
|
2030
|
+
// turns out QuickLook is buggy and interprets texture repeat inverted.
|
|
2031
|
+
// Apple Feedback: FB10036297 and FB11442287
|
|
2032
|
+
if ( quickLookCompatible ) {
|
|
2033
|
+
|
|
2034
|
+
// This is NOT correct yet in QuickLook, but comes close for a range of models.
|
|
2035
|
+
// It becomes more incorrect the bigger the offset is
|
|
2036
|
+
|
|
2037
|
+
// sanitize repeat values to avoid NaNs
|
|
2038
|
+
if (repeat.x === 0) repeat.x = 0.0001;
|
|
2039
|
+
if (repeat.y === 0) repeat.y = 0.0001;
|
|
2040
|
+
|
|
2041
|
+
offset.x = offset.x / repeat.x;
|
|
2042
|
+
offset.y = offset.y / repeat.y;
|
|
2043
|
+
|
|
2044
|
+
offset.x += xRotationOffset / repeat.x;
|
|
2045
|
+
offset.y += yRotationOffset - 1;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
else {
|
|
2049
|
+
|
|
2050
|
+
// results match glTF results exactly. verified correct in usdview.
|
|
2051
|
+
offset.x += xRotationOffset * repeat.x;
|
|
2052
|
+
offset.y += (1 - yRotationOffset) * repeat.y;
|
|
2053
|
+
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
const materialName = getMaterialName(material);
|
|
2057
|
+
|
|
2058
|
+
const needsTextureTransform = ( repeat.x != 1 || repeat.y != 1 || offset.x != 0 || offset.y != 0 || rotation != 0 );
|
|
2059
|
+
const textureTransformInput = `${materialRoot}/${materialName}/${'uvReader_' + uv}.outputs:result>`; const textureTransformOutput = `${materialRoot}/${materialName}/Transform2d_${mapType}.outputs:result>`;
|
|
2060
|
+
const needsTextureScale = mapType !== 'normal' && (color && (color.r !== 1 || color.g !== 1 || color.b !== 1 || opacity !== 1)) || false;
|
|
2061
|
+
|
|
2062
|
+
const needsNormalScaleAndBias = mapType === 'normal';
|
|
2063
|
+
const normalScale = material instanceof MeshStandardMaterial ? (material.normalScale ? material.normalScale.x * 2 : 2) : 2;
|
|
2064
|
+
const normalScaleValueString = normalScale.toFixed( PRECISION );
|
|
2065
|
+
const normalBiasString = (-1 * (normalScale / 2)).toFixed( PRECISION );
|
|
2066
|
+
const normalBiasZString = (1 - normalScale).toFixed( PRECISION );
|
|
2067
|
+
|
|
2068
|
+
return `
|
|
2069
|
+
${needsTextureTransform ? `def Shader "Transform2d_${mapType}" (
|
|
2070
|
+
sdrMetadata = {
|
|
2071
|
+
string role = "math"
|
|
2072
|
+
}
|
|
2073
|
+
)
|
|
2074
|
+
{
|
|
2075
|
+
uniform token info:id = "UsdTransform2d"
|
|
2076
|
+
float2 inputs:in.connect = ${textureTransformInput}
|
|
2077
|
+
float2 inputs:scale = ${buildVector2( repeat )}
|
|
2078
|
+
float2 inputs:translation = ${buildVector2( offset )}
|
|
2079
|
+
float inputs:rotation = ${(rotation / Math.PI * 180).toFixed( PRECISION )}
|
|
2080
|
+
float2 outputs:result
|
|
2081
|
+
}
|
|
2082
|
+
` : '' }
|
|
2083
|
+
def Shader "${name}_${mapType}"
|
|
2084
|
+
{
|
|
2085
|
+
uniform token info:id = "UsdUVTexture"
|
|
2086
|
+
asset inputs:file = @textures/${id}.${isRGBA ? 'png' : 'jpg'}@
|
|
2087
|
+
token inputs:sourceColorSpace = "${ texture.colorSpace === 'srgb' ? 'sRGB' : 'raw' }"
|
|
2088
|
+
float2 inputs:st.connect = ${needsTextureTransform ? textureTransformOutput : textureTransformInput}
|
|
2089
|
+
${needsTextureScale ? `
|
|
2090
|
+
float4 inputs:scale = (${color ? color.r + ', ' + color.g + ', ' + color.b : '1, 1, 1'}, ${opacity})
|
|
2091
|
+
` : `` }
|
|
2092
|
+
${needsNormalScaleAndBias ? `
|
|
2093
|
+
float4 inputs:scale = (${normalScaleValueString}, ${normalScaleValueString}, ${normalScaleValueString}, 1)
|
|
2094
|
+
float4 inputs:bias = (${normalBiasString}, ${normalBiasString}, ${normalBiasZString}, 0)
|
|
2095
|
+
` : `` }
|
|
2096
|
+
token inputs:wrapS = "${ WRAPPINGS[ texture.wrapS ] }"
|
|
2097
|
+
token inputs:wrapT = "${ WRAPPINGS[ texture.wrapT ] }"
|
|
2098
|
+
float outputs:r
|
|
2099
|
+
float outputs:g
|
|
2100
|
+
float outputs:b
|
|
2101
|
+
float3 outputs:rgb
|
|
2102
|
+
${material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : ''}
|
|
2103
|
+
}`;
|
|
2104
|
+
}
|
|
2105
|
+
|
|
1969
2106
|
function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quickLookCompatible = false ) {
|
|
1970
2107
|
|
|
1971
2108
|
const materialName = getMaterialName(material);
|
|
@@ -2008,133 +2145,8 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2008
2145
|
const samplers: Array<string> = [];
|
|
2009
2146
|
const usedUVChannels: Set<number> = new Set();
|
|
2010
2147
|
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
// to avoid exporting the same underlying data multiple times.
|
|
2014
|
-
return makeNameSafe(tex.name) + '_' + (tex.source?.id ?? tex.id);
|
|
2015
|
-
}
|
|
2016
|
-
|
|
2017
|
-
function buildTexture( texture: Texture, mapType: MapType, color: Color | undefined = undefined, opacity: number | undefined = undefined ) {
|
|
2018
|
-
|
|
2019
|
-
const name = texName(texture);
|
|
2020
|
-
// File names need to be unique; so when we're baking color and/or opacity into a texture we need to keep track of that.
|
|
2021
|
-
// TODO This currently results in textures potentially being exported multiple times that are actually identical!
|
|
2022
|
-
// const colorHex = color ? color.getHexString() : undefined;
|
|
2023
|
-
// const colorId = ( color && colorHex != 'ffffff' ? '_' + color.getHexString() : '' );
|
|
2024
|
-
const id = name + ( opacity !== undefined && opacity !== 1.0 ? '_' + opacity : '' );
|
|
2025
|
-
|
|
2026
|
-
// Seems neither QuickLook nor usdview support scale/bias on .a values, so we need to bake opacity multipliers into
|
|
2027
|
-
// the texture. This is not ideal.
|
|
2028
|
-
const opacityIsAppliedToTextureAndNotAsScale = quickLookCompatible && opacity !== undefined && opacity !== 1.0;
|
|
2029
|
-
const scaleToApply = opacityIsAppliedToTextureAndNotAsScale ? new Vector4(1, 1, 1, opacity) : undefined;
|
|
2030
|
-
|
|
2031
|
-
// Treat undefined opacity as 1
|
|
2032
|
-
if (opacity === undefined)
|
|
2033
|
-
opacity = 1.0;
|
|
2034
|
-
|
|
2035
|
-
// When we're baking opacity into the texture, we shouldn't apply it as scale as well – so we set it to 1.
|
|
2036
|
-
if (opacityIsAppliedToTextureAndNotAsScale)
|
|
2037
|
-
opacity = 1.0;
|
|
2038
|
-
|
|
2039
|
-
// sanitize scaleToApply.w === 0 - this isn't working right now, seems the PNG can't be read back properly.
|
|
2040
|
-
if (scaleToApply && scaleToApply.w <= 0.05) scaleToApply.w = 0.05;
|
|
2041
|
-
|
|
2042
|
-
textures[ id ] = { texture, scale: scaleToApply };
|
|
2043
|
-
|
|
2044
|
-
const uv = texture.channel > 0 ? 'st' + texture.channel : 'st';
|
|
2045
|
-
usedUVChannels.add(texture.channel);
|
|
2046
|
-
|
|
2047
|
-
const isRGBA = formatsWithAlphaChannel.includes( texture.format );
|
|
2048
|
-
|
|
2049
|
-
const WRAPPINGS = {
|
|
2050
|
-
1000: 'repeat', // RepeatWrapping
|
|
2051
|
-
1001: 'clamp', // ClampToEdgeWrapping
|
|
2052
|
-
1002: 'mirror' // MirroredRepeatWrapping
|
|
2053
|
-
};
|
|
2054
|
-
|
|
2055
|
-
const repeat = texture.repeat.clone();
|
|
2056
|
-
const offset = texture.offset.clone();
|
|
2057
|
-
const rotation = texture.rotation;
|
|
2058
|
-
|
|
2059
|
-
// rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot
|
|
2060
|
-
const xRotationOffset = Math.sin(rotation);
|
|
2061
|
-
const yRotationOffset = Math.cos(rotation);
|
|
2062
|
-
|
|
2063
|
-
// texture coordinates start in the opposite corner, need to correct
|
|
2064
|
-
offset.y = 1 - offset.y - repeat.y;
|
|
2065
|
-
|
|
2066
|
-
// turns out QuickLook is buggy and interprets texture repeat inverted.
|
|
2067
|
-
// Apple Feedback: FB10036297 and FB11442287
|
|
2068
|
-
if ( quickLookCompatible ) {
|
|
2069
|
-
|
|
2070
|
-
// This is NOT correct yet in QuickLook, but comes close for a range of models.
|
|
2071
|
-
// It becomes more incorrect the bigger the offset is
|
|
2072
|
-
|
|
2073
|
-
// sanitize repeat values to avoid NaNs
|
|
2074
|
-
if (repeat.x === 0) repeat.x = 0.0001;
|
|
2075
|
-
if (repeat.y === 0) repeat.y = 0.0001;
|
|
2076
|
-
|
|
2077
|
-
offset.x = offset.x / repeat.x;
|
|
2078
|
-
offset.y = offset.y / repeat.y;
|
|
2079
|
-
|
|
2080
|
-
offset.x += xRotationOffset / repeat.x;
|
|
2081
|
-
offset.y += yRotationOffset - 1;
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
else {
|
|
2085
|
-
|
|
2086
|
-
// results match glTF results exactly. verified correct in usdview.
|
|
2087
|
-
offset.x += xRotationOffset * repeat.x;
|
|
2088
|
-
offset.y += (1 - yRotationOffset) * repeat.y;
|
|
2089
|
-
|
|
2090
|
-
}
|
|
2091
|
-
|
|
2092
|
-
const needsTextureTransform = ( repeat.x != 1 || repeat.y != 1 || offset.x != 0 || offset.y != 0 || rotation != 0 );
|
|
2093
|
-
const textureTransformInput = `${materialRoot}/${materialName}/${'uvReader_' + uv}.outputs:result>`; const textureTransformOutput = `${materialRoot}/${materialName}/Transform2d_${mapType}.outputs:result>`;
|
|
2094
|
-
const needsTextureScale = mapType !== 'normal' && (color && (color.r !== 1 || color.g !== 1 || color.b !== 1 || opacity !== 1)) || false;
|
|
2095
|
-
|
|
2096
|
-
const needsNormalScaleAndBias = mapType === 'normal';
|
|
2097
|
-
const normalScale = material instanceof MeshStandardMaterial ? (material.normalScale ? material.normalScale.x * 2 : 2) : 2;
|
|
2098
|
-
const normalScaleValueString = normalScale.toFixed( PRECISION );
|
|
2099
|
-
const normalBiasString = (-1 * (normalScale / 2)).toFixed( PRECISION );
|
|
2100
|
-
const normalBiasZString = (1 - normalScale).toFixed( PRECISION );
|
|
2101
|
-
|
|
2102
|
-
return `
|
|
2103
|
-
${needsTextureTransform ? `def Shader "Transform2d_${mapType}" (
|
|
2104
|
-
sdrMetadata = {
|
|
2105
|
-
string role = "math"
|
|
2106
|
-
}
|
|
2107
|
-
)
|
|
2108
|
-
{
|
|
2109
|
-
uniform token info:id = "UsdTransform2d"
|
|
2110
|
-
float2 inputs:in.connect = ${textureTransformInput}
|
|
2111
|
-
float2 inputs:scale = ${buildVector2( repeat )}
|
|
2112
|
-
float2 inputs:translation = ${buildVector2( offset )}
|
|
2113
|
-
float inputs:rotation = ${(rotation / Math.PI * 180).toFixed( PRECISION )}
|
|
2114
|
-
float2 outputs:result
|
|
2115
|
-
}
|
|
2116
|
-
` : '' }
|
|
2117
|
-
def Shader "${name}_${mapType}"
|
|
2118
|
-
{
|
|
2119
|
-
uniform token info:id = "UsdUVTexture"
|
|
2120
|
-
asset inputs:file = @textures/${id}.${isRGBA ? 'png' : 'jpg'}@
|
|
2121
|
-
token inputs:sourceColorSpace = "${ texture.colorSpace === 'srgb' ? 'sRGB' : 'raw' }"
|
|
2122
|
-
float2 inputs:st.connect = ${needsTextureTransform ? textureTransformOutput : textureTransformInput}
|
|
2123
|
-
${needsTextureScale ? `
|
|
2124
|
-
float4 inputs:scale = (${color ? color.r + ', ' + color.g + ', ' + color.b : '1, 1, 1'}, ${opacity})
|
|
2125
|
-
` : `` }
|
|
2126
|
-
${needsNormalScaleAndBias ? `
|
|
2127
|
-
float4 inputs:scale = (${normalScaleValueString}, ${normalScaleValueString}, ${normalScaleValueString}, 1)
|
|
2128
|
-
float4 inputs:bias = (${normalBiasString}, ${normalBiasString}, ${normalBiasZString}, 0)
|
|
2129
|
-
` : `` }
|
|
2130
|
-
token inputs:wrapS = "${ WRAPPINGS[ texture.wrapS ] }"
|
|
2131
|
-
token inputs:wrapT = "${ WRAPPINGS[ texture.wrapT ] }"
|
|
2132
|
-
float outputs:r
|
|
2133
|
-
float outputs:g
|
|
2134
|
-
float outputs:b
|
|
2135
|
-
float3 outputs:rgb
|
|
2136
|
-
${material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : ''}
|
|
2137
|
-
}`;
|
|
2148
|
+
if ((material as any).isMeshPhysicalNodeMaterial === true) {
|
|
2149
|
+
return buildNodeMaterial(material as unknown as MeshPhysicalNodeMaterial, materialName, textures);
|
|
2138
2150
|
}
|
|
2139
2151
|
|
|
2140
2152
|
let effectiveOpacity = ( material.transparent || material.alphaTest ) ? material.opacity : 1;
|
|
@@ -2175,7 +2187,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2175
2187
|
|
|
2176
2188
|
}
|
|
2177
2189
|
|
|
2178
|
-
samplers.push( buildTexture( material.map, 'diffuse', material.color, effectiveOpacity ) );
|
|
2190
|
+
samplers.push( buildTexture( material.map, 'diffuse', quickLookCompatible, textures, material, usedUVChannels, material.color, effectiveOpacity ) );
|
|
2179
2191
|
|
|
2180
2192
|
} else {
|
|
2181
2193
|
|
|
@@ -2200,7 +2212,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2200
2212
|
|
|
2201
2213
|
inputs.push( `${pad}float inputs:occlusion.connect = ${materialRoot}/${materialName}/${texName(material.aoMap)}_occlusion.outputs:r>` );
|
|
2202
2214
|
|
|
2203
|
-
samplers.push( buildTexture( material.aoMap, 'occlusion' ) );
|
|
2215
|
+
samplers.push( buildTexture( material.aoMap, 'occlusion', quickLookCompatible, textures, material, usedUVChannels ) );
|
|
2204
2216
|
|
|
2205
2217
|
}
|
|
2206
2218
|
|
|
@@ -2212,7 +2224,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2212
2224
|
haveConnectedOpacity = true;
|
|
2213
2225
|
haveConnectedOpacityThreshold = true;
|
|
2214
2226
|
|
|
2215
|
-
samplers.push( buildTexture( material.alphaMap, 'opacity', new Color( 1, 1, 1 ), effectiveOpacity ) );
|
|
2227
|
+
samplers.push( buildTexture( material.alphaMap, 'opacity', quickLookCompatible, textures, material, usedUVChannels, new Color( 1, 1, 1 ), effectiveOpacity ) );
|
|
2216
2228
|
|
|
2217
2229
|
} else { // opacity will always be connected if we have a map
|
|
2218
2230
|
|
|
@@ -2243,7 +2255,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2243
2255
|
inputs.push( `${pad}color3f inputs:emissiveColor.connect = ${materialRoot}/${materialName}/${texName(material.emissiveMap)}_emissive.outputs:rgb>` );
|
|
2244
2256
|
const color = material.emissive.clone();
|
|
2245
2257
|
color.multiplyScalar( material.emissiveIntensity );
|
|
2246
|
-
samplers.push( buildTexture( material.emissiveMap, 'emissive', color ) );
|
|
2258
|
+
samplers.push( buildTexture( material.emissiveMap, 'emissive', quickLookCompatible, textures, material, usedUVChannels, color ) );
|
|
2247
2259
|
|
|
2248
2260
|
} else if ( material.emissive?.getHex() > 0 ) {
|
|
2249
2261
|
|
|
@@ -2262,7 +2274,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2262
2274
|
|
|
2263
2275
|
inputs.push( `${pad}normal3f inputs:normal.connect = ${materialRoot}/${materialName}/${texName(material.normalMap)}_normal.outputs:rgb>` );
|
|
2264
2276
|
|
|
2265
|
-
samplers.push( buildTexture( material.normalMap, 'normal' ) );
|
|
2277
|
+
samplers.push( buildTexture( material.normalMap, 'normal', quickLookCompatible, textures, material, usedUVChannels ) );
|
|
2266
2278
|
|
|
2267
2279
|
}
|
|
2268
2280
|
|
|
@@ -2270,7 +2282,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2270
2282
|
|
|
2271
2283
|
inputs.push( `${pad}float inputs:roughness.connect = ${materialRoot}/${materialName}/${texName(material.roughnessMap)}_roughness.outputs:g>` );
|
|
2272
2284
|
|
|
2273
|
-
samplers.push( buildTexture( material.roughnessMap, 'roughness' ) );
|
|
2285
|
+
samplers.push( buildTexture( material.roughnessMap, 'roughness', quickLookCompatible, textures, material, usedUVChannels ) );
|
|
2274
2286
|
|
|
2275
2287
|
} else {
|
|
2276
2288
|
|
|
@@ -2282,7 +2294,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2282
2294
|
|
|
2283
2295
|
inputs.push( `${pad}float inputs:metallic.connect = ${materialRoot}/${materialName}/${texName(material.metalnessMap)}_metallic.outputs:b>` );
|
|
2284
2296
|
|
|
2285
|
-
samplers.push( buildTexture( material.metalnessMap, 'metallic' ) );
|
|
2297
|
+
samplers.push( buildTexture( material.metalnessMap, 'metallic', quickLookCompatible, textures, material, usedUVChannels ) );
|
|
2286
2298
|
|
|
2287
2299
|
} else {
|
|
2288
2300
|
|
|
@@ -2302,7 +2314,7 @@ function buildMaterial( material: MeshBasicMaterial, textures: TextureMap, quick
|
|
|
2302
2314
|
|
|
2303
2315
|
inputs.push( `${pad}float inputs:opacity.connect = ${materialRoot}/${materialName}/${texName(material.transmissionMap)}_transmission.outputs:r>` );
|
|
2304
2316
|
|
|
2305
|
-
samplers.push( buildTexture( material.transmissionMap, 'transmission' ) );
|
|
2317
|
+
samplers.push( buildTexture( material.transmissionMap, 'transmission', quickLookCompatible, textures, material, usedUVChannels ) );
|
|
2306
2318
|
}
|
|
2307
2319
|
|
|
2308
2320
|
}
|
|
@@ -2399,12 +2411,13 @@ export {
|
|
|
2399
2411
|
buildMatrix,
|
|
2400
2412
|
decompressGpuTexture,
|
|
2401
2413
|
findStructuralNodesInBoneHierarchy,
|
|
2414
|
+
formatsWithAlphaChannel,
|
|
2402
2415
|
getBoneName,
|
|
2403
2416
|
getMaterialName as getMaterialNameForUSD,
|
|
2404
2417
|
getPathToSkeleton,
|
|
2405
2418
|
imageToCanvas,
|
|
2406
2419
|
imageToCanvasUnpremultiplied,
|
|
2407
|
-
makeNameSafe as makeNameSafeForUSD,
|
|
2420
|
+
makeNameSafe as makeNameSafeForUSD,
|
|
2408
2421
|
USDDocument,
|
|
2409
2422
|
fn as usdNumberFormatting,
|
|
2410
2423
|
USDObject,
|