/// <returns> /// x = Near; y = 1/(Far-Near) /// </returns> private static Vector2 GetShadowMapDepthParameters(LightShadowMapTexture shadowMapTexture) { var lightPoint = shadowMapTexture.Light as LightPoint; Vector2 clippingPlanes = GetLightClippingPlanes(lightPoint); return(CameraKeys.ZProjectionACalculate(clippingPlanes.X, clippingPlanes.Y)); }
public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex) { // First do everything that doesn't change per individual render object var graphicsDevice = context.GraphicsDevice; var graphicsContext = context.GraphicsContext; var commandList = context.GraphicsContext.CommandList; // Refresh shader, might have changed during runtime _decalShader.UpdateEffect(graphicsDevice); // Set common shader parameters if needed _decalShader.Parameters.Set(TransformationKeys.ViewProjection, renderView.ViewProjection); _decalShader.Parameters.Set(TransformationKeys.ViewInverse, Matrix.Invert(renderView.View)); // Important to release it at the end of the draw, otherwise you'll run out of memory! //var depthStencil = context.Resolver.ResolveDepthStencil(commandList.DepthStencilBuffer); var depthStencil = context.Resolver.ResolveDepthStencil(graphicsDevice.Presenter.DepthStencilBuffer); // Must use the Presenter's depth buffer, otherwise it won't appear in the Game Studio _decalShader.Parameters.Set(DepthBaseKeys.DepthStencil, depthStencil); _decalShader.Parameters.Set(CameraKeys.ViewSize, renderView.ViewSize); _decalShader.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); _decalShader.Parameters.Set(CameraKeys.NearClipPlane, renderView.NearClipPlane); _decalShader.Parameters.Set(CameraKeys.FarClipPlane, renderView.FarClipPlane); for (int index = startIndex; index < endIndex; index++) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); var decalRendObj = (DecalRenderObject)renderNode.RenderObject; if (decalRendObj.RenderCube == null) { continue; // Next render object } // Assign shader parameters _decalShader.Parameters.Set(TransformationKeys.WorldInverse, Matrix.Invert(decalRendObj.WorldMatrix)); _decalShader.Parameters.Set(TransformationKeys.WorldViewProjection, decalRendObj.WorldMatrix * renderView.ViewProjection); _decalShader.Parameters.Set(TransformationKeys.WorldView, decalRendObj.WorldMatrix * renderView.View); _decalShader.Parameters.Set(DecalShaderKeys.DecalTexture, decalRendObj.Texture); _decalShader.Parameters.Set(DecalShaderKeys.TextureScale, decalRendObj.TextureScale); _decalShader.Parameters.Set(DecalShaderKeys.DecalColor, decalRendObj.Color); decalRendObj.RenderCube.Draw(graphicsContext, _decalShader); } context.Resolver.ReleaseDepthStenctilAsShaderResource(depthStencil); }
private void UpdateParameters(RenderDrawContext context, RenderView renderView) { // Compute the camera/view parameters: Vector2 viewSpaceDepthReconstructionParameters = CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane); SetValueParameterForBothShaders(CameraKeys.ZProjection, viewSpaceDepthReconstructionParameters); SetValueParameterForBothShaders(CameraKeys.NearClipPlane, renderView.NearClipPlane); SetValueParameterForBothShaders(CameraKeys.FarClipPlane, renderView.FarClipPlane); // Set the values required for the projected sampling radius calculation: Vector2 projectionSizeOnUnitPlaneInClipSpace = CalculateProjectionSizeOnPlane(renderView, 1.0f); SetValueParameterForBothShaders(SubsurfaceScatteringBlurShaderKeys.ProjectionSizeOnUnitPlaneInClipSpace, projectionSizeOnUnitPlaneInClipSpace); // Other parameters: SetValueParameterForBothShaders(SubsurfaceScatteringBlurShaderKeys.ViewProjectionMatrix, ref renderView.ViewProjection); // This is used for debugging only. // Supply the material arrays of this frame to the shaders: SetValueParameterForBothShaders(SubsurfaceScatteringBlurShaderKeys.ScatteringWidths, materialScatteringWidths); // TODO: PERFORMANCE: Only upload the actual number of elements used? UpdateKernelBuffer(context); }
public void HandleMessages(IntPtr hWnd, NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam) { switch (msg) { // Handle the keyboard case NativeMethods.WindowMessage.KeyDown: CameraKeys mappedKeyDown = MapKey(wParam); if (mappedKeyDown != (CameraKeys)byte.MaxValue) { // Valid key was pressed, mark it as 'down' keys[(int)mappedKeyDown] = true; } break; case NativeMethods.WindowMessage.KeyUp: CameraKeys mappedKeyUp = MapKey(wParam); if (mappedKeyUp != (CameraKeys)byte.MaxValue) { // Valid key was let go, mark it as 'up' keys[(int)mappedKeyUp] = false; } break; case NativeMethods.WindowMessage.RightButtonDown: if (!rightMouseDown) { lastMousePosition = System.Windows.Forms.Cursor.Position; } rightMouseDown = true; break; case NativeMethods.WindowMessage.RightButtonUp: rightMouseDown = false; break; } }
protected override void DrawCore(RenderDrawContext context) { var originalColorBuffer = GetSafeInput(0); var originalDepthBuffer = GetSafeInput(1); var outputTexture = GetSafeOutput(0); if (configurationDirty) { SetupTechnique(); } // Preparation phase: create different downscaled versions of the original image, later needed by the bokeh blur shaders. // TODO use ImageMultiScaler instead? downscaledSources.Clear(); // First we linearize the depth and compute the CoC map based on the user lens configuration. // Render target will contain "CoC"(16 bits) "Linear depth"(16bits). var cocLinearDepthTexture = GetScopedRenderTarget(originalColorBuffer.Description, 1f, PixelFormat.R16G16_Float); var renderView = context.RenderContext.RenderView; var farPlane = renderView.FarClipPlane; var depthAreas = DOFAreas; if (AutoFocus) { // TODO replace this by physical camera parameters (aperture, focus distance...) var diffToTarget = (autoFocusDistanceTarget - autoFocusDistanceCurrent); var maxAmplitude = farPlane * 0.2f; diffToTarget = MathUtil.Clamp(diffToTarget, -maxAmplitude, maxAmplitude); autoFocusDistanceCurrent = autoFocusDistanceCurrent + 0.1f * diffToTarget; if (autoFocusDistanceCurrent < renderView.NearClipPlane * 2.0f) { autoFocusDistanceCurrent = renderView.NearClipPlane * 2.0f; } depthAreas = new Vector4(renderView.NearClipPlane, autoFocusDistanceCurrent, autoFocusDistanceCurrent, autoFocusDistanceCurrent + farPlane * 0.5f); } coclinearDepthMapEffect.SetInput(0, originalDepthBuffer); coclinearDepthMapEffect.SetOutput(cocLinearDepthTexture); coclinearDepthMapEffect.Parameters.Set(CircleOfConfusionKeys.depthAreas, ref depthAreas); coclinearDepthMapEffect.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); coclinearDepthMapEffect.Draw(context, "CoC_LinearDepth"); if (AutoFocus) { // Reads the center depth of the previous frame and use it as a new target // TODO single pixel is really small, average some disk area instead? pointDepthShader.Parameters.Set(PointDepthKeys.Coordinate, new Vector2(0.5f, 0.5f)); pointDepthShader.SetInput(cocLinearDepthTexture); pointDepthShader.SetOutput(depthCenter1x1); pointDepthShader.Draw(context, "Center Depth"); depthReadBack.SetInput(depthCenter1x1); depthReadBack.Draw(context, "Center_Depth_Readback"); var centerDepth = depthReadBack.Result[0]; autoFocusDistanceTarget = centerDepth; } // Find the smallest downscale we should go down to. var maxDownscale = 0; foreach (var cocLevel in cocLevels) { if (cocLevel.DownscaleFactor > maxDownscale) { maxDownscale = cocLevel.DownscaleFactor; } } // Create a series of downscale, with anti-bleeding treatment for (int i = 0; i <= maxDownscale; i++) { var downSizedTexture = originalColorBuffer; if (i > 0) { downSizedTexture = GetScopedRenderTarget(originalColorBuffer.Description, 1f / (float)Math.Pow(2f, i), originalColorBuffer.Description.Format); textureScaler.SetInput(0, downscaledSources[i - 1]); textureScaler.SetOutput(downSizedTexture); textureScaler.Draw(context, "DownScale_Factor{0}", i); } downscaledSources[i] = downSizedTexture; } // We create a blurred version of the CoC map. // This is useful to avoid silhouettes appearing when the CoC changes abruptly. var blurredCoCTexture = NewScopedRenderTarget2D(cocLinearDepthTexture.Description); cocMapBlur.Radius = 6f / 720f * cocLinearDepthTexture.Description.Height; // 6 pixels at 720p cocMapBlur.SetInput(0, cocLinearDepthTexture); cocMapBlur.SetOutput(blurredCoCTexture); cocMapBlur.Draw(context, "CoC_BlurredMap"); // Creates all the levels with different CoC strengths. // (Skips level with CoC 0 which is always the original buffer.) combineLevelsEffect.Parameters.Set(CombineLevelsFromCoCKeys.LevelCount, cocLevels.Count); combineLevelsEffect.SetInput(0, cocLinearDepthTexture); combineLevelsEffect.SetInput(1, blurredCoCTexture); combineLevelsEffect.SetInput(2, originalColorBuffer); combineLevelsFrontEffect.Parameters.Set(CombineLevelsFromCoCKeys.LevelCount, cocLevels.Count); combineLevelsFrontEffect.SetInput(0, cocLinearDepthTexture); combineLevelsFrontEffect.SetInput(1, blurredCoCTexture); combineLevelsFrontEffect.SetInput(2, originalColorBuffer); float previousCoC = 0f; for (int i = 1; i < cocLevels.Count; i++) { // We render a blurred version of the original scene into a downscaled render target. // Blur strength depends on the current level CoC value. var levelConfig = cocLevels[i]; var textureToBlur = downscaledSources[levelConfig.DownscaleFactor]; float downscaleFactor = 1f / (float)(Math.Pow(2f, levelConfig.DownscaleFactor)); var blurOutput = GetScopedRenderTarget(originalColorBuffer.Description, downscaleFactor, originalColorBuffer.Description.Format); var blurOutputFront = NewScopedRenderTarget2D(blurOutput.Description); float blurRadius = (MaxBokehSize * BokehSizeFactor) * levelConfig.CoCValue * downscaleFactor * originalColorBuffer.Width; if (blurRadius < 1f) { blurRadius = 1f; } //--------------------------------- // Far out-of-focus //--------------------------------- // Pre-process the layer for the current CoC // This removes areas which might wrongly bleed into our image when blurring. var alphaTextureToBlur = NewScopedRenderTarget2D(textureToBlur.Description); thresholdAlphaCoC.Parameters.Set(ThresholdAlphaCoCKeys.CoCReference, previousCoC); thresholdAlphaCoC.Parameters.Set(ThresholdAlphaCoCKeys.CoCCurrent, levelConfig.CoCValue); thresholdAlphaCoC.SetInput(0, textureToBlur); thresholdAlphaCoC.SetInput(1, cocLinearDepthTexture); thresholdAlphaCoC.SetOutput(alphaTextureToBlur); thresholdAlphaCoC.Draw(context, "Alphaize_Far_{0}", i); textureToBlur = alphaTextureToBlur; // TODO Quality up: make the opaque areas "bleed" into the areas we just made transparent // Apply the bokeh blur effect BokehBlur levelBlur = levelConfig.BlurEffect; levelBlur.CoCStrength = levelConfig.CoCValue; levelBlur.Radius = blurRadius; // This doesn't generate garbage if the radius value doesn't change. levelBlur.SetInput(0, textureToBlur); levelBlur.SetOutput(blurOutput); levelBlur.Draw(context, "CoC_LoD_Layer_Far_{0}", i); combineLevelsEffect.SetInput(i + 2, blurOutput); //--------------------------------- // Near out-of-focus //--------------------------------- // Negates CoC values and makes background objects transparent thresholdAlphaCoCFront.Parameters.Set(ThresholdAlphaCoCFrontKeys.CoCReference, previousCoC); thresholdAlphaCoCFront.Parameters.Set(ThresholdAlphaCoCFrontKeys.CoCCurrent, levelConfig.CoCValue); thresholdAlphaCoCFront.SetInput(0, downscaledSources[levelConfig.DownscaleFactor]); thresholdAlphaCoCFront.SetInput(1, cocLinearDepthTexture); thresholdAlphaCoCFront.SetOutput(alphaTextureToBlur); thresholdAlphaCoCFront.Draw(context, "Alphaize_Near_{0}", i); textureToBlur = alphaTextureToBlur; // Apply the bokeh blur effect levelBlur.SetInput(0, textureToBlur); levelBlur.SetOutput(blurOutputFront); levelBlur.Draw(context, "CoC_LoD_Layer_Near_{0}", i); combineLevelsFrontEffect.SetInput(i + 2, blurOutputFront); previousCoC = levelConfig.CoCValue; } // Far out-of-focus: each pixel, depending on its CoC, interpolates its color from // the original color buffer and blurred buffer(s). combineLevelsEffect.Parameters.Set(CombineLevelsFromCoCShaderKeys.CoCLevelValues, combineShaderCocLevelValues); combineLevelsEffect.SetOutput(outputTexture); combineLevelsEffect.Draw(context, "CoCLevelCombineInterpolation"); // Finally add front out-of-focus objects on the top of the scene // TODO Quality up: instead of merging all the layers for each pixel, merge only // the relevant layer(s) closest to the pixel CoC. combineLevelsFrontEffect.SetOutput(outputTexture); combineLevelsFrontEffect.Draw(context, "CoCLevelCombineInterpolationFront"); // Release any reference downscaledSources.Clear(); }
protected override void DrawCore(RenderDrawContext context) { var originalColorBuffer = GetSafeInput(0); var originalDepthBuffer = GetSafeInput(1); var outputTexture = GetSafeOutput(0); var renderView = context.RenderContext.RenderView; //--------------------------------- // Ambient Occlusion //--------------------------------- var tempWidth = (originalColorBuffer.Width * (int)TempSize) / (int)TemporaryBufferSize.SizeFull; var tempHeight = (originalColorBuffer.Height * (int)TempSize) / (int)TemporaryBufferSize.SizeFull; var aoTexture1 = NewScopedRenderTarget2D(tempWidth, tempHeight, PixelFormat.R8_UNorm, 1); var aoTexture2 = NewScopedRenderTarget2D(tempWidth, tempHeight, PixelFormat.R8_UNorm, 1); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOKeys.Count, NumberOfSamples > 0 ? NumberOfSamples : 9); // Set Near/Far pre-calculated factors to speed up the linear depth reconstruction aoRawImageEffect.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); Vector4 screenSize = new Vector4(originalColorBuffer.Width, originalColorBuffer.Height, 0, 0); screenSize.Z = screenSize.X / screenSize.Y; aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ScreenInfo, screenSize); // Projection infor used to reconstruct the View space position from linear depth var p00 = renderView.Projection.M11; var p11 = renderView.Projection.M22; var p02 = renderView.Projection.M13; var p12 = renderView.Projection.M23; Vector4 projInfo = new Vector4(-2.0f / (screenSize.X * p00), -2.0f / (screenSize.Y * p11), (1.0f - p02) / p00, (1.0f + p12) / p11); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ProjInfo, projInfo); //********************************** // User parameters aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ParamProjScale, ParamProjScale); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ParamIntensity, ParamIntensity); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ParamBias, ParamBias); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ParamRadius, ParamRadius); aoRawImageEffect.Parameters.Set(AmbientOcclusionRawAOShaderKeys.ParamRadiusSquared, ParamRadius * ParamRadius); aoRawImageEffect.SetInput(0, originalDepthBuffer); aoRawImageEffect.SetOutput(aoTexture1); aoRawImageEffect.Draw(context, "AmbientOcclusionRawAO"); for (int bounces = 0; bounces < NumberOfBounces; bounces++) { if (offsetsWeights == null) { offsetsWeights = new[] { // 0.356642f, 0.239400f, 0.072410f, 0.009869f, // 0.398943f, 0.241971f, 0.053991f, 0.004432f, 0.000134f, // stddev = 1.0 0.153170f, 0.144893f, 0.122649f, 0.092902f, 0.062970f, // stddev = 2.0 // 0.111220f, 0.107798f, 0.098151f, 0.083953f, 0.067458f, 0.050920f, 0.036108f, // stddev = 3.0 }; nameGaussianBlurH = string.Format("AmbientOcclusionBlurH{0}x{0}", offsetsWeights.Length); nameGaussianBlurV = string.Format("AmbientOcclusionBlurV{0}x{0}", offsetsWeights.Length); } // Set Near/Far pre-calculated factors to speed up the linear depth reconstruction blurH.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); blurV.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); // Update permutation parameters blurH.Parameters.Set(AmbientOcclusionBlurKeys.Count, offsetsWeights.Length); blurH.Parameters.Set(AmbientOcclusionBlurKeys.BlurScale, BlurScale); blurH.Parameters.Set(AmbientOcclusionBlurKeys.EdgeSharpness, EdgeSharpness); blurH.EffectInstance.UpdateEffect(context.GraphicsDevice); blurV.Parameters.Set(AmbientOcclusionBlurKeys.Count, offsetsWeights.Length); blurV.Parameters.Set(AmbientOcclusionBlurKeys.BlurScale, BlurScale); blurV.Parameters.Set(AmbientOcclusionBlurKeys.EdgeSharpness, EdgeSharpness); blurV.EffectInstance.UpdateEffect(context.GraphicsDevice); // Update parameters blurH.Parameters.Set(AmbientOcclusionBlurShaderKeys.Weights, offsetsWeights); blurV.Parameters.Set(AmbientOcclusionBlurShaderKeys.Weights, offsetsWeights); // Horizontal pass blurH.SetInput(0, aoTexture1); blurH.SetInput(1, originalDepthBuffer); blurH.SetOutput(aoTexture2); blurH.Draw(context, nameGaussianBlurH); // Vertical pass blurV.SetInput(0, aoTexture2); blurV.SetInput(1, originalDepthBuffer); blurV.SetOutput(aoTexture1); blurV.Draw(context, nameGaussianBlurV); } aoApplyImageEffect.SetInput(0, originalColorBuffer); aoApplyImageEffect.SetInput(1, aoTexture1); aoApplyImageEffect.SetOutput(outputTexture); aoApplyImageEffect.Draw(context, "AmbientOcclusionApply"); }
protected override void DrawCore(RenderDrawContext context) { if (lightShafts == null) { return; // Not collected } if (LightBufferDownsampleLevel < 1) { throw new ArgumentOutOfRangeException(nameof(LightBufferDownsampleLevel)); } if (BoundingVolumeBufferDownsampleLevel < 1) { throw new ArgumentOutOfRangeException(nameof(BoundingVolumeBufferDownsampleLevel)); } var depthInput = GetSafeInput(0); // Create a min/max buffer generated from scene bounding volumes var targetBoundingBoxBufferSize = new Size2(Math.Max(1, depthInput.Width / BoundingVolumeBufferDownsampleLevel), Math.Max(1, depthInput.Height / BoundingVolumeBufferDownsampleLevel)); var boundingBoxBuffer = NewScopedRenderTarget2D(targetBoundingBoxBufferSize.Width, targetBoundingBoxBufferSize.Height, PixelFormat.R32G32_Float); // Buffer that holds the minimum distance in case of being inside the bounding box var backSideRaycastBuffer = NewScopedRenderTarget2D(1, 1, PixelFormat.R32G32_Float); // Create a single channel light buffer PixelFormat lightBufferPixelFormat = needsColorLightBuffer ? PixelFormat.R16G16B16A16_Float : PixelFormat.R16_Float; var targetLightBufferSize = new Size2(Math.Max(1, depthInput.Width / LightBufferDownsampleLevel), Math.Max(1, depthInput.Height / LightBufferDownsampleLevel)); var lightBuffer = NewScopedRenderTarget2D(targetLightBufferSize.Width, targetLightBufferSize.Height, lightBufferPixelFormat); lightShaftsEffectShader.SetOutput(lightBuffer); var lightShaftsParameters = lightShaftsEffectShader.Parameters; lightShaftsParameters.Set(DepthBaseKeys.DepthStencil, depthInput); // Bind scene depth if (!Initialized) { Initialize(context.RenderContext); } var renderView = context.RenderContext.RenderView; var viewInverse = Matrix.Invert(renderView.View); lightShaftsParameters.Set(TransformationKeys.ViewInverse, viewInverse); lightShaftsParameters.Set(TransformationKeys.Eye, new Vector4(viewInverse.TranslationVector, 1)); // Setup parameters for Z reconstruction lightShaftsParameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane)); Matrix projectionInverse; Matrix.Invert(ref renderView.Projection, out projectionInverse); lightShaftsParameters.Set(TransformationKeys.ProjectionInverse, projectionInverse); applyLightEffectShader.SetOutput(GetSafeOutput(0)); foreach (var lightShaft in lightShafts) { if (lightShaft.Light == null) { continue; // Skip entities without a light component } // Set sample count for this light lightShaftsParameters.Set(LightShaftsEffectKeys.SampleCount, lightShaft.SampleCount); // Setup the shader group used for sampling shadows var shadowMapTexture = shadowMapRenderer.FindShadowMap(renderView.LightingView ?? renderView, lightShaft.Light); SetupLight(context, lightShaft, shadowMapTexture, lightShaftsParameters); // Check if we can pack bounding volumes together or need to draw them one by one var boundingVolumeLoop = lightShaft.SeparateBoundingVolumes ? lightShaft.BoundingVolumes.Count : 1; var lightBufferUsed = false; for (int i = 0; i < boundingVolumeLoop; ++i) { // Generate list of bounding volume (either all or one by one depending on SeparateBoundingVolumes) var currentBoundingVolumes = (lightShaft.SeparateBoundingVolumes) ? singleBoundingVolume : lightShaft.BoundingVolumes; if (lightShaft.SeparateBoundingVolumes) { singleBoundingVolume[0] = lightShaft.BoundingVolumes[i]; } using (context.PushRenderTargetsAndRestore()) { // Clear bounding box buffer context.CommandList.Clear(boundingBoxBuffer, new Color4(1.0f, 0.0f, 0.0f, 0.0f)); context.CommandList.SetRenderTargetAndViewport(null, boundingBoxBuffer); // If nothing visible, skip second part if (!DrawBoundingVolumeMinMax(context, currentBoundingVolumes)) { continue; } context.CommandList.Clear(backSideRaycastBuffer, new Color4(1.0f, 0.0f, 0.0f, 0.0f)); context.CommandList.SetRenderTargetAndViewport(null, backSideRaycastBuffer); // If nothing visible, skip second part DrawBoundingVolumeBackside(context, currentBoundingVolumes); } if (!lightBufferUsed) { // First pass: replace (avoid a clear and blend state) lightShaftsEffectShader.BlendState = BlendStates.Opaque; lightBufferUsed = true; } else { // Then: add var desc = BlendStates.Additive; desc.RenderTarget0.ColorSourceBlend = Blend.One; // But without multiplying alpha lightShaftsEffectShader.BlendState = desc; } if (lightShaft.SampleCount < 1) { throw new ArgumentOutOfRangeException(nameof(lightShaft.SampleCount)); } // Set min/max input lightShaftsEffectShader.SetInput(0, boundingBoxBuffer); lightShaftsEffectShader.SetInput(1, backSideRaycastBuffer); // Light accumulation pass (on low resolution buffer) DrawLightShaft(context, lightShaft); } // Everything was outside, skip if (!lightBufferUsed) { continue; } if (LightBufferDownsampleLevel != 1) { // Blur the result blur.Radius = LightBufferDownsampleLevel; blur.SetInput(lightBuffer); blur.SetOutput(lightBuffer); blur.Draw(context); } // Additive blend pass Color3 lightColor = lightShaft.Light2.ComputeColor(context.GraphicsDevice.ColorSpace, lightShaft.Light.Intensity); applyLightEffectShader.Parameters.Set(AdditiveLightShaderKeys.LightColor, lightColor); applyLightEffectShader.Parameters.Set(AdditiveLightEffectKeys.Color, needsColorLightBuffer); applyLightEffectShader.SetInput(lightBuffer); applyLightEffectShader.Draw(context); } // Clean up unused render data unusedLights.Clear(); foreach (var data in renderData) { if (data.Value.UsageCounter != usageCounter) { unusedLights.Add(data.Key); } } foreach (var unusedLight in unusedLights) { renderData.Remove(unusedLight); } usageCounter++; }
public static void UnRegisterKeyDownEvent(CameraKeys k, OnKeyDownEvent e) { cameraEvents[k] -= e; }
public static void RegisterKeyDownEvent(CameraKeys k, OnKeyDownEvent e) { if (!cameraEvents.ContainsKey(k)) cameraEvents[k] = e; else cameraEvents[k] += e; }