Does my KTX2 texture need to be square?

Just a guy who loves to write code and watch anime.
Search for a command to run...

Just a guy who loves to write code and watch anime.
No comments yet. Be the first to comment.
Qualities that make outstanding builders.

Bipedal vs quadrupedal: how many legs This is about the number of legs the creature walks on. Bipedal. Two legs. Humans, ostriches, T-rex, kangaroos, most fantasy humanoids. Quadrupedal. Four legs. Do

Intro You hear "lerp" and "smoothstep" everywhere in game dev. They sound like math jargon. They're not. Both are small tools that do the same job: smoothly move from one value to another. The problem

What is Kinematics Kinematics is the math field. It's the study of how things move without worrying about forces (which would be dynamics). FK and IK are the two branches: forward kinematics and inver

Intro Textures are usually the biggest cost in a 3D scene. Memory, bandwidth, and load time all get eaten by them. Resizing them is the obvious lever. There's more. This post is about the less obvious

I hit an error like this:
KTX2 texture decoded to 512x286, which is incompatible with block size 4x4
I assumed the texture needed to be square (width = height). That was wrong.
Block compression formats don't store individual pixels. They divide the image into 4x4 pixel blocks and compress each block as a single unit.
For each 4x4 block, BC7 stores about 16 bytes that approximate all 16 pixels in that block. The GPU hardware knows how to decode any single pixel out of that block when sampling.
Because the unit of storage is a 4x4 block, the encoder physically cannot encode partial blocks. Every dimension of the input image must be a multiple of 4.
512 x 512: fine. 128 blocks wide, 128 blocks tall.
1024 x 768: fine. Both divisible by 4.
512 x 286: broken. 286 / 4 = 71.5. You can't have half a block.
286 isn't a multiple of 4. That's the actual problem.
Square means width equals height. That's a completely separate thing from the block size constraint.
512 x 512: square AND multiple of 4. Works.
1024 x 768: NOT square but multiple of 4. Works.
512 x 286: NOT square AND not multiple of 4. Fails.
511 x 511: SQUARE but not multiple of 4. Also fails.
The constraint is "both dimensions divisible by 4." Aspect ratio doesn't matter at all.
This is where my confusion came from. Forcing all textures to 1:1 (square) is too aggressive. Banners, UI strips, sky backdrops, and tons of other legitimate textures are not square. The real fix is to round each dimension to the nearest multiple of 4 independently. 286 becomes 284 or 288. 512 stays 512.
Take the input dimensions, round each one to the nearest multiple of 4, resize the image, then run the BC encoder.
512 x 286 → 512 x 284 (or 288)
A 2-pixel resize is invisible. Users won't notice. Pipeline doesn't crash. Done.