Stable version

This commit is contained in:
Kasutaja
2023-04-30 14:23:57 +03:00
parent cdbdbc28c4
commit 294d6117e3
1861 changed files with 1697361 additions and 6747 deletions

View File

@@ -0,0 +1,272 @@
//
// Kino/Bloom v2 - Bloom filter for Unity
//
// Copyright (C) 2015, 2016 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Modified by Jean Moreno for Cartoon FX Remaster Demo
// - effect previews in SceneView
// - disabled a code warning
using UnityEngine;
namespace Kino
{
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[ImageEffectAllowedInSceneView]
public class Bloom : MonoBehaviour
{
#region Public Properties
/// Prefilter threshold (gamma-encoded)
/// Filters out pixels under this level of brightness.
public float thresholdGamma
{
get { return Mathf.Max(_threshold, 0); }
set { _threshold = value; }
}
/// Prefilter threshold (linearly-encoded)
/// Filters out pixels under this level of brightness.
public float thresholdLinear
{
get { return GammaToLinear(thresholdGamma); }
set { _threshold = LinearToGamma(value); }
}
[SerializeField]
[Tooltip("Filters out pixels under this level of brightness.")]
float _threshold = 0.8f;
/// Soft-knee coefficient
/// Makes transition between under/over-threshold gradual.
public float softKnee
{
get { return _softKnee; }
set { _softKnee = value; }
}
[SerializeField, Range(0, 1)]
[Tooltip("Makes transition between under/over-threshold gradual.")]
float _softKnee = 0.5f;
/// Bloom radius
/// Changes extent of veiling effects in a screen
/// resolution-independent fashion.
public float radius
{
get { return _radius; }
set { _radius = value; }
}
[SerializeField, Range(1, 7)]
[Tooltip("Changes extent of veiling effects\n" +
"in a screen resolution-independent fashion.")]
float _radius = 2.5f;
/// Bloom intensity
/// Blend factor of the result image.
public float intensity
{
get { return Mathf.Max(_intensity, 0); }
set { _intensity = value; }
}
[SerializeField]
[Tooltip("Blend factor of the result image.")]
float _intensity = 0.8f;
/// High quality mode
/// Controls filter quality and buffer resolution.
public bool highQuality
{
get { return _highQuality; }
set { _highQuality = value; }
}
[SerializeField]
[Tooltip("Controls filter quality and buffer resolution.")]
bool _highQuality = true;
/// Anti-flicker filter
/// Reduces flashing noise with an additional filter.
[SerializeField]
[Tooltip("Reduces flashing noise with an additional filter.")]
bool _antiFlicker = true;
public bool antiFlicker
{
get { return _antiFlicker; }
set { _antiFlicker = value; }
}
#endregion
#region Private Members
#pragma warning disable 0649
[SerializeField, HideInInspector]
Shader _shader;
#pragma warning restore 0649
Material _material;
const int kMaxIterations = 16;
RenderTexture[] _blurBuffer1 = new RenderTexture[kMaxIterations];
RenderTexture[] _blurBuffer2 = new RenderTexture[kMaxIterations];
float LinearToGamma(float x)
{
#if UNITY_5_3_OR_NEWER
return Mathf.LinearToGammaSpace(x);
#else
if (x <= 0.0031308f)
return 12.92f * x;
else
return 1.055f * Mathf.Pow(x, 1 / 2.4f) - 0.055f;
#endif
}
float GammaToLinear(float x)
{
#if UNITY_5_3_OR_NEWER
return Mathf.GammaToLinearSpace(x);
#else
if (x <= 0.04045f)
return x / 12.92f;
else
return Mathf.Pow((x + 0.055f) / 1.055f, 2.4f);
#endif
}
#endregion
#region MonoBehaviour Functions
void OnEnable()
{
var shader = _shader ? _shader : Shader.Find("Hidden/Kino/Bloom");
_material = new Material(shader);
_material.hideFlags = HideFlags.DontSave;
}
void OnDisable()
{
DestroyImmediate(_material);
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
var useRGBM = Application.isMobilePlatform;
// source texture size
var tw = source.width;
var th = source.height;
// halve the texture size for the low quality mode
if (!_highQuality)
{
tw /= 2;
th /= 2;
}
// blur buffer format
var rtFormat = useRGBM ?
RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR;
// determine the iteration count
var logh = Mathf.Log(th, 2) + _radius - 8;
var logh_i = (int)logh;
var iterations = Mathf.Clamp(logh_i, 1, kMaxIterations);
// update the shader properties
var lthresh = thresholdLinear;
_material.SetFloat("_Threshold", lthresh);
var knee = lthresh * _softKnee + 1e-5f;
var curve = new Vector3(lthresh - knee, knee * 2, 0.25f / knee);
_material.SetVector("_Curve", curve);
var pfo = !_highQuality && _antiFlicker;
_material.SetFloat("_PrefilterOffs", pfo ? -0.5f : 0.0f);
_material.SetFloat("_SampleScale", 0.5f + logh - logh_i);
_material.SetFloat("_Intensity", intensity);
// prefilter pass
var prefiltered = RenderTexture.GetTemporary(tw, th, 0, rtFormat);
var pass = _antiFlicker ? 1 : 0;
Graphics.Blit(source, prefiltered, _material, pass);
// construct a mip pyramid
var last = prefiltered;
for (var level = 0; level < iterations; level++)
{
_blurBuffer1[level] = RenderTexture.GetTemporary(
last.width / 2, last.height / 2, 0, rtFormat
);
pass = (level == 0) ? (_antiFlicker ? 3 : 2) : 4;
Graphics.Blit(last, _blurBuffer1[level], _material, pass);
last = _blurBuffer1[level];
}
// upsample and combine loop
for (var level = iterations - 2; level >= 0; level--)
{
var basetex = _blurBuffer1[level];
_material.SetTexture("_BaseTex", basetex);
_blurBuffer2[level] = RenderTexture.GetTemporary(
basetex.width, basetex.height, 0, rtFormat
);
pass = _highQuality ? 6 : 5;
Graphics.Blit(last, _blurBuffer2[level], _material, pass);
last = _blurBuffer2[level];
}
// finish process
_material.SetTexture("_BaseTex", source);
pass = _highQuality ? 8 : 7;
Graphics.Blit(last, destination, _material, pass);
// release the temporary buffers
for (var i = 0; i < kMaxIterations; i++)
{
if (_blurBuffer1[i] != null)
RenderTexture.ReleaseTemporary(_blurBuffer1[i]);
if (_blurBuffer2[i] != null)
RenderTexture.ReleaseTemporary(_blurBuffer2[i]);
_blurBuffer1[i] = null;
_blurBuffer2[i] = null;
}
RenderTexture.ReleaseTemporary(prefiltered);
}
#endregion
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 6363bba448bf64e60a763433f9ddf81b
timeCreated: 1445671165
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences:
- _shader: {fileID: 4800000, guid: 5a711a01011934ebcb58ef5ad52159d6, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0e7e3e77db40c4cba83bb3a6ab440084
folderAsset: yes
timeCreated: 1445666764
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
//
// Kino/Bloom v2 - Bloom filter for Unity
//
// Copyright (C) 2015, 2016 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
using UnityEngine;
using UnityEditor;
namespace Kino
{
[CanEditMultipleObjects]
[CustomEditor(typeof(Bloom))]
public class BloomEditor : Editor
{
BloomGraphDrawer _graph;
SerializedProperty _threshold;
SerializedProperty _softKnee;
SerializedProperty _radius;
SerializedProperty _intensity;
SerializedProperty _highQuality;
SerializedProperty _antiFlicker;
static GUIContent _textThreshold = new GUIContent("Threshold (gamma)");
void OnEnable()
{
_graph = new BloomGraphDrawer();
_threshold = serializedObject.FindProperty("_threshold");
_softKnee = serializedObject.FindProperty("_softKnee");
_radius = serializedObject.FindProperty("_radius");
_intensity = serializedObject.FindProperty("_intensity");
_highQuality = serializedObject.FindProperty("_highQuality");
_antiFlicker = serializedObject.FindProperty("_antiFlicker");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (!serializedObject.isEditingMultipleObjects) {
EditorGUILayout.Space();
_graph.Prepare((Bloom)target);
_graph.DrawGraph();
EditorGUILayout.Space();
}
EditorGUILayout.PropertyField(_threshold, _textThreshold);
EditorGUILayout.PropertyField(_softKnee);
EditorGUILayout.PropertyField(_intensity);
EditorGUILayout.PropertyField(_radius);
EditorGUILayout.PropertyField(_highQuality);
EditorGUILayout.PropertyField(_antiFlicker);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 036bc30d96c3349ce86bfc8d95667da7
timeCreated: 1435816745
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,183 @@
//
// Kino/Bloom v2 - Bloom filter for Unity
//
// Copyright (C) 2015, 2016 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
using UnityEngine;
using UnityEditor;
namespace Kino
{
// Class used for drawing the brightness response curve
public class BloomGraphDrawer
{
#region Public Methods
// Update internal state with a given bloom instance.
public void Prepare(Bloom bloom)
{
#if UNITY_5_6_OR_NEWER
if (bloom.GetComponent<Camera>().allowHDR)
#else
if (bloom.GetComponent<Camera>().hdr)
#endif
{
_rangeX = 6;
_rangeY = 1.5f;
}
else
{
_rangeX = 1;
_rangeY = 1;
}
_threshold = bloom.thresholdLinear;
_knee = bloom.softKnee * _threshold + 1e-5f;
// Intensity is capped to prevent sampling errors.
_intensity = Mathf.Min(bloom.intensity, 10);
}
// Draw the graph at the current position.
public void DrawGraph()
{
_rectGraph = GUILayoutUtility.GetRect(128, 80);
// Background
DrawRect(0, 0, _rangeX, _rangeY, 0.1f, 0.4f);
// Soft-knee range
DrawRect(_threshold - _knee, 0, _threshold + _knee, _rangeY, 0.25f, -1);
// Horizontal lines
for (var i = 1; i < _rangeY; i++)
DrawLine(0, i, _rangeX, i, 0.4f);
// Vertical lines
for (var i = 1; i < _rangeX; i++)
DrawLine(i, 0, i, _rangeY, 0.4f);
// Label
Handles.Label(
PointInRect(0, _rangeY) + Vector3.right,
"Brightness Response (linear)", EditorStyles.miniLabel
);
// Threshold line
DrawLine(_threshold, 0, _threshold, _rangeY, 0.6f);
// Response curve
var vcount = 0;
while (vcount < _curveResolution)
{
var x = _rangeX * vcount / (_curveResolution - 1);
var y = ResponseFunction(x);
if (y < _rangeY)
{
_curveVertices[vcount++] = PointInRect(x, y);
}
else
{
if (vcount > 1)
{
// Extend the last segment to the top edge of the rect.
var v1 = _curveVertices[vcount - 2];
var v2 = _curveVertices[vcount - 1];
var clip = (_rectGraph.y - v1.y) / (v2.y - v1.y);
_curveVertices[vcount - 1] = v1 + (v2 - v1) * clip;
}
break;
}
}
if (vcount > 1)
{
Handles.color = Color.white * 0.9f;
Handles.DrawAAPolyLine(2.0f, vcount, _curveVertices);
}
}
#endregion
#region Response Function
float _threshold;
float _knee;
float _intensity;
float ResponseFunction(float x)
{
var rq = Mathf.Clamp(x - _threshold + _knee, 0, _knee * 2);
rq = rq * rq * 0.25f / _knee;
return Mathf.Max(rq, x - _threshold) * _intensity;
}
#endregion
#region Graph Functions
// Number of vertices in curve
const int _curveResolution = 96;
// Vertex buffers
Vector3[] _rectVertices = new Vector3[4];
Vector3[] _lineVertices = new Vector3[2];
Vector3[] _curveVertices = new Vector3[_curveResolution];
Rect _rectGraph;
float _rangeX;
float _rangeY;
// Transform a point into the graph rect.
Vector3 PointInRect(float x, float y)
{
x = Mathf.Lerp(_rectGraph.x, _rectGraph.xMax, x / _rangeX);
y = Mathf.Lerp(_rectGraph.yMax, _rectGraph.y, y / _rangeY);
return new Vector3(x, y, 0);
}
// Draw a line in the graph rect.
void DrawLine(float x1, float y1, float x2, float y2, float grayscale)
{
_lineVertices[0] = PointInRect(x1, y1);
_lineVertices[1] = PointInRect(x2, y2);
Handles.color = Color.white * grayscale;
Handles.DrawAAPolyLine(2.0f, _lineVertices);
}
// Draw a rect in the graph rect.
void DrawRect(float x1, float y1, float x2, float y2, float fill, float line)
{
_rectVertices[0] = PointInRect(x1, y1);
_rectVertices[1] = PointInRect(x2, y1);
_rectVertices[2] = PointInRect(x2, y2);
_rectVertices[3] = PointInRect(x1, y2);
Handles.DrawSolidRectangleWithOutline(
_rectVertices,
fill < 0 ? Color.clear : Color.white * fill,
line < 0 ? Color.clear : Color.white * line
);
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4afcb2949e7fb42679b587b8848b7e02
timeCreated: 1457674915
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
{
"name": "ToonyColorsPro.Demo.Editor",
"references": [
"KinoBloom.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cd0a5c04eb538be45bab7f699da24bec
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
Bloom Post Effect by Keijiro Takahashi
https://github.com/keijiro/KinoBloom
---------------------------------------
MIT License
Copyright (c) 2015-2017 Keijiro Takahashi
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fd252a094a85ae0499ad570e08e4652f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"name": "KinoBloom.Runtime"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fb9ff7b799c73af479a69874581439d3
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f44dd1607e93a4131a4003b39c363e93
folderAsset: yes
timeCreated: 1445666764
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,251 @@
//
// Kino/Bloom v2 - Bloom filter for Unity
//
// Copyright (C) 2015, 2016 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include "UnityCG.cginc"
// Mobile: use RGBM instead of float/half RGB
#define USE_RGBM defined(SHADER_API_MOBILE)
sampler2D _MainTex;
sampler2D _BaseTex;
float2 _MainTex_TexelSize;
float2 _BaseTex_TexelSize;
half4 _MainTex_ST;
half4 _BaseTex_ST;
float _PrefilterOffs;
half _Threshold;
half3 _Curve;
float _SampleScale;
half _Intensity;
// Brightness function
half Brightness(half3 c)
{
return max(max(c.r, c.g), c.b);
}
// 3-tap median filter
half3 Median(half3 a, half3 b, half3 c)
{
return a + b + c - min(min(a, b), c) - max(max(a, b), c);
}
// Clamp HDR value within a safe range
half3 SafeHDR(half3 c) { return min(c, 65000); }
half4 SafeHDR(half4 c) { return min(c, 65000); }
// RGBM encoding/decoding
half4 EncodeHDR(float3 rgb)
{
#if USE_RGBM
rgb *= 1.0 / 8;
float m = max(max(rgb.r, rgb.g), max(rgb.b, 1e-6));
m = ceil(m * 255) / 255;
return half4(rgb / m, m);
#else
return half4(rgb, 0);
#endif
}
float3 DecodeHDR(half4 rgba)
{
#if USE_RGBM
return rgba.rgb * rgba.a * 8;
#else
return rgba.rgb;
#endif
}
// Downsample with a 4x4 box filter
half3 DownsampleFilter(float2 uv)
{
float4 d = _MainTex_TexelSize.xyxy * float4(-1, -1, +1, +1);
half3 s;
s = DecodeHDR(tex2D(_MainTex, uv + d.xy));
s += DecodeHDR(tex2D(_MainTex, uv + d.zy));
s += DecodeHDR(tex2D(_MainTex, uv + d.xw));
s += DecodeHDR(tex2D(_MainTex, uv + d.zw));
return s * (1.0 / 4);
}
// Downsample with a 4x4 box filter + anti-flicker filter
half3 DownsampleAntiFlickerFilter(float2 uv)
{
float4 d = _MainTex_TexelSize.xyxy * float4(-1, -1, +1, +1);
half3 s1 = DecodeHDR(tex2D(_MainTex, uv + d.xy));
half3 s2 = DecodeHDR(tex2D(_MainTex, uv + d.zy));
half3 s3 = DecodeHDR(tex2D(_MainTex, uv + d.xw));
half3 s4 = DecodeHDR(tex2D(_MainTex, uv + d.zw));
// Karis's luma weighted average (using brightness instead of luma)
half s1w = 1 / (Brightness(s1) + 1);
half s2w = 1 / (Brightness(s2) + 1);
half s3w = 1 / (Brightness(s3) + 1);
half s4w = 1 / (Brightness(s4) + 1);
half one_div_wsum = 1 / (s1w + s2w + s3w + s4w);
return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum;
}
half3 UpsampleFilter(float2 uv)
{
#if HIGH_QUALITY
// 9-tap bilinear upsampler (tent filter)
float4 d = _MainTex_TexelSize.xyxy * float4(1, 1, -1, 0) * _SampleScale;
half3 s;
s = DecodeHDR(tex2D(_MainTex, uv - d.xy));
s += DecodeHDR(tex2D(_MainTex, uv - d.wy)) * 2;
s += DecodeHDR(tex2D(_MainTex, uv - d.zy));
s += DecodeHDR(tex2D(_MainTex, uv + d.zw)) * 2;
s += DecodeHDR(tex2D(_MainTex, uv )) * 4;
s += DecodeHDR(tex2D(_MainTex, uv + d.xw)) * 2;
s += DecodeHDR(tex2D(_MainTex, uv + d.zy));
s += DecodeHDR(tex2D(_MainTex, uv + d.wy)) * 2;
s += DecodeHDR(tex2D(_MainTex, uv + d.xy));
return s * (1.0 / 16);
#else
// 4-tap bilinear upsampler
float4 d = _MainTex_TexelSize.xyxy * float4(-1, -1, +1, +1) * (_SampleScale * 0.5);
half3 s;
s = DecodeHDR(tex2D(_MainTex, uv + d.xy));
s += DecodeHDR(tex2D(_MainTex, uv + d.zy));
s += DecodeHDR(tex2D(_MainTex, uv + d.xw));
s += DecodeHDR(tex2D(_MainTex, uv + d.zw));
return s * (1.0 / 4);
#endif
}
//
// Vertex shader
//
v2f_img vert(appdata_img v)
{
v2f_img o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST);
return o;
}
struct v2f_multitex
{
float4 pos : SV_POSITION;
float2 uvMain : TEXCOORD0;
float2 uvBase : TEXCOORD1;
};
v2f_multitex vert_multitex(appdata_img v)
{
v2f_multitex o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uvMain = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST);
o.uvBase = UnityStereoScreenSpaceUVAdjust(v.texcoord, _BaseTex_ST);
#if UNITY_UV_STARTS_AT_TOP
if (_BaseTex_TexelSize.y < 0.0)
o.uvBase.y = 1.0 - v.texcoord.y;
#endif
return o;
}
//
// fragment shader
//
half4 frag_prefilter(v2f_img i) : SV_Target
{
float2 uv = i.uv + _MainTex_TexelSize.xy * _PrefilterOffs;
#if ANTI_FLICKER
float3 d = _MainTex_TexelSize.xyx * float3(1, 1, 0);
half4 s0 = SafeHDR(tex2D(_MainTex, uv));
half3 s1 = SafeHDR(tex2D(_MainTex, uv - d.xz).rgb);
half3 s2 = SafeHDR(tex2D(_MainTex, uv + d.xz).rgb);
half3 s3 = SafeHDR(tex2D(_MainTex, uv - d.zy).rgb);
half3 s4 = SafeHDR(tex2D(_MainTex, uv + d.zy).rgb);
half3 m = Median(Median(s0.rgb, s1, s2), s3, s4);
#else
half4 s0 = SafeHDR(tex2D(_MainTex, uv));
half3 m = s0.rgb;
#endif
#if UNITY_COLORSPACE_GAMMA
m = GammaToLinearSpace(m);
#endif
// Pixel brightness
half br = Brightness(m);
// Under-threshold part: quadratic curve
half rq = clamp(br - _Curve.x, 0, _Curve.y);
rq = _Curve.z * rq * rq;
// Combine and apply the brightness response curve.
m *= max(rq, br - _Threshold) / max(br, 1e-5);
return EncodeHDR(m);
}
half4 frag_downsample1(v2f_img i) : SV_Target
{
#if ANTI_FLICKER
return EncodeHDR(DownsampleAntiFlickerFilter(i.uv));
#else
return EncodeHDR(DownsampleFilter(i.uv));
#endif
}
half4 frag_downsample2(v2f_img i) : SV_Target
{
return EncodeHDR(DownsampleFilter(i.uv));
}
half4 frag_upsample(v2f_multitex i) : SV_Target
{
half3 base = DecodeHDR(tex2D(_BaseTex, i.uvBase));
half3 blur = UpsampleFilter(i.uvMain);
return EncodeHDR(base + blur);
}
half4 frag_upsample_final(v2f_multitex i) : SV_Target
{
half4 base = tex2D(_BaseTex, i.uvBase);
half3 blur = UpsampleFilter(i.uvMain);
#if UNITY_COLORSPACE_GAMMA
base.rgb = GammaToLinearSpace(base.rgb);
#endif
half3 cout = base.rgb + blur * _Intensity;
#if UNITY_COLORSPACE_GAMMA
cout = LinearToGammaSpace(cout);
#endif
return half4(cout, base.a);
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1b8325918052c4c5492831d116e3ed27
timeCreated: 1463470294
licenseType: Store
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,141 @@
//
// Kino/Bloom v2 - Bloom filter for Unity
//
// Copyright (C) 2015, 2016 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
Shader "Hidden/Kino/Bloom"
{
Properties
{
_MainTex("", 2D) = "" {}
_BaseTex("", 2D) = "" {}
}
SubShader
{
// 0: Prefilter
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma multi_compile _ UNITY_COLORSPACE_GAMMA
#include "Bloom.cginc"
#pragma vertex vert
#pragma fragment frag_prefilter
#pragma target 3.0
ENDCG
}
// 1: Prefilter with anti-flicker
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#define ANTI_FLICKER 1
#pragma multi_compile _ UNITY_COLORSPACE_GAMMA
#include "Bloom.cginc"
#pragma vertex vert
#pragma fragment frag_prefilter
#pragma target 3.0
ENDCG
}
// 2: First level downsampler
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#include "Bloom.cginc"
#pragma vertex vert
#pragma fragment frag_downsample1
#pragma target 3.0
ENDCG
}
// 3: First level downsampler with anti-flicker
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#define ANTI_FLICKER 1
#include "Bloom.cginc"
#pragma vertex vert
#pragma fragment frag_downsample1
#pragma target 3.0
ENDCG
}
// 4: Second level downsampler
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#include "Bloom.cginc"
#pragma vertex vert
#pragma fragment frag_downsample2
#pragma target 3.0
ENDCG
}
// 5: Upsampler
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#include "Bloom.cginc"
#pragma vertex vert_multitex
#pragma fragment frag_upsample
#pragma target 3.0
ENDCG
}
// 6: High quality upsampler
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#define HIGH_QUALITY 1
#include "Bloom.cginc"
#pragma vertex vert_multitex
#pragma fragment frag_upsample
#pragma target 3.0
ENDCG
}
// 7: Combiner
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma multi_compile _ UNITY_COLORSPACE_GAMMA
#include "Bloom.cginc"
#pragma vertex vert_multitex
#pragma fragment frag_upsample_final
#pragma target 3.0
ENDCG
}
// 8: High quality combiner
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#define HIGH_QUALITY 1
#pragma multi_compile _ UNITY_COLORSPACE_GAMMA
#include "Bloom.cginc"
#pragma vertex vert_multitex
#pragma fragment frag_upsample_final
#pragma target 3.0
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5a711a01011934ebcb58ef5ad52159d6
timeCreated: 1435809878
licenseType: Store
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant: