Created
September 3, 2025 22:24
-
-
Save w0wca7a/6187196a0e4c7f86b5b17bb33a3fb0ca to your computer and use it in GitHub Desktop.
Revisions
-
w0wca7a created this gist
Sep 3, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,6 @@ // add this component to Entity, which must be marked as target using Stride.Core; using Stride.Engine; [DataContract] public class TargetComponent : EntityComponent {} This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,116 @@ // Based on Stride Community Toolkit Example #9 // https://github.com/stride3d/stride-community-toolkit/blob/08218340fb99b6d994e160d2d0af05bcce43fab1/examples/code-only/Example09_Renderer/MyCustomSceneRenderer.cs using Stride.Core.Mathematics; using Stride.Engine; using Stride.Graphics; using Stride.Rendering; using Stride.Rendering.Compositing; namespace BlurUI.CustomRenderer { public class TargetRenderer : SceneRendererBase, ISharedRenderer { public Texture TargetTexture; private SpriteBatch _spriteBatch; private Scene _scene; private CameraComponent _camera; protected override void InitializeCore() { base.InitializeCore(); _spriteBatch = new SpriteBatch(GraphicsDevice); } protected override void DrawCore(RenderContext context, RenderDrawContext drawContext) { var graphicsCompositor = context.Tags.Get(GraphicsCompositor.Current); if (graphicsCompositor is null) return; _camera ??= context.GetCurrentCamera(); _scene ??= SceneInstance.GetCurrent(context).RootScene; if (_spriteBatch is null || _camera is null || _scene is null) return; var viewProjection = _camera.ViewProjectionMatrix; _spriteBatch.Begin( drawContext.GraphicsContext); foreach (var entity in _scene.Entities) { /* using Stride.Core; * using Stride.Engine; * [DataContract] * public class TargetComponent : EntityComponent {} * * can be add from code */ // Find object with TargetComponent if (entity.Components.Get<TargetComponent>() is null) continue; // original // var screenPosition = _camera.WorldToScreenPoint(ref entity.Transform.Position, GraphicsDevice); var worldPos = entity.Transform.Position; // Transform to clip space var clipPosition = Vector4.Transform(new Vector4(worldPos, 1f), viewProjection); if (clipPosition.W <= 0f) continue; // behind the camera // Perspective divide -> Normalized Device Coordinates (NDC) var inverseW = 1f / clipPosition.W; var normalizedDeviceCoordinatesX = clipPosition.X * inverseW; var normalizedDeviceCoordinatesY = clipPosition.Y * inverseW; var normalizedDeviceCoordinatesZ = clipPosition.Z * inverseW; // Clip test in NDC: x and y in [-1,1], z in [0,1] var outsideNdc = normalizedDeviceCoordinatesZ < 0f || normalizedDeviceCoordinatesZ > 1f || normalizedDeviceCoordinatesX < -1f || normalizedDeviceCoordinatesX > 1f || normalizedDeviceCoordinatesY < -1f || normalizedDeviceCoordinatesY > 1f; // culled if (outsideNdc) continue; // implementation // start Vector3.TransformCoordinate(ref worldPos, ref _camera.ViewProjectionMatrix, out Vector3 viewProject); Vector3.TransformCoordinate(ref worldPos, ref _camera.ViewMatrix, out Vector3 viewSpace); Vector3 result = new() { X = (viewProject.X + 1f) / 2f, Y = 1f - (viewProject.Y + 1f) / 2f, Z = viewSpace.Z + _camera.NearClipPlane, }; var windowSize = new Int2( drawContext.GraphicsDevice.Presenter.BackBuffer.Width, drawContext.GraphicsDevice.Presenter.BackBuffer.Height); Vector2 screenPosition = new() { X = result.X * windowSize.X, Y = result.Y * windowSize.Y }; // end // Draw a texture _spriteBatch.Draw( TargetTexture, new Rectangle( (int)screenPosition.X - TargetTexture.Width/2, // horizontal center of texture in center of object (int)screenPosition.Y - TargetTexture.Height/2, // vertical center of texture in center of object TargetTexture.Width, // rectangle width same as texture TargetTexture.Height), // rectangle height same as texture new(1.0f, 1.0f, 1.0f, 1.0f)); // Color } // End the SpriteBatch _spriteBatch.End(); } } }