Skip to content

Commit

Permalink
Merge branch 'curve-graph'
Browse files Browse the repository at this point in the history
  • Loading branch information
Keijiro Takahashi authored and Keijiro Takahashi committed Mar 22, 2016
2 parents 27afd2f + effdc84 commit d05a56c
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 22 deletions.
61 changes: 46 additions & 15 deletions Assets/Kino/Bloom/Bloom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,34 @@ public class Bloom : MonoBehaviour
{
#region Public Properties

/// Prefilter threshold
/// Prefilter threshold (gamma-encoded)
/// Filters out pixels under this level of brightness.
public float threshold {
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(_threshold); }
set { _threshold = LinearToGamma(value); }
}

[SerializeField]
[Tooltip("Filters out pixels under this level of brightness.")]
float _threshold = 0.5f;

/// Prefilter exposure value
/// Controls sensitivity of the effect.
/// 0=less sensitive, 1=fully sensitive
public float exposure {
get { return _exposure; }
set { _exposure = value; }
/// Soft-knee coefficient
/// Makes transition between under/over-threshold gradual.
public float softKnee {
get { return _softKnee; }
set { _softKnee = value; }
}

[SerializeField, Range(0, 1)]
[Tooltip("Sensitivity of the effect.\n"+
"0=less sensitive, 1=fully sensitive")]
float _exposure = 0.5f;
[Tooltip("Makes transition between under/over-threshold gradual.")]
float _softKnee = 0.5f;

/// Bloom radius
/// Changes extent of veiling effects in a screen
Expand Down Expand Up @@ -104,13 +109,37 @@ public bool antiFlicker {

#endregion

#region Private Variables And Properties
#region Private Members

[SerializeField, HideInInspector]
Shader _shader;

Material _material;

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
Expand Down Expand Up @@ -153,10 +182,12 @@ void OnRenderImage(RenderTexture source, RenderTexture destination)
var iteration = Mathf.Max(2, logh_i);

// update the shader properties
_material.SetFloat("_Threshold", threshold);
var lthresh = thresholdLinear;
_material.SetFloat("_Threshold", lthresh);

var pfc = -Mathf.Log(Mathf.Lerp(1e-2f, 1 - 1e-5f, _exposure), 10);
_material.SetFloat("_Cutoff", threshold + pfc * 10);
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);
Expand Down
22 changes: 17 additions & 5 deletions Assets/Kino/Bloom/Editor/BloomEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,22 @@ namespace Kino
[CustomEditor(typeof(Bloom))]
public class BloomEditor : Editor
{
BloomGraphDrawer _graph;

SerializedProperty _threshold;
SerializedProperty _exposure;
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");
_exposure = serializedObject.FindProperty("_exposure");
_softKnee = serializedObject.FindProperty("_softKnee");
_radius = serializedObject.FindProperty("_radius");
_intensity = serializedObject.FindProperty("_intensity");
_highQuality = serializedObject.FindProperty("_highQuality");
Expand All @@ -51,10 +56,17 @@ public override void OnInspectorGUI()
{
serializedObject.Update();

EditorGUILayout.PropertyField(_threshold);
EditorGUILayout.PropertyField(_exposure);
EditorGUILayout.PropertyField(_radius);
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);

Expand Down
171 changes: 171 additions & 0 deletions Assets/Kino/Bloom/Editor/BloomGraphDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
//
// 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 (bloom.GetComponent<Camera>().hdr)
{
_rangeX = 6;
_rangeY = 1.5f;
}
else
{
_rangeX = 1;
_rangeY = 1;
}

_threshold = bloom.thresholdLinear;
_knee = bloom.softKnee * _threshold + 1e-5f;
_intensity = bloom.intensity;
}

// 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
{
// Extend the last segment up 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;
}
}

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 = 64;

// 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
}
}
12 changes: 12 additions & 0 deletions Assets/Kino/Bloom/Editor/BloomGraphDrawer.cs.meta

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

12 changes: 10 additions & 2 deletions Assets/Kino/Bloom/Shader/Bloom.shader
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Shader "Hidden/Kino/Bloom"

float _PrefilterOffs;
half _Threshold;
half _Cutoff;
half3 _Curve;
float _SampleScale;
half _Intensity;

Expand Down Expand Up @@ -209,7 +209,15 @@ Shader "Hidden/Kino/Bloom"
#if GAMMA_COLOR
m = GammaToLinearSpace(m);
#endif
m *= saturate((Brightness(m) - _Threshold) / _Cutoff);
// 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) / (br + 1e-5);

return EncodeHDR(m);
}
Expand Down

0 comments on commit d05a56c

Please sign in to comment.