From: Richard Huang Date: Tue, 21 Nov 2023 11:43:42 +0000 (+0000) Subject: Support glTF extention: KHR_texture_transform X-Git-Tag: dali_2.3.0~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F78%2F301678%2F4;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Support glTF extention: KHR_texture_transform Change-Id: I54048e0c51c1331ca141d5af6486b9e1350e397a --- diff --git a/automated-tests/resources/TextureTransformMultiTest.bin b/automated-tests/resources/TextureTransformMultiTest.bin new file mode 100644 index 0000000..1dd626e Binary files /dev/null and b/automated-tests/resources/TextureTransformMultiTest.bin differ diff --git a/automated-tests/resources/TextureTransformMultiTest.gltf b/automated-tests/resources/TextureTransformMultiTest.gltf new file mode 100644 index 0000000..9f37ec0 --- /dev/null +++ b/automated-tests/resources/TextureTransformMultiTest.gltf @@ -0,0 +1,3186 @@ +{ + "asset" : { + "copyright" : "Copyright 2020 Analytical Graphics, Inc, CC-BY 4.0 https://creativecommons.org/licenses/by/4.0/ - Model and textures by Ed Mackey.", + "generator" : "Khronos glTF Blender I/O v1.2.75", + "version" : "2.0" + }, + "extensionsUsed" : [ + "KHR_texture_transform", + "KHR_materials_unlit", + "KHR_materials_clearcoat" + ], + "extensionsRequired" : [ + "KHR_texture_transform" + ], + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "BaseColorUV0", + "translation" : [ + 0.10000000149011612, + 0.75, + 0 + ] + }, + { + "mesh" : 1, + "name" : "BaseColorUV1", + "translation" : [ + 0.3499999940395355, + 0.75, + 0 + ] + }, + { + "mesh" : 2, + "name" : "BaseColorSample", + "translation" : [ + 0.6000000238418579, + 0.75, + 0 + ] + }, + { + "mesh" : 3, + "name" : "Background", + "translation" : [ + 0, + 0, + -0.02500000037252903 + ] + }, + { + "mesh" : 4, + "name" : "Labels" + }, + { + "mesh" : 5, + "name" : "EmissionUV0", + "translation" : [ + 0.10000000149011612, + 0.5, + 0 + ] + }, + { + "mesh" : 6, + "name" : "EmissionUV1", + "translation" : [ + 0.3499999940395355, + 0.5, + 0 + ] + }, + { + "mesh" : 7, + "name" : "EmissionSample", + "translation" : [ + 0.6000000238418579, + 0.5, + 0 + ] + }, + { + "mesh" : 8, + "name" : "NormalUV0", + "translation" : [ + 0.10000000149011612, + 0.25, + 0 + ] + }, + { + "mesh" : 9, + "name" : "NormalUV1", + "translation" : [ + 0.3499999940395355, + 0.25, + 0 + ] + }, + { + "mesh" : 10, + "name" : "NormalSample", + "translation" : [ + 0.6000000238418579, + 0.25, + 0 + ] + }, + { + "mesh" : 11, + "name" : "MetalRoughUV0", + "translation" : [ + 0.10000000149011612, + 0, + 0 + ] + }, + { + "mesh" : 12, + "name" : "MetalRoughUV1", + "translation" : [ + 0.3499999940395355, + 0, + 0 + ] + }, + { + "mesh" : 13, + "name" : "MetalRoughSample", + "translation" : [ + 0.6000000238418579, + 0, + 0 + ] + }, + { + "mesh" : 14, + "name" : "OcclusionUV0", + "translation" : [ + 0.10000000149011612, + -0.25, + 0 + ] + }, + { + "mesh" : 15, + "name" : "OcclusionUV1", + "translation" : [ + 0.3499999940395355, + -0.25, + 0 + ] + }, + { + "mesh" : 16, + "name" : "OcclusionSample", + "translation" : [ + 0.6000000238418579, + -0.25, + 0 + ] + }, + { + "mesh" : 17, + "name" : "UnlitUV0", + "translation" : [ + 0.10000000149011612, + -0.5, + 0 + ] + }, + { + "mesh" : 18, + "name" : "UnlitUV1", + "translation" : [ + 0.3499999940395355, + -0.5, + 0 + ] + }, + { + "mesh" : 19, + "name" : "UnlitSample", + "translation" : [ + 0.6000000238418579, + -0.5, + 0 + ] + }, + { + "mesh" : 20, + "name" : "ClearcoatUV0", + "translation" : [ + 0.10000000149011612, + -0.75, + 0 + ] + }, + { + "mesh" : 21, + "name" : "ClearcoatUV1", + "translation" : [ + 0.3499999940395355, + -0.75, + 0 + ] + }, + { + "mesh" : 22, + "name" : "ClearcoatSample", + "translation" : [ + 0.6000000238418579, + -0.75, + 0 + ] + }, + { + "mesh" : 23, + "name" : "ClearcoatRoughUV0", + "translation" : [ + 0.10000000149011612, + -1, + 0 + ] + }, + { + "mesh" : 24, + "name" : "ClearcoatRoughUV1", + "translation" : [ + 0.3499999940395355, + -1, + 0 + ] + }, + { + "mesh" : 25, + "name" : "ClearcoatRoughSample", + "translation" : [ + 0.6000000238418579, + -1, + 0 + ] + }, + { + "mesh" : 26, + "name" : "ClearcoatNormalUV0", + "translation" : [ + 0.10000000149011612, + -1.25, + 0 + ] + }, + { + "mesh" : 27, + "name" : "ClearcoatNormalUV1", + "translation" : [ + 0.3499999940395355, + -1.25, + 0 + ] + }, + { + "mesh" : 28, + "name" : "ClearcoatNormalSample", + "translation" : [ + 0.6000000238418579, + -1.25, + 0 + ] + } + ], + "materials" : [ + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "BaseColorTest0Mat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 0, + "texCoord" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "BaseColorTest1Mat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 1, + "texCoord" : 1 + }, + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "BaseColorSampleMat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 2, + "texCoord" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "doubleSided" : true, + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "BackgroundMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.007408552337437868, + 0.07486194372177124, + 0.4639684557914734, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "doubleSided" : true, + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "LabelMat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 3, + "texCoord" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 1, + 1, + 1 + ], + "emissiveTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 4, + "texCoord" : 0 + }, + "name" : "EmissionTest0Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0, + 0.15000000596046448, + 0, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 1, + 1, + 1 + ], + "emissiveTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 5, + "texCoord" : 1 + }, + "name" : "EmissionTest1Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0, + 0.15000000596046448, + 0, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 1, + 1, + 1 + ], + "emissiveTexture" : { + "index" : 6, + "texCoord" : 0 + }, + "name" : "EmissionSampleMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0, + 0.15000000596046448, + 0, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "NormalTest0Mat", + "normalTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 7, + "texCoord" : 0 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 0.10000000149011612 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "NormalTest1Mat", + "normalTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 8, + "texCoord" : 1 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 0.10000000149011612 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "NormalSampleMat", + "normalTexture" : { + "index" : 9, + "texCoord" : 0 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 0.10000000149011612 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "MetalRoughTest0Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicRoughnessTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 10, + "texCoord" : 0 + } + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "MetalRoughTest1Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicRoughnessTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 11, + "texCoord" : 1 + } + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "MetalRoughSampleMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicRoughnessTexture" : { + "index" : 12, + "texCoord" : 0 + } + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "OcclusionTest0Mat", + "occlusionTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 13, + "texCoord" : 0 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "OcclusionTest1Mat", + "occlusionTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 14, + "texCoord" : 1 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "name" : "OcclusionSampleMat", + "occlusionTexture" : { + "index" : 15, + "texCoord" : 0 + }, + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor" : 0, + "roughnessFactor" : 1 + } + }, + { + "extensions" : { + "KHR_materials_unlit" : {} + }, + "name" : "UnlitTest0Mat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 16, + "texCoord" : 0 + } + } + }, + { + "extensions" : { + "KHR_materials_unlit" : {} + }, + "name" : "UnlitTest1Mat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 17, + "texCoord" : 1 + } + } + }, + { + "extensions" : { + "KHR_materials_unlit" : {} + }, + "name" : "UnlitSampleMat", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 18, + "texCoord" : 0 + } + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 19, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatTest0Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 20, + "texCoord" : 1 + } + } + }, + "name" : "ClearcoatTest1Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatTexture" : { + "index" : 21, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatSampleMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 1, + "clearcoatRoughnessTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 22, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatRoughTest0Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 1, + "clearcoatRoughnessTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 23, + "texCoord" : 1 + } + } + }, + "name" : "ClearcoatRoughTest1Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 1, + "clearcoatRoughnessTexture" : { + "index" : 24, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatRoughSampleMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatNormalTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 25, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatNormalTest0Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatNormalTexture" : { + "extensions" : { + "KHR_texture_transform" : { + "offset" : [ + 0.7049999535083774, + 0.28500004152502995 + ], + "rotation" : 1.5707963705062866, + "scale" : [ + 0.3499999940395355, + 0.3499999940395355 + ] + } + }, + "index" : 26, + "texCoord" : 1 + } + } + }, + "name" : "ClearcoatNormalTest1Mat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + }, + { + "emissiveFactor" : [ + 0, + 0, + 0 + ], + "extensions" : { + "KHR_materials_clearcoat" : { + "clearcoatFactor" : 1, + "clearcoatRoughnessFactor" : 0.029999999329447746, + "clearcoatNormalTexture" : { + "index" : 27, + "texCoord" : 0 + } + } + }, + "name" : "ClearcoatNormalSampleMat", + "pbrMetallicRoughness" : { + "baseColorFactor" : [ + 0.0040703266859054565, + 0.030168700963258743, + 0.16859287023544312, + 1 + ], + "metallicFactor" : 1, + "roughnessFactor" : 1 + } + } + ], + "meshes" : [ + { + "name" : "BaseColorUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "NORMAL" : 1, + "TEXCOORD_0" : 2, + "TEXCOORD_1" : 3 + }, + "indices" : 4, + "material" : 0 + } + ] + }, + { + "name" : "BaseColorUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 5, + "NORMAL" : 6, + "TEXCOORD_0" : 7, + "TEXCOORD_1" : 8 + }, + "indices" : 4, + "material" : 1 + } + ] + }, + { + "name" : "BaseColorSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 9, + "NORMAL" : 10, + "TEXCOORD_0" : 11 + }, + "indices" : 4, + "material" : 2 + } + ] + }, + { + "name" : "BackgroundMesh", + "primitives" : [ + { + "attributes" : { + "POSITION" : 12, + "NORMAL" : 13 + }, + "indices" : 4, + "material" : 3 + } + ] + }, + { + "name" : "LabelMesh", + "primitives" : [ + { + "attributes" : { + "POSITION" : 14, + "NORMAL" : 15, + "TEXCOORD_0" : 16 + }, + "indices" : 17, + "material" : 4 + } + ] + }, + { + "name" : "EmissionUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 18, + "NORMAL" : 19, + "TEXCOORD_0" : 20, + "TEXCOORD_1" : 21 + }, + "indices" : 4, + "material" : 5 + } + ] + }, + { + "name" : "EmissionUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 22, + "NORMAL" : 23, + "TEXCOORD_0" : 24, + "TEXCOORD_1" : 25 + }, + "indices" : 4, + "material" : 6 + } + ] + }, + { + "name" : "EmissionSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 26, + "NORMAL" : 27, + "TEXCOORD_0" : 28 + }, + "indices" : 4, + "material" : 7 + } + ] + }, + { + "name" : "NormalUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 29, + "NORMAL" : 30, + "TEXCOORD_0" : 31, + "TEXCOORD_1" : 32 + }, + "indices" : 4, + "material" : 8 + } + ] + }, + { + "name" : "NormalUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 33, + "NORMAL" : 34, + "TEXCOORD_0" : 35, + "TEXCOORD_1" : 36 + }, + "indices" : 4, + "material" : 9 + } + ] + }, + { + "name" : "NormalSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 37, + "NORMAL" : 38, + "TEXCOORD_0" : 39 + }, + "indices" : 4, + "material" : 10 + } + ] + }, + { + "name" : "MetalRoughUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 40, + "NORMAL" : 41, + "TEXCOORD_0" : 42, + "TEXCOORD_1" : 43 + }, + "indices" : 4, + "material" : 11 + } + ] + }, + { + "name" : "MetalRoughUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 44, + "NORMAL" : 45, + "TEXCOORD_0" : 46, + "TEXCOORD_1" : 47 + }, + "indices" : 4, + "material" : 12 + } + ] + }, + { + "name" : "MetalRoughSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 48, + "NORMAL" : 49, + "TEXCOORD_0" : 50 + }, + "indices" : 4, + "material" : 13 + } + ] + }, + { + "name" : "OcclusionUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 51, + "NORMAL" : 52, + "TEXCOORD_0" : 53, + "TEXCOORD_1" : 54 + }, + "indices" : 4, + "material" : 14 + } + ] + }, + { + "name" : "OcclusionUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 55, + "NORMAL" : 56, + "TEXCOORD_0" : 57, + "TEXCOORD_1" : 58 + }, + "indices" : 4, + "material" : 15 + } + ] + }, + { + "name" : "OcclusionSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 59, + "NORMAL" : 60, + "TEXCOORD_0" : 61 + }, + "indices" : 4, + "material" : 16 + } + ] + }, + { + "name" : "UnlitUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 62, + "NORMAL" : 63, + "TEXCOORD_0" : 64, + "TEXCOORD_1" : 65 + }, + "indices" : 4, + "material" : 17 + } + ] + }, + { + "name" : "UnlitUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 66, + "NORMAL" : 67, + "TEXCOORD_0" : 68, + "TEXCOORD_1" : 69 + }, + "indices" : 4, + "material" : 18 + } + ] + }, + { + "name" : "UnlitSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 70, + "NORMAL" : 71, + "TEXCOORD_0" : 72 + }, + "indices" : 4, + "material" : 19 + } + ] + }, + { + "name" : "ClearcoatUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 73, + "NORMAL" : 74, + "TEXCOORD_0" : 75, + "TEXCOORD_1" : 76 + }, + "indices" : 77, + "material" : 20 + } + ] + }, + { + "name" : "ClearcoatUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 78, + "NORMAL" : 79, + "TEXCOORD_0" : 80, + "TEXCOORD_1" : 81 + }, + "indices" : 77, + "material" : 21 + } + ] + }, + { + "name" : "ClearcoatSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 82, + "NORMAL" : 83, + "TEXCOORD_0" : 84 + }, + "indices" : 77, + "material" : 22 + } + ] + }, + { + "name" : "ClearcoarRoughUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 85, + "NORMAL" : 86, + "TEXCOORD_0" : 87, + "TEXCOORD_1" : 88 + }, + "indices" : 77, + "material" : 23 + } + ] + }, + { + "name" : "ClearcoatRoughUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 89, + "NORMAL" : 90, + "TEXCOORD_0" : 91, + "TEXCOORD_1" : 92 + }, + "indices" : 77, + "material" : 24 + } + ] + }, + { + "name" : "ClearcoatRoughSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 93, + "NORMAL" : 94, + "TEXCOORD_0" : 95 + }, + "indices" : 77, + "material" : 25 + } + ] + }, + { + "name" : "ClearcoatNormalUV0", + "primitives" : [ + { + "attributes" : { + "POSITION" : 96, + "NORMAL" : 97, + "TEXCOORD_0" : 98, + "TEXCOORD_1" : 99 + }, + "indices" : 4, + "material" : 26 + } + ] + }, + { + "name" : "ClearcoatNormalUV1", + "primitives" : [ + { + "attributes" : { + "POSITION" : 100, + "NORMAL" : 101, + "TEXCOORD_0" : 102, + "TEXCOORD_1" : 103 + }, + "indices" : 4, + "material" : 27 + } + ] + }, + { + "name" : "ClearcoatNormalSample", + "primitives" : [ + { + "attributes" : { + "POSITION" : 104, + "NORMAL" : 105, + "TEXCOORD_0" : 106 + }, + "indices" : 4, + "material" : 28 + } + ] + } + ], + "textures" : [ + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 1 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 2 + }, + { + "source" : 2 + }, + { + "source" : 2 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 0 + }, + { + "source" : 3 + }, + { + "source" : 3 + }, + { + "source" : 3 + }, + { + "source" : 2 + }, + { + "source" : 2 + }, + { + "source" : 2 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "TestMap", + "uri" : "TestMap.png" + }, + { + "mimeType" : "image/png", + "name" : "TTMT_Labels", + "uri" : "TTMT_Labels.png" + }, + { + "mimeType" : "image/png", + "name" : "TestMap_Normal", + "uri" : "TestMap_Normal.png" + }, + { + "mimeType" : "image/png", + "name" : "TestMap", + "uri" : "TestMap-1.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 3, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 4, + "componentType" : 5123, + "count" : 6, + "type" : "SCALAR" + }, + { + "bufferView" : 5, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 6, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 7, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 8, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 9, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 10, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 11, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 12, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.9999999403953552, + 1, + 0 + ], + "min" : [ + -0.9999999403953552, + -1.399999976158142, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 13, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 14, + "componentType" : 5126, + "count" : 48, + "max" : [ + 0.8163908123970032, + 0.9983971118927002, + 0 + ], + "min" : [ + -0.9999999403953552, + -1.3177802562713623, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 15, + "componentType" : 5126, + "count" : 48, + "type" : "VEC3" + }, + { + "bufferView" : 16, + "componentType" : 5126, + "count" : 48, + "type" : "VEC2" + }, + { + "bufferView" : 17, + "componentType" : 5123, + "count" : 72, + "type" : "SCALAR" + }, + { + "bufferView" : 18, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 19, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 20, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 21, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 22, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 23, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 24, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 25, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 26, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 27, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 28, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 29, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 30, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 31, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 32, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 33, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 34, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 35, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 36, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 37, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 38, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 39, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 40, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 41, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 42, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 43, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 44, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 45, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 46, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 47, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 48, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 49, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 50, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 51, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 52, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 53, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 54, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 55, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 56, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 57, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 58, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 59, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 60, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 61, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 62, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 63, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 64, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 65, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 66, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 67, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 68, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 69, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 70, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 71, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 72, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 73, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.035051580518484116 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266523532569408 + ], + "type" : "VEC3" + }, + { + "bufferView" : 74, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 75, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 76, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 77, + "componentType" : 5123, + "count" : 1944, + "type" : "SCALAR" + }, + { + "bufferView" : 78, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.03505159914493561 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266500249505043 + ], + "type" : "VEC3" + }, + { + "bufferView" : 79, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 80, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 81, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 82, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.03505159914493561 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266500249505043 + ], + "type" : "VEC3" + }, + { + "bufferView" : 83, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 84, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 85, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.03505159914493561 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266500249505043 + ], + "type" : "VEC3" + }, + { + "bufferView" : 86, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 87, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 88, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 89, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.03505159914493561 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266500249505043 + ], + "type" : "VEC3" + }, + { + "bufferView" : 90, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 91, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 92, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 93, + "componentType" : 5126, + "count" : 361, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0.03505159914493561 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + -0.014266500249505043 + ], + "type" : "VEC3" + }, + { + "bufferView" : 94, + "componentType" : 5126, + "count" : 361, + "type" : "VEC3" + }, + { + "bufferView" : 95, + "componentType" : 5126, + "count" : 361, + "type" : "VEC2" + }, + { + "bufferView" : 96, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 97, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 98, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 99, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 100, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 101, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 102, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 103, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 104, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.10000002384185791, + 0.10000002384185791, + 0 + ], + "min" : [ + -0.10000002384185791, + -0.10000002384185791, + 0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 105, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 106, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 0 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 48 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 96 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 128 + }, + { + "buffer" : 0, + "byteLength" : 12, + "byteOffset" : 160 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 172 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 220 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 268 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 300 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 332 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 380 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 428 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 460 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 508 + }, + { + "buffer" : 0, + "byteLength" : 576, + "byteOffset" : 556 + }, + { + "buffer" : 0, + "byteLength" : 576, + "byteOffset" : 1132 + }, + { + "buffer" : 0, + "byteLength" : 384, + "byteOffset" : 1708 + }, + { + "buffer" : 0, + "byteLength" : 144, + "byteOffset" : 2092 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2236 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2284 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2332 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2364 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2396 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2444 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2492 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2524 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2556 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2604 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2652 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2684 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2732 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2780 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2812 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2844 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 2892 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2940 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 2972 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3004 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3052 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3100 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3132 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3180 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3228 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3260 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3292 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3340 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3388 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3420 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3452 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3500 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3548 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3580 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3628 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3676 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3708 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3740 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3788 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3836 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3868 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3900 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 3948 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 3996 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4028 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4076 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 4124 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 4156 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4188 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4236 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 4284 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 4316 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4348 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 4396 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 4444 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 4476 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 8808 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 13140 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 16028 + }, + { + "buffer" : 0, + "byteLength" : 3888, + "byteOffset" : 18916 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 22804 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 27136 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 31468 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 34356 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 37244 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 41576 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 45908 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 48796 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 53128 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 57460 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 60348 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 63236 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 67568 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 71900 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 74788 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 77676 + }, + { + "buffer" : 0, + "byteLength" : 4332, + "byteOffset" : 82008 + }, + { + "buffer" : 0, + "byteLength" : 2888, + "byteOffset" : 86340 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89228 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89276 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 89324 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 89356 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89388 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89436 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 89484 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 89516 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89548 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 89596 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 89644 + } + ], + "buffers" : [ + { + "byteLength" : 89676, + "uri" : "TextureTransformMultiTest.bin" + } + ] +} diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp index 30ad93f..069941c 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp @@ -538,6 +538,7 @@ int UtcDaliGltfLoaderSuccessShort(void) "MorphPrimitivesTest", "MRendererTest", "SimpleSparseAccessor", + "TextureTransformMultiTest", "AnimatedCube", /** * For the Avocado glTF file and its Assets @@ -944,3 +945,48 @@ int UtcDaliGltfLoaderQuantizedMesh(void) END_TEST; } + +int UtcDaliGltfLoaderTextureTransform(void) +{ + Context ctx; + + auto& resources = ctx.resources; + + /** + * For the Avocado glTF file and its Assets + * Donated by Microsoft for glTF testing + * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized + */ + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AvocadoQuantized.gltf", ctx.loadResult); + + auto& scene = ctx.scene; + DALI_TEST_EQUAL(1u, scene.GetRoots().size()); + DALI_TEST_EQUAL(1u, scene.GetNodeCount()); + + TestApplication app; + + Customization::Choices choices; + for(auto iRoot : scene.GetRoots()) + { + auto resourceRefs = resources.CreateRefCounter(); + scene.CountResourceRefs(iRoot, choices, resourceRefs); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); + } + + auto& materials = resources.mMaterials; + DALI_TEST_EQUAL(1u, materials.size()); + + auto iMaterial = materials.begin(); + auto& md = iMaterial->first; + + DALI_TEST_EQUAL(3u, md.mTextureStages.size()); + + Matrix3 textureTransformGroundTruth(0.000238f, 0.0f, 0.0f, 0.0f, 0.000242f, 0.0f, 0.00678f, 0.002982f, 1.0f); + DALI_TEST_EQUALS(md.mTextureStages[0].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION); + DALI_TEST_EQUALS(md.mTextureStages[1].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION); + DALI_TEST_EQUALS(md.mTextureStages[2].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION); + + END_TEST; +} diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp index e3bc2d2..38eb937 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp @@ -265,6 +265,13 @@ int UtcDaliMaterialCheckUniform(void) DALI_TEST_EQUALS(FaceCullingMode::BACK, renderer.GetProperty(Dali::Renderer::Property::FACE_CULLING_MODE), TEST_LOCATION); DALI_TEST_EQUALS(DepthTestMode::ON, renderer.GetProperty(Dali::Renderer::Property::DEPTH_TEST_MODE), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uBaseColorTextureTransformAvailable")), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uNormalTextureTransformAvailable")), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uNormalRoughnessTextureTransformAvailable")), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uMetalRoughnessTextureTransformAvailable")), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uOcclusionTextureTransformAvailable")), TEST_LOCATION); + DALI_TEST_EQUALS(0.0f, renderer.GetProperty(renderer.GetPropertyIndex("uEmissiveTextureTransformAvailable")), TEST_LOCATION); + END_TEST; } diff --git a/dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag b/dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag index db3c146..a77b5fa 100644 --- a/dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag +++ b/dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag @@ -40,26 +40,42 @@ uniform lowp float uDielectricSpecular; #ifdef THREE_TEX #ifdef BASECOLOR_TEX uniform sampler2D sAlbedoAlpha; +uniform float uBaseColorTextureTransformAvailable; +uniform mat3 uBaseColorTextureTransform; #endif // BASECOLOR_TEX #ifdef METALLIC_ROUGHNESS_TEX uniform sampler2D sMetalRoughness; +uniform float uMetalRoughnessTextureTransformAvailable; +uniform mat3 uMetalRoughnessTextureTransform; #endif // METALLIC_ROUGHNESS_TEX #ifdef NORMAL_TEX uniform sampler2D sNormal; +uniform float uNormalTextureTransformAvailable; +uniform mat3 uNormalTextureTransform; uniform float uNormalScale; #endif // NORMAL_TEX #else // THREE_TEX uniform sampler2D sAlbedoMetal; +uniform float uBaseColorTextureTransformAvailable; +uniform mat3 uBaseColorTextureTransform; uniform sampler2D sNormalRoughness; +uniform float uNormalRoughnessTextureTransformAvailable; +uniform mat3 uNormalRoughnessTextureTransform; #endif + + #ifdef OCCLUSION uniform sampler2D sOcclusion; +uniform float uOcclusionTextureTransformAvailable; +uniform mat3 uOcclusionTextureTransform; uniform float uOcclusionStrength; #endif #ifdef EMISSIVE_TEXTURE uniform sampler2D sEmissive; +uniform float uEmissiveTextureTransformAvailable; +uniform mat3 uEmissiveTextureTransform; #endif uniform vec3 uEmissiveFactor; @@ -127,6 +143,11 @@ vec3 linear(vec3 color) return pow(color, vec3(2.2)); } +vec2 computeTextureTransform(vec2 texCoord, mat3 textureTransform) +{ + return vec2(textureTransform * vec3(texCoord, 1.0)); +} + void main() { // Metallic and Roughness material properties are packed together @@ -142,29 +163,34 @@ void main() #ifdef THREE_TEX // The albedo may be defined from a base texture or a flat color #ifdef BASECOLOR_TEX - lowp vec4 baseColor = texture(sAlbedoAlpha, vUV); + mediump vec2 baseColorTexCoords = mix(vUV, computeTextureTransform(vUV, uBaseColorTextureTransform), uBaseColorTextureTransformAvailable); + lowp vec4 baseColor = texture(sAlbedoAlpha, baseColorTexCoords); baseColor = vColor * vec4(linear(baseColor.rgb), baseColor.w) * uColorFactor; #else // BASECOLOR_TEX lowp vec4 baseColor = vColor * uColorFactor; #endif // BASECOLOR_TEX #ifdef METALLIC_ROUGHNESS_TEX - lowp vec4 metrou = texture(sMetalRoughness, vUV); + mediump vec2 metalRoughnessTexCoords = mix(vUV, computeTextureTransform(vUV, uMetalRoughnessTextureTransform), uMetalRoughnessTextureTransformAvailable); + lowp vec4 metrou = texture(sMetalRoughness, metalRoughnessTexCoords); metallic = metrou.METALLIC * metallic; perceptualRoughness = metrou.ROUGHNESS * perceptualRoughness; #endif // METALLIC_ROUGHNESS_TEX #ifdef NORMAL_TEX - n = texture(sNormal, vUV).rgb; + mediump vec2 normalTexCoords = mix(vUV, computeTextureTransform(vUV, uNormalTextureTransform), uNormalTextureTransformAvailable); + n = texture(sNormal, normalTexCoords).rgb; n = normalize(vTBN * ((2.0 * n - 1.0) * vec3(uNormalScale, uNormalScale, 1.0))); #endif // NORMAL_TEX #else // THREE_TEX - vec4 albedoMetal = texture(sAlbedoMetal, vUV); + mediump vec2 baseColorTexCoords = mix(vUV, computeTextureTransform(vUV, uBaseColorTextureTransform), uBaseColorTextureTransformAvailable); + vec4 albedoMetal = texture(sAlbedoMetal, baseColorTexCoords); lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * vColor * uColorFactor; metallic = albedoMetal.METALLIC * metallic; - vec4 normalRoughness = texture(sNormalRoughness, vUV); + mediump vec2 normalRoughnessTexCoords = mix(vUV, computeTextureTransform(vUV, uNormalRoughnessTextureTransform), uNormalRoughnessTextureTransformAvailable); + vec4 normalRoughness = texture(sNormalRoughness, normalRoughnessTexCoords); perceptualRoughness = normalRoughness.ROUGHNESS * perceptualRoughness; n = normalRoughness.rgb; @@ -290,12 +316,14 @@ void main() } #ifdef OCCLUSION - lowp float ao = texture(sOcclusion, vUV).r; + mediump vec2 occlusionTexCoords = mix(vUV, computeTextureTransform(vUV, uOcclusionTextureTransform), uOcclusionTextureTransformAvailable); + lowp float ao = texture(sOcclusion, occlusionTexCoords).r; color = mix(color, color * ao, uOcclusionStrength); #endif // OCCLUSION #ifdef EMISSIVE_TEXTURE - lowp vec3 emissive = linear(texture(sEmissive, vUV).rgb) * uEmissiveFactor; + mediump vec2 emissiveTexCoords = mix(vUV, computeTextureTransform(vUV, uEmissiveTextureTransform), uEmissiveTextureTransformAvailable); + lowp vec3 emissive = linear(texture(sEmissive, emissiveTexCoords).rgb) * uEmissiveFactor; #else lowp vec3 emissive = uEmissiveFactor; #endif // EMISSIVE_TEXTURE diff --git a/dali-scene3d/internal/loader/gltf2-asset.h b/dali-scene3d/internal/loader/gltf2-asset.h index e90cf38..16c7cd8 100644 --- a/dali-scene3d/internal/loader/gltf2-asset.h +++ b/dali-scene3d/internal/loader/gltf2-asset.h @@ -20,7 +20,9 @@ // EXTERNAL INCLUDES #include #include +#include #include +#include #include #include #include @@ -375,6 +377,39 @@ struct Texture Ref mSampler; }; +struct TextureTransform +{ + float mRotation = 0.0f; + Dali::Vector2 mUvOffset = Dali::Vector2::ZERO; + Dali::Vector2 mUvScale = Dali::Vector2::ONE; + uint32_t mTexCoord = 0u; + + operator bool() const + { + return !Dali::EqualsZero(mRotation) || mUvOffset != Dali::Vector2::ZERO || mUvScale != Dali::Vector2::ONE || mTexCoord != 0u; + } + + const Dali::Matrix3 GetTransform() const + { + // See: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform + Dali::Matrix3 translation = Dali::Matrix3(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, mUvOffset.x, mUvOffset.y, 1.0f); + Dali::Matrix3 rotation = Dali::Matrix3(cos(-mRotation), sin(-mRotation), 0.0f, -sin(-mRotation), cos(-mRotation), 0.0f, 0.0f, 0.0f, 1.0f); + Dali::Matrix3 scale = Dali::Matrix3(mUvScale.x, 0.0f, 0.0f, 0.0f, mUvScale.y, 0.0f, 0.0f, 0.0f, 1.0f); + + return translation * rotation * scale; + } +}; + +struct TextureExtensions +{ + TextureTransform mTextureTransform; + + operator bool() const + { + return mTextureTransform; + } +}; + struct TextureInfo { Ref mTexture; @@ -382,9 +417,11 @@ struct TextureInfo float mScale = 1.f; float mStrength = 1.f; + TextureExtensions mTextureExtensions; + operator bool() const { - return !!mTexture; + return mTexture; } }; diff --git a/dali-scene3d/internal/loader/gltf2-util.cpp b/dali-scene3d/internal/loader/gltf2-util.cpp index c4e492f..7979786 100644 --- a/dali-scene3d/internal/loader/gltf2-util.cpp +++ b/dali-scene3d/internal/loader/gltf2-util.cpp @@ -49,12 +49,12 @@ static const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{ Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two. static const Dali::Scripting::StringEnum EXTENSION_STRING_TABLE[] = -{ - {"NONE", gltf2::ExtensionFlags::NONE}, - {"KHR_mesh_quantization", gltf2::ExtensionFlags::KHR_MESH_QUANTIZATION}, - {"KHR_texture_transform", gltf2::ExtensionFlags::KHR_TEXTURE_TRANSFORM}, - {"KHR_materials_ior", gltf2::ExtensionFlags::KHR_MATERIALS_IOR}, - {"KHR_materials_specular", gltf2::ExtensionFlags::KHR_MATERIALS_SPECULAR}, + { + {"NONE", gltf2::ExtensionFlags::NONE}, + {"KHR_mesh_quantization", gltf2::ExtensionFlags::KHR_MESH_QUANTIZATION}, + {"KHR_texture_transform", gltf2::ExtensionFlags::KHR_TEXTURE_TRANSFORM}, + {"KHR_materials_ior", gltf2::ExtensionFlags::KHR_MATERIALS_IOR}, + {"KHR_materials_specular", gltf2::ExtensionFlags::KHR_MATERIALS_SPECULAR}, }; static const unsigned int EXTENSION_STRING_TABLE_COUNT = sizeof(EXTENSION_STRING_TABLE) / sizeof(EXTENSION_STRING_TABLE[0]); @@ -173,13 +173,31 @@ const json::Reader& GetTextureReader() return TEXURE_READER; } +const json::Reader& GetTextureTransformReader() +{ + static const auto TEXURE_TRANSFORM_READER = std::move(json::Reader() + .Register(*json::MakeProperty("rotation", json::Read::Number, &gltf2::TextureTransform::mRotation)) + .Register(*json::MakeProperty("offset", gltf2::ReadDaliVector, &gltf2::TextureTransform::mUvOffset)) + .Register(*json::MakeProperty("scale", gltf2::ReadDaliVector, &gltf2::TextureTransform::mUvScale)) + .Register(*json::MakeProperty("texCoord", json::Read::Number, &gltf2::TextureTransform::mTexCoord))); + return TEXURE_TRANSFORM_READER; +} + +const json::Reader& GetTextureExtensionsReader() +{ + static const auto TEXTURE_EXTENSION_READER = std::move(json::Reader() + .Register(*json::MakeProperty("KHR_texture_transform", json::ObjectReader::Read, &gltf2::TextureExtensions::mTextureTransform))); + return TEXTURE_EXTENSION_READER; +} + const json::Reader& GetTextureInfoReader() { static const auto TEXURE_INFO_READER = std::move(json::Reader() .Register(*json::MakeProperty("index", gltf2::RefReader::Read, &gltf2::TextureInfo::mTexture)) .Register(*json::MakeProperty("texCoord", json::Read::Number, &gltf2::TextureInfo::mTexCoord)) .Register(*json::MakeProperty("scale", json::Read::Number, &gltf2::TextureInfo::mScale)) - .Register(*json::MakeProperty("strength", json::Read::Number, &gltf2::TextureInfo::mStrength))); + .Register(*json::MakeProperty("strength", json::Read::Number, &gltf2::TextureInfo::mStrength)) + .Register(*json::MakeProperty("extensions", json::ObjectReader::Read, &gltf2::TextureInfo::mTextureExtensions))); return TEXURE_INFO_READER; } @@ -588,18 +606,23 @@ TextureDefinition ConvertTextureInfo(const gltf2::TextureInfo& textureInfo, Conv std::vector dataBuffer; dataBuffer.resize(textureInfo.mTexture->mSource->mBufferView->mByteLength); stream.read(reinterpret_cast(dataBuffer.data()), static_cast(static_cast(textureInfo.mTexture->mSource->mBufferView->mByteLength))); - return TextureDefinition{std::move(dataBuffer), ConvertSampler(textureInfo.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; + return TextureDefinition{std::move(dataBuffer), ConvertSampler(textureInfo.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode, textureInfo.mTextureExtensions.mTextureTransform.GetTransform()}; } return TextureDefinition(); } else { - return TextureDefinition{uri, ConvertSampler(textureInfo.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; + return TextureDefinition{uri, ConvertSampler(textureInfo.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode, textureInfo.mTextureExtensions.mTextureTransform.GetTransform()}; } } void AddTextureStage(uint32_t semantic, MaterialDefinition& materialDefinition, gltf2::TextureInfo textureInfo, const Dali::Scene3D::Loader::ImageMetadata& metaData, ConversionContext& context) { + // Overrides the textureInfo texCoord value if KHR_texture_transform extension is supported and texCoord value is supplied. + if(textureInfo.mTextureExtensions && textureInfo.mTexCoord != textureInfo.mTextureExtensions.mTextureTransform.mTexCoord && textureInfo.mTextureExtensions.mTextureTransform.mTexCoord != 0u) + { + textureInfo.mTexCoord = textureInfo.mTextureExtensions.mTextureTransform.mTexCoord; + } materialDefinition.mTextureStages.push_back({semantic, ConvertTextureInfo(textureInfo, context, metaData)}); materialDefinition.mFlags |= semantic; } @@ -767,19 +790,20 @@ MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gltf2::Accessor& acc return MeshDefinition::Accessor{ std::move(MeshDefinition::Blob{bufferViewOffset + accessor.mByteOffset, - accessor.GetBytesLength(), - static_cast(bufferViewStride), - static_cast(accessor.GetElementSizeBytes()), - accessor.mMin, - accessor.mMax}), - std::move(sparseBlob), - accessor.mBufferView ? accessor.mBufferView->mBuffer.GetIndex() : 0, - accessor.mNormalized}; + accessor.GetBytesLength(), + static_cast(bufferViewStride), + static_cast(accessor.GetElementSizeBytes()), + accessor.mMin, + accessor.mMax}), + std::move(sparseBlob), + accessor.mBufferView ? accessor.mBufferView->mBuffer.GetIndex() : 0, + accessor.mNormalized}; } MeshDefinition::Accessor* GetAccessorFromAttribute(gltf2::Attribute::HashType attributeHash, - MeshDefinition& meshDefinition, - bool& needNormals, bool& needTangents) + MeshDefinition& meshDefinition, + bool& needNormals, + bool& needTangents) { MeshDefinition::Accessor* accessorDest{nullptr}; @@ -841,10 +865,10 @@ MeshDefinition::Accessor* GetAccessorFromAttribute(gltf2::Attribute::HashType at return accessorDest; } -void SetFlagsFromComponentType(const gltf2::Accessor& accessor, +void SetFlagsFromComponentType(const gltf2::Accessor& accessor, gltf2::Attribute::HashType attributeHash, - MeshDefinition& meshDefinition, - bool isQuantized) + MeshDefinition& meshDefinition, + bool isQuantized) { switch(gltf2::Attribute::TypeFromHash(attributeHash)) { @@ -1554,6 +1578,8 @@ void SetObjectReaders() json::SetObjectReader(GetImageReader()); json::SetObjectReader(GetSamplerReader()); json::SetObjectReader(GetTextureReader()); + json::SetObjectReader(GetTextureTransformReader()); + json::SetObjectReader(GetTextureExtensionsReader()); json::SetObjectReader(GetTextureInfoReader()); json::SetObjectReader(GetMaterialPbrReader()); json::SetObjectReader(GetMaterialSpecularReader()); diff --git a/dali-scene3d/internal/model-components/material-impl.cpp b/dali-scene3d/internal/model-components/material-impl.cpp index 69a1a53..0e58ce5 100644 --- a/dali-scene3d/internal/model-components/material-impl.cpp +++ b/dali-scene3d/internal/model-components/material-impl.cpp @@ -679,6 +679,14 @@ void Material::SetRendererUniform(Dali::Renderer renderer) renderer.RegisterProperty("uSpecularFactor", mTextureInformations[TextureIndex::SPECULAR].mFactor.x); renderer.RegisterProperty("uSpecularColorFactor", Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor)); + // No requirement to use texture transform for runtime generated models. + renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uNormalTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f); + float opaque = mIsOpaque ? 1.0f : 0.0f; float mask = mIsMask ? 1.0f : 0.0f; renderer.RegisterProperty("uOpaque", opaque); @@ -752,8 +760,7 @@ void Material::NotifyObserver() mObserverNotifying = false; // Resolve observer queue during notify - mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) - { return !e.second; }), + mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) { return !e.second; }), mObservers.end()); } } diff --git a/dali-scene3d/internal/model-components/material-impl.h b/dali-scene3d/internal/model-components/material-impl.h index fe45dee..a41b8b5 100644 --- a/dali-scene3d/internal/model-components/material-impl.h +++ b/dali-scene3d/internal/model-components/material-impl.h @@ -73,6 +73,7 @@ public: uint32_t mLoadingTaskId{0u}; uint32_t mSemantic; Scene3D::Loader::ShaderOption::Type mShaderOptionType; + Matrix3 mTransform{Scene3D::Loader::TextureDefinition::DEFAULT_TRANSFORM}; }; using TextureInformationContainer = std::vector; @@ -278,10 +279,10 @@ private: private: // Delete copy & move operator - Material(const Material&) = delete; - Material(Material&&) = delete; + Material(const Material&) = delete; + Material(Material&&) = delete; Material& operator=(const Material& rhs) = delete; - Material& operator=(Material&& rhs) = delete; + Material& operator=(Material&& rhs) = delete; private: ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed. diff --git a/dali-scene3d/public-api/loader/material-definition.cpp b/dali-scene3d/public-api/loader/material-definition.cpp index 0d3cb20..2e6ef5f 100644 --- a/dali-scene3d/public-api/loader/material-definition.cpp +++ b/dali-scene3d/public-api/loader/material-definition.cpp @@ -33,6 +33,8 @@ namespace Scene3D { namespace Loader { +const Matrix3 TextureDefinition::DEFAULT_TRANSFORM = Matrix3(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); + namespace { constexpr SamplerFlags::Type FILTER_MODES_FROM_DALI[]{ @@ -152,27 +154,30 @@ Sampler SamplerFlags::MakeSampler(Type flags) return sampler; } -TextureDefinition::TextureDefinition(const std::string& imageUri, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode) +TextureDefinition::TextureDefinition(const std::string& imageUri, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode, Matrix3 transform) : mImageUri(imageUri), mSamplerFlags(samplerFlags), mMinImageDimensions(minImageDimensions), - mSamplingMode(samplingMode) + mSamplingMode(samplingMode), + mTransform(transform) { } -TextureDefinition::TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode) +TextureDefinition::TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode, Matrix3 transform) : mImageUri(std::move(imageUri)), mSamplerFlags(samplerFlags), mMinImageDimensions(minImageDimensions), - mSamplingMode(samplingMode) + mSamplingMode(samplingMode), + mTransform(transform) { } -TextureDefinition::TextureDefinition(std::vector&& textureBuffer, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode) +TextureDefinition::TextureDefinition(std::vector&& textureBuffer, SamplerFlags::Type samplerFlags, ImageDimensions minImageDimensions, SamplingMode::Type samplingMode, Matrix3 transform) : mImageUri(), mSamplerFlags(samplerFlags), mMinImageDimensions(minImageDimensions), mSamplingMode(samplingMode), + mTransform(transform), mTextureBuffer(std::move(textureBuffer)) { } diff --git a/dali-scene3d/public-api/loader/material-definition.h b/dali-scene3d/public-api/loader/material-definition.h index 43dabc1..a995d69 100644 --- a/dali-scene3d/public-api/loader/material-definition.h +++ b/dali-scene3d/public-api/loader/material-definition.h @@ -111,16 +111,19 @@ struct DALI_SCENE3D_API SamplerFlags */ struct DALI_SCENE3D_API TextureDefinition { + static const Matrix3 DEFAULT_TRANSFORM; + std::string mImageUri; // When the texture is loaded from embedded resources, this URI is used as a data stream. std::string mDirectoryPath; SamplerFlags::Type mSamplerFlags; ImageDimensions mMinImageDimensions; SamplingMode::Type mSamplingMode; + Matrix3 mTransform{DEFAULT_TRANSFORM}; // Texture transform std::vector mTextureBuffer; - TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR); - TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR); - TextureDefinition(std::vector&& textureBuffer, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR); + TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM); + TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM); + TextureDefinition(std::vector&& textureBuffer, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM); }; /** diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index 56e63af..218969b 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -350,6 +350,66 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit renderer.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength); } + renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uNormalTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f); + renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f); + + auto iTexture = matDef.mTextureStages.begin(); + auto checkStage = [&](uint32_t flags) { + return iTexture != matDef.mTextureStages.end() && MaskMatch(iTexture->mSemantic, flags); + }; + + if(checkStage(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC)) + { + renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + + if(checkStage(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS)) + { + renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uNormalRoughnessTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + } + else if(checkStage(MaterialDefinition::ALBEDO)) + { + renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + + if(checkStage(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS)) + { + renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uMetalRoughnessTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + + if(checkStage(MaterialDefinition::NORMAL)) + { + renderer.RegisterProperty("uNormalTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uNormalTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + + if(checkStage(MaterialDefinition::OCCLUSION)) + { + renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uOcclusionTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + + if(checkStage(MaterialDefinition::EMISSIVE)) + { + renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 1.0f); + renderer.RegisterProperty("uEmissiveTextureTransform", iTexture->mTexture.mTransform); + ++iTexture; + } + float opaque = matDef.mIsOpaque ? 1.0f : 0.0f; float mask = matDef.mIsMask ? 1.0f : 0.0f; float alphaCutoff = matDef.GetAlphaCutoff(); @@ -378,9 +438,10 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit Internal::Material::TextureInformation textureInformation; if(matDef.CheckTextures(SEMANTICS[i])) { - textureInformation.mTexture = textures.GetTexture(textureIndex + textureIndexOffset); - textureInformation.mSampler = textures.GetSampler(textureIndex + textureIndexOffset); - textureInformation.mUrl = matDef.mTextureStages[textureIndex].mTexture.mDirectoryPath + matDef.mTextureStages[textureIndex].mTexture.mImageUri; + textureInformation.mTexture = textures.GetTexture(textureIndex + textureIndexOffset); + textureInformation.mSampler = textures.GetSampler(textureIndex + textureIndexOffset); + textureInformation.mUrl = matDef.mTextureStages[textureIndex].mTexture.mDirectoryPath + matDef.mTextureStages[textureIndex].mTexture.mImageUri; + textureInformation.mTransform = matDef.mTextureStages[textureIndex].mTexture.mTransform; textureIndex++; } textureInformation.mFactor = GetTextureFactor(matDef, SEMANTICS[i]);