From 58ce7e9b41bf56a6acdb7b8e2d847b7d4d16c828 Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Thu, 28 Nov 2024 11:20:07 -0600 Subject: [PATCH] Updated goldens. --- .../jenny/output/0000CE08.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000CF48.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D128.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D4CC.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D6AC.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D74C.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D7EC.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000D88C.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000DA6C.fragment.glsl | 17 ++++++++++++++-- .../jenny/output/0000DBAC.fragment.glsl | 17 ++++++++++++++-- .../goldens/chibi_robo/jenny/output/jenny.glb | Bin 7474868 -> 7475464 bytes .../PlMr/output/00008F5C.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/0000901C.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/000090DC.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/000095D0.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/00009B10.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/00009F90.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/0000A110.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/0000A650.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/0000A710.fragment.glsl | 17 ++++++++++++++-- .../PlMr/output/PlMrNr.glb | Bin 14657676 -> 14658204 bytes .../PlZd/output/00008E30.fragment.glsl | 17 ++++++++++++++-- .../PlZd/output/PlZdNr.glb | Bin 27358076 -> 27358156 bytes .../TyAndruf/output/0002CD14.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002D1E8.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002D7B4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002D854.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002D8F4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002D994.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002DD54.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002DDF4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002DE94.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002DFD4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E074.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E114.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E1B4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E394.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E574.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E614.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E6B4.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/0002E754.fragment.glsl | 17 ++++++++++++++-- .../TyAndruf/output/TyAndruf.glb | Bin 549972 -> 551164 bytes .../TyBField/output/0000B5F8.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000B6B8.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000B778.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000B818.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000B904.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000BCD4.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000BD74.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000BEB4.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000C068.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C1A8.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000C248.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000C3A8.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C468.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C508.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000C5F4.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C694.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000C7A8.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C868.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C928.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000C9C8.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000CAB4.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000CB54.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000CC68.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000CD28.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000CDE8.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000CE88.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000CF74.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/0000D014.fragment.glsl | 17 ++++++++++++++-- .../TyBField/output/0000D128.fragment.glsl | 19 +++++++++++++++--- .../TyBField/output/TyBField.glb | Bin 408188 -> 409932 bytes .../TyDaisy/output/000489D8.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/00048BB8.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/00048C58.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/00049018.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/000490B8.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/00049338.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/000495B8.fragment.glsl | 17 ++++++++++++++-- .../TyDaisy/output/TyDaisy.glb | Bin 859524 -> 859904 bytes .../TyGmCube/output/00006684.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/000067D4.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/00007464.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/00007504.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/000075A4.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/00007644.fragment.glsl | 17 ++++++++++++++-- .../TyGmCube/output/TyGmCube.glb | Bin 443780 -> 444108 bytes .../TyGwfeld/output/00005614.fragment.glsl | 17 ++++++++++++++-- .../TyGwfeld/output/TyGwfeld.glb | Bin 218768 -> 218832 bytes 89 files changed, 1231 insertions(+), 178 deletions(-) diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CE08.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CE08.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CE08.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CE08.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CF48.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CF48.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CF48.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000CF48.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D128.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D128.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D128.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D128.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D4CC.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D4CC.fragment.glsl index d68b61342..27fed7e18 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D4CC.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D4CC.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D6AC.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D6AC.fragment.glsl index d68b61342..27fed7e18 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D6AC.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D6AC.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D74C.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D74C.fragment.glsl index d68b61342..27fed7e18 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D74C.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D74C.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D7EC.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D7EC.fragment.glsl index d68b61342..27fed7e18 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D7EC.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D7EC.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D88C.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D88C.fragment.glsl index d68b61342..27fed7e18 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D88C.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000D88C.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(1,0.20000000298023224,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DA6C.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DA6C.fragment.glsl index 2b4a20e47..3d9d2ec8e 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DA6C.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DA6C.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(0,0.800000011920929,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(0,0.800000011920929,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DBAC.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DBAC.fragment.glsl index 2b4a20e47..3d9d2ec8e 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DBAC.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/0000DBAC.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec4 vertexColor0; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vec3(0,0.800000011920929,0)*vertexColor0.rgb*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*vec3(0,0.800000011920929,0)*vertexColor0.rgb*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/jenny.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/chibi_robo/jenny/output/jenny.glb index 0dd5749fcfc8411f62d86a41fa6f2421ed67f371..0d9196aa7f535abdcf1abf4adeabdc56df80ac1d 100644 GIT binary patch delta 12375 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 diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00008F5C.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00008F5C.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00008F5C.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00008F5C.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000901C.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000901C.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000901C.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000901C.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000090DC.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000090DC.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000090DC.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000090DC.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000095D0.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000095D0.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000095D0.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/000095D0.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009B10.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009B10.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009B10.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009B10.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009F90.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009F90.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009F90.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/00009F90.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A110.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A110.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A110.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A110.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A650.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A650.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A650.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A650.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A710.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A710.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A710.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/0000A710.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/PlMrNr.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlMr/output/PlMrNr.glb index 01e9327a06ec5f0e43352482dcbcf2202976aa68..141ed8c28d63e2812bcff679b05d8fc8819f1d38 100644 GIT binary patch delta 12178 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 G|Nj8v9q5<< delta 11721 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 diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/00008E30.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/00008E30.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/00008E30.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/00008E30.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/PlZdNr.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/PlZd/output/PlZdNr.glb index 69e5d58a822becaac620ed5f028511c1dd69847e..0a6538f5688263d3bc0dddb5d4e1199adaa43abc 100644 GIT binary patch delta 2196 zcmZwFcT|&C9LDj)g`xpP6vQ0|jt~=)upGGeLUAHX1O*upP*Frh{D~9XaYw3M)>b<# zZGWwF+1i#`yQdvm)b4GU9naJD99RGNe$L6gZ|=SCJ@3_vVye9)Cez&P_~G>o219K@ zmGS5n)3G3ndCbU3$%W}fg$wi3lMC}xa|<%^@^ea6)F@g{w7zHq(T1XpM14dXi#8GU z6>TcoOw=UmC+aWST(pH~fM`q6K+#sBtwn=GgGJkjhKRNmZ714Zw1a3z(N3bBMa`mJ zM7xT16YVY$A5ojAT{K+OA?g%$iAIPi^hod740Y5 zUvz+Itmr_|L8602hlmap9VR+lbcE4 zP8FRdI$d;z=uFWB(OII2qDi93qA8-OqO(QQMCXX6i)M(<6`d!Vc|xPobjb24+yF$p&7za!zExJKgxJ!h-3Ld*Tjve0~#jdD;f%0q6n0Og|sREQR$ zMQAZ9LQBw6RE(CP60{txKr2xxT7}BcY9we4Do1P4I zU3PnvGs0mB!$n0!JMGSJTwOt0YIZv2omQva5n+q6IINDyXq!DUBC({zQtjw+sPEI| z?z%(hFuEPxf$l_ip}Wx$bPqa;?nU>ZW9T@#A3cB`L=T}8=wVci9zlTq36)^=rno(y@*~ywdiGZ2EBsLqF2#t=ymi4dK0~c-bU}BchP(3 zee?l3hdx9fp^wog=sdcBK1FrtBD#bwqtDRi=nM2E`U-uGzCquj@6h+?2lONQ30*-y zqhHXk=r{B`x{Cflf1Lj0XFJVvAY-ZQ-4n{6DKz zaPXGZYB74IX7Nk7t`3?Q*&AQ?mklObd%8AgVa5o9D8MMje`WGop+#*+zTB8elD$Yc^vrjV&* z8ktUJkeMWb%p!>-i6oO0l1gTiG%|;zlMFJK%p;j3i_9n4B!}dZJmMw`NIoebg=8UF zL>7}GvV<%p#bg;NAvW;vf gJIGGrA-l+KvWM&?`^bKBfOyG4W6i0QDr0rP-<=!H`~Uy| delta 2183 zcmZ|LcU)C<7{_rgEtqCTR&qJE;aMg2w1q5-0HMC*#y6AcutFB&9j5e*h? zAQ~dtP&8Duk!WMlCZbJ6n~8>rHWv*SjSy`i+ETQYXlv0nqHRUniMAJw6pa#%7VRKv zh{lLoMQx&XQHQ8g)Fm1#8Ydbr+EKKVXo6^>Xp(4W(PYssqFqJ1iFOz5A=*>4muPR% zKB9d^Q$+iT_7@!>I#6_w=wQ(yqC-W8i4GSXAv#iYl;~*DRM9b_V@1SJFIbD%4(FU$KyVGHfaXI1)n{8}l z_>9b%;qj?PwAJo(I$~oDt6{U+U4|>th&F6a2Of@f#o6tK&2Ty0$*Z#*1-J9F&@?n1 z%|J8JEHoRiJ1nfAqH;evfF4GVphwYT=y7xqJ%J9PC(&Va1RX`k&{ODX^b9(Vo<(KoIrKbw z0lkP$pqJ1|RE{dp%jgt(1-*)1L$9MZ(3|Kj^fo$;&Y-jC9C`=6i_W79=sl$9ee?nP z5PgI`MinFT}GdwE9i4{6@7ueM3v|ox{hw3uh7@%8}u#u4tbKhU4(7P^h@puf=H=d>s-lQ6-PHK>vq!#fZzQm8zCjP`s0!STF zm((MHq&^8E77}bKuc&NbDqiI4ALW-6S}ixJgZuo_0~Yt_I+y%BIcXs#e_!MDz@!lG z3kmlp=K?V~dT$a|oRfGn`%>b+6VFB546gFHCtw_JKDga;D|491&y#|Yzi*W#X&43j z&JH?}c;%So{yRMf?=5-oAfC(rzq#@F|89044!BWuv6~-bF-JL)uBHw;d8k=bd6m-~ z#-ggH=fA1)nL&k?^biwhNJ2>?(wHr-BgjZHii{?yWDFTg(#SY6o}`lrWFnbFCX*>7gG?ovB#TTV z)5#1nlguKs$s975WRrPhK3PB(l0{@OSwfbQ9I}ioCo4!U$s_q>C0Rv;tR@9y4OvUp yk@aK)*+@2#Lb90@ku78^DJI*?V82Ub2sPNQtT3l3r>m3;YLeSKPt? diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002CD14.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002CD14.fragment.glsl index acbd6fac9..0115ab46f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002CD14.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002CD14.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -130,7 +143,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D1E8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D1E8.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D1E8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D1E8.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D7B4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D7B4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D7B4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D7B4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D854.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D854.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D854.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D854.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D8F4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D8F4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D8F4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D8F4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D994.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D994.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D994.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002D994.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DD54.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DD54.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DD54.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DD54.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DDF4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DDF4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DDF4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DDF4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DE94.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DE94.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DE94.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DE94.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DFD4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DFD4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DFD4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002DFD4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E074.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E074.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E074.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E074.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E114.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E114.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E114.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E114.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E1B4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E1B4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E1B4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E1B4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E394.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E394.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E394.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E394.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E574.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E574.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E574.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E574.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E614.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E614.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E614.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E614.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E6B4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E6B4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E6B4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E6B4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E754.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E754.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E754.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/0002E754.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/TyAndruf.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyAndruf/output/TyAndruf.glb index 5a83ed7a23735db601e249b1f2d12cdad1d9c27e..1a51f80ece62f4b6be7d705fecd80c5054643e5e 100644 GIT binary patch delta 18547 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 delta 18700 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 DpZ(&U diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B5F8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B5F8.fragment.glsl index f66d15dbe..1cf9b80ee 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B5F8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B5F8.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 sphericalReflectionUv; in vec2 uv0; @@ -8,7 +21,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = texture(texture0, sphericalReflectionUv).rgb; + vec3 colorComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, sphericalReflectionUv)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B6B8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B6B8.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B6B8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B6B8.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B778.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B778.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B778.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B778.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B818.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B818.fragment.glsl index d624d9746..9bf2fa43d 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B818.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B818.fragment.glsl @@ -1,13 +1,26 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B904.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B904.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B904.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000B904.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BCD4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BCD4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BCD4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BCD4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BD74.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BD74.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BD74.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BD74.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BEB4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BEB4.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BEB4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000BEB4.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C068.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C068.fragment.glsl index fe17ac96b..86346c2ec 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C068.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C068.fragment.glsl @@ -1,7 +1,20 @@ #version 430 -uniform sampler2D texture0; -uniform sampler2D texture1; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; +uniform Texture texture1; in vec2 sphericalReflectionUv; in vec2 uv0; @@ -10,7 +23,7 @@ in vec2 uv1; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb*texture(texture1, sphericalReflectionUv).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb*texture(texture1.sampler, transformUv3d(texture1.transform3d, sphericalReflectionUv)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C1A8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C1A8.fragment.glsl index 86f03ad1b..a30c7a5ab 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C1A8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C1A8.fragment.glsl @@ -1,6 +1,19 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 sphericalReflectionUv; in vec4 vertexColor0; @@ -9,7 +22,7 @@ in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*vertexColor0.rgb*vec3(0.5) + texture(texture0, sphericalReflectionUv).rgb*vec3(0.5); + vec3 colorComponent = vec3(2)*vertexColor0.rgb*vec3(0.5) + texture(texture0.sampler, transformUv3d(texture0.transform3d, sphericalReflectionUv)).rgb*vec3(0.5); float alphaComponent = 0.3499999940395355*vertexColor0.a; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C248.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C248.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C248.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C248.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C3A8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C3A8.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C3A8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C3A8.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C468.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C468.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C468.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C468.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C508.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C508.fragment.glsl index d624d9746..9bf2fa43d 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C508.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C508.fragment.glsl @@ -1,13 +1,26 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C5F4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C5F4.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C5F4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C5F4.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C694.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C694.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C694.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C694.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C7A8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C7A8.fragment.glsl index fe17ac96b..86346c2ec 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C7A8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C7A8.fragment.glsl @@ -1,7 +1,20 @@ #version 430 -uniform sampler2D texture0; -uniform sampler2D texture1; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; +uniform Texture texture1; in vec2 sphericalReflectionUv; in vec2 uv0; @@ -10,7 +23,7 @@ in vec2 uv1; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb*texture(texture1, sphericalReflectionUv).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb*texture(texture1.sampler, transformUv3d(texture1.transform3d, sphericalReflectionUv)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C868.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C868.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C868.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C868.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C928.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C928.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C928.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C928.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C9C8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C9C8.fragment.glsl index d624d9746..9bf2fa43d 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C9C8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000C9C8.fragment.glsl @@ -1,13 +1,26 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CAB4.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CAB4.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CAB4.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CAB4.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CB54.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CB54.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CB54.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CB54.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CC68.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CC68.fragment.glsl index fe17ac96b..86346c2ec 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CC68.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CC68.fragment.glsl @@ -1,7 +1,20 @@ #version 430 -uniform sampler2D texture0; -uniform sampler2D texture1; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; +uniform Texture texture1; in vec2 sphericalReflectionUv; in vec2 uv0; @@ -10,7 +23,7 @@ in vec2 uv1; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb*texture(texture1, sphericalReflectionUv).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb*texture(texture1.sampler, transformUv3d(texture1.transform3d, sphericalReflectionUv)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CD28.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CD28.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CD28.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CD28.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CDE8.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CDE8.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CDE8.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CDE8.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CE88.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CE88.fragment.glsl index d624d9746..9bf2fa43d 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CE88.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CE88.fragment.glsl @@ -1,13 +1,26 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CF74.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CF74.fragment.glsl index 7957871e5..54afd853f 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CF74.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000CF74.fragment.glsl @@ -1,15 +1,28 @@ #version 430 -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec2 uv0; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; - float alphaComponent = texture(texture0, uv0).a; + float alphaComponent = texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).a; fragColor = vec4(colorComponent, alphaComponent); diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D014.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D014.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D014.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D014.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D128.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D128.fragment.glsl index fe17ac96b..86346c2ec 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D128.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/0000D128.fragment.glsl @@ -1,7 +1,20 @@ #version 430 -uniform sampler2D texture0; -uniform sampler2D texture1; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; +uniform Texture texture1; in vec2 sphericalReflectionUv; in vec2 uv0; @@ -10,7 +23,7 @@ in vec2 uv1; out vec4 fragColor; void main() { - vec3 colorComponent = vec3(2)*texture(texture0, uv0).rgb*texture(texture1, sphericalReflectionUv).rgb; + vec3 colorComponent = vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb*texture(texture1.sampler, transformUv3d(texture1.transform3d, sphericalReflectionUv)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/TyBField.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyBField/output/TyBField.glb index 9d2ad6e41b2bb32c6e1916a991e8bfa113435e69..7609c178b36f3dfc297484ad728d3cefb6099cf3 100644 GIT binary patch delta 32640 zcmbuI33Qd!wa0U(kOXpblaQGqjACR+!aOBGK?MaO3MgX$nWun&hzt=KBXb}}P#~gG zr4>*V6cwVaT6ry^uiBPcq%KP>4p6LAc@FQl&v5SryPkHvu9f5(_H@qK_ulXO z_~xIPzge0UoH*^a>%B2CF*o;$jma(87~GN3y6H_f4jMgY{QNm{XOAB}XZDyGcTJc% zd-~HqpBI#THax#=e*2CE9jlIJcG?t|bf6->No-zz z+phVY3OlyWZ`-*;r~Iz%J9mtN7Z!Br(t$2U3-hZ&O*>YVg+f)i4H_S46M7<$TF_RD zMo&<6B(qD^l5_*=m%b!Wp9zE^8YCKYJ`if~pf`)r!h#=Y*||$WRc&Uc1Lqr^&1_WA znt3|r(^nX!8!G9}s^q2}s%kois%n?!9vI%`x8B$ShB|es8Z)TAzo30#7Y+ElTd1mW zgWRgp{_U&e`e^Sl2X5*S>&&Ca19eB4_tADTLzTU~=TT$}BzTR_x zT)7iBXn_OUZ#eUlwCUS7qK#ZPzIDujpY_Z8x7r-Y?SJyeH8?uZ_;vdY?W^QkyQkzp z`YqT0B!!Z0O|IIoIQPJx2W`r#`e&f%z*Ez{@HNVB+ogSBz62$bio~>_Q|GQEbk!q$ z3lE$xPxE>Tsy?~*`l`Km2}k3q+*x?-uKga(vwiO8KZU2N^d9j@Zq@0fh5CBQ^3ex= zv7pG~DLC-Sy+gd3YsuoXK0VhBRqd809jIOUt>-7GST%FG(d+cm_6N$BAJlqPy}2?4 zWp6$3=E@B}NxzwufdhLVsE4fwUR+x?q^kX=Db0Vd-kWy2x9MHu#!MT}5-%i=7cFXC zmHp9H0k`-+!3A9``k9Yj`EhCop8eOKKwa3Ob)i-y;mm)6-gTz`Pf)v);Xd&BnPT6M z!`l~HRgQmlUDeF9?SI@-=fp?O4)}5U0;^5c=V#~sICYmOT^|4BKhWj(pZsUKTvs*m z)58BupFe&2ALx_#*?+3f_RoI0J_n9}_9q?M|2x~;x9*~o?1_JD7gO8++iagXVZvSG z=g9G=_jtEb3Tz~1{PVi1l^6E^xT^|Ux7U-EeR*BgJzos_DFS8*lzrK|D*c~#{694O z;-^gJw9~Hmzy0QH7tKm8{(m&*FQ^xIE9Hae3Y^u2vu3;?E5Jp|(k{mrG(|1{G7U#i-M___I~@ zZQhXD74T-Lmv8eXo2$RdRZ4qLMzG=!C068UOiYDJYVXNb9S6&3tuHh9dp8K*UB%UP zyxD5SU~kA9(?jKt@ua8xE^2(1%xU`7dw|rSgT9Pl?z;{G|6+CYMQ@I3IfT&*+ZjE5 z!i^$4Q=QxH%T{xTF#9vZ(XIAvH;U{+_0|{277g{rtG9-D>!?A$@Ma|CzFQk*aSxTd z$&;nhhQcuR9$%)QLvod&#?$Am>7mMdqV{hcFSE|z&-SZ>z`YBLs{i0kPd@H2%)J22 zLUlCHlc8d72U6QZmE7)a?5BI0n)wP|8GO4;c^gW{{8yCVd{o7uk2C6x>8Z{y^Q5ce z!VuMnSKr@`IlJ;b8A&y7L4$-uM*S;!_fQMLX19L8zpy_DlWw67Q=<~Da8770_ItePYQS&;xMVnz z7v_616JL%JoTYZoLh!ZW=;|rQ-m>Gh5qoQURF_L|M~J!i7TZWV0QzpgUivGNnPmbf zZ&^>1r7yTSuy`zgwqG3tq-M`X|J=h40?$k}b2e%OMxu3jPwm#{+^|UVSE0MrkdY8v zc-@nka?k;gpAKM?P9n7%fOl0-qw6yc!}uuvY`?lFEblx<_{$DB2sBfR)rrR>{G%9t zdy6ki&EU#gQmkt8NFy5YYUe0#9nS()e7iR@u{N@fYkI2FTZ!u#5gl}c9|QL}W+on? z2HwEN&~Y>YD(p@W_Par*ovglJi1o`E^unW4cJF8=j%viK4@MKfSMR}fHNS`wo~VxA zgYfn;Z-Q!9CfV^SN%e$7F!vqBs^nD`%)ByG+jJ`{3NYy!93qnJ1XVzsM&|2L9OXm2LY*FJtcd?5NO7! zC3`So(O67K8tbj&{k2Kllt-d?2E$|f)sV69JoAY+Q!SROO|7xy@v+$S&TqUK!IB+O zVz;U#4-u9xWpq%fCnGg?ryFHvNvtPK-W(Z6a0iaVfrU4c7bU-{jW{E}rz)Ev>wcUp zgu9Dnw^9g%)U~r%Y=0dm?%c=Jr?)wBh;LEr_u=-AcQQKr55COAhuk1Dk5W5Vqt|i< zy&v0bRc;*Nf&85}{p!6tnQ3+bZYz7xL7*6+W|sTd+Q;MhuX^f5n6lZ8Bi^4s+pp#U zQcLG~GJ{(j0)}BM-FbNa_3_>$Urcw2WaD_GN{Op(weYhgc~!5E{OKvRkz_x?xb#20 zHjtrCPrzq0`9DvLI=9S|k-Wjp0MkwU`E|ECI05G!EQ&}4Jg2? zhTR=yoljzT<8-#YikF>v2$%O%HT@*qlL*cnyEtBQ0OU_&|6OJ~RA+?aLpj%LRzxXr zz4}0(>yy#@+K*A7Vx=2}U=U04V`f+`!%aDslS=M)!zj?ZSmkbK_jy-_FU*rOeVH3Z zx>TK;NA9$kB0jl*Px^D^X>Qy+V2W(^QzVZUvd>gR$qiKJ@`!fNsjRcNKzO^Dtvls# zZ6w#_2($eveJZxS^GE6!WSHxZthfpEd0H8--{Z*9xr9H{tqzLV?7v}j?E;5D?f!V| zZx|hz23JaNYNy$56j?T#{HKZZkZA~SdI6Wj%yGjA-^B1oD8HLwZ-*jvdYVbq9*CM| zOLgHX_T=eNLL|>qQ1+Ql96Oo)D|oOrV(WuFRq3y!UYqVsQcv&kW~QEg&J8nXOcA-@ z!aNL{F7Fl@O$r%SJZSp6Jgw1oCm%O#kUe3HroxZ<6O`HIofHxzx>p1|9h` z-RdAjYS#dNX5t_RfTWlDemXl->?{VoL-16aS@_IdC8*J}Fnm*2PiFE>QBuXwzHeN% zTO?n7gYD`%2Vk&(bNCH%;G&G~I>0g4+l?}5PinUVUKaIiv8}y3vuUZNUwJasjM;K} z&-TW8W2URdqrI8QwUHeygxS-r$QcpY^#zNkhofimc53Gro*dQbE(QmUB)4OV+$fXx zC|0E-WkKJCp}Q6%+tH08+r||6@5mm399j2Je{(Y9i;Z>wGngct0XB_#?M7e zJ~ODba>XZrOto$^AvlBQ!L;jd z1gDuBM9~h#)$P#paRxmLbw(v-yJ2Kon4G#DEqDE5x=ct1V&^|ST(;O_0=tUyL-piH#!0?YKfd=Z_ zd<2Hv%Z^!4&HfVer5k0|tC_J{;(RZ0-ei1m9G<9aK6~Bkja6f&`LYuK7A1O>+F2`m z^+K_zjoq1cMcI6wgUR-*>V-_-YcZ>#<`D-G&#B_Yr1f7HV$D14upzhz8>sX3RlF)* zgb&8HA%uU7nz==>3cW>?R|wd<2oJsKMu|ka6z4hWJqEq8#?i^YapTO{3{0$QTutP6 zF80Q$c8i&V5}#9fF=|M`E>{U^2?L(EFf!HKs_Nf18v} zTS7`tFxZqG4#3nMi1B#4X-!yy@`F0b0*=07DKGKH`eNd3iaZ^qd1L0FUp}6z#TBGT zQU$8>u^=%aGB~yy&aQTY z=$wNcZ6WD%AI=%HQEG&ToJmX;SENceGQ5Rh@15oY_BJ<;cn?gz)2-($yl+g?SjrU93C?2Y>&iyyu zU%Xrbx}21I*6c8i9foNG{F!bwWI3*@uZq{>#wE+WN#6Q)?%gtQ(8&6uWPQk*Zgmm7 zdb`q-m6+fFC=gO_Ria&=6|#`8vU#^9%IHjDX!}+53i;$Q#@3;m9SWM8LD8>2c#m3% zG3Qp`!lfPYXmBNlyDNgdQlhpOH-cj!$<=ovv3{jEeU!vmB%};iPpxDret?88hIG*E zV9BHPz;>)cs@*D?XCTc1t7IN~MN!RwH`@vU4M{^j6Q^!)dgGg1^lo838>QEa?pFh^ z!!2p6iEo+xEFG4^-rJBHZOKoqMvs}RMf-W=#Jbh!aUl!;B63rCaG8YVDjQh z#*!)#y7n%hZ7aoOdlj!nSK_2wrWjn3xoY$P68l6#igoqdN>a9PHL}Nr>U)uB(i;hI zIA{`(J`Vu#-b=wSJ^Cs^?R)^8M(JZWd9AY=t43heC^dQ&*)@6%yW=@pH7^)f(ZPw0^FoG^#VUK#p8%e)3R$Rsu926WxAmVtI_ z#U^TU)qgFsxGVPHwGwy^eI0nPB%f=&zLt5%e&o$esdNSq&U_4LX1?M`Uq{GC7}*F0 zBg??pesyXc^Uqwz{9Y>lV8YSJS$n#udKahD!F4h#hmO_(d{irTJvx}8zD1Pe`)d7* zDPq)Z$uV)#qS>cA6cv6unc@~~CGW_ZwcB$b}Q~s{Vl;a&Y ziqaby9qdMt{akN+oVgp3O*ufMo)Vn9Vu@~)MSVS6ae0*3S*D!8lsh&_lsDmJN^utI zCRiw}^%Vg3yQa+cK-0y}_wOkdK z`g7C-8NKiV&aZX~A$v@ndjaPkWRN;dhcutXNM$Pz# zqUyfPxI*yM?wN_daf29kSPlFD!`_oY`4kp>(+#34DN?c)(Uyv%<|}i254ilAU@CSN zKD_IB-;0tyLD;4uUGyO8y(K92MEw=z0%sTs$T4F3Rr-UXg~!j=84uzfeKlTR-H(~; z^r*dJmwgcTK3(C<3Vswd>2L7U8W!>5trE+v_)==+#4jC$8TYDvy(E@fDw=%7i*+EZ~ioYmQpx&uv5X*+r-x=U}K#2~~vZogPAA z`4&`-dJ!kkBHy;+IDD1paRV@dz_5Rh+?MYF`{Z^d6y=iZR7G9E^_*W*6+ zm$WG98sh&r1@7F3nJ;+>u1tb?B14oOE46bfjHb1dtiU9uN=O@)?C(N_fu*fGwN!+R4>Veyim;59j;7dBYVYFPMlAa_<-_@htc0MiE`5J}AKrb05LJrkBJ^J=`d=yO{S9!>=RkO}9&Uv;!bM z4Nu#CmA;D^-s#ImGRh&K*ifWS$R2cR7ml8}i_|V0D_-gCFtDsp?ZyImZWl_V^vAV; zIePk&<%=FA!;&7wE0pe8!JDF_mhu_wzj4aoN2QwOOGt^HTKuRiG+KIJ-%U#;ufv}u zgQ7$ilE3Q^{Ss02w*0nMQR;@#xf-42$F)9>Q4rdqJ9vi!pzs_3Qb<=n27SRyp&#mo zktb_T9Q9@&I`f#fbf8zhsc1rY2L02UDUB1^WWbdAzEA?6BV#JSm)g$5f}o+{$G*by z)13mb>brk>8|M!Xr|t<7#a=LmtT6* z5UB3Y5js5NON!D*_qA&uNK(hYG?SNo=WVVYyyy*vr+D?Ev8Tr4YpA}y2p8(mXr|hQ ze09{0i$+kJi)9IF(!Y=fqs_ws3F=|nqcPi3={X@i<<=iNE_o9||MYjnMKLkvzYLXL zg)`fJ#pJGWTqLJ`6(w0M!%U@#@uY5)b__IEabFuHXf#wKMbRF%=X@G*neesYmBy9< zzWC(gAIz^!{QcKB+fCrTWGA@fZK%3l!V{v|C2wK0C0bo=I)>I$r!INxg@TH?GtspY0w9spDQ>T-YtgQrtddbkmNzlpNJr zW4(Di77c#wMFV;?8+%M&l9#zA_jPIVYQZRZUpu$x5Z z6FiLRWxc}!b>p3ADRfIvp|~hg^uJ7@oec&#zTOHGzz1w(4NuecS}RLn-fqDhiHrEB|v~*b)ylRzHHwZ z>b7r&w4^vg{Vjp1nLziX)HO-p+wZDeshSI^k4h0X{A8t4WKQ8(~Pb9H+nwnLzmUMeHTUk%j@i4cg^ zi8#+`f7pY+S_P3Qamjd*J#BbUhd}53%3vh#*-kRT$VMXjmB_MbXib_XF`wH(7^VV9 zf~eeiKPqB~fu?y&86gb~71VIIz%HCtlW!oYbW%X*PAqyJ@~GPrkW+YDb{1 zDsSV9Rg2Tie6{IRT{oorl04-GGAkW;xq2(j-%RaI_i@)1ACuC3g`QPre7daMj0~KF z5A~X1X4Z0s$<5Gg`EZv`&l17lJKghShA&GRPCz?dk7&N6cD_2{8q)FZXnXm&pk)_i z;(!{8aG9q~qCZ|8%tXo4eA){7o2s+6p@;9u^wm|lSt#ZNwzu`wy`n5+=zK#YS7iA@ z+;_4hh~0FP1%Mm%~ZQPfw)-@!!>jmQ|59c6F1A&(6QVttX zIk&Wkbc+VQG#AYHd|zT>w5~RYs~cbxfkkgB`v&lmMl>3#MP!irrhzZ$vFX#Iq0R^G zi#xcMc^ooP?P%zWGsqnEYC}|lr=pE7FC5H#ew}GV_Sgh$)0oVd*oX;3THPG=^8!qJ zxDgYEB*Ai2ULznUq(jT(s7sCDg$L_$RJ+FPC#SXDIcl73=-512AhzlgL!u%-S!ktY z%4E7P8`4@fQ+0CDL;}(XKXi8uNv-j@(P3|F(ngb;V+j>>J`U*M3#n7N&I{a!(+u@@ zc6IrT2rj8@27hrACc_T4jD~7@6QX3Dvb~9R@%jv3BlWKImmAIFn~}evrg*}Jt!q;g zHdcQ_HLGbj!&q?w{RL3TiQJ|fFsG$K{%pvQjA{nftwpd|0@EyabaEBcQC(qbSAN#f zmmH3uxJNIxt{C=xXVPOpGZLK&D_ioV1s$2qnG26-+_%{*%6`qwqQvm#szQdL(S|?O z9910W-)q>9K4#biKU-=p=9p9+897Qj!3=h9^b(`2j4PB{KZ3$x^O&*!bkq)%Gl zEscZAJNcSNZyJP@ z3A9jF2VbHZc9pN53)y{FnH5sr0D_U7eeuD|R$p;7nuPH5WxXcv8@2Lfx}}6E32HJmQ+ng zz;6gRWK!bqOrGC2W(fVNw$-K7Vzg=V9BUDc`(CCxwDWN5<*If1L^( zICWK**3hucv2!$2Q(I%^Ds!;yXibKd>jC{qTQB7qX=GHe4H<>g_0HJ64Mx$>!+UoG z66EaE-e8ZDJ?&gWPK)>2=yVP5PjRYlTkTOjTEr<9-muuc>ITIJ&T!P#Cq}$O`qR$!q!R|yFCsrphf<+y+P8uB5Emd{_=Yd=9oB{gi)d|~E8W8CP zqfeE4^9{8g=EO`^1M>CqHW-es$a$MsVB)H=y`md)X}BC>BMx6vd?c&S3)miQ=CQkn z;$8OZzHIepDIh3a!YPYl5m2egvZo3o=g?oGu63>P0se8Dq}Ut2mThrW`^XOZ_p4a2 zN7}Ps?Uwr2_7PfEvy?vi)aWnQdg>gtw1Zoj*@~?(K^^VDbXxfw#q!E@8@b-jT6K(U zXDp4nYD84WJuR5OlKI1HMOKe|XLChXXcseCR(Kh(FsQV3s=Fd0OHFUe1ZAB_N*7f2 z#Yl0bPY|&`oDE?IgnKwt64jJ0CS%;brB4feKy2)6c0s)*zGfS2>v?KNXOkyxtF06M z9AM9eFz*S0Ku)2@pXD*n=1kzy+;X|q zod(Mgv@TZH~?H%`AyZR41b(z6!6D+rkT0cX8IG= z*#MgJ!IQf}6degFCzff=9U-y&h_&P`Y+MklU2^&)uG$-Q{h_%o{hF`6^Rkdz9J2nB zo_=+Z;xP*=6|Yv-0rJ5~2#00jv?FzxU(fW{Iyw|uiKk-yiI*KJztd$;Q#B+G({v@Z zJkFnP1nvg8TjyjUc)xfX$EoVpqF4tF;a;4|$))1?XCFoR;=fEy7VuRVT zuD+CXxT7w-I(63RPDzy<^`}PuBz4LYj`o+JY@qop#P913nck(NmRL`2s)_Z;Hr9er zRMqom8sd|U{Cp!~w;tJk@S)CKX8gf`{*2Tq5wGY^NQ)aoyV!@FTF2@{taIAZCu-QV z)v5O#<2FGHf;x)u<*5OF5}}5N9D=fNbiQ_N$P|*Ab|nr&7Zpq*2lO4#Pd1iNMy03z z2>4#mAM#E!OLsvo0((S2C(YYQk)#QP^mWBsBxtt~8tW|En`=@s9Q&;~%yA@EJ6TH5 zKZYdSdgDq=jzqp^G7-{q%#th3wJqm|o->(^R#*C3FNk1@%aHG~acNNl{%=$qe${;Q zWK>@jC1X~0ioc%A;XkKDj7doq_bN@;uZc-z?O5FdaY%C6xLS_O@d{nvS{b zb`PZK-A-36N7D2{;#&4fw#+=$HXUC__Dxn|I&=RnYF}KJ9^TMiNY{2pHrap44yco( zNd|GyR}=;DvX$A*R5vez^YBoX+(rs_C54RD>5mqe6%5yE?6 zX9=C&HO6L(dyUABY((sJClKDrCQOS6p$g{c*)(5ajt+r@aB_~$Tun`u$~0~r)Ke#O z5OfI_Qbl}%BZwl_wE<%0lB_V7P1WuOxR2_#x%yLs$j+j-8kWAx2sS#cvg|sHC8@;? z;WfwBE*Z1myqsdm;{kRA$q4oWHikxGgx(NlH4?|`%g5!?<_Vh@1iG88GErqW=KtJY z6jI-jQYO@M8@r@n@386dXSvdm??(cgM9|@9O>@{aj;ykKa$N#E#g$8dznE(s;)G-v zj^vU6QUT}_tqH2><01Rd;wJu&y86x*`P3_Uo;0;!xIg6k)V6}p)ozIK_TsrA_Tbhm z-w|Ztn;`r#ONxD}V2md%wSE+23AJBc29oa#q^q0}{v=<5Z6!Js2yPTPeS08FO&;M- z_EmKEsedfbGpAU2wMSsm5@)1dHxsl^TXYcO&;8EOc~d1tu*KN^KLx)*Z%j z)X^dAHX4{~rM7c0*zN?DZRJ(vXi+YUrjBC=hXd1rzYW$`>ZH&;Xj`cr9Sk~ovbCX= zS9xVZCr$0T?hXg04S)Nsv($nz=$^N&)E*87ojkGG#LBB<0?VbPZSCb?K(6BN1oGO} z>@mPxEA=`DgRK-;3oEat2&}ndd&7++c?TlgeLx2(;t2jf2j$QinPibUlIPTX}U>)3u|i zZ5`ooVCwOg3!Tp3Zg)c0+_q9jIv8}FfVH>ss`5_JPMYHH)IAOd<_QAvJEz@Ap?lA^ zQh)AX&@ChobFI9}8xL#_EuF#R91ONt{_>I6u3I3m4z`tgr-Q-P4p?U^uZ{_<6D{qz z$qokOJ0|Ucyk7g+6M&W2R_as-gY9ad-L1TuBCu|>wByPh49I!dZbn`^?y$g0Z7X$_ zgTdAmXpxmy2@`=yOIv!kg8}&nwh_o{ONR-}wNmFh7;HH}ueI`O&qN7BFPb{%e&%ps zv(B>es^27`lcx6EqA0rez)gZcdv4n#=%(3L>JkToE{&P5 zxAN+&rt3pf8@truz#M~aJ_I_2yG@2}p>3t!?_kgcf%diXs&cYuC(Wll*v+)G>sC7$kiD=~!Y0$G1p-@RTd83fY#yMuSb23! zV5LsCN2A!}fymd9*BevzRA8=^`j~^kCbt95aJo&IDyB}SsXe#G;h1q3xJ}S$&m9)J z&9;@g*1@3rC$QVByh@lRbhkR~);k<@o55{^K*x31H0WH5hY}(+!^gmGciQdIbVF%s z*Ht+jbSuEsK&M@IN$7UjR%#fAb|--ixALmrbkRww0p=n?FKf*u~p6xSb23! zVA7K4rPMF6@q(?QdrS=Xx`*xzWU2<`{-F0$)2J5-DP`dKa>~HT<)#eu8}~o!SeVR| zfqt87;3xx4EBKs)G1=ha>M;~~@w0Rp=+~P^@aZT3W#Ik^fowHw76t4x69Sp3;ZbHW zRiF`5dw@^{T4nY|k(esb!Y&Ccrl)D8KILGrnJUo8tA4YArC6O)f9_!DY^p#D+a|CQ z*vw((V6d4g(0btPY{`W*N0;Mp(3vXGD%b5U=sqg4%4InibfyZlbd>^I2%Fw)f97DY znJUo2P716X<#ft~VX&Dh&`z2+N0iHQo_j2c&QyVZn_6?Adk{LE&yPA7bfyZlE;**@ z8ai7aaX7RyRiMRX&xP)J=eimPgU(ce)`%$r%Y{wPy4}HGGgY949TwOLXKNS+o2de= z4GHsrHFutC62)e!K)>D21ol30(3@zkgTZF1Kf!OciJyoOh4VwRd!_ z91c2D1zPPE+ymWvPP?ld3_4Q*g$75yfVzKnoituu|u^+C<;B5W3^g=?$li zgF$DiKudR4)6H_WE^#>MOciM9x-Eiknxk9fV9=Q=&>B&>NVMw%oi3o~I~;VT3beSB zLbuQvd$)r@XR1IWukscPU0>+56|)=;I#UH&+=9i>ErZUK?G6T=sRFGL#{_n>vvsP2 z!DgyJ3(H;tY>l&ZvV*~9sz7VQ6oHjG-8woLY^Dmdu)_j--I?0K!C*60pq(_KLQI|R zJa?zVL1(H!OE;_ny3LMmoP$AUszB?JJ(})Tr`<@0gU(ce7I#VLwmHv@a4_gh6==2V zcb{lC6gs`<40Sl@OciKx+wOyImvh}<2ZPR3fiCMb-Ee1Ysl!2Msz8hDwiLQO(CJwR zIv8}O3baO43TzZ?dXwnkV6d4g(6XHrSgm90?qIN)D$sg3?|!j$vU6Quhl9>kfp*pf z_d~bex$Z^>gU(ce)+NUTHr9FWItPQzRDl+jy$sm%&U3vS3^r2*S{tSaY=U##?~ZOL zZz13G!Dgz!fOeHSEU-_DOe^?%2ZN1DaKm!GIjy_gACxZy17^+quGlgGF_oZY8nzs! z1Yi<^;O`xb3He6w{A5bOCztC|&?1gSAt(hmOa<{Z2(@Xdd?WaV8)hC;3)*@5tze!Y z^E^G<$6KMoW|>ORg0=}Lrl)D89**KNm7tMUpRVu+sRS)-pM#;ZsRWJ9s@qD~N?_Bw z#xEQU%}ga|C#_s5`H<%5-Z&aj&QyXHcT(s+vOZ5e=3vm7O3=dcRsmZGo1XO%H!I4S zO3=a<2&~+hy3@g6GnJsV;n*rsF3Ztvb~xxvC1`QktD$?)*}Boepfi=Ag-uy4bPb)Y zD;*9xQwdt!VWE58(JgZ@=u9POjYy~jmh0H=axmCTC1_#81a`vNI>W(WGnJr)?GadW z$9DK=Bo3w$)X`5@|5M3V*zXeuGATX9p&&Dbpe5_~0A%wW*&S|9R5OL3g>4hqd8gW~ z4hEYk1TE~Wz*;%BA_s%b6oMAkZ4IzEmm*yp3^r2;T3F>8iNZCGu9?F@X9_`!J1KPa z9bF>_gU%F!7M8bG=-N5DIERDI6oMAFU@dgb9i7j?pfiP_g&os$?V&U4=4d1irVzBa z>~+w+=jir17<8r(bSWpWIZnCviy~~M5VUNE1=hi_op3PNOd)7t3G0D%a%{UD3{y=Z zXko(y#!dF-V0qZVU^9iFh3yeoH^)}yV6d4&Frdb);#~vZtY^O|g-u#+?}E#eftIV^ z2DpkG*T+30cA7FUpkJJ)9@;?mj(|(QM$e%jGgY7^I}1vxKx@EG=Ug;1RiJflw~b7C z95%DrI2d%M3bb^U8-;F`qbunVQO;C>7I#wUra8Bjykud}nJUo2@-_)wALz6ZFGtu+ z5oloxHo>;gv3=}du$dyzdgQ-0$w}20Hr$(@awNiLYCy}DT?N}R$5!TGu$darh^whp z`1fXK>BA0I>}o*Ec39ZfIJVsm2Ain?Ei7R(uu|Bxe>Xb+!e(kf8-`&5dmT0n+w5Sl znHtc-_G}ivO?S$jaI->ZYCt>dC868wlzZR7pffd~h4tGabhkP>pPLpsQv+Juwk^H|dD{?UCObuvZc?uX0;}{n&b1>LU4QOEt1XkO;p3-KRh||o@Wr$=cTpTk3uJn8i`9mPfgJTkS|HuW)^7w_ zrdxrMbR%G%6=*UWDZXUP5DDJSp`R`p#j6T@e9Tj) zMdG0hk$4tREjLEIuE%!hF+}JtKSFogOcCMX=KYz7OwHt}x?M;84OF%6@2&d_y%qWv zZ(gjXdv9a9T&!rH70B>r@~D)bo1G?PVc#l#<hnuVNXuMC6Ff4E*O~vKg9piS}QPdNe1H z?yXpB?lOK)4*@)%gCe}S2N&_ui3Xy`Fj~z~{H_M#eqPb##(3PnfjA35Z3CHzSn9E0 zLzIeXsgi2Z@LC!YSbbN_yoTX;f_I@jWg&`C=BU(0GEYnUgwOSjM4Wh*H8MfdJbQI7 zp`^E&`lOMGvWaJUW04@9`He-wg>td(CX{qHQ!h5QVb<|HqsOX?s&fN{CXxekg`~Ii zaKBD&fJb+1G!N<#6V1YKAS;^+-b6A--P!~PxNr_@CPRd?rU||!@&qtPHESwXnsC~d zL`*+FHAIu~PS*0K66#eF&;~-9?xM6+!D%t-rEAPhjuj&bkFh1Tb}RcUcT&ScqW*)d={inJE&a^fKn;72XW;8y8%R{Mo}=0ES_W?UoU6%P z`FQb{+CLojs}FkXswV{2>mZLpzjJLMBUab7=G}}c_Bvh#*yJ2T-L8Wn8V>|SZ=q_+WI_l3ws9=ee&A6 z{d3WLcW-eh0A72}(@(U#F%!-EPrDt)l*~SXL~qP^b@X$*H{}I-Zl=d4uQt>#(4E^y zrke=cCoJPVeT@A2)}T-6h80b@UgmL9_xuAzO0O5{iK^WNj9Z|`jUHL*sq2N+>G+`@ zb0$4`9@*R*L3!Gj7cMc@u^9$6ECr^=A9*D$+n75n5VLzc+qC%#Oh>DbbBD^-N60F za?jMr+XHfsSMCV*z=v+vT)O|WN{o3c+|fRkpYh#oOlrq)RP20*o0*^7Mq=8uI|50b z9_F5|Eq4U6V|y48ZRW8%E>k5_d4>hjoo?EFhh@ed!;Jf4xXp@}a;K}LQD{7KSRf== z>6P!%RMAM%sbVRsZA75ZbDs%FBO$0a93^x=PoE9v0eC-5}d2+fFxxXsfzZTbkD77^!_5+fqMc=;7rPKywy zi3n+zaMF$pWO1#DXN|-?Hd5O7-3(sVang1~J0epM(jnh>scT1}_qlT7K6excxxQMv zCXkRWj*5|NA#1qy>jdyC5+Geo-9Y3%9_4b>esh;H+EKl^4&_TnN5-|g7cg#OWd+WT z!PUTMv{T^f@yO?v8RO+wT{Nnjc6s_fuMM}~RIXctLMzKmeB~EX?T)tV;D1SI zNYn9?U$>^WYQ7RYdxk_Sur+{C9j#JY~8<>rTo%Zju_f8J*=*u18^Ol z3EZji-8yuAYdq(!WN1j#*ZwLS=lu08UJkvx@XV11I=YPgw zfga*TF?W*AI?UTQATLplWHZH=cx3IJl9^mm7X#OqSt{|>K;7!`I*m~W?-@6YL^ZB2 z(=aIiK8to3O0olthlHd>%A}{wqjvmw9?)?#Ub%AuUeVcUy^<&KsF{E>ZLiMRQ&VwG zor!2NO08c`>V7Lf$Lp)<8xiO}(ItZYJkf6pz2yj)nAl#S2^C9vM>a)E_}huBEFCV3 zJwA~s>rT3Y7ls5?GKqjVHR}Fglhq^JCutw?y);iAZ6s~pN65IsPB3F56C_Q(VuD~5 z6U?7%c3QrR&QUWb2Qu+?{&ZsVbKvGWNA26p4)=lS0BCnwOI|dEO`}M@7SB?Dp33wK zr{KIErUP3O)V?XqtkXDRa6+0SM`Q~a5$%v5UwbzB9%@}a=RO92A9szT=ZR44! zwPdO>OM3M-K46B~c&lgVeHRx|pNOdqrb&9y-AoOfMxJWtB{Cw7A2M`6Yp9-|!l{*U;g-?totQTwIo| zP*?U`#QA6>3ASd&7128g!i7_NwE`~ zwDrHo-;kpe+vp{7dVI;MKzf|+3f~~gp~1GPsaoRp@D!g{;;wV60>L;wbD0}TISn#Z z!_|TMar%b`fw~GI&2$N?j``BnqVv6$(4D^ts&;iCSVx}D3nS0|5XqsO83yS|2Uq^P zN$aTfm7<^g3KF)5l7N}7G{tra$~h`dUGsoQU+JJYH9FiMW~ENMG6qM&U4qiloG}7l ze)E8druKtAs@kmyB-xPKV`J3#aM&YfnhU$#E`Pa3VkO@#U(FGR8`9Oz4Xm&4*NE2A z|1mdo=yYJ?L_1@M?HWZ_9UE!0-ELkRNULKVBRy?gV66nFAtd5UnNRa_q}nc-${p*x z32dEYo{27ZfrJmRo$D~vL^pCi!f++hMb}PKxZX_@Ju`1tTTims=o%XyUVpg_jn%(& z2AB-BblwgB&Ktb?Z-WcBSfd?EY4dM+FHi!-y6eWwL6{OQOs(N zZ1gUywrAHy(awa`fhNO$dShfYM|P2aznblM@utXXwq5K*@oM2Fp)yOr_Ui*<-zIT@ z@s*vLjXgg7C_6?`WXCWm-~d%FHXqwxjg&qeZ>kb56WGW;pP(w}w<%y5fG4DN`)z75 ze@ErN@~>t|l36j10+$bNPB~~BY!)M~)P*OJHp|3j$y?(%j0oA4_S!B{TW`|(aQZ|` zo0Vew@ggs#-xA3Us|97mm4R9u?h;nLz!y(P*O#_PZWy^kXSM`FabBLO)$feS*};Kh zAC@)`a7%}NVme##QWyQ672Kg;7QlabWY;}LuixgO8z1hV4A2i!^A7Eu98WwhD=&AD zr}|QMM87}}hLE1Qp}KEpApDAqrx6mB^rOLlXFwhe){TZWpsYIjq3xkH=x66@)0M}j z*VIsuQVEs&9H`4Nrbue7J>4mEk? za7j$XD$@}XV@S3q6X!-rboa*}$+8G^cO#=V!%=&B{7x}JYPJFSz^+@3dV)q-%X%Mp5} zQLlz)vPW-QgEF?+<7}^>jE456$8`o}EU|sx2`b#c`(3M89{Oz+%j<*+)hlvA)*az^=n`Fh7=`&IY@Ma4H|o!-KH}(St!=Cwcc zV!Nn8BY2v8w_IH)=MCIn7Q}WnSA7a&yFzC(vAWRE+4Mb9sOPeSXTpQ}6GgDS9<+y5 jr}jqDHb-4HxZ?7`y$q^N%hBWA_UIv3hgx)q9UA+;;Z6>? delta 34111 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 delta 4555 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 ZZP1cgO8V(<9WydAnEZI@8{Dx8{|D_1jT-;} diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/00005614.fragment.glsl b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/00005614.fragment.glsl index 51718c8ba..339f9c336 100644 --- a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/00005614.fragment.glsl +++ b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/00005614.fragment.glsl @@ -30,7 +30,20 @@ layout (std140, binding = 2) uniform Lights { uniform vec3 cameraPosition; uniform float shininess; -uniform sampler2D texture0; + +struct Texture { + sampler2D sampler; + mat4 transform3d; +}; + +vec2 transformUv3d(mat4 transform3d, vec2 inUv) { + vec4 rawTransformedUv = (transform3d * vec4(inUv, 0, 1)); + + // We need to manually divide by w for perspective correction! + return rawTransformedUv.xy / rawTransformedUv.w; +} + +uniform Texture texture0; in vec3 vertexPosition; in vec3 vertexNormal; @@ -129,7 +142,7 @@ void main() { vec4 mergedLightSpecularColor = vec4(0); getMergedLightColors(vertexPosition, fragNormal, shininess, mergedLightDiffuseColor, mergedLightSpecularColor); - vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0, uv0).rgb; + vec3 colorComponent = mergedLightDiffuseColor.rgb*vec3(2)*texture(texture0.sampler, transformUv3d(texture0.transform3d, uv0)).rgb; float alphaComponent = 1; diff --git a/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/TyGwfeld.glb b/FinModelUtility/Formats/Hsd/Hsd Tests/goldens/super_smash_bros_melee/TyGwfeld/output/TyGwfeld.glb index 959ac2b106df8f8c559f1364d2e0967e4eec5444..fbe17bdc6b4ddd4f67e2d782f76f920927b51cc7 100644 GIT binary patch delta 313 zcmbQRmiNM1Uf%Sa5H}_U28Ih^%nUsfd5?;i3S!Hv9+~2oB1~ds5B>B zYfrewxIN(-lS~LR(8ZJUUx`njro}A90_50FesE1}`Y8xcVej+<@r+{A|G~IGNzv(s x+RV~GeXY~=`548gr)h&Vwn8+{LgAf*@EGi;fA9wy!=wXNs<3yvf(~;<#b$3|Vs2q(WNKt-Zfas?Y+)X&qm-MO zr(_jvpl4uiVq|DxZmOdTWE&e80hJjT7?_xwSs0renoVvrmD;T5@T_oi;3j{S=K0s! z=U-#oKK~k%YzXrX2d2sEUx`n@ro}A90_50FR=6%Uol6_Y6L|T3&$I+avFUa&9#Bqn xdZ9M6G;@qX+w^=sM)B#(KypAHMBgnG9-j`>%;^RJKx3RhT#%vL6Lgphv;f>`Ni6^X