public void DrawBasic(DeviceContext dc, EffectPass effectPass, Matrix viewProj) { var world = World; var wit = MathF.InverseTranspose(world); var wvp = world * viewProj; Effects.BasicFX.SetWorld(world); Effects.BasicFX.SetWorldInvTranspose(wit); Effects.BasicFX.SetWorldViewProj(wvp); Effects.BasicFX.SetWorldViewProjTex(wvp * ToTexSpace); Effects.BasicFX.SetTexTransform(TexTransform); Effects.BasicFX.SetShadowTransform(world*ShadowTransform); for (int i = 0; i < Model.SubsetCount; i++) { Effects.BasicFX.SetMaterial(Model.Materials[i]); Effects.BasicFX.SetDiffuseMap(Model.DiffuseMapSRV[i]); effectPass.Apply(dc); Model.ModelMesh.Draw(dc, i); } }
/// <summary> /// Main draw function /// </summary> /// <param name="inputTexture">the image from which we want to extract bright parts and blur these</param> /// <param name="width">width of our target. If different to the input.Texture width our final texture will be smaller/larger. /// For example we can use half resolution. Input: 1280px wide -> width = 640px /// The smaller this value the better performance and the worse our final image quality</param> /// <param name="height">see: width</param> /// <returns></returns> public Texture2D Draw(Texture2D inputTexture, int width, int height) { //Check if we are initialized if (_graphicsDevice == null) { throw new Exception("Module not yet Loaded / Initialized. Use Load() first"); } //Change renderTarget resolution if different from what we expected. If lower than the inputTexture we gain performance. if (width != _width || height != _height) { UpdateResolution(width, height); //Adjust the blur so it looks consistent across diferrent scalings _radiusMultiplier = (float)width / inputTexture.Width; //Update our variables with the multiplier SetBloomPreset(BloomPreset); } _graphicsDevice.RasterizerState = RasterizerState.CullNone; _graphicsDevice.BlendState = BlendState.Opaque; //EXTRACT //Note: Is setRenderTargets(binding better?) //We extract the bright values which are above the Threshold and save them to Mip0 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip0); BloomScreenTexture = inputTexture; BloomInverseResolution = new Vector2(1.0f / _width, 1.0f / _height); if (BloomUseLuminance) { _bloomPassExtractLuminance.Apply(); } else { _bloomPassExtract.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); //Now downsample to the next lower mip texture if (BloomDownsamplePasses > 0) { //DOWNSAMPLE TO MIP1 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip1); BloomScreenTexture = _bloomRenderTarget2DMip0; //Pass _bloomPassDownsample.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); if (BloomDownsamplePasses > 1) { //Our input resolution is halfed, so our inverse 1/res. must be doubled BloomInverseResolution *= 2; //DOWNSAMPLE TO MIP2 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip2); BloomScreenTexture = _bloomRenderTarget2DMip1; //Pass _bloomPassDownsample.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); if (BloomDownsamplePasses > 2) { BloomInverseResolution *= 2; //DOWNSAMPLE TO MIP3 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip3); BloomScreenTexture = _bloomRenderTarget2DMip2; //Pass _bloomPassDownsample.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); if (BloomDownsamplePasses > 3) { BloomInverseResolution *= 2; //DOWNSAMPLE TO MIP4 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip4); BloomScreenTexture = _bloomRenderTarget2DMip3; //Pass _bloomPassDownsample.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); if (BloomDownsamplePasses > 4) { BloomInverseResolution *= 2; //DOWNSAMPLE TO MIP5 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip5); BloomScreenTexture = _bloomRenderTarget2DMip4; //Pass _bloomPassDownsample.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); ChangeBlendState(); //UPSAMPLE TO MIP4 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip4); BloomScreenTexture = _bloomRenderTarget2DMip5; BloomStrength = _bloomStrength5; BloomRadius = _bloomRadius5; if (BloomUseLuminance) { _bloomPassUpsampleLuminance.Apply(); } else { _bloomPassUpsample.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); BloomInverseResolution /= 2; } ChangeBlendState(); //UPSAMPLE TO MIP3 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip3); BloomScreenTexture = _bloomRenderTarget2DMip4; BloomStrength = _bloomStrength4; BloomRadius = _bloomRadius4; if (BloomUseLuminance) { _bloomPassUpsampleLuminance.Apply(); } else { _bloomPassUpsample.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); BloomInverseResolution /= 2; } ChangeBlendState(); //UPSAMPLE TO MIP2 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip2); BloomScreenTexture = _bloomRenderTarget2DMip3; BloomStrength = _bloomStrength3; BloomRadius = _bloomRadius3; if (BloomUseLuminance) { _bloomPassUpsampleLuminance.Apply(); } else { _bloomPassUpsample.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); BloomInverseResolution /= 2; } ChangeBlendState(); //UPSAMPLE TO MIP1 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip1); BloomScreenTexture = _bloomRenderTarget2DMip2; BloomStrength = _bloomStrength2; BloomRadius = _bloomRadius2; if (BloomUseLuminance) { _bloomPassUpsampleLuminance.Apply(); } else { _bloomPassUpsample.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); BloomInverseResolution /= 2; } ChangeBlendState(); //UPSAMPLE TO MIP0 _graphicsDevice.SetRenderTarget(_bloomRenderTarget2DMip0); BloomScreenTexture = _bloomRenderTarget2DMip1; BloomStrength = _bloomStrength1; BloomRadius = _bloomRadius1; if (BloomUseLuminance) { _bloomPassUpsampleLuminance.Apply(); } else { _bloomPassUpsample.Apply(); } _quadRenderer.RenderQuad(_graphicsDevice, Vector2.One * -1, Vector2.One); } //Note the final step could be done as a blend to the final texture. return(_bloomRenderTarget2DMip0); }
/// <inheritdoc/> public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } if (order != RenderOrder.UserDefined) { throw new NotImplementedException("Render order must be 'UserDefined'."); } if (context.CameraNode == null) { throw new GraphicsException("Camera node needs to be set in render context."); } if (context.GBuffer0 == null) { throw new GraphicsException("GBuffer0 needs to be set in render context."); } int numberOfNodes = nodes.Count; if (numberOfNodes == 0) { return; } var graphicsService = context.GraphicsService; var graphicsDevice = graphicsService.GraphicsDevice; var viewport = context.Viewport; int width = viewport.Width; int height = viewport.Height; var renderTargetPool = graphicsService.RenderTargetPool; var cameraNode = context.CameraNode; var projection = cameraNode.Camera.Projection; Pose view = cameraNode.PoseWorld.Inverse; Pose cameraPose = cameraNode.PoseWorld; float near = projection.Near; float far = projection.Far; int frame = context.Frame; cameraNode.LastFrame = frame; // Save render state. var originalRasterizerState = graphicsDevice.RasterizerState; var originalDepthStencilState = graphicsDevice.DepthStencilState; var originalBlendState = graphicsDevice.BlendState; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; RenderTarget2D offscreenBuffer = null; Texture depthBufferHalf = null; if (!EnableOffscreenRendering || context.RenderTarget == null) { graphicsDevice.BlendState = BlendState.AlphaBlend; _parameterGBuffer0.SetValue(context.GBuffer0); } else { // Render at half resolution into off-screen buffer. width = Math.Max(1, width / 2); height = Math.Max(1, height / 2); graphicsDevice.BlendState = BlendStateOffscreen; offscreenBuffer = renderTargetPool.Obtain2D( new RenderTargetFormat(width, height, false, context.RenderTarget.Format, DepthFormat.None)); graphicsDevice.SetRenderTarget(offscreenBuffer); graphicsDevice.Clear(Color.Black); // Get half-res depth buffer. object obj; if (context.Data.TryGetValue(RenderContextKeys.DepthBufferHalf, out obj) && obj is Texture2D) { depthBufferHalf = (Texture2D)obj; _parameterGBuffer0.SetValue(depthBufferHalf); } else { string message = "Downsampled depth buffer is not set in render context. (The downsampled " + "depth buffer (half width and height) is required by the VolumetricLightRenderer " + "to use half-res off-screen rendering. It needs to be stored in " + "RenderContext.Data[RenderContextKeys.DepthBufferHalf].)"; throw new GraphicsException(message); } } // Set global effect parameters. _parameterViewportSize.SetValue(new Vector2(width, height)); var isHdrEnabled = context.RenderTarget != null && context.RenderTarget.Format == SurfaceFormat.HdrBlendable; for (int i = 0; i < numberOfNodes; i++) { var node = nodes[i] as VolumetricLightNode; if (node == null) { continue; } // VolumetricLightNode is visible in current frame. node.LastFrame = frame; // Effect parameters for volumetric light properties. _parameterColor.SetValue((Vector3)node.Color / node.NumberOfSamples); _parameterNumberOfSamples.SetValue(node.NumberOfSamples); _parameterLightTextureMipMap.SetValue((float)node.MipMapBias); // The volumetric light effect is created for the parent light node. var lightNode = node.Parent as LightNode; if (lightNode == null) { continue; } Pose lightPose = lightNode.PoseWorld; // Get start and end depth values of light AABB in view space. var lightAabbView = lightNode.Shape.GetAabb(lightNode.ScaleWorld, view * lightPose); var startZ = Math.Max(-lightAabbView.Maximum.Z, near) / far; var endZ = Math.Min(-lightAabbView.Minimum.Z / far, 1); _parameterDepthInterval.SetValue(new Vector2(startZ, endZ)); // Get a rectangle that covers the light in screen space. var rectangle = GraphicsHelper.GetScissorRectangle(cameraNode, new Viewport(0, 0, width, height), lightNode); var texCoordTopLeft = new Vector2F(rectangle.Left / (float)width, rectangle.Top / (float)height); var texCoordBottomRight = new Vector2F(rectangle.Right / (float)width, rectangle.Bottom / (float)height); GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, texCoordTopLeft, texCoordBottomRight, _frustumFarCorners); // Convert frustum far corners from view space to world space. for (int j = 0; j < _frustumFarCorners.Length; j++) { _frustumFarCorners[j] = (Vector3)cameraPose.ToWorldDirection((Vector3)_frustumFarCorners[j]); } _parameterFrustumCorners.SetValue(_frustumFarCorners); Vector2 randomSeed = AnimateNoise ? new Vector2((float)MathHelper.Frac(context.Time.TotalSeconds)) : new Vector2(0); _parameterRandomSeed.SetValue(randomSeed); // Set light parameters and apply effect pass. if (lightNode.Light is PointLight) { var light = (PointLight)lightNode.Light; float hdrScale = isHdrEnabled ? light.HdrScale : 1; _parameterLightDiffuse.SetValue((Vector3)light.Color * light.DiffuseIntensity * hdrScale); _parameterLightPosition.SetValue((Vector3)(lightPose.Position - cameraPose.Position)); _parameterLightRange.SetValue(light.Range); _parameterLightAttenuation.SetValue(light.Attenuation); bool hasTexture = (light.Texture != null); if (hasTexture) { _parameterLightTexture.SetValue(light.Texture); // Cube maps are left handed --> Sample with inverted z. (Otherwise, the // cube map and objects or texts in it are mirrored.) var mirrorZ = Matrix.CreateScale(1, 1, -1); _parameterLightTextureMatrix.SetValue((Matrix)(mirrorZ * lightPose.Inverse)); } if (hasTexture) { if (light.Texture.Format == SurfaceFormat.Alpha8) { _passPointLightTextureAlpha.Apply(); } else { _passPointLightTextureRgb.Apply(); } } else { _passPointLight.Apply(); } } else if (lightNode.Light is Spotlight) { var light = (Spotlight)lightNode.Light; float hdrScale = isHdrEnabled ? light.HdrScale : 1; _parameterLightDiffuse.SetValue((Vector3)light.Color * light.DiffuseIntensity * hdrScale); _parameterLightPosition.SetValue((Vector3)(lightPose.Position - cameraPose.Position)); _parameterLightRange.SetValue(light.Range); _parameterLightAttenuation.SetValue(light.Attenuation); _parameterLightDirection.SetValue((Vector3)lightPose.ToWorldDirection(Vector3.Forward)); _parameterLightAngles.SetValue(new Vector2(light.FalloffAngle, light.CutoffAngle)); bool hasTexture = (light.Texture != null); if (hasTexture) { _parameterLightTexture.SetValue(light.Texture); var proj = Matrix.CreatePerspectiveFieldOfView(light.CutoffAngle * 2, 1, 0.1f, 100); _parameterLightTextureMatrix.SetValue((Matrix)(GraphicsHelper.ProjectorBiasMatrix * proj * (lightPose.Inverse * new Pose(cameraPose.Position)))); } if (hasTexture) { if (light.Texture.Format == SurfaceFormat.Alpha8) { _passSpotlightTextureAlpha.Apply(); } else { _passSpotlightTextureRgb.Apply(); } } else { _passSpotlight.Apply(); } } else if (lightNode.Light is ProjectorLight) { var light = (ProjectorLight)lightNode.Light; float hdrScale = isHdrEnabled ? light.HdrScale : 1; _parameterLightDiffuse.SetValue((Vector3)light.Color * light.DiffuseIntensity * hdrScale); _parameterLightPosition.SetValue((Vector3)(lightPose.Position - cameraPose.Position)); _parameterLightRange.SetValue(light.Projection.Far); _parameterLightAttenuation.SetValue(light.Attenuation); _parameterLightTexture.SetValue(light.Texture); _parameterLightTextureMatrix.SetValue((Matrix)(GraphicsHelper.ProjectorBiasMatrix * light.Projection * (lightPose.Inverse * new Pose(cameraPose.Position)))); if (light.Texture.Format == SurfaceFormat.Alpha8) { _passProjectorLightTextureAlpha.Apply(); } else { _passProjectorLightTextureRgb.Apply(); } } else { continue; } // Draw a screen space quad covering the light. graphicsDevice.DrawQuad(rectangle); } _parameterGBuffer0.SetValue((Texture)null); _parameterLightTexture.SetValue((Texture)null); if (offscreenBuffer != null) { // ----- Combine off-screen buffer with scene. graphicsDevice.BlendState = BlendState.Opaque; // The previous scene render target is bound as texture. // --> Switch scene render targets! var sceneRenderTarget = context.RenderTarget; var renderTarget = renderTargetPool.Obtain2D(new RenderTargetFormat(sceneRenderTarget)); context.SourceTexture = offscreenBuffer; context.RenderTarget = renderTarget; // Use the UpsampleFilter, which supports "nearest-depth upsampling". // (Nearest-depth upsampling is an "edge-aware" method that tries to // maintain the original geometry and prevent blurred edges.) if (_upsampleFilter == null) { _upsampleFilter = new UpsampleFilter(graphicsService); _upsampleFilter.Mode = UpsamplingMode.NearestDepth; _upsampleFilter.RebuildZBuffer = true; } _upsampleFilter.DepthThreshold = DepthThreshold; context.SceneTexture = sceneRenderTarget; _upsampleFilter.Process(context); context.SceneTexture = null; context.SourceTexture = null; renderTargetPool.Recycle(offscreenBuffer); renderTargetPool.Recycle(sceneRenderTarget); } // Restore render states. graphicsDevice.RasterizerState = originalRasterizerState; graphicsDevice.DepthStencilState = originalDepthStencilState; graphicsDevice.BlendState = originalBlendState; }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (nodes.Count == 0) { return; } context.Validate(_effect); var originalRenderTarget = context.RenderTarget; var originalViewport = context.Viewport; var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; int frame = context.Frame; float deltaTime = (float)context.DeltaTime.TotalSeconds; for (int nodeIndex = 0; nodeIndex < numberOfNodes; nodeIndex++) { var cloudNode = nodes[nodeIndex] as CloudLayerNode; if (cloudNode == null) { continue; } var cloudMap = cloudNode.CloudMap as LayeredCloudMap; if (cloudMap == null) { continue; } // We update the cloud map only once per frame. if (cloudMap.LastFrame == frame) { continue; } cloudMap.LastFrame = frame; var layers = cloudMap.Layers; var animationTimes = cloudMap.AnimationTimes; var sources = cloudMap.SourceLayers; var targets = cloudMap.TargetLayers; var renderTargets = cloudMap.LayerTextures; // Animate the cloud map layers. for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { if (layers[i] == null || layers[i].Texture != null) { continue; } if (cloudMap.Random == null) { cloudMap.Random = new Random(cloudMap.Seed); } // Make sure there is a user-defined texture or data for procedural textures. if (sources[i] == null) { // Each octave is 128 x 128 (= 1 / 4 of the 512 * 512 noise texture). sources[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); targets[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); renderTargets[i] = new RenderTarget2D(graphicsDevice, 128, 128, false, SurfaceFormat.Alpha8, DepthFormat.None); } // Update animation time. animationTimes[i] += deltaTime * layers[i].AnimationSpeed; // Update source and target if animation time is beyond 1. if (animationTimes[i] > 1) { // Wrap animation time. animationTimes[i] = animationTimes[i] % 1; // Swap source and target. MathHelper.Swap(ref sources[i], ref targets[i]); // Set target to a new random part of the noise texture. targets[i].Offset = cloudMap.Random.NextVector2F(0, 1); } // Lerp source and target together to get the final noise texture. graphicsDevice.SetRenderTarget(renderTargets[i]); _parameterViewportSize.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _parameterTextures[0].SetValue(sources[i].TextureAtlas); _parameterTextures[1].SetValue(targets[i].TextureAtlas); _parameterTexture0Parameters.SetValue(new Vector4(sources[i].Scale.X, sources[i].Scale.Y, sources[i].Offset.X, sources[i].Offset.Y)); _parameterTexture1Parameters.SetValue(new Vector4(targets[i].Scale.X, targets[i].Scale.Y, targets[i].Offset.X, targets[i].Offset.Y)); _parameterLerp.SetValue(animationTimes[i]); _passLerp.Apply(); graphicsDevice.DrawFullScreenQuad(); } // Initialize the cloud map. if (cloudMap.Texture == null || cloudMap.Size != cloudMap.Texture.Width) { cloudMap.Texture.SafeDispose(); var cloudTexture = new RenderTarget2D( graphicsDevice, cloudMap.Size, cloudMap.Size, false, SurfaceFormat.Alpha8, DepthFormat.None); cloudMap.SetTexture(cloudTexture); } // Combine the layers. graphicsDevice.SetRenderTarget((RenderTarget2D)cloudMap.Texture); _parameterViewportSize.SetValue(new Vector2(cloudMap.Texture.Width, cloudMap.Texture.Height)); for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { var layer = layers[i] ?? EmptyLayer; _parameterTextures[i].SetValue(layer.Texture ?? renderTargets[i]); _parameterMatrices[i].SetValue((Matrix) new Matrix44F(layer.TextureMatrix, Vector3F.Zero)); _parameterDensities[i].SetValue(new Vector2(layer.DensityScale, layer.DensityOffset)); } _parameterCoverage.SetValue(cloudMap.Coverage); _parameterDensity.SetValue(cloudMap.Density); _passDensity.Apply(); graphicsDevice.DrawFullScreenQuad(); } savedRenderState.Restore(); graphicsDevice.SetRenderTarget(null); context.RenderTarget = originalRenderTarget; context.Viewport = originalViewport; }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (numberOfNodes == 0) { return; } context.Validate(_effect); context.ThrowIfCameraMissing(); var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); // Camera properties int viewportHeight = graphicsDevice.Viewport.Height; var cameraNode = context.CameraNode; var projection = cameraNode.Camera.Projection; _parameterProjection.SetValue(projection); // Update SceneNode.LastFrame for all visible nodes. int frame = context.Frame; cameraNode.LastFrame = frame; for (int i = 0; i < numberOfNodes; i++) { var node = nodes[i] as CloudLayerNode; if (node == null) { continue; } // CloudLayerNode is visible in current frame. node.LastFrame = frame; if (node.CloudMap.Texture == null) { continue; } var sunDirection = node.SunDirection; _parameterSunDirection.SetValue((Vector3)sunDirection); _parameterSkyCurvature.SetValue(node.SkyCurvature); _parameterTextureMatrix.SetValue((Matrix) new Matrix44F(node.TextureMatrix, Vector3F.Zero)); // The sample at the pixel counts as one, the rest are for the blur. // Note: We must not set -1 because a for loop like // for (int i = 0; i < -1, i++) // crashes the AMD DX9 WP8.1 graphics driver. LOL _parameterNumberOfSamples.SetValue(Math.Max(0, node.NumberOfSamples - 1)); _parameterSampleDistance.SetValue(node.SampleDistance); _parameterScatterParameters.SetValue(new Vector3(node.ForwardScatterExponent, node.ForwardScatterScale, node.ForwardScatterOffset)); _parameterHorizonFade.SetValue(new Vector2(node.HorizonFade, node.HorizonBias)); _parameterSunLight.SetValue((Vector3)node.SunLight); _parameterAmbientLight.SetValue(new Vector4((Vector3)node.AmbientLight, node.Alpha)); _parameterTexture.SetValue(node.CloudMap.Texture); // Occlusion query. if (graphicsDevice.GraphicsProfile != GraphicsProfile.Reach && node.SunQuerySize >= Numeric.EpsilonF) { bool skipQuery = false; if (node.OcclusionQuery != null) { if (node.OcclusionQuery.IsComplete) { node.TryUpdateSunOcclusion(); } else { // The previous query is still not finished. Do not start a new query, this would // create a SharpDX warning. skipQuery = true; } } else { node.OcclusionQuery = new OcclusionQuery(graphicsDevice); } if (!skipQuery) { node.IsQueryPending = true; float totalPixels = viewportHeight * node.SunQuerySize; totalPixels *= totalPixels; node.QuerySize = totalPixels; // Use a camera which looks at the sun. // Get an relative up vector which is not parallel to the forward direction. var lookAtUp = Vector3F.UnitY; if (Vector3F.AreNumericallyEqual(sunDirection, lookAtUp)) { lookAtUp = Vector3F.UnitZ; } Vector3F zAxis = -sunDirection; Vector3F xAxis = Vector3F.Cross(lookAtUp, zAxis).Normalized; Vector3F yAxis = Vector3F.Cross(zAxis, xAxis); var lookAtSunView = new Matrix(xAxis.X, yAxis.X, zAxis.X, 0, xAxis.Y, yAxis.Y, zAxis.Y, 0, xAxis.Z, yAxis.Z, zAxis.Z, 0, 0, 0, 0, 1); _parameterView.SetValue(lookAtSunView); graphicsDevice.BlendState = GraphicsHelper.BlendStateNoColorWrite; graphicsDevice.DepthStencilState = DepthStencilState.None; graphicsDevice.RasterizerState = RasterizerState.CullNone; // Create small quad shortly behind the near plane. // Note: We use an "untranslated" view matrix, so we can ignore the camera position. float width = (projection.Top - projection.Bottom) * node.SunQuerySize; Vector3F right = sunDirection.Orthonormal1 * (width / 2); Vector3F up = sunDirection.Orthonormal2 * (width / 2); Vector3F center = sunDirection * (projection.Near * 1.0001f); _queryGeometry[0] = center - up - right; _queryGeometry[1] = center + up - right; _queryGeometry[2] = center - up + right; _queryGeometry[3] = center + up + right; if (node.CloudMap.Texture.Format == SurfaceFormat.Alpha8) { _passOcclusionAlpha.Apply(); } else { _passOcclusionRgb.Apply(); } node.OcclusionQuery.Begin(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _queryGeometry, 0, 2, VertexPosition.VertexDeclaration); node.OcclusionQuery.End(); } } else { node.IsQueryPending = false; node.SunOcclusion = 0; } Matrix viewUntranslated = (Matrix) new Matrix44F(cameraNode.PoseWorld.Orientation.Transposed, new Vector3F(0)); _parameterView.SetValue(viewUntranslated); // Render clouds. graphicsDevice.BlendState = BlendState.AlphaBlend; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; if (context.IsHdrEnabled()) { if (node.CloudMap.Texture.Format == SurfaceFormat.Alpha8) { _passCloudAlphaLinear.Apply(); } else { _passCloudRgbLinear.Apply(); } } else { if (node.CloudMap.Texture.Format == SurfaceFormat.Alpha8) { _passCloudAlphaGamma.Apply(); } else { _passCloudRgbGamma.Apply(); } } _submesh.Draw(); } savedRenderState.Restore(); }
public void Update(IPluginIO pin, DX11RenderContext context) { Device device = context.Device; DeviceContext ctx = context.CurrentDeviceContext; if (!this.deviceshaderdata.ContainsKey(context)) { this.deviceshaderdata.Add(context, new DX11ShaderData(context)); this.deviceshaderdata[context].SetEffect(this.FShader); } DX11ShaderData shaderdata = this.deviceshaderdata[context]; if (this.shaderupdated) { shaderdata.SetEffect(this.FShader); this.shaderupdated = false; } context.RenderStateStack.Push(new DX11RenderState()); this.OnBeginQuery(context); //Clear shader stages shaderdata.ResetShaderStages(ctx); context.Primitives.ApplyFullTriVS(); foreach (DX11ResourcePoolEntry <DX11RenderTarget2D> rt in this.lastframetargets) { rt.UnLock(); } this.lastframetargets.Clear(); DX11ObjectRenderSettings or = new DX11ObjectRenderSettings(); int wi, he; bool preserve = false; DX11ResourcePoolEntry <DX11RenderTarget2D> preservedtarget = null; for (int i = 0; i < this.spmax; i++) { int passcounter = 0; if (this.FInEnabled[i]) { List <DX11ResourcePoolEntry <DX11RenderTarget2D> > locktargets = new List <DX11ResourcePoolEntry <DX11RenderTarget2D> >(); #region Manage size DX11Texture2D initial; if (this.FIn.PluginIO.IsConnected) { if (this.FInUseDefaultSize[0]) { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } else { initial = this.FIn[i][context]; if (initial != null) { wi = initial.Width; he = initial.Height; } else { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } } } else { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } #endregion DX11RenderSettings r = new DX11RenderSettings(); r.RenderWidth = wi; r.RenderHeight = he; if (this.FInSemantics.PluginIO.IsConnected) { r.CustomSemantics.AddRange(this.FInSemantics.ToArray()); } if (this.FInResSemantics.PluginIO.IsConnected) { r.ResourceSemantics.AddRange(this.FInResSemantics.ToArray()); } this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, r); this.varmanager.ApplyGlobal(shaderdata.ShaderInstance); DX11Texture2D lastrt = initial; DX11ResourcePoolEntry <DX11RenderTarget2D> lasttmp = null; List <DX11Texture2D> rtlist = new List <DX11Texture2D>(); //Bind Initial (once only is ok) this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "INITIAL", initial); //Go trough all passes EffectTechnique tech = shaderdata.ShaderInstance.Effect.GetTechniqueByIndex(tid); for (int j = 0; j < tech.Description.PassCount; j++) { ImageShaderPass pi = this.varmanager.passes[j]; EffectPass pass = tech.GetPassByIndex(j); for (int kiter = 0; kiter < pi.IterationCount; kiter++) { if (passcounter > 0) { for (int pid = 0; pid < passcounter; pid++) { string pname = "PASSRESULT" + pid; this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, pname, rtlist[pid]); } } Format fmt = initial.Format; if (pi.CustomFormat) { fmt = pi.Format; } bool mips = pi.Mips; int w, h; if (j == 0) { h = he; w = wi; } else { h = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? he : lastrt.Height; w = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? wi : lastrt.Width; } if (pi.DoScale) { if (pi.Absolute) { w = Convert.ToInt32(pi.ScaleVector.X); h = Convert.ToInt32(pi.ScaleVector.Y); } else { w = Convert.ToInt32((float)w * pi.ScaleVector.X); h = Convert.ToInt32((float)h * pi.ScaleVector.Y); } w = Math.Max(w, 1); h = Math.Max(h, 1); } //Check format support for render target, and default to rgb8 if not if (!context.IsSupported(FormatSupport.RenderTarget, fmt)) { fmt = Format.R8G8B8A8_UNorm; } //Since device is not capable of telling us BGR not supported if (fmt == Format.B8G8R8A8_UNorm) { fmt = Format.R8G8B8A8_UNorm; } DX11ResourcePoolEntry <DX11RenderTarget2D> elem; if (preservedtarget != null) { elem = preservedtarget; } else { elem = context.ResourcePool.LockRenderTarget(w, h, fmt, new SampleDescription(1, 0), mips, 0); locktargets.Add(elem); } DX11RenderTarget2D rt = elem.Element; if (this.FDepthIn.PluginIO.IsConnected && pi.UseDepth) { context.RenderTargetStack.Push(this.FDepthIn[0][context], true, elem.Element); } else { context.RenderTargetStack.Push(elem.Element); } if (pi.Clear) { elem.Element.Clear(new Color4(0, 0, 0, 0)); } #region Check for depth/blend preset bool validdepth = false; bool validblend = false; DepthStencilStateDescription ds = new DepthStencilStateDescription(); BlendStateDescription bs = new BlendStateDescription(); if (pi.DepthPreset != "") { try { ds = DX11DepthStencilStates.Instance.GetState(pi.DepthPreset); validdepth = true; } catch { } } if (pi.BlendPreset != "") { try { bs = DX11BlendStates.Instance.GetState(pi.BlendPreset); validblend = true; } catch { } } #endregion if (validdepth || validblend) { DX11RenderState state = new DX11RenderState(); if (validdepth) { state.DepthStencil = ds; } if (validblend) { state.Blend = bs; } context.RenderStateStack.Push(state); } r.RenderWidth = w; r.RenderHeight = h; r.BackBuffer = elem.Element; this.varmanager.ApplyGlobal(shaderdata.ShaderInstance); //Apply settings (note that textures swap is handled later) this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, or, i); //Bind last render target this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "PREVIOUS", lastrt); this.BindPassIndexSemantic(shaderdata.ShaderInstance.Effect, j); this.BindPassIterIndexSemantic(shaderdata.ShaderInstance.Effect, kiter); if (this.FDepthIn.PluginIO.IsConnected) { if (this.FDepthIn[0].Contains(context)) { this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "DEPTHTEXTURE", this.FDepthIn[0][context]); } } //Apply pass and draw quad pass.Apply(ctx); if (pi.ComputeData.Enabled) { pi.ComputeData.Dispatch(context, w, h); context.CleanUpCS(); } else { ctx.ComputeShader.Set(null); context.Primitives.FullScreenTriangle.Draw(); ctx.OutputMerger.SetTargets(this.nullrtvs); } //Generate mips if applicable if (pi.Mips) { ctx.GenerateMips(rt.SRV); } if (!pi.KeepTarget) { preserve = false; rtlist.Add(rt); lastrt = rt; lasttmp = elem; preservedtarget = null; passcounter++; } else { preserve = true; preservedtarget = elem; } context.RenderTargetStack.Pop(); if (validblend || validdepth) { context.RenderStateStack.Pop(); } if (pi.HasState) { context.RenderStateStack.Apply(); } } } //Set last render target this.FOut[i][context] = lastrt; //Unlock all resources foreach (DX11ResourcePoolEntry <DX11RenderTarget2D> lt in locktargets) { lt.UnLock(); } //Keep lock on last rt, since don't want it overidden lasttmp.Lock(); this.lastframetargets.Add(lasttmp); } else { this.FOut[i][context] = this.FIn[i][context]; } } context.RenderStateStack.Pop(); this.OnEndQuery(context); //UnLock previous frame in applicable //if (previoustarget != null) { context.ResourcePool.Unlock(previoustarget); } }
public void ApplyPass(EffectPass pass) { pass.Apply(this.context.CurrentDeviceContext); this.ApplyCounterUAVS(); }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (numberOfNodes == 0) { return; } context.Validate(_effect); context.ThrowIfCameraMissing(); var graphicsDevice = _effect.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.DepthStencilState = DepthStencilState.None; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.BlendState = GraphicsHelper.BlendStateAdd; var viewport = graphicsDevice.Viewport; _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height)); _parameterGBuffer0.SetValue(context.GBuffer0); _parameterGBuffer1.SetValue(context.GBuffer1); var cameraNode = context.CameraNode; Pose cameraPose = cameraNode.PoseWorld; Matrix viewProjection = (Matrix)cameraNode.View * cameraNode.Camera.Projection; // Update SceneNode.LastFrame for all visible nodes. int frame = context.Frame; context.CameraNode.LastFrame = frame; var isHdrEnabled = context.IsHdrEnabled(); for (int i = 0; i < numberOfNodes; i++) { var lightNode = nodes[i] as LightNode; if (lightNode == null) { continue; } var light = lightNode.Light as PointLight; if (light == null) { continue; } // LightNode is visible in current frame. lightNode.LastFrame = frame; float hdrScale = isHdrEnabled ? light.HdrScale : 1; _parameterDiffuseColor.SetValue((Vector3)light.Color * light.DiffuseIntensity * hdrScale); _parameterSpecularColor.SetValue((Vector3)light.Color * light.SpecularIntensity * hdrScale); Pose lightPose = lightNode.PoseWorld; bool hasShadow = (lightNode.Shadow != null && lightNode.Shadow.ShadowMask != null); if (hasShadow) { switch (lightNode.Shadow.ShadowMaskChannel) { case 0: _parameterShadowMaskChannel.SetValue(new Vector4(1, 0, 0, 0)); break; case 1: _parameterShadowMaskChannel.SetValue(new Vector4(0, 1, 0, 0)); break; case 2: _parameterShadowMaskChannel.SetValue(new Vector4(0, 0, 1, 0)); break; default: _parameterShadowMaskChannel.SetValue(new Vector4(0, 0, 0, 1)); break; } _parameterShadowMask.SetValue(lightNode.Shadow.ShadowMask); } _parameterPosition.SetValue((Vector3)(lightPose.Position - cameraPose.Position)); _parameterRange.SetValue(light.Range); _parameterAttenuation.SetValue(light.Attenuation); bool hasTexture = (light.Texture != null); if (hasTexture) { _parameterTexture.SetValue(light.Texture); // Cube maps are left handed --> Sample with inverted z. (Otherwise, the // cube map and objects or texts in it are mirrored.) var mirrorZ = Matrix44F.CreateScale(1, 1, -1); _parameterTextureMatrix.SetValue((Matrix)(mirrorZ * lightPose.Inverse)); } var rectangle = GraphicsHelper.GetViewportRectangle(cameraNode, viewport, lightPose.Position, light.Range); var texCoordTopLeft = new Vector2F(rectangle.Left / (float)viewport.Width, rectangle.Top / (float)viewport.Height); var texCoordBottomRight = new Vector2F(rectangle.Right / (float)viewport.Width, rectangle.Bottom / (float)viewport.Height); GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, texCoordTopLeft, texCoordBottomRight, _frustumFarCorners); // Convert frustum far corners from view space to world space. for (int j = 0; j < _frustumFarCorners.Length; j++) { _frustumFarCorners[j] = (Vector3)cameraPose.ToWorldDirection((Vector3F)_frustumFarCorners[j]); } _parameterFrustumCorners.SetValue(_frustumFarCorners); if (lightNode.Clip != null) { var data = lightNode.RenderData as LightRenderData; if (data == null) { data = new LightRenderData(); lightNode.RenderData = data; } data.UpdateClipSubmesh(context.GraphicsService, lightNode); graphicsDevice.DepthStencilState = GraphicsHelper.DepthStencilStateOnePassStencilFail; graphicsDevice.BlendState = GraphicsHelper.BlendStateNoColorWrite; _parameterWorldViewProjection.SetValue((Matrix)data.ClipMatrix * viewProjection); _passClip.Apply(); data.ClipSubmesh.Draw(); graphicsDevice.DepthStencilState = lightNode.InvertClip ? GraphicsHelper.DepthStencilStateStencilEqual0 : GraphicsHelper.DepthStencilStateStencilNotEqual0; graphicsDevice.BlendState = GraphicsHelper.BlendStateAdd; } else { graphicsDevice.DepthStencilState = DepthStencilState.None; } if (hasShadow) { if (hasTexture) { if (light.Texture.Format == SurfaceFormat.Alpha8) { _passShadowedTexturedAlpha.Apply(); } else { _passShadowedTexturedRgb.Apply(); } } else { _passShadowed.Apply(); } } else { if (hasTexture) { if (light.Texture.Format == SurfaceFormat.Alpha8) { _passTexturedAlpha.Apply(); } else { _passTexturedRgb.Apply(); } } else { _passDefault.Apply(); } } graphicsDevice.DrawQuad(rectangle); } savedRenderState.Restore(); }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (nodes.Count == 0) { return; } context.Validate(_effect); context.ThrowIfCameraMissing(); var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.BlendState = BlendState.AlphaBlend; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; // Camera properties var cameraNode = context.CameraNode; Matrix view = (Matrix) new Matrix(cameraNode.PoseWorld.Orientation.Transposed, new Vector3()); _parameterView.SetValue(view); Matrix projection = cameraNode.Camera.Projection; _parameterProjection.SetValue(projection); // Update SceneNode.LastFrame for all visible nodes. int frame = context.Frame; cameraNode.LastFrame = frame; for (int i = 0; i < numberOfNodes; i++) { var node = nodes[i] as GradientTextureSkyNode; if (node == null) { continue; } // GradientTextureSkyNode is visible in current frame. node.LastFrame = frame; _parameterSunDirection.SetValue((Vector3)node.SunDirection); _parameterTime.SetValue((float)node.TimeOfDay.TotalHours / 24); _parameterColor.SetValue((Vector4)node.Color); _parameterFrontTexture.SetValue(node.FrontTexture); _parameterBackTexture.SetValue(node.BackTexture); if (node.CieSkyStrength < Numeric.EpsilonF) { if (context.IsHdrEnabled()) { _passLinear.Apply(); } else { _passGamma.Apply(); } } else { var p = node.CieSkyParameters; _parameterAbcd.SetValue(new Vector4(p.A, p.B, p.C, p.D)); _parameterEAndStrength.SetValue(new Vector2(p.E, node.CieSkyStrength)); if (context.IsHdrEnabled()) { _passCieLinear.Apply(); } else { _passCieGamma.Apply(); } } _submesh.Draw(); } savedRenderState.Restore(); }
protected override void OnProcess(RenderContext context) { var graphicsDevice = GraphicsService.GraphicsDevice; var renderTargetPool = GraphicsService.RenderTargetPool; var source = context.SourceTexture; var target = context.RenderTarget; var viewport = context.Viewport; int downsampledWidth = Math.Max(1, source.Width / DownsampleFactor); int downsampledHeight = Math.Max(1, source.Height / DownsampleFactor); // ----- Get temporary render targets. var sourceDownsampled = renderTargetPool.Obtain2D(new RenderTargetFormat( downsampledWidth, downsampledHeight, false, source.Format, DepthFormat.None)); var bloom = renderTargetPool.Obtain2D(new RenderTargetFormat( downsampledWidth, downsampledHeight, false, SurfaceFormat.Color, DepthFormat.None)); // ----- Downsample scene. context.RenderTarget = sourceDownsampled; context.Viewport = new Viewport(0, 0, sourceDownsampled.Width, sourceDownsampled.Height); _downsampleFilter.Process(context); // ----- Compute luminance. context.SourceTexture = sourceDownsampled; context.RenderTarget = _luminanceTarget; context.Viewport = new Viewport(0, 0, _luminanceTarget.Width, _luminanceTarget.Height); _luminance.Process(context); // ----- Create bloom image. graphicsDevice.SetRenderTarget(bloom); _viewportSizeParameter.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _bloomThresholdParameter.SetValue(BloomThreshold); _middleGrayParameter.SetValue(MiddleGray); _minExposureParameter.SetValue(MinExposure); _maxExposureParameter.SetValue(MaxExposure); _bloomIntensityParameter.SetValue(BloomIntensity); _sceneTextureParameter.SetValue(sourceDownsampled); _luminanceTextureParameter.SetValue(_luminanceTarget); _brightnessPass.Apply(); graphicsDevice.DrawFullScreenQuad(); // sourceDownsampled is not needed anymore. renderTargetPool.Recycle(sourceDownsampled); // We make a two-pass blur, so source can be equal to target. context.SourceTexture = bloom; context.RenderTarget = bloom; context.Viewport = new Viewport(0, 0, bloom.Width, bloom.Height); _blur.Process(context); // ----- Combine scene and bloom. graphicsDevice.SetRenderTarget(target); graphicsDevice.Viewport = viewport; _viewportSizeParameter.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _sceneTextureParameter.SetValue(source); _bloomTextureParameter.SetValue(bloom); _luminanceTextureParameter.SetValue(_luminanceTarget); _middleGrayParameter.SetValue(MiddleGray); if (EnableBlueShift) { _blueShiftColorParameter.SetValue((Vector3)BlueShiftColor); _blueShiftParameter.SetValue(new Vector2(1 / BlueShiftCenter, 1 / BlueShiftRange)); _combineWithBlueShiftPass.Apply(); } else { _combinePass.Apply(); } graphicsDevice.DrawFullScreenQuad(); // ----- Clean-up _sceneTextureParameter.SetValue((Texture2D)null); _luminanceTextureParameter.SetValue((Texture2D)null); _bloomTextureParameter.SetValue((Texture2D)null); renderTargetPool.Recycle(bloom); context.SourceTexture = source; context.RenderTarget = target; context.Viewport = viewport; }
public void Render(SceneGraph SceneGraph, Camera Camera, Matrix ProjMatrix) { // Set input assembler information... ImmediateContext.InputAssembler.InputLayout = InputLayout; ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // Since a menu node is a root node (according to the scene graph), // just draw it without traversing or recursing or any of that mess. var vertsList = new List<object>(); var indicesList = new List<uint>(); var sets = new List<Tuple<int, int>>(); vertsList.AddRange(SceneGraph.Renderable.GetVertexList(EffectName())); indicesList.AddRange(SceneGraph.Renderable.GetIndexList(EffectName())); sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count)); // TODO KAM: Remove this hack. if (vertsList.Count == 0) { return; } // Render buttons individually, both action and submenu buttons var menuButtons = (SceneGraph.Renderable as Menu).MenuButtons; for (var i = 0; i < menuButtons.Length; i++) { vertsList.AddRange(menuButtons[i].GetVertexList(EffectName())); indicesList.AddRange(menuButtons[i].GetIndexList(EffectName())); sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count)); } var vertexBufferDesc = new BufferDescription(MenuEffectVertex.Stride * vertsList.Count, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); Util.ReleaseCom(ref VertexBuffer); // TODO KAM: Make this dirtyable instead VertexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(vertsList.Cast<MenuEffectVertex>().ToArray(), false, false), vertexBufferDesc); var indexBufferDesc = new BufferDescription( sizeof(uint) * indicesList.Count, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); Util.ReleaseCom(ref IndexBuffer); IndexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(indicesList.ToArray(), false, false), indexBufferDesc); // Set buffers ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, MenuEffectVertex.Stride, 0)); ImmediateContext.InputAssembler.SetIndexBuffer(IndexBuffer, SlimDX.DXGI.Format.R32_UInt, 0); Pass = Technique.GetPassByIndex(0); CPO_BlendColor.Set(new Vector4(1.0f, 1.0f, 1.0f, 0.8f)); // 80% opacity // // Set depth stencil state // var existingState = ImmediateContext.OutputMerger.DepthStencilState; ImmediateContext.OutputMerger.DepthStencilState = DepthDisabledState; // // Render background... // SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, SceneGraph.Renderable.GetTexturePath())); Pass.Apply(ImmediateContext); ImmediateContext.DrawIndexed(sets[0].Item2, 0, 0); // // Render each button... // for (var i = 0; i < menuButtons.Length; i++) { CPO_BlendColor.Set(menuButtons[i].GetBlendColor()); SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, menuButtons[i].GetTexturePath())); Pass.Apply(ImmediateContext); ImmediateContext.DrawIndexed(6, sets[i].Item2, sets[i].Item1); } // // Restore depth stencil state // ImmediateContext.OutputMerger.DepthStencilState = existingState; }
private void DrawAmbient(DeviceContext dc, EffectPass pass, Matrix view, Matrix proj) { var model = _bunnyInstance.Model; var world = _bunnyInstance.World; var wit = MathF.InverseTranspose(world); _effect.SetWorld(world); _effect.SetWorldViewProj(world * view * proj); _effect.SetWorldInvTranspose(wit); for (var i = 0; i < model.SubsetCount; i++) { _effect.SetDiffuseMap(model.DiffuseMapSRV[i]); pass.Apply(ImmediateContext); model.ModelMesh.Draw(ImmediateContext, i); } }
private void DrawDirectional(DeviceContext dc, EffectPass pass, Matrix view, Matrix proj) { var model = _bunnyInstance.Model; var world = _bunnyInstance.World; var wit = MathF.InverseTranspose(world); _effect.SetWorld(world); _effect.SetWorldViewProj(world * view * proj); _effect.SetWorldInvTranspose(wit); _effect.SetEyePosition(_camera.Position); _effect.SetSpecularExponent(250.0f); _effect.SetSpecularIntensity(0.25f); for (var i = 0; i < model.SubsetCount; i++) { _effect.SetDiffuseMap(model.DiffuseMapSRV[i]); pass.Apply(ImmediateContext); model.ModelMesh.Draw(ImmediateContext, i); } }
public void ApplyAlert(GraphicsDevice g, Texture2D tColor) { g.Textures[1] = tColor; g.SamplerStates[1] = SamplerState.LinearWrap; fxPassAlert.Apply(); }
protected override void OnProcess(RenderContext context) { context.ThrowIfCameraMissing(); var graphicsDevice = GraphicsService.GraphicsDevice; var renderTargetPool = GraphicsService.RenderTargetPool; var source = context.SourceTexture; var target = context.RenderTarget; var viewport = context.Viewport; RenderTarget2D temp128x128 = renderTargetPool.Obtain2D( new RenderTargetFormat(128, 128, false, SurfaceFormat.HalfVector4, DepthFormat.None)); RenderTarget2D temp64x64 = renderTargetPool.Obtain2D( new RenderTargetFormat(64, 64, false, SurfaceFormat.HalfVector4, DepthFormat.None)); RenderTarget2D luminance = renderTargetPool.Obtain2D( new RenderTargetFormat(1, 1, false, SurfaceFormat.HalfVector4, DepthFormat.None)); // ----- Downsample scene into temp128x128. context.RenderTarget = temp128x128; context.Viewport = new Viewport(0, 0, temp128x128.Width, temp128x128.Height); _downsampleFilter.Process(context); _useGeometricMeanParameter.SetValue(UseGeometricMean); // Get view-dependent information stored in camera node. var cameraNode = context.CameraNode; object dummy; cameraNode.ViewDependentData.TryGetValue(this, out dummy); var data = dummy as ViewDependentData; if (data == null) { data = new ViewDependentData(GraphicsService); cameraNode.ViewDependentData[this] = data; } if (UseAdaption) { // Use adaption if required by user and if we already have luminance info. _useAdaptionParameter.SetValue(data.LastLuminance != null); _deltaTimeParameter.SetValue((float)context.DeltaTime.TotalSeconds); _adaptionSpeedParameter.SetValue(AdaptionSpeed); _lastLuminanceTextureParameter.SetValue(data.LastLuminance); } else { _useAdaptionParameter.SetValue(false); _lastLuminanceTextureParameter.SetValue((Texture2D)null); // Reset old luminance info. data.Dispose(); } // ----- First downsample temp128x128 into temp64x64 and create luminance info. graphicsDevice.SetRenderTarget(temp64x64); _textureParameter.SetValue(temp128x128); _sourceSizeParameter.SetValue(new Vector2(temp128x128.Width, temp128x128.Height)); _targetSizeParameter.SetValue(new Vector2(temp64x64.Width, temp64x64.Height)); _createPass.Apply(); graphicsDevice.DrawFullScreenQuad(); // temp128x128 is not needed anymore. renderTargetPool.Recycle(temp128x128); // ----- Downsample luminance info. RenderTarget2D last = temp64x64; while (last.Width > 2) { Debug.Assert(last.Width == last.Height, "The render target must be quadratic"); RenderTarget2D temp = renderTargetPool.Obtain2D( new RenderTargetFormat(last.Width / 2, last.Height / 2, false, last.Format, DepthFormat.None)); graphicsDevice.SetRenderTarget(temp); _textureParameter.SetValue(last); _sourceSizeParameter.SetValue(new Vector2(last.Width, last.Height)); _targetSizeParameter.SetValue(new Vector2(temp.Width, temp.Height)); _downsamplePass.Apply(); graphicsDevice.DrawFullScreenQuad(); renderTargetPool.Recycle(last); last = temp; } // ----- Sample 'last' and store final info in 'luminance'. graphicsDevice.SetRenderTarget(luminance); _textureParameter.SetValue(last); _sourceSizeParameter.SetValue(new Vector2(last.Width, last.Height)); _targetSizeParameter.SetValue(new Vector2(luminance.Width, luminance.Height)); _finalPass.Apply(); graphicsDevice.DrawFullScreenQuad(); renderTargetPool.Recycle(last); // ----- Copy luminance to original context.RenderTarget. context.SourceTexture = luminance; context.RenderTarget = target; context.Viewport = viewport; _copyFilter.Process(context); // ----- Store luminance for next frame. renderTargetPool.Recycle(data.LastLuminance); data.LastLuminance = luminance; // Restore original context. context.SourceTexture = source; _textureParameter.SetValue((Texture2D)null); }
public void PrepareClearGBuffer() { clearGBufferPass.Apply(); }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (numberOfNodes == 0) { return; } context.Validate(_effect); context.ThrowIfCameraMissing(); var graphicsDevice = _effect.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.DepthStencilState = DepthStencilState.None; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.BlendState = GraphicsHelper.BlendStateAdd; var viewport = graphicsDevice.Viewport; _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height)); _parameterGBuffer0.SetValue(context.GBuffer0); _parameterGBuffer1.SetValue(context.GBuffer1); var cameraNode = context.CameraNode; Matrix viewProjection = (Matrix)cameraNode.View * cameraNode.Camera.Projection; // Update SceneNode.LastFrame for all visible nodes. int frame = context.Frame; cameraNode.LastFrame = frame; var isHdrEnabled = context.IsHdrEnabled(); for (int i = 0; i < numberOfNodes; i++) { var lightNode = nodes[i] as LightNode; if (lightNode == null) { continue; } var light = lightNode.Light as AmbientLight; if (light == null) { continue; } // LightNode is visible in current frame. lightNode.LastFrame = frame; float hdrScale = isHdrEnabled ? light.HdrScale : 1; _parameterLightColor.SetValue((Vector3)light.Color * light.Intensity * hdrScale); _parameterHemisphericAttenuation.SetValue(light.HemisphericAttenuation); Vector3 upWorld = lightNode.PoseWorld.ToWorldDirection(Vector3.Up); _parameterUp.SetValue((Vector3)upWorld); if (lightNode.Clip != null) { var data = lightNode.RenderData as LightRenderData; if (data == null) { data = new LightRenderData(); lightNode.RenderData = data; } data.UpdateClipSubmesh(context.GraphicsService, lightNode); graphicsDevice.DepthStencilState = GraphicsHelper.DepthStencilStateOnePassStencilFail; graphicsDevice.BlendState = GraphicsHelper.BlendStateNoColorWrite; _parameterWorldViewProjection.SetValue((Matrix)data.ClipMatrix * viewProjection); _passClip.Apply(); data.ClipSubmesh.Draw(); graphicsDevice.DepthStencilState = lightNode.InvertClip ? GraphicsHelper.DepthStencilStateStencilEqual0 : GraphicsHelper.DepthStencilStateStencilNotEqual0; graphicsDevice.BlendState = GraphicsHelper.BlendStateAdd; } else { graphicsDevice.DepthStencilState = DepthStencilState.None; } _passLight.Apply(); graphicsDevice.DrawFullScreenQuad(); } savedRenderState.Restore(); }
protected override void OnProcess(RenderContext context) { context.ThrowIfCameraMissing(); context.ThrowIfGBuffer0Missing(); var graphicsDevice = GraphicsService.GraphicsDevice; var cameraNode = context.CameraNode; var renderTargetPool = GraphicsService.RenderTargetPool; var source = context.SourceTexture; var target = context.RenderTarget; var viewport = context.Viewport; var sourceSize = new Vector2F(source.Width, source.Height); int width = (int)sourceSize.X; int height = (int)sourceSize.Y; int downsampledWidth = Math.Max(1, width / DownsampleFactor); int downsampledHeight = Math.Max(1, height / DownsampleFactor); if (TextureHelper.IsFloatingPointFormat(source.Format)) { graphicsDevice.SamplerStates[0] = SamplerState.PointClamp; InitializeGaussianBlur(new Vector2F(downsampledWidth, downsampledHeight), false); } else { graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; InitializeGaussianBlur(new Vector2F(downsampledWidth, downsampledHeight), true); } // Get temporary render targets. var downsampleFormat = new RenderTargetFormat(downsampledWidth, downsampledHeight, false, source.Format, DepthFormat.None); RenderTarget2D blurredScene0 = renderTargetPool.Obtain2D(downsampleFormat); RenderTarget2D blurredScene1 = renderTargetPool.Obtain2D(downsampleFormat); var blurredDepthFormat = new RenderTargetFormat(downsampledWidth, downsampledHeight, false, context.GBuffer0.Format, DepthFormat.None); RenderTarget2D blurredDepth0 = renderTargetPool.Obtain2D(blurredDepthFormat); var cocFormat = new RenderTargetFormat(width, height, false, SurfaceFormat.Single, DepthFormat.None); RenderTarget2D cocImage = renderTargetPool.Obtain2D(cocFormat); var downSampledCocFormat = new RenderTargetFormat(downsampledWidth, downsampledHeight, false, cocFormat.SurfaceFormat, DepthFormat.None); RenderTarget2D cocImageBlurred = renderTargetPool.Obtain2D(downSampledCocFormat); // ----- Create CoC map. _effect.CurrentTechnique = _effect.Techniques[0]; graphicsDevice.SetRenderTarget(cocImage); _screenSizeParameter.SetValue(new Vector2(cocImage.Width, cocImage.Height)); _depthTextureParameter.SetValue(context.GBuffer0); _nearBlurDistanceParameter.SetValue(NearBlurDistance); _nearFocusDistanceParameter.SetValue(NearFocusDistance); _farFocusDistanceParameter.SetValue(FarFocusDistance); _farBlurDistanceParameter.SetValue(FarBlurDistance); _farParameter.SetValue(cameraNode.Camera.Projection.Far); _circleOfConfusionPass.Apply(); graphicsDevice.DrawFullScreenQuad(); // ----- Downsample cocImage to cocImageBlurred. context.SourceTexture = cocImage; context.RenderTarget = cocImageBlurred; context.Viewport = new Viewport(0, 0, cocImageBlurred.Width, cocImageBlurred.Height); _downsampleFilter.Process(context); renderTargetPool.Recycle(cocImage); // ----- Downsample source to blurredScene0. context.SourceTexture = source; context.RenderTarget = blurredScene0; context.Viewport = new Viewport(0, 0, blurredScene0.Width, blurredScene0.Height); _downsampleFilter.Process(context); // ----- Downsample depth texture to blurredDepth0. context.SourceTexture = context.GBuffer0; context.RenderTarget = blurredDepth0; context.Viewport = new Viewport(0, 0, blurredDepth0.Width, blurredDepth0.Height); _downsampleFilter.Process(context); // ----- Blur scene. // Horizontal blur graphicsDevice.SetRenderTarget(blurredScene1); _screenSizeParameter.SetValue(new Vector2(blurredScene0.Width, blurredScene0.Height)); _blurTextureParameter.SetValue(blurredScene0); _downsampledDepthTextureParameter.SetValue(blurredDepth0); _downsampledCocTextureParameter.SetValue(cocImageBlurred); _offsetsParameter.SetValue(_horizontalOffsets); _weightsParameter.SetValue(_weights); _blurPass.Apply(); graphicsDevice.DrawFullScreenQuad(); // Vertical blur. graphicsDevice.SetRenderTarget(blurredScene0); _blurTextureParameter.SetValue(blurredScene1); _offsetsParameter.SetValue(_verticalOffsets); _blurPass.Apply(); graphicsDevice.DrawFullScreenQuad(); renderTargetPool.Recycle(blurredScene1); // ----- Blur cocImageBlurred. context.SourceTexture = cocImageBlurred; context.RenderTarget = cocImageBlurred; context.Viewport = new Viewport(0, 0, cocImageBlurred.Width, cocImageBlurred.Height); _cocBlur.Process(context); // We make a two pass blur, so context.SourceTexture can be equal to context.RenderTarget. // ----- Blur depth. context.SourceTexture = blurredDepth0; context.RenderTarget = blurredDepth0; context.Viewport = new Viewport(0, 0, blurredDepth0.Width, blurredDepth0.Height); _cocBlur.Process(context); // ----- Create final DoF image. _effect.CurrentTechnique = _effect.Techniques[0]; graphicsDevice.SetRenderTarget(target); graphicsDevice.Viewport = viewport; _screenSizeParameter.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _sceneTextureParameter.SetValue(source); _blurTextureParameter.SetValue(blurredScene0); _depthTextureParameter.SetValue(context.GBuffer0); _downsampledDepthTextureParameter.SetValue(blurredDepth0); _downsampledCocTextureParameter.SetValue(cocImageBlurred); _depthOfFieldPass.Apply(); graphicsDevice.DrawFullScreenQuad(); // ----- Clean-up _depthTextureParameter.SetValue((Texture2D)null); _blurTextureParameter.SetValue((Texture2D)null); _downsampledDepthTextureParameter.SetValue((Texture2D)null); _downsampledCocTextureParameter.SetValue((Texture2D)null); _sceneTextureParameter.SetValue((Texture2D)null); renderTargetPool.Recycle(blurredScene0); renderTargetPool.Recycle(blurredDepth0); renderTargetPool.Recycle(cocImageBlurred); context.SourceTexture = source; context.RenderTarget = target; context.Viewport = viewport; }
public void Update(IPluginIO pin, DX11RenderContext context) { Device device = context.Device; DeviceContext ctx = context.CurrentDeviceContext; if (!this.deviceshaderdata.ContainsKey(context)) { this.deviceshaderdata.Add(context, new DX11ShaderData(context)); this.deviceshaderdata[context].SetEffect(this.FShader); } DX11ShaderData shaderdata = this.deviceshaderdata[context]; if (this.shaderupdated) { shaderdata.SetEffect(this.FShader); this.shaderupdated = false; } context.RenderStateStack.Push(new DX11RenderState()); this.OnBeginQuery(context); //Clear shader stages shaderdata.ResetShaderStages(ctx); context.Primitives.ApplyFullTriVS(); foreach (DX11ResourcePoolEntry <DX11RenderTarget2D> rt in this.lastframetargets) { rt.UnLock(); } this.lastframetargets.Clear(); DX11ObjectRenderSettings or = new DX11ObjectRenderSettings(); int wi, he; for (int i = 0; i < this.spmax; i++) { if (this.FInEnabled[i]) { List <DX11ResourcePoolEntry <DX11RenderTarget2D> > locktargets = new List <DX11ResourcePoolEntry <DX11RenderTarget2D> >(); DX11Texture2D initial; if (this.FIn.PluginIO.IsConnected) { if (this.FInUseDefaultSize[0]) { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } else { initial = this.FIn[i][context]; if (initial != null) { wi = initial.Width; he = initial.Height; } else { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } } } else { initial = context.DefaultTextures.WhiteTexture; wi = (int)this.FInSize[0].X; he = (int)this.FInSize[0].Y; } DX11RenderSettings r = new DX11RenderSettings(); r.RenderWidth = wi; r.RenderHeight = he; if (this.FInSemantics.PluginIO.IsConnected) { r.CustomSemantics.AddRange(this.FInSemantics.ToArray()); } if (this.FInResSemantics.PluginIO.IsConnected) { r.ResourceSemantics.AddRange(this.FInResSemantics.ToArray()); } this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, r); this.varmanager.ApplyGlobal(shaderdata.ShaderInstance); DX11Texture2D lastrt = initial; DX11ResourcePoolEntry <DX11RenderTarget2D> lasttmp = null; List <DX11Texture2D> rtlist = new List <DX11Texture2D>(); //Bind Initial (once only is ok) this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "INITIAL", initial); if (this.persistedframe != null) { this.BindSemanticSRV(shaderdata.ShaderInstance.Effect, "LASTFRAME", persistedframe.SRV); } //Go trough all passes EffectTechnique tech = shaderdata.ShaderInstance.Effect.GetTechniqueByIndex(tid); for (int j = 0; j < tech.Description.PassCount; j++) { ImageShaderPass pi = this.varmanager.passes[j]; EffectPass pass = tech.GetPassByIndex(j); if (j > 0) { int pid = j - 1; string pname = "PASSRESULT" + pid; this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, pname, rtlist[pid]); } Format fmt = initial.Format; if (pi.CustomFormat) { fmt = pi.Format; } bool mips = pi.Mips; int w, h; if (j == 0) { h = he; w = wi; } else { h = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? he : lastrt.Height; w = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? wi : lastrt.Width; } if (pi.DoScale) { h = Convert.ToInt32((float)h * pi.Scale); w = Convert.ToInt32((float)w * pi.Scale); h = Math.Max(h, 1); w = Math.Max(w, 1); } //Check format support for render target, and default to rgb8 if not if (!context.IsSupported(FormatSupport.RenderTarget, fmt)) { fmt = Format.R8G8B8A8_UNorm; } //Since device is not capable of telling us BGR not supported if (fmt == Format.B8G8R8A8_UNorm) { fmt = Format.R8G8B8A8_UNorm; } DX11ResourcePoolEntry <DX11RenderTarget2D> elem = context.ResourcePool.LockRenderTarget(w, h, fmt, new SampleDescription(1, 0), mips, 0); locktargets.Add(elem); DX11RenderTarget2D rt = elem.Element; ctx.OutputMerger.SetTargets(rt.RTV); r.RenderWidth = w; r.RenderHeight = h; r.BackBuffer = rt; this.varmanager.ApplyGlobal(shaderdata.ShaderInstance); //Apply settings (note that textures swap is handled later) this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, or, i); Viewport vp = new Viewport(); vp.Width = rt.Width; vp.Height = rt.Height; ctx.Rasterizer.SetViewports(vp); //Bind last render target this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "PREVIOUS", lastrt); //Apply pass and draw quad pass.Apply(ctx); if (pi.ComputeData.Enabled) { pi.ComputeData.Dispatch(context, w, h); context.CleanUpCS(); } else { ctx.ComputeShader.Set(null); context.Primitives.FullScreenTriangle.Draw(); ctx.OutputMerger.SetTargets(this.nullrtvs); } //Generate mips if applicable if (pi.Mips) { ctx.GenerateMips(rt.SRV); } rtlist.Add(rt); lastrt = rt; lasttmp = elem; } //Set last render target this.FOut[i][context] = lastrt; //Unlock all resources foreach (DX11ResourcePoolEntry <DX11RenderTarget2D> lt in locktargets) { lt.UnLock(); } //Keep lock on last rt, since don't want it overidden lasttmp.Lock(); //this.lastframetargets. //this.lasttarget = lasttmp; this.lastframetargets.Add(lasttmp); //previousrts[context] = lasttmp.Element; } else { this.FOut[i][context] = this.FIn[i][context]; } } context.RenderStateStack.Pop(); this.OnEndQuery(context); //UnLock previous frame in applicable //if (previoustarget != null) { context.ResourcePool.Unlock(previoustarget); } }
public void DrawSsaoDepth(DeviceContext dc, EffectPass pass, Matrix view, Matrix proj) { var world = World; var wit = MathF.InverseTranspose(world); var wv = world * view; var witv = wit * view; var wvp = world * view*proj; Effects.SsaoNormalDepthFX.SetWorldView(wv); Effects.SsaoNormalDepthFX.SetWorldInvTransposeView(witv); Effects.SsaoNormalDepthFX.SetWorldViewProj(wvp); Effects.SsaoNormalDepthFX.SetTexTransform(TexTransform); pass.Apply(dc); for (int i = 0; i < Model.SubsetCount; i++) { Model.ModelMesh.Draw(dc, i); } }
// Perform FFTs. // 4 complex input images: source0.xy, source0.zw, source1.xy, source1.zw // 2 targets: target0 = displacement map, target1 = normal map using Color format. public void Process(RenderContext context, bool forward, Texture2D source0, Texture2D source1, RenderTarget2D target0, RenderTarget2D target1, float choppiness) { if (context == null) { throw new ArgumentNullException("context"); } if (source0 == null) { throw new ArgumentNullException("source0"); } if (source1 == null) { throw new ArgumentNullException("source1"); } if (forward) { // For forward FFT, uncomment the LastPassScale stuff! throw new NotImplementedException("Forward FFT not implemented."); } var graphicsService = context.GraphicsService; var graphicsDevice = graphicsService.GraphicsDevice; var renderTargetPool = graphicsService.RenderTargetPool; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; int size = source0.Width; _parameterSize.SetValue((float)size); _parameterChoppiness.SetValue(choppiness); int numberOfButterflyPasses = (int)MathHelper.Log2GreaterOrEqual((uint)source0.Width); // ReSharper disable once ConditionIsAlwaysTrueOrFalse _parameterButterflyTexture.SetValue(GetButterflyTexture(forward, numberOfButterflyPasses)); var format = new RenderTargetFormat(size, size, false, source0.Format, DepthFormat.None); var tempPing0 = renderTargetPool.Obtain2D(format); var tempPing1 = renderTargetPool.Obtain2D(format); var tempPong0 = renderTargetPool.Obtain2D(format); var tempPong1 = renderTargetPool.Obtain2D(format); //_parameterIsLastPass.SetValue(false); // Perform horizontal and vertical FFT pass. for (int i = 0; i < 2; i++) { //_parameterLastPassScale.SetValue(1); // Perform butterfly passes. We ping-pong between two temp targets. for (int pass = 0; pass < numberOfButterflyPasses; pass++) { _parameterButterflyIndex.SetValue(0.5f / numberOfButterflyPasses + (float)pass / numberOfButterflyPasses); if (i == 0 && pass == 0) { // First pass. _renderTargetBindings[0] = new RenderTargetBinding(tempPing0); _renderTargetBindings[1] = new RenderTargetBinding(tempPing1); graphicsDevice.SetRenderTargets(_renderTargetBindings); _parameterSourceTexture0.SetValue(source0); _parameterSourceTexture1.SetValue(source1); } else if (i == 1 && pass == numberOfButterflyPasses - 1) { // Last pass. // We have explicit shader passes for the last FFT pass. break; //_parameterIsLastPass.SetValue(true); //if (forward) // _parameterLastPassScale.SetValue(1.0f / size / size); //if (_renderTargetBindings[0].RenderTarget == tempPing0) //{ // _renderTargetBindings[0] = new RenderTargetBinding(target0); // _renderTargetBindings[1] = new RenderTargetBinding(target1); // graphicsDevice.SetRenderTargets(_renderTargetBindings); // _parameterSourceTexture0.SetValue(tempPing0); // _parameterSourceTexture1.SetValue(tempPing1); //} //else //{ // _renderTargetBindings[0] = new RenderTargetBinding(target0); // _renderTargetBindings[1] = new RenderTargetBinding(target1); // graphicsDevice.SetRenderTargets(_renderTargetBindings); // _parameterSourceTexture0.SetValue(tempPong0); // _parameterSourceTexture1.SetValue(tempPong1); //} } else { // Intermediate pass. if (_renderTargetBindings[0].RenderTarget == tempPing0) { _renderTargetBindings[0] = new RenderTargetBinding(tempPong0); _renderTargetBindings[1] = new RenderTargetBinding(tempPong1); graphicsDevice.SetRenderTargets(_renderTargetBindings); _parameterSourceTexture0.SetValue(tempPing0); _parameterSourceTexture1.SetValue(tempPing1); } else { _renderTargetBindings[0] = new RenderTargetBinding(tempPing0); _renderTargetBindings[1] = new RenderTargetBinding(tempPing1); graphicsDevice.SetRenderTargets(_renderTargetBindings); _parameterSourceTexture0.SetValue(tempPong0); _parameterSourceTexture1.SetValue(tempPong1); } } if (i == 0) { _passFftHorizontal.Apply(); } else { _passFftVertical.Apply(); } graphicsDevice.DrawFullScreenQuad(); } } // Perform final vertical FFT passes. We have to perform them separately // because displacement map and normal map usually have different bit depth. // Final pass for displacement. graphicsDevice.SetRenderTarget(target0); if (_renderTargetBindings[1].RenderTarget == tempPing1) { _parameterSourceTexture0.SetValue(tempPing0); } else { _parameterSourceTexture0.SetValue(tempPong0); } _passFftDisplacement.Apply(); graphicsDevice.DrawFullScreenQuad(); // Final pass for normals. graphicsDevice.SetRenderTarget(target1); if (_renderTargetBindings[1].RenderTarget == tempPing1) { _parameterSourceTexture0.SetValue(tempPing1); } else { _parameterSourceTexture0.SetValue(tempPong1); } _passFftNormal.Apply(); graphicsDevice.DrawFullScreenQuad(); // Clean up. _renderTargetBindings[0] = default(RenderTargetBinding); _renderTargetBindings[1] = default(RenderTargetBinding); _parameterButterflyTexture.SetValue((Texture2D)null); _parameterSourceTexture0.SetValue((Texture2D)null); _parameterSourceTexture1.SetValue((Texture2D)null); renderTargetPool.Recycle(tempPing0); renderTargetPool.Recycle(tempPing1); renderTargetPool.Recycle(tempPong0); renderTargetPool.Recycle(tempPong1); savedRenderState.Restore(); // Reset the texture stages. If a floating point texture is set, we get exceptions // when a sampler with bilinear filtering is set. graphicsDevice.ResetTextures(); }
void Render() { // Clear targets _immediateContext.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); //_immediateContext.ClearRenderTargetView(renderView, ambient); _immediateContext.ClearRenderTargetView(gBufferLightView, Color4.Black); _immediateContext.ClearRenderTargetView(gBufferNormalView, Color4.Black); _immediateContext.ClearRenderTargetView(gBufferDiffuseView, Color4.Black); // Read collision object transforms, create geometry, etc. _meshFactory.InitInstancedRender(); // Light depth map pass _immediateContext.ClearDepthStencilView(lightDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); if (shadowsEnabled) { outputMerger.SetDepthStencilState(lightDepthStencilState); outputMerger.SetRenderTargets(lightDepthView); shadowGenPass.Apply(_immediateContext); OnRender(); shadowLightDepthBufferVar.SetResource(lightDepthRes); } // Render geometry (colors, normals, depth) to G-buffer outputMerger.SetDepthStencilState(depthState); outputMerger.SetTargets(depthView, gBufferViews); gBufferGenPass.Apply(_immediateContext); OnRender(); /* * if (IsDebugDrawEnabled) * { * debugDrawPass.Apply(_immediateContext); * (PhysicsContext.World.DebugDrawer as PhysicsDebugDraw).DrawDebugWorld(PhysicsContext.World); * } */ // Light accumulation to G-buffer if (deferredLightingEnabled) { outputMerger.SetBlendState(additiveBlendState); // Can't set depthView as render target and shader variable at the same time, // so early HW depth test is not available for light volumes. //outputMerger.SetTargets(depthView, gBufferLightView); outputMerger.SetTargets(gBufferLightView); RenderLights(); } // Render G-buffer outputMerger.SetBlendState(alphaBlendState); outputMerger.SetDepthStencilState(null); if (depthOfFieldEnabled) { outputMerger.SetTargets(gBufferPostProcessView); } else { outputMerger.SetTargets(renderView); } inputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; lightBufferVar.SetResource(lightBufferRes); normalBufferVar.SetResource(normalBufferRes); diffuseBufferVar.SetResource(diffuseBufferRes); depthMapVar.SetResource(depthBufferRes); //_immediateContext.ClearRenderTargetView(gBufferPostProcessView, Color4.Black); gBufferRenderPass.Apply(_immediateContext); _immediateContext.Draw(3, 0); if (depthOfFieldEnabled) { diffuseBufferVar.SetResource(postProcessBufferRes); outputMerger.SetTargets(gBufferPostProcessViewBlur1); gBufferPostProcessPass.Apply(_immediateContext); _immediateContext.Draw(3, 0); diffuseBufferVar.SetResource(postProcessBufferBlur1Res); outputMerger.SetTargets(gBufferPostProcessViewBlur2); gBufferPostProcessPass.Apply(_immediateContext); _immediateContext.Draw(3, 0); diffuseBufferVar.SetResource(postProcessBufferBlur2Res); outputMerger.SetTargets(gBufferPostProcessViewBlur1); gBufferPostProcessPass.Apply(_immediateContext); _immediateContext.Draw(3, 0); diffuseBufferVar.SetResource(postProcessBufferBlur1Res); outputMerger.SetTargets(gBufferPostProcessViewBlur2); gBufferPostProcessPass.Apply(_immediateContext); _immediateContext.Draw(3, 0); diffuseBufferVar.SetResource(postProcessBufferRes); normalBufferVar.SetResource(postProcessBufferBlur2Res); outputMerger.SetTargets(renderView); gBufferPostProcessPass2.Apply(_immediateContext); _immediateContext.Draw(3, 0); } // Render overlay Info.Render(); outputMerger.SetBlendState(alphaBlendState); diffuseBufferVar.SetResource(Info.OverlayBufferRes); gBufferOverlayPass.Apply(_immediateContext); _immediateContext.Draw(4, 0); _swapChain.Present(0, PresentFlags.None); }
/// <summary> /// Draws the specified effect pass onto the quad. The effect pass must have a pixel shader with the signature float2:TEXCOORD. /// </summary> /// <param name="effectPass">The effect pass.</param> public void Draw(EffectPass effectPass) { // Apply the Effect pass effectPass.Apply(); Draw(); }
protected override void OnProcess(RenderContext context) { var graphicsDevice = GraphicsService.GraphicsDevice; if (TextureHelper.IsFloatingPointFormat(context.SourceTexture.Format)) { graphicsDevice.SamplerStates[0] = SamplerState.PointClamp; } else { graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; } graphicsDevice.SetRenderTarget(context.RenderTarget); graphicsDevice.Viewport = context.Viewport; _viewportSizeParameter.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _sourceTextureParameter.SetValue(context.SourceTexture); _strengthParameter.SetValue(new Vector2(Strength, InterpolationParameter)); if (LookupTextureA == null && LookupTextureB == null) { if (_defaultLookupTexture == null) { _defaultLookupTexture = ConvertLookupTexture(CreateLookupTexture2D(graphicsDevice)); } Debug.Assert(_defaultLookupTexture != null, "Failed to create 3D lookup texture."); _lookupTexture0Parameter.SetValue(_defaultLookupTexture); _lookupTableSizeParameter.SetValue(_defaultLookupTexture.Width); _fullColorLookupPass.Apply(); } else if (LookupTextureA == null) { ApplyPassWithOneLookupTexture(LookupTextureB); } else if (LookupTextureB == null) { ApplyPassWithOneLookupTexture(LookupTextureA); } else { if (Numeric.AreEqual(InterpolationParameter, 0)) { ApplyPassWithOneLookupTexture(LookupTextureA); } else if (Numeric.AreEqual(InterpolationParameter, 1)) { ApplyPassWithOneLookupTexture(LookupTextureB); } else { _lookupTexture0Parameter.SetValue(LookupTextureA); _lookupTexture1Parameter.SetValue(LookupTextureB); _lookupTableSizeParameter.SetValue(LookupTextureA.Width); _lerpColorLookupPass.Apply(); } } graphicsDevice.DrawFullScreenQuad(); _sourceTextureParameter.SetValue((Texture2D)null); _lookupTexture0Parameter.SetValue((Texture2D)null); _lookupTexture1Parameter.SetValue((Texture2D)null); }
public override void Draw(GameTime gameTime) { Vector2 pos = new Vector2((GraphicsDevice.Viewport.Width - texture.Width) / 2, (GraphicsDevice.Viewport.Height - texture.Height) / 2); GraphicsDevice device = GraphicsDevice; //Draw hotspots on the first Render Target device.SetRenderTarget(renderTarget1); device.Clear(Color.Black); OurGame.SpriteBatch.Begin(); //get last drawn screen — if not first time in //fire is null first time in, and when device is lost (LoadGraphicsContent) if (fire != null) //render target has valid texture { OurGame.SpriteBatch.Draw(fire, Vector2.Zero, Color.White); } //draw hotspots for (int i = 0; i < device.Viewport.Width / hotSpotTexture.Width; i++) { OurGame.SpriteBatch.Draw(hotSpotTexture, new Vector2(i * hotSpotTexture.Width, device.Viewport.Height - hotSpotTexture.Height), colors[rand.Next(colors.Length)]); } OurGame.SpriteBatch.End(); //resolve what we just drew to our render target //and clear it out device.SetRenderTarget(null); // Transfer from first to second render target device.SetRenderTarget(renderTarget2); OurGame.SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); EffectPass pass = fireEffect.CurrentTechnique.Passes[0]; pass.Apply(); OurGame.SpriteBatch.Draw(renderTarget1, new Rectangle(0, offset, device.Viewport.Width, device.Viewport.Height - offset), Color.White); OurGame.SpriteBatch.End(); //resolve what we just drew to our render target //and clear it out device.SetRenderTarget(null); device.Clear(Color.Black); //set texture to render fire = renderTarget2; // Draw second render target onto the screen (back buffer) OurGame.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive); OurGame.SpriteBatch.Draw(texture, pos, Color.White); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, Color.White); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, Color.White); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, Color.White); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, null, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.FlipVertically, 0); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, null, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.FlipVertically, 0); OurGame.SpriteBatch.Draw(fire, Vector2.Zero, null, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.FlipVertically, 0); OurGame.SpriteBatch.End(); base.Draw(gameTime); }
public void PrepareClearGBuffer() { CurrentTechnique = Techniques["ClearGBuffer"]; clearGBufferPass.Apply(); }
/// <summary> /// 三大块:初始化设备、设置缓冲和管线等、渲染循环 /// </summary> private void DoCommonThings() { _renderForm = new RenderForm(); _renderForm.ClientSize = new System.Drawing.Size(800, 600); _renderForm.KeyDown += _renderForm_KeyDown; _renderForm.Text = "愉快的学习SharpDX"; _renderForm.Icon = null; _renderForm.ResizeBegin += (object sender, EventArgs e) => { _resized = true; }; _renderForm.MouseDown += _renderForm_MouseDown; _renderForm.MouseUp += _renderForm_MouseUp; _renderForm.MouseMove += _renderForm_MouseMove; ModeDescription backBufferDesc = new ModeDescription(_renderForm.ClientSize.Width, _renderForm.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm); SwapChainDescription swapChainDesc = new SwapChainDescription() { ModeDescription = backBufferDesc, SampleDescription = new SampleDescription(1, 0), Usage = Usage.RenderTargetOutput, BufferCount = 1, OutputHandle = _renderForm.Handle, IsWindowed = true, Flags = SwapChainFlags.AllowModeSwitch, SwapEffect = SwapEffect.Discard, }; D3D11.Device.CreateWithSwapChain( SharpDX.Direct3D.DriverType.Hardware, D3D11.DeviceCreationFlags.Debug, swapChainDesc, out _d3DDevice, out _swapChain); _d3DDeviceContext = _d3DDevice.ImmediateContext; using (var effectByteCode = ShaderBytecode.CompileFromFile("../../MyShader.fx", "fx_5_0", ShaderFlags.Debug | ShaderFlags.SkipOptimization)) { var effect = new Effect(_d3DDevice, effectByteCode); var technique = effect.GetTechniqueByName("LightTech"); //光照 mfxDirLight = effect.GetVariableByName("gDirLight"); mfxPointLight = effect.GetVariableByName("gPointLight"); mfxSpotLight = effect.GetVariableByName("gSpotLight"); mfxEyePosW = effect.GetVariableByName("gEyePosW"); //材质 mfxMaterial = effect.GetVariableByName("gMaterial"); //纹理 mfxShaderRSVar = effect.GetVariableByName("gTexture").AsShaderResource(); mfxTexTransform = effect.GetVariableByName("gTexTransform").AsMatrix(); //pass mfxPassW = technique.GetPassByName("P0"); mfxPassS = technique.GetPassByName("P1"); mfxPass = mfxPassS; mfxWorld = effect.GetVariableByName("gWorld").AsMatrix(); mfxWorldTranInv = effect.GetVariableByName("gWorldInvTranspose").AsMatrix(); mfxWorldViewProj = effect.GetVariableByName("gWorldViewProj").AsMatrix(); var passSignature = mfxPassW.Description.Signature; _inputShaderSignature = ShaderSignature.GetInputSignature(passSignature); } _inputLayout = new D3D11.InputLayout(_d3DDevice, _inputShaderSignature, _inputElementsForMesh); var VertexBuffer = D3D11.Buffer.Create <MyVertex>(_d3DDevice, BindFlags.VertexBuffer, mMeshData.Vertices.ToArray()); var IndexBuffer = D3D11.Buffer.Create <int>(_d3DDevice, BindFlags.IndexBuffer, mMeshData.Indices.ToArray()); ShaderRSV = Tools.CreateShaderResourceViewFromFile(_d3DDevice, System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "../../model/ydmy.jpg")); _d3DDeviceContext.InputAssembler.InputLayout = _inputLayout; _d3DDeviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; _d3DDeviceContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, Utilities.SizeOf <MyVertex>(), 0)); _d3DDeviceContext.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0); proj = Matrix.Identity; world = new Matrix[228]; for (int i = 0; i < 228; i++) { world[i] = Matrix.Identity; } //world[0] = Matrix.Identity; _resized = true; Texture2D backBuffer = null; RenderTargetView renderView = null; Texture2D depthBuffer = null; DepthStencilView depthView = null; long lastTime = 0; var clock = new System.Diagnostics.Stopwatch(); clock.Start(); int fpsCounter = 0; byte[] d; RenderLoop.Run(_renderForm, () => { view.Row1 = new Vector4(camRight, 0); view.Row2 = new Vector4(camUp, 0); view.Row3 = new Vector4(camLook, 0); view.Row4 = new Vector4(camPos, 1); view = Matrix.Invert(view); if (_resized) { Utilities.Dispose(ref backBuffer); Utilities.Dispose(ref renderView); Utilities.Dispose(ref depthBuffer); Utilities.Dispose(ref depthView); _swapChain.ResizeBuffers(swapChainDesc.BufferCount, _renderForm.ClientSize.Width, _renderForm.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); backBuffer = Texture2D.FromSwapChain <Texture2D>(_swapChain, 0); renderView = new RenderTargetView(_d3DDevice, backBuffer); depthBuffer = new Texture2D(_d3DDevice, new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, Width = _renderForm.ClientSize.Width, Height = _renderForm.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }); depthView = new DepthStencilView(_d3DDevice, depthBuffer); _d3DDeviceContext.Rasterizer.SetViewport(new Viewport(0, 0, _renderForm.ClientSize.Width, _renderForm.ClientSize.Height, 0.0f, 1.0f)); _d3DDeviceContext.OutputMerger.SetTargets(depthView, renderView); proj = Matrix.PerspectiveFovLH((float)Math.PI / 4f, _renderForm.ClientSize.Width / (float)_renderForm.ClientSize.Height, 0.1f, 1000f); _resized = false; } _d3DDeviceContext.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); _d3DDeviceContext.ClearRenderTargetView(renderView, SharpDX.Color.Black); var viewProj = Matrix.Multiply(view, proj); //设置平行光 d = Tools.StructureToBytes(mDirLight); Array.Copy(d, 0, _dirLightArray, 0, Marshal.SizeOf(typeof(DirectionalLight))); using (var dataStream = DataStream.Create(_dirLightArray, false, false)) { mfxDirLight.SetRawValue(dataStream, _dirLightArray.Length); } //纹理贴图:画正方体 //world[0] = Matrix.RotationAxis(Vector3.UnitY, clock.ElapsedMilliseconds / 1000f); for (int i = 0; i < mSubMeshData.Length - 1; i++) { world[i] = Matrix.RotationAxis(Vector3.UnitY, clock.ElapsedMilliseconds / 1000f); worldViewProj = world[i] * viewProj; //像素着色器计算需要的变量 mfxWorld.SetMatrix(world[i]); mfxWorldTranInv.SetMatrix(Tools.InverseTranspose(world[i])); mfxWorldViewProj.SetMatrix(worldViewProj); //设置材质 d = Tools.StructureToBytes(mMatArray[0]); Array.Copy(d, 0, _matArray, 0, Marshal.SizeOf(typeof(Material))); // 结构体大小 using (var dataStream = DataStream.Create(_matArray, false, false)) { mfxMaterial.SetRawValue(dataStream, _matArray.Length); } //设置纹理 mfxShaderRSVar.SetResource(ShaderRSV); mfxTexTransform.SetMatrix(Matrix.Identity); mfxPass.Apply(_d3DDeviceContext); _d3DDeviceContext.DrawIndexed(mSubMeshData[i].Indices.Length, indOff[i], vexOff[i]); } //平面 worldViewProj = Matrix.Identity * viewProj; //像素着色器计算需要的变量 mfxWorld.SetMatrix(Matrix.Identity); mfxWorldTranInv.SetMatrix(Tools.InverseTranspose(Matrix.Identity)); mfxWorldViewProj.SetMatrix(worldViewProj); //设置材质 d = Tools.StructureToBytes(mMatArray[0]); Array.Copy(d, 0, _matArray, 0, Marshal.SizeOf(typeof(Material))); // 结构体大小 using (var dataStream = DataStream.Create(_matArray, false, false)) { mfxMaterial.SetRawValue(dataStream, _matArray.Length); } //设置纹理 mfxShaderRSVar.SetResource(ShaderRSV); mfxTexTransform.SetMatrix(Matrix.Identity); mfxPass.Apply(_d3DDeviceContext); _d3DDeviceContext.DrawIndexed(mSubMeshData[228].Indices.Length, indOff[228], vexOff[228]); _swapChain.Present(0, PresentFlags.None); fpsCounter++; if (clock.ElapsedMilliseconds - lastTime >= 1000) { _renderForm.Text = "FPS:" + fpsCounter.ToString(); fpsCounter = 0; lastTime = clock.ElapsedMilliseconds; } }); }
public static void Render(Camera camera) { if (numTilesReady > 0) { GraphicsDevice device = BokuGame.bokuGame.GraphicsDevice; Debug.Assert(InGame.inGame.renderEffects == InGame.RenderEffect.Normal); Parameter(EffectParams.WorldViewProjMatrix).SetValue(camera.ViewProjectionMatrix); SetupWater(); #if !ALLOW_BLOOM ShaderGlobals.FixExplicitBloom(0); #endif // !ALLOW_BLOOM #if !LLLLLL //device.RasterizerState = UI2D.Shared.RasterStateWireframe; device.Indices = indices; device.SetVertexBuffer(verts); EffectTechnique tech = effect.CurrentTechnique; int numPasses = tech.Passes.Count; for (int i = 0; i < numPasses; ++i) { EffectPass pass = tech.Passes[i]; pass.Apply(); int firstVert = lastCulled * 4; int lastVert = nextVert; if (firstVert < lastVert) { int numVerts = lastVert - firstVert; int firstTri = firstVert / 4 * 2; int numTris = numVerts * 2 / 4; int firstIndex = firstTri * 3; device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, firstVert, numVerts, firstIndex, numTris); } else { int firstTopTri = firstVert / 4 * 2; int numTopVerts = kMaxVerts - firstVert; int numTopTris = numTopVerts * 2 / 4; int firstTopIndex = firstTopTri * 3; if (numTopTris > 0) { device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, firstVert, numTopVerts, firstTopIndex, numTopTris); } int firstBotVert = 0; int numBotVerts = lastVert; int numBotTris = numBotVerts / 4 * 2; int firstBotIndex = 0; if (numBotTris > 0) { device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, firstBotVert, numBotVerts, firstBotIndex, numBotTris); } } } //device.RasterizerState = RasterizerState.CullCounterClockwise; #if !ALLOW_BLOOM ShaderGlobals.ReleaseExplicitBloom(); #endif // !ALLOW_BLOOM #endif /// LLLLLL } }
/// <summary> /// Draws the specified effect pass onto the quad. The effect pass must have a pixel shader with the signature float2:TEXCOORD. /// </summary> /// <param name="effectPass">The effect pass.</param> /// <param name="fullScreenTriangle">if set to <c>true</c> to draw an optimized full screen triangle as a full screen quad.</param> public void Draw(EffectPass effectPass, bool fullScreenTriangle = false) { ResetShaderStages(); // Apply the Effect pass effectPass.Apply(); Draw(fullScreenTriangle); // Unapply this effect effectPass.UnApply(); }
public void ApplyLightning(GraphicsDevice g, Texture2D tColor) { g.Textures[1] = tColor; g.SamplerStates[1] = SamplerState.LinearWrap; fxPassLightning.Apply(); }
public void DrawFloor(GraphicsDevice gd, Effect e, WorldZoom zoom, WorldRotation rot, List <Texture2D> roommaps, HashSet <sbyte> floors, EffectPass pass, Matrix?lightWorld = null, WorldState state = null, int minFloor = 0) { //assumes the effect and all its parameters have been set up already //we just need to get the right texture and offset var flrContent = Content.Content.Get().WorldFloors; e.Parameters["TexOffset"].SetValue(new Vector2());// TexOffset[zoom]*-1f); var tmat = TexMat[rot]; e.Parameters["TexMatrix"].SetValue(tmat); var f = 0; foreach (var floor in Floors) { if (!floors.Contains((sbyte)(f++))) { continue; } Matrix worldmat; if (lightWorld == null) { worldmat = Matrix.CreateTranslation(0, 2.95f * (f - 1) * 3 - Bp.BaseAlt * Bp.TerrainFactor * 3, 0); } else { worldmat = Matrix.CreateScale(1, 0, 1) * Matrix.CreateTranslation(0, 1f * (f - (1 + minFloor)), 0) * lightWorld.Value; e.Parameters["DiffuseColor"].SetValue(new Vector4(1, 1, 1, 1) * (float)(6 - (f - (minFloor))) / 5f); } e.Parameters["World"].SetValue(worldmat); e.Parameters["Level"].SetValue((float)(f - ((lightWorld == null)?0.999f:1f))); if (roommaps != null) { e.Parameters["RoomMap"].SetValue(roommaps[f - 1]); } foreach (var type in floor.GroupForTileType) { bool water = false; var dat = type.Value.GPUData; if (dat == null) { continue; } gd.Indices = dat; var id = type.Key; if (id == 0) { e.Parameters["UseTexture"].SetValue(false); e.Parameters["IgnoreColor"].SetValue(false); } else { Texture2D SPR = null; if (id >= 65503) { if (id == 65503) { water = true; var airTiles = TextureGenerator.GetAirTiles(gd); switch (zoom) { case WorldZoom.Far: SPR = airTiles[2]; break; case WorldZoom.Medium: SPR = airTiles[1]; break; case WorldZoom.Near: SPR = airTiles[0]; break; } } else { e.Parameters["Water"].SetValue(true); var pool = id >= 65520; water = true; if (!pool) { e.Parameters["UseTexture"].SetValue(false); e.Parameters["IgnoreColor"].SetValue(false); //quickly draw under the water pass.Apply(); gd.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, type.Value.GeomForOffset.Count * 2); e.Parameters["UseTexture"].SetValue(true); e.Parameters["IgnoreColor"].SetValue(true); if (lightWorld == null) { e.Parameters["World"].SetValue(worldmat * Matrix.CreateTranslation(0, 0.05f, 0)); } id -= 65504; } else { id -= 65520; } e.Parameters["TexMatrix"].SetValue(CounterTexMat[rot]); var roti = (int)rot; roti = (4 - roti) % 4; id = (ushort)(((id << roti) & 15) | (id >> (4 - roti))); //pools & water are drawn with special logic, and may also be drawn slightly above the ground. int baseSPR; int frameNum = 0; if (state != null) { switch (zoom) { case WorldZoom.Far: baseSPR = (pool) ? 0x400 : 0x800; frameNum = (pool) ? 0 : 2; SPR = state._2D.GetTexture(flrContent.GetGlobalSPR((ushort)(baseSPR + id)).Frames[frameNum]); break; case WorldZoom.Medium: baseSPR = (pool) ? 0x410 : 0x800; frameNum = (pool) ? 0 : 1; SPR = state._2D.GetTexture(flrContent.GetGlobalSPR((ushort)(baseSPR + id)).Frames[frameNum]); break; default: baseSPR = (pool) ? 0x420 : 0x800; SPR = state._2D.GetTexture(flrContent.GetGlobalSPR((ushort)(baseSPR + id)).Frames[frameNum]); break; } } } } else { var flr = flrContent.Get(id); if (flr == null) { continue; } if (state != null) { switch (zoom) { case WorldZoom.Far: SPR = state._2D.GetTexture(flr.Far.Frames[0]); break; case WorldZoom.Medium: SPR = state._2D.GetTexture(flr.Medium.Frames[0]); break; default: SPR = state._2D.GetTexture(flr.Near.Frames[0]); break; } } } //e.Parameters["UseTexture"].SetValue(SPR != null); e.Parameters["BaseTex"].SetValue(SPR); } pass.Apply(); gd.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, type.Value.GeomForOffset.Count * 2); if (id == 0) { e.Parameters["UseTexture"].SetValue(true); e.Parameters["IgnoreColor"].SetValue(true); } if (water) { e.Parameters["World"].SetValue(worldmat); e.Parameters["TexMatrix"].SetValue(tmat); e.Parameters["Water"].SetValue(false); } } } e.Parameters["Water"].SetValue(false); }
/// <summary> /// Draws the current frame /// </summary> public void Draw() { //try { int index = 0; // Update all the effects with the palette and world and draw the meshes for (int i = 0; i < numMeshes; i++) { ModelMesh mesh = model.Meshes[i]; // The starting index for the modelEffects array int effectStartIndex = index; if (matrixPaletteParams[index] != null) { foreach (Effect effect in mesh.Effects) { worldParams[index].SetValue(world); matrixPaletteParams[index].SetValue(palette[i]); index++; } } else { foreach (Effect effect in mesh.Effects) { worldParams[index].SetValue(pose[mesh.ParentBone.Index] * world); index++; } } int numParts = mesh.MeshParts.Count - 2; // HACK: -1 added if (numParts <= 0) { continue; } for (int j = 0; j < numParts; j++) { ModelMeshPart currentPart = mesh.MeshParts[j]; if (currentPart.NumVertices == 0 || currentPart.PrimitiveCount == 0) { continue; } Effect currentEffect = modelEffects[effectStartIndex + j]; GraphicsDevice device = currentPart.VertexBuffer.GraphicsDevice; device.Indices = currentPart.IndexBuffer; /*device.VertexDeclaration = currentPart.VertexDeclaration; * device.Vertices[0].SetSource(mesh.VertexBuffer, currentPart.StreamOffset, * currentPart.VertexStride);*/ device.SetVertexBuffer(currentPart.VertexBuffer, currentPart.VertexOffset); //currentEffect.Begin(); EffectPassCollection passes = currentEffect.CurrentTechnique.Passes; int numPasses = passes.Count; for (int k = 0; k < numPasses; k++) { EffectPass pass = passes[k]; pass.Apply(); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, currentPart.NumVertices, currentPart.StartIndex, currentPart.PrimitiveCount); //pass.End(); } //currentEffect.End(); } } } //catch (NullReferenceException) //{ // throw new InvalidOperationException("The effects on the model for a " + // "ModelAnimator were changed without calling ModelAnimator.InitializeEffectParams()."); //} //catch (InvalidCastException) //{ // throw new InvalidCastException("ModelAnimator has thrown an InvalidCastException. This is " + // "likely because the model uses too many bones for the matrix palette. The default palette size " // + "is 56 for windows and 40 for Xbox."); //} }
private void RenderTileCacheEntry(DeviceContext deviceContext, Camera camera, int datasetExtentDataSpaceX, int datasetExtentDataSpaceY, TileCacheEntry tileCacheEntry) { //Check if this tile is over the edge of the image var tileMinExtentX = tileCacheEntry.CenterDataSpace.X - (tileCacheEntry.ExtentDataSpace.X / 2f); var tileMinExtentY = tileCacheEntry.CenterDataSpace.Y - (tileCacheEntry.ExtentDataSpace.Y / 2f); var tileMaxExtentX = tileCacheEntry.CenterDataSpace.X + (tileCacheEntry.ExtentDataSpace.X / 2f); var tileMaxExtentY = tileCacheEntry.CenterDataSpace.Y + (tileCacheEntry.ExtentDataSpace.Y / 2f); var tileProportionClipX = 1f; var tileProportionClipY = 1f; if (datasetExtentDataSpaceX > 0 && tileMaxExtentX > datasetExtentDataSpaceX) { tileProportionClipX = 1 - ((tileMaxExtentX - datasetExtentDataSpaceX) / (tileMaxExtentX - tileMinExtentX)); tileMaxExtentX = datasetExtentDataSpaceX; } if (datasetExtentDataSpaceY > 0 && tileMaxExtentY > datasetExtentDataSpaceY) { tileProportionClipY = 1 - ((tileMaxExtentY - datasetExtentDataSpaceY) / (tileMaxExtentY - tileMinExtentY)); tileMaxExtentY = datasetExtentDataSpaceY; } var p1 = new Vector3(tileMinExtentX, tileMinExtentY, 0.5f); var p2 = new Vector3(tileMinExtentX, tileMaxExtentY, 0.5f); var p3 = new Vector3(tileMaxExtentX, tileMaxExtentY, 0.5f); var p4 = new Vector3(tileMaxExtentX, tileMinExtentY, 0.5f); var t1 = new Vector3(0f, 0f, 0f); var t2 = new Vector3(0f, tileProportionClipY, 0f); var t3 = new Vector3(tileProportionClipX, tileProportionClipY, 0f); var t4 = new Vector3(tileProportionClipX, 0f, 0f); DataBox databox; databox = deviceContext.MapSubresource(mPositionVertexBuffer, 0, QUAD_NUM_VERTICES * POSITION_NUM_COMPONENTS_PER_VERTEX * POSITION_NUM_BYTES_PER_COMPONENT, MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None); databox.Data.Write(p1); databox.Data.Write(p4); databox.Data.Write(p2); databox.Data.Write(p3); deviceContext.UnmapSubresource(mPositionVertexBuffer, 0); databox = deviceContext.MapSubresource(mTexCoordVertexBuffer, 0, QUAD_NUM_VERTICES * TEXCOORD_NUM_COMPONENTS_PER_VERTEX * TEXCOORD_NUM_BYTES_PER_COMPONENT, MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None); databox.Data.Write(t1); databox.Data.Write(t4); databox.Data.Write(t2); databox.Data.Write(t3); deviceContext.UnmapSubresource(mTexCoordVertexBuffer, 0); deviceContext.InputAssembler.InputLayout = mInputLayout; deviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; deviceContext.InputAssembler.SetVertexBuffers(POSITION_SLOT, new VertexBufferBinding(mPositionVertexBuffer, POSITION_NUM_COMPONENTS_PER_VERTEX * POSITION_NUM_BYTES_PER_COMPONENT, 0)); deviceContext.InputAssembler.SetVertexBuffers(TEXCOORD_SLOT, new VertexBufferBinding(mTexCoordVertexBuffer, TEXCOORD_NUM_COMPONENTS_PER_VERTEX * TEXCOORD_NUM_BYTES_PER_COMPONENT, 0)); mEffect.GetVariableByName("gSourceTexture3D").AsResource().SetResource(tileCacheEntry.D3D11CudaTextures.Get("SourceMap")); if (mTileManager.SegmentationLoaded) { //if ( tileCacheEntry.D3D11CudaTextures.Internal.ContainsKey( "IdMap" ) ) //{ // mEffect.GetVariableByName( "gIdTexture3D" ).AsResource().SetResource( tileCacheEntry.D3D11CudaTextures.Get( "IdMap" ) ); //} //else //{ // System.Console.WriteLine("Warning: expected IdMap not found."); //} mEffect.GetVariableByName("gIdTexture3D").AsResource().SetResource(tileCacheEntry.D3D11CudaTextures.Get("IdMap")); mEffect.GetVariableByName("gIdColorMapBuffer").AsResource().SetResource(mTileManager.Internal.GetIdColorMap()); mEffect.GetVariableByName("gLabelIdMapBuffer").AsResource().SetResource(mTileManager.Internal.GetLabelIdMap()); mEffect.GetVariableByName("gIdConfidenceMapBuffer").AsResource().SetResource(mTileManager.Internal.GetIdConfidenceMap()); } mEffect.GetVariableByName("gTransform").AsMatrix().SetMatrix(camera.GetLookAtMatrix() * camera.GetProjectionMatrix()); mEffect.GetVariableByName("gSegmentationRatio").AsScalar().Set(mTileManager.SegmentationVisibilityRatio); mEffect.GetVariableByName("gBoundaryLinesVisible").AsScalar().Set(mTileManager.ShowBoundaryLines); mEffect.GetVariableByName("gSelectedSegmentId").AsScalar().Set(mTileManager.SelectedSegmentId); mEffect.GetVariableByName("gMouseOverSegmentId").AsScalar().Set(mTileManager.MouseOverSegmentId); mPass.Apply(deviceContext); deviceContext.Draw(QUAD_NUM_VERTICES, 0); //mDebugRenderer.RenderQuadWireframeOnly( deviceContext, p1, p2, p3, p4, new Vector3( 1, 0, 0 ), camera ); }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <summary> /// Computes the intersection of <see cref="MeshNode"/>s. /// </summary> /// <param name="meshNodePairs"> /// A collection of <see cref="MeshNode"/> pairs.The renderer computes the intersection volume /// of each pair. /// </param> /// <param name="color">The diffuse color used for the intersection.</param> /// <param name="alpha">The opacity of the intersection.</param> /// <param name="maxConvexity"> /// The maximum convexity of the submeshes. A convex mesh has a convexity of 1. A concave mesh /// has a convexity greater than 1. Convexity is the number of layers required for depth peeling /// (= the number of front face layers when looking at the object). /// </param> /// <param name="context">The render context.</param> /// <remarks> /// <para> /// This method renders an off-screen image (color and depth) of the intersection volume. This /// operation destroys the currently set render target and depth/stencil buffer. /// </para> /// </remarks> /// <exception cref="ObjectDisposedException"> /// The <see cref="IntersectionRenderer"/> has already been disposed. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="meshNodePairs"/> or <see cref="context"/> is /// <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// The convexity must be greater than 0. /// </exception> /// <exception cref="GraphicsException"> /// Invalid render context: Graphics service is not set. /// </exception> /// <exception cref="GraphicsException"> /// Invalid render context: Wrong graphics device. /// </exception> /// <exception cref="GraphicsException"> /// Invalid render context: Scene is not set. /// </exception> /// <exception cref="GraphicsException"> /// Invalid render context: Camera node needs to be set in render context. /// </exception> public void ComputeIntersection(IEnumerable <Pair <MeshNode> > meshNodePairs, Vector3F color, float alpha, float maxConvexity, RenderContext context) { if (_isDisposed) { throw new ObjectDisposedException("IntersectionRenderer has already been disposed."); } if (meshNodePairs == null) { throw new ArgumentNullException("meshNodePairs"); } if (maxConvexity < 1) { throw new ArgumentOutOfRangeException("maxConvexity", "The max convexity must be greater than 0."); } if (context == null) { throw new ArgumentNullException("context"); } if (context.GraphicsService == null) { throw new GraphicsException("Invalid render context: Graphics service is not set."); } if (_graphicsService != context.GraphicsService) { throw new GraphicsException("Invalid render context: Wrong graphics service."); } if (context.CameraNode == null) { throw new GraphicsException("Camera node needs to be set in render context."); } if (context.Scene == null) { throw new GraphicsException("A scene needs to be set in the render context."); } // Create 2 ordered pairs for each unordered pair. _pairs.Clear(); foreach (var pair in meshNodePairs) { if (pair.First == null || pair.Second == null) { continue; } // Frustum culling. if (!context.Scene.HaveContact(pair.First, context.CameraNode)) { continue; } if (!context.Scene.HaveContact(pair.Second, context.CameraNode)) { continue; } _pairs.Add(new Pair <MeshNode, MeshNode>(pair.First, pair.Second)); _pairs.Add(new Pair <MeshNode, MeshNode>(pair.Second, pair.First)); } var renderTargetPool = _graphicsService.RenderTargetPool; if (_pairs.Count == 0) { renderTargetPool.Recycle(_intersectionImage); _intersectionImage = null; return; } // Color and alpha are applied in RenderIntersection(). _color = color; _alpha = alpha; var graphicsDevice = _graphicsService.GraphicsDevice; // Save original render states. var originalBlendState = graphicsDevice.BlendState; var originalDepthStencilState = graphicsDevice.DepthStencilState; var originalRasterizerState = graphicsDevice.RasterizerState; var originalScissorRectangle = graphicsDevice.ScissorRectangle; // Get offscreen render targets. var viewport = context.Viewport; viewport.X = 0; viewport.Y = 0; viewport.Width = (int)(viewport.Width / DownsampleFactor); viewport.Height = (int)(viewport.Height / DownsampleFactor); var renderTargetFormat = new RenderTargetFormat(viewport.Width, viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8); // Try to reuse any existing render targets. // (Usually they are recycled in RenderIntersection()). var currentScene = _intersectionImage; if (currentScene == null || !renderTargetFormat.IsCompatibleWith(currentScene)) { currentScene.SafeDispose(); currentScene = renderTargetPool.Obtain2D(renderTargetFormat); } var lastScene = renderTargetPool.Obtain2D(renderTargetFormat); // Set shared effect parameters. var cameraNode = context.CameraNode; var view = (Matrix)cameraNode.View; var projection = cameraNode.Camera.Projection; var near = projection.Near; var far = projection.Far; _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height)); // The DepthEpsilon has to be tuned if depth peeling does not work because // of numerical problems equality z comparisons. _parameterCameraParameters.SetValue(new Vector3(near, far - near, 0.0000001f)); _parameterView.SetValue(view); _parameterProjection.SetValue((Matrix)projection); var defaultTexture = _graphicsService.GetDefaultTexture2DBlack(); // Handle all pairs. bool isFirstPass = true; while (true) { // Find a mesh node A and all mesh nodes to which it needs to be clipped. MeshNode meshNodeA = null; _partners.Clear(); for (int i = 0; i < _pairs.Count; i++) { var pair = _pairs[i]; if (pair.First == null) { continue; } if (meshNodeA == null) { meshNodeA = pair.First; } if (pair.First == meshNodeA) { _partners.Add(pair.Second); // Remove this pair. _pairs[i] = new Pair <MeshNode, MeshNode>(); } } // Abort if we have handled all pairs. if (meshNodeA == null) { break; } var worldTransformA = (Matrix)(meshNodeA.PoseWorld * Matrix44F.CreateScale(meshNodeA.ScaleWorld)); if (EnableScissorTest) { // Scissor rectangle of A. var scissorA = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, meshNodeA); // Union of scissor rectangles of partners. Rectangle partnerRectangle = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, _partners[0]); for (int i = 1; i < _partners.Count; i++) { var a = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, _partners[i]); partnerRectangle = Rectangle.Union(partnerRectangle, a); } // Use intersection of A and partners. graphicsDevice.ScissorRectangle = Rectangle.Intersect(scissorA, partnerRectangle); // We store the union of all scissor rectangles for use in RenderIntersection(). if (isFirstPass) { _totalScissorRectangle = graphicsDevice.ScissorRectangle; } else { _totalScissorRectangle = Rectangle.Union(_totalScissorRectangle, graphicsDevice.ScissorRectangle); } } // Depth peeling of A. for (int layer = 0; layer < maxConvexity; layer++) { // Set and clear render target. graphicsDevice.SetRenderTarget(currentScene); graphicsDevice.Clear(new Color(1, 1, 1, 0)); // RGB = "a large depth", A = "empty area" // Render a depth layer of A. graphicsDevice.DepthStencilState = DepthStencilStateWriteLess; graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = EnableScissorTest ? CullCounterClockwiseScissor : RasterizerState.CullCounterClockwise; _parameterWorld.SetValue(worldTransformA); _parameterTexture.SetValue((layer == 0) ? defaultTexture : lastScene); _passPeel.Apply(); foreach (var submesh in meshNodeA.Mesh.Submeshes) { submesh.Draw(); } // Render partners to set stencil. graphicsDevice.DepthStencilState = DepthStencilStateOnePassStencilFail; graphicsDevice.BlendState = BlendStateNoWrite; graphicsDevice.RasterizerState = EnableScissorTest ? CullNoneScissor : RasterizerState.CullNone; foreach (var partner in _partners) { _parameterWorld.SetValue((Matrix)(partner.PoseWorld * Matrix44F.CreateScale(partner.ScaleWorld))); _passMark.Apply(); foreach (var submesh in partner.Mesh.Submeshes) { submesh.Draw(); } } // Clear depth buffer. Leave stencil buffer unchanged. graphicsDevice.Clear(ClearOptions.DepthBuffer, new Color(0, 1, 0), 1, 0); // Render A to compute lighting. graphicsDevice.DepthStencilState = DepthStencilStateStencilNotEqual0; graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = EnableScissorTest ? CullCounterClockwiseScissor : RasterizerState.CullCounterClockwise; _parameterWorld.SetValue(worldTransformA); _passDraw.Apply(); foreach (var submesh in meshNodeA.Mesh.Submeshes) { submesh.Draw(); } // Combine last intersection image with current. if (!isFirstPass) { graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = EnableScissorTest ? CullNoneScissor : RasterizerState.CullNone; _parameterTexture.SetValue(lastScene); _passCombine.Apply(); graphicsDevice.DrawFullScreenQuad(); } isFirstPass = false; // ----- Swap render targets. MathHelper.Swap(ref lastScene, ref currentScene); } } // Store final images for RenderIntersection. _intersectionImage = lastScene; // Scale scissor rectangle back to full-screen resolution. if (DownsampleFactor > 1) { _totalScissorRectangle.X = (int)(_totalScissorRectangle.X * DownsampleFactor); _totalScissorRectangle.Y = (int)(_totalScissorRectangle.Y * DownsampleFactor); _totalScissorRectangle.Width = (int)(_totalScissorRectangle.Width * DownsampleFactor); _totalScissorRectangle.Height = (int)(_totalScissorRectangle.Height * DownsampleFactor); } // Restore original render state. graphicsDevice.BlendState = originalBlendState ?? BlendState.Opaque; graphicsDevice.DepthStencilState = originalDepthStencilState ?? DepthStencilState.Default; graphicsDevice.RasterizerState = originalRasterizerState ?? RasterizerState.CullCounterClockwise; graphicsDevice.ScissorRectangle = originalScissorRectangle; renderTargetPool.Recycle(currentScene); _partners.Clear(); _pairs.Clear(); }
public void Activate() { _pass.Apply(); CurrentProgram = _effect; }
public void DrawAmbientOcclusion() { _ssaoPass.Apply(); _quadRenderer.RenderQuad(_graphicsDevice, -Vector2.One, Vector2.One); }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } context.Validate(_effect); context.ThrowIfCameraMissing(); context.ThrowIfGBuffer0Missing(); // Fog is not used in all games. --> Early out, if possible. int numberOfNodes = nodes.Count; if (nodes.Count == 0) { return; } if (nodes.Count > 1) { // Get a sorted list of all fog nodes. if (_fogNodes == null) { _fogNodes = new List <SceneNode>(); } _fogNodes.Clear(); for (int i = 0; i < numberOfNodes; i++) { var node = nodes[i] as FogNode; if (node != null) { _fogNodes.Add(node); node.SortTag = node.Priority; } } // Sort ascending. (Fog with lower priority is rendered first.) // Note: Since this list is a list of SceneNodes, we use the AscendingNodeComparer // instead of the AscendingFogNodeComparer. The Priority was written to the SortTag, // so this will work. _fogNodes.Sort(AscendingNodeComparer.Instance); nodes = _fogNodes; numberOfNodes = _fogNodes.Count; } var graphicsDevice = _effect.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; graphicsDevice.BlendState = BlendState.AlphaBlend; var viewport = graphicsDevice.Viewport; _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height)); var cameraNode = context.CameraNode; var cameraPose = cameraNode.PoseWorld; GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, _cameraFrustumFarCorners); // Convert frustum far corners from view space to world space. for (int i = 0; i < _cameraFrustumFarCorners.Length; i++) { _cameraFrustumFarCorners[i] = (Vector3)cameraPose.ToWorldDirection((Vector3F)_cameraFrustumFarCorners[i]); } _parameterFrustumCorners.SetValue(_cameraFrustumFarCorners); _parameterGBuffer0.SetValue(context.GBuffer0); // Update SceneNode.LastFrame for all visible nodes. int frame = context.Frame; cameraNode.LastFrame = frame; bool directionalLightIsSet = false; float scatteringSymmetryStrength = 1; for (int i = 0; i < numberOfNodes; i++) { var node = nodes[i] as FogNode; if (node == null) { continue; } // FogNode is visible in current frame. node.LastFrame = frame; var fog = node.Fog; if (fog.Density <= Numeric.EpsilonF) { continue; } // Compute actual density and falloff. float fogDensity = fog.Density; float heightFalloff = fog.HeightFalloff; // In previous versions, we gave FogDensity * 2^(-h*y) to the effect. Following code // avoids numerical problems where this value is numerically 0. This is now handled // in the shader. //if (!Numeric.IsZero(heightFalloff)) //{ // float cameraDensity = (float)Math.Pow(2, -heightFalloff * cameraPose.Position.Y); // // Trick: If the heightFalloff is very large, the e^x function can quickly reach // // the float limit! If this happens, the shader will not compute any fog and this // // looks like the fog disappears. To avoid this problem we reduce the heightFalloff // // to keep the result of e^x always within floating point range. // const float Limit = 1e-37f; // if (cameraDensity < Limit) // { // heightFalloff = (float)Math.Log(Limit) / -cameraPose.Position.Y / ConstantsF.Ln2; // cameraDensity = Limit; // } // // Compute actual fog density. // // fogDensity is at world space height 0. If the fog node is on another height, // // we change the fogDensity. // fogDensity *= (float)Math.Pow(2, -heightFalloff * (-node.PoseWorld.Position.Y)); // // Combine camera and fog density. // fogDensity *= cameraDensity; //} _parameterFogParameters.SetValue(new Vector4(fog.Start, fog.End, fogDensity, heightFalloff)); _parameterColor0.SetValue((Vector4)fog.Color0); _parameterColor1.SetValue((Vector4)fog.Color1); // Compute world space reference heights. var fogBaseHeight = node.PoseWorld.Position.Y; var height0 = fogBaseHeight + fog.Height0; var height1 = fogBaseHeight + fog.Height1; // Avoid division by zero in the shader. if (Numeric.AreEqual(height0, height1)) { height1 = height0 + 0.0001f; } _parameterHeights.SetValue(new Vector4( cameraNode.PoseWorld.Position.Y, fogBaseHeight, height0, height1)); var scatteringSymmetry = fog.ScatteringSymmetry; bool useScatteringSymmetry = !scatteringSymmetry.IsNumericallyZero; if (useScatteringSymmetry) { if (!directionalLightIsSet) { scatteringSymmetryStrength = SetDirectionalLightParameter(context, cameraNode); directionalLightIsSet = true; } } if (!useScatteringSymmetry || Numeric.IsZero(scatteringSymmetryStrength)) { // No phase function. if (Numeric.IsZero(heightFalloff)) { _passFog.Apply(); } else { _passFogWithHeightFalloff.Apply(); } } else { // Use phase function. // Set parameters for phase function. _parameterScatteringSymmetry.SetValue((Vector3)scatteringSymmetry * scatteringSymmetryStrength); if (Numeric.IsZero(heightFalloff)) { _passFogWithPhase.Apply(); } else { _passFogWithHeightFalloffWithPhase.Apply(); } } graphicsDevice.DrawFullScreenQuad(); } if (_fogNodes != null) { _fogNodes.Clear(); } savedRenderState.Restore(); }
/// <summary> /// Draws the specified effect pass onto the quad. The effect pass must have a pixel shader with the signature float2:TEXCOORD. /// </summary> /// <param name="effectPass">The effect pass.</param> public void Draw(EffectPass effectPass) { ResetShaderStages(); // Apply the Effect pass effectPass.Apply(); Draw(); // Unapply this effect effectPass.UnApply(); }
public void DrawInstancedPrimitivesVisualTest() { VertexBuffer vertexBuffer = null; IndexBuffer indexBuffer = null; VertexBuffer instanceVertexBuffer = null; Matrix[] worldTransforms = null; EffectPass pass = null; Game.LoadContentWith += (sender, e) => { // Create vertex and index buffer for a quad. var vertices = new[] { new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)), new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0)), new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)), new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)), }; vertexBuffer = new VertexBuffer( Game.GraphicsDevice, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.None); vertexBuffer.SetData(vertices); var indices = new ushort[] { 0, 1, 2, 1, 3, 2 }; indexBuffer = new IndexBuffer(Game.GraphicsDevice, IndexElementSize.SixteenBits, 6, BufferUsage.None); indexBuffer.SetData(indices); // Create vertex buffer with instance data. worldTransforms = new Matrix[8 * 4]; for (int i = 0; i < worldTransforms.Length; i++) { worldTransforms[i] = Matrix.CreateScale(0.4f) * Matrix.CreateRotationZ(0.05f * i) * Matrix.CreateTranslation(-3.5f + (i % 8), -1.5f + (int)(i / 8), 0); } VertexDeclaration instanceVertexDeclaration = new VertexDeclaration ( new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0), new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 1), new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 2), new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 3) ); instanceVertexBuffer = new VertexBuffer(Game.GraphicsDevice, instanceVertexDeclaration, worldTransforms.Length, BufferUsage.None); instanceVertexBuffer.SetData(worldTransforms); var view = Matrix.CreateLookAt(new Vector3(0, 0, 6), new Vector3(0, 0, 0), Vector3.Up); var projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, Game.GraphicsDevice.Viewport.AspectRatio, 0.1f, 100); var effect = AssetTestUtility.CompileEffect(Game.GraphicsDevice, "Instancing.fx"); effect.Parameters["View"].SetValue(view); effect.Parameters["Projection"].SetValue(projection); pass = effect.Techniques[0].Passes[0]; }; Game.DrawWith += (sender, e) => { Game.GraphicsDevice.Clear(Color.CornflowerBlue); Game.GraphicsDevice.SetVertexBuffers( new VertexBufferBinding(vertexBuffer, 0, 0), new VertexBufferBinding(instanceVertexBuffer, 0, 1)); Game.GraphicsDevice.Indices = indexBuffer; pass.Apply(); Game.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 6, 0, 2, worldTransforms.Length); }; //Game.Run(until: frameInfo => false); // There is a minor difference in the rasterization between XNA and DirectX. var similarity = 0.98f; RunSingleFrameTest(similarity); }
public void Draw(DeviceContext dc, Matrix viewProj, EffectPass pass) { var world = World; var wit = MathF.InverseTranspose(world); var wvp = world * viewProj; Effects.NormalMapFX.SetWorld(world); Effects.NormalMapFX.SetWorldInvTranspose(wit); Effects.NormalMapFX.SetWorldViewProj(wvp); Effects.NormalMapFX.SetTexTransform(Matrix.Identity); Effects.NormalMapFX.SetBoneTransforms(FinalTransforms); for (int i = 0; i < _model.SubsetCount; i++) { Effects.NormalMapFX.SetMaterial(_model.Materials[i]); Effects.NormalMapFX.SetDiffuseMap(_model.DiffuseMapSRV[i]); Effects.NormalMapFX.SetNormalMap(_model.NormalMapSRV[i]); pass.Apply(dc); _model.ModelMesh.Draw(dc, i); } }
public void DrawShadow(DeviceContext dc, EffectPass effectPass, Matrix viewProj) { var world = World; var wit = MathF.InverseTranspose(world); var wvp = world * viewProj; Effects.BuildShadowMapFX.SetWorld(world); Effects.BuildShadowMapFX.SetWorldInvTranspose(wit); Effects.BuildShadowMapFX.SetWorldViewProj(wvp); for (int i = 0; i < Model.SubsetCount; i++) { effectPass.Apply(dc); Model.ModelMesh.Draw(dc, i); } }