/// <summary> /// /// </summary> /// <param name="rtCube"></param> public void CopyFromRenderTargetCube(int index, RenderTargetCube rtCube) { if (rtCube.MipCount != this.MipCount) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different mip count"); } if (rtCube.Width != this.Width) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different width"); } if (rtCube.Height != this.Height) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different height"); } int subResourceCount = 6 * rtCube.MipCount; for (int i = 0; i < subResourceCount; i++) { int srcIndex = i; int dstIndex = i + subResourceCount * index; GraphicsDevice.DeviceContext.CopySubresourceRegion(rtCube.TextureResource, srcIndex, null, texCubeArray, dstIndex); } }
/// <summary> /// /// </summary> /// <param name="rtCube"></param> public void CopyFromRenderTargetCube ( int index, RenderTargetCube rtCube ) { if (rtCube.MipCount!=this.MipCount) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different mip count"); } if (rtCube.Width!=this.Width) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different width"); } if (rtCube.Height!=this.Height) { throw new GraphicsException("CopyFromRenderTargetCube: source and destination have different height"); } int subResourceCount = 6 * rtCube.MipCount; for (int i=0; i<subResourceCount; i++) { int srcIndex = i; int dstIndex = i + subResourceCount * index; GraphicsDevice.DeviceContext.CopySubresourceRegion( rtCube.TextureResource, srcIndex, null, texCubeArray, dstIndex ); } }
/// <summary> /// /// </summary> /// <param name="dst"></param> /// <param name="cubeSrc"></param> /// <param name="sampleCount"></param> public void PrefilterEnvMap ( RenderTargetCube envMap ) { SetDefaultRenderStates(); int width = envMap.Width / 2; int height = envMap.Height / 2; using( new PixEvent("PrefilterEnvMap") ) { var sides = new[]{ ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSX, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGX, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSY, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGY, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSZ, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGZ }; // loop through mip levels from second to last specular mip level : for (int mip=1; mip<RenderSystem.EnvMapSpecularMipCount; mip++) { float roughness = (float)mip / (float)(RenderSystem.EnvMapSpecularMipCount-1); float step = 1.0f / width; vectorCB.SetData( new Vector4( roughness, step,0,0 ) ); for (int face=0; face<6; face++) { rs.SetTargets( null, envMap.GetSurface( mip, (CubeFace)face ) ); rs.SetViewport( 0,0, width, height ); rs.PixelShaderConstants[0] = vectorCB; rs.PipelineState = factory[ (int)sides[face] ]; rs.VertexShaderResources[0] = envMap.GetCubeShaderResource( mip-1 ); rs.PixelShaderResources[0] = envMap.GetCubeShaderResource( mip-1 ); rs.PixelShaderSamplers[0] = SamplerState.LinearWrap; rs.VertexShaderConstants[0] = matrixCB; rs.Draw( 3, 0 ); } width /= 2; height /= 2; } } rs.ResetStates(); }
/// <summary> /// /// </summary> public override void Initialize() { skyCube = new RenderTargetCube( rs, ColorFormat.Rgba16F, 128, true ); skyConstsCB = new ConstantBuffer( rs, typeof(SkyConsts) ); LoadContent(); Game.Reloading += (s,e) => LoadContent(); var skySphere = SkySphere.GetVertices(4).Select( v => new SkyVertex{ Vertex = v } ).ToArray(); skyVB = new VertexBuffer( Game.GraphicsDevice, typeof(SkyVertex), skySphere.Length ); skyVB.SetData( skySphere ); randVectors = new Vector3[64]; for (int i=0; i<randVectors.Length; i++) { Vector3 randV; do { randV = rand.NextVector3( -Vector3.One, Vector3.One ); } while ( randV.Length()>1 && randV.Y < 0 ); randVectors[i] = randV.Normalized(); } }
/// <summary> /// /// </summary> /// <param name="view"></param> /// <param name="projection"></param> internal void RenderLighting ( StereoEye stereoEye, Camera camera, HdrFrame hdrFrame, RenderWorld viewLayer, RenderTargetCube envLight ) { using ( new PixEvent("TiledLighting") ) { var view = camera.GetViewMatrix( stereoEye ); var projection = camera.GetProjectionMatrix( stereoEye ); var device = Game.GraphicsDevice; device.ResetStates(); var width = hdrFrame.HdrBuffer.Width; var height = hdrFrame.HdrBuffer.Height; ICSMController csmCtrl = viewLayer.LightSet.DirectLight.CSMController ?? csmController; int activeCascadeCount = Math.Min( cascadedShadowMap.CascadeCount, csmCtrl.GetActiveCascadeCount() ); // // Setup compute shader parameters and states : // try { var cbData = new LightingParams(); var invView = Matrix.Invert( view ); var invVP = Matrix.Invert( view * projection ); var viewPos = invView.TranslationVector; cbData.DirectLightDirection = new Vector4( viewLayer.LightSet.DirectLight.Direction, 0 ); cbData.DirectLightIntensity = viewLayer.LightSet.DirectLight.Intensity.ToVector4(); cbData.Projection = projection; cbData.CSMViewProjection0 = csmCtrl.GetShadowViewMatrix(0) * csmCtrl.GetShadowProjectionMatrix(0); cbData.CSMViewProjection1 = csmCtrl.GetShadowViewMatrix(1) * csmCtrl.GetShadowProjectionMatrix(1); cbData.CSMViewProjection2 = csmCtrl.GetShadowViewMatrix(2) * csmCtrl.GetShadowProjectionMatrix(2); cbData.CSMViewProjection3 = csmCtrl.GetShadowViewMatrix(3) * csmCtrl.GetShadowProjectionMatrix(3); cbData.View = view; cbData.ViewPosition = new Vector4(viewPos,1); cbData.InverseViewProjection = invVP; cbData.CSMFilterRadius = new Vector4( CSMFilterSize ); cbData.AmbientColor = viewLayer.LightSet.AmbientLevel; cbData.Viewport = new Vector4( 0, 0, width, height ); cbData.ShowCSLoadOmni = ShowOmniLightTileLoad ? 1 : 0; cbData.ShowCSLoadEnv = ShowEnvLightTileLoad ? 1 : 0; cbData.ShowCSLoadSpot = ShowSpotLightTileLoad ? 1 : 0; cbData.CascadeCount = activeCascadeCount; cbData.CascadeScale = 1.0f / (float)cascadedShadowMap.CascadeCount; ComputeOmniLightsTiles( view, projection, viewLayer.LightSet ); ComputeSpotLightsTiles( view, projection, viewLayer.LightSet ); ComputeEnvLightsTiles( view, projection, viewLayer.LightSet ); // // set states : // device.SetTargets( null, hdrFrame.HdrBuffer.Surface ); lightingCB.SetData( cbData ); device.ComputeShaderSamplers[0] = SamplerState.PointClamp; device.ComputeShaderSamplers[1] = SamplerState.LinearClamp; device.ComputeShaderSamplers[2] = SamplerState.ShadowSampler; device.ComputeShaderSamplers[3] = SamplerState.LinearPointWrap; device.ComputeShaderResources[0] = hdrFrame.DiffuseBuffer; device.ComputeShaderResources[1] = hdrFrame.SpecularBuffer; device.ComputeShaderResources[2] = hdrFrame.NormalMapBuffer; device.ComputeShaderResources[3] = hdrFrame.ScatteringBuffer; device.ComputeShaderResources[4] = hdrFrame.DepthBuffer; device.ComputeShaderResources[5] = cascadedShadowMap.ColorBuffer; device.ComputeShaderResources[6] = spotColor; device.ComputeShaderResources[7] = viewLayer.LightSet.SpotAtlas==null ? rs.WhiteTexture.Srv : viewLayer.LightSet.SpotAtlas.Texture.Srv; device.ComputeShaderResources[8] = omniLightBuffer; device.ComputeShaderResources[9] = spotLightBuffer; device.ComputeShaderResources[10] = envLightBuffer; device.ComputeShaderResources[11] = rs.SsaoFilter.OcclusionMap; device.ComputeShaderResources[12] = viewLayer.RadianceCache; device.ComputeShaderResources[13] = viewLayer.ParticleSystem.SimulatedParticles; device.ComputeShaderResources[14] = cascadedShadowMap.ParticleShadow; device.ComputeShaderConstants[0] = lightingCB; device.SetCSRWTexture( 0, hdrFrame.LightAccumulator.Surface ); device.SetCSRWTexture( 1, hdrFrame.SSSAccumulator.Surface ); device.SetCSRWBuffer( 2, viewLayer.ParticleSystem.ParticleLighting ); // // Dispatch solids : // using (new PixEvent("Solid Lighting")) { device.PipelineState = factory[ (int)LightingFlags.SOLIDLIGHTING ]; device.Dispatch( MathUtil.IntDivUp( width, BlockSizeX ), MathUtil.IntDivUp( height, BlockSizeY ), 1 ); } // // Dispatch particles : // using (new PixEvent("Particle Lighting")) { if (stereoEye!=StereoEye.Right) { int threadGroupCount = MathUtil.IntDivUp( ParticleSystem.MaxSimulatedParticles, ParticleSystem.BlockSize ); device.PipelineState = factory[ (int)LightingFlags.PARTICLES ]; device.Dispatch( threadGroupCount, 1, 1 ); } } } catch ( UbershaderException e ) { Log.Warning("{0}", e.Message ); } // // Add accumulated light : // rs.Filter.OverlayAdditive( hdrFrame.HdrBuffer.Surface, hdrFrame.LightAccumulator ); // Uncomment to enable SSS : #if false rs.Filter.GaussBlur( hdrFrame.SSSAccumulator, hdrFrame.LightAccumulator, 5, 0 ); rs.Filter.OverlayAdditive( hdrFrame.HdrBuffer.Surface, hdrFrame.SSSAccumulator ); #endif device.ResetStates(); if (rs.ShowLightCounters) { var ls = viewLayer.LightSet; Log.Message("lights: {0,5} omni {1,5} spot {2,5} env", ls.OmniLights.Count, ls.SpotLights.Count, ls.EnvLights.Count ); } } }
/// <summary> /// Creates ViewLayerHDR instance /// </summary> /// <param name="Game">Game engine</param> /// <param name="width">Target width.</param> /// <param name="height">Target height.</param> public RenderWorld ( Game game, int width, int height ) : base( game ) { var vp = Game.GraphicsDevice.DisplayBounds; if (width<=0) { width = vp.Width; } if (height<=0) { height = vp.Height; } HdrSettings = new HdrSettings(); SkySettings = new SkySettings(); DofSettings = new DofSettings(); Instances = new List<MeshInstance>(); LightSet = new LightSet( Game.RenderSystem ); debug = new DebugRender( Game ); particleSystem = new ParticleSystem( Game.RenderSystem, this ); MeasuredOld = new RenderTarget2D( Game.GraphicsDevice, ColorFormat.Rgba32F, 1, 1 ); MeasuredNew = new RenderTarget2D( Game.GraphicsDevice, ColorFormat.Rgba32F, 1, 1 ); radianceFrame = new HdrFrame( Game, 512,512 ); Radiance = new RenderTargetCube( Game.GraphicsDevice, ColorFormat.Rgba16F, RenderSystem.EnvMapSize, true ); RadianceCache = new TextureCubeArray( Game.GraphicsDevice, 128, RenderSystem.MaxEnvLights, ColorFormat.Rgba16F, true ); Resize( width, height ); }