Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USDZExporter: Added texture.offset and texture.repeat support #21852

Merged
merged 5 commits into from
May 21, 2021

Conversation

kolodi
Copy link
Contributor

@kolodi kolodi commented May 18, 2021

Hello.

This is just a proposal for USDZ generation for the following features:

  1. Using of Transform2D for tiled textures
  2. Mixing of material color to diffuseMap with bias (does not work for some reason)
  3. Using of same texture image but with different parameters specific for a certain material
  4. Separate Texture def for each type of map (for better control about specific settings)

@@ -36,7 +36,7 @@ class USDZExporter {
materials[ material.uuid ] = material;
if ( material.map !== null ) textures[ material.map.uuid ] = material.map;
if ( material.normalMap !== null ) textures[ material.normalMap.uuid ] = material.normalMap;
if ( material.aoMap !== null ) textures[ material.aoMap.uuid ] = material.aoMap;
//if ( material.aoMap !== null ) textures[ material.aoMap.uuid ] = material.aoMap;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I skip AO because it is broken when using Transform2D. For some reason it is always scaled the same amount as albedo (diffuse) map, for example if albedo has scale (8,8) and you obviously want your AO map to remain (1,1), no luck here, AO will be also (8,8).

@@ -53,7 +53,7 @@ class USDZExporter {
} );

output += buildMaterials( materials );
output += buildTextures( textures );
//output += buildTextures( textures );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not build all textures in same scope, their defs are now in side each material.


}

function prepareTextureTransform(texture) {
Copy link
Contributor Author

@kolodi kolodi May 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one prepares the standard UsdTransform2d as from USD specs

asset inputs:file = @textures/Texture_${ texture.id }.jpg@
float2 inputs:st.connect = </Materials/Material_${ material.id }/Transform2D_${ texture.id }.outputs:result>
float4 inputs:scale = (1, 1, 1, 1)
float4 inputs:bias = (${material.color.r}, ${material.color.g}, ${material.color.b}, 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should theoretically add material color to rgb components of the diffuse map, but it does not work! Playing with scale I can achieve some coloration to happen, but bias does nothing.


}

if ( material.aoMap !== null ) {

parameters.push( `${ pad }float inputs:occlusion.connect = </Textures/Texture_${ material.aoMap.id }.outputs:r>` );
//parameters.push( `${ pad }float inputs:occlusion.connect = </Materials/Material_${ material.id }/Texture_${ material.aoMap.id }.outputs:r>` );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, ommit AO because it is broken (tiled same as albedo no matter what)

parameters.push( `${ pad }float inputs:metallic.connect = </Materials/Material_${ material.id }/Texture_${ material.metalnessMap.id }_metalness.outputs:b>` );

texture = material.metalnessMap;
//texturesTransforms.push(prepareTextureTransform(texture));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metalness and Roughness maps are often the same map but uses different channels so to avoid duplicated defs for same texture id just use the same as metalness. For now it supposes that if we have roughness map there should also be e matalness one.

token inputs:wrapS = "repeat"
token inputs:wrapT = "repeat"
float outputs:r

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method remains just for reference. I quickly found all the limitations for new features when having all textures in a single separate scope.

@mrdoob
Copy link
Owner

mrdoob commented May 19, 2021

Hmm, this PR changes too many things at once...
Would it be possible to do split it into multiple PRs?

@kolodi
Copy link
Contributor Author

kolodi commented May 19, 2021

Hmm, this PR changes too many things at once...
Would it be possible to do split it into multiple PRs?

Yes I know this. Intention of this PR is to demonstrate the required changes to accommodate support for Trandform2D. I would probably remove all other features except Transform2D. In any case, moving Textures defs from a single scope inside each material scope is necessary, also for all other e future features.

@@ -445,23 +439,40 @@ function buildMaterial( material ) {

if ( material.aoMap !== null ) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AO map is enabled now, but it will be broken if you actually use tiling on diffuse map other than (1,1). I was also thinking about introducing options parameter for the parse() function (similarly to how it is for export glTF). One can specify maps to exclude (or include) in options in order to avoid using AO map where tiling can break it.

@mrdoob
Copy link
Owner

mrdoob commented May 19, 2021

I guess we no longer need this line?

@mrdoob
Copy link
Owner

mrdoob commented May 19, 2021

/cc @qeeqez

@mrdoob mrdoob added this to the r129 milestone May 19, 2021
@kolodi
Copy link
Contributor Author

kolodi commented May 19, 2021

I guess we no longer need this line?


still needed when generating texture image files
for ( const uuid in textures ) {
const texture = textures[ uuid ];
files[ 'textures/Texture_' + texture.id + '.jpg' ] = await imgToU8( texture.image );
}

also I would use Map instead of plane object for this.

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

I want to get some progress on this so I'll merge and clean up.

@mrdoob mrdoob changed the title Usdz transform2d USDZExporter: Added texture.offset and texture.repeat support May 21, 2021
@mrdoob mrdoob marked this pull request as ready for review May 21, 2021 12:07
@mrdoob mrdoob merged commit d66b8ae into mrdoob:dev May 21, 2021
@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

Thanks!

@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

I want to get some progress on this so I'll merge and clean up.

Great. I have tons of features to add :)

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

I'm cleaning it up and trying to add support for aoMap/uv2.

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

Clean up: 14fab09

Hopefully I didn't break anything 🤞

@qeeqez
Copy link
Contributor

qeeqez commented May 21, 2021

Cool guys! Looking for your changes 👀

@kolodi kolodi deleted the usdz-transform2d branch May 21, 2021 14:01
@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

I'm cleaning it up and trying to add support for aoMap/uv2.

Glad to hear. AFAIK 2nd UV is not supported in QuickLook tho.

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

@kolodi do you know if usdz supports multiple uv channels? I'm trying to usdzconvert and doesn't seem to work 🤔

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

This is what I tried to do:

diff --git a/examples/jsm/exporters/USDZExporter.js b/examples/jsm/exporters/USDZExporter.js
index a2df0b0cbe..2951abd8ea 100644
--- a/examples/jsm/exporters/USDZExporter.js
+++ b/examples/jsm/exporters/USDZExporter.js
@@ -199,25 +199,27 @@ function buildMesh( geometry ) {
 	const attributes = geometry.attributes;
 	const count = attributes.position.count;
 
+	const pad = '        ';
+	const parameters = [];
+
+	parameters.push( `${ pad }int[] faceVertexCounts = [${ buildMeshVertexCount( geometry ) }]` );
+	parameters.push( `${ pad }int[] faceVertexIndices = [${ buildMeshVertexIndices( geometry ) }]` );
+	parameters.push( `${ pad }normal3f[] normals = [${ buildVector3Array( attributes.normal, count )}] ( interpolation = "vertex" )` );
+	parameters.push( `${ pad }point3f[] points = [${ buildVector3Array( attributes.position, count )}]` );
+	parameters.push( `${ pad }float2[] primvars:st = [${ buildVector2Array( attributes.uv, count )}] ( interpolation = "vertex" )` );
+
 	if ( 'uv2' in attributes ) {
 
-		console.warn( 'THREE.USDZExporter: uv2 not supported yet.' );
+		parameters.push( `${ pad }float2[] primvars:st2 = [${ buildVector2Array( attributes.uv2, count )}] ( interpolation = "vertex" )` );
 
 	}
 
+	parameters.push( `${ pad }uniform token subdivisionScheme = "none"` );
+
 	return `
     def Mesh "${ name }"
     {
-        int[] faceVertexCounts = [${ buildMeshVertexCount( geometry ) }]
-        int[] faceVertexIndices = [${ buildMeshVertexIndices( geometry ) }]
-        normal3f[] normals = [${ buildVector3Array( attributes.normal, count )}] (
-            interpolation = "vertex"
-        )
-        point3f[] points = [${ buildVector3Array( attributes.position, count )}]
-        float2[] primvars:st = [${ buildVector2Array( attributes.uv, count )}] (
-            interpolation = "vertex"
-        )
-        uniform token subdivisionScheme = "none"
+${ parameters.join( '\n' ) }
     }
 `;
 
@@ -329,6 +331,8 @@ function buildMaterial( material ) {
 
 	function buildTexture( texture, mapType ) {
 
+		const uvReader = mapType === 'occlusion' ? 'uvReader_st2' : 'uvReader_st';
+
 		return `
         def Shader "Transform2d_${ mapType }" (
             sdrMetadata = {
@@ -337,7 +341,7 @@ function buildMaterial( material ) {
         )
         {
             uniform token info:id = "UsdTransform2d"
-            float2 inputs:in.connect = </Materials/Material_${ material.id }/uvReader_st.outputs:result>
+            float2 inputs:in.connect = </Materials/Material_${ material.id }/${ uvReader }.outputs:result>
             float2 inputs:scale = ${ buildVector2( texture.repeat ) }
             float2 inputs:translation = ${ buildVector2( texture.offset ) }
             float2 outputs:result
@@ -433,7 +437,9 @@ ${ parameters.join( '\n' ) }
         }
 
         token outputs:surface.connect = </Materials/Material_${ material.id }/PreviewSurface.outputs:surface>
+
         token inputs:frame:stPrimvarName = "st"
+        token inputs:frame:st2PrimvarName = "st2"
 
         def Shader "uvReader_st"
         {
@@ -443,6 +449,13 @@ ${ parameters.join( '\n' ) }
             float2 outputs:result
         }
 
+        def Shader "uvReader_st2"
+        {
+            uniform token info:id = "UsdPrimvarReader_float2"
+            token inputs:varname.connect = </Materials/Material_${ material.id }.inputs:frame:st2PrimvarName>
+            float2 inputs:fallback = (0.0, 0.0)
+            float2 outputs:result
+        }
 ${ textures.join( '\n' ) }
 
     }

I tried to run usdzconvert on a gltf with aoMap to see what I'm doing wrong but it doesn't seem to be able to handle the second uv set 🤔

@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

@kolodi do you know if usdz supports multiple uv channels? I'm trying to usdzconvert and doesn't seem to work 🤔

There is no official list of supported features for QuickLook, but it seems like it is not supported for now. USD comand line tools have a feature to check the genrated usdz (usdchecker). If you run it with flag --arkit it will check other specific limitations for QuockLook. And it actualy fails when Trandform2D is found saying that it is not supported. On the other hand I can clearly see that Transform2D is working (tried on dozens of different objects and devices). And in latest apple tool USDPython v 0.64 they added the support for Transform2D. So they are clearly moving towards supporting more staff. When I convert glTF with repeat textures to usdz with their tool, it is converted just fine, all different textures have differen scale and if you preview it in xCode it is all rendered ok. But then on device in QuickLook all tiling (transform) is inherited from the diffuse map for some reason.

@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

So theoretically, we may be allowed to use separate transform settings for different maps and it works in other USD viewers (like in xCode) but not in QuickLook just yet.

@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

I remember having tried to duplicate UV (create the second one from the 1st) and the use st2 PrimVar, the result was very strange, it was looking like tiling of 100x more than expected.

@mrdoob
Copy link
Owner

mrdoob commented May 21, 2021

Okay, I think I won't try adding uv2 support then.

The Transform2d is a nice addition. Thanks!

@kolodi
Copy link
Contributor Author

kolodi commented May 21, 2021

Okay, I think I won't try adding uv2 support then.

The Transform2d is a nice addition. Thanks!

Thank you.
I have more features already in use in my projects.
Now I'll try to create smaller pull request so we can try integrate them 1 by 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants