public override void Load() { base.Load(); Parameters.AddSources(GBufferPlugin.MainPlugin.ViewParameters); Lights = this.EffectSystemOld.BuildEffect("Lights").Using(new LightPlugin()).InstantiatePermutation(); // TODO: Check if released properly. for (int i = 0; i < 2; ++i) { if (i == 1) { if (!Debug) { continue; } // Add the debug as an overlay on the main pass debugRenderPass = new RenderPass("LightPrePassDebug").KeepAliveBy(ActiveObjects); GBufferPlugin.MainPlugin.RenderPass.AddPass(debugRenderPass); } var debug = i == 1; var renderPass = i == 1 ? debugRenderPass : RenderPass; var lightDeferredEffectBuilder = this.EffectSystemOld.BuildEffect("LightPrePass" + (debug ? "Debug" : string.Empty)).KeepAliveBy(ActiveObjects); foreach (var effectPlugin in BasePlugins) { lightDeferredEffectBuilder.Using(new BasicShaderPlugin(effectPlugin) { Services = Services, RenderPassPlugin = this, RenderPass = renderPass }); } lightDeferredEffectBuilder.Using(new LightingPrepassShaderPlugin("LightPreShaderPass" + (debug ? "Debug" : string.Empty)) { Services = Services, RenderPassPlugin = this, RenderPass = renderPass, Debug = debug }); lightDeferredEffects[i] = lightDeferredEffectBuilder.InstantiatePermutation().KeepAliveBy(ActiveObjects); } if (OfflineCompilation) { return; } // Create lighting accumulation texture (that LightPlugin will use) var mainBackBuffer = graphicsDeviceService.GraphicsDevice.BackBuffer; var lightTexture = Texture2D.New(GraphicsDevice, mainBackBuffer.Width, mainBackBuffer.Height, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget); lightTexture.Name = "LightTexture"; LightTexture = lightTexture.ToRenderTarget(); // Set Parameters for this plugin Parameters.Set(LightDeferredShadingKeys.LightTexture, lightTexture); // Set GBuffer Texture0 Parameters.Set(GBufferBaseKeys.GBufferTexture, (Texture2D)GBufferPlugin.RenderTarget.Texture); // Set parameters for MainPlugin GBufferPlugin.MainTargetPlugin.Parameters.Set(LightDeferredShadingKeys.LightTexture, lightTexture); CreatePrePassMesh(RenderPass, false); if (Debug) { CreatePrePassMesh(debugRenderPass, true); } }
internal static ModelRendererState GetModelRendererState(this RenderPass pass) { return(GetOrCreateModelRendererState(pass, false)); }
public override void Unload() { RenderPass.RemovePass(PostPass); base.Unload(); }
private void CreatePrePassMesh(RenderPass renderPass, bool debug) { var lightDeferredEffect = lightDeferredEffects[debug ? 1 : 0]; Tiles = new List <LightingPrepassShaderPlugin.LightData> [TileCountX * TileCountY]; for (int i = 0; i < Tiles.Length; ++i) { Tiles[i] = new List <LightingPrepassShaderPlugin.LightData>(); } renderPass.StartPass.AddLast = (threadContext) => { // TODO THIS IS NOT ACCURATE TO TAKE THE CURRENT BACKBUFFER var mainBackBuffer = graphicsDeviceService.GraphicsDevice.BackBuffer; threadContext.GraphicsDevice.SetViewport(new Viewport(0, 0, mainBackBuffer.Width, mainBackBuffer.Height)); if (threadContext.FirstContext) { if (debug) { threadContext.GraphicsDevice.SetRenderTarget(GBufferPlugin.MainTargetPlugin.RenderTarget); } else { threadContext.GraphicsDevice.Clear(LightTexture, new Color(0.0f, 0.0f, 0.0f, 0.0f)); threadContext.GraphicsDevice.SetRenderTarget(LightTexture); } } for (int i = 0; i < Tiles.Length; ++i) { Tiles[i].Clear(); } var lights = Lights; var lightAttenuationCutoff = 0.1f; Matrix viewMatrix; var mainParameters = GBufferPlugin.MainPlugin.ViewParameters; mainParameters.Get(TransformationKeys.View, out viewMatrix); Matrix projMatrix; mainParameters.Get(TransformationKeys.Projection, out projMatrix); for (int index = 0; index < lights.Meshes.Count; index++) { LightingPrepassShaderPlugin.LightData lightData; var lightMesh = lights.Meshes[index]; Vector3 lightPos; lightMesh.Parameters.TryGet(LightKeys.LightPosition, out lightPos); Vector3.TransformCoordinate(ref lightPos, ref viewMatrix, out lightData.LightPosVS); lightMesh.Parameters.TryGet(LightKeys.LightColor, out lightData.DiffuseColor); lightMesh.Parameters.TryGet(LightKeys.LightIntensity, out lightData.LightIntensity); lightMesh.Parameters.TryGet(LightKeys.LightRadius, out lightData.LightRadius); // ------------------------------------------------------------------------------------------ // TEMPORARY FIX FOR DEFERRED LIGHTS // ------------------------------------------------------------------------------------------ //lightData2[index].DiffuseColor.Pow(1 / 4.0f); //lightData2[index].LightIntensity = (float)Math.Pow(lightData2[index].LightIntensity, 1.0f / 2.2f); // ------------------------------------------------------------------------------------------ // Linearize color lightData.DiffuseColor.Pow(Color.DefaultGamma); lightData.LightIntensity = (float)Math.Pow(lightData.LightIntensity, Color.DefaultGamma); float lightDistanceMax = CalculateMaxDistance(lightData.LightIntensity, lightData.LightRadius, lightAttenuationCutoff); var clipRegion = ComputeClipRegion(lightData.LightPosVS, lightDistanceMax, ref projMatrix); var tileStartX = (int)((clipRegion.X * 0.5f + 0.5f) * TileCountX); var tileEndX = (int)((clipRegion.Z * 0.5f + 0.5f) * TileCountX); var tileStartY = (int)((clipRegion.Y * 0.5f + 0.5f) * TileCountY); var tileEndY = (int)((clipRegion.W * 0.5f + 0.5f) * TileCountY); // Check if this light is really visible (not behind us) if (lightData.LightPosVS.Z + lightDistanceMax < 0.0f) { continue; } for (int y = tileStartY; y <= tileEndY; ++y) { if (y < 0 || y >= TileCountY) { continue; } for (int x = tileStartX; x <= tileEndX; ++x) { if (x < 0 || x >= TileCountX) { continue; } Tiles[y * TileCountX + x].Add(lightData); } } } }; var lightDeferredMesh = new EffectMesh(lightDeferredEffect).KeepAliveBy(ActiveObjects); RenderSystem.GlobalMeshes.AddMesh(lightDeferredMesh); renderPass.EndPass.AddLast = (context) => { // Clear thread context overridden variables. context.Parameters.Reset(LightingPrepassShaderPlugin.LightCount); context.Parameters.Reset(LightingPrepassShaderPlugin.LightInfos); context.Parameters.Reset(LightingPrepassShaderPlugin.TileIndex); context.Parameters.Reset(TransformationKeys.Projection); context.Parameters.Reset(RenderTargetKeys.DepthStencilSource); }; var tileRenderPasses = new RenderPass[TileCountX * TileCountY]; for (int i = 0; i < tileRenderPasses.Length; ++i) { int tileIndex = i; tileRenderPasses[i] = new RenderPass("Lighting Tile"); tileRenderPasses[i].StartPass.AddLast = (context) => { context.Parameters.Set(LightingPrepassShaderPlugin.TileIndex, tileIndex); }; throw new NotImplementedException(); //tileRenderPasses[i].Meshes.Add(lightDeferredMesh); } throw new NotImplementedException(); //renderPass.UpdatePasses += (RenderPass currentRenderPass, ref FastList<RenderPass> currentPasses) => // { // lightDeferredEffect.Passes[0].Passes.Clear(); // lightDeferredEffect.Passes[0].Passes.AddRange(tileRenderPasses); // }; }
public override void Load() { base.Load(); if (OfflineCompilation) { return; } // Declare post render pass PostPass = new RenderPass("PostPass").KeepAliveBy(ActiveObjects); RenderPass.AddPass(PostPass); var depthStencilTexture = Texture2D.New(GraphicsDevice, AtlasSize, AtlasSize, PixelFormat.D32_Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource).KeepAliveBy(ActiveObjects); var depthStencilBuffer = depthStencilTexture.ToDepthStencilBuffer(false); ShadowMapDepth = depthStencilBuffer; //MainTargetPlugin.Parameters.Set(ShadowMapKeys.Texture0, ShadowMapDepth); // Setup clear of this target var renderTargetPlugin = new RenderTargetsPlugin { Services = Services, EnableClearDepth = true, EnableSetTargets = false, RenderPass = RenderPass, RenderTarget = null, DepthStencil = depthStencilBuffer, }; renderTargetPlugin.Apply(); // Use Default ZTest for GBuffer depthStencilStateZStandard = DepthStencilState.New(GraphicsDevice, new DepthStencilStateDescription().Default()).KeepAliveBy(ActiveObjects); depthStencilStateZStandard.Name = "ZStandard"; Parameters.Set(EffectPlugin.DepthStencilStateKey, depthStencilStateZStandard); casterRasterizerState = RasterizerState.New(GraphicsDevice, new RasterizerStateDescription(CullMode.Back)).KeepAliveBy(ActiveObjects); // Variance Shadow Mapping // Create the blur temporary texture var shadowMapTextureDesc = ShadowMapDepth.Description; var shadowMapBlurH = Texture2D.New(GraphicsDevice, shadowMapTextureDesc.Width, shadowMapTextureDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects); var shadowMapBlurV = Texture2D.New(GraphicsDevice, shadowMapTextureDesc.Width, shadowMapTextureDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects); Texture2D textureSourceH = ShadowMapDepth.Texture; Texture2D textureSourceV = shadowMapBlurH; RenderTarget renderTargetH = shadowMapBlurH.ToRenderTarget(); RenderTarget renderTargetV = shadowMapBlurV.ToRenderTarget(); var blurQuadMesh = new EffectMesh[2]; for (int j = 0; j < BlurCount; j++) { for (int i = 0; i < 2; ++i) { blurQuadMesh[i] = new EffectMesh(j > 0 ? blurEffects[1] : blurEffects[i]).KeepAliveBy(ActiveObjects); blurQuadMesh[i].Parameters.Set(PostEffectBlurKeys.Coefficients, new[] { 0.2270270270f, 0.3162162162f, 0.3162162162f, 0.0702702703f, 0.0702702703f }); var unit = i == 0 ? Vector2.UnitX : Vector2.UnitY; blurQuadMesh[i].Parameters.Set(PostEffectBlurKeys.Offsets, new[] { Vector2.Zero, unit * -1.3846153846f, unit * +1.3846153846f, unit * -3.2307692308f, unit * +3.2307692308f }); PostPass.AddPass(blurQuadMesh[i].EffectPass); RenderSystem.GlobalMeshes.AddMesh(blurQuadMesh[i]); } blurQuadMesh[0].Parameters.Set(TexturingKeys.Texture0, textureSourceH); blurQuadMesh[1].Parameters.Set(TexturingKeys.Texture0, textureSourceV); blurQuadMesh[0].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetH); blurQuadMesh[1].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetV); textureSourceH = shadowMapBlurV; textureSourceV = shadowMapBlurH; } ShadowMapVsm = shadowMapBlurV; // Final texture for VSM is result of blur //MainTargetPlugin.Parameters.Set(ShadowMapKeys.Texture0, shadowMapBlurV); }
public override void Load() { base.Load(); RenderPass.AddPass(boundingBoxPass, heatShimmerPass, heatShimmerComposePass); // Use MinMax Plugin var bbRenderTargetPlugin = new RenderTargetsPlugin("BoundingBoxRenderTargetPlugin") { EnableSetTargets = true, EnableClearTarget = true, RenderTarget = null, RenderPass = boundingBoxPass, Services = Services }; bbRenderTargetPlugin.Apply(); Parameters.AddSources(ViewParameters); Parameters.SetDefault(RenderTargetKeys.DepthStencilSource); Parameters.SetDefault(TexturingKeys.Sampler); bbRenderTargetPlugin.Parameters.AddSources(Parameters); EffectOld minMaxEffect = this.EffectSystemOld.BuildEffect("MinMax") .Using(new MinMaxShaderPlugin("MinMaxShaderPlugin") { RenderPassPlugin = bbRenderTargetPlugin }) .Using(new BasicShaderPlugin("TransformationWVP") { RenderPassPlugin = bbRenderTargetPlugin }) .KeepAliveBy(ActiveObjects) .InstantiatePermutation() .KeepAliveBy(ActiveObjects); heatShimmerPass.Parameters = new ParameterCollection(); heatShimmerPass.Parameters.AddSources(Parameters); heatShimmerPass.Parameters.AddSources(NoisePlugin.Parameters); EffectOld heatShimmerEffect = this.EffectSystemOld.BuildEffect("HeatShimmer") .Using(new PostEffectSeparateShaderPlugin() { RenderPass = heatShimmerPass }) .Using( new BasicShaderPlugin( new ShaderMixinSource() { Mixins = new List <ShaderClassSource>() { // TODO add support for IsZReverse //new ShaderClassSource("PostEffectHeatShimmer", Debug ? 1 : 0, effectSystemOld.IsZReverse ? 1 : 0, 3), new ShaderClassSource("PostEffectHeatShimmer", Debug ? 1 : 0, false ? 1 : 0, 3) }, Compositions = new Dictionary <string, ShaderSource>() { { "NoiseSource", new ShaderClassSource("SimplexNoise") } }, } ) { RenderPass = heatShimmerPass }) .KeepAliveBy(ActiveObjects) .InstantiatePermutation() .KeepAliveBy(ActiveObjects); EffectOld heatShimmerDisplayEffect = this.EffectSystemOld.BuildEffect("HeatShimmer") .Using(new PostEffectSeparateShaderPlugin() { RenderPass = heatShimmerComposePass }) .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectHeatShimmerDisplay", Debug ? 1 : 0)) { RenderPass = heatShimmerComposePass }) .KeepAliveBy(ActiveObjects) .InstantiatePermutation() .KeepAliveBy(ActiveObjects); if (OfflineCompilation) { return; } Parameters.Set(RenderTargetKeys.DepthStencilSource, DepthStencil.Texture); Parameters.Set(TexturingKeys.Sampler, GraphicsDevice.SamplerStates.PointClamp); // ------------------------------------------ // BoundingBox prepass // ------------------------------------------ var renderTargetDesc = RenderSource.Description; var bbRenderTarget = Texture2D.New(GraphicsDevice, renderTargetDesc.Width, renderTargetDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects); bbRenderTargetPlugin.RenderTarget = bbRenderTarget.ToRenderTarget(); // Add meshes foreach (var bbMeshData in BoundingBoxes) { // Mesh for MinPass var bbMesh = new EffectMesh(minMaxEffect, bbMeshData).KeepAliveBy(ActiveObjects); // Add mesh // boundingBoxPass.AddPass(bbMesh.EffectMeshPasses[0].EffectPass); effectMeshes.Add(bbMesh); RenderSystem.GlobalMeshes.AddMesh(bbMesh); } // ------------------------------------------ // Heat Compute // ------------------------------------------ var shimmerTexture = Texture2D.New(GraphicsDevice, renderTargetDesc.Width, renderTargetDesc.Height, PixelFormat.R8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget); var shimmerRenderTarget = shimmerTexture.ToRenderTarget(); heatShimmerPass.StartPass += context => context.GraphicsDevice.Clear(shimmerRenderTarget, Color.Black); var quadMesh = new EffectMesh(heatShimmerEffect).KeepAliveBy(ActiveObjects); quadMesh.Parameters.Set(TexturingKeys.Texture1, bbRenderTarget); quadMesh.Parameters.Set(RenderTargetKeys.RenderTarget, shimmerRenderTarget); effectMeshes.Add(quadMesh); RenderSystem.GlobalMeshes.AddMesh(quadMesh); // ------------------------------------------ // Heat display // ------------------------------------------ quadMesh = new EffectMesh(heatShimmerDisplayEffect).KeepAliveBy(ActiveObjects); quadMesh.Parameters.Set(TexturingKeys.Texture0, RenderSource); quadMesh.Parameters.Set(TexturingKeys.Texture1, shimmerTexture); quadMesh.Parameters.Set(RenderTargetKeys.RenderTarget, RenderTarget); effectMeshes.Add(quadMesh); RenderSystem.GlobalMeshes.AddMesh(quadMesh); }
public override void Load() { base.Load(); if (OfflineCompilation) { return; } var renderTargets = new RenderTarget[2]; DepthStencilBuffer depthStencilBuffer = null; Texture2D depthStencilTexture = null; Parameters.AddSources(MainPlugin.ViewParameters); Parameters.RegisterParameter(EffectPlugin.BlendStateKey); var filteredPasses = new FastList <RenderPass>(); RenderPass.UpdatePasses += updatePassesAction = (RenderPass currentRenderPass, ref FastList <RenderPass> currentPasses) => { var originalPasses = currentPasses; filteredPasses.Clear(); currentPasses = filteredPasses; Parameters.Set(PickingFrameIndex, ++currentPickingFrameIndex); Request[] requests; lock (pendingRequests) { // No picking request or no mesh to pick? if (pendingRequests.Count == 0) { return; } requests = pendingRequests.ToArray(); pendingRequests.Clear(); } foreach (var request in requests) { requestResults.Add(request); } if (originalPasses == null) { return; } // Count mesh passes int meshIndex = 0; foreach (var pass in originalPasses) { meshIndex += pass.Passes.Count; } // No mesh to pick? if (meshIndex == 0) { return; } // Copy mesh passes and assign indices var meshPasses = new EffectMesh[meshIndex]; meshIndex = 0; foreach (var pass in RenderPass.Passes) { throw new NotImplementedException(); //foreach (var effectMeshPass in pass.Meshes) //{ // meshPasses[meshIndex] = (EffectMesh)effectMeshPass; // // Prefix increment so that 0 means no rendering. // effectMeshPass.Parameters.Set(PickingMeshIndex, ++meshIndex); //} } // For now, it generates one rendering per picking. // It would be quite easy to optimize it by make Picking shader works on multiple picking points at a time. foreach (var request in requests) { var pickingRenderPass = new RenderPass("Picking"); pickingRenderPass.StartPass.AddFirst = (threadContext) => { threadContext.GraphicsDevice.Clear(renderTargets[0], Color.Black); threadContext.GraphicsDevice.Clear(renderTargets[1], Color.Black); threadContext.Parameters.Set(PickingScreenPosition, request.Location); threadContext.GraphicsDevice.SetViewport(new Viewport(0, 0, renderTargets[0].Description.Width, renderTargets[0].Description.Height)); threadContext.GraphicsDevice.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer); threadContext.GraphicsDevice.SetRenderTargets(depthStencilBuffer, renderTargets); }; pickingRenderPass.EndPass.AddLast = (threadContext) => { threadContext.Parameters.Reset(PickingScreenPosition); threadContext.GraphicsDevice.Copy(renderTargets[0].Texture, request.ResultTextures[0]); threadContext.GraphicsDevice.Copy(renderTargets[1].Texture, request.ResultTextures[1]); }; //pickingRenderPass.PassesInternal = originalPasses; throw new NotImplementedException(); request.MeshPasses = meshPasses; currentPasses.Add(pickingRenderPass); request.HasResults = true; // Wait 2 frames before pulling the results. request.FrameCounter = 2; } }; RenderSystem.GlobalPass.EndPass.AddLast = CheckPickingResults; var backBuffer = GraphicsDevice.BackBuffer; int pickingArea = 1 + PickingDistance * 2; renderTargets[0] = Texture2D.New(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32_UInt, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects); renderTargets[1] = Texture2D.New(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32G32B32A32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects); depthStencilTexture = Texture2D.New(GraphicsDevice, pickingArea, pickingArea, PixelFormat.D32_Float, TextureFlags.ShaderResource | TextureFlags.DepthStencil).KeepAliveBy(ActiveObjects); depthStencilBuffer = depthStencilTexture.ToDepthStencilBuffer(false); Parameters.AddDynamic(PickingMatrix, ParameterDynamicValue.New(PickingScreenPosition, (ref Vector2 pickingPosition, ref Matrix picking) => { // Move center to picked position, and zoom (it is supposed to stay per-pixel according to render target size) picking = Matrix.Translation(1.0f - (pickingPosition.X) / backBuffer.Width * 2.0f, -1.0f + (pickingPosition.Y) / backBuffer.Height * 2.0f, 0.0f) * Matrix.Scaling((float)backBuffer.Width / (float)pickingArea, (float)backBuffer.Height / (float)pickingArea, 1.0f); })); }
public override void Load() { base.Load(); if (string.IsNullOrEmpty(StructureName) || StructureSize == 0) { throw new InvalidOperationException("StructureName and StructureSize must be setup on ParticlePlugin"); } // Add passes to the render pass RenderPass.AddPass(updatePasses, copyPass, sortPass, renderPass); // Create effect to copy from particle buffer to sort buffer effectCopyToSortBuffer = this.EffectSystemOld.BuildEffect("CopyToSortBuffer").Using( new ComputeShaderPlugin(new ShaderClassSource("ParticleSortInitializer"), MaximumThreadPerGroup, 1, 1) { RenderPass = copyPass, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName) } }); effectCopyToSortBuffer.KeepAliveBy(ActiveObjects); effectCopyToSortBuffer.Parameters.AddSources(MainPlugin.ViewParameters); effectMeshCopyToSortBuffer = new EffectMesh(effectCopyToSortBuffer); // Clear the sort buffer copyPass.StartPass.AddFirst = (context) => { if (CapacityCount > 0) { // TODO handle progressive sorting context.GraphicsDevice.ClearReadWrite(sortBuffer, new UInt4(0xFF7FFFFF)); // 0xFF7FFFFF = - float.MaxValue } }; // Create effect for bitonic sort 1 - pass 1 effectBitonicSort1Pass1 = this.EffectSystemOld.BuildEffect("ParticleBitonicSort1-Pass1").Using( new ComputeShaderPlugin(new ShaderClassSource("ParticleBitonicSort1"), MaximumThreadPerGroup, 1, 1) { RenderPass = bitonicSort1Pass1, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName), new ShaderMacro("PARTICLE_SORT_PASS", 0) } }); effectBitonicSort1Pass1.KeepAliveBy(this); effectMeshSort1Pass1 = new EffectMesh(effectBitonicSort1Pass1); // Create effect for bitonic sort 1 - pass 2 effectBitonicSort1Pass2 = this.EffectSystemOld.BuildEffect("ParticleBitonicSort1-Pass2").Using( new ComputeShaderPlugin(new ShaderClassSource("ParticleBitonicSort1"), MaximumThreadPerGroup, 1, 1) { RenderPass = bitonicSort1Pass2, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName), new ShaderMacro("PARTICLE_SORT_PASS", 1) } }); effectBitonicSort1Pass2.KeepAliveBy(this); effectMeshSort1Pass2 = new EffectMesh(effectBitonicSort1Pass2); // Creates Effect for bitonic sort 2 var currentDepth = MaximumDepthLevel; for (int i = 0; i < bitonicSort2Passes.Length; i++) { var bitonicShader = new RenderPass(string.Format("Bitonic-{0}", currentDepth)); bitonicSort2Passes[i] = bitonicShader; // Compile the new shader for this count effectBitonicSort2[i] = this.EffectSystemOld.BuildEffect("ParticleBitonicSort2-" + currentDepth).Using( new ComputeShaderPlugin(new ShaderClassSource("ParticleBitonicSort2", currentDepth), MaximumThreadPerGroup, 1, 1) { RenderPass = bitonicShader, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName) } }); effectBitonicSort2[i].KeepAliveBy(this); currentDepth /= 2; } effectMeshBitonicSort2 = new EffectMesh[bitonicSort2Passes.Length]; for (int i = 0; i < effectMeshBitonicSort2.Length; i++) { effectMeshBitonicSort2[i] = new EffectMesh(effectBitonicSort2[i]); } // Creates Effect for rendering EffectOld particleRenderEffect = this.EffectSystemOld.BuildEffect("ParticleRender") .Using(new StateShaderPlugin() { UseBlendState = true, UseDepthStencilState = true, RenderPass = renderPass }) .Using(new BasicShaderPlugin(RenderShader) { RenderPass = renderPass, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName) } }); particleRenderEffect.KeepAliveBy(this); particleRenderEffect.Parameters.AddSources(this.Parameters); particleRenderEffect.Parameters.AddSources(MainPlugin.ViewParameters); particleRenderEffect.Parameters.Set(EffectPlugin.BlendStateKey, graphicsDeviceService.GraphicsDevice.BlendStates.AlphaBlend); particleRenderEffect.Parameters.Set(EffectPlugin.DepthStencilStateKey, MainTargetPlugin.DepthStencilState); particleRenderEffect.Parameters.Set(RenderTargetKeys.DepthStencilSource, MainTargetPlugin.DepthStencil.Texture); effectMeshRender = new EffectMesh(particleRenderEffect); effectMeshRender.Render += (context) => { if (currentParticleCount > 0) { context.GraphicsDevice.SetVertexArrayObject(null); context.GraphicsDevice.SetViewport(MainTargetPlugin.Viewport); //context.GraphicsDevice.SetRenderTargets(MainTargetPlugin.DepthStencil, 0, MainTargetPlugin.RenderTarget); context.GraphicsDevice.SetRenderTargets((MainTargetPlugin.DepthStencilReadOnly != null) ? MainTargetPlugin.DepthStencilReadOnly : MainTargetPlugin.DepthStencil, RenderTarget); // TODO HANDLE dynamic count //context.GraphicsDevice.Draw(PrimitiveType.PointList, CapacityCount); context.GraphicsDevice.Draw(PrimitiveType.PointList, currentParticleCount); } //context.GraphicsDevice.SetRenderTargets(null, 0, new ITexture2D[] { null } ); }; if (OfflineCompilation) { return; } // Allocate global buffers at register time // Buffers can also be reallocated at runtime OnCapacityCountChange(); // Add our local meshes to render RenderContext.RenderPassEnumerators RenderSystem.RenderPassEnumerators.Add(meshesToRender); // Register update per frame RenderSystem.GlobalPass.StartPass += OnFrameUpdate; // Register sort pass sortPass.EndPass.Set = ComputeBitonicSort; }
public SlotKey(RenderPass pass, string effectName) { Pass = pass; EffectName = effectName; }