protected override void CollectCore(RenderContext context) { base.CollectCore(context); using (context.PushTagAndRestore(CameraComponentRendererExtensions.Current, Camera)) { var oldRenderView = context.RenderView; context.RenderSystem.Views.Add(RenderView); context.RenderView = RenderView; OutputSize = context.ViewportState.Viewport0.Size; Viewport = new Viewport((context.ViewportState.Viewport0.Width - ViewportSize) * ViewportPosition.X, (context.ViewportState.Viewport0.Height - ViewportSize) * ViewportPosition.Y, ViewportSize, ViewportSize); using (context.SaveViewportAndRestore()) { context.ViewportState = new ViewportState { Viewport0 = Viewport }; SceneCameraRenderer.UpdateCameraToRenderView(context, RenderView, Camera); Content.Collect(context); } context.RenderView = oldRenderView; } }
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 CollectCore(RenderContext context) { base.CollectCore(context); Camera = previewService.selectedEntity?.Components.Get <CameraComponent>(); // Enable camera incrust only if we have an active camera and IsActive is true // Also disabled when previewing game graphics compositor IsIncrustEnabled = previewService.isActive && !previewService.Rendering.RenderMode.PreviewGameGraphicsCompositor && Camera != null; if (IsIncrustEnabled) { var width = context.ViewportState.Viewport0.Width * 0.3f; var height = context.ViewportState.Viewport0.Height * 0.2f; var aspectRatio = width / height; if (Camera.UseCustomAspectRatio) { // Make sure to respect aspect ratio aspectRatio = Camera.AspectRatio; } else if (GameSettingsAccessor != null) { var renderingSettings = GameSettingsAccessor.GetConfiguration <RenderingSettings>(); if (renderingSettings != null) { aspectRatio = (float)renderingSettings.DefaultBackBufferWidth / (float)renderingSettings.DefaultBackBufferHeight; } } if (width > height * aspectRatio) { width = height * aspectRatio; } else { height = width / aspectRatio; } if (width < 32.0f || height < 32.0f) { // Do not display incrust if too small IsIncrustEnabled = false; } context.RenderSystem.Views.Add(RenderView); context.RenderView = RenderView; // Setup viewport Viewport = new Viewport(0, 0, (int)width, (int)height); using (context.SaveViewportAndRestore()) { context.ViewportState = new ViewportState { Viewport0 = Viewport }; SceneCameraRenderer.UpdateCameraToRenderView(context, RenderView, Camera); using (context.PushRenderViewAndRestore(RenderView)) using (context.PushTagAndRestore(CameraComponentRendererExtensions.Current, Camera)) { Content.Collect(context); } } } }
/// <summary> /// Creates a graphics compositor programatically that renders into a Rendertarget. It can render everything the default Compositor can /// </summary> public static GraphicsCompositor CreateOffscreenCompositor( bool enablePostEffects, Texture renderTarget, CameraComponent camera = null, RenderGroupMask groupMask = RenderGroupMask.All) { #region Render stages var opaqueRenderStage = new RenderStage("Opaque", "Main") { SortMode = new StateChangeSortMode() }; var transparentRenderStage = new RenderStage("Transparent", "Main") { SortMode = new BackToFrontSortMode() }; var shadowMapCaster = new RenderStage("ShadowMapCaster", "ShadowMapCaster") { SortMode = new FrontToBackSortMode() }; var shadowMapCasterrParaboloidRenderStage = new RenderStage("ShadowMapCasterParaboloid", "ShadowMapCasterParaboloid") { SortMode = new FrontToBackSortMode() }; var shadowMapCasterCubeMapRenderStage = new RenderStage("ShadowMapCasterCubeMap", "ShadowMapCasterCubeMap") { SortMode = new FrontToBackSortMode() }; var gBuffer = new RenderStage("GBuffer", "GBuffer") { SortMode = new FrontToBackSortMode() }; #endregion #region RenderFeatures var meshRenderFeature = new MeshRenderFeature { PipelineProcessors = { new MeshPipelineProcessor() { TransparentRenderStage = transparentRenderStage }, new ShadowMeshPipelineProcessor() { DepthClipping = false, ShadowMapRenderStage = shadowMapCaster }, new ShadowMeshPipelineProcessor() { DepthClipping = true, ShadowMapRenderStage = shadowMapCasterrParaboloidRenderStage }, new ShadowMeshPipelineProcessor() { DepthClipping = true, ShadowMapRenderStage = shadowMapCasterCubeMapRenderStage } }, RenderFeatures = { new TransformRenderFeature(), new SkinningRenderFeature(), new MaterialRenderFeature(), new ShadowCasterRenderFeature(), new ForwardLightingRenderFeature() { LightRenderers = { new LightAmbientRenderer(), new LightDirectionalGroupRenderer(), new LightSkyboxRenderer(), new LightClusteredPointSpotGroupRenderer(), new LightPointGroupRenderer() } } }, RenderStageSelectors = { new MeshTransparentRenderStageSelector() { EffectName = "XenkoForwardShadingEffect", OpaqueRenderStage = opaqueRenderStage, TransparentRenderStage = transparentRenderStage, RenderGroup = groupMask }, new ShadowMapRenderStageSelector() { EffectName = "XenkoForwardShadingEffect.ShadowMapCaster", ShadowMapRenderStage = shadowMapCaster, RenderGroup = groupMask }, new ShadowMapRenderStageSelector() { EffectName = "XenkoForwardShadingEffect.ShadowMapCasterParaboloid", ShadowMapRenderStage = shadowMapCasterrParaboloidRenderStage, RenderGroup = groupMask }, new ShadowMapRenderStageSelector() { EffectName = "XenkoForwardShadingEffect.ShadowMapCasterCubeMap", ShadowMapRenderStage = shadowMapCasterCubeMapRenderStage, RenderGroup = groupMask }, new MeshTransparentRenderStageSelector() { EffectName = "XenkoForwardShadingEffect.ShadowMapCaster", OpaqueRenderStage = gBuffer, RenderGroup = groupMask } } }; var spriteRenderFeature = new SpriteRenderFeature() { RenderStageSelectors = { new SpriteTransparentRenderStageSelector() { EffectName = "Test", // TODO: Check this OpaqueRenderStage = opaqueRenderStage, TransparentRenderStage = transparentRenderStage, RenderGroup = groupMask } } }; var backgroundRenderFeature = new BackgroundRenderFeature() { RenderStageSelectors = { new SimpleGroupToRenderStageSelector() { EffectName = "Test", RenderStage = opaqueRenderStage, RenderGroup = groupMask } } }; var uiRenderFeature = new UIRenderFeature() { RenderStageSelectors = { new SimpleGroupToRenderStageSelector() { EffectName = "Test", RenderStage = transparentRenderStage, RenderGroup = groupMask } } }; var particleEmitterRenderFeature = new ParticleEmitterRenderFeature() { RenderStageSelectors = { new ParticleEmitterTransparentRenderStageSelector() { OpaqueRenderStage = opaqueRenderStage, TransparentRenderStage = transparentRenderStage, RenderGroup = groupMask } } }; //TODO: add that when in VL Context (needs VL.Xenko nuget) //var vlLayerRenderfeature = new LayerRenderFeature() //{ // RenderStageSelectors = // { // new SimpleGroupToRenderStageSelector() // { // RenderStage = opaqueRenderStage, // RenderGroup = groupMask // } // } //}; #endregion #region Camera slots var offscreenCameraSlot = new SceneCameraSlot(); if (camera != null) { camera.Slot = offscreenCameraSlot.ToSlotId(); } #endregion #region post fx var postProcessingEffects = enablePostEffects ? new PostProcessingEffects { ColorTransforms = { Transforms = { new ToneMap(), }, }, } : null; if (postProcessingEffects != null) { postProcessingEffects.DisableAll(); postProcessingEffects.ColorTransforms.Enabled = true; } #endregion #region Renderers var forwardRenderer = new ForwardRenderer { Clear = { ClearFlags = ClearRendererFlags.ColorAndDepth, Color = new Color4(0, 0, 0, 0) }, GBufferRenderStage = gBuffer, LightProbes = true, MSAALevel = MultisampleCount.None, //MSAAResolver = new MSAAResolver() { FilterType = MSAAResolver.FilterTypes.BSpline, FilterRadius = 1.0f }, OpaqueRenderStage = opaqueRenderStage, ShadowMapRenderStages = { shadowMapCaster }, //SubsurfaceScatteringBlurEffect, TransparentRenderStage = transparentRenderStage, // TODO: add postFX once their alpha is sorted out PostEffects = postProcessingEffects }; var singleViewforwardRenderer = new ForwardRenderer { Clear = { ClearFlags = ClearRendererFlags.ColorAndDepth, Color = new Color4(0, 0, 0, 0) }, GBufferRenderStage = gBuffer, LightProbes = true, MSAALevel = MultisampleCount.None, //MSAAResolver = new MSAAResolver() { FilterType = MSAAResolver.FilterTypes.BSpline, FilterRadius = 1.0f }, OpaqueRenderStage = opaqueRenderStage, ShadowMapRenderStages = { shadowMapCaster }, //SubsurfaceScatteringBlurEffect, TransparentRenderStage = transparentRenderStage }; #endregion #region Game var game = new SceneCameraRenderer() { Camera = offscreenCameraSlot, Child = new RenderTextureSceneRenderer() { RenderTexture = renderTarget, Child = forwardRenderer, } }; #endregion return(new GraphicsCompositor { Cameras = { offscreenCameraSlot }, RenderStages = { opaqueRenderStage, transparentRenderStage, shadowMapCaster, shadowMapCasterrParaboloidRenderStage, shadowMapCasterCubeMapRenderStage, gBuffer }, RenderFeatures = { meshRenderFeature, spriteRenderFeature, backgroundRenderFeature, uiRenderFeature, particleEmitterRenderFeature, //vlLayerRenderfeature }, Game = game }); }