/// <summary> /// SetPSRWBuffer & SetPSRWTexture share same registers. /// </summary> /// <param name="register"></param> /// <param name="buffer"></param> /// <param name="initialCount">An array of append and consume buffer offsets. /// A value of -1 indicates to keep the current offset. /// Any other values set the hidden counter for that appendable and consumable UAV. </param> public void SetPSRWTexture(int register, RenderTargetSurface surface) { if (register > 8) { throw new GraphicsException("Could not bind RW texture at register " + register.ToString() + " (max 8)"); } lock (deviceContext) { DeviceContext.OutputMerger.SetUnorderedAccessView(register, surface == null?null:surface.UAV, -1); } }
/// <summary> /// Internal constructor to create RT for backbuffer. /// </summary> /// <param name="device"></param> /// <param name="backbufColor"></param> internal RenderTarget2D(GraphicsDevice device, D3D.Texture2D backbufColor) : base(device) { if (backbufColor.Description.Format != DXGI.Format.R8G8B8A8_UNorm) { Log.Warning("R8G8B8A8_UNorm"); } Width = backbufColor.Description.Width; Height = backbufColor.Description.Height; Format = ColorFormat.Rgba8; MipCount = 1; SampleCount = backbufColor.Description.SampleDescription.Count; SRV = null; tex2D = backbufColor; surfaces = new RenderTargetSurface[1]; surfaces[0] = new RenderTargetSurface(new RenderTargetView(device.Device, backbufColor), null, tex2D, 0, Format, Width, Height, SampleCount); }
/// <summary> /// /// </summary> /// <param name="dst">target to copy to</param> /// <param name="src">target to copy from</param> public void Copy( RenderTargetSurface dst, ShaderResource src ) { SetDefaultRenderStates(); using( new PixEvent() ) { if(dst == null) { rs.RestoreBackbuffer(); } else { SetViewport(dst); rs.SetTargets( null, dst ); } rs.PipelineState = factory[ (int)ShaderFlags.COPY ]; rs.PixelShaderResources[0] = src; rs.Draw( 3, 0 ); } rs.ResetStates(); }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="destination"></param> public void Resolve(RenderTargetSurface source, RenderTargetSurface destination) { if (source.Width != destination.Width || source.Height != destination.Height) { throw new GraphicsException("Could not resolve: source and destination are not the same size"); } if (source.SampleCount <= 1) { throw new GraphicsException("Could not resolve: source surface is not multisampled"); } if (destination.SampleCount > 1) { throw new GraphicsException("Could not resolve: destination surface is multisampled"); } lock (deviceContext) { deviceContext.ResolveSubresource(source.Resource, source.Subresource, destination.Resource, destination.Subresource, Converter.Convert(source.Format)); } }
/// <summary> /// /// </summary> /// <param name="depthStencil"></param> /// <param name="renderTargets"></param> public void GetTargets( out DepthStencilSurface depthStencil, out RenderTargetSurface[] renderTargets ) { depthStencil = depthStencilSurface; renderTargets = renderTargetSurfaces.ToArray(); }
void SetViewport( RenderTargetSurface dst ) { rs.SetViewport( 0,0, dst.Width, dst.Height ); }
public void StretchRect4x4( RenderTargetSurface dst, RenderTarget2D src, SamplerState filter = null ) { SetDefaultRenderStates(); using( new PixEvent() ) { rs.SetTargets( null, dst ); SetViewport(dst); rs.PipelineState = factory[ (int)ShaderFlags.DOWNSAMPLE_2_4x4 ]; rs.VertexShaderResources[0] = src; rs.PixelShaderResources[0] = src; rs.PixelShaderSamplers[0] = filter ?? SamplerState.LinearPointClamp; rs.Draw( 3, 0 ); } rs.ResetStates(); }
public void RadialBlur( RenderTargetSurface dst, RenderTarget2D src, Vector2 blurPoint, float offset, float size ) { SetDefaultRenderStates(); var data = new Vector4(blurPoint.X, blurPoint.Y, offset, size); radialDataCB.SetData(data); using( new PixEvent() ) { rs.SetTargets( null, dst ); SetViewport(dst); rs.PipelineState = factory[ (int)ShaderFlags.RADIAL_BLUR ]; rs.VertexShaderResources[0] = src; rs.PixelShaderResources[0] = src; rs.PixelShaderSamplers[0] = SamplerState.LinearPointClamp; rs.PixelShaderConstants[0] = radialDataCB; rs.VertexShaderConstants[0] = radialDataCB; rs.Draw( 3, 0 ); } rs.ResetStates(); }
public void LinearizeDepth( RenderTargetSurface dst, ShaderResource src ) { throw new NotImplementedException(); #if false Debug.Assert( Game.IsServiceExist<Camera>() ); var camera = Game.GetService<Camera>(); bufLinearizeDepth.Data.linearizeDepthA = 1.0f / camera.FrustumZFar - 1.0f / camera.FrustumZNear; bufLinearizeDepth.Data.linearizeDepthB = 1.0f / camera.FrustumZNear; bufLinearizeDepth.UpdateCBuffer(); var isDepthMSAA = ( src.SampleCount > 1 ); var depthShader = (int)( isDepthMSAA ? ShaderFlags.RESOLVE_AND_LINEARIZE_DEPTH_MSAA : ShaderFlags.LINEARIZE_DEPTH ); string signature; SetDefaultRenderStates(); using( new PixEvent() ) { bufLinearizeDepth.SetCBufferPS( 0 ); shaders.SetPixelShader( depthShader ); shaders.SetVertexShader( depthShader ); dst.SetViewport(); rs.SetRenderTargets( dst ); src.SetPS( 0 ); rs.Draw( Primitive.TriangleList, 3, 0 ); } rs.ResetStates(); #endif }
/// <summary> /// Performs FXAA antialiasing. /// </summary> /// <param name="dst">Target buffer to render FXAA to</param> /// <param name="src">Source image with luminance in alpha</param> public void Fxaa( RenderTargetSurface dst, ShaderResource src ) { SetDefaultRenderStates(); using( new PixEvent() ) { if(dst == null) { rs.RestoreBackbuffer(); } else { SetViewport( dst ); rs.SetTargets( null, dst ); } rs.PipelineState = factory[ (int)ShaderFlags.FXAA ]; rs.VertexShaderResources[0] = src; rs.PixelShaderResources[0] = src; rs.PixelShaderSamplers[0] = SamplerState.LinearPointClamp; rs.Draw( 3, 0 ); } rs.ResetStates(); }
/// <summary> /// Creates render target /// </summary> /// <param name="?"></param> /// <param name="format"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="samples"></param> /// <param name="mips"></param> /// <param name="debugName"></param> void Create(ColorFormat format, int width, int height, int samples, bool mips, bool enableRWBuffer) { bool msaa = samples > 1; CheckSamplesCount(samples); if (mips && samples > 1) { throw new ArgumentException("Render target should be multisampler either mipmapped"); } SampleCount = samples; Format = format; SampleCount = samples; Width = width; Height = height; Depth = 1; MipCount = mips ? ShaderResource.CalculateMipLevels(width, height) : 1; var texDesc = new Texture2DDescription(); texDesc.Width = width; texDesc.Height = height; texDesc.ArraySize = 1; texDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert(format); texDesc.MipLevels = mips ? MipCount : 1; texDesc.OptionFlags = mips ? ResourceOptionFlags.GenerateMipMaps : ResourceOptionFlags.None; texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; if (enableRWBuffer) { texDesc.BindFlags |= BindFlags.UnorderedAccess; } tex2D = new D3D.Texture2D(device.Device, texDesc); SRV = new ShaderResourceView(device.Device, tex2D); // // Create surfaces : // surfaces = new RenderTargetSurface[MipCount]; for (int i = 0; i < MipCount; i++) { width = GetMipSize(Width, i); height = GetMipSize(Height, i); var rtvDesc = new RenderTargetViewDescription(); rtvDesc.Texture2D.MipSlice = i; rtvDesc.Dimension = msaa ? RenderTargetViewDimension.Texture2DMultisampled : RenderTargetViewDimension.Texture2D; rtvDesc.Format = Converter.Convert(format); var rtv = new RenderTargetView(device.Device, tex2D, rtvDesc); UnorderedAccessView uav = null; if (enableRWBuffer) { var uavDesc = new UnorderedAccessViewDescription(); uavDesc.Buffer.ElementCount = width * height; uavDesc.Buffer.FirstElement = 0; uavDesc.Buffer.Flags = UnorderedAccessViewBufferFlags.None; uavDesc.Dimension = UnorderedAccessViewDimension.Texture2D; uavDesc.Format = Converter.Convert(format); uavDesc.Texture2D.MipSlice = i; uav = new UnorderedAccessView(device.Device, tex2D, uavDesc); } surfaces[i] = new RenderTargetSurface(rtv, uav, tex2D, i, format, width, height, samples); } }
/// <summary> /// /// </summary> /// <param name="view"></param> /// <param name="projection"></param> public void RenderLighting( Matrix view, Matrix projection, RenderTargetSurface hdrTarget, ShaderResource occlusionMap ) { var device = Game.GraphicsDevice; device.ResetStates(); LightingFlags flags = LightingFlags.NONE; if (!Config.SkipDirectLight) { flags |= LightingFlags.DIRECT; if (Config.ShowCSMSplits) { flags |= LightingFlags.SHOW_SPLITS; } } if (!Config.SkipOmniLights) { flags |= LightingFlags.OMNI; if (Config.ShowOmniLightTileLoad) { flags |= LightingFlags.SHOW_OMNI_LOAD; } } if (!Config.SkipSpotLights) { flags |= LightingFlags.SPOT; if (Config.ShowSpotLightTileLoad) { flags |= LightingFlags.SHOW_SPOT_LOAD; } } if (Config.UseUE4LightingModel) { flags |= LightingFlags.USE_UE4; } // // Setup compute shader parameters and states : // try { device.PipelineState = factory[ (int)flags ]; //lightingShader.SetComputeShader((int)flags); var cbData = new LightingParams(); var invView = Matrix.Invert( view ); var invVP = Matrix.Invert( view * projection ); var viewPos = invView.TranslationVector; cbData.DirectLightDirection = new Vector4( DirectLightDirection, 0 ); cbData.DirectLightIntensity = DirectLightIntensity.ToVector4(); cbData.Projection = projection; cbData.CSMViewProjection0 = csmViewProjections[0]; cbData.CSMViewProjection1 = csmViewProjections[1]; cbData.CSMViewProjection2 = csmViewProjections[2]; cbData.CSMViewProjection3 = csmViewProjections[3]; cbData.View = view; cbData.ViewPosition = new Vector4(viewPos,1); cbData.InverseViewProjection = invVP; cbData.CSMFilterRadius = new Vector4( Config.CSMFilterSize ); cbData.AmbientColor = AmbientLevel; PrepareOmniLights( view, projection ); PrepareSpotLights( view, projection ); // // set states : // device.SetTargets( null, hdrTarget ); lightingCB.SetData( cbData ); device.ComputeShaderSamplers[0] = SamplerState.PointClamp; device.ComputeShaderSamplers[1] = SamplerState.LinearClamp; device.ComputeShaderSamplers[2] = SamplerState.ShadowSampler; device.ComputeShaderResources[0] = diffuseBuffer; device.ComputeShaderResources[1] = specularBuffer; device.ComputeShaderResources[2] = normalMapBuffer; device.ComputeShaderResources[3] = depthBuffer; device.ComputeShaderResources[4] = csmColor; device.ComputeShaderResources[5] = spotColor; device.ComputeShaderResources[6] = MaskAtlas.Texture; device.ComputeShaderResources[7] = omniLightBuffer; device.ComputeShaderResources[8] = spotLightBuffer; device.ComputeShaderResources[9] = occlusionMap; device.ComputeShaderConstants[0] = lightingCB; device.SetCSRWTexture( 0, lightAccumBuffer.Surface ); // // Dispatch : // device.Dispatch( MathUtil.IntDivUp( hdrTarget.Width, BlockSizeX ), MathUtil.IntDivUp( hdrTarget.Height, BlockSizeY ), 1 ); } catch ( UbershaderException e ) { e.Report(); } //device.DisplayBounds // // Add accumulated light : // device.ResetStates(); device.SetTargets( null, hdrTarget ); var sb = Game.GetService<SpriteBatch>(); sb.Begin( SpriteBlend.Additive ); sb.Draw( lightAccumBuffer, 0, 0, lightAccumBuffer.Width, lightAccumBuffer.Height, Color.White ); sb.End(); device.ResetStates(); /*if ( Config.ShowSpotLightExtents ) { device.ResetStates(); device.SetTargets( null, hdrTarget ); var sb = Game.GetService<SpriteBatch>(); sb.Begin( BlendState.Additive ); foreach ( var spot in spotLightData ) { sb.Draw( sb.TextureWhite, spot.ExtentMin.X, spot.ExtentMin.Y, spot.ExtentMax.X-spot.ExtentMin.X, spot.ExtentMax.Y-spot.ExtentMin.Y, new Color(32,0,32,255) ); } sb.End(); } */ }
/// <summary> /// Clears render target using given color /// </summary> /// <param name="surface"></param> /// <param name="color"></param> public void Clear( RenderTargetSurface surface, Color4 color ) { lock (deviceContext) { deviceContext.ClearRenderTargetView( surface.RTV, SharpDXHelper.Convert( color ) ); } }
/// <summary> /// Creates render target /// </summary> /// <param name="?"></param> /// <param name="format"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="samples"></param> /// <param name="mips"></param> /// <param name="debugName"></param> void Create(ColorFormat format, int size, int samples, bool mips, string debugName) { bool msaa = samples > 1; CheckSamplesCount(samples); if (mips && samples > 1) { throw new ArgumentException("Render target should be multisampler either mipmapped"); } SampleCount = samples; Format = format; SampleCount = samples; Width = size; Height = size; Depth = 1; MipCount = mips ? ShaderResource.CalculateMipLevels(Width, Height) : 1; var texDesc = new Texture2DDescription(); texDesc.Width = Width; texDesc.Height = Height; texDesc.ArraySize = 6; texDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert(format); texDesc.MipLevels = mips ? MipCount : 1; texDesc.OptionFlags = ResourceOptionFlags.TextureCube | (mips ? ResourceOptionFlags.GenerateMipMaps : ResourceOptionFlags.None); texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; texCube = new D3D.Texture2D(device.Device, texDesc); SRV = new ShaderResourceView(device.Device, texCube); // // Create surfaces : // surfaces = new RenderTargetSurface[MipCount, 6]; for (int mip = 0; mip < MipCount; mip++) { int width = GetMipSize(Width, mip); int height = GetMipSize(Height, mip); for (int face = 0; face < 6; face++) { var rtvDesc = new RenderTargetViewDescription(); rtvDesc.Texture2DArray.MipSlice = mip; rtvDesc.Texture2DArray.FirstArraySlice = face; rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Dimension = msaa ? RenderTargetViewDimension.Texture2DMultisampledArray : RenderTargetViewDimension.Texture2DArray; rtvDesc.Format = Converter.Convert(format); var rtv = new RenderTargetView(device.Device, texCube, rtvDesc); int subResId = Resource.CalculateSubResourceIndex(mip, face, MipCount); surfaces[mip, face] = new RenderTargetSurface(rtv, null, texCube, subResId, format, Width, Height, samples); } } }
/// <summary> /// Creates render target /// </summary> /// <param name="?"></param> /// <param name="format"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="samples"></param> /// <param name="mips"></param> /// <param name="debugName"></param> void Create( ColorFormat format, int size, int samples, bool mips, string debugName ) { bool msaa = samples > 1; CheckSamplesCount( samples ); if (mips && samples>1) { throw new ArgumentException("Render target should be multisampler either mipmapped"); } SampleCount = samples; Format = format; SampleCount = samples; Width = size; Height = size; Depth = 1; MipCount = mips ? ShaderResource.CalculateMipLevels( Width, Height ) : 1; var texDesc = new Texture2DDescription(); texDesc.Width = Width; texDesc.Height = Height; texDesc.ArraySize = 6; texDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert( format ); texDesc.MipLevels = mips ? MipCount : 1; texDesc.OptionFlags = ResourceOptionFlags.TextureCube | (mips ? ResourceOptionFlags.GenerateMipMaps : ResourceOptionFlags.None); texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; texCube = new D3D.Texture2D( device.Device, texDesc ); SRV = new ShaderResourceView( device.Device, texCube ); // // Create surfaces : // surfaces = new RenderTargetSurface[ MipCount, 6 ]; for ( int mip=0; mip<MipCount; mip++ ) { int width = GetMipSize( Width, mip ); int height = GetMipSize( Height, mip ); for ( int face=0; face<6; face++) { var rtvDesc = new RenderTargetViewDescription(); rtvDesc.Texture2DArray.MipSlice = mip; rtvDesc.Texture2DArray.FirstArraySlice = face; rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Dimension = msaa ? RenderTargetViewDimension.Texture2DMultisampledArray : RenderTargetViewDimension.Texture2DArray; rtvDesc.Format = Converter.Convert( format ); var rtv = new RenderTargetView( device.Device, texCube, rtvDesc ); int subResId = Resource.CalculateSubResourceIndex( mip, face, MipCount ); surfaces[mip,face] = new RenderTargetSurface( rtv, null, texCube, subResId, format, Width, Height, samples ); } } }
/// <summary> /// Renders sky with specified technique /// </summary> /// <param name="rendCtxt"></param> /// <param name="techName"></param> public void Render( GameTime gameTime, DepthStencilSurface depthBuffer, RenderTargetSurface hdrTarget, Matrix view, Matrix projection ) { var camera = Game.GetService<Camera>(); var scale = Matrix.Scaling( Params.SkySphereSize ); var rotation = Matrix.Identity; var sunPos = GetSunDirection(); var sunColor = GetSunGlowColor(); rs.ResetStates(); //rs.DepthStencilState = depthBuffer==null? DepthStencilState.None : DepthStencilState.Default ; rs.SetViewport( 0, 0, hdrTarget.Width, hdrTarget.Height ); rs.SetTargets( depthBuffer, hdrTarget ); var viewMatrix = view; var projMatrix = projection; skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = sunColor; skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsCB.SetData( skyConstsData ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; // // Sky : // SkyFlags flags = SkyFlags.PROCEDURAL_SKY; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; for ( int j=0; j<skySphere.Meshes.Count; j++) { var mesh = skySphere.Meshes[j]; rs.SetupVertexInput( vertexBuffers[j], indexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } // // Clouds : // scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize, Params.SkySphereSize ); //scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize * 0.1f, Params.SkySphereSize ); skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = GetSunLightColor(); skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsData.Ambient = GetAmbientLevel().ToVector3(); skyConstsData.Time = (float)gameTime.Total.TotalSeconds; skyConstsCB.SetData( skyConstsData ); flags = SkyFlags.CLOUDS; for (int i=0; i<3; i++) { if (i==0) flags = SkyFlags.CLOUDS| SkyFlags.A; if (i==1) flags = SkyFlags.CLOUDS| SkyFlags.B; if (i==2) flags = SkyFlags.CLOUDS| SkyFlags.C; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[0] = clouds; rs.PixelShaderResources[1] = cirrus; rs.PixelShaderResources[2] = noise; rs.PixelShaderResources[3] = arrows; rs.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap; for ( int j=0; j<cloudSphere.Meshes.Count; j++) { var mesh = cloudSphere.Meshes[j]; rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } } rs.ResetStates(); }
/// <summary> /// Performs luminance measurement, tonemapping, applies bloom. /// </summary> /// <param name="target">LDR target.</param> /// <param name="hdrImage">HDR source image.</param> public void Render( GameTime gameTime, RenderTargetSurface target, ShaderResource hdrImage ) { var device = Game.GraphicsDevice; var filter = Game.GetService<Filter>(); var ds = Game.GetService<DebugStrings>(); // // Rough downsampling of source HDR-image : // filter.StretchRect( averageLum.Surface, hdrImage ); averageLum.BuildMipmaps(); // // Make bloom : // filter.StretchRect( bloom0.Surface, hdrImage ); bloom0.BuildMipmaps(); filter.GaussBlur( bloom0, bloom1, Config.GaussBlurSigma, 0 ); filter.GaussBlur( bloom0, bloom1, Config.GaussBlurSigma, 1 ); filter.GaussBlur( bloom0, bloom1, Config.GaussBlurSigma, 2 ); filter.GaussBlur( bloom0, bloom1, Config.GaussBlurSigma, 3 ); // // Setup parameters : // var paramsData = new Params(); paramsData.AdaptationRate = 1 - (float)Math.Pow( 0.5f, gameTime.ElapsedSec / Config.AdaptationHalfLife ); paramsData.LuminanceLowBound = Config.LuminanceLowBound; paramsData.LuminanceHighBound = Config.LuminanceHighBound; paramsData.KeyValue = Config.KeyValue; paramsData.BloomAmount = Config.BloomAmount; paramsCB.SetData( paramsData ); device.PixelShaderConstants[0] = paramsCB; // // Measure and adapt : // device.SetTargets( null, measuredNew ); device.PixelShaderResources[0] = averageLum; device.PixelShaderResources[1] = measuredOld; device.PipelineState = factory[ (int)(Flags.MEASURE_ADAPT) ]; device.Draw( 3, 0 ); // // Tonemap and compose : // device.SetTargets( null, target ); device.PixelShaderResources[0] = hdrImage;// averageLum; device.PixelShaderResources[1] = measuredNew;// averageLum; device.PixelShaderResources[2] = bloom0;// averageLum; device.PixelShaderResources[3] = Game.GetService<SpriteBatch>().TextureWhite; device.PixelShaderSamplers[0] = SamplerState.LinearClamp; Flags op = Flags.LINEAR; if (Config.TonemappingOperator==TonemappingOperator.Filmic) { op = Flags.FILMIC; } if (Config.TonemappingOperator==TonemappingOperator.Linear) { op = Flags.LINEAR; } if (Config.TonemappingOperator==TonemappingOperator.Reinhard) { op = Flags.REINHARD; } device.PipelineState = factory[ (int)(Flags.TONEMAPPING|op) ]; device.Draw( 3, 0 ); device.ResetStates(); // swap luminanice buffers : Misc.Swap( ref measuredNew, ref measuredOld ); }
/// <summary> /// Clears render target using given color /// </summary> /// <param name="surface"></param> /// <param name="color"></param> public void Clear(RenderTargetSurface surface, Color4 color) { lock (deviceContext) { deviceContext.ClearRenderTargetView(surface.RTV, SharpDXHelper.Convert(color)); } }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="destination"></param> public void Resolve( RenderTargetSurface source, RenderTargetSurface destination ) { if ( source.Width != destination.Width || source.Height != destination.Height ) { throw new GraphicsException( "Could not resolve: source and destination are not the same size"); } if ( source.SampleCount <= 1 ) { throw new GraphicsException( "Could not resolve: source surface is not multisampled"); } if ( destination.SampleCount > 1 ) { throw new GraphicsException( "Could not resolve: destination surface is multisampled"); } lock (deviceContext) { deviceContext.ResolveSubresource( source.Resource, source.Subresource, destination.Resource, destination.Subresource, Converter.Convert( source.Format ) ); } }
/// <summary> /// SetPSRWBuffer & SetPSRWTexture share same registers. /// </summary> /// <param name="register"></param> /// <param name="buffer"></param> /// <param name="initialCount">An array of append and consume buffer offsets. /// A value of -1 indicates to keep the current offset. /// Any other values set the hidden counter for that appendable and consumable UAV. </param> public void SetPSRWTexture( int register, RenderTargetSurface surface ) { if (register>8) { throw new GraphicsException("Could not bind RW texture at register " + register.ToString() + " (max 8)"); } lock (deviceContext) { DeviceContext.OutputMerger.SetUnorderedAccessView ( register, surface==null?null:surface.UAV, -1 ); } }
/// <summary> /// Renders sky with specified technique /// </summary> /// <param name="rendCtxt"></param> /// <param name="techName"></param> public void Render( GameTime gameTime, DepthStencilSurface depthBuffer, RenderTargetSurface hdrTarget, Matrix view, Matrix projection, RenderTarget2D cloudTarget, RenderTarget2D smallerCloudTarget) { var camera = Game.GetService<Camera>(); var scale = Matrix.Scaling( Params.SkySphereSize ); var rotation = Matrix.Identity; var sunPos = GetSunDirection(); var sunColor = GetSunGlowColor(); rs.ResetStates(); //rs.DepthStencilState = depthBuffer==null? DepthStencilState.None : DepthStencilState.Default ; rs.SetViewport( 0, 0, hdrTarget.Width, hdrTarget.Height ); rs.SetTargets( depthBuffer, hdrTarget ); var viewMatrix = view; var projMatrix = projection; skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = sunColor; skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsCB.SetData( skyConstsData ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; // // Sky : // SkyFlags flags = SkyFlags.PROCEDURAL_SKY; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; for ( int j=0; j<skySphere.Meshes.Count; j++) { var mesh = skySphere.Meshes[j]; rs.SetupVertexInput( vertexBuffers[j], indexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } // // Clouds : // scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize, Params.SkySphereSize ); //scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize * 0.1f, Params.SkySphereSize ); skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = GetSunLightColor(); skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsData.Ambient = GetAmbientLevel().ToVector3(); skyConstsData.Time = (float)gameTime.Total.TotalSeconds; skyConstsCB.SetData( skyConstsData ); rs.SetTargets( depthBuffer, hdrTarget); // rs.SetTargets( null, cloudTarget.Surface ); flags = SkyFlags.CLOUDS; //int i = 0; for (int i=0; i<3; i++) { if (i==0) flags = SkyFlags.CLOUDS| SkyFlags.A | SkyFlags.RED; if (i==1) flags = SkyFlags.CLOUDS| SkyFlags.B | SkyFlags.GREEN; if (i==2) flags = SkyFlags.CLOUDS| SkyFlags.C | SkyFlags.BLUE; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[0] = clouds; rs.PixelShaderResources[1] = cirrus; rs.PixelShaderResources[2] = noise; rs.PixelShaderResources[3] = arrows; rs.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap; for ( int j=0; j<cloudSphere.Meshes.Count; j++) { var mesh = cloudSphere.Meshes[j]; rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } } #if false //Blur var filter = Game.GetService<Filter>(); //filter.RadialBlur(smallerCloudTarget.Surface, cloudTarget, new Vector2(0.5f, 0.5f), 1.0f, -0.2f); //if(Game.InputDevice.IsKeyDown(Keys.LeftButton)) //{ Vector4 sunProj = Vector4.Transform(new Vector4(sunPos, 0), viewMatrix); sunProj = Vector4.Transform(sunProj, projMatrix); sunProj = new Vector4(sunProj.X / sunProj.W, sunProj.Y / sunProj.W, sunProj.Z / sunProj.W, 1); Vector2 relSunPosition = new Vector2(0.5f, 0.5f); //if ( Math.Abs(sunProj.X ) < 1 && Math.Abs (sunProj.Y) < 1){ relSunPosition = new Vector2( (sunProj.X + 1) / 2, - (sunProj.Y - 1) / 2); //} //Log.Message(relSunPosition + ""); filter.RadialBlur(smallerCloudTarget.Surface, cloudTarget, relSunPosition, 1.0f, -0.2f); //} flags = SkyFlags.BLUR_CLOUD; skyConstsData.MatrixWVP = Matrix.Identity; skyConstsCB.SetData( skyConstsData ); rs.SetTargets(null, hdrTarget); ApplyColorSpace( ref flags ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[4] = cloudTarget; rs.PixelShaderSamplers[1] = SamplerState.LinearWrap; var v0 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, -1.0f, 0 ), TexCoord = new Vector2( 0, 1 ), }; var v1 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, 1.0f, 0 ), TexCoord = new Vector2( 1, 0 ), }; var v2 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, 1.0f, 0 ), TexCoord = new Vector2( 0, 0 ), }; var v3 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, -1.0f, 0 ), TexCoord = new Vector2( 0, 1 ), }; var v4 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, -1.0f, 0 ), TexCoord = new Vector2( 1, 1 ), }; var v5 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, 1.0f, 0 ), TexCoord = new Vector2( 1, 0 ), };//*/ var data = new VertexColorTextureTBN[] { v0, v1, v2, v3, v4, v5 }; //Log.Message(""+v0.TexCoord); vertexBufferBlur.SetData( data, 0, 6 ); //for ( int j=0; j<cloudSphere.Meshes.Count; j++) { // var mesh = cloudSphere.Meshes[j]; // rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); // rs.DrawIndexed( mesh.IndexCount, 0, 0 ); // } rs.SetupVertexInput( vertexBufferBlur, null ); rs.Draw( 6, 0 ); #endif rs.ResetStates(); }