Пример #1
0
        private void PreRenderMesh(RenderContext context, RenderMesh renderMesh)
        {
            var contextParameters = context.Parameters;
            RenderModelLights renderModelLights;

            if (!modelToLights.TryGetValue(renderMesh.RenderModel, out renderModelLights))
            {
                contextParameters.Set(LightingKeys.DirectLightGroups, null);
                contextParameters.Set(LightingKeys.EnvironmentLights, null);
                return;
            }

            // TODO: copy shadow receiver info to mesh
            var isShadowReceiver = renderMesh.IsShadowReceiver;

            if (currentModelLightShadersPermutationEntry != renderModelLights.LightShadersPermutation || currentModelShadersParameters != renderModelLights.Parameters || currentShadowReceiver != isShadowReceiver)
            {
                currentModelLightShadersPermutationEntry = renderModelLights.LightShadersPermutation;
                currentModelShadersParameters            = renderModelLights.Parameters;
                currentShadowReceiver = isShadowReceiver;

                if (currentShadowReceiver)
                {
                    currentModelShadersParameters.Parameters.CopySharedTo(contextParameters);
                }
                else
                {
                    currentModelShadersParameters.ParametersNoShadows.CopySharedTo(contextParameters);
                }
            }
        }
 public RenderModelLights(LightShaderPermutationEntry lightShadersPermutation, LightParametersPermutationEntry parameters)
 {
     LightShadersPermutation = lightShadersPermutation;
     Parameters = parameters;
 }
        private void PreRenderMesh(RenderContext context, RenderMesh renderMesh)
        {
            var contextParameters = context.Parameters;
            RenderModelLights renderModelLights;
            if (!modelToLights.TryGetValue(renderMesh.RenderModel, out renderModelLights))
            {
                contextParameters.Set(LightingKeys.DirectLightGroups, null);
                contextParameters.Set(LightingKeys.EnvironmentLights, null);
                return;
            }

            // TODO: copy shadow receiver info to mesh
            var isShadowReceiver = renderMesh.IsShadowReceiver;
            if (currentModelLightShadersPermutationEntry != renderModelLights.LightShadersPermutation || currentModelShadersParameters != renderModelLights.Parameters || currentShadowReceiver != isShadowReceiver)
            {
                currentModelLightShadersPermutationEntry = renderModelLights.LightShadersPermutation;
                currentModelShadersParameters = renderModelLights.Parameters;
                currentShadowReceiver = isShadowReceiver;

                if (currentShadowReceiver)
                {
                    currentModelShadersParameters.Parameters.CopySharedTo(contextParameters);
                }
                else
                {
                    currentModelShadersParameters.ParametersNoShadows.CopySharedTo(contextParameters);
                }
            }
        }
        protected override void DrawCore(RenderContext context)
        {
            modelProcessor = SceneInstance.GetCurrent(context).GetProcessor<ModelProcessor>();
            lightProcessor = SceneInstance.GetCurrent(context).GetProcessor<LightProcessor>();

            // No light processors means no light in the scene, so we can early exit
            if (lightProcessor == null || modelProcessor == null)
            {
                return;
            }

            // Not in the context of a SceneCameraRenderer? just exit
            sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current);
            sceneCamera = context.Tags.Get(CameraComponentRenderer.Current);
            if (sceneCameraRenderer == null || sceneCamera == null)
            {
                return;
            }
            sceneCullingMask = sceneCameraRenderer.CullingMask;

            // Setup the callback on the ModelRenderer and shadow map LightGroupRenderer
            if (!isModelComponentRendererSetup)
            {
                // TODO: Check if we could discover declared renderers in a better way than just hacking the tags of a component
                var modelRenderer = ModelComponentRenderer.GetAttached(sceneCameraRenderer);
                if (modelRenderer == null)
                {
                    return;
                }

                modelRenderer.Callbacks.PreRenderModel += PrepareRenderModelForRendering;
                modelRenderer.Callbacks.PreRenderMesh += PreRenderMesh;

                // TODO: Make this pluggable
                // TODO: Shadows should work on mobile platforms
                if (context.GraphicsDevice.Features.Profile >= GraphicsProfile.Level_10_0
                    && (Platform.Type == PlatformType.Windows || Platform.Type == PlatformType.WindowsStore || Platform.Type == PlatformType.Windows10))
                {
                    shadowMapRenderer = new ShadowMapRenderer(modelRenderer.EffectName);
                    shadowMapRenderer.Renderers.Add(typeof(LightDirectional), new LightDirectionalShadowMapRenderer());
                    shadowMapRenderer.Renderers.Add(typeof(LightSpot), new LightSpotShadowMapRenderer());
                }

                isModelComponentRendererSetup = true;
            }

            // Collect all visible lights
            CollectVisibleLights();

            // Draw shadow maps
            if (shadowMapRenderer != null)
                shadowMapRenderer.Draw(context, visibleLightsWithShadows);

            // Prepare active renderers in an ordered list (by type and shadow on/off)
            CollectActiveLightRenderers(context);

            currentModelLightShadersPermutationEntry = null;
            currentModelShadersParameters = null;
            currentShadowReceiver = true;

            // Clear the cache of parameter entries
            lightParameterEntries.Clear();
            parameterCollectionEntryPool.Clear();

            // Clear association between model and lights
            modelToLights.Clear();

            // Clear all data generated by shader entries
            foreach (var shaderEntry in shaderEntries)
            {
                shaderEntry.Value.ResetGroupDatas();
            }
        }
Пример #5
0
        private unsafe bool PrepareLightParameterEntry(RenderThreadContext context, LightParametersPermutationEntry lightParameterEntry, RenderEffect renderEffect)
        {
            var lightShadersPermutation = lightParameterEntry.ShaderPermutationEntry;

            // Create layout for new light shader permutations
            if (lightShadersPermutation.PerLightingLayout == null || lightShadersPermutation.PerLightingLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index].Hash)
            {
                var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index];
                if (resourceGroupDescription.DescriptorSetLayout == null)
                {
                    return(false);
                }

                var parameterCollectionLayout = lightShadersPermutation.ParameterCollectionLayout = new ParameterCollectionLayout();
                parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout);
                lightShadersPermutation.ResourceCount = parameterCollectionLayout.ResourceCount;

                // Process PerLighting cbuffer (if any)
                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    lightShadersPermutation.ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection;
                    parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection);
                }

                lightShadersPermutation.PerLightingLayout = ResourceGroupLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription, renderEffect.Effect.Bytecode);
            }

            // Assign layout to new parameter permutations
            var parameters = lightParameterEntry.Parameters;

            if (parameters.Layout != lightShadersPermutation.ParameterCollectionLayout)
            {
                // TODO GRAPHICS REFACTOR should we recompute or store the parameter layout?
                parameters.UpdateLayout(lightShadersPermutation.ParameterCollectionLayout);
            }

            // Do we need to allocate resources?
            if (lightParameterEntry.LastFrameUsed == RenderSystem.FrameCounter)
            {
                return(true);
            }

            lightParameterEntry.LastFrameUsed = RenderSystem.FrameCounter;

            // Set values
            foreach (var lightGroup in lightParameterEntry.DirectLightGroupDatas)
            {
                lightGroup.ApplyParameters(parameters);
            }

            foreach (var lightGroup in lightParameterEntry.EnvironmentLightDatas)
            {
                lightGroup.ApplyParameters(parameters);
            }

            context.ResourceGroupAllocator.PrepareResourceGroup(lightShadersPermutation.PerLightingLayout, BufferPoolAllocationType.UsedMultipleTime, lightParameterEntry.Resources);

            // Set resource bindings in PerLighting resource set
            for (int resourceSlot = 0; resourceSlot < lightShadersPermutation.ResourceCount; ++resourceSlot)
            {
                lightParameterEntry.Resources.DescriptorSet.SetValue(resourceSlot, parameters.ObjectValues[resourceSlot]);
            }

            // Process PerMaterial cbuffer
            if (lightShadersPermutation.ConstantBufferReflection != null)
            {
                var mappedCB = lightParameterEntry.Resources.ConstantBuffer.Data;

                fixed(byte *dataValues = parameters.DataValues)
                Utilities.CopyMemory(mappedCB, (IntPtr)dataValues, lightParameterEntry.Resources.ConstantBuffer.Size);
            }

            return(true);
        }
Пример #6
0
 public RenderModelLights(LightShaderPermutationEntry lightShadersPermutation, LightParametersPermutationEntry parameters)
 {
     LightShadersPermutation = lightShadersPermutation;
     Parameters = parameters;
 }
Пример #7
0
        protected override void DrawCore(RenderContext context)
        {
            modelProcessor = SceneInstance.GetCurrent(context).GetProcessor <ModelProcessor>();
            lightProcessor = SceneInstance.GetCurrent(context).GetProcessor <LightProcessor>();

            // No light processors means no light in the scene, so we can early exit
            if (lightProcessor == null || modelProcessor == null)
            {
                return;
            }

            // Not in the context of a SceneCameraRenderer? just exit
            sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current);
            sceneCamera         = context.Tags.Get(CameraComponentRenderer.Current);
            if (sceneCameraRenderer == null || sceneCamera == null)
            {
                return;
            }
            sceneCullingMask = sceneCameraRenderer.CullingMask;

            // Setup the callback on the ModelRenderer and shadow map LightGroupRenderer
            if (!isModelComponentRendererSetup)
            {
                // TODO: Check if we could discover declared renderers in a better way than just hacking the tags of a component
                var modelRenderer = ModelComponentRenderer.GetAttached(sceneCameraRenderer);
                if (modelRenderer == null)
                {
                    return;
                }

                modelRenderer.Callbacks.PreRenderModel += PrepareRenderModelForRendering;
                modelRenderer.Callbacks.PreRenderMesh  += PreRenderMesh;

                // TODO: Make this pluggable
                // TODO: Shadows should work on mobile platforms
                if (context.GraphicsDevice.Features.Profile >= GraphicsProfile.Level_10_0 &&
                    (Platform.Type == PlatformType.Windows || Platform.Type == PlatformType.WindowsStore || Platform.Type == PlatformType.Windows10))
                {
                    shadowMapRenderer = new ShadowMapRenderer(modelRenderer.EffectName);
                    shadowMapRenderer.Renderers.Add(typeof(LightDirectional), new LightDirectionalShadowMapRenderer());
                    shadowMapRenderer.Renderers.Add(typeof(LightSpot), new LightSpotShadowMapRenderer());
                }

                isModelComponentRendererSetup = true;
            }

            // Collect all visible lights
            CollectVisibleLights();

            // Draw shadow maps
            if (shadowMapRenderer != null)
            {
                shadowMapRenderer.Draw(context, visibleLightsWithShadows);
            }

            // Prepare active renderers in an ordered list (by type and shadow on/off)
            CollectActiveLightRenderers(context);

            currentModelLightShadersPermutationEntry = null;
            currentModelShadersParameters            = null;
            currentShadowReceiver = true;

            // Clear the cache of parameter entries
            lightParameterEntries.Clear();
            parameterCollectionEntryPool.Clear();

            // Clear association between model and lights
            modelToLights.Clear();

            // Clear all data generated by shader entries
            foreach (var shaderEntry in shaderEntries)
            {
                shaderEntry.Value.ResetGroupDatas();
            }
        }