private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry)
        {
            // TODO GRAPHICS REFACTOR to use Set*() instead of Set*Slow() we would need to pool data by LightShaderPermutationEntry (just like ParameterCollections)

            var parameterCollectionEntry = lightShaderPermutationEntry.ParameterCollectionEntryPool.Add();

            parameterCollectionEntry.Clear();

            var directLightGroups = parameterCollectionEntry.DirectLightGroupDatas;
            var environmentLights = parameterCollectionEntry.EnvironmentLightDatas;

            foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups)
            {
                directLightGroups.Add(directLightGroup.CreateGroupData());
            }

            foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights)
            {
                environmentLights.Add(environmentLightGroup.CreateGroupData());
            }

            foreach (var lightEntry in directLightsPerMesh)
            {
                directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow);
            }

            foreach (var lightEntry in environmentLightsPerMesh)
            {
                environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null);
            }

            return(parameterCollectionEntry);
        }
 public LightParametersPermutationEntry(LightShaderPermutationEntry shaderPermutationEntry)
 {
     ShaderPermutationEntry = shaderPermutationEntry;
     Parameters             = new ParameterCollection();
     DirectLightGroupDatas  = new List <LightShaderGroupData>();
     EnvironmentLightDatas  = new List <LightShaderGroupData>();
 }
Example #3
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);
                }
            }
        }
Example #4
0
        private LightShaderPermutationEntry CreateShaderPermutationEntry()
        {
            var shaderEntry = new LightShaderPermutationEntry();

            // Direct Lights (with or without shadows)
            for (int i = 0; i < directLightShaderGroupEntryKeys.Count; i++)
            {
                var shaderGroupEntry = directLightShaderGroupEntryKeys.Items[i];
                int lightCount       = shaderGroupEntry.Key.LightCount;

                ILightShadowMapShaderGroupData shadowGroupData = null;
                if (shaderGroupEntry.ShadowRenderer != null)
                {
                    // TODO: Cache ShaderGroupData
                    shadowGroupData = shaderGroupEntry.ShadowRenderer.CreateShaderGroupData(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.ShadowType, lightCount);
                }
                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], lightCount, shadowGroupData);

                shaderEntry.DirectLightGroups.Add(lightShaderGroup);
                shaderEntry.DirectLightShaders.Add(lightShaderGroup.ShaderSource);
            }

            // All Direct Lights
            for (int i = 0; i < directLightShaderGroupEntryKeysNoShadows.Count; i++)
            {
                var shaderGroupEntry = directLightShaderGroupEntryKeysNoShadows.Items[i];

                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null);

                shaderEntry.DirectLightGroupsNoShadows.Add(lightShaderGroup);
                shaderEntry.DirectLightShadersNoShadows.Add(lightShaderGroup.ShaderSource);
            }

            // All Environment lights
            for (int i = 0; i < environmentLightShaderGroupEntryKeys.Count; i++)
            {
                var shaderGroupEntry = environmentLightShaderGroupEntryKeys.Items[i];

                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(EnvironmentLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null);

                shaderEntry.EnvironmentLights.Add(lightShaderGroup);
                shaderEntry.EnvironmentLightShaders.Add(lightShaderGroup.ShaderSource);
            }

            return(shaderEntry);
        }
 public RenderModelLights(LightShaderPermutationEntry lightShadersPermutation, LightParametersPermutationEntry parameters)
 {
     LightShadersPermutation = lightShadersPermutation;
     Parameters = parameters;
 }
        private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry)
        {
            var parameterCollectionEntry = parameterCollectionEntryPool.Add();
            parameterCollectionEntry.Clear();

            var directLightGroups = parameterCollectionEntry.DirectLightGroupDatas;
            var directLightGroupsNoShadows = parameterCollectionEntry.DirectLightGroupsNoShadowDatas;
            var environmentLights = parameterCollectionEntry.EnvironmentLightDatas;
            
            foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups)
            {
                directLightGroups.Add(directLightGroup.CreateGroupData());
            }

            foreach (var directLightGroupNoShadow in lightShaderPermutationEntry.DirectLightGroupsNoShadows)
            {
                directLightGroupsNoShadows.Add(directLightGroupNoShadow.CreateGroupData());
            }

            foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights)
            {
                environmentLights.Add(environmentLightGroup.CreateGroupData());
            }

            var parameters = parameterCollectionEntry.Parameters;
            var parametersNoShadows = parameterCollectionEntry.ParametersNoShadows;

            parameters.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShaders);
            parameters.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders);
            parametersNoShadows.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShadersNoShadows);
            parametersNoShadows.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders);

            foreach (var lightEntry in directLightsPerModel)
            {
                directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow);
                directLightGroupsNoShadows[lightEntry.GroupIndexNoShadows].AddLight(lightEntry.Light, null);
            }

            foreach (var lightEntry in environmentLightsPerModel)
            {
                environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null);
            }

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

            foreach (var lightGroup in directLightGroupsNoShadows)
            {
                lightGroup.ApplyParameters(parametersNoShadows);
            }

            foreach (var lightGroup in environmentLights)
            {
                lightGroup.ApplyParameters(parameters);
                lightGroup.ApplyParameters(parametersNoShadows);
            }

            return parameterCollectionEntry;
        }
        private LightShaderPermutationEntry CreateShaderPermutationEntry()
        {
            var shaderEntry = new LightShaderPermutationEntry();

            // Direct Lights (with or without shadows)
            for (int i = 0; i < directLightShaderGroupEntryKeys.Count; i++)
            {
                var shaderGroupEntry = directLightShaderGroupEntryKeys.Items[i];
                int lightCount = shaderGroupEntry.Key.LightCount;

                ILightShadowMapShaderGroupData shadowGroupData = null;
                if (shaderGroupEntry.ShadowRenderer != null)
                {
                    // TODO: Cache ShaderGroupData
                    shadowGroupData = shaderGroupEntry.ShadowRenderer.CreateShaderGroupData(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.ShadowType, lightCount);
                }
                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], lightCount, shadowGroupData);

                shaderEntry.DirectLightGroups.Add(lightShaderGroup);
                shaderEntry.DirectLightShaders.Add(lightShaderGroup.ShaderSource);
            }

            // All Direct Lights
            for (int i = 0; i < directLightShaderGroupEntryKeysNoShadows.Count; i++)
            {
                var shaderGroupEntry = directLightShaderGroupEntryKeysNoShadows.Items[i];

                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(DirectLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null);

                shaderEntry.DirectLightGroupsNoShadows.Add(lightShaderGroup);
                shaderEntry.DirectLightShadersNoShadows.Add(lightShaderGroup.ShaderSource);
            }

            // All Environment lights
            for (int i = 0; i < environmentLightShaderGroupEntryKeys.Count; i++)
            {
                var shaderGroupEntry = environmentLightShaderGroupEntryKeys.Items[i];

                // TODO: Cache LightShaderGroup
                var lightShaderGroup = shaderGroupEntry.LightGroupRenderer.CreateLightShaderGroup(EnvironmentLightGroupsCompositionNames[i], shaderGroupEntry.Key.LightCount, null);

                shaderEntry.EnvironmentLights.Add(lightShaderGroup);
                shaderEntry.EnvironmentLightShaders.Add(lightShaderGroup.ShaderSource);
            }

            return shaderEntry;
        }
        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();
            }
        }
Example #10
0
 public RenderModelLights(LightShaderPermutationEntry lightShadersPermutation, LightParametersPermutationEntry parameters)
 {
     LightShadersPermutation = lightShadersPermutation;
     Parameters = parameters;
 }
Example #11
0
        private LightParametersPermutationEntry CreateParametersPermutationEntry(LightShaderPermutationEntry lightShaderPermutationEntry)
        {
            var parameterCollectionEntry = parameterCollectionEntryPool.Add();

            parameterCollectionEntry.Clear();

            var directLightGroups          = parameterCollectionEntry.DirectLightGroupDatas;
            var directLightGroupsNoShadows = parameterCollectionEntry.DirectLightGroupsNoShadowDatas;
            var environmentLights          = parameterCollectionEntry.EnvironmentLightDatas;

            foreach (var directLightGroup in lightShaderPermutationEntry.DirectLightGroups)
            {
                directLightGroups.Add(directLightGroup.CreateGroupData());
            }

            foreach (var directLightGroupNoShadow in lightShaderPermutationEntry.DirectLightGroupsNoShadows)
            {
                directLightGroupsNoShadows.Add(directLightGroupNoShadow.CreateGroupData());
            }

            foreach (var environmentLightGroup in lightShaderPermutationEntry.EnvironmentLights)
            {
                environmentLights.Add(environmentLightGroup.CreateGroupData());
            }

            var parameters          = parameterCollectionEntry.Parameters;
            var parametersNoShadows = parameterCollectionEntry.ParametersNoShadows;

            parameters.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShaders);
            parameters.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders);
            parametersNoShadows.Set(LightingKeys.DirectLightGroups, lightShaderPermutationEntry.DirectLightShadersNoShadows);
            parametersNoShadows.Set(LightingKeys.EnvironmentLights, lightShaderPermutationEntry.EnvironmentLightShaders);

            foreach (var lightEntry in directLightsPerModel)
            {
                directLightGroups[lightEntry.GroupIndex].AddLight(lightEntry.Light, lightEntry.Shadow);
                directLightGroupsNoShadows[lightEntry.GroupIndexNoShadows].AddLight(lightEntry.Light, null);
            }

            foreach (var lightEntry in environmentLightsPerModel)
            {
                environmentLights[lightEntry.GroupIndex].AddLight(lightEntry.Light, null);
            }

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

            foreach (var lightGroup in directLightGroupsNoShadows)
            {
                lightGroup.ApplyParameters(parametersNoShadows);
            }

            foreach (var lightGroup in environmentLights)
            {
                lightGroup.ApplyParameters(parameters);
                lightGroup.ApplyParameters(parametersNoShadows);
            }

            return(parameterCollectionEntry);
        }
Example #12
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();
            }
        }