Skip to content

Commit

Permalink
Add full-screen sprites feature
Browse files Browse the repository at this point in the history
Such sprites will stretch to screen size and (for now) repeat it's texture, so some UVs settings from authorings may by ignored because of working of new full-screen size sprites (related only for those kind of sprites)
  • Loading branch information
Antoshidza committed May 13, 2023
1 parent c0b0096 commit 831551b
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 11 deletions.
25 changes: 25 additions & 0 deletions Base/Authoring/FullScreenSpriteAuthoring.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Unity.Entities;
using UnityEngine;

namespace NSprites
{
public class FullScreenSpriteAuthoring : MonoBehaviour
{
[SerializeField] private SpriteRendererAuthoring _spriteAuthoring;

private partial class Baker : Baker<FullScreenSpriteAuthoring>
{
public override void Bake(FullScreenSpriteAuthoring authoring)
{
if(authoring._spriteAuthoring == null)
return;

var entity = GetEntity(TransformUsageFlags.None);
AddComponent<FullScreenSpriteTag>(entity);
AddComponent(entity, new NativeSpriteSize{ Value = authoring._spriteAuthoring.NativeSpriteSize });

DependsOn(authoring._spriteAuthoring);
}
}
}
}
3 changes: 3 additions & 0 deletions Base/Authoring/FullScreenSpriteAuthoring.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions Base/Common/Bounds2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ public readonly struct Bounds2D
private readonly float2 _position;
private readonly float2 _extents;

private float2 Min => _position - _extents;
private float2 Max => _position + _extents;
public float2 Min => _position - _extents;
public float2 Max => _position + _extents;
public float2 Size => _extents * 2f;

public Bounds2D(in float2 position, in float2 size)
{
Expand All @@ -22,6 +23,22 @@ public Bounds2D(in float2x2 rect)
_extents = math.abs(rect.c1 - rect.c0) / 2f;
}

private static bool Equals(Bounds2D lhs, Bounds2D rhs)
{
return math.all(lhs._position == rhs._position)
&& math.all(lhs._extents == rhs._extents);
}

public static bool operator ==(Bounds2D lhs, Bounds2D rhs)
{
return Equals(lhs, rhs);
}

public static bool operator !=(Bounds2D lhs, Bounds2D rhs)
{
return !Equals(lhs, rhs);
}

public bool Intersects(in Bounds2D bounds)
{
var max = Max;
Expand Down
8 changes: 8 additions & 0 deletions Base/Components/Regular/FullScreenSpriteTag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Unity.Entities;

namespace NSprites
{
public struct FullScreenSpriteTag : IComponentData
{
}
}
3 changes: 3 additions & 0 deletions Base/Components/Regular/FullScreenSpriteTag.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Base/Components/Regular/NativeSpriteSize.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Unity.Entities;
using Unity.Mathematics;

namespace NSprites
{
public struct NativeSpriteSize : IComponentData
{
public float2 Value;
}
}
3 changes: 3 additions & 0 deletions Base/Components/Regular/NativeSpriteSize.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions Base/Systems/FullScreenSpriteSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;

namespace NSprites
{
[UpdateAfter(typeof(UpdateCullingDataSystem))]
public partial struct FullScreenSpriteSystem : ISystem
{
[BurstCompile]
[WithAll(typeof(FullScreenSpriteTag))]
private partial struct RecalculateSpritesJob : IJobEntity
{
public float2 CameraPosition;
public float2 ScreenSize;

private void Execute(ref Scale2D size, ref WorldPosition2D position, ref UVTilingAndOffset uvTilingAndOffset, in NativeSpriteSize nativeSpriteSize)
{
size.value = ScreenSize;
position.value = CameraPosition;
uvTilingAndOffset.value = new float4(size.value / nativeSpriteSize.Value, CameraPosition / nativeSpriteSize.Value - size.value / nativeSpriteSize.Value / 2f);
}
}

private struct SystemData : IComponentData
{
public float2 LastCameraPosition;
public Bounds2D LastCameraBounds;
}

[BurstCompile]
public void OnCreate(ref SystemState state)
{
_ = state.EntityManager.AddComponent<SystemData>(state.SystemHandle);
}

[BurstCompile]
public void OnUpdate(ref SystemState state)
{
if(!SystemAPI.TryGetSingleton<SpriteFrustumCullingSystem.CameraData>(out var cameraData))
return;

var sysData = SystemAPI.GetComponentRW<SystemData>(state.SystemHandle);

if(cameraData.CullingBounds2D != sysData.ValueRO.LastCameraBounds)
{
sysData.ValueRW.LastCameraBounds = cameraData.CullingBounds2D;

var recalculateSpriteJob = new RecalculateSpritesJob
{
CameraPosition = cameraData.Position,
ScreenSize = cameraData.CullingBounds2D.Size
};
state.Dependency = recalculateSpriteJob.ScheduleByRef(state.Dependency);
}
}
}
}
3 changes: 3 additions & 0 deletions Base/Systems/FullScreenSpriteSystem.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions Base/Systems/SpriteFrustumCullingSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Unity.Burst;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEditor;

namespace NSprites
Expand Down Expand Up @@ -38,8 +39,9 @@ private void Execute(Entity entity, [ChunkIndexInQuery] int chunkIndex, in World
EntityCommandBuffer.RemoveComponent<CullSpriteTag>(chunkIndex, entity);
}
}
public struct SystemData : IComponentData
public struct CameraData : IComponentData
{
public float2 Position;
public Bounds2D CullingBounds2D;
}

Expand All @@ -64,14 +66,15 @@ public static void ToggleFrustumCullingSystem()
[BurstCompile]
public void OnCreate(ref SystemState state)
{
_ = state.EntityManager.AddComponentData(state.SystemHandle, new SystemData());
state.RequireForUpdate<EndSimulationEntityCommandBufferSystem.Singleton>();
_ = state.EntityManager.AddComponentData(state.SystemHandle, new CameraData());
}

[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var ecbSingleton = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
var cullingBounds2D = SystemAPI.GetComponent<SystemData>(state.SystemHandle).CullingBounds2D;
var cullingBounds2D = SystemAPI.GetComponent<CameraData>(state.SystemHandle).CullingBounds2D;

var disableCulledJob = new DisableCulledJob
{
Expand Down
7 changes: 6 additions & 1 deletion Base/Systems/UpdateCullingDataSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ public void OnCreate(ref SystemState state)
public void OnUpdate(ref SystemState state)
{
var camera = state.EntityManager.GetComponentObject<SystemData>(state.SystemHandle).Camera;
var cameraPos = camera.transform.position;
var leftBottomPoint = camera.ScreenToWorldPoint(new Vector3(0f, 0f, 0f));
var rightUpPoint = camera.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0f));
var cameraViewBounds2D = new Bounds2D(new float2x2(new float2(leftBottomPoint.x, leftBottomPoint.y), new float2(rightUpPoint.x, rightUpPoint.y)));
SystemAPI.SetSingleton(new SpriteFrustumCullingSystem.SystemData{ CullingBounds2D = cameraViewBounds2D});
SystemAPI.SetSingleton(new SpriteFrustumCullingSystem.CameraData
{
Position = new float2(cameraPos.x, cameraPos.y),
CullingBounds2D = cameraViewBounds2D
});
}
}
}
7 changes: 3 additions & 4 deletions Graphics/Regular Render/RegularNSprites_Shader.shader
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,9 @@
return varyings;
}

half4 UnlitFragment(Varyings varyings, uint instanceID : SV_InstanceID) : SV_Target
float4 UnlitFragment(Varyings varyings, uint instanceID : SV_InstanceID) : SV_Target
{
// TODO: instead of accessing every time in frag shader do this ones in vertex and then pass value with varyings
#if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) || defined(UNITY_STEREO_INSTANCING_ENABLED)
#if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) || defined(UNITY_STEREO_INSTANCING_ENABLED)
int propertyIndex = _propertyPointers[instanceID];
float4 uvAtlas = _uvAtlasBuffer[propertyIndex];
#else
Expand All @@ -126,7 +125,7 @@
// finally frac UV and locate texture on atlas, now our UV is inside actual texture bounds (repeated)
varyings.uv = TilingAndOffset(frac(varyings.uv), uvAtlas.xy, uvAtlas.zw);

half4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, varyings.uv);
float4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, varyings.uv);
clip(texColor.w - 0.5);
return texColor;
}
Expand Down
2 changes: 1 addition & 1 deletion Graphics/Regular Render/RegularSprite_PropertiesSet.asset
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ MonoBehaviour:
- propertyName: _pivotBuffer
updateMode: 2
- propertyName: _heightWidthBuffer
updateMode: 2
updateMode: 0
- propertyName: _flipBuffer
updateMode: 0

0 comments on commit 831551b

Please sign in to comment.