-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
First Release
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,40 @@ | ||
# UnityXScaling | ||
Unity XScaling - a runtime framework for GPU-based textures and screen upscaling (super-resolution). Supports every platform. | ||
# Unity XScaling Framework | ||
![Unity XScaling Framework](https://github.com/DevsDaddy/UnityXScaling/assets/147835900/ac00e72d-923f-443e-9228-5ea5c1f52ea7) | ||
**Unity XScaling Framework** - is a set of tools for texture upscaling and real-time camera rendering, allowing you to improve picture quality without increasing the size of your build. | ||
|
||
Simply load 256x256 textures into your build and upscale them to any size in real time on demand. Or increase performance and quality with Super-Resolution Rendering and the Camera Upscale component | ||
|
||
**:question: What does the XScaling Library include?** | ||
* Real-time Texture Upscaling; | ||
* UI Image and RawImage Upscaler; | ||
* Distance-based textures upscaling; | ||
* Rendering Upscaling (Super-Sampling) (similar FRS or DLSS but fully cross-platform); | ||
* GPU-Based and cross-platform; | ||
|
||
## Get Started | ||
**GameShield** installs into your project as easily as possible - basic installation and configuration takes **only 4 steps**. Below we will consider both **automatic initialization** and **manual configuration**. | ||
|
||
**Basic Installation:** | ||
* Download <a href="https://github.com/DevsDaddy/UnityXScaling/releases">Latest Release from GitHUB</a>; | ||
* Import **.unitypackage** into your project; | ||
* See example scenes or add ready-to-use components on your models / ui elements; | ||
* Done! | ||
|
||
**Dependencies:** | ||
- Unity 2019+ and Built-in Render Pipeline Only (URP and HDRP support is coming soon); | ||
- TextMesh Pro and Texture2D packages for UI support; | ||
|
||
## Note | ||
> This library is still under development. The system performs best on cartoon textures, but I aim to solve this soon by adding new algorithms such as Real-ESRGAN. | ||
> Do not use preset HQ Quality at Production. Use HQ Performance instead. | ||
## Join Community | ||
- <a href="https://discord.gg/xuNTKRDebx">Discord Community</a> | ||
|
||
## Support Me | ||
**You can support the development and updating of libraries and assemblies by dropping a coin:** | ||
<table> | ||
<tr><td>Bitcoin (BTC)</td><td>bc1qef2d34r4xkrm48zknjdjt7c0ea92ay9m2a7q55</td></tr> | ||
<tr><td>Etherium (ETH)</td><td>0x1112a2Ef850711DF4dE9c432376F255f416ef5d0</td></tr> | ||
<tr><td>Boosty</td><td>https://boosty.to/devsdaddy</td></tr> | ||
</table> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using DevsDaddy.XScaling.Core.Render; | ||
using DevsDaddy.XScaling.Core.Upscale; | ||
using DevsDaddy.XScaling.Enum; | ||
using DevsDaddy.XScaling.Utils; | ||
using UnityEngine; | ||
using UnityEngine.Experimental.Rendering; | ||
using UnityEngine.Rendering; | ||
|
||
namespace DevsDaddy.XScaling | ||
{ | ||
/// <summary> | ||
/// XScale Camera Render Upscaling Component | ||
/// </summary> | ||
[AddComponentMenu("XScaling/Camera/Upscale Camera")] | ||
[RequireComponent(typeof(Camera))] | ||
public class CameraUpscaler : MonoBehaviour | ||
{ | ||
// Events | ||
public delegate void ApplyMipMapBiasDelegate(float biasOffset); | ||
public static ApplyMipMapBiasDelegate OnApplyMipMapBias; | ||
|
||
public delegate void UndoMipMapBiasDelegate(); | ||
public static UndoMipMapBiasDelegate OnUndoMipMapBias; | ||
|
||
[Header("Basic Setup")] | ||
[Tooltip("Standard Upscale Presets")] | ||
public UpscaleMode qualityMode = UpscaleMode.HQQuality; | ||
|
||
private Vector2Int _maxRenderSize; | ||
private Vector2Int _displaySize; | ||
private bool _resetHistory; | ||
|
||
private Camera _renderCamera; | ||
private RenderTexture _originalRenderTarget; | ||
private DepthTextureMode _originalDepthTextureMode; | ||
private Rect _originalRect; | ||
|
||
private UpscaleMode _prevQualityMode; | ||
private Vector2Int _prevDisplaySize; | ||
|
||
private Material _copyWithDepthMaterial; | ||
|
||
private bool _isActiveRender = false; | ||
|
||
private void OnEnable() | ||
{ | ||
_renderCamera = GetComponent<Camera>(); | ||
_originalRenderTarget = _renderCamera.targetTexture; | ||
_originalDepthTextureMode = _renderCamera.depthTextureMode; | ||
_renderCamera.targetTexture = null; | ||
_renderCamera.depthTextureMode = _originalDepthTextureMode | DepthTextureMode.Depth | DepthTextureMode.MotionVectors; | ||
|
||
// Determine the desired rendering and display resolutions | ||
_displaySize = GetDisplaySize(); | ||
UpscaleUtils.GetRenderResolutionFromQualityMode(out var maxRenderWidth, out var maxRenderHeight, _displaySize.x, _displaySize.y, qualityMode); | ||
_maxRenderSize = new Vector2Int(maxRenderWidth, maxRenderHeight); | ||
|
||
if (_maxRenderSize.x == 0 || _maxRenderSize.y == 0) | ||
{ | ||
Debug.LogError($"XScaling Upscaler render size is invalid: {_maxRenderSize.x}x{_maxRenderSize.y}. Please check your screen resolution and camera viewport parameters."); | ||
enabled = false; | ||
return; | ||
} | ||
|
||
_copyWithDepthMaterial = new Material(Shader.Find("Hidden/BlitCopyWithDepth")); | ||
CreateContext(); | ||
|
||
XRender.OnStateChanged += OnRenderStateChanged; | ||
OnRenderStateChanged(XRender.IsActive); | ||
} | ||
|
||
private void OnDisable() | ||
{ | ||
DestroyContext(); | ||
|
||
if (_copyWithDepthMaterial != null) | ||
{ | ||
Destroy(_copyWithDepthMaterial); | ||
_copyWithDepthMaterial = null; | ||
} | ||
|
||
// Restore the camera's original state | ||
_renderCamera.depthTextureMode = _originalDepthTextureMode; | ||
_renderCamera.targetTexture = _originalRenderTarget; | ||
XRender.OnStateChanged -= OnRenderStateChanged; | ||
} | ||
|
||
private void OnRenderStateChanged(bool isRenderActive) { | ||
_isActiveRender = isRenderActive; | ||
} | ||
|
||
private void CreateContext() | ||
{ | ||
_prevDisplaySize = _displaySize; | ||
_prevQualityMode = qualityMode; | ||
ApplyMipmapBias(); | ||
} | ||
|
||
private void DestroyContext() | ||
{ | ||
UndoMipmapBias(); | ||
} | ||
|
||
private void ApplyMipmapBias() | ||
{ | ||
// Apply a mipmap bias so that textures retain their sharpness | ||
float biasOffset = UpscaleUtils.GetMipmapBiasOffset(_maxRenderSize.x, _displaySize.x); | ||
if (!float.IsNaN(biasOffset) && !float.IsInfinity(biasOffset)) | ||
{ | ||
OnApplyMipMapBias?.Invoke(biasOffset); | ||
} | ||
} | ||
|
||
private void UndoMipmapBias() | ||
{ | ||
OnUndoMipMapBias?.Invoke(); | ||
} | ||
|
||
private void Update() | ||
{ | ||
// Monitor for any changes in parameters that require a reset of the FSR3 Upscaler context | ||
var displaySize = GetDisplaySize(); | ||
if (displaySize.x != _prevDisplaySize.x || displaySize.y != _prevDisplaySize.y || qualityMode != _prevQualityMode) | ||
{ | ||
OnDisable(); | ||
OnEnable(); | ||
} | ||
} | ||
private void LateUpdate() | ||
{ | ||
// Remember the original camera viewport before we modify it in OnPreCull | ||
_originalRect = _renderCamera.rect; | ||
} | ||
|
||
private void OnPreCull() | ||
{ | ||
_renderCamera.aspect = (float)_displaySize.x / _displaySize.y; | ||
_renderCamera.rect = new Rect(0, 0, _originalRect.width * _maxRenderSize.x / _renderCamera.pixelWidth, _originalRect.height * _maxRenderSize.y / _renderCamera.pixelHeight); | ||
} | ||
|
||
private void OnRenderImage(RenderTexture src, RenderTexture dest) | ||
{ | ||
// Restore the camera's viewport rect so we can output at full resolution | ||
_renderCamera.rect = _originalRect; | ||
_renderCamera.ResetProjectionMatrix(); | ||
|
||
if (_isActiveRender) { | ||
// The backbuffer is not set up to allow random-write access, so we need a temporary render texture for FSR3 to output to | ||
RenderTexture renderTexture = UpscaleProcessor.UpscaleToRenderTexture(src, _prevQualityMode, | ||
UpscaleTechnique.TechniqueB, new UpscaleSize(Screen.width, Screen.height)); | ||
|
||
// Output the upscaled image | ||
if (_originalRenderTarget != null) | ||
Graphics.Blit(renderTexture, _originalRenderTarget, _copyWithDepthMaterial); | ||
else | ||
Graphics.Blit(renderTexture, dest); | ||
|
||
RenderTexture.ReleaseTemporary(renderTexture); | ||
renderTexture.Release(); | ||
RenderTexture.active = dest; | ||
} | ||
else { | ||
// Output the upscaled image | ||
if (_originalRenderTarget != null) | ||
Graphics.Blit(src, _originalRenderTarget, _copyWithDepthMaterial); | ||
else | ||
Graphics.Blit(src, dest); | ||
} | ||
} | ||
|
||
private RenderTextureFormat GetDefaultFormat() | ||
{ | ||
if (_originalRenderTarget != null) | ||
return _originalRenderTarget.format; | ||
|
||
return _renderCamera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; | ||
} | ||
|
||
private Vector2Int GetDisplaySize() | ||
{ | ||
if (_originalRenderTarget != null) | ||
return new Vector2Int(_originalRenderTarget.width, _originalRenderTarget.height); | ||
|
||
return new Vector2Int(_renderCamera.pixelWidth, _renderCamera.pixelHeight); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.