public void OnRenderTaskEnd(SceneRenderTask task, GPUContext context) { Return(0, Output); Return(1, RenderTask.Buffers?.DepthBuffer); Return(2, RenderTask.Buffers?.MotionVectors); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.CubeTexture = (CubeTexture)request.Asset; _preview.Parent = guiRoot; _preview.Task.Internal_Render(context); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.CubeTexture = (CubeTexture)request.Asset; _preview.Parent = guiRoot; _preview.SyncBackbufferSize(); _preview.Task.OnDraw(); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.Parent = guiRoot; _preview.Task.OnRender(context); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { var preview = (AudioClipPreview)request.Tag; preview.Parent = guiRoot; }
protected abstract void OnRenderUpdate(GPUContext context);
/// <summary> /// Called when thumbnail rendering begins. /// </summary> /// <param name="task">The scene rendering task to customize.</param> /// <param name="context">The GPU rendering context.</param> /// <param name="req">The request data.</param> public void OnThumbnailRenderingBegin(SceneRenderTask task, GPUContext context, ref CameraCutThumbnailRenderer.Request req) { RenderView view = new RenderView(); var track = (CameraCutTrack)Track; Camera cam = track.Camera; var viewport = new FlaxEngine.Viewport(Vector2.Zero, task.Buffers.Size); Quaternion orientation = Quaternion.Identity; view.Near = 10.0f; view.Far = 20000.0f; bool usePerspective = true; float orthoScale = 1.0f; float fov = 60.0f; float customAspectRatio = 0.0f; view.RenderLayersMask = new LayersMask(uint.MaxValue); // Try to evaluate camera properties based on the initial camera state if (cam) { view.Position = cam.Position; orientation = cam.Orientation; view.Near = cam.NearPlane; view.Far = cam.FarPlane; usePerspective = cam.UsePerspective; orthoScale = cam.OrthographicScale; fov = cam.FieldOfView; customAspectRatio = cam.CustomAspectRatio; view.RenderLayersMask = cam.RenderLayersMask; } // Try to evaluate camera properties based on the animated tracks float time = Start; if (req.ThumbnailIndex == 1) { time += Duration; } else if (req.ThumbnailIndex == 2) { time += Duration * 0.5f; } foreach (var subTrack in track.SubTracks) { if (subTrack is MemberTrack memberTrack) { object value = memberTrack.Evaluate(time); if (value != null) { // TODO: try to make it better if (memberTrack.MemberName == "Position" && value is Vector3 asPosition) { view.Position = asPosition; } else if (memberTrack.MemberName == "Orientation" && value is Quaternion asRotation) { orientation = asRotation; } else if (memberTrack.MemberName == "NearPlane" && value is float asNearPlane) { view.Near = asNearPlane; } else if (memberTrack.MemberName == "FarPlane" && value is float asFarPlane) { view.Far = asFarPlane; } else if (memberTrack.MemberName == "UsePerspective" && value is bool asUsePerspective) { usePerspective = asUsePerspective; } else if (memberTrack.MemberName == "FieldOfView" && value is float asFieldOfView) { fov = asFieldOfView; } else if (memberTrack.MemberName == "CustomAspectRatio" && value is float asCustomAspectRatio) { customAspectRatio = asCustomAspectRatio; } else if (memberTrack.MemberName == "OrthographicScale" && value is float asOrthographicScale) { orthoScale = asOrthographicScale; } } } } // Build view view.Direction = Vector3.Forward * orientation; if (usePerspective) { float aspect = customAspectRatio <= 0.0f ? viewport.AspectRatio : customAspectRatio; view.Projection = Matrix.PerspectiveFov(fov * Mathf.DegreesToRadians, aspect, view.Near, view.Far); } else { view.Projection = Matrix.Ortho(viewport.Width * orthoScale, viewport.Height * orthoScale, view.Near, view.Far); } Vector3 target = view.Position + view.Direction; var up = Vector3.Transform(Vector3.Up, orientation); view.View = Matrix.LookAt(view.Position, target, up); view.NonJitteredProjection = view.Projection; view.TemporalAAJitter = Vector4.Zero; view.ModelLODDistanceFactor = 100.0f; view.Flags = ViewFlags.DefaultGame & ~(ViewFlags.MotionBlur); view.UpdateCachedData(); task.View = view; }
public override void RenderFrame(GPUContext context, ref StagingTexture frame, RenderOptions options, GPUTexture output) { // Copy texture back to the staging texture context.CopyTexture(frame.Texture, 0, 0, 0, 0, output, 0); }
/// <summary> /// Called when thumbnail drawing begins. Proxy should setup scene GUI for guiRoot. /// </summary> /// <param name="request">The request to render thumbnail.</param> /// <param name="guiRoot">The GUI root container control.</param> /// <param name="context">GPU context.</param> public virtual void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { guiRoot.AddChild(new Label { Text = Name, Size = guiRoot.Size, Wrapping = TextWrapping.WrapWords }); }
public abstract void RenderFrame(GPUContext context, ref StagingTexture frame, RenderOptions options, GPUTexture output);
public abstract void CollectFrame(GPUContext context, ref StagingTexture frame, RenderOptions options);
/// <summary> /// Performs custom postFx rendering. /// </summary> /// <param name="context">The GPU commands context.</param> /// <param name="task">The current rendering task.</param> /// <param name="input">The input texture.</param> /// <param name="output">The output texture.</param> public abstract void Render(GPUContext context, SceneRenderTask task, RenderTarget input, RenderTarget output);
/// <summary> /// Performs custom postFx rendering. /// </summary> /// <param name="context">The GPU commands context.</param> /// <param name="renderContext">The rendering context.</param> /// <param name="input">The input texture.</param> /// <param name="output">The output texture.</param> public abstract void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output);
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { guiRoot.AddChild(new Label { Text = "Audio", Size = guiRoot.Size, Wrapping = TextWrapping.WrapWords }); }
/// <inheritdoc /> public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output) { if (Viewport == null) { throw new NullReferenceException(); } Profiler.BeginEventGPU("Editor Primitives"); // Check if use MSAA var format = output.Format; var formatFeatures = GPUDevice.Instance.GetFormatFeatures(format); bool enableMsaa = formatFeatures.MSAALevelMax >= MSAALevel.X4 && Editor.Instance.Options.Options.Visual.EnableMSAAForDebugDraw; // Prepare var msaaLevel = enableMsaa ? MSAALevel.X4 : MSAALevel.None; var width = output.Width; var height = output.Height; var desc = GPUTextureDescription.New2D(width, height, format, GPUTextureFlags.RenderTarget | GPUTextureFlags.ShaderResource, 1, 1, msaaLevel); var target = RenderTargetPool.Get(ref desc); desc = GPUTextureDescription.New2D(width, height, PixelFormat.D24_UNorm_S8_UInt, GPUTextureFlags.DepthStencil, 1, 1, msaaLevel); var targetDepth = RenderTargetPool.Get(ref desc); // Copy frame and clear depth context.Draw(target, input); context.ClearDepth(targetDepth.View()); context.SetViewport(width, height); context.SetRenderTarget(targetDepth.View(), target.View()); // Draw gizmos and other editor primitives var renderList = RenderList.GetFromPool(); var prevList = renderContext.List; renderContext.List = renderList; for (int i = 0; i < Viewport.Gizmos.Count; i++) { Viewport.Gizmos[i].Draw(ref renderContext); } Viewport.DrawEditorPrimitives(context, ref renderContext, target, targetDepth); // Sort draw calls renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBuffer); renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBufferNoDecals); renderList.SortDrawCalls(ref renderContext, true, DrawCallsListType.Forward); // Perform the rendering renderContext.View.Pass = DrawPass.GBuffer; renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBuffer); renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBufferNoDecals); renderContext.View.Pass = DrawPass.Forward; renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.Forward); // Resolve MSAA texture if (enableMsaa) { context.ResolveMultisample(target, output); } else { context.Draw(output, target); } // Cleanup RenderTargetPool.Release(targetDepth); RenderTargetPool.Release(target); RenderList.ReturnToPool(renderList); renderContext.List = prevList; Profiler.EndEventGPU(); }
private void OnRender(GPUContext context) { lock (_requests) { // Check if there is ready next asset to render thumbnail for it // But don't check whole queue, only a few items var request = GetReadyRequest(10); if (request == null) { // Disable task _task.Enabled = false; return; } // Find atlas with an free slot var atlas = GetValidAtlas(); if (atlas == null) { // Error _task.Enabled = false; _requests.Clear(); Editor.LogError("Failed to get atlas."); return; } // Wait for atlas being loaded if (!atlas.IsReady) { return; } // Setup _guiRoot.RemoveChildren(); _guiRoot.AccentColor = request.Proxy.AccentColor; // Call proxy to prepare for thumbnail rendering request.Proxy.OnThumbnailDrawBegin(request, _guiRoot, context); _guiRoot.UnlockChildrenRecursive(); // Draw preview context.Clear(_output, Color.Black); Render2D.CallDrawing(_guiRoot, context, _output); // Call proxy and cleanup UI (delete create controls, shared controls should be unlinked during OnThumbnailDrawEnd event) request.Proxy.OnThumbnailDrawEnd(request, _guiRoot); _guiRoot.DisposeChildren(); // Copy backbuffer with rendered preview into atlas Sprite icon = atlas.OccupySlot(_output, request.Item.ID); if (!icon.IsValid) { // Error _task.Enabled = false; _requests.Clear(); Editor.LogError("Failed to occupy previews cache atlas slot."); return; } // End request.FinishRender(ref icon); RemoveRequest(request); } }
/// <summary> /// Called when thumbnail rendering begins. /// </summary> /// <param name="task">The scene rendering task to customize.</param> /// <param name="context">The GPU rendering context.</param> /// <param name="req">The request data.</param> public void OnThumbnailRenderingBegin(SceneRenderTask task, GPUContext context, ref CameraCutThumbnailRenderer.Request req) { var view = new RenderView(); var track = (CameraCutTrack)Track; var cam = track.Camera; var viewport = new FlaxEngine.Viewport(Vector2.Zero, task.Buffers.Size); var orientation = Quaternion.Identity; view.Near = 10.0f; view.Far = 20000.0f; var usePerspective = true; var orthoScale = 1.0f; var fov = 60.0f; var customAspectRatio = 0.0f; // Try to evaluate camera properties based on the initial camera state if (cam) { view.Position = cam.Position; orientation = cam.Orientation; view.Near = cam.NearPlane; view.Far = cam.FarPlane; usePerspective = cam.UsePerspective; orthoScale = cam.OrthographicScale; fov = cam.FieldOfView; customAspectRatio = cam.CustomAspectRatio; } // Try to evaluate camera properties based on the animated tracks var time = req.ThumbnailIndex == 0 ? Start : Start + Duration; foreach (var subTrack in track.SubTracks) { if (subTrack is MemberTrack memberTrack) { object value = memberTrack.Evaluate(time); if (value != null) { // TODO: try to make it better if (memberTrack.MemberName == "Position" && value is Vector3 asPosition) { view.Position = asPosition; } else if (memberTrack.MemberName == "Orientation" && value is Quaternion asRotation) { orientation = asRotation; } else if (memberTrack.MemberName == "NearPlane" && value is float asNearPlane) { view.Near = asNearPlane; } else if (memberTrack.MemberName == "FarPlane" && value is float asFarPlane) { view.Far = asFarPlane; } else if (memberTrack.MemberName == "UsePerspective" && value is bool asUsePerspective) { usePerspective = asUsePerspective; } else if (memberTrack.MemberName == "FieldOfView" && value is float asFieldOfView) { fov = asFieldOfView; } else if (memberTrack.MemberName == "CustomAspectRatio" && value is float asCustomAspectRatio) { customAspectRatio = asCustomAspectRatio; } else if (memberTrack.MemberName == "OrthographicScale" && value is float asOrthographicScale) { orthoScale = asOrthographicScale; } } } } // Build view view.Direction = Vector3.Forward * orientation; if (usePerspective) { float aspect = customAspectRatio <= 0.0f ? viewport.AspectRatio : customAspectRatio; view.Projection = Matrix.PerspectiveFov(fov * Mathf.DegreesToRadians, aspect, view.Near, view.Far); } else { view.Projection = Matrix.Ortho(viewport.Width * orthoScale, viewport.Height * orthoScale, view.Near, view.Far); } Vector3 target = view.Position + view.Direction; var up = Vector3.Transform(Vector3.Up, orientation); view.View = Matrix.LookAt(view.Position, target, up); view.NonJitteredProjection = view.Projection; view.TemporalAAJitter = Vector4.Zero; view.ModelLODDistanceFactor = 100.0f; view.Flags = ViewFlags.Reflections | ViewFlags.SSR | ViewFlags.AO | ViewFlags.GI | ViewFlags.DirectionalLights | ViewFlags.PointLights | ViewFlags.SpotLights | ViewFlags.SkyLights | ViewFlags.Shadows | ViewFlags.SpecularLight | ViewFlags.AntiAliasing | ViewFlags.CustomPostProcess | ViewFlags.Bloom | ViewFlags.ToneMapping | ViewFlags.CameraArtifacts | ViewFlags.LensFlares | ViewFlags.Decals | ViewFlags.DepthOfField | ViewFlags.Fog; view.UpdateCachedData(); task.View = view; }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { var asset = FlaxEngine.Content.LoadAsync <FontAsset>(request.Item.ID); guiRoot.AddChild(new Label { Text = asset.FamilyName, AnchorPreset = AnchorPresets.StretchAll, Offsets = Margin.Zero, Wrapping = TextWrapping.WrapWords }); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { var asset = FlaxEngine.Content.Load <FontAsset>(request.Item.Path); guiRoot.AddChild(new Label(Vector2.Zero, guiRoot.Size) { Text = asset.FamilyName, Wrapping = TextWrapping.WrapWords }); }
public void OnRenderTaskEnd(SceneRenderTask task, GPUContext context) { Return(0, Output); }
private void OnEnd(RenderTask task, GPUContext context) { // Pick the atlas or create a new one int atlasIndex = -1; for (int i = 0; i < _atlases.Count; i++) { if (!_atlases[i].IsFull) { atlasIndex = i; break; } } if (atlasIndex == -1) { // Setup configuration var atlasSize = 1024; var atlasFormat = PixelFormat.R8G8B8A8_UNorm; var width = (float)Width; var height = (float)Height; var countX = Mathf.FloorToInt(atlasSize / width); var countY = Mathf.FloorToInt(atlasSize / height); var count = countX * countY; // Create sprite atlas texture var spriteAtlas = FlaxEngine.Content.CreateVirtualAsset <SpriteAtlas>(); var data = new byte[atlasSize * atlasSize * PixelFormatExtensions.SizeInBytes(atlasFormat)]; var initData = new TextureBase.InitData { Width = atlasSize, Height = atlasSize, ArraySize = 1, Format = atlasFormat, Mips = new[] { new TextureBase.InitData.MipData { Data = data, RowPitch = data.Length / atlasSize, SlicePitch = data.Length }, }, }; spriteAtlas.Init(ref initData); // Setup sprite atlas slots (each per thumbnail) var thumbnailSizeUV = new Vector2(width / atlasSize, height / atlasSize); for (int i = 0; i < count; i++) { var x = i % countX; var y = i / countX; var s = new Sprite { Name = string.Empty, Area = new Rectangle(new Vector2(x, y) * thumbnailSizeUV, thumbnailSizeUV), }; spriteAtlas.AddSprite(s); } // Add atlas to the cached ones atlasIndex = _atlases.Count; _atlases.Add(new Atlas { Texture = spriteAtlas, SlotsUsage = new BitArray(count, false), Count = 0, }); } // Skip ending if the atlas is not loaded yet (streaming backend uploads texture to GPU or sth) var atlas = _atlases[atlasIndex]; if (atlas.Texture.ResidentMipLevels == 0) { return; } // Pick the sprite slot from the atlas var spriteIndex = -1; for (int i = 0; i < atlas.SlotsUsage.Count; i++) { if (atlas.SlotsUsage[i] == false) { atlas.SlotsUsage[i] = true; spriteIndex = i; break; } } if (spriteIndex == -1) { throw new FlaxException(); } atlas.Count++; _atlases[atlasIndex] = atlas; var sprite = new SpriteHandle(atlas.Texture, spriteIndex); // Copy output frame to the sprite atlas slot var spriteLocation = sprite.Location; context.CopyTexture(atlas.Texture.Texture, 0, (uint)spriteLocation.X, (uint)spriteLocation.Y, 0, _output, 0); // Link sprite to the UI var req = _queue[0]; req.Media.OnThumbnailRenderingEnd((SceneRenderTask)task, context, ref req, ref sprite); // End _queue.RemoveAt(0); task.Enabled = false; }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.Prefab = (Prefab)request.Asset; _preview.Parent = guiRoot; _preview.Scale = Vector2.One; _preview.ShowDefaultSceneActors = true; _preview.SyncBackbufferSize(); // Special case for UI prefabs if (_preview.Instance is UIControl uiControl && uiControl.HasControl) { // Ensure to place UI in a proper way uiControl.Control.Location = Vector2.Zero; uiControl.Control.Scale *= PreviewsCache.AssetIconSize / uiControl.Control.Size.MaxValue; uiControl.Control.AnchorPreset = AnchorPresets.TopLeft; uiControl.Control.AnchorPreset = AnchorPresets.MiddleCenter; // Tweak preview _preview.ShowDefaultSceneActors = false; }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { guiRoot.AddChild(new Label { Text = Path.GetFileNameWithoutExtension(request.Asset.Path), Size = guiRoot.Size, Wrapping = TextWrapping.WrapWords }); }
/// <summary> /// Performs custom postFx rendering. /// </summary> /// <param name="context">The GPU commands context.</param> /// <param name="task">The current rendering task.</param> /// <param name="input">The input texture.</param> /// <param name="output">The output texture.</param> public abstract void Render(GPUContext context, SceneRenderTask task, GPUTexture input, GPUTexture output);
/// <summary> /// Called when thumbnail drawing begins. Proxy should setup scene GUI for guiRoot. /// </summary> /// <param name="request">The request to render thumbnail.</param> /// <param name="guiRoot">The GUI root container control.</param> /// <param name="context">GPU context.</param> public virtual void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { guiRoot.AddChild(new Label { Text = Name, Offsets = Margin.Zero, AnchorPreset = AnchorPresets.StretchAll, Wrapping = TextWrapping.WrapWords }); }
/// <inheritdoc /> public void DrawEditorPrimitives(GPUContext context, ref RenderContext renderContext, GPUTexture target, GPUTexture targetDepth) { }
protected override void OnRenderUpdate(GPUContext context) { Return(0, GetInput(0)); }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.Asset = (SpriteAtlas)request.Asset; _preview.Parent = guiRoot; }
/// <inheritdoc /> public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context) { _preview.Material = (MaterialInstance)request.Asset; _preview.Parent = guiRoot; _preview.Task.Internal_Render(context); }
public void OnRenderTaskBegin(SceneRenderTask task, GPUContext context) { Output.Size = Size; }