Hello CesiumJS users!
Materials in Cesium are based on the Fabric schema . This schema defines components (alpha, diffuse, etc.), uniforms, and more. While working on a PR to add an async factory method to the Material class , it came to my attention that Material’s only support certain texture settings (like min and mag filters) at the top-level. There’s no support for per-texture sampler settings (Materials can have multiple textures).
I feel that the most sensible way to support per-texture settings would be to add a property on the schema, “samplers”, which would map each texture name to an object of sampler settings.
The Material schema hasn’t changed for 13 years; while this proposal would be backwards compatible, I’d like to double check with the community that there aren’t any obvious objections to it.
Thanks!
Matt
main
← async-material-constructor
opened 05:24AM - 25 Jul 25 UTC
# Description
There's currently no way to wait for a material to load its req… uired resources, or to know when they're loaded. Currently, the Material constructor only creates functions that *will* load resources, but those functions are only called on subsequent Update calls.
One consequence of this is that our unit tests rely on polling the internal `_imagesLoaded` list to determine when its okay to make assertions. This is verbose and flaky.
For ease of testing and consistency with other APIs (like `Model.fromGltfAsync`), we'd like an analogous `Material.fromTypeAsync` factory function. Because of the current image-loading polling model, and the complexity of the Material creation logic, creating such an async method is a challenge. For more context, see [this comment and following discussion](https://github.com/CesiumGS/cesium/issues/10566#issuecomment-3111564508).
The solution this PR takes is to extract image-loading logic into callable, async functions. The Update loop calls those functions indirectly (similar to before), but now we also call those functions on Material construction and keep a list of the resulting promises. The `fromTypeAsync` constructor can then `await` all the initialization promises, and the caller of `fromTypeAsync` can `await` the result of that.
See [my comment below](https://github.com/CesiumGS/cesium/pull/12767#issuecomment-3120030138) for a commit-by-commit breakdown of this PR.
## Issue number and link
#10566
## Testing plan
[Localhost sandcastle](http://localhost:8080/Apps/Sandcastle/index.html#c=pVRtT9swEP4rp35pkIpTBmwoK2gM2ITEtImXbR8qIZNcU2uJHdlOu4L233d24qQvfCMf2vheHj/35O7i+I3PVMYxXKARdQl3XGYpN7ZAMFJUFdoELBorZA7fuEUteMFmWpX3qwqj4XXJcxzuOYQ3k/A0DhhcaKSLwM4RFgKXqCHKhOFPRMmKEuHhGmZKgxFlVYhU2BVdv+A6BJ+CxGVbDvvpbdEw9ccLJS0XEvVwBC9TCfRwKUpuhZIJzHhhcNSY3UUFRbbWqfy397Fl+I7BJc7IBxxyVLnm1VykoDG1XOZEUkjIMNeIpuHVe04Drdtg8lJeNtHR/sF4zMYjOPS/+yf+7+iYjbu7Dxl8rkWR0dUdxFdUJVq9gqWwc7i/+n3/cHt1CQvUFv86pai+hkgeIjck2gGKWmk63kn/2srTgH/x2EkACu1xTl3DNZcpdqa7uqqUtiywY+sA6+IeMfhFgoKwTkYOgdO1NNYhNoWI9rRZyHZsqCOUnXRv6zceU8MpytB1amGlag2+p6FsqVNb8d3Ob3m4yOAjMnzJifiWHF3OuVnJNIxM14AeI4EhY7H3mLjJf7xRuXpUJFTBV6yS+XCd9ftuTHpyve40O9xCSmXVJRo/SSGoIc770A0Jd6GCiEGOZLPoMC4Ua4o6RWlfmZgPGzP9Q4tSWLFAqI3bKl7zrjVp/ayxa9hWXcYG2Q5o+0OHBjBJ1yktzx45WXsPTvd95lpJVZtXqjhhcJ5lvoSekFXeYKhy9NyflSqdVbiZ88uHeSfrcgzjWRZ1R4ffBqa8RM2ZQevWVvRCa8Qt3nY99WvEcxqMBhNjVwWeNewBPtFCpCGDWhcRdZNF2o8kuomf6vQPWpYa4xJd6CReT51kYgEiO50OttbkdABpwY0hz6wuijvxjNPB2SSm+J3UQvGMPuf3pmFd2Pzg7KYxMsYmMR1fz7RKFU9cbyH/Bw)
Also tested with [the materials sandcastle](https://sandcastle.cesium.com/?src=Materials.html) and everything looks good to me. Feel free to suggest / test with more materials-type sandcastles.
# Author checklist
- [x] I have submitted a Contributor License Agreement
- [x] I have added my name to `CONTRIBUTORS.md`
- [x] I have updated `CHANGES.md` with a short summary of my change
- [x] I have added or updated unit tests to ensure consistent code coverage
- [x] I have updated the inline documentation, and included code examples where relevant
- [x] I have performed a self-review of my code