Tap a texel, or use the arrow keys, to light the texels it combines in every level before it. Level 0 holds depths: a near box on a far wall. With max, each texel keeps the farthest depth under it, so a box nearer than that is in front of everything there. With mean, each texel averages its block, as sampling a smaller level wants.
A texture you draw into, such as an atlas or a depth buffer, has only its first level. Sampling it small needs the smaller levels averaged from it, and an occlusion test needs each level to keep the farthest depth under it, so one texel answers for a whole block of the screen. mipmaps.create fills the levels from your 'use gpu' function of each 2×2 block, in the encoder or compute pass of your frame.
Creates what fills a texture's mip levels, every array layer of each, from the level above. A
level of odd size leaves the last texels of the one above out.
@owns ― a pipeline, a bind group per level: the kernel or the draw that fills a level, and the
views each level reads and writes
@records ― record after whatever writes level 0 or source, before what reads the levels
@param ― texture a float texture with storage usage, or render usage, and sampled usage
@returns ― mipmaps the garbage collector frees with the texture
create(
constroot:TgpuRoot
root,
constfarthest:TgpuTexture<{
size:[1024,512];
format:"r32float";
mipLevelCount:11;
}>&SampledFlag&StorageFlag
farthest,{
Options.combine: mipmaps.Combine
Combines a 2×2 block of the level above into one texel, as a 'use gpu' function.
combine:
import mipmaps
mipmaps.
constlargest:mipmaps.Combine
Keeps the largest of the four per channel, such as the farthest depth over a block.
Fills level 0 from this texture's 2×2 blocks too, such as the depth a pyramid of farthest
depths starts from. It has as many array layers, and blocks past its edge repeat its last
texels. Default leaving level 0 to you.
Records a frame into one encoder and submits once, with a clock. Borrows the root. The
synchronous recorder borrows each frame's encoder.
@submits ― always once a frame after your recorder returns, and again at each frame.submit()
@param ― record your frame, recorded into each frame's encoder
@returns ― a loop you run with each frame's time and destroy
create(
constroot:TgpuRoot
root,(
frame:frames.Frame
frame)=>{
// ... the depth prepass
const
constcompute:TgpuComputePass
compute=
frame:frames.Frame
frame.
Frame.encoder: TgpuCommandEncoder
Records commands for submission after the recorder returns. submit() replaces this encoder.
Read it at each call instead of keeping it, and let the frame submit it.
Records the levels in order. A texture with storage usage fills in a compute pass, the
pass given or one of its own on the encoder. Another fills in render passes on the encoder.
Level 0 is yours to draw or write, and record fills level 1 and on from it. With source, record fills level 0 too, from that texture’s blocks. A source larger than two texels per texel of level 0 leaves its far part out; one smaller repeats its last row and column.
Levels fill as a baker’s texture does: one dispatch per level for a texture with storage usage, and otherwise a render pass per level and array layer, such as for the rgba8unorm-srgb atlas of impostors. Both fill every array layer of a level.
create makes a bind group per level of its texture. of(texture, source) fills another texture of the same format and usage through the same pipeline, with bind groups of its own, such as the other texture of a pair. For a target that a resize replaces, call of through memo with the current texture, so a resize makes bind groups and no pipeline.