internal static void PreparePointLights() { var activePointlights = 0; MyLights.Update(); MyLights.PointlightsBvh.OverlapAllFrustum(ref MyEnvironment.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(); RC.CSSetCB(0, MyCommon.FrameConstants); 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.Srv); RC.SetCS(m_preparePointLights); RC.DeviceContext.Dispatch(MyScreenDependants.TilesX, MyScreenDependants.TilesY, 1); RC.SetCS(null); }
internal static void PreparePointLights() { var activePointlights = 0; MyLights.Update(); MyLights.PointlightsBvh.OverlapAllFrustum(ref MyEnvironment.ViewFrustumClippedD, 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); } var mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(16)); mapping.stream.Write(activePointlights); mapping.stream.Write(0f); mapping.stream.Write(0f); mapping.stream.Write(0f); mapping.Unmap(); mapping = MyMapping.MapDiscard(m_pointlightCullHwBuffer.Buffer); for (int i = 0; i < activePointlights; i++) { mapping.stream.Write(m_pointlightsCullBuffer[i]); } for (int i = activePointlights; i < MyRender11Constants.MAX_POINT_LIGHTS; i++) { mapping.stream.Write(new MyPointlightConstants()); } mapping.Unmap(); RC.CSSetCB(0, MyCommon.FrameConstants); RC.CSSetCB(1, MyCommon.GetObjectCB(16)); //RC.BindUAV(0, MyScreenDependants.m_test); RC.BindUAV(0, MyScreenDependants.m_tileIndexes); RC.BindGBufferForRead(0, MyGBuffer.Main); RC.CSBindRawSRV(MyCommon.POINTLIGHT_SLOT, m_pointlightCullHwBuffer.Srv); RC.SetCS(m_preparePointLights); var size = MyRender11.ViewportResolution; RC.Context.Dispatch((size.X + TILE_SIZE - 1) / TILE_SIZE, (size.Y + TILE_SIZE - 1) / TILE_SIZE, 1); RC.SetCS(null); }
// Per-frame emission of particles into the GPU simulation private static void Emit(int emitterCount, MyGPUEmitterData[] emitterData) { // update emitter data var mapping = MyMapping.MapDiscard(m_emitterStructuredBuffer.Buffer); int maxParticlesToEmitThisFrame = 0; for (int i = 0; i < emitterCount; i++) { mapping.WriteAndPosition(ref emitterData[i]); if (emitterData[i].NumParticlesToEmitThisFrame > maxParticlesToEmitThisFrame) { maxParticlesToEmitThisFrame = emitterData[i].NumParticlesToEmitThisFrame; } } mapping.Unmap(); int numThreadGroupsX = align(maxParticlesToEmitThisFrame, MAX_PARTICLE_EMIT_THREADS) / MAX_PARTICLE_EMIT_THREADS; int numThreadGroupsY = align(emitterCount, MAX_EMITTERS) / MAX_EMITTERS; // update emitter count mapping = MyMapping.MapDiscard(m_emitterConstantBuffer); mapping.WriteAndPosition(ref emitterCount); mapping.WriteAndPosition(ref numThreadGroupsX); mapping.Unmap(); if (maxParticlesToEmitThisFrame > 0) { // Set resources but don't reset any atomic counters RC.BindUAV(0, m_particleBuffer); RC.BindUAV(1, m_deadListBuffer); RC.BindUAV(2, m_skippedParticleCountBuffer, 0); RC.CSSetCB(1, m_emitterConstantBuffer); RC.CSBindRawSRV(0, Resources.MyTextures.RandomTexId); RC.CSBindRawSRV(1, m_emitterStructuredBuffer); RC.SetCS(m_csEmit); RC.DeviceContext.Dispatch(numThreadGroupsX, numThreadGroupsY, 1); RC.CSSetCB(1, null); RC.SetCS(m_csEmitSkipFix); // Disaptch a set of 1d thread groups to fill out the dead list, one thread per particle RC.DeviceContext.Dispatch(1, 1, 1); } #if DEBUG //m_numDeadParticlesAfterEmit = ReadCounter(m_deadListBuffer); #endif }
// Per-frame simulation step private static void Simulate(MyBindableResource depthRead) { RC.BindUAV(0, m_particleBuffer); RC.BindUAV(1, m_deadListBuffer); RC.BindUAV(2, m_aliveIndexBuffer, 0); RC.BindUAV(3, m_indirectDrawArgsBuffer); RC.BindSRV(0, depthRead); RC.CSBindRawSRV(1, m_emitterStructuredBuffer); RC.SetCS(m_csSimulate); RC.DeviceContext.Dispatch(align(MyGPUEmitters.MAX_PARTICLES, 256) / 256, 1, 1); RC.DeviceContext.ComputeShader.SetUnorderedAccessView(0, null, -1); RC.DeviceContext.ComputeShader.SetUnorderedAccessView(1, null, -1); RC.DeviceContext.ComputeShader.SetUnorderedAccessView(2, null, -1); RC.DeviceContext.ComputeShader.SetUnorderedAccessView(3, null, -1); }
internal static void Render() { MyLights.Update(); MyGpuProfiler.IC_BeginBlock("Map lights to tiles"); if (MyRender11.DebugOverrides.PointLights) { PreparePointLights(); } MyGpuProfiler.IC_EndBlock(); RC.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; if (!MyStereoRender.Enable) { RC.CSSetCB(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); } else { MyStereoRender.CSBindRawCB_FrameConstants(RC); } RC.BindGBufferForRead(0, MyGBuffer.Main); RC.BindRawSRV(MyCommon.MATERIAL_BUFFER_SLOT, MySceneMaterials.m_buffer); RC.SetBS(MyRender11.BlendAdditive); if (!MyStereoRender.Enable) { RC.SetDS(MyDepthStencilState.IgnoreDepthStencil); } else { RC.SetDS(MyDepthStencilState.StereoIgnoreDepthStencil); } RC.DeviceContext.PixelShader.SetSamplers(0, SamplerStates.StandardSamplers); MyGpuProfiler.IC_BeginBlock("Apply point lights"); if (MyRender11.DebugOverrides.PointLights) { RenderPointlightsTiled(); } MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Apply spotlights"); if (MyRender11.DebugOverrides.SpotLights) { RenderSpotlights(); } MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Apply directional light"); if (MyRender11.DebugOverrides.EnvLight) { RenderDirectionalEnvironmentLight(); } MyGpuProfiler.IC_EndBlock(); // Because of BindGBufferForRead: RC.BindRawSRV(0, null); RC.BindRawSRV(1, null); RC.BindRawSRV(2, null); RC.BindRawSRV(3, null); RC.BindRawSRV(4, null); RC.CSBindRawSRV(0, null); RC.CSBindRawSRV(1, null); RC.CSBindRawSRV(2, null); RC.CSBindRawSRV(3, null); RC.CSBindRawSRV(4, null); 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); }