public void RenderCasters(RenderContext context, EntityGroupMask cullingMask) { context.GraphicsDevice.PushState(); context.PushParameters(shadowCasterParameters); try { CameraComponentRenderer.UpdateParameters(context, ShadowCamera); opaqueRenderItems.Clear(); transparentRenderItems.Clear(); // When rendering shadow maps, objects should not be culled by the rasterizer (in case the object is out of the frustum but cast // a shadow into the frustum) shadowModelComponentRenderer.RasterizerState = shadowRasterizerState; shadowModelComponentRenderer.CurrentCullingMask = cullingMask; shadowModelComponentRenderer.Prepare(context, opaqueRenderItems, transparentRenderItems); shadowModelComponentRenderer.Draw(context, opaqueRenderItems, 0, opaqueRenderItems.Count - 1); } finally { context.PopParameters(); context.GraphicsDevice.PopState(); } }
public void RenderCasters(RenderContext context, EntityGroupMask cullingMask) { context.GraphicsDevice.PushState(); context.PushParameters(shadowCasterParameters); try { CameraComponentRenderer.UpdateParameters(context, ShadowCamera); opaqueRenderItems.Clear(); transparentRenderItems.Clear(); // When rendering shadow maps, objects should not be culled by the rasterizer (in case the object is out of the frustum but cast // a shadow into the frustum) shadowModelComponentRenderer.RasterizerState = shadowRasterizerState; // We should not cull models in the view frustum, as objects can be outside the frustum and cast shadows // TODO: We need at some point to be perform shadow culling based on the frustum of the shadow view shadowModelComponentRenderer.CullingModeOverride = CullingMode.None; shadowModelComponentRenderer.CurrentCullingMask = cullingMask; shadowModelComponentRenderer.Prepare(context, opaqueRenderItems, transparentRenderItems); shadowModelComponentRenderer.Draw(context, opaqueRenderItems, 0, opaqueRenderItems.Count - 1); } finally { context.PopParameters(); context.GraphicsDevice.PopState(); } }
/// <summary> /// Queries the list of <see cref="RenderModelCollection"/> for the specified mask /// </summary> /// <param name="mask">The mask.</param> /// <param name="outputCollection">The output collection.</param> public void QueryModelGroupsByMask(EntityGroupMask mask, List <RenderModelCollection> outputCollection) { // Get all meshes from the render model processor foreach (var renderModelGroup in ModelGroups) { // Perform culling on group and accept if (!mask.Contains(renderModelGroup.Group)) { continue; } outputCollection.Add(renderModelGroup); } }
public void Prepare(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList) { if (Context == null) { Initialize(context); } else if (Context != context) { throw new InvalidOperationException("Cannot use a different context between Load and Draw"); } if (SceneCameraRenderer != null) { CurrentCullingMask = SceneCameraRenderer.CullingMask; } PrepareCore(context, opaqueList, transparentList); }
public void RenderCasters(RenderContext context, EntityGroupMask cullingMask) { context.GraphicsDevice.PushState(); context.PushParameters(shadowCasterParameters); try { CameraComponentRenderer.UpdateParameters(context, ShadowCamera); opaqueRenderItems.Clear(); transparentRenderItems.Clear(); // Query all models for the specified culling mask and collect render models var modelProcessor = SceneInstance.GetProcessor <ModelProcessor>(); shadowRenderModels.Clear(); modelProcessor.QueryModelGroupsByMask(cullingMask, shadowRenderModels); // Copy the ViewProjectionMatrix to the model renderer shadowModelComponentRenderer.ViewProjectionMatrix = ShadowCamera.ViewProjectionMatrix; foreach (var renderModelList in shadowRenderModels) { shadowModelComponentRenderer.RenderModels = renderModelList; shadowModelComponentRenderer.Prepare(context, opaqueRenderItems, transparentRenderItems); } // Render only Opaque items for now // TODO: Add semi-transparent items with light shadowModelComponentRenderer.Draw(context, opaqueRenderItems, 0, opaqueRenderItems.Count - 1); } finally { // Make sure we clear any references left so that we don't hold them in memory shadowRenderModels.Clear(); shadowModelComponentRenderer.RenderModels = null; context.PopParameters(); context.GraphicsDevice.PopState(); } }
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(); } }
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(); } }
public static bool Contains(this EntityGroupMask mask, EntityGroup group) { return(((uint)mask & (1 << (int)group)) != 0); }