stride3d/stride · error · NotSupportedException

Only cubemaps are currently supported as input

Error message

Only cubemaps are currently supported as input

What it means

RadiancePrefilteringGGXNoCompute expects RadianceMap to be a cubemap texture (ViewDimension == TextureCube). DrawCore throws NotSupportedException when the input is null or any other view dimension (e.g. Texture2D).

Solutions

  1. Assign a cubemap texture (ViewDimension TextureCube, render-targetable if you also generate mips) to RadianceMap.
  2. Convert equirectangular panoramas to a cubemap first (e.g. via the equiangular-to-cube effect).
  3. Check input.ViewDimension == TextureDimension.TextureCube before drawing.

Example fix

// before
prefilter.RadianceMap = equirectangularTexture; // Texture2D
// after
prefilter.RadianceMap = cubemapTexture; // ViewDimension == TextureCube
Defensive patterns

Strategy: validation

Validate before calling

if (input == null || input.ViewDimension != TextureDimension.TextureCube) throw new ArgumentException("RadianceMap must be a cubemap texture");

Type guard

bool IsCubemap(Texture t) => t?.ViewDimension == TextureDimension.TextureCube;

Try / catch

try { prefilter.Draw(context); } catch (NotSupportedException ex) { log.Error(ex, "Convert the environment map to a cubemap before prefiltering"); }

Prevention

When it happens

Trigger: Drawing the prefilter with RadianceMap set to a 2D texture or panorama, or leaving RadianceMap unset.

Common situations: Trying to prefilter an equirectangular HDRI directly instead of first converting it to a cubemap; wiring up the wrong texture slot in the IBL generation chain.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/d72138d5a35b78ef. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoCompute.cs:86

                if (!MathUtil.IsPow2(value))
                    throw new ArgumentException("The provided value should be a power of 2");

                samplingsCount = Math.Max(1, value);
            }
        }

        protected override void DrawCore(RenderDrawContext context)
        {
            var output = PrefilteredRadiance;
            if (output == null || (output.ViewDimension != TextureDimension.Texture2D && output.ViewDimension != TextureDimension.TextureCube) || output.ArraySize != 6)
                throw new NotSupportedException("Only array of 2D textures are currently supported as output");

            if (!output.IsRenderTarget)
                throw new NotSupportedException("Only render targets are supported as output");

            var input = RadianceMap;
            if (input == null || input.ViewDimension != TextureDimension.TextureCube)
                throw new NotSupportedException("Only cubemaps are currently supported as input");

            var roughness = 0f;
            var faceCount = output.ArraySize;
            var levelSize = new Int2(output.Width, output.Height);
            var mipCount = MipmapGenerationCount == 0 ? output.MipLevelCount : MipmapGenerationCount;

            for (int mipLevel = 0; mipLevel < mipCount; mipLevel++)
            {
                for (int faceIndex = 0; faceIndex < faceCount; faceIndex++)
                {
                    using var outputView = output.ToTextureView(ViewType.Single, faceIndex, mipLevel);
                    var inputLevel = MathUtil.Log2(input.Width / output.Width);
                    if (mipLevel == 0 && DoNotFilterHighestLevel)
                    {
                        if (input.Width >= output.Width && inputLevel < input.MipLevelCount && input.Format == output.Format) // TODO: This comparison excludes sRGB to/from non-sRGB, which are indistinguishable in memory
                        {
                            // Optimization: make a simple copy of the texture when possible
                            var inputSubresource = inputLevel + faceIndex * input.MipLevelCount;

View on GitHub (pinned to 96fad776d2)