Kastell/Assets/Pixel3D/Scripts/PostProcesser.cs
Gerard Gascón f5c1616018 init
2025-02-02 23:45:04 +01:00

474 lines
16 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(Camera)),
// RequireComponent(typeof(SceneColorSetup))
]
public class PostProcesser : MonoBehaviour
{
[Header("Grass Overlaying Shaders")]
public LayerMask grassLayer;
public ShaderState grassState = ShaderState.On;
public Shader grassReplacementShader;
public float alphaThreshold = 0.5f;
private GameObject _grassCameraObject;
[Header("Pixel Shader")]
public ShaderState pixelState = ShaderState.On;
public bool dynamicPixelSize = false;
public int screenHeight = 192;
public float pixelsPerUnit = 24f;
[Range(1f / 32f, 1)] public float zoom = 0.125f;
[Header("Outline Shader")]
public ShaderState outlineState = ShaderState.On;
public Color outlineColor = Color.black;
public Color edgeColor = Color.white;
public float depthThreshold = 0.02f;
public float normalThreshold = 0.05f;
public Vector3 normalEdgeBias = Vector3.one;
public float angleThreshold = 0.5f;
public int angleFactorScale = 7;
[Header("Cloud Shader")]
public ShaderState cloudState = ShaderState.On;
public Texture2D cloudsFineDetail;
public Texture2D cloudsMediumDetail;
public Texture2D cloudsLargeDetail;
public Light lightSource;
public float cloudSpeed = 0.1f;
[Range(0, 1)] public float cloudThickness = 0.5f;
[Range(0, 1)] public float cloudCoverage = 0.5f;
[Range(0, 360)] public float cloudDirection = 30f;
public float cloudZoom = 10f;
public enum ShaderState
{
On,
Off,
Debug,
}
void OnEnable()
{
// Camera.main.depthTextureMode = DepthTextureMode.MotionVectors | DepthTextureMode.DepthNormals | DepthTextureMode.Depth;
Camera.main.depthTextureMode = DepthTextureMode.DepthNormals | DepthTextureMode.Depth;
if (grassState != ShaderState.Debug)
Camera.main.cullingMask = ~(1 << (int)Mathf.Log(grassLayer.value, 2));
if (grassState == ShaderState.On && _grassCameraObject == null)
{
_grassCameraObject = new GameObject("GrassCamera");
_grassCameraObject.transform.SetParent(Camera.main.transform);
_grassCameraObject.AddComponent<Camera>();
}
}
void OnDisable()
{
if (_grassCameraObject != null)
{
Destroy(_grassCameraObject);
_grassCameraObject = null;
}
}
void UpdateZoom()
{
if (Camera.main == null)
return;
Camera.main.orthographicSize = 1 / zoom;
var farPlane = 20 / zoom;
var pos = Camera.main.transform.localPosition;
pos.z = -farPlane / 2;
Camera.main.transform.SetLocalPositionAndRotation(pos, Quaternion.identity);
Camera.main.farClipPlane = farPlane;
}
void OnValidate()
{
UpdateZoom();
}
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
var outlineMaterial = CoreUtils.CreateEngineMaterial("Custom/PixelPerfectOutline");
outlineMaterial.SetFloat("_DepthThreshold", depthThreshold);
outlineMaterial.SetFloat("_AngleThreshold", angleThreshold);
outlineMaterial.SetFloat("_AngleFactorScale", angleFactorScale);
outlineMaterial.SetFloat("_NormalThreshold", normalThreshold);
outlineMaterial.SetVector("_NormalEdgeBias", normalEdgeBias);
outlineMaterial.SetInteger("_DebugOutline", outlineState == ShaderState.Debug ? 1 : 0);
outlineMaterial.SetColor("_OutlineColor", outlineColor);
outlineMaterial.SetColor("_EdgeColor", edgeColor);
var grassBlendingMaterial = CoreUtils.CreateEngineMaterial("Custom/GrassBlending");
grassBlendingMaterial.SetFloat("_AlphaThreshold", alphaThreshold);
UpdateZoom();
var pixelScreenHeight = screenHeight;
if (dynamicPixelSize)
{
pixelScreenHeight = (int)(1 / zoom * pixelsPerUnit);
}
var pixelScreenWidth = (int)(pixelScreenHeight * Camera.main.aspect + 0.5f);
var tempTex = RenderTexture.GetTemporary(src.descriptor);
var grassTex = RenderTexture.GetTemporary(src.descriptor);
var cloudTex = RenderTexture.GetTemporary(2048, 2048);
var screenSize = new Vector2(Screen.width, Screen.height);
if (pixelState == ShaderState.On)
{
src.filterMode = FilterMode.Point;
tempTex.Release();
tempTex.height = pixelScreenHeight;
tempTex.width = pixelScreenWidth;
tempTex.filterMode = FilterMode.Point;
tempTex.Create();
grassTex.Release();
grassTex.height = pixelScreenHeight;
grassTex.width = pixelScreenWidth;
grassTex.filterMode = FilterMode.Point;
grassTex.Create();
screenSize = new Vector2(pixelScreenWidth, pixelScreenHeight);
}
else
{
src.filterMode = FilterMode.Bilinear;
tempTex.filterMode = FilterMode.Bilinear;
tempTex.Release();
tempTex.Create();
grassTex.filterMode = FilterMode.Bilinear;
grassTex.Release();
grassTex.Create();
}
if (cloudState == ShaderState.On)
{
var cloudMaterial = CoreUtils.CreateEngineMaterial("Custom/Clouds");
cloudMaterial.SetFloat("_Speed", cloudSpeed);
cloudMaterial.SetFloat("_Coverage", cloudCoverage);
cloudMaterial.SetFloat("_Thickness", cloudThickness);
cloudMaterial.SetFloat("_Direction", cloudDirection);
cloudMaterial.SetTexture("_FineDetail", cloudsFineDetail);
cloudMaterial.SetTexture("_MediumDetail", cloudsMediumDetail);
cloudMaterial.SetTexture("_LargeDetail", cloudsLargeDetail);
var cloudTexTemp = RenderTexture.GetTemporary(2048, 2048);
cloudTexTemp.filterMode = FilterMode.Bilinear;
cloudTexTemp.wrapMode = TextureWrapMode.Repeat;
cloudTex.filterMode = FilterMode.Bilinear;
cloudTex.wrapMode = TextureWrapMode.Repeat;
Graphics.Blit(cloudTexTemp, cloudTex, cloudMaterial);
RenderTexture.ReleaseTemporary(cloudTexTemp);
lightSource.cookie = cloudTex;
lightSource.cookieSize = cloudZoom;
}
else
{
lightSource.cookie = null;
}
outlineMaterial.SetVector("_ScreenSize", screenSize);
Camera grassCamera = null;
if (grassState == ShaderState.On)
{
grassCamera = _grassCameraObject.GetComponent<Camera>();
grassCamera.enabled = false;
}
if (grassState == ShaderState.On && outlineState != ShaderState.Debug && grassCamera != null)
{
// var grassCameraObject = new GameObject("GrassCamera");
// grassCameraObject.transform.SetParent(Camera.main.transform);
// var grassCamera = _grassCameraObject.GetComponent<Camera>();
grassCamera.CopyFrom(Camera.main);
grassCamera.targetTexture = grassTex;
grassCamera.cullingMask = -1;
grassCamera.clearFlags = CameraClearFlags.Nothing;
grassCamera.enabled = true;
grassCamera.RenderWithShader(grassReplacementShader, "RenderType");
grassCamera.enabled = false;
// Destroy(grassCameraObject);
grassBlendingMaterial.SetTexture("_GrassTex", grassTex);
}
if (outlineState != ShaderState.Off)
{
Graphics.Blit(src, tempTex, outlineMaterial);
if (grassState == ShaderState.On && outlineState != ShaderState.Debug)
Graphics.Blit(tempTex, dest, grassBlendingMaterial);
else
Graphics.Blit(tempTex, dest);
}
else if (grassState == ShaderState.On)
{
Graphics.Blit(src, tempTex, grassBlendingMaterial);
Graphics.Blit(tempTex, dest);
}
else
{
Graphics.Blit(src, tempTex);
Graphics.Blit(tempTex, dest);
}
if (grassCamera != null)
grassCamera.targetTexture = null;
RenderTexture.ReleaseTemporary(tempTex);
RenderTexture.ReleaseTemporary(grassTex);
RenderTexture.ReleaseTemporary(cloudTex);
Graphics.SetRenderTarget(dest);
}
}
// using UnityEngine;
// using UnityEngine.Rendering;
// [RequireComponent(typeof(Camera)),
// RequireComponent(typeof(SceneColorSetup))]
// public class PostProcesser : MonoBehaviour
// {
// [Header("Grass Overlaying Shaders")]
// public LayerMask grassLayer;
// public ShaderState grassState = ShaderState.On;
// public Shader grassReplacementShader;
// public float alphaThreshold = 0.5f;
// private GameObject _grassCameraObject;
// [Header("Pixel Shader")]
// public ShaderState pixelState = ShaderState.On;
// public bool dynamicPixelSize = false;
// public int screenHeight = 192;
// public float pixelsPerUnit = 24f;
// [Range(1f / 32f, 1)] public float zoom = 0.125f;
// [Header("Outline Shader")]
// public ShaderState outlineState = ShaderState.On;
// public Color outlineColor = Color.black;
// public Color edgeColor = Color.white;
// public float depthThreshold = 0.02f;
// public float normalThreshold = 0.05f;
// public Vector3 normalEdgeBias = Vector3.one;
// public float angleThreshold = 0.5f;
// public int angleFactorScale = 7;
// [Header("Cloud Shader")]
// public ShaderState cloudState = ShaderState.On;
// public Texture2D cloudsFineDetail;
// public Texture2D cloudsMediumDetail;
// public Texture2D cloudsLargeDetail;
// public Light lightSource;
// public float cloudSpeed = 0.1f;
// [Range(0, 1)] public float cloudThickness = 0.5f;
// [Range(0, 1)] public float cloudCoverage = 0.5f;
// [Range(0, 360)] public float cloudDirection = 30f;
// public float cloudZoom = 10f;
// public enum ShaderState
// {
// On,
// Off,
// Debug,
// }
// void OnEnable()
// {
// Camera.main.depthTextureMode = DepthTextureMode.DepthNormals;
// if (grassState != ShaderState.Debug)
// Camera.main.cullingMask = ~(1 << (int)Mathf.Log(grassLayer.value, 2));
// if (grassState == ShaderState.On && _grassCameraObject == null)
// {
// _grassCameraObject = new GameObject("GrassCamera");
// _grassCameraObject.transform.SetParent(Camera.main.transform);
// _grassCameraObject.AddComponent<Camera>();
// }
// }
// void OnDisable()
// {
// if (_grassCameraObject != null)
// {
// Destroy(_grassCameraObject);
// _grassCameraObject = null;
// }
// }
// void UpdateZoom()
// {
// if (Camera.main == null)
// return;
// Camera.main.orthographicSize = 1 / zoom;
// var farPlane = 20 / zoom;
// var pos = Camera.main.transform.localPosition;
// pos.z = -farPlane / 2;
// Camera.main.transform.SetLocalPositionAndRotation(pos, Quaternion.identity);
// Camera.main.farClipPlane = farPlane;
// }
// void OnValidate()
// {
// UpdateZoom();
// }
// void OnRenderImage(RenderTexture src, RenderTexture dest)
// {
// var outlineMaterial = CoreUtils.CreateEngineMaterial("Custom/PixelPerfectOutline");
// outlineMaterial.SetFloat("_DepthThreshold", depthThreshold);
// outlineMaterial.SetFloat("_AngleThreshold", angleThreshold);
// outlineMaterial.SetFloat("_AngleFactorScale", angleFactorScale);
// outlineMaterial.SetFloat("_NormalThreshold", normalThreshold);
// outlineMaterial.SetVector("_NormalEdgeBias", normalEdgeBias);
// outlineMaterial.SetInteger("_DebugOutline", outlineState == ShaderState.Debug ? 1 : 0);
// outlineMaterial.SetColor("_OutlineColor", outlineColor);
// outlineMaterial.SetColor("_EdgeColor", edgeColor);
// var grassBlendingMaterial = CoreUtils.CreateEngineMaterial("Custom/GrassBlending");
// grassBlendingMaterial.SetFloat("_AlphaThreshold", alphaThreshold);
// UpdateZoom();
// var pixelScreenHeight = screenHeight;
// if (dynamicPixelSize)
// {
// pixelScreenHeight = (int)(1 / zoom * pixelsPerUnit);
// }
// var pixelScreenWidth = (int)(pixelScreenHeight * Camera.main.aspect + 0.5f);
// var tempTex = RenderTexture.GetTemporary(src.descriptor);
// var grassTex = RenderTexture.GetTemporary(src.descriptor);
// var cloudTex = RenderTexture.GetTemporary(2048, 2048);
// var screenSize = new Vector2(Screen.width, Screen.height);
// if (pixelState == ShaderState.On)
// {
// src.filterMode = FilterMode.Point;
// tempTex.Release();
// tempTex.height = pixelScreenHeight;
// tempTex.width = pixelScreenWidth;
// tempTex.filterMode = FilterMode.Point;
// tempTex.Create();
// grassTex.Release();
// grassTex.height = pixelScreenHeight;
// grassTex.width = pixelScreenWidth;
// grassTex.filterMode = FilterMode.Point;
// grassTex.Create();
// screenSize = new Vector2(pixelScreenWidth, pixelScreenHeight);
// }
// else
// {
// src.filterMode = FilterMode.Bilinear;
// tempTex.filterMode = FilterMode.Bilinear;
// tempTex.Release();
// tempTex.Create();
// grassTex.filterMode = FilterMode.Bilinear;
// grassTex.Release();
// grassTex.Create();
// }
// if (cloudState == ShaderState.On)
// {
// var cloudMaterial = CoreUtils.CreateEngineMaterial("Custom/Clouds");
// cloudMaterial.SetFloat("_Speed", cloudSpeed);
// cloudMaterial.SetFloat("_Coverage", cloudCoverage);
// cloudMaterial.SetFloat("_Thickness", cloudThickness);
// cloudMaterial.SetFloat("_Direction", cloudDirection);
// cloudMaterial.SetTexture("_FineDetail", cloudsFineDetail);
// cloudMaterial.SetTexture("_MediumDetail", cloudsMediumDetail);
// cloudMaterial.SetTexture("_LargeDetail", cloudsLargeDetail);
// var cloudTexTemp = RenderTexture.GetTemporary(2048, 2048);
// cloudTexTemp.filterMode = FilterMode.Bilinear;
// cloudTexTemp.wrapMode = TextureWrapMode.Repeat;
// cloudTex.filterMode = FilterMode.Bilinear;
// cloudTex.wrapMode = TextureWrapMode.Repeat;
// Graphics.Blit(cloudTexTemp, cloudTex, cloudMaterial);
// RenderTexture.ReleaseTemporary(cloudTexTemp);
// lightSource.cookie = cloudTex;
// lightSource.cookieSize = cloudZoom;
// }
// else
// {
// lightSource.cookie = null;
// }
// outlineMaterial.SetVector("_ScreenSize", screenSize);
// var grassCamera = _grassCameraObject.GetComponent<Camera>();
// if (grassState == ShaderState.On && outlineState != ShaderState.Debug)
// {
// grassCamera.CopyFrom(Camera.main);
// grassCamera.targetTexture = grassTex;
// grassCamera.cullingMask = -1;
// grassCamera.clearFlags = CameraClearFlags.Nothing;
// grassCamera.RenderWithShader(grassReplacementShader, "RenderType");
// grassBlendingMaterial.SetTexture("_GrassTex", grassTex);
// }
// if (outlineState != ShaderState.Off)
// {
// Graphics.Blit(src, tempTex, outlineMaterial);
// if (grassState == ShaderState.On && outlineState != ShaderState.Debug)
// Graphics.Blit(tempTex, dest, grassBlendingMaterial);
// else
// Graphics.Blit(tempTex, dest);
// }
// else if (grassState == ShaderState.On)
// {
// Graphics.Blit(src, tempTex, grassBlendingMaterial);
// Graphics.Blit(tempTex, dest);
// }
// else
// {
// Graphics.Blit(src, tempTex);
// Graphics.Blit(tempTex, dest);
// }
// if (grassCamera != null)
// grassCamera.targetTexture = null;
// RenderTexture.ReleaseTemporary(tempTex);
// RenderTexture.ReleaseTemporary(grassTex);
// RenderTexture.ReleaseTemporary(cloudTex);
// Graphics.SetRenderTarget(dest);
// }
// }