Available now for lead or senior environment roles, remote or hybrid. Get in touch

← Personal work

Texture Up-res

2026Part of Texture Resolution QCOne octave per level, from the file's own detailMeasured against the real 2K, 4K and 8K

  • Houdini 22
  • Solaris
  • Karma
  • Python

The hero asset that ships a level short cannot be re-textured overnight, and a plain upscale adds nothing. Write Up-res Textures, a button on the Texture Resolution QC node, lays the detail a texture already holds one octave finer, and every claim about it is measured against the real files.

Three plaster walls under a raking light: the true 2K, the own-octave up-res of the 1K, a plain x2 upscale
Write Up-res Textures, a button on the node: the true 2K, the own-octave up-res of the 1K, a plain ×2 upscale, under the same raking light

01

How it works

The tool lays the detail a texture already holds one octave finer: for every output neighborhood, its low band is matched against the input's own low band nearby, at the input's pixel scale, and the matched spot's finest detail becomes the new octave, scaled to the energy the texture's own octave decay predicts. One match per material keeps albedo, normal, roughness and height coherent; the filters wrap, so tiling maps stay seamless; a UDIM set is written whole; the files land as tiled .tx and the resized layer points the materials at them. The pieces are found by PatchMatch over the whole input, read at the output's own pace: the textbook local self-example at 2x pastes every feature twice and turns grain into strokes.

Three plaster walls under a raking light: plain upscale, own-octave up-res, true 2K
Judged the way a texture is judged: the 2K plaster on a 2 m wall under a raking light at 14 degrees, Karma, the same close camera. Plain x2 upscale of the 1K, the own-octave up-res of the 1K, the real 2K; a 300 px crop at 3x below

02

Measured against the real files

It is an estimate, and it is measured: the alley's plaster, 1K up one level against the real 2K from Poly Haven, carries a top octave whose spectrum shape is within a few percent of the true file's, 25 % too strong in energy in the albedo, 7 % in the normal map, and a fifth of it in the roughness, whose structure only appears at 2K. A plain upscale holds 5 %. Chained against the real 4K and 8K: at 4K the look holds and the amounts drift, at 8K the real plaster turns into fibers the 1K never held and the energies are off by 3x. One level is honest, two is a stretch, three is a guess that still reads as the wall under the light, measured rather than assumed; the report of the next cook says what the file really holds.

The maps alone overstate the softness: a normal map is judged by its shading, and under a raking light the up-res wall and the real wall read alike, the real one keeping slightly sharper pits (its finest octave is sparser, a kurtosis of 0.8 against 0.25; the up-res raises its own by a crispness step, and the rest is the limit of what a 1K can say).

Three plaster walls at 8K under the raking light: plain x8 upscale, the 1K up-res'd three levels, the real 8K
Three levels under the same light, the camera 4x closer so a texel keeps its screen size: plain x8 upscale of the 1K, the chain from the 1K, the real 8K. Still the same wall; the real one is grittier in its finest pits, whose octaves hold 2.5x the relief the chain estimated
The real 4K plaster up-res'd one level against the real 8K, under the raking light
From a 4K source, one level: the real 4K up-res'd to 8K against the real 8K, same light and camera. The albedo holds 116 % of the real finest-octave energy, the normal map 93 %, and the two walls read alike; a texture that ships a level short of 8K is the everyday case, and it costs nothing

03

Six other materials

Six other materials went through the same judge: the stochastic ones hold, a regular weave does not (its next octave is its fibers, which the 1K never held), and a map that is smooth at the top gets a noise octave the material never had. The method cannot tell no detail there from detail it has not seen.

Six materials under the raking light, plain upscale, own-octave up-res and the real 2K: brick, cobblestone, planks, rusty metal, fabric, bark
Six other materials through the same judge, 1K up one level against the real 2K: plain x2, own-octave up-res, real. Brick, cobblestone, planks, rust and bark hold, the real set a touch crisper in each. Two checks keep the up-res where it helps: the fabric reads as a regular pattern (lattice peaks in its second-finest octave), since a weave's next octave is its fibers, which the 1K never held, so it is held back to a plain upscale; the rust normal map is smooth at its top, so it gets no invented octave (its top band went from 6x the real one to 1.2x). The amount of new detail now follows the square root of the file's own octave decay: the typical miss against the real 2K fell from 1.7x to 1.25x

04

The whole alley from 1K

The scene test: every texture of the alley swapped to its 1K file, then Write Up-res Textures on the node, Up-res Levels 3, to the sizes the tool recommended (Size Per = Object, measured on 30 Oct with the first footprint metric, area): the crates, the cobblestone and the near plaster wall three levels to 8K, the stove, the seating and the lamps two to 4K, the barrel, the jerrycan, the bench and the back wall one to 2K. Today's defaults give the crates, the cobblestone, the walls, the barrel and the jerrycan the same sizes, so the crops below stand. 36 files, 53 minutes, 16 GB peak, one button. Rendered against the real Poly Haven files at those sizes from the same cameras (demo/upres_scene.py), under a sun added for the comparison (the scene's dome alone left every normal map flat): at 1080p the two alleys are the same picture; at 100 % of a 3840 render the crates at the dolly's start, 4K needed from their 1K, read as the real file after two levels, and at the dolly's end, 8K after three, the grain is still the crate's own while the real scratches are finer.

The push-in's first frame: real textures at the recommended sizes on the left, the 1K scene up-res'd by the tool on the right; below, 100 % crops at 3840 of the crates: 1K, up-res two levels, real 4K
cam_push, frame 1: the crates need 4K here, two levels from their 1K. Top: the real files at the recommended sizes | the 1K scene up-res'd by the tool. Below, 100 % pixels at 3840: everything at 1K, the up-res, the real
The push-in's last frame: real textures at the recommended sizes on the left, the 1K scene up-res'd by the tool on the right; below, 100 % crops at 3840 of the crates: 1K, up-res, real
cam_push, frame 48: the crates need 8K here, three levels. Below, 100 % pixels at 3840: everything at 1K, the up-res, the real 8K; the chain's limit, the grain is the crate's own and the real scratches are finer
cam_shot's first frame: real textures at the recommended sizes on the left, the 1K scene up-res'd by the tool on the right; below, 100 % crops of the barrel and the jerrycan: 1K, up-res, real
cam_shot, frame 1: the barrel and the jerrycan need 2K here, one level from their 1K. Top: the real files at the recommended sizes | the 1K scene up-res'd by the tool. Below, 100 % pixels: everything at 1K, the up-res, the real

Part of Texture Resolution QC, October 2026: the node measures the size each shot needs, and Write Up-res Textures fills the gap for the files that ship a level short. Houdini 22, Solaris, Karma. Demo assets CC0 Poly Haven.