Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
LightingIBLRenderer.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (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.EntityModel;
10 using SiliconStudio.Paradox.Graphics;
11 
12 namespace SiliconStudio.Paradox.Effects.Modules.Renderers
13 {
14  /// <summary>
15  /// Computes cubemaps contribution of the ambient specular.
16  /// </summary>
18  {
19  #region Public static members
20 
21  public static readonly ParameterKey<Texture> IBLLightingTexture = ParameterKeys.New<Texture>();
22 
23  #endregion
24 
25  #region Private members
26 
27  private string specularEffectName;
28 
29  private bool clearTarget;
30 
31  private bool externRenderTarget;
32 
33  private RenderTarget IBLRenderTarget;
34 
35  private DepthStencilBuffer readOnlyDepthBuffer;
36 
37  private GeometricPrimitive cubemapMesh;
38 
39  private Effect IBLEffect;
40 
41  private BlendState IBLBlendState;
42 
43  private DepthStencilState IBLDepthStencilState;
44 
45  private ParameterCollection parameters;
46 
47  #endregion
48 
49  #region Public properties
50 
51  /// <summary>
52  /// The texture the lighting will be rendered into.
53  /// </summary>
54  public Texture IBLTexture
55  {
56  get
57  {
58  return IBLRenderTarget == null ? null : IBLRenderTarget.Texture;
59  }
60  }
61 
62  #endregion
63 
64  #region Constructor
65 
66  /// <summary>
67  /// This renderer will compute the cubemap influence on the scene. It supposes a deferred shading/rendering pipeline. Will set a RenderTarget and a DepthStencilBuffer.
68  /// </summary>
69  /// <param name="services">The services.</param>
70  /// <param name="effectName">The name of the effect to create the specular ambient buffer.</param>
71  /// <param name="depthBuffer">The depth buffer. Should be read only.</param>
72  /// <param name="renderTarget">The render target. If null, a new render target will be created.</param>
73  /// <param name="clearRenderTarget">A flag to enable the clear of the render target.</param>
74  public LightingIBLRenderer(IServiceRegistry services, string effectName, DepthStencilBuffer depthBuffer, RenderTarget renderTarget = null, bool clearRenderTarget = true) : base(services)
75  {
76  if (depthBuffer == null)
77  throw new ArgumentNullException("depthBuffer");
78 
79  specularEffectName = effectName ?? "CubemapIBLSpecular";
80 
81  readOnlyDepthBuffer = depthBuffer;
82 
83  if (renderTarget != null)
84  {
85  if (renderTarget.Width != readOnlyDepthBuffer.Description.Width
86  || renderTarget.Height != readOnlyDepthBuffer.Description.Height)
87  throw new Exception("Size of readOnlyDepthBuffer and renderTarget do not match.");
88  IBLRenderTarget = renderTarget;
89  externRenderTarget = true;
90  }
91 
92  clearTarget = clearRenderTarget;
93  }
94 
95  #endregion
96 
97  #region Public methods
98 
99  /// <inheritdoc/>
100  public override void Load()
101  {
102  base.Load();
103 
104  // Create necessary objects
105  if (IBLRenderTarget == null)
106  IBLRenderTarget = Texture2D.New(GraphicsDevice, readOnlyDepthBuffer.Description.Width, readOnlyDepthBuffer.Description.Height, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget();
107 
108  cubemapMesh = GeometricPrimitive.Cube.New(GraphicsDevice);
109 
110  var blendStateDescr = new BlendStateDescription()
111  {
112  RenderTargets = new[]
113  {
115  {
116  BlendEnable = true,
117  ColorSourceBlend = Blend.SourceAlpha,
118  ColorDestinationBlend = Blend.One,
119  ColorBlendFunction = BlendFunction.Add,
120  AlphaSourceBlend = Blend.One,
121  AlphaDestinationBlend = Blend.One,
122  AlphaBlendFunction = BlendFunction.Add,
123  ColorWriteChannels = ColorWriteChannels.All
124  }
125  }
126  };
127  IBLBlendState = BlendState.New(GraphicsDevice, blendStateDescr);
128 
129  // depth state to test z-fail of backfaces
130  IBLDepthStencilState = DepthStencilState.New(GraphicsDevice, new DepthStencilStateDescription(true, false)
131  {
132  StencilEnable = false,
133  DepthBufferFunction = CompareFunction.GreaterEqual,
134  });
135 
136  // effect
137  IBLEffect = EffectSystem.LoadEffect(specularEffectName);
138 
139  parameters = new ParameterCollection();
140  parameters.Set(RenderTargetKeys.DepthStencilSource, readOnlyDepthBuffer.Texture);
141  }
142 
143  /// <inheritdoc/>
144  public override void Unload()
145  {
146  base.Unload();
147 
148  parameters.Clear();
149 
150  Utilities.Dispose(ref IBLEffect);
151  Utilities.Dispose(ref IBLDepthStencilState);
152  Utilities.Dispose(ref IBLBlendState);
153  Utilities.Dispose(ref cubemapMesh);
154  if (!externRenderTarget)
155  Utilities.Dispose(ref IBLRenderTarget);
156  }
157 
158  #endregion
159 
160  #region Private methods
161 
162  protected override void OnRendering(RenderContext context)
163  {
164  var entitySystem = Services.GetServiceAs<EntitySystem>();
165  var cubemapSourceProcessor = entitySystem.GetProcessor<CubemapSourceProcessor>();
166  if (cubemapSourceProcessor == null)
167  return;
168 
169  // clear render target
170  if (clearTarget)
171  GraphicsDevice.Clear(IBLRenderTarget, new Color4(0, 0, 0, 0));
172 
173  // if no cubemap, exit
174  if (cubemapSourceProcessor.Cubemaps.Count <= 0)
175  return;
176 
177  // set render target
178  GraphicsDevice.SetRenderTarget(readOnlyDepthBuffer, IBLRenderTarget);
179 
180  // set depth state
181  GraphicsDevice.SetDepthStencilState(IBLDepthStencilState);
182 
183  // set culling
184  GraphicsDevice.SetRasterizerState(GraphicsDevice.RasterizerStates.CullFront);
185 
186  // set blend state
187  GraphicsDevice.SetBlendState(IBLBlendState);
188 
189  foreach (var cubemap in cubemapSourceProcessor.Cubemaps)
190  {
191  // set world matrix matrices
192  // TODO: rotation of cubemap & cube mesh
193  parameters.Set(TransformationKeys.World, ComputeTransformationMatrix(cubemap.Value.InfluenceRadius, cubemap.Key.Transformation.Translation));
194  parameters.Set(CubemapIBLBaseKeys.CubemapRadius, cubemap.Value.InfluenceRadius);
195  parameters.Set(CubemapIBLBaseKeys.Cubemap, cubemap.Value.Texture);
196  parameters.Set(CubemapIBLBaseKeys.CubemapPosition, cubemap.Key.Transformation.Translation);
197 
198  // apply effect
199  IBLEffect.Apply(parameters, context.CurrentPass.Parameters);
200 
201  // render cubemap
202  cubemapMesh.Draw(GraphicsDevice);
203  }
204 
205  IBLEffect.UnbindResources();
206 
207  // TODO: revert to correct old settings
208  GraphicsDevice.SetDepthStencilState(GraphicsDevice.DepthStencilStates.None);
209  GraphicsDevice.SetRasterizerState(GraphicsDevice.RasterizerStates.CullBack);
210  GraphicsDevice.SetBlendState(GraphicsDevice.BlendStates.Default);
211  }
212 
213  #endregion
214 
215  #region Helpers
216 
217  private static Matrix ComputeTransformationMatrix(float size, Vector3 position)
218  {
219  // x2 because the size is a radius
220  return Matrix.Scaling(2 * size) * Matrix.Translation(position);
221  }
222 
223  #endregion
224  }
225 }
LightingIBLRenderer(IServiceRegistry services, string effectName, DepthStencilBuffer depthBuffer, RenderTarget renderTarget=null, bool clearRenderTarget=true)
This renderer will compute the cubemap influence on the scene. It supposes a deferred shading/renderi...
Key of an effect parameter.
Definition: ParameterKey.cs:15
override void Unload()
Unloads this instance. This method is called when a RenderPass is de-attached (directly or indirectly...
Contains depth-stencil state for the device.
Computes cubemaps contribution of the ambient specular.
Performs render pipeline transformations attached to a specific RenderPass.
Definition: Renderer.cs:13
A geometric primitive. Use Cube, Cylinder, GeoSphere, Plane, Sphere, Teapot, Torus. See Draw+vertices to learn how to use it.
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
A service registry is a IServiceProvider that provides methods to register and unregister services...
static void Translation(ref Vector3 value, out Matrix result)
Creates a translation matrix using the specified offsets.
Definition: Matrix.cs:2672
Represents a color in the form of rgba.
Definition: Color4.cs:42
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.
override void Load()
Loads this instance. This method is called when a RenderPass is attached (directly or indirectly) to ...
Thread-local storage context used during rendering.
Manage a collection of entities.
Definition: EntitySystem.cs:22
ColorWriteChannels
Identify which components of each pixel of a render target are writable during blending.
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
A container to handle a hierarchical collection of effect variables.
Base class for texture resources.
Definition: Texture.cs:38
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47