/// <inheritdoc/> public override unsafe void Prepare(RenderDrawContext context) { var blendValue = (selectionService?.DisplaySelectionMask ?? false) ? 1.0f : MathUtil.Clamp((1.0f - (float)clockSelection.Elapsed.TotalSeconds) / 1.0f, 0, 1); var perDrawValue = new PerDraw { FrontColor = ((Color3)Color.FromBgra(0xFFFFDC51)).ToColorSpace(Context.GraphicsDevice.ColorSpace), BackColor = ((Color3)Color.FromBgra(0xFFFF8300)).ToColorSpace(Context.GraphicsDevice.ColorSpace), ColorBlend = 0.3f * blendValue, AlphaBlend = 0.1f * blendValue }; foreach (var renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes) { var perDrawLayout = renderNode.RenderEffect.Reflection?.PerDrawLayout; if (perDrawLayout == null) { continue; } var perDrawDataOffset = perDrawLayout.GetConstantBufferOffset(this.perDrawData); if (perDrawDataOffset == -1) { continue; } var mappedCB = renderNode.Resources.ConstantBuffer.Data; var perDraw = (PerDraw *)((byte *)mappedCB + perDrawDataOffset); * perDraw = perDrawValue; } }
/// <param name="context"></param> /// <inheritdoc/> public unsafe override void Prepare(RenderDrawContext context) { // Compute WorldView, WorldViewProj var renderModelObjectInfoData = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); var renderModelViewInfoData = RootRenderFeature.RenderData.GetData(renderModelViewInfoKey); // Update PerFrame (time) // TODO Move that to RootEffectRenderFeature? foreach (var frameLayout in ((RootEffectRenderFeature)RootRenderFeature).FrameLayouts) { var timeOffset = frameLayout.GetConstantBufferOffset(time); if (timeOffset == -1) continue; var resourceGroup = frameLayout.Entry.Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perFrameTime = (PerFrameTime*)((byte*)mappedCB + timeOffset); perFrameTime->Time = (float)Context.Time.Total.TotalSeconds; perFrameTime->TimeStep = (float)Context.Time.Elapsed.TotalSeconds; } // Update PerView (View, Proj, etc...) for (int index = 0; index < RenderSystem.Views.Count; index++) { var view = RenderSystem.Views[index]; var viewFeature = view.Features[RootRenderFeature.Index]; // Compute WorldView and WorldViewProjection Dispatcher.ForEach(viewFeature.ViewObjectNodes, renderPerViewNodeReference => { var renderPerViewNode = RootRenderFeature.GetViewObjectNode(renderPerViewNodeReference); var renderModelFrameInfo = renderModelObjectInfoData[renderPerViewNode.ObjectNode]; var renderModelViewInfo = new RenderModelViewInfo(); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.View, out renderModelViewInfo.WorldView); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.ViewProjection, out renderModelViewInfo.WorldViewProjection); // TODO: Use ref locals or Utilities instead, to avoid double copy renderModelViewInfoData[renderPerViewNodeReference] = renderModelViewInfo; }); // Copy ViewProjection to PerView cbuffer foreach (var viewLayout in viewFeature.Layouts) { var viewProjectionOffset = viewLayout.GetConstantBufferOffset(this.view); if (viewProjectionOffset == -1) continue; var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perView = (PerView*)((byte*)mappedCB + viewProjectionOffset); // Fill PerView perView->View = view.View; Matrix.Invert(ref view.View, out perView->ViewInverse); perView->Projection = view.Projection; Matrix.Invert(ref view.Projection, out perView->ProjectionInverse); perView->ViewProjection = view.ViewProjection; perView->ProjScreenRay = new Vector2(-1.0f / view.Projection.M11, 1.0f / view.Projection.M22); // TODO GRAPHICS REFACTOR avoid cbuffer read perView->Eye = new Vector4(perView->ViewInverse.M41, perView->ViewInverse.M42, perView->ViewInverse.M43, 1.0f); } // Copy Camera to PerView cbuffer foreach (var viewLayout in viewFeature.Layouts) { var cameraOffset = viewLayout.GetConstantBufferOffset(camera); if (cameraOffset == -1) continue; var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perViewCamera = (PerViewCamera*)((byte*)mappedCB + cameraOffset); perViewCamera->NearClipPlane = view.NearClipPlane; perViewCamera->FarClipPlane = view.FarClipPlane; perViewCamera->ZProjection = CameraKeys.ZProjectionACalculate(view.NearClipPlane, view.FarClipPlane); perViewCamera->ViewSize = view.ViewSize; perViewCamera->AspectRatio = view.ViewSize.X / Math.Max(view.ViewSize.Y, 1.0f); } } // Update PerDraw (World, WorldViewProj, etc...) // Copy Entity.World to PerDraw cbuffer // TODO: Have a PerObject cbuffer? Dispatcher.ForEach(((RootEffectRenderFeature)RootRenderFeature).RenderNodes, (ref RenderNode renderNode) => { var perDrawLayout = renderNode.RenderEffect.Reflection.PerDrawLayout; if (perDrawLayout == null) return; var worldOffset = perDrawLayout.GetConstantBufferOffset(this.world); if (worldOffset == -1) return; var renderModelObjectInfo = renderModelObjectInfoData[renderNode.RenderObject.ObjectNode]; var renderModelViewInfo = renderModelViewInfoData[renderNode.ViewObjectNode]; var mappedCB = renderNode.Resources.ConstantBuffer.Data; var perDraw = (PerDraw*)((byte*)mappedCB + worldOffset); // Fill PerDraw var perDrawData = new PerDraw { World = renderModelObjectInfo.World, WorldView = renderModelViewInfo.WorldView, WorldViewProjection = renderModelViewInfo.WorldViewProjection }; Matrix.Invert(ref renderModelObjectInfo.World, out perDrawData.WorldInverse); Matrix.Transpose(ref perDrawData.WorldInverse, out perDrawData.WorldInverseTranspose); Matrix.Invert(ref renderModelViewInfo.WorldView, out perDrawData.WorldViewInverse); perDrawData.WorldScale = new Vector3( ((Vector3)renderModelObjectInfo.World.Row1).Length(), ((Vector3)renderModelObjectInfo.World.Row2).Length(), ((Vector3)renderModelObjectInfo.World.Row3).Length()); perDrawData.EyeMS = new Vector4(perDrawData.WorldInverse.M41, perDrawData.WorldInverse.M42, perDrawData.WorldInverse.M43, 1.0f); *perDraw = perDrawData; }); }
/// <param name="context"></param> /// <inheritdoc/> public unsafe override void Prepare(RenderDrawContext context) { // Compute WorldView, WorldViewProj var renderModelObjectInfoData = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); var renderModelViewInfoData = RootRenderFeature.RenderData.GetData(renderModelViewInfoKey); // Update PerFrame (time) // TODO Move that to RootEffectRenderFeature? foreach (var frameLayout in ((RootEffectRenderFeature)RootRenderFeature).FrameLayouts) { var timeOffset = frameLayout.GetConstantBufferOffset(time); if (timeOffset == -1) { continue; } var resourceGroup = frameLayout.Entry.Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perFrameTime = (PerFrameTime *)((byte *)mappedCB + timeOffset); perFrameTime->Time = (float)Context.Time.Total.TotalSeconds; perFrameTime->TimeStep = (float)Context.Time.Elapsed.TotalSeconds; } // Update PerView (View, Proj, etc...) for (int index = 0; index < RenderSystem.Views.Count; index++) { var view = RenderSystem.Views[index]; var viewFeature = view.Features[RootRenderFeature.Index]; // Compute WorldView and WorldViewProjection Dispatcher.ForEach(viewFeature.ViewObjectNodes, renderPerViewNodeReference => { var renderPerViewNode = RootRenderFeature.GetViewObjectNode(renderPerViewNodeReference); var renderModelFrameInfo = renderModelObjectInfoData[renderPerViewNode.ObjectNode]; var renderModelViewInfo = new RenderModelViewInfo(); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.View, out renderModelViewInfo.WorldView); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.ViewProjection, out renderModelViewInfo.WorldViewProjection); // TODO: Use ref locals or Utilities instead, to avoid double copy renderModelViewInfoData[renderPerViewNodeReference] = renderModelViewInfo; }); // Copy ViewProjection to PerView cbuffer foreach (var viewLayout in viewFeature.Layouts) { var viewProjectionOffset = viewLayout.GetConstantBufferOffset(this.view); if (viewProjectionOffset == -1) { continue; } var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perView = (PerView *)((byte *)mappedCB + viewProjectionOffset); // Fill PerView perView->View = view.View; Matrix.Invert(ref view.View, out perView->ViewInverse); perView->Projection = view.Projection; Matrix.Invert(ref view.Projection, out perView->ProjectionInverse); perView->ViewProjection = view.ViewProjection; perView->ProjScreenRay = new Vector2(-1.0f / view.Projection.M11, 1.0f / view.Projection.M22); // TODO GRAPHICS REFACTOR avoid cbuffer read perView->Eye = new Vector4(perView->ViewInverse.M41, perView->ViewInverse.M42, perView->ViewInverse.M43, 1.0f); } // Copy Camera to PerView cbuffer foreach (var viewLayout in viewFeature.Layouts) { var cameraOffset = viewLayout.GetConstantBufferOffset(camera); if (cameraOffset == -1) { continue; } var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perViewCamera = (PerViewCamera *)((byte *)mappedCB + cameraOffset); perViewCamera->NearClipPlane = view.NearClipPlane; perViewCamera->FarClipPlane = view.FarClipPlane; perViewCamera->ZProjection = CameraKeys.ZProjectionACalculate(view.NearClipPlane, view.FarClipPlane); perViewCamera->ViewSize = view.ViewSize; perViewCamera->AspectRatio = view.ViewSize.X / Math.Max(view.ViewSize.Y, 1.0f); } } // Update PerDraw (World, WorldViewProj, etc...) // Copy Entity.World to PerDraw cbuffer // TODO: Have a PerObject cbuffer? Dispatcher.ForEach(((RootEffectRenderFeature)RootRenderFeature).RenderNodes, (ref RenderNode renderNode) => { var perDrawLayout = renderNode.RenderEffect.Reflection.PerDrawLayout; if (perDrawLayout == null) { return; } var worldOffset = perDrawLayout.GetConstantBufferOffset(this.world); if (worldOffset == -1) { return; } var renderModelObjectInfo = renderModelObjectInfoData[renderNode.RenderObject.ObjectNode]; var renderModelViewInfo = renderModelViewInfoData[renderNode.ViewObjectNode]; var mappedCB = renderNode.Resources.ConstantBuffer.Data; var perDraw = (PerDraw *)((byte *)mappedCB + worldOffset); // Fill PerDraw var perDrawData = new PerDraw { World = renderModelObjectInfo.World, WorldView = renderModelViewInfo.WorldView, WorldViewProjection = renderModelViewInfo.WorldViewProjection }; Matrix.Invert(ref renderModelObjectInfo.World, out perDrawData.WorldInverse); Matrix.Transpose(ref perDrawData.WorldInverse, out perDrawData.WorldInverseTranspose); Matrix.Invert(ref renderModelViewInfo.WorldView, out perDrawData.WorldViewInverse); perDrawData.WorldScale = new Vector3( ((Vector3)renderModelObjectInfo.World.Row1).Length(), ((Vector3)renderModelObjectInfo.World.Row2).Length(), ((Vector3)renderModelObjectInfo.World.Row3).Length()); perDrawData.EyeMS = new Vector4(perDrawData.WorldInverse.M41, perDrawData.WorldInverse.M42, perDrawData.WorldInverse.M43, 1.0f); *perDraw = perDrawData; }); }