/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself. /// </summary> /// <param name="gameTime">Time passed since the last call to Draw.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public void Draw(GameTime gameTime, DeferredRenderSystem renderSystem) { if (this.GetWorldDrawBounds().Intersects(renderSystem.GetCameraRenderBounds())) { this.Render(gameTime, renderSystem); } }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem) { if (this.currentAnimation != null && !this.currentAnimation.IsStopped) { base.DrawOptionsMap(gameTime, renderSystem, this.currentAnimation.GetCurrentFrameBounds()); } }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> /// <param name="drawBoundingBox">The bounding box of the sprite within the texture.</param> protected void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem, Rectangle drawBoundingBox) { renderSystem.BeginRender(this.optionMapFlagsShader); this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this); renderSystem.DrawSprite(this.spriteTexture, this.Position, drawBoundingBox, Color.White, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None); renderSystem.EndRender(); }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="technique">Technique to use (can be null)</param> protected override void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique) { base.ConfigureShader(renderSystem, technique); this.ShaderAsset.Parameters["colorMap"].SetValue(renderSystem.RenderTargets.ColorMap); this.ShaderAsset.Parameters["lightMap"].SetValue(renderSystem.RenderTargets.LightMap); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to Draw.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> protected override void Render(GameTime gameTime, DeferredRenderSystem renderSystem) { RenderTarget2D shadowMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // The core shadow map this.GenerateShadowMap(renderSystem, shadowMap); renderSystem.SetRenderTargets(RenderTargetTypes.LightMap, 1); // Request light map as output this.PostProcessEffect.ConfigureShader(renderSystem); // Configure the shader // Set parameters this.PostProcessEffect.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem)); this.PostProcessEffect.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition); this.PostProcessEffect.GetParameter("lightPosition").SetValue(this.PixelPosition); this.PostProcessEffect.GetParameter("lightPower").SetValue(this.Power); this.PostProcessEffect.GetParameter("lightRange").SetValue(this.World.GetPixelFromWorld(this.Range)); this.PostProcessEffect.GetParameter("lightDecay").SetValue(this.Decay); this.PostProcessEffect.GetParameter("lightColor").SetValue(this.Color.ToVector4()); this.PostProcessEffect.GetParameter("specularStrength").SetValue(this.SpecularStrength); this.PostProcessEffect.GetParameter("normalMap").SetValue(renderSystem.RenderTargets.NormalMap); this.PostProcessEffect.GetParameter("optionsMap").SetValue(renderSystem.RenderTargets.OptionsMap); this.PostProcessEffect.GetParameter("shadowMap").SetValue(shadowMap); // Render this.PostProcessEffect.ApplyPass(0); renderSystem.DirectScreenPaint(this.GetWorldDrawBounds()); renderSystem.SetRenderTargets(RenderTargetTypes.None, 0); // Resolve the render target renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(shadowMap); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to be drawn. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(); this.ForEachTile((pos, rect) => renderSystem.DrawSprite(this.SpriteTexture, pos, rect, this.RenderColor, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None)); renderSystem.EndRender(); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to be drawn. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(this.shaderAsset); this.shaderAsset.ConfigureShader(renderSystem); this.shaderAsset.ApplyPass(0); renderSystem.DrawSprite(this.SpriteTexture, this.Position, null, this.RenderColor, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None); renderSystem.EndRender(); }
/// <summary> /// Gets the transform matrix used when rendering the scene. /// </summary> /// <param name="renderSystem">The render system that requires it.</param> /// <returns>The transformation matrix to use when rendering.</returns> public Matrix GetViewMatrix(DeferredRenderSystem renderSystem) { Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle; return(Matrix.CreateTranslation(new Vector3(-this.PixelPosition.X, -this.PixelPosition.Y, 0)) * // Translate into screen space Matrix.CreateRotationZ(-this.Rotation) * // Rotate counter to camera rotation Matrix.CreateScale(new Vector3(this.cameraZoom, this.cameraZoom, 1)) * // Scale based on camera zoom Matrix.CreateTranslation(new Vector3(screenSize.Width * 0.5f, screenSize.Height * 0.5f, 0))); // Translate to center on the screen }
/// <summary> /// Gets the inverted transform matrix used when rendering the scene. /// </summary> /// <param name="renderSystem">The render system that requires it.</param> /// <returns>The inversion of the transformation matrix to use when rendering.</returns> public Matrix GetInvertedViewMatrix(DeferredRenderSystem renderSystem) { Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle; return(Matrix.CreateTranslation(new Vector3(this.PixelPosition.X, this.PixelPosition.Y, 0)) * Matrix.CreateRotationZ(this.Rotation) * Matrix.CreateScale(new Vector3(1 / this.cameraZoom, 1 / this.cameraZoom, 1)) * Matrix.CreateTranslation(new Vector3(-screenSize.Width * 0.5f, -screenSize.Height * 0.5f, 0))); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(this.OptionMapFlagsShader); this.OptionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this); this.ForEachTile((pos, rect) => renderSystem.DrawSprite(this.SpriteTexture, pos, rect, Color.White, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None)); renderSystem.EndRender(); }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="technique">Technique to use</param> protected virtual void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique) { if (!this.isConfigured) { this.InitConfigure(renderSystem); } this.shaderAsset.CurrentTechnique = technique; }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="sprite">The sprite we are rendering.</param> public void ConfigureShaderAndApplyPass(DeferredRenderSystem renderSystem, SpriteBase sprite) { base.ConfigureShader(renderSystem, "ApplyFlagsToOptionsMap"); this.ShaderAsset.Parameters["viewProjection"].SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem)); this.ShaderAsset.Parameters["cameraPosition"].SetValue(renderSystem.GameCamera.PixelPosition); this.ShaderAsset.Parameters["pixelOptions"].SetValue((int)sprite.RenderOptions / 255.0f); this.ShaderAsset.Parameters["specularReflectivity"].SetValue(sprite.SpecularReflectivity); this.ApplyPass(0); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(this.optionMapFlagsShader); this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this); RectangleF posRect = new RectangleF(this.targetSprite.Position.X - this.lineWidth * 2.0f, this.targetSprite.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f); renderSystem.DrawFilledRectangle(posRect, Color.Black, this.Rotation); // Draw position renderSystem.DrawRectangleBorder(this.targetSprite.SpriteWorldBounds, Color.Black, this.lineWidth, 0.0f); // Draw bounding rectangle renderSystem.DrawLine(this.targetSprite.Position, this.targetSprite.Position + this.targetSprite.Velocity, Color.Black, this.lineWidth); // Draw velocity line renderSystem.EndRender(); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its color map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(); RectangleF posRect = new RectangleF(this.targetPostProcess.Position.X - this.lineWidth * 2.0f, this.targetPostProcess.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f); float lineMag = this.targetPostProcess.Velocity.Length(); renderSystem.DrawFilledRectangle(posRect, Color.White, this.targetPostProcess.Rotation); // Draw position renderSystem.DrawRectangleBorder(this.targetPostProcess.GetWorldDrawBounds(), Color.Green, this.lineWidth, 0.0f); // Draw bounding rectangle renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + this.targetPostProcess.Velocity, Color.Blue, this.lineWidth); // Draw velocity line renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + (lineMag * this.targetPostProcess.RotationVector), Color.OrangeRed, this.lineWidth); renderSystem.EndRender(); }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="technique">Technique to use (can be null)</param> protected override void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique) { if (!technique.Name.Equals("ApplyFlagsToOptionsMap")) { throw new ArgumentException("You dun goofed."); } base.ConfigureShader(renderSystem, technique); this.ShaderAsset.Parameters["viewProjection"].SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem)); this.ShaderAsset.Parameters["cameraPosition"].SetValue(renderSystem.GameCamera.PixelPosition); this.ShaderAsset.Parameters["pixelOptions"].SetValue((float)SpriteRenderOptions.None); this.ShaderAsset.Parameters["specularReflectivity"].SetValue(0.5f); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(this.optionMapFlagsShader); this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this); RectangleF posRect = new RectangleF(this.targetPostProcess.Position.X - this.lineWidth * 2.0f, this.targetPostProcess.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f); float lineMag = this.targetPostProcess.Velocity.Length(); renderSystem.DrawFilledRectangle(posRect, Color.Black, this.targetPostProcess.Rotation); // Draw position renderSystem.DrawRectangleBorder(this.targetPostProcess.GetWorldDrawBounds(), Color.Black, this.lineWidth, 0.0f); // Draw bounding rectangle renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + this.targetPostProcess.Velocity, Color.Black, this.lineWidth); // Draw velocity line renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + (lineMag * this.targetPostProcess.RotationVector), Color.Black, this.lineWidth); renderSystem.EndRender(); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem" /> when this <see cref="StaticPostProcess" /> component needs render itself. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to Draw.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem" /> to render with.</param> public override void Draw(GameTime gameTime, DeferredRenderSystem renderSystem) { RenderTarget2D intermediateColorMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // Intermediate map used for selective sampling renderSystem.GraphicsDevice.SetRenderTarget(intermediateColorMap); this.PostProcessEffect.ConfigureShader(renderSystem); this.PostProcessEffect.GetParameter("spriteTexture").SetValue(renderSystem.RenderTargets.ColorMap); this.PostProcessEffect.ApplyPass(0); renderSystem.DirectScreenPaint(); renderSystem.SetRenderTargets(RenderTargetTypes.ColorMap, 1); this.PostProcessEffect.ConfigureShader(renderSystem); this.PostProcessEffect.GetParameter("spriteTexture").SetValue(intermediateColorMap); this.PostProcessEffect.ApplyPass(0); renderSystem.DirectScreenPaint(); renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(intermediateColorMap); }
/// <summary> /// Removes a shadow from sprite or fully covers the sprite in shadow, depending on the layer depth transition. /// </summary> /// <param name="renderSystem">The render system.</param> /// <param name="sprite">The sprite.</param> private void ProcessSpriteDepthTransition(DeferredRenderSystem renderSystem, SpriteBase sprite) { // Remove the shadow map that overlaps with the sprite (or fully cover it) if (sprite.LayerDepth <= this.layerDepth) { this.shadowMapShader.ApplyPass(1); // Remove } if (sprite.SpriteWorldPrimitives != null) { foreach (var currShape in sprite.SpriteWorldPrimitives) { renderSystem.DirectScreenPaint(currShape); } } else { renderSystem.DirectScreenPaint(sprite.SpriteWorldBounds); } }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its color map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem) { renderSystem.BeginRender(); RectangleF posRect = new RectangleF(this.targetSprite.Position.X - this.lineWidth * 2.0f, this.targetSprite.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f); renderSystem.DrawFilledRectangle(posRect, Color.White, this.Rotation); // Draw position // Draw shape outline if it exists if (this.targetSprite.SpriteWorldShape != null) { for (int index = 0; index < this.targetSprite.SpriteWorldShape.Count - 1; index++) { renderSystem.DrawLine(this.targetSprite.SpriteWorldShape[index], this.targetSprite.SpriteWorldShape[index + 1], Color.Red, this.lineWidth); } } renderSystem.DrawRectangleBorder(this.targetSprite.SpriteWorldBounds, Color.Green, this.lineWidth, 0.0f); // Draw bounding rectangle renderSystem.DrawLine(this.targetSprite.Position, this.targetSprite.Position + this.targetSprite.Velocity, Color.Blue, this.lineWidth); // Draw velocity line renderSystem.EndRender(); }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="technique">Technique to use</param> public void ConfigureShader(DeferredRenderSystem renderSystem, string technique) { this.ConfigureShader(renderSystem, this.shaderAsset.Techniques[technique]); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="StaticPostProcess"/> component needs render itself. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to Draw.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public abstract void Draw(GameTime gameTime, DeferredRenderSystem renderSystem);
/// <summary> /// Gets the inverted view projection matrix for the camera. /// </summary> /// <param name="renderSystem">The render system that requires it.</param> /// <returns>The inversion of the product of the view matrix for the camera and the projection matrix used by SpriteBatch when rendering.</returns> public Matrix GetInvertedViewProjectionMatrix(DeferredRenderSystem renderSystem) { return(this.GetInvertedViewMatrix(renderSystem) * this.GetInvertedProjectionMatrix(renderSystem)); }
/// <summary> /// Gets the inverted projection matrix for the camera. /// </summary> /// <param name="renderSystem">The render system that requires it.</param> /// <returns>The inversion of the projection matrix used by SpriteBatch when rendering.</returns> public Matrix GetInvertedProjectionMatrix(DeferredRenderSystem renderSystem) { return(Matrix.Invert(this.GetProjectionMatrix(renderSystem))); }
/// <summary> /// Gets the projection matrix for the camera. /// </summary> /// <param name="renderSystem">The render system that requires it.</param> /// <returns>The projection matrix used by SpriteBatch when rendering.</returns> public Matrix GetProjectionMatrix(DeferredRenderSystem renderSystem) { Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle; return(Matrix.CreateTranslation(-0.5f, -0.5f, 0) * Matrix.CreateOrthographicOffCenter(0, screenSize.Width, screenSize.Height, 0, 0, 1)); }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its normal map. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> public override void DrawNormalMap(GameTime gameTime, DeferredRenderSystem renderSystem) { return; }
/// <summary> /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself. /// Override this method with component-specific drawing code. /// </summary> /// <param name="gameTime">Time passed since the last call to Draw.</param> /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param> protected abstract void Render(GameTime gameTime, DeferredRenderSystem renderSystem);
/// <summary> /// Generates the shadow map to be used when rendering this light. /// </summary> /// <remarks>If this instance is not to cast shadows the shadow map is cleared.</remarks> /// <param name="renderSystem">The render system to render with.</param> /// <param name="shadowMap">The shadow map to render on</param> protected virtual void GenerateShadowMap(DeferredRenderSystem renderSystem, RenderTarget2D shadowMap) { RenderTarget2D intermediateShadowMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // Intermediate map used for selective sampling RectangleF lightDrawBounds = this.GetWorldDrawBounds(); renderSystem.GraphicsDevice.SetRenderTarget(shadowMap); renderSystem.ClearCurrentRenderTarget(Color.White); // Clear the core shadow map // Only render the shadows if we are to cast them if (this.CastsShadows) { // Render the shadow caused by each object within the lights range List <SpriteBase> objectList = this.World.GetSpriteObjectsInArea(lightDrawBounds).Where(currObj => (currObj.RenderOptions & SpriteRenderOptions.CastsShadows) != 0).OrderBy(s => s.LayerDepth).ToList(); if (objectList.Count > 0) { int lastLayerDepth = 0; int lastLayerDepthIndex = 0; bool renderedShadow = false; // This is used so that we don't bother occluding objects if we didn't even render anything lastLayerDepth = (int)objectList[0].LayerDepth; for (int objectIndex = 0; objectIndex < objectList.Count; objectIndex++) { SpriteBase currObj = objectList[objectIndex]; RectangleF spriteWorldBounds = currObj.SpriteWorldBounds; // If the object we found doesn't cast shadows (or we're inside it), skip it if (spriteWorldBounds.Contains(base.Position)) { continue; } this.shadowMapShader.ConfigureShader(renderSystem); // Configure the shader this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem)); this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition); // If we switched light planes remove occlusion from all previous objects if (lastLayerDepth != (int)currObj.LayerDepth) { // Only occlude if we actually rendered something if (renderedShadow) { // Loop through all the objects between the last layer index and the current index for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectIndex; clearObjIndex++) { this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]); } } // Save the last values lastLayerDepth = (int)currObj.LayerDepth; lastLayerDepthIndex = objectIndex; renderedShadow = false; // Reset this } // Create the shadow map caused by the current sprite this.shadowMapShader.ApplyPass(0); // Construct the vertex primitive to mask with Vector2[] extrema; if (currObj.SpriteWorldShape != null) { extrema = currObj.SpriteWorldShape.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow } else { extrema = spriteWorldBounds.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow } Vector2 widthVector = Vector2.Normalize(extrema[0] - base.Position); // Get the vector to the first extrema Vector2 heightVector = Vector2.Normalize(extrema[1] - base.Position); // Get the vector to the second extrema VertexPrimitive shadowArea = new VertexPrimitive(PrimitiveType.TriangleStrip, 4); shadowArea.Add(extrema[0]); shadowArea.Add(extrema[1]); // Let's extend the shadow vector until it hits the edge of the draw bounds shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[0], widthVector)); shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[1], heightVector)); // Let's get the remaining verts that might exist to finish up the rect List <Vector2> interiorVerts = lightDrawBounds.GetInteriorVertices(base.Position, widthVector, heightVector); shadowArea.Add(interiorVerts); // Add the interior verts (if any exist) renderSystem.DirectScreenPaint(shadowArea); // Render the shadow renderedShadow = true; // We just rendered a shadow; keep track of that } // Loop through all the objects between the last layer index and the current index if (renderedShadow) { // Remove the shadows over the LAST shadow plane for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectList.Count; clearObjIndex++) { this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]); } // Blur the shadow map if enabled if (!float.IsPositiveInfinity(this.minShadowBlurDistance)) { renderSystem.GraphicsDevice.SetRenderTarget(intermediateShadowMap); // We need to render to a temp target // Configure the shader this.shadowMapShader.ConfigureShader(renderSystem, 1); // Set parameters this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem)); this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition); this.shadowMapShader.GetParameter("lightPosition").SetValue(base.PixelPosition); this.shadowMapShader.GetParameter("maxBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance)); this.shadowMapShader.GetParameter("minBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance)); this.shadowMapShader.GetParameter("shadowMap").SetValue(shadowMap); this.shadowMapShader.ApplyPass(0); renderSystem.DirectScreenPaint(lightDrawBounds); // Render the shadow renderSystem.GraphicsDevice.SetRenderTarget(shadowMap); // Set the shadow map for final render // Update shadow map this.shadowMapShader.GetParameter("shadowMap").SetValue(intermediateShadowMap); this.shadowMapShader.ApplyPass(0); renderSystem.DirectScreenPaint(lightDrawBounds); // Render } } } } renderSystem.SetRenderTargets(RenderTargetTypes.None, 0); // Resolve the render target renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(intermediateShadowMap); }
/// <summary> /// Called when the shader parameters are to be configured initially. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> protected virtual void InitConfigure(DeferredRenderSystem renderSystem) { this.isConfigured = true; }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> /// <param name="techniqueIndex">Index of the technique to use</param> public void ConfigureShader(DeferredRenderSystem renderSystem, int techniqueIndex) { this.ConfigureShader(renderSystem, this.shaderAsset.Techniques[techniqueIndex]); }
/// <summary> /// Called when the shader parameters are to be configured before rendering. /// </summary> /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param> public void ConfigureShader(DeferredRenderSystem renderSystem) { this.ConfigureShader(renderSystem, 0); }