Jump to content

Space Marine 2 pct_mip / pct.resource textures


Go to solution Solved by haus,

Recommended Posts

Posted (edited)

Space Marine 2 uses Saber Interactive's Swarm Engine.

It uses a few of Saber's pct textures, with the vast majority being pct_mip.
From what I understand, the pct_mip is raw texture data with the pct.resource specifying how it is read.
pct.resource files can be read as plain text.

The existing QCTools/QCPCT tool is not able to read the SM2 textures, from what I have found.
https://github.com/iOrange/QCTools

Samples https://drive.google.com/drive/folders/19dmtmLcdLUzA7Z8Y-IkJVZUrB7OQetbQ?usp=sharing

ch_termagaunt_head.pct.resource

Spoiler

__type: res_desc_pct
header:
  faceSize: 1398096
  format: 51
  mipLevel:
  - offset: 0
    size: 1048576
  - offset: 1048576
    size: 262144
  - offset: 1310720
    size: 65536
  - offset: 1376256
    size: 16384
  - offset: 1392640
    size: 4096
  - offset: 1396736
    size: 1024
  - offset: 1397760
    size: 256
  - offset: 1398016
    size: 64
  - offset: 1398080
    size: 16
  nFaces: 1
  nMipMap: 9
  sign: 1346978644
  size: 1398096
  sx: 1024
  sy: 1024
  sz: 1
imageOffset: 0
isCopyDst: false
isImposter: false
isLightmap: false
linkTd: res://td/ch_termagaunt_head.td.resource
mipMaps:
- ch_termagaunt_head_0.pct_mip
- ch_termagaunt_head_1.pct_mip
- ch_termagaunt_head_2.pct_mip
- ch_termagaunt_head_3.pct_mip
- ch_termagaunt_head_4.pct_mip
- ch_termagaunt_head_5.pct_mip
- ch_termagaunt_head_6.pct_mip
- ch_termagaunt_head_7.pct_mip
- ch_termagaunt_head_8.pct_mip
pct: ''
source: <source>\characters\ch_termagaunt_head.tga
texName: ch_termagaunt_head
texType: ''
tileLayout: 0
tiles: []
useHeaderFromResource: true

 

Edited by 09williamsad
Posted (edited)
On 9/8/2024 at 12:08 PM, 09williamsad said:

From what I understand, the pct_mip is raw texture data with the pct.resource specifying how it is read.

Yeah, given ch_termagaunt_head_0.pct_mip's exact size of 1048576 bytes (1024x1024), it's evidently headerless and doesn't use variable length compression (could still use block-based compression though, like BC*/DXT*/ATSC/ETC/PVR, depending on which target hardware). At 1024 8-bpp pixels wide, you can see some vertical patterns align (whereas at 1023 or 1025, they appear diagonally shifted), but the overall image doesn't look like much 🤷. It could be a case of encryption atop a block-based format. 🤔 (update) It's BC7, the complicated one. It's curious that there are histogram spikes at 40h, 7Fh, 80h, and FFh.

image.png.70bf3b151012a0f0a83d6e8c9753da51.png

(update after haus's reply)

image.png.05f2781bc7df2231f31842fb96cb2132.png

Edited by piken
Update after haus's reply.
Posted
9 hours ago, piken said:

It could be a case of encryption atop a block-based format.

As the games other files are not encrypted (models, audio, zips etc), I suspect it is more format specification than encryption.

  • Solution
Posted (edited)

ch_soldier_head_01_BC7_UNORM.thumb.jpg.1d22c5e3801b64ddf390d6764eade0d7.jpg

 

EDIT: Yep, just get the info from the .pct.resource file, clobber all of the .pct_mip files together into a single stream, and use something to re-create the DX header.

Formats:

Spoiler
0x00 | 00 = ARGB8888
0x01 | 01 = ARGB4444
0x02 | 02 = RGB888
0x03 | 03 = A8
0x04 | 04 = RGB332
0x05 | 05 = RGB565
0x06 | 06 = ARGB8332
0x07 | 07 = ARGB1555
0x08 | 08 = I8
0x09 | 09 = AI44
0x0A | 10 = AI88
0x0B | 11 = UV88
0x0C | 12 = OXT1
0x0D | 13 = AXT1
0x0E | 14 = XT2
0x0F | 15 = XT3
0x10 | 16 = XT4
0x11 | 17 = XT5
0x12 | 18 = PAL_8
0x13 | 19 = PAL_4
0x14 | 20 = PAL_A8
0x15 | 21 = PAL_A4
0x16 | 22 = XRGB8888
0x17 | 23 = ARGB7888R
0x18 | 24 = ARGB1555R
0x19 | 25 = RGB555R
0x1A | 26 = RGB888R
0x1B | 27 = SWZ_ARGB8888
0x1C | 28 = SWZ_ARGB4444
0x1D | 29 = SWZ_RGB888
0x1E | 30 = SWZ_RGB565
0x1F | 31 = SWZ_ARGB1555
0x20 | 32 = SWZ_UV88
0x21 | 33 = SWZ_XRGB8888
0x22 | 34 = SWZ_PAL_8
0x23 | 35 = SWZ_PAL_A8
0x24 | 36 = DXN
0x25 | 37 = DXT5A
0x26 | 38 = RGBA16161616F
0x27 | 39 = ARGB16161616S
0x28 | 40 = ARGB16161616U
0x29 | 41 = R16F
0x2A | 42 = R32F
0x2B | 43 = RGB323232F
0x2C | 44 = SWZ_ARGB8888U
0x2D | 45 = R9G9B9E5_SHAREDEXP
0x2E | 46 = R8U
0x2F | 47 = R10G10B10A2_UNORM
0x30 | 48 = R32U
0x31 | 49 = BC6U
0x32 | 50 = BC6S
0x33 | 51 = BC7
0x34 | 52 = BC7A
0x35 | 53 = R16G16F
0x36 | 54 = R16G16
0x37 | 55 = R16
0x38 | 56 = R32G32U
0x39 | 57 = RGBA32323232F
0x3A | 58 = R32G32B32A32U
0x3B | 59 = R32G32B32A32S
0x3C | 60 = R32G32B32U
0x3D | 61 = R32G32B332S
0x3E | 62 = R16G16U
0x3F | 63 = R8G8U
0x40 | 64 = SWZ_ARGB8888S

 

 

Attached is a C# code example that uses DirectXTexNet to recreate the header.

SM2 Tex.zip

Edited by haus
added all format mappings
  • Like 1
  • Thanks 1
Posted
On 9/18/2024 at 12:13 PM, haus said:

EDIT: Yep, just get the info from the .pct.resource file, clobber all of the .pct_mip files together into a single stream, and use something to re-create the DX header.

Hi, I'm a super newbie just starting to touch the grass for texture editing for SM2.  Can you help walk me through how to clobber all the .pct_mip files together + re-create the DX header.  Sorry if this is too much trouble, but I am a new to this step and am having trouble finding resources to learn.

Thanks ❤️

Posted (edited)
On 9/19/2024 at 12:13 AM, haus said:

EDIT: Yep, just get the info from the .pct.resource file, clobber all of the .pct_mip files together into a single stream, and use something to re-create the DX header.

 

The means the reverse of this would be to split the exported the single texture file to # (depending on the .pct.resource) .pct_mip files.

No need to do any anyting else? Since the data is in the .pct.resource file?

EDIT: Wait...

You don't even really need to do that for textures...

Anyway thanks man. Helped a ton.

https://streamable.com/tck37o

image.thumb.png.64328dc4b87c5c36990432d3acab9965.png

Edited by kulatong

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...