internal virtual void PerFrame() { MyCommon.UpdateFrameConstants(); }
// viewport, render target internal unsafe static void Draw(IRtvBindable rtv, MyViewport viewport, IBlendState blendstate = null) { if (StackTop.m_internalBatch.Texture != null && StackTop.m_internalBatch.Count > 0) { StackTop.m_internalBatch.Commit(); } StackTop.m_internalBatch = new MySpritesBatch(); RC.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); RC.SetInputLayout(m_inputLayout); //RC.SetScreenViewport(); RC.SetViewport(viewport.OffsetX, viewport.OffsetY, viewport.Width, viewport.Height); RC.VertexShader.Set(m_vs); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.AllShaderStages.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.GetObjectCB(64)); RC.PixelShader.Set(m_ps); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); //RC.BindDepthRT(null, DepthStencilAccess.DepthReadOnly, MyRender11.Backbuffer); // to reset state RC.SetRtv(rtv); RC.SetBlendState(blendstate == null ? MyBlendStateManager.BlendAlphaPremult : blendstate); RC.SetDepthStencilState(MyDepthStencilStateManager.IgnoreDepthStencil, 0); CheckBufferSize(StackTop.m_instances.Count); RC.SetVertexBuffer(0, m_VB); var mapping = MyMapping.MapDiscard(m_VB); for (int i = 0; i < StackTop.m_instances.Count; i++) { var helper = StackTop.m_instances[i]; mapping.WriteAndPosition(ref helper); } mapping.Unmap(); mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(64)); var viewportSize = new Vector2(viewport.Width, viewport.Height); mapping.WriteAndPosition(ref viewportSize); mapping.Unmap(); foreach (var batch in StackTop.m_batches) { if (batch.ScissorRectangle.HasValue) { RC.SetRasterizerState(MyRasterizerStateManager.ScissorTestRasterizerState); var scissor = batch.ScissorRectangle.Value; RC.SetScissorRectangle((int)scissor.X, (int)scissor.Y, (int)(scissor.X + scissor.Width), (int)(scissor.Y + scissor.Height)); } else { RC.SetRasterizerState(MyRasterizerStateManager.NocullRasterizerState); } RC.PixelShader.SetSrv(0, batch.Texture); RC.DrawInstanced(4, batch.Count, 0, batch.Start); } RC.SetBlendState(null); RC.SetRasterizerState(null); RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); StackTop.m_instances.Clear(); StackTop.m_batches.Clear(); }
internal unsafe static void Render() { var RC = MyImmediateRC.RC; if (Atmospheres.Count == 0 || !Enabled) { return; } var sphereMesh = MyMeshes.GetMeshId(X.TEXT_("Models/Debug/Sphere.mwm"), 1.0f); var buffers = MyMeshes.GetLodMesh(sphereMesh, 0).Buffers; RC.SetVertexBuffer(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIndexBuffer(buffers.IB.Buffer, buffers.IB.Format); RC.VertexShader.Set(m_proxyVs); RC.SetInputLayout(m_proxyIL); RC.SetRasterizerState(null); RC.SetBlendState(MyBlendStateManager.BlendAtmosphere); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); var cb = MyCommon.GetObjectCB(sizeof(AtmosphereConstants)); RC.AllShaderStages.SetConstantBuffer(1, cb); RC.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); // depth, RC.PixelShader.SetSrvs(0, MyGBuffer.Main); RC.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.ReadOnly, MyGBuffer.Main.LBuffer); var indicesNum = MyMeshes.GetLodMesh(sphereMesh, 0).Info.IndicesNum; // sort by distance int i = Atmospheres.Count; foreach (var atmosphere in Atmospheres.OrderByDescending(x => (x.Value.WorldMatrix.Translation - MyRender11.Environment.Matrices.CameraPosition).LengthSquared())) { var worldMatrix = atmosphere.Value.WorldMatrix; worldMatrix.Translation -= MyRender11.Environment.Matrices.CameraPosition; var worldViewProj = ((Matrix)worldMatrix) * MyRender11.Environment.Matrices.ViewProjectionAt0; double distance = worldMatrix.Translation.Length(); double atmosphereTop = atmosphere.Value.AtmosphereRadius * atmosphere.Value.Settings.AtmosphereTopModifier * atmosphere.Value.PlanetScaleFactor * atmosphere.Value.Settings.RayleighTransitionModifier; float rayleighHeight = atmosphere.Value.Settings.RayleighHeight; float t = 0.0f; if (distance > atmosphereTop) { if (distance > atmosphereTop * 2.0f) { t = 1.0f; } else { t = (float)((distance - atmosphereTop) / atmosphereTop); } } rayleighHeight = MathHelper.Lerp(atmosphere.Value.Settings.RayleighHeight, atmosphere.Value.Settings.RayleighHeightSpace, t); AtmosphereConstants constants = new AtmosphereConstants(); constants.WorldViewProj = Matrix.Transpose(worldViewProj); constants.PlanetCentre = (Vector3)worldMatrix.Translation; constants.AtmosphereRadius = atmosphere.Value.AtmosphereRadius * atmosphere.Value.Settings.AtmosphereTopModifier; // Raise the ground a bit for better sunsets constants.GroundRadius = atmosphere.Value.PlanetRadius * 1.01f * atmosphere.Value.Settings.SeaLevelModifier; constants.BetaRayleighScattering = atmosphere.Value.BetaRayleighScattering / atmosphere.Value.Settings.RayleighScattering; constants.BetaMieScattering = atmosphere.Value.BetaMieScattering / atmosphere.Value.Settings.MieColorScattering; constants.HeightScaleRayleighMie = atmosphere.Value.HeightScaleRayleighMie * new Vector2(rayleighHeight, atmosphere.Value.Settings.MieHeight); constants.MieG = atmosphere.Value.Settings.MieG; constants.PlanetScaleFactor = atmosphere.Value.PlanetScaleFactor; constants.AtmosphereScaleFactor = atmosphere.Value.AtmosphereScaleFactor; constants.Intensity = atmosphere.Value.Settings.Intensity; constants.FogIntensity = atmosphere.Value.Settings.FogIntensity; var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref constants); mapping.Unmap(); var luts = AtmosphereLUT[atmosphere.Key]; RC.PixelShader.SetSrvs(5, luts.TransmittanceLut); bool inside = worldMatrix.Translation.Length() < atmosphere.Value.AtmosphereRadius * atmosphere.Value.PlanetScaleFactor; if (inside) { RC.SetRasterizerState(MyRasterizerStateManager.InvTriRasterizerState); if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.IgnoreDepthStencil); } } else { RC.SetRasterizerState(null); if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestDepthAndEdgeStencil, 0); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.DepthTestReadOnly); } } RC.PixelShader.Set(m_ps); RC.DrawIndexed(indicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { if (inside) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0x80); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.TestDepthAndEdgeStencil, 0x80); } RC.PixelShader.Set(m_psPerSample); RC.DrawIndexed(indicesNum, 0, 0); } i--; } RC.PixelShader.SetSrvs(5, null, null); RC.SetRasterizerState(null); RC.SetDepthStencilState(null); RC.SetRtv(null); }
static unsafe MyMaterialProxy_2 CreateProxy(MyVoxelMaterialTriple triple) { byte[] buffer; int size; System.Diagnostics.Debug.Assert(triple.I0 < Table.Length, "Index to table incorrect"); System.Diagnostics.Debug.Assert(triple.I1 < Table.Length, "Index to table incorrect"); System.Diagnostics.Debug.Assert(triple.I2 < Table.Length, "Index to table incorrect"); //TODO: This shouldnt happen if Table is created correctly if (triple.I0 >= Table.Length) { triple.I0 = 0; } if (triple.I1 >= Table.Length) { triple.I1 = -1; } if (triple.I2 >= Table.Length) { triple.I2 = -1; } //////end of hack bool singleMaterial = triple.I1 == -1 && triple.I2 == -1; if (singleMaterial) { size = sizeof(MyVoxelMaterialConstants); MyVoxelMaterialConstants constantsData = new MyVoxelMaterialConstants(); constantsData.DistancesAndScale = Table[triple.I0].DistanceAndScale; constantsData.DistancesAndScaleFar = Table[triple.I0].DistanceAndScaleFar; constantsData.DistancesAndScaleFar3 = Table[triple.I0].DistanceAndScaleFar3; constantsData.Far3Color = Table[triple.I0].Far3Color; constantsData.ExtensionDetailScale = Table[triple.I0].ExtensionDetailScale; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } else { size = sizeof(MyVoxelMultiMaterialConstants); MyVoxelMultiMaterialConstants constantsData = new MyVoxelMultiMaterialConstants(); constantsData.DistancesAndScale0 = Table[triple.I0].DistanceAndScale; constantsData.DistancesAndScale1 = Table[triple.I1].DistanceAndScale; constantsData.DistancesAndScale2 = triple.I2 >= 0 ? Table[triple.I2].DistanceAndScale : Vector4.Zero; constantsData.DistancesAndScaleFar0 = Table[triple.I0].DistanceAndScaleFar; constantsData.DistancesAndScaleFar1 = Table[triple.I1].DistanceAndScaleFar; constantsData.DistancesAndScaleFar2 = triple.I2 >= 0 ? Table[triple.I2].DistanceAndScaleFar : Vector4.Zero; constantsData.DistancesAndScaleFar3 = triple.I2 >= 0 ? Table[triple.I2].DistanceAndScaleFar3 : Vector2.Zero; constantsData.Far3Color = triple.I2 >= 0 ? Table[triple.I2].Far3Color : Color.Black; constantsData.ExtensionDetailScale0 = Table[triple.I0].ExtensionDetailScale; constantsData.ExtensionDetailScale1 = Table[triple.I1].ExtensionDetailScale; constantsData.ExtensionDetailScale2 = triple.I2 >= 0 ? Table[triple.I2].ExtensionDetailScale : 0; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); return(new MyMaterialProxy_2 { MaterialConstants = { BindFlag = MyBindFlag.BIND_PS, CB = MyCommon.GetMaterialCB(size), Version = version, Data = buffer }, MaterialSRVs = { // NOTE(AF) Adding BIND_VS here will interfere with shadows, causing flickering in the first cascade BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, SRVs = singleMaterial ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, } : ( triple.I2 == -1 ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, null, null, null, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, null, null, null, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, Table[triple.I1].Near.ExtArray.ShaderView, Table[triple.I1].Far1.ExtArray.ShaderView, Table[triple.I1].Far2.ExtArray.ShaderView, null, null, null } : new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, Table[triple.I2].Near.ColorMetalArray.ShaderView, Table[triple.I2].Far1.ColorMetalArray.ShaderView, Table[triple.I2].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, Table[triple.I2].Near.NormalGlossArray.ShaderView, Table[triple.I2].Far1.NormalGlossArray.ShaderView, Table[triple.I2].Far2.NormalGlossArray.ShaderView, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, Table[triple.I1].Near.ExtArray.ShaderView, Table[triple.I1].Far1.ExtArray.ShaderView, Table[triple.I1].Far2.ExtArray.ShaderView, Table[triple.I2].Near.ExtArray.ShaderView, Table[triple.I2].Far1.ExtArray.ShaderView, Table[triple.I2].Far2.ExtArray.ShaderView, } ) } }); }
internal static MyBindableResource Run(MyBindableResource uav0, MyBindableResource uav1, MyBindableResource src, MyBindableResource prevLum) { var size = src.GetSize(); var texelsNum = size.X * size.Y; uint sizeX = (uint)size.X; uint sizeY = (uint)size.Y; float adaptationFactor = MyRender11.Postprocess.EnableEyeAdaptation ? -1.0f : MyRender11.Postprocess.ConstantLuminance; var buffer = MyCommon.GetObjectCB(16); var mapping = MyMapping.MapDiscard(buffer); mapping.WriteAndPosition(ref sizeX); mapping.WriteAndPosition(ref sizeY); mapping.WriteAndPosition(ref texelsNum); mapping.WriteAndPosition(ref adaptationFactor); mapping.Unmap(); RC.CSSetCB(0, MyCommon.FrameConstants); RC.CSSetCB(1, MyCommon.GetObjectCB(16)); RC.BindUAV(0, uav0); RC.BindSRV(0, src); RC.SetCS(m_initialShader); RC.DeviceContext.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1); RC.SetCS(m_sumShader); int i = 0; while (true) { size.X = (size.X + m_numthreads - 1) / m_numthreads; size.Y = (size.Y + m_numthreads - 1) / m_numthreads; if (size.X <= 8 && size.Y <= 8) { break; } //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer); //mapping.stream.Write(new Vector2I(size.X, size.Y)); //mapping.Unmap(); RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0); RC.BindSRV(0, (i % 2 == 0) ? uav0 : uav1); RC.DeviceContext.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1); //might not be exactly correct if we skip this var dirty = (i % 2 == 0) ? uav0 : uav1; RC.DeviceContext.ClearUnorderedAccessView((dirty as IUnorderedAccessBindable).UAV, new SharpDX.Int4(0, 0, 0, 0)); i++; } RC.SetCS(m_finalShader); //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer); //mapping.stream.Write(new Vector2I(size.X, size.Y)); //mapping.stream.Write(texelsNum); //mapping.Unmap(); RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0); RC.BindSRVs(0, (i % 2 == 0) ? uav0 : uav1, prevLum); RC.DeviceContext.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1); RC.SetCS(null); var output = (i % 2 == 0) ? uav1 : uav0; RC.DeviceContext.CopySubresourceRegion(output.m_resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), prevLum.m_resource, 0); return(output); }
internal unsafe static void RenderSpotlights() { RC.BindDepthRT(MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.ReadOnly, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer)); RC.DeviceContext.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); RC.DeviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; var coneMesh = MyMeshes.GetMeshId(X.TEXT_("Models/Debug/Cone.mwm")); var buffers = MyMeshes.GetLodMesh(coneMesh, 0).Buffers; RC.SetVB(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIB(buffers.IB.Buffer, buffers.IB.Format); RC.SetVS(SpotlightProxyVs); RC.SetIL(SpotlightProxyIL); RC.SetRS(MyRender11.m_invTriRasterizerState); var cb = MyCommon.GetObjectCB(sizeof(SpotlightConstants)); RC.SetCB(1, cb); RC.DeviceContext.PixelShader.SetSampler(13, SamplerStates.m_alphamask); RC.DeviceContext.PixelShader.SetSampler(14, SamplerStates.m_shadowmap); RC.DeviceContext.PixelShader.SetSampler(15, SamplerStates.m_shadowmap); int index = 0; int casterIndex = 0; foreach (var id in VisibleSpotlights) { MyLights.WriteSpotlightConstants(id, ref Spotlights[index]); var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref Spotlights[index]); mapping.Unmap(); RC.DeviceContext.PixelShader.SetShaderResource(13, MyTextures.GetView(MyLights.Spotlights[id.Index].ReflectorTexture)); if (id.CastsShadowsThisFrame) { RC.DeviceContext.PixelShader.SetShaderResource(14, MyRender11.DynamicShadows.ShadowmapsPool[casterIndex].SRV); casterIndex++; } RC.SetPS(SpotlightPs_Pixel); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0); } RC.DeviceContext.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { RC.SetPS(SpotlightPs_Sample); RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0x80); RC.DeviceContext.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); } index++; if (index >= SPOTLIGHTS_MAX) { break; } } if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.DefaultDepthState); } RC.SetRS(null); }
static unsafe MyMaterialProxy_2 CreateProxy(MyVoxelMaterialTriple triple) { byte[] buffer; int size; bool singleMaterial = triple.I1 == -1 && triple.I2 == -1; if (singleMaterial) { size = sizeof(MyVoxelMaterialConstants); MyVoxelMaterialConstants constantsData = new MyVoxelMaterialConstants(); constantsData.Scales = Table[triple.I0].ScaleFactors; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } else { size = sizeof(MyVoxelMultiMaterialConstants); MyVoxelMultiMaterialConstants constantsData = new MyVoxelMultiMaterialConstants(); constantsData.Scales0 = Table[triple.I0].ScaleFactors; constantsData.Scales1 = Table[triple.I1].ScaleFactors; constantsData.Scales2 = triple.I2 >= 0 ? Table[triple.I2].ScaleFactors : Vector3.One; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); return(new MyMaterialProxy_2 { MaterialConstants = { BindFlag = MyBindFlag.BIND_PS, CB = MyCommon.GetMaterialCB(size), Version = version, Data = buffer }, MaterialSRVs = { BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, SRVs = singleMaterial ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, } : ( triple.I2 == -1 ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, null, null, null, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, null, null, null, null, null, null, null, null, null, null, null, null } : new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, Table[triple.I2].Near.ColorMetalArray.ShaderView, Table[triple.I2].Far1.ColorMetalArray.ShaderView, Table[triple.I2].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, Table[triple.I2].Near.NormalGlossArray.ShaderView, Table[triple.I2].Far1.NormalGlossArray.ShaderView, Table[triple.I2].Far2.NormalGlossArray.ShaderView, null, null, null, null, null, null, null, null, null } ) } }); }
internal unsafe static void Render(MyBindableResource dst, MyBindableResource depth, MyBindableResource depthRead) { if (!MyRender11.DebugOverrides.BillboardsDynamic) { OnFrameStart(); } m_stats.Clear(); MyRender11.GetRenderProfiler().StartProfilingBlock("Gather"); Gather(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Draw"); TransferData(); RC.SetupScreenViewport(); RC.BindDepthRT(depth, DepthStencilAccess.ReadOnly, dst); RC.SetBS(MyRender11.BlendAlphaPremult); RC.SetRS(MyRender11.m_nocullRasterizerState); RC.BindRawSRV(104, m_SB); RC.BindSRV(1, depthRead); RC.SetCB(2, MyCommon.GetObjectCB(sizeof(Matrix) * MaxCustomProjections)); RC.SetDS(MyDepthStencilState.DefaultDepthState); RC.SetCB(4, MyRender11.DynamicShadows.ShadowCascades.CascadeConstantBuffer); RC.DeviceContext.VertexShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, SamplerStates.m_shadowmap); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.CASCADES_SM_SLOT, MyRender11.DynamicShadows.ShadowCascades.CascadeShadowmapArray.SRV); RC.DeviceContext.VertexShader.SetSamplers(0, SamplerStates.StandardSamplers); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.SKYBOX_IBL_SLOT, MyRender11.IsIntelBrokenCubemapsWorkaround ? MyTextures.GetView(MyTextures.IntelFallbackCubeTexId) : MyEnvironmentProbe.Instance.cubemapPrefiltered.SRV); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.SKYBOX2_IBL_SLOT, MyTextures.GetView(MyTextures.GetTexture(MyEnvironment.NightSkyboxPrefiltered, MyTextureEnum.CUBEMAP, true))); RC.SetVB(0, m_VB.Buffer, m_VB.Stride); RC.SetIB(m_IB.Buffer, m_IB.Format); RC.SetIL(m_inputLayout); for (int i = 0; i < m_batches.Count; i++) { // first part of batches contain sorted billboards and they read depth // second part of batches contain unsorted billboards and they ignore depth // switch here: if (m_batches[i].Offset == m_sortedBillboardsNum) { //RC.BindDepthRT(null, DepthStencilAccess.ReadOnly, dst); } if (m_batches[i].Lit) { RC.SetVS(m_vsLit); if (m_batches[i].AlphaCutout) { RC.SetPS(m_psAlphaCutoutAndLit); } else { RC.SetPS(m_psLit); } } else if (m_batches[i].AlphaCutout) { RC.SetVS(m_vs); RC.SetPS(m_psAlphaCutout); } else { RC.SetVS(m_vs); RC.SetPS(m_ps); } RC.BindRawSRV(0, m_batches[i].Texture); RC.DeviceContext.DrawIndexed(m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); ++RC.Stats.BillboardDrawIndexed; } m_stats.Billboards += m_sorted + m_unsorted; RC.SetRS(null); RC.SetBS(null); m_batches.Clear(); MyRender11.GatherStats(m_stats); MyRender11.GetRenderProfiler().EndProfilingBlock(); }
internal static int Gather(MyGPUEmitterData[] data, out SharpDX.Direct3D11.ShaderResourceView textureArraySRV) { for (int i = 0; i < MAX_LIVE_EMITTERS; i++) { data[i].NumParticlesToEmitThisFrame = 0; } // sort emitters! List <MyLiveData> emitters = m_emitters.Values.ToList(); //if (emitters.Count > MAX_LIVE_EMITTERS) emitters.Sort(); int maxEmitterIndex = -1; uint textureIndex = 0; int unassociatedCount = 0; int skipCount = 0; int unsortedCount = 0; int firstUnassociatedIndex = -1; int lastAssociatedIndex = -1; for (int i = 0; i < emitters.Count; i++) { var emitter = emitters[i]; // assiociate buffer index to new emitters & track overload to free space for unassociated near emitters later if (emitter.BufferIndex == -1) { if (m_freeBufferIndices.Count > 0) { emitter.BufferIndex = m_freeBufferIndices.Pop(); } else { unassociatedCount++; if (firstUnassociatedIndex == -1) { firstUnassociatedIndex = i; } } } else { skipCount = unassociatedCount; lastAssociatedIndex = i; if (unassociatedCount > 0) { unsortedCount++; } } if (MyCommon.TimerMs > emitter.DieAt) { emitter.GPUEmitter.Data.Flags |= GPUEmitterFlags.Dead; } if (emitter.BufferIndex != -1) { if ((emitter.GPUEmitter.Data.Flags & GPUEmitterFlags.FreezeEmit) == 0) { float toEmit = MyCommon.LastFrameDelta() * emitter.GPUEmitter.ParticlesPerSecond + emitter.ParticlesEmittedFraction; emitter.GPUEmitter.Data.NumParticlesToEmitThisFrame = (int)toEmit; emitter.ParticlesEmittedFraction = toEmit - emitter.GPUEmitter.Data.NumParticlesToEmitThisFrame; } if (emitter.TextureId != Resources.TexId.NULL) { MyRenderProxy.Assert(m_textureArrayIndices.ContainsKey(emitter.TextureId)); textureIndex = m_textureArrayIndices[emitter.TextureId].Index; } else { textureIndex = 0; } int bufferIndex = emitter.BufferIndex; data[bufferIndex] = emitter.GPUEmitter.Data; Vector3 pos = emitter.GPUEmitter.WorldPosition - MyRender11.Environment.CameraPosition; data[bufferIndex].RotationMatrix.M14 = pos.X; data[bufferIndex].RotationMatrix.M24 = pos.Y; data[bufferIndex].RotationMatrix.M34 = pos.Z; data[bufferIndex].TextureIndex1 |= textureIndex << (ATLAS_INDEX_BITS + ATLAS_DIMENSION_BITS * 2); if (bufferIndex > maxEmitterIndex) { maxEmitterIndex = bufferIndex; } } } /*MyRenderStats.Generic.WriteFormat("GPU particles allocated: {0}", totalParticles, VRage.Stats.MyStatTypeEnum.CurrentValue, 300, 0); * MyRenderStats.Generic.WriteFormat("GPU particles overload: {0}", overloadedParticles ? 1.0f : 0, VRage.Stats.MyStatTypeEnum.CurrentValue, 300, 0); * MyRenderStats.Generic.WriteFormat("GPU emitters overload: {0}", overloadedEmitters ? 1.0f : 0, VRage.Stats.MyStatTypeEnum.CurrentValue, 300, 0);*/ UpdateTextureArray(); if (m_textureArray != null) { textureArraySRV = m_textureArray.SRV; } else { textureArraySRV = null; } // stop emitters far away to make room for emitters nearby if (skipCount > 0 && unsortedCount > 0) { // iterate until buffer-unassociated index is larger then unassocited one for (int i = firstUnassociatedIndex, j = lastAssociatedIndex; i < j;) { var emitter = emitters[j]; // free last buffer-associated emitter data[emitter.BufferIndex].Flags |= GPUEmitterFlags.Dead; data[emitter.BufferIndex].NumParticlesToEmitThisFrame = 0; m_freeBufferIndices.Push(emitter.BufferIndex); emitter.BufferIndex = -1; // find new last buffer-associated emitter do { j--; }while (j > 0 && emitters[j].BufferIndex == -1); // find next buffer-unassociated emitter do { i++; } while (i < emitters.Count && emitters[i].BufferIndex != -1); } } foreach (var emitter in emitters) { if ((emitter.GPUEmitter.Data.Flags & GPUEmitterFlags.Dead) > 0) { Remove(emitter); } } return(maxEmitterIndex + 1); }
internal unsafe static void Render(MyBindableResource dst, MyBindableResource depth, MyBindableResource depthRead) { MyRender11.GetRenderProfiler().StartProfilingBlock("Gather"); Gather(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Draw"); TransferData(); RC.SetupScreenViewport(); RC.BindDepthRT(depth, DepthStencilAccess.ReadOnly, dst); RC.SetBS(MyRender11.BlendAlphaPremult); RC.SetRS(MyRender11.m_nocullRasterizerState); RC.BindRawSRV(104, m_SB.Srv); RC.BindSRV(1, depthRead); RC.SetCB(2, MyCommon.GetObjectCB(sizeof(Matrix) * MaxCustomProjections)); RC.SetDS(MyDepthStencilState.DefaultDepthState); RC.SetCB(4, MyShadows.m_csmConstants); RC.Context.VertexShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MyRender11.m_shadowmapSamplerState); RC.Context.VertexShader.SetShaderResource(MyCommon.CASCADES_SM_SLOT, MyShadows.m_cascadeShadowmapArray.ShaderView); RC.Context.VertexShader.SetSamplers(0, MyRender11.StandardSamplers); RC.Context.VertexShader.SetShaderResource(MyCommon.SKYBOX_IBL_SLOT, MyTextures.GetView(MyTextures.GetTexture(MyEnvironment.DaySkyboxPrefiltered, MyTextureEnum.CUBEMAP, true))); RC.Context.PixelShader.SetShaderResource(MyCommon.SKYBOX2_IBL_SLOT, MyTextures.GetView(MyTextures.GetTexture(MyEnvironment.NightSkyboxPrefiltered, MyTextureEnum.CUBEMAP, true))); RC.SetVB(0, m_VB.Buffer, m_VB.Stride); RC.SetIB(m_IB.Buffer, m_IB.Format); RC.SetIL(m_inputLayout); for (int i = 0; i < m_batches.Count; i++) { // first part of batches contain sorted billboards and they read depth // second part of batches contain unsorted billboards and they ignore depth // switch here: if (m_batches[i].Offset == m_sortedBillboardsNum) { //RC.BindDepthRT(null, DepthStencilAccess.ReadOnly, dst); } if (m_batches[i].Lit) { RC.SetVS(m_vsLit); RC.SetPS(m_psLit); } else { RC.SetVS(m_vs); RC.SetPS(m_ps); } RC.BindRawSRV(0, m_batches[i].Texture); RC.Context.DrawIndexed(m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); } RC.SetRS(null); m_batches.Clear(); MyRender11.GetRenderProfiler().EndProfilingBlock(); }
// can be on another job internal unsafe static void Draw() { var decals = IdIndex.Values.ToArray(); // sort visible decals by material Array.Sort(decals, DecalsMaterialComparer); /// // copy gbuffer with normals for read (uhoh) // bind copy and depth for read // bind gbuffer for write var RC = MyImmediateRC.RC; RC.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; RC.SetIB(m_IB.Buffer, m_IB.Format); RC.SetIL(null); RC.DeviceContext.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); RC.SetCB(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.BindGBufferForWrite(MyGBuffer.Main, DepthStencilAccess.DepthReadOnly); RC.SetVS(m_vs); RC.SetPS(m_ps); RC.SetDS(MyDepthStencilState.DepthTest); RC.DeviceContext.PixelShader.SetSamplers(0, MyRender11.StandardSamplers); RC.BindSRV(0, MyGBuffer.Main.DepthStencil.Depth); RC.DeviceContext.PixelShader.SetShaderResource(1, MyRender11.m_gbuffer1Copy.ShaderView); var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * MAX_DECALS); RC.SetCB(2, decalCb); var prevMaterial = new MyStringId(); MyScreenDecalType decalType = MyScreenDecalType.ScreenDecalBump; for (int i = 0; i < decals.Length; ++i) { var index = decals[i]; var material = Decals.Data[index].Material; if (i == 0 || material != prevMaterial) { DrawBatch(decalType); var matDesc = Materials[material]; decalType = matDesc.DecalType; // factor 1 makes overwriting of gbuffer color & subtracting from ao RC.SetBS(MyRender11.BlendDecal, matDesc.DecalType == MyScreenDecalType.ScreenDecalBump ? new SharpDX.Color4(0) : SharpDX.Color4.White); RC.DeviceContext.PixelShader.SetShaderResource(3, MyTextures.GetView(matDesc.AlphamaskTexture)); RC.DeviceContext.PixelShader.SetShaderResource(4, MyTextures.GetView(matDesc.ColorMetalTexture)); RC.DeviceContext.PixelShader.SetShaderResource(5, MyTextures.GetView(matDesc.NormalmapTexture)); } var parent = MyIDTracker <MyActor> .FindByID(Decals.Data[index].ParentID); if (parent != null) { var parentMatrix = parent.WorldMatrix; var volumeMatrix = Decals.Data[index].LocalOBB * parentMatrix * Matrix.CreateTranslation(-MyEnvironment.CameraPosition); m_matrices.Add(volumeMatrix); } } DrawBatch(decalType); RC.SetBS(null); }
internal static void PreparePointLights() { var activePointlights = 0; MyLights.Update(); BoundingFrustumD viewFrustumClippedD = MyRender11.Environment.ViewFrustumClippedD; if (MyStereoRender.Enable) { if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT) { viewFrustumClippedD = MyStereoRender.EnvMatricesLeftEye.ViewFrustumClippedD; } else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT) { viewFrustumClippedD = MyStereoRender.EnvMatricesRightEye.ViewFrustumClippedD; } } MyLights.PointlightsBvh.OverlapAllFrustum(ref viewFrustumClippedD, VisiblePointlights); bool visiblePointlights = VisiblePointlights.Count != 0; if (!visiblePointlights && !m_lastFrameVisiblePointlights) { return; } m_lastFrameVisiblePointlights = visiblePointlights; if (VisiblePointlights.Count > MyRender11Constants.MAX_POINT_LIGHTS) { VisiblePointlights.Sort((x, y) => x.ViewerDistanceSquared.CompareTo(y.ViewerDistanceSquared)); while (VisiblePointlights.Count > MyRender11Constants.MAX_POINT_LIGHTS) { VisiblePointlights.RemoveAtFast(VisiblePointlights.Count - 1); } } foreach (var light in VisiblePointlights) { MyLights.WritePointlightConstants(light, ref m_pointlightsCullBuffer[activePointlights]); activePointlights++; Debug.Assert(activePointlights <= MyRender11Constants.MAX_POINT_LIGHTS); } for (int lightIndex = activePointlights; lightIndex < MyRender11Constants.MAX_POINT_LIGHTS; ++lightIndex) { MyLights.WritePointlightConstants(LightId.NULL, ref m_pointlightsCullBuffer[lightIndex]); } var mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(16)); mapping.WriteAndPosition(ref activePointlights); mapping.Unmap(); mapping = MyMapping.MapDiscard(m_pointlightCullHwBuffer.Buffer); mapping.WriteAndPosition(m_pointlightsCullBuffer, 0, MyRender11Constants.MAX_POINT_LIGHTS); mapping.Unmap(); if (!MyStereoRender.Enable) { RC.CSSetCB(0, MyCommon.FrameConstants); } else { MyStereoRender.CSBindRawCB_FrameConstants(RC); } RC.CSSetCB(1, MyCommon.GetObjectCB(16)); //RC.BindUAV(0, MyScreenDependants.m_test); RC.BindUAV(0, MyScreenDependants.m_tileIndices); RC.BindGBufferForRead(0, MyGBuffer.Main); RC.CSBindRawSRV(MyCommon.POINTLIGHT_SLOT, m_pointlightCullHwBuffer); RC.SetCS(m_preparePointLights); Vector2I tiles = new Vector2I(MyScreenDependants.TilesX, MyScreenDependants.TilesY); if (MyStereoRender.Enable && MyStereoRender.RenderRegion != MyStereoRegion.FULLSCREEN) { tiles.X /= 2; } RC.DeviceContext.Dispatch(tiles.X, tiles.Y, 1); RC.SetCS(null); }
internal static IBorrowedUavTexture Run(ISrvBindable src) { IBorrowedUavTexture uav0 = MyManagers.RwTexturesPool.BorrowUav("MyLuminanceAverage.Uav0", Format.R32G32_Float); IBorrowedUavTexture uav1 = MyManagers.RwTexturesPool.BorrowUav("MyLuminanceAverage.Uav1", Format.R32G32_Float); Vector2I size = src.Size; int texelsNum = size.X * size.Y; uint sizeX = (uint)size.X; uint sizeY = (uint)size.Y; var buffer = MyCommon.GetObjectCB(16); var mapping = MyMapping.MapDiscard(buffer); mapping.WriteAndPosition(ref sizeX); mapping.WriteAndPosition(ref sizeY); mapping.WriteAndPosition(ref texelsNum); mapping.Unmap(); RC.ComputeShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.ComputeShader.SetConstantBuffer(1, MyCommon.GetObjectCB(16)); RC.ComputeShader.Set(m_initialShader); IBorrowedUavTexture output = uav0; ISrvBindable inputSrc = src; RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrv(0, inputSrc); int threadGroupCountX = ComputeGroupCount(size.X); int threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); RC.ComputeShader.Set(m_sumShader); IBorrowedUavTexture input; int i = 0; while (true) { size.X = threadGroupCountX; size.Y = threadGroupCountY; if (size.X <= NUM_THREADS && size.Y <= NUM_THREADS) { break; } output = (i % 2 == 0) ? uav1 : uav0; input = (i % 2 == 0) ? uav0 : uav1; RC.ComputeShader.SetSrv(0, null); RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrv(0, input); threadGroupCountX = ComputeGroupCount(size.X); threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); i++; } RC.ComputeShader.Set(m_finalShader); output = (i % 2 == 0) ? uav1 : uav0; input = (i % 2 == 0) ? uav0 : uav1; RC.ComputeShader.SetSrv(0, null); RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrvs(0, input, m_prevLum); threadGroupCountX = ComputeGroupCount(size.X); threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); RC.ComputeShader.Set(null); RC.ComputeShader.SetUav(0, null); // Backup the result for later process RC.CopySubresourceRegion(output, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), m_prevLum, 0); input.Release(); return(output); }