Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
CubeMapRenderer.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corporation (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 
4 using System;
5 
6 using SiliconStudio.Core;
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Paradox.Effects.Modules.Processors;
9 using SiliconStudio.Paradox.Engine;
10 using SiliconStudio.Paradox.EntityModel;
11 using SiliconStudio.Paradox.Graphics;
12 
13 namespace SiliconStudio.Paradox.Effects.Modules.Renderers
14 {
15  /// <summary>
16  /// Render dynamic cubemaps.
17  /// </summary>
19  {
20  #region Private static members
21 
22  private static readonly Vector3[] TargetPositions = new Vector3[6]
23  {
24  Vector3.UnitX,
25  -Vector3.UnitX,
26  Vector3.UnitY,
27  -Vector3.UnitY,
28  // since camera matrices will flip the z coordinate, we need to swap the Z and -Z faces render target.
29  -Vector3.UnitZ,
30  Vector3.UnitZ,
31  };
32 
33  private static readonly Vector3[] CameraUps = new Vector3[6]
34  {
35  Vector3.UnitY,
36  Vector3.UnitY,
37  Vector3.UnitZ,
38  -Vector3.UnitZ,
39  Vector3.UnitY,
40  Vector3.UnitY
41  };
42 
43  #endregion
44 
45  #region Private members
46 
47  // camera parameters
48  private Matrix[] cameraViewProjMatrices = new Matrix[6];
49 
50  // flag to render in a single pass
51  private bool renderInSinglePass;
52 
53  #endregion
54 
55  #region Constructor
56 
57  /// <summary>
58  /// CubemapRenderer constructor.
59  /// </summary>
60  /// <param name="services">The IServiceRegistry.</param>
61  /// <param name="recursivePipeline">The recursive pipeline.</param>
62  /// <param name="singlePass">A flag stating if the cubemap should be rendered in one or 6 passes.</param>
63  public CubemapRenderer(IServiceRegistry services, RenderPipeline recursivePipeline, bool singlePass) : base(services, recursivePipeline)
64  {
65  // temporary
67  throw new Exception("Cubemaps not supported on profiles below 10.1.");
68  renderInSinglePass = singlePass && (GraphicsDevice.Features.Profile >= GraphicsProfile.Level_10_1);
69  }
70 
71  #endregion
72 
73  #region Protected methods
74 
75  protected override void OnRendering(RenderContext context)
76  {
77  var entitySystem = Services.GetServiceAs<EntitySystem>();
78  var cubemapSourceProcessor = entitySystem.GetProcessor<CubemapSourceProcessor>();
79  if (cubemapSourceProcessor == null)
80  return;
81 
82  foreach (var source in cubemapSourceProcessor.Cubemaps)
83  {
84  if (source.Value.IsDynamic)
85  {
86  if (renderInSinglePass)
87  RenderInSinglePass(context, source.Key, source.Value);
88  else
89  RenderInSixPasses(context, source.Key, source.Value);
90  }
91  }
92  }
93 
94  #endregion
95 
96  #region Private methods
97 
98  /// <summary>
99  /// Renders the cubemap in 6 passes, one for each face.
100  /// </summary>
101  /// <param name="context">The render context.</param>
102  /// <param name="entity">The entity the cubemap is attached to.</param>
103  /// <param name="component">The CubemapSource component.</param>
104  private void RenderInSixPasses(RenderContext context, Entity entity, CubemapSourceComponent component)
105  {
106  var cameraPos = entity.Transformation.Translation;
107  for (var i = 0; i < 6; ++i)
108  {
109  Matrix worldToCamera;
110  Matrix projection;
111  ComputeViewProjectionMatrices(cameraPos, TargetPositions[i], CameraUps[i], component, out worldToCamera, out projection);
112 
113  // TODO: set parameters on another collection?
114  GraphicsDevice.Parameters.Set(TransformationKeys.View, worldToCamera);
115  GraphicsDevice.Parameters.Set(TransformationKeys.Projection, projection);
116  GraphicsDevice.Parameters.Set(CameraKeys.NearClipPlane, component.NearPlane);
117  GraphicsDevice.Parameters.Set(CameraKeys.FarClipPlane, component.FarPlane);
118  GraphicsDevice.Parameters.Set(CameraKeys.FieldOfView, MathUtil.PiOverTwo);
119  GraphicsDevice.Parameters.Set(CameraKeys.Aspect, 1);
120 
121  if (component.RenderTargets == null)
122  component.CreateSingleViewRenderTargets();
123 
124  var renderTarget = component.RenderTargets[i];
125  GraphicsDevice.Clear(component.DepthStencil, DepthStencilClearOptions.DepthBuffer);
126  GraphicsDevice.Clear(renderTarget, Color.Black);
127 
128  GraphicsDevice.SetRenderTargets(component.DepthStencil, renderTarget);
129 
130  // TODO: flip face culling
131 
132  base.OnRendering(context);
133  }
134 
135  GraphicsDevice.SetRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer);
136 
137  GraphicsDevice.Parameters.Remove(TransformationKeys.View);
138  GraphicsDevice.Parameters.Remove(TransformationKeys.Projection);
139  GraphicsDevice.Parameters.Remove(CameraKeys.NearClipPlane);
140  GraphicsDevice.Parameters.Remove(CameraKeys.FarClipPlane);
141  GraphicsDevice.Parameters.Remove(CameraKeys.FieldOfView);
142  GraphicsDevice.Parameters.Remove(CameraKeys.Aspect);
143  GraphicsDevice.Parameters.Remove(CameraKeys.FocusDistance);
144  }
145 
146  /// <summary>
147  /// Renders the cubemap in one pass using a geometry shader.
148  /// </summary>
149  /// <param name="context">The render context.</param>
150  /// <param name="entity">The entity the cubemap is attached to.</param>
151  /// <param name="component">The CubemapSource component.</param>
152  private void RenderInSinglePass(RenderContext context, Entity entity, CubemapSourceComponent component)
153  {
154  var cameraPos = component.Entity.Transformation.Translation;
155  for (var i = 0; i < 6; ++i)
156  {
157  Matrix worldToCamera;
158  Matrix projection;
159  ComputeViewProjectionMatrices(cameraPos, TargetPositions[i], CameraUps[i], component, out worldToCamera, out projection);
160  cameraViewProjMatrices[i] = worldToCamera * projection;
161  }
162 
163  // TODO: set parameters on another collection?
164  GraphicsDevice.Parameters.Set(CameraCubeKeys.CameraViewProjectionMatrices, cameraViewProjMatrices);
165  GraphicsDevice.Parameters.Set(CameraCubeKeys.CameraWorldPosition, cameraPos);
166 
167  if (component.RenderTarget == null)
168  component.CreateFullViewRenderTarget();
169 
170  GraphicsDevice.Clear(component.DepthStencil, DepthStencilClearOptions.DepthBuffer);
171  GraphicsDevice.Clear(component.RenderTarget, Color.Black);
172 
173  GraphicsDevice.SetRenderTargets(component.DepthStencil, component.RenderTarget);
174 
175  base.OnRendering(context);
176 
177  GraphicsDevice.SetRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer);
178 
179  GraphicsDevice.Parameters.Remove(CameraCubeKeys.CameraViewProjectionMatrices);
180  GraphicsDevice.Parameters.Remove(CameraCubeKeys.CameraWorldPosition);
181  }
182 
183  #endregion
184 
185  #region Helpers
186 
187  private static void ComputeViewProjectionMatrices(Vector3 position, Vector3 faceOffset, Vector3 up, CubemapSourceComponent source, out Matrix viewMatrix, out Matrix projection)
188  {
189  viewMatrix = Matrix.LookAtRH(position, position + faceOffset, up);
190  Matrix.PerspectiveFovRH(MathUtil.PiOverTwo, 1, source.NearPlane, source.FarPlane, out projection);
191  }
192 
193  #endregion
194  }
195 }
RenderTarget RenderTarget
The render target of the cubemap.
Game entity. It usually aggregates multiple EntityComponent
Definition: Entity.cs:28
Puts a cubemap at the containing entity location. This could be dynamic (runtime rendered) or static ...
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
A service registry is a IServiceProvider that provides methods to register and unregister services...
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
This Renderer recursively render another RenderPass.
Thread-local storage context used during rendering.
GraphicsDeviceFeatures Features
Gets the features supported by this graphics device.
RenderTarget[] RenderTargets
The render targets of the cubemap.
Manage a collection of entities.
Definition: EntitySystem.cs:22
CubemapRenderer(IServiceRegistry services, RenderPipeline recursivePipeline, bool singlePass)
CubemapRenderer constructor.
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
Defines an entry point for mesh instantiation and recursive rendering.
GraphicsProfile Profile
Features level of the current device.
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47