Flatkit 추가 및 설정

This commit is contained in:
2026-01-25 11:27:33 +09:00
parent 05233497e7
commit cf16910a32
1938 changed files with 408633 additions and 244 deletions

View File

@@ -0,0 +1,362 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
#if UNITY_2022_3_OR_NEWER
using ExternPropertyAttributes;
namespace FlatKit {
public class FlatKitFog : ScriptableRendererFeature {
[Tooltip("To create new settings use 'Create > FlatKit > Fog Settings'.")]
[Expandable]
public FogSettings settings;
private Material _effectMaterial;
private ScreenRenderPass _fullScreenPass;
private bool _requiresColor;
private bool _injectedBeforeTransparents;
private ScriptableRenderPassInput _requirements = ScriptableRenderPassInput.Color;
private Texture2D _lutDepth;
private Texture2D _lutHeight;
private const string ShaderName = "Hidden/FlatKit/FogWrap";
private const string CameraRelativePosition = "FOG_CAMERA_RELATIVE";
private const string UseDistanceFog = "USE_DISTANCE_FOG";
private const string UseHeightFog = "USE_HEIGHT_FOG";
private static int distanceLut => Shader.PropertyToID("_DistanceLUT");
private static int near => Shader.PropertyToID("_Near");
private static int far => Shader.PropertyToID("_Far");
private static int distanceFogIntensity => Shader.PropertyToID("_DistanceFogIntensity");
private static int heightLut => Shader.PropertyToID("_HeightLUT");
private static int lowWorldY => Shader.PropertyToID("_LowWorldY");
private static int highWorldY => Shader.PropertyToID("_HighWorldY");
private static int heightFogIntensity => Shader.PropertyToID("_HeightFogIntensity");
private static int distanceHeightBlend => Shader.PropertyToID("_DistanceHeightBlend");
/// <summary>
/// Access the runtime effect material to override fog parameters at runtime.
/// This enables minimal, code-driven tweaks without changing the Settings asset.
///
/// Shader (2022.3+ path): "Hidden/FlatKit/FogWrap"
///
/// Common shader properties you can set:
/// - Textures: _DistanceLUT (Texture2D), _HeightLUT (Texture2D)
/// - Floats: _Near, _Far, _LowWorldY, _HighWorldY,
/// _DistanceFogIntensity, _HeightFogIntensity, _DistanceHeightBlend
/// - Keywords: USE_DISTANCE_FOG, USE_HEIGHT_FOG, FOG_CAMERA_RELATIVE
///
/// Notes:
/// - If you supply your own LUTs, set _DistanceLUT/_HeightLUT directly.
/// - Settings asset changes (via its inspector) can overwrite your values when applied.
/// </summary>
public Material EffectMaterial => _effectMaterial;
public override void Create() {
// Settings.
{
if (settings == null) return;
settings.onSettingsChanged = null;
settings.onReset = null;
settings.onSettingsChanged += SetMaterialProperties;
settings.onReset += SetMaterialProperties;
}
// Material.
{
#if UNITY_EDITOR
settings.effectMaterial = SubAssetMaterial.GetOrCreate(settings, ShaderName);
if (settings.effectMaterial == null) return;
#endif
_effectMaterial = settings.effectMaterial;
SetMaterialProperties();
}
{
_fullScreenPass = new ScreenRenderPass {
renderPassEvent = settings.renderEvent,
};
_requirements = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Color;
ScriptableRenderPassInput modifiedRequirements = _requirements;
_requiresColor = (_requirements & ScriptableRenderPassInput.Color) != 0;
_injectedBeforeTransparents = settings.renderEvent <= RenderPassEvent.BeforeRenderingTransparents;
if (_requiresColor && !_injectedBeforeTransparents) {
modifiedRequirements ^= ScriptableRenderPassInput.Color;
}
_fullScreenPass.ConfigureInput(modifiedRequirements);
}
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
if (settings == null || !settings.applyInSceneView && renderingData.cameraData.isSceneViewCamera) return;
if (renderingData.cameraData.isPreviewCamera) return;
if (_effectMaterial == null) return;
_fullScreenPass.Setup(_effectMaterial, _requiresColor, _injectedBeforeTransparents, "Flat Kit Fog",
renderingData);
renderer.EnqueuePass(_fullScreenPass);
}
// Re-generate LUT textures when unity disposes them on scene save.
#if UNITY_EDITOR
public override void OnCameraPreCull(ScriptableRenderer renderer, in CameraData cameraData) {
base.OnCameraPreCull(renderer, in cameraData);
if (settings == null || _effectMaterial == null) return;
if (settings.useDistance && !_effectMaterial.GetTexture(distanceLut)) UpdateDistanceLut();
if (settings.useHeight && !_effectMaterial.GetTexture(heightLut)) UpdateHeightLut();
}
#endif
protected override void Dispose(bool disposing) {
_fullScreenPass?.Dispose();
}
private void SetMaterialProperties() {
if (_effectMaterial == null) return;
RendererFeatureUtils.SetKeyword(_effectMaterial, UseDistanceFog, settings.useDistance);
if (settings.useDistance) {
UpdateDistanceLut();
_effectMaterial.SetFloat(near, settings.near);
_effectMaterial.SetFloat(far, settings.far);
_effectMaterial.SetFloat(distanceFogIntensity, settings.distanceFogIntensity);
}
RendererFeatureUtils.SetKeyword(_effectMaterial, UseHeightFog, settings.useHeight);
if (settings.useHeight) {
UpdateHeightLut();
_effectMaterial.SetFloat(lowWorldY, settings.low);
_effectMaterial.SetFloat(highWorldY, settings.high);
_effectMaterial.SetFloat(heightFogIntensity, settings.heightFogIntensity);
_effectMaterial.SetFloat(distanceHeightBlend, settings.distanceHeightBlend);
}
RendererFeatureUtils.SetKeyword(_effectMaterial, CameraRelativePosition, settings.cameraRelativePosition);
}
private void UpdateDistanceLut() {
if (settings.distanceGradient == null) return;
const int width = 256;
const int height = 1;
if (_lutDepth == null) {
_lutDepth = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
wrapMode = TextureWrapMode.Clamp,
hideFlags = HideFlags.HideAndDontSave,
filterMode = FilterMode.Bilinear
};
}
for (float x = 0; x < width; x++) {
Color color = settings.distanceGradient.Evaluate(x / (width - 1));
for (float y = 0; y < height; y++) {
_lutDepth.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
}
}
_lutDepth.Apply();
_effectMaterial.SetTexture(distanceLut, _lutDepth);
}
private void UpdateHeightLut() {
if (settings.heightGradient == null) return;
const int width = 256;
const int height = 1;
if (_lutHeight == null) {
_lutHeight = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
wrapMode = TextureWrapMode.Clamp,
hideFlags = HideFlags.HideAndDontSave,
filterMode = FilterMode.Bilinear
};
}
for (float x = 0; x < width; x++) {
Color color = settings.heightGradient.Evaluate(x / (width - 1));
for (float y = 0; y < height; y++) {
_lutHeight.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
}
}
_lutHeight.Apply();
_effectMaterial.SetTexture(heightLut, _lutHeight);
}
}
}
#else
namespace FlatKit {
public class FlatKitFog : ScriptableRendererFeature {
[Tooltip("To create new settings use 'Create > FlatKit > Fog Settings'.")]
public FogSettings settings;
[SerializeField, HideInInspector]
private Material _effectMaterial;
private BlitTexturePass _blitTexturePass;
private Texture2D _lutDepth;
private Texture2D _lutHeight;
private static readonly string FogShaderName = "Hidden/FlatKit/FogFilter";
private static readonly int DistanceLut = Shader.PropertyToID("_DistanceLUT");
private static readonly int Near = Shader.PropertyToID("_Near");
private static readonly int Far = Shader.PropertyToID("_Far");
private static readonly int UseDistanceFog = Shader.PropertyToID("_UseDistanceFog");
private static readonly int UseDistanceFogOnSky = Shader.PropertyToID("_UseDistanceFogOnSky");
private static readonly int DistanceFogIntensity = Shader.PropertyToID("_DistanceFogIntensity");
private static readonly int HeightLut = Shader.PropertyToID("_HeightLUT");
private static readonly int LowWorldY = Shader.PropertyToID("_LowWorldY");
private static readonly int HighWorldY = Shader.PropertyToID("_HighWorldY");
private static readonly int UseHeightFog = Shader.PropertyToID("_UseHeightFog");
private static readonly int UseHeightFogOnSky = Shader.PropertyToID("_UseHeightFogOnSky");
private static readonly int HeightFogIntensity = Shader.PropertyToID("_HeightFogIntensity");
private static readonly int DistanceHeightBlend = Shader.PropertyToID("_DistanceHeightBlend");
/// <summary>
/// Access the runtime effect material to override fog parameters at runtime.
/// This enables minimal, code-driven tweaks without changing the Settings asset.
///
/// Shader (legacy path): "Hidden/FlatKit/FogFilter"
///
/// Common shader properties you can set:
/// - Textures: _DistanceLUT (Texture2D), _HeightLUT (Texture2D)
/// - Floats: _Near, _Far, _LowWorldY, _HighWorldY,
/// _UseDistanceFog (0/1), _UseDistanceFogOnSky (0/1), _DistanceFogIntensity,
/// _UseHeightFog (0/1), _UseHeightFogOnSky (0/1), _HeightFogIntensity, _DistanceHeightBlend
///
/// Notes:
/// - If you supply your own LUTs, set _DistanceLUT/_HeightLUT directly.
/// - Settings asset changes (via its inspector) can overwrite your values when applied.
/// </summary>
public Material EffectMaterial => _effectMaterial;
public override void Create() {
#if UNITY_EDITOR
if (_effectMaterial == null) {
SubAssetMaterial.AlwaysInclude(BlitTexturePass.CopyEffectShaderName);
SubAssetMaterial.AlwaysInclude(FogShaderName);
}
#endif
if (settings == null) {
return;
}
if (!CreateMaterials()) {
return;
}
SetMaterialProperties();
_blitTexturePass = new BlitTexturePass(_effectMaterial, useDepth: true, useNormals: false, useColor: false);
}
protected override void Dispose(bool disposing) {
_blitTexturePass.Dispose();
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
#if UNITY_EDITOR
if (renderingData.cameraData.isPreviewCamera) return;
if (!settings.applyInSceneView && renderingData.cameraData.cameraType == CameraType.SceneView) return;
#endif
SetMaterialProperties();
_blitTexturePass.Setup(renderingData);
_blitTexturePass.renderPassEvent = settings.renderEvent;
renderer.EnqueuePass(_blitTexturePass);
}
private bool CreateMaterials() {
if (_effectMaterial == null) {
var effectShader = Shader.Find(FogShaderName);
var blitShader = Shader.Find(BlitTexturePass.CopyEffectShaderName);
if (effectShader == null || blitShader == null) return false;
_effectMaterial = UnityEngine.Rendering.CoreUtils.CreateEngineMaterial(effectShader);
}
return _effectMaterial != null;
}
private void SetMaterialProperties() {
if (_effectMaterial == null) {
return;
}
UpdateDistanceLut();
_effectMaterial.SetTexture(DistanceLut, _lutDepth);
_effectMaterial.SetFloat(Near, settings.near);
_effectMaterial.SetFloat(Far, settings.far);
_effectMaterial.SetFloat(UseDistanceFog, settings.useDistance ? 1f : 0f);
_effectMaterial.SetFloat(UseDistanceFogOnSky, settings.useDistanceFogOnSky ? 1f : 0f);
_effectMaterial.SetFloat(DistanceFogIntensity, settings.distanceFogIntensity);
UpdateHeightLut();
_effectMaterial.SetTexture(HeightLut, _lutHeight);
_effectMaterial.SetFloat(LowWorldY, settings.low);
_effectMaterial.SetFloat(HighWorldY, settings.high);
_effectMaterial.SetFloat(UseHeightFog, settings.useHeight ? 1f : 0f);
_effectMaterial.SetFloat(UseHeightFogOnSky, settings.useHeightFogOnSky ? 1f : 0f);
_effectMaterial.SetFloat(HeightFogIntensity, settings.heightFogIntensity);
_effectMaterial.SetFloat(DistanceHeightBlend, settings.distanceHeightBlend);
}
private void UpdateDistanceLut() {
if (settings.distanceGradient == null) return;
if (_lutDepth != null) {
DestroyImmediate(_lutDepth);
}
const int width = 256;
const int height = 1;
_lutDepth = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
wrapMode = TextureWrapMode.Clamp,
hideFlags = HideFlags.HideAndDontSave,
filterMode = FilterMode.Bilinear
};
//22b5f7ed-989d-49d1-90d9-c62d76c3081a
for (float x = 0; x < width; x++) {
Color color = settings.distanceGradient.Evaluate(x / (width - 1));
for (float y = 0; y < height; y++) {
_lutDepth.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
}
}
_lutDepth.Apply();
}
private void UpdateHeightLut() {
if (settings.heightGradient == null) return;
if (_lutHeight != null) {
DestroyImmediate(_lutHeight);
}
const int width = 256;
const int height = 1;
_lutHeight = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
wrapMode = TextureWrapMode.Clamp,
hideFlags = HideFlags.HideAndDontSave,
filterMode = FilterMode.Bilinear
};
for (float x = 0; x < width; x++) {
Color color = settings.heightGradient.Evaluate(x / (width - 1));
for (float y = 0; y < height; y++) {
_lutHeight.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
}
}
_lutHeight.Apply();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 770acbaed70db4ad696458511aa3f084
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
#ifndef FLAT_KIT_FOG_INCLUDED
#define FLAT_KIT_FOG_INCLUDED
TEXTURE2D_X (_BlitTexture);
SAMPLER (sampler_BlitTexture);
float Linear01Depth(float z)
{
const float isOrtho = unity_OrthoParams.w;
const float isPers = 1.0 - unity_OrthoParams.w;
z *= _ZBufferParams.x;
return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y);
}
float LinearEyeDepth(float z)
{
return rcp(_ZBufferParams.z * z + _ZBufferParams.w);
}
float4 SampleCameraColor(float2 uv)
{
return SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, UnityStereoTransformScreenSpaceTex(uv));
}
void Fog_float(float2 UV, out float4 Out)
{
float4 original = SampleCameraColor(UV);
float fogBlend = _DistanceHeightBlend;
float depthPacked = SampleSceneDepth(UV);
#if defined(USE_DISTANCE_FOG)
const float depthCameraPlanes = Linear01Depth(depthPacked);
const float depthAbsolute = _ProjectionParams.y + (_ProjectionParams.z - _ProjectionParams.y) * depthCameraPlanes;
const float depthFogPlanes = saturate((depthAbsolute - _Near) / (_Far - _Near));
float4 distanceFog = SAMPLE_TEXTURE2D_X(_DistanceLUT, sampler_DistanceLUT, float2(depthFogPlanes, 0.5));
distanceFog.a *= _DistanceFogIntensity;
#else
float4 distanceFog = float4(0, 0, 0, 0);
fogBlend = 1.0;
#endif
#if defined(USE_HEIGHT_FOG)
#if defined(FOG_CAMERA_RELATIVE)
const float3 worldPos = float3(UV, depthPacked) * LinearEyeDepth(depthPacked) + _WorldSpaceCameraPos;
#else
#if !UNITY_REVERSED_Z
// Adjust z to match NDC for OpenGL
depthPacked = lerp(UNITY_NEAR_CLIP_VALUE, 1, depthPacked);
#endif
const float3 worldPos = ComputeWorldSpacePosition(UV, depthPacked, UNITY_MATRIX_I_VP);
#endif
const float heightUV = saturate((worldPos.y - _LowWorldY) / (_HighWorldY - _LowWorldY));
float4 heightFog = SAMPLE_TEXTURE2D_X(_HeightLUT, sampler_HeightLUT, float2(heightUV, 0.5));
heightFog.a *= _HeightFogIntensity;
#else
float4 heightFog = float4(0, 0, 0, 0);
fogBlend = 0.0;
#endif
const float4 fog = lerp(distanceFog, heightFog, fogBlend);
float4 final = lerp(original, fog, fog.a);
final.a = original.a;
Out = final;
}
#endif // FLAT_KIT_FOG_INCLUDED

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 44d13df04220413aa6b3f8ee1597a610
timeCreated: 1691556962

View File

@@ -0,0 +1,149 @@
using System;
using ExternPropertyAttributes;
using UnityEngine;
using UnityEngine.Rendering.Universal;
// ReSharper disable RedundantDefaultMemberInitializer
#if UNITY_2022_3_OR_NEWER
namespace FlatKit {
[CreateAssetMenu(fileName = "FogSettings", menuName = "FlatKit/Fog Settings")]
public class FogSettings : ScriptableObject {
[Space] // Expandable.
[Label("<b>Distance Fog</b>")]
[Tooltip("Whether to use distance fog. This is the fog that fades out the scene into the background.")]
public bool useDistance = true;
[Tooltip("The color changes from near (left) to far (right).")]
[Label(" Distance Gradient"), ShowIf(nameof(useDistance))]
public Gradient distanceGradient;
[Tooltip("The distance from the camera in world units at which the fog starts.")]
[Label(" Near"), ShowIf(nameof(useDistance))]
public float near = 0;
[Tooltip("The distance from the camera in world units at which the fog ends.")]
[Label(" Far"), ShowIf(nameof(useDistance))]
public float far = 100;
[Range(0, 1)]
[Tooltip("How much the fog should be applied. 0 means no fog, 1 means full fog.")]
[Label(" Intensity"), ShowIf(nameof(useDistance))]
public float distanceFogIntensity = 1.0f;
[Space(12)]
[HorizontalLine(1, EColor.Translucent)]
[Label("<b>Height Fog</b>")]
[Tooltip("Whether to use height fog. This is the fog that goes up from the ground.")]
public bool useHeight = false;
[Tooltip("The color changes from low (left) to high (right).")]
[Label(" Height Gradient"), ShowIf(nameof(useHeight))]
public Gradient heightGradient;
[Tooltip("The height in world units at which the fog starts.")]
[Label(" Low"), ShowIf(nameof(useHeight))]
public float low = 0;
[Tooltip("The height in world units at which the fog ends.")]
[Label(" High"), ShowIf(nameof(useHeight))]
public float high = 10;
[Range(0, 1)]
[Tooltip("How much the fog should be applied. 0 means no fog, 1 means full fog.")]
[Label(" Intensity"), ShowIf(nameof(useHeight))]
public float heightFogIntensity = 1.0f;
[Tooltip("Reverts fog behavior to pre-3.9.0. This is useful if you want to use the new fog settings, but want to " +
"keep the old look of your scene.")]
[Label(" Camera Relative Position"), ShowIf(nameof(useHeight))]
public bool cameraRelativePosition = false;
[Space(12)]
[HorizontalLine]
[Header("Blending")]
[Range(0, 1)]
[Tooltip("The ratio between distance and height fog. 0 means only distance fog, 1 means only height fog.")]
[Label(" Distance/Height Blend")]
public float distanceHeightBlend = 0.5f;
[Header("Advanced Settings")]
[Tooltip("The render stage at which the effect is applied. To exclude transparent objects, like water or " +
"UI elements, set this to \"Before Transparent\".")]
[Label(" Render Event")]
public RenderPassEvent renderEvent = RenderPassEvent.BeforeRenderingPostProcessing;
[Tooltip("Whether the effect should be applied in the Scene view as well as in the Game view. Please keep in " +
"mind that Unity always renders the scene view with the default Renderer settings of the URP config.")]
[Label(" Apply In Scene View")]
public bool applyInSceneView = true;
[HideInInspector]
public Material effectMaterial;
internal Action onSettingsChanged;
internal Action onReset;
private void OnValidate() {
low = Mathf.Min(low, high);
high = Mathf.Max(low, high);
onSettingsChanged?.Invoke();
}
private void Reset() {
onReset?.Invoke();
}
private void OnDestroy() {
onSettingsChanged = null;
onReset = null;
}
}
}
#else
namespace FlatKit {
[CreateAssetMenu(fileName = "FogSettings", menuName = "FlatKit/Fog Settings")]
public class FogSettings : ScriptableObject {
[Header("Distance Fog")]
public bool useDistance = true;
public Gradient distanceGradient;
public float near = 0;
public float far = 100;
[Range(0, 1)]
public float distanceFogIntensity = 1.0f;
public bool useDistanceFogOnSky = false;
[Header("Height Fog")]
[Space]
public bool useHeight = false;
public Gradient heightGradient;
public float low = 0;
public float high = 10;
[Range(0, 1)]
public float heightFogIntensity = 1.0f;
public bool useHeightFogOnSky = false;
[Header("Blending")]
[Space]
[Range(0, 1)]
public float distanceHeightBlend = 0.5f;
[Header("Advanced settings")]
[Space, Tooltip("The render stage at which the effect is applied. To exclude transparent objects, like water or " +
"UI elements, set this to \"Before Transparent\".")]
public RenderPassEvent renderEvent = RenderPassEvent.BeforeRenderingPostProcessing;
[Tooltip("Whether the effect should be applied in the Scene view as well as in the Game view. Please keep in " +
"mind that Unity always renders the scene view with the default Renderer settings of the URP config.")]
public bool applyInSceneView = true;
private void OnValidate() {
low = Mathf.Min(low, high);
high = Mathf.Max(low, high);
}
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8a6f656ab8114e939b71b289ffd9d7b2
timeCreated: 1585524905

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c77db07224d9f784d90d7eb0e84c57f7
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}