public void RenderEffect(Renderer renderer, GraphicsDevice device) { RenderTarget2D half0 = renderer.HalfDepth; //render to a half-res buffer device.SetRenderTarget(half0); Apply(); device.BlendState = BlendState.Opaque; device.DepthStencilState = DepthStencilState.None; _quadRenderer.RenderQuad(device, -Vector2.One, Vector2.One); }
public void Init(ContentManager contentManager, Renderer renderer) { try { _effect = contentManager.Load<Effect>("shaders/DownsampleDepth"); ExtractParameters(); Vector2 pixelSize = new Vector2(1.0f / (float)renderer.DepthBuffer.Width, 1.0f / (float)renderer.DepthBuffer.Height); PixelSize.SetValue(pixelSize); HalfPixel.SetValue(pixelSize * 0.5f); DepthBuffer.SetValue(renderer.DepthBuffer); } catch (Exception ex) { Console.WriteLine("Error loading downsample depth efect: " + ex.ToString()); } }
public ShadowRenderer(Renderer renderer) { //create the render targets for (int i = 0; i < NUM_SPOT_SHADOWS; i++) { SpotShadowMapEntry entry = new SpotShadowMapEntry(); //we store the linear depth, in a float render target. We need also the HW zbuffer entry.Texture = new RenderTarget2D(renderer.GraphicsDevice, SPOT_SHADOW_RESOLUTION, SPOT_SHADOW_RESOLUTION, false, SurfaceFormat.Single, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents); entry.LightViewProjection = Matrix.Identity; _spotShadowMaps.Add(entry); } for (int i = 0; i < NUM_CSM_SHADOWS; i++) { CascadeShadowMapEntry entry = new CascadeShadowMapEntry(); entry.Texture = new RenderTarget2D(renderer.GraphicsDevice, CASCADE_SHADOW_RESOLUTION * NUM_CSM_SPLITS, CASCADE_SHADOW_RESOLUTION, false, SurfaceFormat.Single, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents); _cascadeShadowMaps.Add(entry); } }
public void GenerateShadowTextureDirectionalLight(Renderer renderer, object[] meshes, object[] InstancedMeshes, Light light, CascadeShadowMapEntry cascadeShadowMap, Camera.Camera camera) { //bind the render target renderer.GraphicsDevice.SetRenderTarget(cascadeShadowMap.Texture); //clear it to white, ie, far far away renderer.GraphicsDevice.Clear(Color.White); renderer.GraphicsDevice.BlendState = BlendState.Opaque; renderer.GraphicsDevice.DepthStencilState = DepthStencilState.Default; // Get the corners of the frustum camera.Frustum.GetCorners(frustumCornersWS); Matrix eyeTransform = camera.View; Vector3.Transform(frustumCornersWS, ref eyeTransform, frustumCornersVS); float near = camera.NearPlane, far = MathHelper.Min(camera.FarPlane, light.ShadowDistance); splitDepthsTmp[0] = near; splitDepthsTmp[NUM_CSM_SPLITS] = far; //compute each distance the way you like... for (int i = 1; i < splitDepthsTmp.Length - 1; i++) splitDepthsTmp[i] = near + (far - near) * (float)Math.Pow((i / (float)NUM_CSM_SPLITS), 3); Viewport splitViewport = new Viewport(); Vector3 lightDir = -Vector3.Normalize(light.Transform.Forward); BoundingFrustum frustum = new BoundingFrustum(Matrix.Identity); for (int i = 0; i < NUM_CSM_SPLITS; i++) { cascadeShadowMap.LightClipPlanes[i].X = -splitDepthsTmp[i]; cascadeShadowMap.LightClipPlanes[i].Y = -splitDepthsTmp[i + 1]; cascadeShadowMap.LightViewProjectionMatrices[i] = CreateLightViewProjectionMatrix(lightDir, far, camera, splitDepthsTmp[i], splitDepthsTmp[i + 1], i); Matrix viewProj = cascadeShadowMap.LightViewProjectionMatrices[i]; // Set the viewport for the current split splitViewport.MinDepth = 0; splitViewport.MaxDepth = 1; splitViewport.Width = CASCADE_SHADOW_RESOLUTION; splitViewport.Height = CASCADE_SHADOW_RESOLUTION; splitViewport.X = i * CASCADE_SHADOW_RESOLUTION; splitViewport.Y = 0; renderer.GraphicsDevice.Viewport = splitViewport; frustum.Matrix = viewProj; foreach (object mesh in meshes) { if (mesh is List<Models>) for (int index = 0; index < ((List<Models>)mesh).Count; index++) { Models m = ((List<Models>)mesh)[index]; //cull meshes outside the light volume // if (!frustum.Intersects(m.BoundingSphere)) // continue; //render it m.RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is Models) { //cull meshes outside the light volume // if (!frustum.Intersects(((Models)mesh).BoundingSphere)) // continue; //render it ((Models)mesh).RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is CarPlayer) { ((CarPlayer)mesh).RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is Terrain.Terrain) { for (int index = 0; index < ((Terrain.Terrain)mesh).QuadTrees.Count; index++) { //cull meshes outside the light volume // if (!frustum.Intersects(((Terrain.Terrain)mesh).QuadTrees[index].BoundingSphere)) // continue; //render it ((Terrain.Terrain)mesh).QuadTrees[index].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } } } foreach (object mesh in InstancedMeshes) { if (mesh is Billboards.Billboard) { ((Billboards.Billboard)mesh).TreePreDraw(); for (int lod = 0; lod < ((Billboards.Billboard)mesh).LOD; lod++) if (((Billboards.Billboard)mesh).instanceTransforms[lod].Length != 0) ((Billboards.Billboard)mesh).trunck[lod][0].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); if (((Billboards.Billboard)mesh).Leaves) for (int tree = 0; tree < ((Billboards.Billboard)mesh).NoTrees; tree++) { if (((Billboards.Billboard)mesh).LeavesAreVisible[tree]) for (int j = 0; j < ((Billboards.Billboard)mesh).NoLeaves; j++) { ((Billboards.Billboard)mesh).leaves[tree][j].UpdateTransformationMatrix(((Billboards.Billboard)mesh).instanceTransforms1[tree]); if (j == 0) ((Billboards.Billboard)mesh).leaves[tree][j].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } } } } } }
public void GenerateShadowTextureSpotLight(Renderer renderer, object[] meshes, object[] InstancedMeshes, Light light, SpotShadowMapEntry shadowMap) { //bind the render target renderer.GraphicsDevice.SetRenderTarget(shadowMap.Texture); //clear it to white, ie, far far away renderer.GraphicsDevice.Clear(Color.White); renderer.GraphicsDevice.BlendState = BlendState.Opaque; renderer.GraphicsDevice.DepthStencilState = DepthStencilState.Default; Matrix viewProj = light.ViewProjection; shadowMap.LightViewProjection = viewProj; BoundingFrustum frustum = light.Frustum; foreach (object mesh in meshes) { if (mesh is List<Models>) for (int index = 0; index < ((List<Models>)mesh).Count; index++) { Models m = ((List<Models>)mesh)[index]; //cull meshes outside the light volume // if (!frustum.Intersects(m.BoundingSphere)) // continue; //render it m.RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is Models) { //cull meshes outside the light volume // if (!frustum.Intersects(((Models)mesh).BoundingSphere)) // continue; //render it ((Models)mesh).RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is CarPlayer) { ((CarPlayer)mesh).RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } if (mesh is Terrain.Terrain) { for (int index = 0; index < ((Terrain.Terrain)mesh).QuadTrees.Count; index++) { //cull meshes outside the light volume // if (!frustum.Intersects(((Terrain.Terrain)mesh).QuadTrees[index].BoundingSphere)) // continue; //render it ((Terrain.Terrain)mesh).QuadTrees[index].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } } } foreach (object mesh in InstancedMeshes) { if (mesh is Billboards.Billboard) { ((Billboards.Billboard)mesh).TreePreDraw(); for (int lod = 0; lod < ((Billboards.Billboard)mesh).LOD; lod++) if (((Billboards.Billboard)mesh).instanceTransforms[lod].Length != 0) ((Billboards.Billboard)mesh).trunck[lod][0].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); if (((Billboards.Billboard)mesh).Leaves) for (int tree = 0; tree < ((Billboards.Billboard)mesh).NoTrees; tree++) { if (((Billboards.Billboard)mesh).LeavesAreVisible[tree]) for (int j = 0; j < ((Billboards.Billboard)mesh).NoLeaves; j++) { ((Billboards.Billboard)mesh).leaves[tree][j].UpdateTransformationMatrix(((Billboards.Billboard)mesh).instanceTransforms1[tree]); if (j == 0) ((Billboards.Billboard)mesh).leaves[tree][j].RenderShadowMap(ref viewProj, renderer.GraphicsDevice); } } } } }
public void RenderPostFx(Renderer renderer, GraphicsDevice device, RenderTarget2D srcTarget, RenderTarget2D dstTarget) { RenderTarget2D quarter0 = renderer.QuarterBuffer0; RenderTarget2D quarter1 = renderer.QuarterBuffer1; RenderTarget2D halfDepth = renderer.GetDownsampledDepth(); _effect.CurrentTechnique = _effect.Techniques[0]; device.BlendState = BlendState.Opaque; device.DepthStencilState = DepthStencilState.None; device.RasterizerState = RasterizerState.CullNone; //render to a half-res buffer device.SetRenderTarget(quarter0); _parameterColorBuffer.SetValue(srcTarget); _parameterHalfDepthTexture.SetValue(halfDepth); _parameterTextureAspectRatio.SetValue(srcTarget.Height / (float)srcTarget.Width); // Convert to rgb first, so we have linear filtering _effect.CurrentTechnique = _effect.Techniques[0]; Vector2 pixelSize = new Vector2(1.0f / (float)srcTarget.Width, 1.0f / (float)srcTarget.Height); _parameterPixelSize.SetValue(pixelSize); _parameterHalfPixel.SetValue(pixelSize * 0.5f); _effect.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(device, -Vector2.One, Vector2.One); pixelSize = new Vector2(1.0f / (float)quarter0.Width, 1.0f / (float)quarter0.Height); _parameterPixelSize.SetValue(pixelSize); _parameterHalfPixel.SetValue(pixelSize * 0.5f); _effect.CurrentTechnique = _effect.Techniques[1]; device.SetRenderTarget(quarter1); _parameterRGBShaftTexture.SetValue(quarter0); _effect.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(device, -Vector2.One, Vector2.One); device.SetRenderTarget(dstTarget); pixelSize = new Vector2(1.0f / (float)srcTarget.Width, 1.0f / (float)srcTarget.Height); _parameterPixelSize.SetValue(pixelSize); _parameterHalfPixel.SetValue(pixelSize * 0.5f); device.RasterizerState = RasterizerState.CullNone; device.DepthStencilState = DepthStencilState.None; device.BlendState = BlendState.Opaque; _parameterRGBShaftTexture.SetValue(quarter1); _effect.CurrentTechnique = _effect.Techniques[2]; _effect.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(device, -Vector2.One, Vector2.One); device.SetRenderTarget(null); }
/// <summary> /// Initialize the effect. Loads the shader file, extract the parameters, apply /// the default values /// </summary> /// <param name="contentManager"></param> /// <param name="renderer"></param> public void Init(ContentManager contentManager, Renderer renderer) { _quadRenderer = new QuadRenderer(); try { _effect = contentManager.Load<Effect>("Shaders/LightShaft"); ExtractParameters(); } catch (Exception ex) { Console.WriteLine("Error loading bloom depth effect: " + ex.ToString()); } }