Exemplo n.º 1
0
        private void AddMaterialToArrayAndDictionary(ScatteringParameters scatteringParameters, uint materialArrayIndex)
        {
            // "SetScatteringWidth()" throws an exception if the range is exceeded. // TODO: How to handle this? Don't throw at all?
            SubsurfaceScatteringBlurEffect.SetScatteringWidth(materialArrayIndex, scatteringParameters.ScatteringWidth); // Add the scattering width to the scattering width array.
            if (scatteringParameters.ScatteringKernel != null)
            {
                // TODO: STABILITY: What to do if the scattering width is present but no kernel? The post-process wouldn't be able to handle that correctly.
                //                  Maybe just save a dummy kernel?
                SubsurfaceScatteringBlurEffect.SetScatteringKernel(materialArrayIndex, scatteringParameters.ScatteringKernel);
            }

            scatteringParametersToArrayIndexDictionary[scatteringParameters] = materialArrayIndex; // Add the material to the dictionary and save its associated index in the scattering width array.
        }
Exemplo n.º 2
0
        /// <inheritdoc/>
        public override void Prepare(RenderDrawContext context)
        {
            if (DeduplicateMaterialParameters)
            {
                scatteringParametersToArrayIndexDictionary.Clear();
            }

            // TODO: Generate a material array per view? This could in some cases limit the number of materials present in the array.
            //       In case every object is visible from every view, it wouldn't save us anything though.

            uint materialArrayIndexCounter = 1; // We start at index 1 instead of 0 because we use index 0 to flag (and discard) non-scattering materials.

            // TODO: Not sure if the following line is even necessary, because we don't use any material parameters of material 0 anyway. I mean not even the kernel of material 0 is set. So either set both or none.
            SubsurfaceScatteringBlurEffect.SetScatteringWidth(0, 0.0f);    // This element is unused because a material index of 0 means the material is not a subsurface scattering material and therefore will be skipped by the post-process.

            // Generate the material dictionary that contains only scattering materials:
            //Dispatcher.ForEach(((RootEffectRenderFeature)RootRenderFeature).RenderNodes, (ref RenderNode renderNode) =>   // TODO: PERFORMANCE: Use this instead?
            foreach (RenderNode renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes)
            {
                var perDrawLayout = renderNode.RenderEffect?.Reflection?.PerDrawLayout;
                if (perDrawLayout == null)
                {
                    continue;
                }

                var  renderMesh         = (RenderMesh)renderNode.RenderObject;
                uint materialArrayIndex = 0; // If the mesh doesn't have a scattering kernel we write index 0 into the constant buffer.

                if (HasScatteringKernel(renderMesh.MaterialPass))
                {
                    materialArrayIndex = AddMaterialToDictionaryAndGetArrayIndex(renderMesh, ref materialArrayIndexCounter);
                }

                WriteMaterialIndexIntoRenderNodeConstantBuffer(perDrawLayout, renderNode, materialArrayIndex);
            }

            bool scatteringMaterialsAreVisible = (materialArrayIndexCounter > 1);

            SubsurfaceScatteringBlurEffect.Enabled = scatteringMaterialsAreVisible;   // Disable the post-process if no scattering objects are visible (to save performance).
        }