public void SetSpotLightParameters(SpotLight light, Microsoft.Xna.Framework.Graphics.Effect effect, Vector3 cameraPos) { bool shadowed = light.Shadowed && this.shadowMapIndices.ContainsKey(light); effect.CurrentTechnique = effect.Techniques[shadowed ? "SpotLightShadowed" : "SpotLight"]; if (shadowed) { effect.Parameters["ShadowMap" + Model.SamplerPostfix].SetValue(this.spotShadowMaps[this.shadowMapIndices[light]]); effect.Parameters["ShadowMapSize"].SetValue(this.spotShadowMapSize); } float horizontalScale = (float)Math.Sin(light.FieldOfView * 0.5f) * light.Attenuation; float depthScale = (float)Math.Cos(light.FieldOfView * 0.5f) * light.Attenuation; effect.Parameters["SpotLightViewProjectionMatrix"].SetValue(Matrix.CreateTranslation(cameraPos) * light.ViewProjection); effect.Parameters["SpotLightPosition"].SetValue(light.Position - cameraPos); Matrix rotation = Matrix.CreateFromQuaternion(light.Orientation); rotation.Forward *= -1.0f; effect.Parameters["SpotLightDirection"].SetValue(rotation.Forward); effect.Parameters["WorldMatrix"].SetValue(Matrix.CreateScale(horizontalScale, horizontalScale, depthScale) * rotation * Matrix.CreateTranslation(light.Position - cameraPos)); effect.Parameters["SpotLightRadius"].SetValue(depthScale); effect.Parameters["SpotLightColor"].SetValue(light.Color); effect.Parameters["Cookie" + Model.SamplerPostfix].SetValue(light.CookieTexture); }
public void RenderSpotShadowMap(SpotLight light, int index) { this.shadowCamera.View.Value = light.View; this.shadowCamera.SetPerspectiveProjection(light.FieldOfView, new Point(this.spotShadowMapSize, this.spotShadowMapSize), 1.0f, Math.Max(2.0f, light.Attenuation)); this.main.GraphicsDevice.SetRenderTarget(this.spotShadowMaps[index]); this.main.GraphicsDevice.Clear(new Color(0, 255, 255)); this.main.DrawScene(this.shadowRenderParameters); }
public override Entity Create(Main main) { Entity result = new Entity(main, "SpotLight"); Transform transform = new Transform(); result.Add("Transform", transform); SpotLight spotLight = new SpotLight(); result.Add("SpotLight", spotLight); return result; }
public void PostProcess(RenderTarget2D result, RenderParameters parameters) { if (this.needBufferReallocation()) { return; } Vector3 originalCameraPosition = parameters.Camera.Position; Matrix originalViewMatrix = parameters.Camera.View; BoundingFrustum originalBoundingFrustum = parameters.Camera.BoundingFrustum; parameters.Camera.Position.Value = Vector3.Zero; Matrix newViewMatrix = originalViewMatrix; newViewMatrix.Translation = Vector3.Zero; parameters.Camera.View.Value = newViewMatrix; RasterizerState originalState = this.main.GraphicsDevice.RasterizerState; bool enableSSAO = this.allowSSAO && this.EnableSSAO; if (enableSSAO) { // Down-sample depth buffer this.downsampleEffect.CurrentTechnique = this.downsampleEffect.Techniques["DownsampleDepth"]; this.sources2[0] = this.depthBuffer; this.sources2[1] = this.normalBuffer; this.destinations2[0] = this.halfDepthBuffer; this.destinations2[1] = this.halfBuffer1; if (!this.preparePostProcess(this.sources2, this.destinations2, this.downsampleEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Compute SSAO parameters.Camera.SetParameters(this.ssaoEffect); this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["SSAO"]; this.sources2[0] = this.halfDepthBuffer; this.sources2[1] = this.halfBuffer1; this.destinations1[0] = this.halfBuffer2; if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Blur this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["BlurHorizontal"]; this.sources2[0] = this.halfBuffer2; this.sources2[1] = this.halfDepthBuffer; this.destinations1[0] = this.halfBuffer1; if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["Composite"]; this.sources2[0] = this.halfBuffer1; this.sources2[1] = this.halfDepthBuffer; this.destinations1[0] = this.halfBuffer2; if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); } // Global lighting this.destinations2[0] = this.lightingBuffer; this.destinations2[1] = this.specularBuffer; if (!this.setTargets(this.destinations2)) { return; } string globalLightTechnique = "GlobalLight"; if (this.lightingManager.EnableGlobalShadowMap && this.lightingManager.HasGlobalShadowLight) { if (parameters.IsMainRender) { if (this.lightingManager.HasGlobalShadowLightClouds) { if (this.lightingManager.EnableDetailGlobalShadowMap) { globalLightTechnique = "GlobalLightDetailShadowClouds"; } else { globalLightTechnique = "GlobalLightShadowClouds"; } } else { if (this.lightingManager.EnableDetailGlobalShadowMap) { globalLightTechnique = "GlobalLightDetailShadow"; } else { globalLightTechnique = "GlobalLightShadow"; } } } else { globalLightTechnique = "GlobalLightShadow"; } } Renderer.globalLightEffect.CurrentTechnique = Renderer.globalLightEffect.Techniques[globalLightTechnique]; parameters.Camera.SetParameters(Renderer.globalLightEffect); this.lightingManager.SetGlobalLightParameters(Renderer.globalLightEffect, parameters.Camera, originalCameraPosition); Renderer.globalLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData); this.sources3[0] = this.depthBuffer; this.sources3[1] = this.normalBuffer; this.sources3[2] = this.colorBuffer1; this.destinations2[0] = this.lightingBuffer; this.destinations2[1] = this.specularBuffer; this.setTargetParameters(this.sources3, this.destinations2, Renderer.globalLightEffect); this.applyEffect(Renderer.globalLightEffect); Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Spot and point lights if (!parameters.ReverseCullOrder) { this.main.GraphicsDevice.RasterizerState = this.reverseCullState; } // HACK // Increase the far plane to prevent clipping back faces of huge lights float originalFarPlane = parameters.Camera.FarPlaneDistance; parameters.Camera.FarPlaneDistance.Value *= 4.0f; parameters.Camera.SetParameters(Renderer.pointLightEffect); parameters.Camera.SetParameters(Renderer.spotLightEffect); parameters.Camera.FarPlaneDistance.Value = originalFarPlane; // Spot lights Renderer.spotLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData); this.setTargetParameters(this.sources3, this.destinations2, Renderer.spotLightEffect); for (int i = 0; i < SpotLight.All.Count; i++) { SpotLight light = SpotLight.All[i]; if (!light.Enabled || light.Suspended || light.Attenuation == 0.0f || light.Color.Value.LengthSquared() == 0.0f || !originalBoundingFrustum.Intersects(light.BoundingFrustum)) { continue; } this.lightingManager.SetSpotLightParameters(light, Renderer.spotLightEffect, originalCameraPosition); this.applyEffect(Renderer.spotLightEffect); this.drawModel(Renderer.spotLightModel); } // Point lights Renderer.pointLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData); this.setTargetParameters(this.sources3, this.destinations2, Renderer.pointLightEffect); for (int i = 0; i < PointLight.All.Count; i++) { PointLight light = PointLight.All[i]; if (!light.Enabled || light.Suspended || light.Attenuation == 0.0f || light.Color.Value.LengthSquared() == 0.0f || !originalBoundingFrustum.Intersects(light.BoundingSphere)) { continue; } this.lightingManager.SetPointLightParameters(light, Renderer.pointLightEffect, originalCameraPosition); this.applyEffect(Renderer.pointLightEffect); this.drawModel(Renderer.pointLightModel); } if (!parameters.ReverseCullOrder) { this.main.GraphicsDevice.RasterizerState = originalState; } RenderTarget2D colorSource = this.colorBuffer1; RenderTarget2D colorDestination = this.hdrBuffer2; RenderTarget2D colorTemp = null; // Compositing this.compositeEffect.CurrentTechnique = this.compositeEffect.Techniques[enableSSAO ? "CompositeSSAO" : "Composite"]; this.lightingManager.SetCompositeParameters(this.compositeEffect); parameters.Camera.SetParameters(this.compositeEffect); this.compositeEffect.Parameters["Materials"].SetValue(parameters.MaterialData); RenderTarget2D[] compositeSources; if (enableSSAO) { compositeSources = this.sources4; compositeSources[3] = this.halfBuffer2; } else { compositeSources = this.sources3; } compositeSources[0] = colorSource; compositeSources[1] = this.lightingBuffer; compositeSources[2] = this.specularBuffer; this.destinations1[0] = colorDestination; if (!this.preparePostProcess(compositeSources, this.destinations1, this.compositeEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); bool enableBloom = this.allowBloom && this.EnableBloom; bool enableMotionBlur = this.MotionBlurAmount > 0.0f; #if VR if (this.main.VR) { enableMotionBlur = false; } #endif bool enableBlur = this.BlurAmount > 0.0f; // Swap the color buffers colorSource = this.hdrBuffer2; colorDestination = enableBloom || this.allowToneMapping || enableBlur || enableMotionBlur ? this.hdrBuffer1 : result; parameters.DepthBuffer = this.depthBuffer; parameters.FrameBuffer = colorSource; // Alpha components // Drawing to the color destination this.destinations1[0] = colorDestination; if (!this.setTargets(this.destinations1)) { return; } // Copy the color source to the destination this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, originalState); this.spriteBatch.Draw(colorSource, Vector2.Zero, Color.White); this.spriteBatch.End(); parameters.Camera.Position.Value = originalCameraPosition; parameters.Camera.View.Value = originalViewMatrix; this.main.DrawAlphaComponents(parameters); this.main.DrawPostAlphaComponents(parameters); // Swap the color buffers colorTemp = colorDestination; colorDestination = colorSource; parameters.FrameBuffer = colorSource = colorTemp; // Bloom if (enableBloom) { this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["Downsample"]; this.sources1[0] = colorSource; this.destinations1[0] = this.halfBuffer1; if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["BlurHorizontal"]; this.sources1[0] = this.halfBuffer1; this.destinations1[0] = this.halfBuffer2; if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["BlurVertical"]; this.sources1[0] = this.halfBuffer2; this.destinations1[0] = this.halfBuffer1; if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["Composite"]; this.sources2[0] = colorSource; this.sources2[1] = this.halfBuffer1; this.destinations1[0] = enableBlur || enableMotionBlur ? this.colorBuffer2 : result; if (!this.preparePostProcess(this.sources2, this.destinations1, this.bloomEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Swap the color buffers colorDestination = this.colorBuffer1; colorSource = this.colorBuffer2; } else if (this.allowToneMapping) { this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["ToneMapOnly"]; this.sources1[0] = colorSource; this.destinations1[0] = enableBlur || enableMotionBlur ? this.colorBuffer2 : result; if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Swap the color buffers colorDestination = this.colorBuffer1; colorSource = this.colorBuffer2; } // Motion blur if (enableMotionBlur) { this.motionBlurEffect.CurrentTechnique = this.motionBlurEffect.Techniques["MotionBlur"]; parameters.Camera.SetParameters(this.motionBlurEffect); // If we just reallocated our buffers, don't use the velocity buffer from the last frame because it will be empty this.sources3[0] = colorSource; this.sources3[1] = this.normalBuffer; this.sources3[2] = this.justReallocatedBuffers ? this.normalBuffer : this.normalBufferLastFrame; this.destinations1[0] = enableBlur ? colorDestination : result; if (!this.preparePostProcess(this.sources3, this.destinations1, this.motionBlurEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); // Swap the velocity buffers RenderTarget2D temp = this.normalBufferLastFrame; this.normalBufferLastFrame = this.normalBuffer; this.normalBuffer = temp; // Swap the color buffers colorTemp = colorDestination; colorDestination = colorSource; colorSource = colorTemp; } if (enableBlur) { // Blur this.blurEffect.CurrentTechnique = this.blurEffect.Techniques["BlurHorizontal"]; parameters.Camera.SetParameters(this.blurEffect); this.sources1[0] = colorSource; this.destinations1[0] = colorDestination; if (!this.preparePostProcess(this.sources1, this.destinations1, this.blurEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); this.blurEffect.CurrentTechnique = this.blurEffect.Techniques["Composite"]; // Swap the color buffers colorTemp = colorDestination; colorDestination = colorSource; colorSource = colorTemp; this.sources1[0] = colorSource; this.destinations1[0] = result; if (!this.preparePostProcess(this.sources1, this.destinations1, this.blurEffect)) { return; } Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default); } parameters.DepthBuffer = null; parameters.FrameBuffer = null; this.justReallocatedBuffers = false; }