Add Texture Sampler State as an Asset Type

Sampler states are structures that describe what filtering and wrapping operations a shader should perform when reading from a texture. In older graphics API’s (pre-Direct3D10), textures and samplers were bound together in a single object. Currently this is how unity treats them with sampler states being defined as part of a texture’s properties and there being no way to create or reference a sampler state apart from a texture. In “newer” API’s (newer being over a decade old at this point!) the two are distinct objects and are bound to shaders separately. Shaders are free to sample textures with any sampler state, but Unity only binds states corresponding to assigned textures and hard-coded states defined by giving their variable a magic name. Additionally, Unity only supports the small selection of sampler state configurations available to DirectX9.

Proposal: Add a new asset type that defines a sampler state. This should contain:

  • The behavior of wrapping on the U, V, and W axes

  • minification and magnification filter modes

  • Mip LOD bias

  • Number of anisotropic samples

  • Reference value comparison operator

  • (Optionally) Graphics API-specific properties

Sampler State assets should be able to be set on materials in the same way as textures, and properties for them should be added to ShaderLab’s syntax. Additionally there should be API’s for:

  • Creating and modifying a sampler state object from code

  • Assigning a sampler state as a global shader property, both directly and from a command buffer

  • Native plugin API’s, including getting a pointer to the underlying native sampler object and creating a managed sampler object from a pointer to an externally created native sampler

  • Setting a sampler object as an override to a texture’s internally defined sampler

The current texture-defined sampler states are restricted to values compatible with openGL and D3D9. These are safe, and should be treated as the default set of values for the sampler asset.

Every newer API supports more complex sampler states, but each API differs quite dramatically in what it supports. A native plugin API is an easy catch-all taking care of all per-graphics API specifics. but such a solution is overly complex for most cases. A simpler solution to utilize at least some of these would be to provide per-API overrides for the sampler, mirroring the texture compression platform override. For example, Direct3D11 and 12 support more filter modes but are limited to specific combinations of filtering values defined by an enum (see [D3D11], [D3D12]). Conversely, Vulkan sampler states support arbitrary combinations and even more sampling parameters like mipmap range clamping, border colors, and coordinate normalization ([Vk]). Another example is the min/max filter modes which are supported by D3D11 and 12 but not OpenGL, Metal, or base Vulkan (but is available via an an extension [Vk]). While per-API overrides could get complicated quickly, given how common D3D11 and 12 are and how few states they support it should at least be possible to access all of them.

Hi, thanks for the detailed information, our folks are aware of those limitation, but at the same time Unity is a generic engine that can scale on a wide range of platform and have historical choice that remain.

You can have separate sampler control currently when dealing with the ShaderGraph, (I think Amplify allow this as well). But indeed there is still limitation. I don’t have the answers, will ask around.