{"record":{"id":"0bccac6c07642bc2","repo":"stride3d/stride","slug":"only-texture-cube-are-currently-supported-as-input-of","errorCode":null,"errorMessage":"Only texture cube are currently supported as input of 'LambertianPrefilteringSH' effect.","messagePattern":"Only texture cube are currently supported as input of 'LambertianPrefilteringSH' effect\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.cs","lineNumber":71,"sourceCode":"            firstPassEffect = new ComputeEffectShader(context) { ShaderSourceName = \"LambertianPrefilteringSHEffectPass1\" };\n            secondPassEffect = new ComputeEffectShader(context) { ShaderSourceName = \"LambertianPrefilteringSHEffectPass2\" };\n\n            HarmonicOrder = 3;\n        }\n\n        protected override void DrawCore(RenderDrawContext context)\n        {\n            var inputTexture = RadianceMap;\n            if (inputTexture == null)\n                return;\n\n            const int FirstPassBlockSize = 4;\n            const int FirstPassSumsCount = FirstPassBlockSize * FirstPassBlockSize;\n\n            var faceCount = inputTexture.ViewDimension == TextureDimension.TextureCube ? 6 : 1;\n            if (faceCount == 1)\n            {\n                throw new NotSupportedException(\"Only texture cube are currently supported as input of 'LambertianPrefilteringSH' effect.\");\n            }\n            var inputSize = new Int2(inputTexture.Width, inputTexture.Height); // (Note: for cube maps width = height)\n            var coefficientsCount = harmonicalOrder * harmonicalOrder;\n\n            var sumsToPerfomRemaining = inputSize.X * inputSize.Y * faceCount / FirstPassSumsCount;\n            var partialSumBuffer = NewScopedTypedBuffer(coefficientsCount * sumsToPerfomRemaining, PixelFormat.R32G32B32A32_Float, true);\n\n            // Project the radiance on the SH basis and sum up the results along the 4x4 blocks\n            firstPassEffect.ThreadNumbers = new Int3(FirstPassBlockSize, FirstPassBlockSize, 1);\n            firstPassEffect.ThreadGroupCounts = new Int3(inputSize.X / FirstPassBlockSize, inputSize.Y / FirstPassBlockSize, faceCount);\n            firstPassEffect.Parameters.Set(LambertianPrefilteringSHParameters.BlockSize, FirstPassBlockSize);\n            firstPassEffect.Parameters.Set(SphericalHarmonicsParameters.HarmonicsOrder, harmonicalOrder);\n            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.RadianceMap, inputTexture);\n            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.OutputBuffer, partialSumBuffer);\n            ((RendererBase)firstPassEffect).Draw(context);\n\n            // Recursively applies the pass2 (sums the coefficients together) as long as needed. Swap input/output buffer at each iteration.\n            var secondPassInputBuffer = partialSumBuffer;","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.cs#L53-L89","documentation":"LambertianPrefilteringSH precomputes spherical-harmonics irradiance by running compute passes over the input; it only supports cubemap inputs. DrawCore throws NotSupportedException when the input texture's ViewDimension is not TextureCube.","triggerScenarios":"Calling Draw with inputTexture bound to a 2D/panorama texture instead of a cubemap.","commonSituations":"Feeding an equirectangular environment map directly into SH prefiltering; migrating code that previously accepted 2D inputs.","solutions":["Convert the environment to a cubemap texture before running LambertianPrefilteringSH.","Verify ViewDimension == TextureDimension.TextureCube before drawing.","Use a dedicated 2D irradiance/SH approximation if cubemap conversion is not possible."],"exampleFix":"// before\nshPrefilter.Draw(context, equirectTexture);\n// after\nvar cube = ToCubemap(context, equirectTexture);\nshPrefilter.Draw(context, cube);","handlingStrategy":"validation","validationCode":"if (inputTexture?.ViewDimension != TextureDimension.TextureCube) throw new ArgumentException(\"LambertianPrefilteringSH requires a TextureCube input\");","typeGuard":"bool IsCube(Texture t) => t?.ViewDimension == TextureDimension.TextureCube;","tryCatchPattern":"try { prefilter.Draw(context, inputTexture); } catch (NotSupportedException ex) { log.Error(ex, \"SH prefiltering needs a cubemap input\"); }","preventionTips":["Keep an explicit equirect->cubemap conversion stage in environment pipelines.","Validate ViewDimension at texture assignment time, not draw time."],"tags":["stride","rendering","cubemap","spherical-harmonics"],"backgroundTag":"incompatible-source-type","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}