public sealed class TextureDemandHow many texels across the frame needs each of its textures to be, said once a frame.
Remarks
The join Want was written for and that nothing made. Extraction knows a drawable's bounds and which material it is painted in; AssetMaterialSource knows which textures a material samples; neither knows the other, so a streamed texture had no size on it and every texture in a scene wanted to be complete. That is a correct default — see Update — and it means the pool bounds memory without prioritising it: under pressure the least-recently-used order decides which texture is blurry, and the least-recently-used order knows nothing about what is in front of the camera.
Demand is the caller's decision and residency is the service's. This computes what a frame would like and asks for it; TextureStreamer owns the budget, the queue and the eviction order, and is free to answer with something coarser. GrassResidency makes the same split from the other side and its remarks say why: one component deciding both is a component with two budgets in it.
Every frame, and decomposed by material rather than by drawable. The per-drawable pass is one distance, one multiply and one max into an array indexed by material — the same shape and the same cost as LodRenderFeature.Prepare, which already walks this list once per view per frame. Only then does the per-material pass fan the number out to the material's textures, and materials number in the tens where drawables number in the thousands. Amortising over frames was the alternative and is worse for the reason the whole class exists: a want that lags the camera is a swap that happens late, and a swap is an upload. What removes churn is the hysteresis below, not a lower rate.
⚠ One frame stale, and deliberately. This reads RenderSystem.Visibility, which the compositor fills during Draw — so what it sees at the top of Draw is the previous frame's cull. A page takes many frames to arrive, so a signal one frame behind the camera is exact enough; the alternative is running this after the frame is recorded, where the wants it produced could not reach the uploads that same frame.
⚠ A texture no material here paints keeps whatever behaviour it had. Terrain layer textures reach the streamer through AssetTerrainTextures, particle materials through a second MaterialRenderFeature, and a project's own IMaterialSource through neither — none of those is surveyed, so none is sized, so each falls into the "sampled and not sized wants to be complete" branch that has always been there. This narrows what it can see and silences nothing.
Fields and properties (10)
public RenderSystem SystemThe render system whose objects are surveyed.
public MeshRenderFeature MeshesThe feature whose objects they are.
public MaterialRenderFeature MaterialsThe feature that says which material each is painted in.
public AssetMaterialSource PainterWhich textures a material samples.
public AssetTextureSource TexturesWhere the wants are said.
public int ScreenHeightHow many pixels tall the output is, which is what turns a projected size into texels.
public float HysteresisHow far past a rung a width has to go before the rung moves, as a fraction of it.
public int SizedHow many textures were given a width by the last Update.
public long PromotionsHow many times a texture's rung has moved up since this was created.
public long DemotionsAnd down. A texture that leaves the view is neither: it stops being asked for.
Methods (3)
public TextureDemand(RenderSystem system, MeshRenderFeature meshes, MaterialRenderFeature materials, AssetMaterialSource painter, AssetTextureSource textures)Builds the survey over a frame's objects and the sources behind them.
public bool TryGetWidth(AssetReference texture, out int width)The width the last Update asked for, for a texture it sized.
public void Update()Surveys the frame's drawables and says what each of their textures should be.
Used by (3)
- ArenaThirdPersonShooter
- TextureDemandTestsVixen.Engine.Renderer.Tests
- WorldRendererVixen.Engine.Renderer