Commit 90a5e627 by Tim Reiter

added vignette and bloom (+several other standard asset image effect shaders)

parent 0d094b57
fileFormatVersion: 2
guid: 225198e07aaae3547a6d1f6e7177555f
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
using System;
using UnityEditor;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[CustomEditor (typeof(BloomAndFlares))]
class BloomAndFlaresEditor : Editor
{
SerializedProperty tweakMode;
SerializedProperty screenBlendMode;
SerializedObject serObj;
SerializedProperty hdr;
SerializedProperty sepBlurSpread;
SerializedProperty useSrcAlphaAsMask;
SerializedProperty bloomIntensity;
SerializedProperty bloomthreshold;
SerializedProperty bloomBlurIterations;
SerializedProperty lensflares;
SerializedProperty hollywoodFlareBlurIterations;
SerializedProperty lensflareMode;
SerializedProperty hollyStretchWidth;
SerializedProperty lensflareIntensity;
SerializedProperty lensflarethreshold;
SerializedProperty flareColorA;
SerializedProperty flareColorB;
SerializedProperty flareColorC;
SerializedProperty flareColorD;
SerializedProperty lensFlareVignetteMask;
void OnEnable () {
serObj = new SerializedObject (target);
screenBlendMode = serObj.FindProperty("screenBlendMode");
hdr = serObj.FindProperty("hdr");
sepBlurSpread = serObj.FindProperty("sepBlurSpread");
useSrcAlphaAsMask = serObj.FindProperty("useSrcAlphaAsMask");
bloomIntensity = serObj.FindProperty("bloomIntensity");
bloomthreshold = serObj.FindProperty("bloomThreshold");
bloomBlurIterations = serObj.FindProperty("bloomBlurIterations");
lensflares = serObj.FindProperty("lensflares");
lensflareMode = serObj.FindProperty("lensflareMode");
hollywoodFlareBlurIterations = serObj.FindProperty("hollywoodFlareBlurIterations");
hollyStretchWidth = serObj.FindProperty("hollyStretchWidth");
lensflareIntensity = serObj.FindProperty("lensflareIntensity");
lensflarethreshold = serObj.FindProperty("lensflareThreshold");
flareColorA = serObj.FindProperty("flareColorA");
flareColorB = serObj.FindProperty("flareColorB");
flareColorC = serObj.FindProperty("flareColorC");
flareColorD = serObj.FindProperty("flareColorD");
lensFlareVignetteMask = serObj.FindProperty("lensFlareVignetteMask");
tweakMode = serObj.FindProperty("tweakMode");
}
public override void OnInspectorGUI () {
serObj.Update();
GUILayout.Label("HDR " + (hdr.enumValueIndex == 0 ? "auto detected, " : (hdr.enumValueIndex == 1 ? "forced on, " : "disabled, ")) + (useSrcAlphaAsMask.floatValue < 0.1f ? " ignoring alpha channel glow information" : " using alpha channel glow information"), EditorStyles.miniBoldLabel);
EditorGUILayout.PropertyField (tweakMode, new GUIContent("Tweak mode"));
EditorGUILayout.PropertyField (screenBlendMode, new GUIContent("Blend mode"));
EditorGUILayout.PropertyField (hdr, new GUIContent("HDR"));
// display info text when screen blend mode cannot be used
Camera cam = (target as BloomAndFlares).GetComponent<Camera>();
if (cam != null) {
if (screenBlendMode.enumValueIndex==0 && ((cam.hdr && hdr.enumValueIndex==0) || (hdr.enumValueIndex==1))) {
EditorGUILayout.HelpBox("Screen blend is not supported in HDR. Using 'Add' instead.", MessageType.Info);
}
}
if (1 == tweakMode.intValue)
EditorGUILayout.PropertyField (lensflares, new GUIContent("Cast lens flares"));
EditorGUILayout.Separator ();
EditorGUILayout.PropertyField (bloomIntensity, new GUIContent("Intensity"));
bloomthreshold.floatValue = EditorGUILayout.Slider ("threshold", bloomthreshold.floatValue, -0.05f, 4.0f);
bloomBlurIterations.intValue = EditorGUILayout.IntSlider ("Blur iterations", bloomBlurIterations.intValue, 1, 4);
sepBlurSpread.floatValue = EditorGUILayout.Slider ("Blur spread", sepBlurSpread.floatValue, 0.1f, 10.0f);
if (1 == tweakMode.intValue)
useSrcAlphaAsMask.floatValue = EditorGUILayout.Slider (new GUIContent("Use alpha mask", "Make alpha channel define glowiness"), useSrcAlphaAsMask.floatValue, 0.0f, 1.0f);
else
useSrcAlphaAsMask.floatValue = 0.0f;
if (1 == tweakMode.intValue) {
EditorGUILayout.Separator ();
if (lensflares.boolValue) {
// further lens flare tweakings
if (0 != tweakMode.intValue)
EditorGUILayout.PropertyField (lensflareMode, new GUIContent("Lens flare mode"));
else
lensflareMode.enumValueIndex = 0;
EditorGUILayout.PropertyField(lensFlareVignetteMask, new GUIContent("Lens flare mask", "This mask is needed to prevent lens flare artifacts"));
EditorGUILayout.PropertyField (lensflareIntensity, new GUIContent("Local intensity"));
lensflarethreshold.floatValue = EditorGUILayout.Slider ("Local threshold", lensflarethreshold.floatValue, 0.0f, 1.0f);
if (lensflareMode.intValue == 0) {
// ghosting
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorA, new GUIContent("1st Color"));
EditorGUILayout.PropertyField (flareColorB, new GUIContent("2nd Color"));
EditorGUILayout.EndHorizontal ();
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorC, new GUIContent("3rd Color"));
EditorGUILayout.PropertyField (flareColorD, new GUIContent("4th Color"));
EditorGUILayout.EndHorizontal ();
}
else if (lensflareMode.intValue == 1) {
// hollywood
EditorGUILayout.PropertyField (hollyStretchWidth, new GUIContent("Stretch width"));
hollywoodFlareBlurIterations.intValue = EditorGUILayout.IntSlider ("Blur iterations", hollywoodFlareBlurIterations.intValue, 1, 4);
EditorGUILayout.PropertyField (flareColorA, new GUIContent("Tint Color"));
}
else if (lensflareMode.intValue == 2) {
// both
EditorGUILayout.PropertyField (hollyStretchWidth, new GUIContent("Stretch width"));
hollywoodFlareBlurIterations.intValue = EditorGUILayout.IntSlider ("Blur iterations", hollywoodFlareBlurIterations.intValue, 1, 4);
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorA, new GUIContent("1st Color"));
EditorGUILayout.PropertyField (flareColorB, new GUIContent("2nd Color"));
EditorGUILayout.EndHorizontal ();
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorC, new GUIContent("3rd Color"));
EditorGUILayout.PropertyField (flareColorD, new GUIContent("4th Color"));
EditorGUILayout.EndHorizontal ();
}
}
} else
lensflares.boolValue = false; // disable lens flares in simple tweak mode
serObj.ApplyModifiedProperties();
}
}
}
fileFormatVersion: 2
guid: 4deca87cb459d1642ac8f734856ca84e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEditor;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[CustomEditor (typeof(Bloom))]
class BloomEditor : Editor
{
SerializedProperty tweakMode;
SerializedProperty screenBlendMode;
SerializedObject serObj;
SerializedProperty hdr;
SerializedProperty quality;
SerializedProperty sepBlurSpread;
SerializedProperty bloomIntensity;
SerializedProperty bloomThresholdColor;
SerializedProperty bloomThreshold;
SerializedProperty bloomBlurIterations;
SerializedProperty hollywoodFlareBlurIterations;
SerializedProperty lensflareMode;
SerializedProperty hollyStretchWidth;
SerializedProperty lensflareIntensity;
SerializedProperty flareRotation;
SerializedProperty lensFlareSaturation;
SerializedProperty lensflareThreshold;
SerializedProperty flareColorA;
SerializedProperty flareColorB;
SerializedProperty flareColorC;
SerializedProperty flareColorD;
SerializedProperty lensFlareVignetteMask;
void OnEnable () {
serObj = new SerializedObject (target);
screenBlendMode = serObj.FindProperty("screenBlendMode");
hdr = serObj.FindProperty("hdr");
quality = serObj.FindProperty("quality");
sepBlurSpread = serObj.FindProperty("sepBlurSpread");
bloomIntensity = serObj.FindProperty("bloomIntensity");
bloomThreshold = serObj.FindProperty("bloomThreshold");
bloomThresholdColor = serObj.FindProperty("bloomThresholdColor");
bloomBlurIterations = serObj.FindProperty("bloomBlurIterations");
lensflareMode = serObj.FindProperty("lensflareMode");
hollywoodFlareBlurIterations = serObj.FindProperty("hollywoodFlareBlurIterations");
hollyStretchWidth = serObj.FindProperty("hollyStretchWidth");
lensflareIntensity = serObj.FindProperty("lensflareIntensity");
lensflareThreshold = serObj.FindProperty("lensflareThreshold");
lensFlareSaturation = serObj.FindProperty("lensFlareSaturation");
flareRotation = serObj.FindProperty("flareRotation");
flareColorA = serObj.FindProperty("flareColorA");
flareColorB = serObj.FindProperty("flareColorB");
flareColorC = serObj.FindProperty("flareColorC");
flareColorD = serObj.FindProperty("flareColorD");
lensFlareVignetteMask = serObj.FindProperty("lensFlareVignetteMask");
tweakMode = serObj.FindProperty("tweakMode");
}
public override void OnInspectorGUI () {
serObj.Update();
EditorGUILayout.LabelField("Glow and Lens Flares for bright screen pixels", EditorStyles.miniLabel);
EditorGUILayout.PropertyField (quality, new GUIContent("Quality", "High quality preserves high frequencies with bigger blurs and uses a better blending and down-/upsampling"));
EditorGUILayout.Separator ();
EditorGUILayout.PropertyField (tweakMode, new GUIContent("Mode"));
EditorGUILayout.PropertyField (screenBlendMode, new GUIContent("Blend"));
EditorGUILayout.PropertyField (hdr, new GUIContent("HDR"));
EditorGUILayout.Separator ();
// display info text when screen blend mode cannot be used
Camera cam = (target as Bloom).GetComponent<Camera>();
if (cam != null) {
if (screenBlendMode.enumValueIndex==0 && ((cam.hdr && hdr.enumValueIndex==0) || (hdr.enumValueIndex==1))) {
EditorGUILayout.HelpBox("Screen blend is not supported in HDR. Using 'Add' instead.", MessageType.Info);
}
}
EditorGUILayout.PropertyField (bloomIntensity, new GUIContent("Intensity"));
bloomThreshold.floatValue = EditorGUILayout.Slider ("Threshold", bloomThreshold.floatValue, -0.05f, 4.0f);
if (1 == tweakMode.intValue) {
EditorGUILayout.PropertyField(bloomThresholdColor, new GUIContent(" RGB Threshold"));
}
EditorGUILayout.Separator ();
bloomBlurIterations.intValue = EditorGUILayout.IntSlider ("Blur Iterations", bloomBlurIterations.intValue, 1, 4);
sepBlurSpread.floatValue = EditorGUILayout.Slider (" Sample Distance", sepBlurSpread.floatValue, 0.1f, 10.0f);
EditorGUILayout.Separator ();
if (1 == tweakMode.intValue) {
// further lens flare tweakings
if (0 != tweakMode.intValue)
EditorGUILayout.PropertyField (lensflareMode, new GUIContent("Lens Flares"));
else
lensflareMode.enumValueIndex = 0;
EditorGUILayout.PropertyField (lensflareIntensity, new GUIContent(" Local Intensity", "0 disables lens flares entirely (optimization)"));
lensflareThreshold.floatValue = EditorGUILayout.Slider ("Threshold", lensflareThreshold.floatValue, 0.0f, 4.0f);
if (Mathf.Abs(lensflareIntensity.floatValue) > Mathf.Epsilon) {
if (lensflareMode.intValue == 0) {
// ghosting
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorA, new GUIContent(" 1st Color"));
EditorGUILayout.PropertyField (flareColorB, new GUIContent(" 2nd Color"));
EditorGUILayout.EndHorizontal ();
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorC, new GUIContent(" 3rd Color"));
EditorGUILayout.PropertyField (flareColorD, new GUIContent(" 4th Color"));
EditorGUILayout.EndHorizontal ();
}
else if (lensflareMode.intValue == 1) {
// hollywood
EditorGUILayout.PropertyField (hollyStretchWidth, new GUIContent(" Stretch width"));
EditorGUILayout.PropertyField (flareRotation, new GUIContent( " Rotation"));
hollywoodFlareBlurIterations.intValue = EditorGUILayout.IntSlider (" Blur Iterations", hollywoodFlareBlurIterations.intValue, 1, 4);
EditorGUILayout.PropertyField (lensFlareSaturation, new GUIContent(" Saturation"));
EditorGUILayout.PropertyField (flareColorA, new GUIContent(" Tint Color"));
}
else if (lensflareMode.intValue == 2) {
// both
EditorGUILayout.PropertyField (hollyStretchWidth, new GUIContent(" Stretch width"));
hollywoodFlareBlurIterations.intValue = EditorGUILayout.IntSlider (" Blur Iterations", hollywoodFlareBlurIterations.intValue, 1, 4);
EditorGUILayout.PropertyField (lensFlareSaturation, new GUIContent(" Saturation"));
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorA, new GUIContent(" 1st Color"));
EditorGUILayout.PropertyField (flareColorB, new GUIContent(" 2nd Color"));
EditorGUILayout.EndHorizontal ();
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.PropertyField (flareColorC, new GUIContent(" 3rd Color"));
EditorGUILayout.PropertyField (flareColorD, new GUIContent(" 4th Color"));
EditorGUILayout.EndHorizontal ();
}
EditorGUILayout.PropertyField(lensFlareVignetteMask, new GUIContent(" Mask", "This mask is needed to prevent lens flare artifacts"));
}
}
serObj.ApplyModifiedProperties();
}
}
}
fileFormatVersion: 2
guid: 43fcc28c40e404d4eabfc88b1dbda7b5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEditor;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[CustomEditor (typeof(VignetteAndChromaticAberration))]
class VignetteAndChromaticAberrationEditor : Editor
{
private SerializedObject m_SerObj;
private SerializedProperty m_Mode;
private SerializedProperty m_Intensity; // intensity == 0 disables pre pass (optimization)
private SerializedProperty m_ChromaticAberration;
private SerializedProperty m_AxialAberration;
private SerializedProperty m_Blur; // blur == 0 disables blur pass (optimization)
private SerializedProperty m_BlurSpread;
private SerializedProperty m_BlurDistance;
private SerializedProperty m_LuminanceDependency;
void OnEnable ()
{
m_SerObj = new SerializedObject (target);
m_Mode = m_SerObj.FindProperty ("mode");
m_Intensity = m_SerObj.FindProperty ("intensity");
m_ChromaticAberration = m_SerObj.FindProperty ("chromaticAberration");
m_AxialAberration = m_SerObj.FindProperty ("axialAberration");
m_Blur = m_SerObj.FindProperty ("blur");
m_BlurSpread = m_SerObj.FindProperty ("blurSpread");
m_LuminanceDependency = m_SerObj.FindProperty ("luminanceDependency");
m_BlurDistance = m_SerObj.FindProperty ("blurDistance");
}
public override void OnInspectorGUI ()
{
m_SerObj.Update ();
EditorGUILayout.LabelField("Simulates the common lens artifacts 'Vignette' and 'Aberration'", EditorStyles.miniLabel);
EditorGUILayout.PropertyField (m_Intensity, new GUIContent("Vignetting"));
EditorGUILayout.PropertyField (m_Blur, new GUIContent(" Blurred Corners"));
if (m_Blur.floatValue>0.0f)
EditorGUILayout.PropertyField (m_BlurSpread, new GUIContent(" Blur Distance"));
EditorGUILayout.Separator ();
EditorGUILayout.PropertyField (m_Mode, new GUIContent("Aberration"));
if (m_Mode.intValue>0)
{
EditorGUILayout.PropertyField (m_ChromaticAberration, new GUIContent(" Tangential Aberration"));
EditorGUILayout.PropertyField (m_AxialAberration, new GUIContent(" Axial Aberration"));
m_LuminanceDependency.floatValue = EditorGUILayout.Slider(" Contrast Dependency", m_LuminanceDependency.floatValue, 0.001f, 1.0f);
m_BlurDistance.floatValue = EditorGUILayout.Slider(" Blur Distance", m_BlurDistance.floatValue, 0.001f, 5.0f);
}
else
EditorGUILayout.PropertyField (m_ChromaticAberration, new GUIContent(" Chromatic Aberration"));
m_SerObj.ApplyModifiedProperties();
}
}
}
fileFormatVersion: 2
guid: 08126bf2baa528c4cb9c60340a24e5d6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
fileFormatVersion: 2
guid: 82bcf04d8112e204eae4c5b3ccca54aa
folderAsset: yes
timeCreated: 1433529656
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 115d1f9d9bd29064ab981e57c8fc8cdf
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
fileFormatVersion: 2
guid: d6e0c95a128e14227939c51b5d9ad74e
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
fileFormatVersion: 2
guid: cd3e1490c3d9a7a498538315414d5129
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom")]
public class Bloom : PostEffectsBase
{
public enum LensFlareStyle
{
Ghosting = 0,
Anamorphic = 1,
Combined = 2,
}
public enum TweakMode
{
Basic = 0,
Complex = 1,
}
public enum HDRBloomMode
{
Auto = 0,
On = 1,
Off = 2,
}
public enum BloomScreenBlendMode
{
Screen = 0,
Add = 1,
}
public enum BloomQuality
{
Cheap = 0,
High = 1,
}
public TweakMode tweakMode = 0;
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
public HDRBloomMode hdr = HDRBloomMode.Auto;
private bool doHdr = false;
public float sepBlurSpread = 2.5f;
public BloomQuality quality = BloomQuality.High;
public float bloomIntensity = 0.5f;
public float bloomThreshold = 0.5f;
public Color bloomThresholdColor = Color.white;
public int bloomBlurIterations = 2;
public int hollywoodFlareBlurIterations = 2;
public float flareRotation = 0.0f;
public LensFlareStyle lensflareMode = (LensFlareStyle) 1;
public float hollyStretchWidth = 2.5f;
public float lensflareIntensity = 0.0f;
public float lensflareThreshold = 0.3f;
public float lensFlareSaturation = 0.75f;
public Color flareColorA = new Color (0.4f, 0.4f, 0.8f, 0.75f);
public Color flareColorB = new Color (0.4f, 0.8f, 0.8f, 0.75f);
public Color flareColorC = new Color (0.8f, 0.4f, 0.8f, 0.75f);
public Color flareColorD = new Color (0.8f, 0.4f, 0.0f, 0.75f);
public Texture2D lensFlareVignetteMask;
public Shader lensFlareShader;
private Material lensFlareMaterial;
public Shader screenBlendShader;
private Material screenBlend;
public Shader blurAndFlaresShader;
private Material blurAndFlaresMaterial;
public Shader brightPassFilterShader;
private Material brightPassFilterMaterial;
public override bool CheckResources ()
{
CheckSupport (false);
screenBlend = CheckShaderAndCreateMaterial (screenBlendShader, screenBlend);
lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader,lensFlareMaterial);
blurAndFlaresMaterial = CheckShaderAndCreateMaterial (blurAndFlaresShader, blurAndFlaresMaterial);
brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
if (!isSupported)
ReportAutoDisable ();
return isSupported;
}
public void OnRenderImage (RenderTexture source, RenderTexture destination)
{
if (CheckResources()==false)
{
Graphics.Blit (source, destination);
return;
}
// screen blend is not supported when HDR is enabled (will cap values)
doHdr = false;
if (hdr == HDRBloomMode.Auto)
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
else {
doHdr = hdr == HDRBloomMode.On;
}
doHdr = doHdr && supportHDRTextures;
BloomScreenBlendMode realBlendMode = screenBlendMode;
if (doHdr)
realBlendMode = BloomScreenBlendMode.Add;
var rtFormat= (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
var rtW2= source.width/2;
var rtH2= source.height/2;
var rtW4= source.width/4;
var rtH4= source.height/4;
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
float oneOverBaseSize = 1.0f / 512.0f;
// downsample
RenderTexture quarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
RenderTexture halfRezColorDown = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
if (quality > BloomQuality.Cheap) {
Graphics.Blit (source, halfRezColorDown, screenBlend, 2);
RenderTexture rtDown4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
Graphics.Blit (halfRezColorDown, rtDown4, screenBlend, 2);
Graphics.Blit (rtDown4, quarterRezColor, screenBlend, 6);
RenderTexture.ReleaseTemporary(rtDown4);
}
else {
Graphics.Blit (source, halfRezColorDown);
Graphics.Blit (halfRezColorDown, quarterRezColor, screenBlend, 6);
}
RenderTexture.ReleaseTemporary (halfRezColorDown);
// cut colors (thresholding)
RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
BrightFilter (bloomThreshold * bloomThresholdColor, quarterRezColor, secondQuarterRezColor);
// blurring
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
else if (bloomBlurIterations > 10) bloomBlurIterations = 10;
for (int iter = 0; iter < bloomBlurIterations; iter++)
{
float spreadForPass = (1.0f + (iter * 0.25f)) * sepBlurSpread;
// vertical blur
RenderTexture blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
RenderTexture.ReleaseTemporary(secondQuarterRezColor);
secondQuarterRezColor = blur4;
// horizontal blur
blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
secondQuarterRezColor = blur4;
if (quality > BloomQuality.Cheap)
{
if (iter == 0)
{
Graphics.SetRenderTarget(quarterRezColor);
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
Graphics.Blit (secondQuarterRezColor, quarterRezColor);
}
else
{
quarterRezColor.MarkRestoreExpected(); // using max blending, RT restore expected
Graphics.Blit (secondQuarterRezColor, quarterRezColor, screenBlend, 10);
}
}
}
if (quality > BloomQuality.Cheap)
{
Graphics.SetRenderTarget(secondQuarterRezColor);
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
Graphics.Blit (quarterRezColor, secondQuarterRezColor, screenBlend, 6);
}
// lens flares: ghosting, anamorphic or both (ghosted anamorphic flares)
if (lensflareIntensity > Mathf.Epsilon)
{
RenderTexture rtFlares4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
if (lensflareMode == 0)
{
// ghosting only
BrightFilter (lensflareThreshold, secondQuarterRezColor, rtFlares4);
if (quality > BloomQuality.Cheap)
{
// smooth a little
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, (1.5f) / (1.0f * quarterRezColor.height), 0.0f, 0.0f));
Graphics.SetRenderTarget(quarterRezColor);
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((1.5f) / (1.0f * quarterRezColor.width), 0.0f, 0.0f, 0.0f));
Graphics.SetRenderTarget(rtFlares4);
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
}
// no ugly edges!
Vignette (0.975f, rtFlares4, rtFlares4);
BlendFlares (rtFlares4, secondQuarterRezColor);
}
else
{
//Vignette (0.975ff, rtFlares4, rtFlares4);
//DrawBorder(rtFlares4, screenBlend, 8);
float flareXRot = 1.0f * Mathf.Cos(flareRotation);
float flareyRot = 1.0f * Mathf.Sin(flareRotation);
float stretchWidth = (hollyStretchWidth * 1.0f / widthOverHeight) * oneOverBaseSize;
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot, flareyRot, 0.0f, 0.0f));
blurAndFlaresMaterial.SetVector ("_Threshhold", new Vector4 (lensflareThreshold, 1.0f, 0.0f, 0.0f));
blurAndFlaresMaterial.SetVector ("_TintColor", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
blurAndFlaresMaterial.SetFloat ("_Saturation", lensFlareSaturation);
// "pre and cut"
quarterRezColor.DiscardContents();
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 2);
// "post"
rtFlares4.DiscardContents();
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 3);
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot * stretchWidth, flareyRot * stretchWidth, 0.0f, 0.0f));
// stretch 1st
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth);
quarterRezColor.DiscardContents();
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
// stretch 2nd
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 2.0f);
rtFlares4.DiscardContents();
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 1);
// stretch 3rd
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 4.0f);
quarterRezColor.DiscardContents();
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
// additional blur passes
for (int iter = 0; iter < hollywoodFlareBlurIterations; iter++)
{
stretchWidth = (hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize;
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
rtFlares4.DiscardContents();
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
quarterRezColor.DiscardContents();
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
}
if (lensflareMode == (LensFlareStyle) 1)
// anamorphic lens flares
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
else
{
// "combined" lens flares
Vignette (1.0f, quarterRezColor, rtFlares4);
BlendFlares (rtFlares4, quarterRezColor);
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
}
}
RenderTexture.ReleaseTemporary (rtFlares4);
}
int blendPass = (int) realBlendMode;
//if (Mathf.Abs(chromaticBloom) < Mathf.Epsilon)
// blendPass += 4;
screenBlend.SetFloat ("_Intensity", bloomIntensity);
screenBlend.SetTexture ("_ColorBuffer", source);
if (quality > BloomQuality.Cheap)
{
RenderTexture halfRezColorUp = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
Graphics.Blit (secondQuarterRezColor, halfRezColorUp);
Graphics.Blit (halfRezColorUp, destination, screenBlend, blendPass);
RenderTexture.ReleaseTemporary (halfRezColorUp);
}
else
Graphics.Blit (secondQuarterRezColor, destination, screenBlend, blendPass);
RenderTexture.ReleaseTemporary (quarterRezColor);
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
}
private void AddTo (float intensity_, RenderTexture from, RenderTexture to)
{
screenBlend.SetFloat ("_Intensity", intensity_);
to.MarkRestoreExpected(); // additive blending, RT restore expected
Graphics.Blit (from, to, screenBlend, 9);
}
private void BlendFlares (RenderTexture from, RenderTexture to)
{
lensFlareMaterial.SetVector ("colorA", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
lensFlareMaterial.SetVector ("colorB", new Vector4 (flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
lensFlareMaterial.SetVector ("colorC", new Vector4 (flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
lensFlareMaterial.SetVector ("colorD", new Vector4 (flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
to.MarkRestoreExpected(); // additive blending, RT restore expected
Graphics.Blit (from, to, lensFlareMaterial);
}
private void BrightFilter (float thresh, RenderTexture from, RenderTexture to)
{
brightPassFilterMaterial.SetVector ("_Threshhold", new Vector4 (thresh, thresh, thresh, thresh));
Graphics.Blit (from, to, brightPassFilterMaterial, 0);
}
private void BrightFilter (Color threshColor, RenderTexture from, RenderTexture to)
{
brightPassFilterMaterial.SetVector ("_Threshhold", threshColor);
Graphics.Blit (from, to, brightPassFilterMaterial, 1);
}
private void Vignette (float amount, RenderTexture from, RenderTexture to)
{
if (lensFlareVignetteMask)
{
screenBlend.SetTexture ("_ColorBuffer", lensFlareVignetteMask);
to.MarkRestoreExpected(); // using blending, RT restore expected
Graphics.Blit (from == to ? null : from, to, screenBlend, from == to ? 7 : 3);
}
else if (from != to)
{
Graphics.SetRenderTarget (to);
GL.Clear(false, true, Color.black); // clear destination to avoid RT restore
Graphics.Blit (from, to);
}
}
}
}
fileFormatVersion: 2
guid: 7fceaeb339b971b429c4cc600acabd13
MonoImporter:
serializedVersion: 2
defaultReferences:
- lensFlareVignetteMask: {fileID: 2800000, guid: 95ef4804fe0be4c999ddaa383536cde8,
type: 3}
- lensFlareShader: {fileID: 4800000, guid: 459fe69d2f6d74ddb92f04dbf45a866b, type: 3}
- screenBlendShader: {fileID: 4800000, guid: 7856cbff0a0ca45c787d5431eb805bb0, type: 3}
- blurAndFlaresShader: {fileID: 4800000, guid: be6e39cf196f146d5be72fbefb18ed75,
type: 3}
- brightPassFilterShader: {fileID: 4800000, guid: 0aeaa4cb29f5d4e9c8455f04c8575c8c,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
public enum LensflareStyle34
{
Ghosting = 0,
Anamorphic = 1,
Combined = 2,
}
public enum TweakMode34
{
Basic = 0,
Complex = 1,
}
public enum HDRBloomMode
{
Auto = 0,
On = 1,
Off = 2,
}
public enum BloomScreenBlendMode
{
Screen = 0,
Add = 1,
}
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Bloom and Glow/BloomAndFlares (3.5, Deprecated)")]
public class BloomAndFlares : PostEffectsBase
{
public TweakMode34 tweakMode = 0;
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
public HDRBloomMode hdr = HDRBloomMode.Auto;
private bool doHdr = false;
public float sepBlurSpread = 1.5f;
public float useSrcAlphaAsMask = 0.5f;
public float bloomIntensity = 1.0f;
public float bloomThreshold = 0.5f;
public int bloomBlurIterations = 2;
public bool lensflares = false;
public int hollywoodFlareBlurIterations = 2;
public LensflareStyle34 lensflareMode = (LensflareStyle34)1;
public float hollyStretchWidth = 3.5f;
public float lensflareIntensity = 1.0f;
public float lensflareThreshold = 0.3f;
public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f);
public Texture2D lensFlareVignetteMask;
public Shader lensFlareShader;
private Material lensFlareMaterial;
public Shader vignetteShader;
private Material vignetteMaterial;
public Shader separableBlurShader;
private Material separableBlurMaterial;
public Shader addBrightStuffOneOneShader;
private Material addBrightStuffBlendOneOneMaterial;
public Shader screenBlendShader;
private Material screenBlend;
public Shader hollywoodFlaresShader;
private Material hollywoodFlaresMaterial;
public Shader brightPassFilterShader;
private Material brightPassFilterMaterial;
public override bool CheckResources()
{
CheckSupport(false);
screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
vignetteMaterial = CheckShaderAndCreateMaterial(vignetteShader, vignetteMaterial);
separableBlurMaterial = CheckShaderAndCreateMaterial(separableBlurShader, separableBlurMaterial);
addBrightStuffBlendOneOneMaterial = CheckShaderAndCreateMaterial(addBrightStuffOneOneShader, addBrightStuffBlendOneOneMaterial);
hollywoodFlaresMaterial = CheckShaderAndCreateMaterial(hollywoodFlaresShader, hollywoodFlaresMaterial);
brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
if (!isSupported)
ReportAutoDisable();
return isSupported;
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (CheckResources() == false)
{
Graphics.Blit(source, destination);
return;
}
// screen blend is not supported when HDR is enabled (will cap values)
doHdr = false;
if (hdr == HDRBloomMode.Auto)
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
else
{
doHdr = hdr == HDRBloomMode.On;
}
doHdr = doHdr && supportHDRTextures;
BloomScreenBlendMode realBlendMode = screenBlendMode;
if (doHdr)
realBlendMode = BloomScreenBlendMode.Add;
var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
RenderTexture halfRezColor = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, rtFormat);
RenderTexture quarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
RenderTexture thirdQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
float oneOverBaseSize = 1.0f / 512.0f;
// downsample
Graphics.Blit(source, halfRezColor, screenBlend, 2); // <- 2 is stable downsample
Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); // <- 2 is stable downsample
RenderTexture.ReleaseTemporary(halfRezColor);
// cut colors (thresholding)
BrightFilter(bloomThreshold, useSrcAlphaAsMask, quarterRezColor, secondQuarterRezColor);
quarterRezColor.DiscardContents();
// blurring
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
for (int iter = 0; iter < bloomBlurIterations; iter++)
{
float spreadForPass = (1.0f + (iter * 0.5f)) * sepBlurSpread;
separableBlurMaterial.SetVector("offsets", new Vector4(0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
RenderTexture src = iter == 0 ? secondQuarterRezColor : quarterRezColor;
Graphics.Blit(src, thirdQuarterRezColor, separableBlurMaterial);
src.DiscardContents();
separableBlurMaterial.SetVector("offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit(thirdQuarterRezColor, quarterRezColor, separableBlurMaterial);
thirdQuarterRezColor.DiscardContents();
}
// lens flares: ghosting, anamorphic or a combination
if (lensflares)
{
if (lensflareMode == 0)
{
BrightFilter(lensflareThreshold, 0.0f, quarterRezColor, thirdQuarterRezColor);
quarterRezColor.DiscardContents();
// smooth a little, this needs to be resolution dependent
/*
separableBlurMaterial.SetVector ("offsets", Vector4 (0.0ff, (2.0ff) / (1.0ff * quarterRezColor.height), 0.0ff, 0.0ff));
Graphics.Blit (thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
separableBlurMaterial.SetVector ("offsets", Vector4 ((2.0ff) / (1.0ff * quarterRezColor.width), 0.0ff, 0.0ff, 0.0ff));
Graphics.Blit (secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
*/
// no ugly edges!
Vignette(0.975f, thirdQuarterRezColor, secondQuarterRezColor);
thirdQuarterRezColor.DiscardContents();
BlendFlares(secondQuarterRezColor, quarterRezColor);
secondQuarterRezColor.DiscardContents();
}
// (b) hollywood/anamorphic flares?
else
{
// thirdQuarter has the brightcut unblurred colors
// quarterRezColor is the blurred, brightcut buffer that will end up as bloom
hollywoodFlaresMaterial.SetVector("_threshold", new Vector4(lensflareThreshold, 1.0f / (1.0f - lensflareThreshold), 0.0f, 0.0f));
hollywoodFlaresMaterial.SetVector("tintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 2);
thirdQuarterRezColor.DiscardContents();
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 3);
secondQuarterRezColor.DiscardContents();
hollywoodFlaresMaterial.SetVector("offsets", new Vector4((sepBlurSpread * 1.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth);
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
thirdQuarterRezColor.DiscardContents();
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 2.0f);
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 1);
secondQuarterRezColor.DiscardContents();
hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 4.0f);
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
thirdQuarterRezColor.DiscardContents();
if (lensflareMode == (LensflareStyle34)1)
{
for (int itera = 0; itera < hollywoodFlareBlurIterations; itera++)
{
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
secondQuarterRezColor.DiscardContents();
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
thirdQuarterRezColor.DiscardContents();
}
AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
secondQuarterRezColor.DiscardContents();
}
else
{
// (c) combined
for (int ix = 0; ix < hollywoodFlareBlurIterations; ix++)
{
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
secondQuarterRezColor.DiscardContents();
separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
thirdQuarterRezColor.DiscardContents();
}
Vignette(1.0f, secondQuarterRezColor, thirdQuarterRezColor);
secondQuarterRezColor.DiscardContents();
BlendFlares(thirdQuarterRezColor, secondQuarterRezColor);
thirdQuarterRezColor.DiscardContents();
AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
secondQuarterRezColor.DiscardContents();
}
}
}
// screen blend bloom results to color buffer
screenBlend.SetFloat("_Intensity", bloomIntensity);
screenBlend.SetTexture("_ColorBuffer", source);
Graphics.Blit(quarterRezColor, destination, screenBlend, (int)realBlendMode);
RenderTexture.ReleaseTemporary(quarterRezColor);
RenderTexture.ReleaseTemporary(secondQuarterRezColor);
RenderTexture.ReleaseTemporary(thirdQuarterRezColor);
}
private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
{
addBrightStuffBlendOneOneMaterial.SetFloat("_Intensity", intensity_);
Graphics.Blit(from, to, addBrightStuffBlendOneOneMaterial);
}
private void BlendFlares(RenderTexture from, RenderTexture to)
{
lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
Graphics.Blit(from, to, lensFlareMaterial);
}
private void BrightFilter(float thresh, float useAlphaAsMask, RenderTexture from, RenderTexture to)
{
if (doHdr)
brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f, 0.0f, 0.0f));
else
brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f / (1.0f - thresh), 0.0f, 0.0f));
brightPassFilterMaterial.SetFloat("useSrcAlphaAsMask", useAlphaAsMask);
Graphics.Blit(from, to, brightPassFilterMaterial);
}
private void Vignette(float amount, RenderTexture from, RenderTexture to)
{
if (lensFlareVignetteMask)
{
screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
Graphics.Blit(from, to, screenBlend, 3);
}
else
{
vignetteMaterial.SetFloat("vignetteIntensity", amount);
Graphics.Blit(from, to, vignetteMaterial);
}
}
}
}
fileFormatVersion: 2
guid: 02536f33053638549ab5c50ff3ecc0de
MonoImporter:
serializedVersion: 2
defaultReferences:
- lensFlareVignetteMask: {fileID: 2800000, guid: 95ef4804fe0be4c999ddaa383536cde8,
type: 3}
- lensFlareShader: {fileID: 4800000, guid: 459fe69d2f6d74ddb92f04dbf45a866b, type: 3}
- vignetteShader: {fileID: 4800000, guid: 627943dc7a9a74286b70a4f694a0acd5, type: 3}
- separableBlurShader: {fileID: 4800000, guid: a9df009a214e24a5ebbf271595f8d5b6,
type: 3}
- addBrightStuffOneOneShader: {fileID: 4800000, guid: f7898d203e9b94c0dbe2bf9dd5cb32c0,
type: 3}
- screenBlendShader: {fileID: 4800000, guid: 53b3960ee3d3d4a5caa8d5473d120187, type: 3}
- hollywoodFlaresShader: {fileID: 4800000, guid: e2baf3cae8edc4daf94c9adc2154be00,
type: 3}
- brightPassFilterShader: {fileID: 4800000, guid: 186c4c0d31e314f049595dcbaf4ca129,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom (Optimized)")]
public class BloomOptimized : PostEffectsBase
{
public enum Resolution
{
Low = 0,
High = 1,
}
public enum BlurType
{
Standard = 0,
Sgx = 1,
}
[Range(0.0f, 1.5f)]
public float threshold = 0.25f;
[Range(0.0f, 2.5f)]
public float intensity = 0.75f;
[Range(0.25f, 5.5f)]
public float blurSize = 1.0f;
Resolution resolution = Resolution.Low;
[Range(1, 4)]
public int blurIterations = 1;
public BlurType blurType= BlurType.Standard;
public Shader fastBloomShader = null;
private Material fastBloomMaterial = null;
public override bool CheckResources ()
{
CheckSupport (false);
fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial);
if (!isSupported)
ReportAutoDisable ();
return isSupported;
}
void OnDisable ()
{
if (fastBloomMaterial)
DestroyImmediate (fastBloomMaterial);
}
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
if (CheckResources() == false)
{
Graphics.Blit (source, destination);
return;
}
int divider = resolution == Resolution.Low ? 4 : 2;
float widthMod = resolution == Resolution.Low ? 0.5f : 1.0f;
fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, 0.0f, threshold, intensity));
source.filterMode = FilterMode.Bilinear;
var rtW= source.width/divider;
var rtH= source.height/divider;
// downsample
RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
rt.filterMode = FilterMode.Bilinear;
Graphics.Blit (source, rt, fastBloomMaterial, 1);
var passOffs= blurType == BlurType.Standard ? 0 : 2;
for(int i = 0; i < blurIterations; i++)
{
fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + (i*1.0f), 0.0f, threshold, intensity));
// vertical blur
RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
rt2.filterMode = FilterMode.Bilinear;
Graphics.Blit (rt, rt2, fastBloomMaterial, 2 + passOffs);
RenderTexture.ReleaseTemporary (rt);
rt = rt2;
// horizontal blur
rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
rt2.filterMode = FilterMode.Bilinear;
Graphics.Blit (rt, rt2, fastBloomMaterial, 3 + passOffs);
RenderTexture.ReleaseTemporary (rt);
rt = rt2;
}
fastBloomMaterial.SetTexture ("_Bloom", rt);
Graphics.Blit (source, destination, fastBloomMaterial, 0);
RenderTexture.ReleaseTemporary (rt);
}
}
}
fileFormatVersion: 2
guid: 4975a6e437fc3b149a8cd508ce5bdd69
MonoImporter:
serializedVersion: 2
defaultReferences:
- fastBloomShader: {fileID: 4800000, guid: 68a00c837b82e4c6d92e7da765dc5f1d, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[RequireComponent(typeof (Camera))]
[AddComponentMenu("")]
public class ImageEffectBase : MonoBehaviour
{
/// Provides a shader property that is set in the inspector
/// and a material instantiated from the shader
public Shader shader;
private Material m_Material;
protected virtual void Start()
{
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
// Disable the image effect if the shader can't
// run on the users graphics card
if (!shader || !shader.isSupported)
enabled = false;
}
protected Material material
{
get
{
if (m_Material == null)
{
m_Material = new Material(shader);
m_Material.hideFlags = HideFlags.HideAndDontSave;
}
return m_Material;
}
}
protected virtual void OnDisable()
{
if (m_Material)
{
DestroyImmediate(m_Material);
}
}
}
}
fileFormatVersion: 2
guid: f6469eb0ad1119d6d00011d98d76c639
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
/// A Utility class for performing various image based rendering tasks.
[AddComponentMenu("")]
public class ImageEffects
{
public static void RenderDistortion(Material material, RenderTexture source, RenderTexture destination, float angle, Vector2 center, Vector2 radius)
{
bool invertY = source.texelSize.y < 0.0f;
if (invertY)
{
center.y = 1.0f - center.y;
angle = -angle;
}
Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, angle), Vector3.one);
material.SetMatrix("_RotationMatrix", rotationMatrix);
material.SetVector("_CenterRadius", new Vector4(center.x, center.y, radius.x, radius.y));
material.SetFloat("_Angle", angle*Mathf.Deg2Rad);
Graphics.Blit(source, destination, material);
}
[Obsolete("Use Graphics.Blit(source,dest) instead")]
public static void Blit(RenderTexture source, RenderTexture dest)
{
Graphics.Blit(source, dest);
}
[Obsolete("Use Graphics.Blit(source, destination, material) instead")]
public static void BlitWithMaterial(Material material, RenderTexture source, RenderTexture dest)
{
Graphics.Blit(source, dest, material);
}
}
}
fileFormatVersion: 2
guid: 89a037199d11087f1100e2b844295342
MonoImporter:
serializedVersion: 2
defaultReferences:
- blitCopyShader: {fileID: 4800000, guid: 3338b5ea2f3cb594698fae65cf060346, type: 3}
- blitMultiplyShader: {fileID: 4800000, guid: 7034c801b78acab448cdcf845f7c352d,
type: 3}
- blitMultiply2XShader: {fileID: 4800000, guid: cde82987e0a884c4788c65f7b54390e8,
type: 3}
- blitAddShader: {fileID: 4800000, guid: c7515f214a63bdb42b6ae6335a00a8a4, type: 3}
- blitAddSmoothShader: {fileID: 4800000, guid: 7741a77a7c455d0418bc429bd508dc87,
type: 3}
- blitBlendShader: {fileID: 4800000, guid: f1cf7e9c98754c4429ff0f7cc1d9dd7b, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
public class PostEffectsBase : MonoBehaviour
{
protected bool supportHDRTextures = true;
protected bool supportDX11 = false;
protected bool isSupported = true;
protected Material CheckShaderAndCreateMaterial ( Shader s, Material m2Create)
{
if (!s)
{
Debug.Log("Missing shader in " + ToString ());
enabled = false;
return null;
}
if (s.isSupported && m2Create && m2Create.shader == s)
return m2Create;
if (!s.isSupported)
{
NotSupported ();
Debug.Log("The shader " + s.ToString() + " on effect "+ToString()+" is not supported on this platform!");
return null;
}
else
{
m2Create = new Material (s);
m2Create.hideFlags = HideFlags.DontSave;
if (m2Create)
return m2Create;
else return null;
}
}
protected Material CreateMaterial (Shader s, Material m2Create)
{
if (!s)
{
Debug.Log ("Missing shader in " + ToString ());
return null;
}
if (m2Create && (m2Create.shader == s) && (s.isSupported))
return m2Create;
if (!s.isSupported)
{
return null;
}
else
{
m2Create = new Material (s);
m2Create.hideFlags = HideFlags.DontSave;
if (m2Create)
return m2Create;
else return null;
}
}
void OnEnable ()
{
isSupported = true;
}
protected bool CheckSupport ()
{
return CheckSupport (false);
}
public virtual bool CheckResources ()
{
Debug.LogWarning ("CheckResources () for " + ToString() + " should be overwritten.");
return isSupported;
}
protected void Start ()
{
CheckResources ();
}
protected bool CheckSupport (bool needDepth)
{
isSupported = true;
supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;
if (!SystemInfo.supportsImageEffects || !SystemInfo.supportsRenderTextures)
{
NotSupported ();
return false;
}
if (needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
{
NotSupported ();
return false;
}
if (needDepth)
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
return true;
}
protected bool CheckSupport (bool needDepth, bool needHdr)
{
if (!CheckSupport(needDepth))
return false;
if (needHdr && !supportHDRTextures)
{
NotSupported ();
return false;
}
return true;
}
public bool Dx11Support ()
{
return supportDX11;
}
protected void ReportAutoDisable ()
{
Debug.LogWarning ("The image effect " + ToString() + " has been disabled as it's not supported on the current platform.");
}
// deprecated but needed for old effects to survive upgrading
bool CheckShader (Shader s)
{
Debug.Log("The shader " + s.ToString () + " on effect "+ ToString () + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package.");
if (!s.isSupported)
{
NotSupported ();
return false;
}
else
{
return false;
}
}
protected void NotSupported ()
{
enabled = false;
isSupported = false;
return;
}
protected void DrawBorder (RenderTexture dest, Material material)
{
float x1;
float x2;
float y1;
float y2;
RenderTexture.active = dest;
bool invertY = true; // source.texelSize.y < 0.0ff;
// Set up the simple Matrix
GL.PushMatrix();
GL.LoadOrtho();
for (int i = 0; i < material.passCount; i++)
{
material.SetPass(i);
float y1_; float y2_;
if (invertY)
{
y1_ = 1.0f; y2_ = 0.0f;
}
else
{
y1_ = 0.0f; y2_ = 1.0f;
}
// left
x1 = 0.0f;
x2 = 0.0f + 1.0f/(dest.width*1.0f);
y1 = 0.0f;
y2 = 1.0f;
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// right
x1 = 1.0f - 1.0f/(dest.width*1.0f);
x2 = 1.0f;
y1 = 0.0f;
y2 = 1.0f;
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// top
x1 = 0.0f;
x2 = 1.0f;
y1 = 0.0f;
y2 = 0.0f + 1.0f/(dest.height*1.0f);
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// bottom
x1 = 0.0f;
x2 = 1.0f;
y1 = 1.0f - 1.0f/(dest.height*1.0f);
y2 = 1.0f;
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
GL.End();
}
GL.PopMatrix();
}
}
}
fileFormatVersion: 2
guid: b6f4318ec6c2bf643a0f9edfeeaba0ec
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
class PostEffectsHelper : MonoBehaviour
{
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
Debug.Log("OnRenderImage in Helper called ...");
}
static void DrawLowLevelPlaneAlignedWithCamera (
float dist ,
RenderTexture source, RenderTexture dest ,
Material material ,
Camera cameraForProjectionMatrix )
{
// Make the destination texture the target for all rendering
RenderTexture.active = dest;
// Assign the source texture to a property from a shader
material.SetTexture("_MainTex", source);
bool invertY = true; // source.texelSize.y < 0.0f;
// Set up the simple Matrix
GL.PushMatrix();
GL.LoadIdentity();
GL.LoadProjectionMatrix(cameraForProjectionMatrix.projectionMatrix);
float fovYHalfRad = cameraForProjectionMatrix.fieldOfView * 0.5f * Mathf.Deg2Rad;
float cotangent = Mathf.Cos(fovYHalfRad) / Mathf.Sin(fovYHalfRad);
float asp = cameraForProjectionMatrix.aspect;
float x1 = asp/-cotangent;
float x2 = asp/cotangent;
float y1 = 1.0f/-cotangent;
float y2 = 1.0f/cotangent;
float sc = 1.0f; // magic constant (for now)
x1 *= dist * sc;
x2 *= dist * sc;
y1 *= dist * sc;
y2 *= dist * sc;
float z1 = -dist;
for (int i = 0; i < material.passCount; i++)
{
material.SetPass(i);
GL.Begin(GL.QUADS);
float y1_; float y2_;
if (invertY)
{
y1_ = 1.0f; y2_ = 0.0f;
}
else
{
y1_ = 0.0f; y2_ = 1.0f;
}
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, z1);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, z1);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, z1);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, z1);
GL.End();
}
GL.PopMatrix();
}
static void DrawBorder (
RenderTexture dest ,
Material material )
{
float x1;
float x2;
float y1;
float y2;
RenderTexture.active = dest;
bool invertY = true; // source.texelSize.y < 0.0ff;
// Set up the simple Matrix
GL.PushMatrix();
GL.LoadOrtho();
for (int i = 0; i < material.passCount; i++)
{
material.SetPass(i);
float y1_; float y2_;
if (invertY)
{
y1_ = 1.0f; y2_ = 0.0f;
}
else
{
y1_ = 0.0f; y2_ = 1.0f;
}
// left
x1 = 0.0f;
x2 = 0.0f + 1.0f/(dest.width*1.0f);
y1 = 0.0f;
y2 = 1.0f;
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// right
x1 = 1.0f - 1.0f/(dest.width*1.0f);
x2 = 1.0f;
y1 = 0.0f;
y2 = 1.0f;
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// top
x1 = 0.0f;
x2 = 1.0f;
y1 = 0.0f;
y2 = 0.0f + 1.0f/(dest.height*1.0f);
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
// bottom
x1 = 0.0f;
x2 = 1.0f;
y1 = 1.0f - 1.0f/(dest.height*1.0f);
y2 = 1.0f;
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
GL.End();
}
GL.PopMatrix();
}
static void DrawLowLevelQuad ( float x1, float x2, float y1, float y2, RenderTexture source, RenderTexture dest, Material material )
{
// Make the destination texture the target for all rendering
RenderTexture.active = dest;
// Assign the source texture to a property from a shader
material.SetTexture("_MainTex", source);
bool invertY = true; // source.texelSize.y < 0.0f;
// Set up the simple Matrix
GL.PushMatrix();
GL.LoadOrtho();
for (int i = 0; i < material.passCount; i++)
{
material.SetPass(i);
GL.Begin(GL.QUADS);
float y1_; float y2_;
if (invertY)
{
y1_ = 1.0f; y2_ = 0.0f;
}
else
{
y1_ = 0.0f; y2_ = 1.0f;
}
GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);
GL.End();
}
GL.PopMatrix();
}
}
}
fileFormatVersion: 2
guid: 50b03df8f04b5c441aaac5b7fccb4734
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
using Object = UnityEngine.Object;
// same as Triangles but creates quads instead which generally
// saves fillrate at the expense for more triangles to issue
namespace UnityStandardAssets.ImageEffects
{
class Quads
{
static Mesh[] meshes;
static int currentQuads = 0;
static bool HasMeshes ()
{
if (meshes == null)
return false;
foreach (Mesh m in meshes)
if (null == m)
return false;
return true;
}
public static void Cleanup ()
{
if (meshes == null)
return;
for (int i = 0; i < meshes.Length; i++)
{
if (null != meshes[i])
{
Object.DestroyImmediate (meshes[i]);
meshes[i] = null;
}
}
meshes = null;
}
public static Mesh[] GetMeshes ( int totalWidth, int totalHeight)
{
if (HasMeshes () && (currentQuads == (totalWidth * totalHeight))) {
return meshes;
}
int maxQuads = 65000 / 6;
int totalQuads = totalWidth * totalHeight;
currentQuads = totalQuads;
int meshCount = Mathf.CeilToInt ((1.0f * totalQuads) / (1.0f * maxQuads));
meshes = new Mesh [meshCount];
int i = 0;
int index = 0;
for (i = 0; i < totalQuads; i += maxQuads)
{
int quads = Mathf.FloorToInt (Mathf.Clamp ((totalQuads-i), 0, maxQuads));
meshes[index] = GetMesh (quads, i, totalWidth, totalHeight);
index++;
}
return meshes;
}
static Mesh GetMesh (int triCount, int triOffset, int totalWidth, int totalHeight)
{
var mesh = new Mesh ();
mesh.hideFlags = HideFlags.DontSave;
var verts = new Vector3[triCount * 4];
var uvs = new Vector2[triCount * 4];
var uvs2 = new Vector2[triCount * 4];
var tris = new int[triCount * 6];
for (int i = 0; i < triCount; i++)
{
int i4 = i * 4;
int i6 = i * 6;
int vertexWithOffset = triOffset + i;
float x = Mathf.Floor (vertexWithOffset % totalWidth) / totalWidth;
float y = Mathf.Floor (vertexWithOffset / totalWidth) / totalHeight;
Vector3 position = new Vector3 (x * 2 - 1, y * 2 - 1, 1.0f);
verts[i4 + 0] = position;
verts[i4 + 1] = position;
verts[i4 + 2] = position;
verts[i4 + 3] = position;
uvs[i4 + 0] = new Vector2 (0.0f, 0.0f);
uvs[i4 + 1] = new Vector2 (1.0f, 0.0f);
uvs[i4 + 2] = new Vector2 (0.0f, 1.0f);
uvs[i4 + 3] = new Vector2 (1.0f, 1.0f);
uvs2[i4 + 0] = new Vector2 (x, y);
uvs2[i4 + 1] = new Vector2 (x, y);
uvs2[i4 + 2] = new Vector2 (x, y);
uvs2[i4 + 3] = new Vector2 (x, y);
tris[i6 + 0] = i4 + 0;
tris[i6 + 1] = i4 + 1;
tris[i6 + 2] = i4 + 2;
tris[i6 + 3] = i4 + 1;
tris[i6 + 4] = i4 + 2;
tris[i6 + 5] = i4 + 3;
}
mesh.vertices = verts;
mesh.triangles = tris;
mesh.uv = uvs;
mesh.uv2 = uvs2;
return mesh;
}
}
}
fileFormatVersion: 2
guid: a20852ce049f64e4695a48b6a354be83
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityStandardAssets.ImageEffects
{
class Triangles
{
private static Mesh[] meshes;
private static int currentTris = 0;
static bool HasMeshes()
{
if (meshes == null)
return false;
for (int i = 0; i < meshes.Length; i++)
if (null == meshes[i])
return false;
return true;
}
static void Cleanup()
{
if (meshes == null)
return;
for (int i = 0; i < meshes.Length; i++)
{
if (null != meshes[i])
{
Object.DestroyImmediate(meshes[i]);
meshes[i] = null;
}
}
meshes = null;
}
static Mesh[] GetMeshes(int totalWidth, int totalHeight)
{
if (HasMeshes() && (currentTris == (totalWidth * totalHeight)))
{
return meshes;
}
int maxTris = 65000 / 3;
int totalTris = totalWidth * totalHeight;
currentTris = totalTris;
int meshCount = Mathf.CeilToInt((1.0f * totalTris) / (1.0f * maxTris));
meshes = new Mesh[meshCount];
int i = 0;
int index = 0;
for (i = 0; i < totalTris; i += maxTris)
{
int tris = Mathf.FloorToInt(Mathf.Clamp((totalTris - i), 0, maxTris));
meshes[index] = GetMesh(tris, i, totalWidth, totalHeight);
index++;
}
return meshes;
}
static Mesh GetMesh(int triCount, int triOffset, int totalWidth, int totalHeight)
{
var mesh = new Mesh();
mesh.hideFlags = HideFlags.DontSave;
var verts = new Vector3[triCount * 3];
var uvs = new Vector2[triCount * 3];
var uvs2 = new Vector2[triCount * 3];
var tris = new int[triCount * 3];
for (int i = 0; i < triCount; i++)
{
int i3 = i * 3;
int vertexWithOffset = triOffset + i;
float x = Mathf.Floor(vertexWithOffset % totalWidth) / totalWidth;
float y = Mathf.Floor(vertexWithOffset / totalWidth) / totalHeight;
Vector3 position = new Vector3(x * 2 - 1, y * 2 - 1, 1.0f);
verts[i3 + 0] = position;
verts[i3 + 1] = position;
verts[i3 + 2] = position;
uvs[i3 + 0] = new Vector2(0.0f, 0.0f);
uvs[i3 + 1] = new Vector2(1.0f, 0.0f);
uvs[i3 + 2] = new Vector2(0.0f, 1.0f);
uvs2[i3 + 0] = new Vector2(x, y);
uvs2[i3 + 1] = new Vector2(x, y);
uvs2[i3 + 2] = new Vector2(x, y);
tris[i3 + 0] = i3 + 0;
tris[i3 + 1] = i3 + 1;
tris[i3 + 2] = i3 + 2;
}
mesh.vertices = verts;
mesh.triangles = tris;
mesh.uv = uvs;
mesh.uv2 = uvs2;
return mesh;
}
}
}
fileFormatVersion: 2
guid: 18b91636de2ba3445913e4cf38528dc8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
using System;
using UnityEngine;
namespace UnityStandardAssets.ImageEffects
{
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
[AddComponentMenu ("Image Effects/Camera/Vignette and Chromatic Aberration")]
public class VignetteAndChromaticAberration : PostEffectsBase
{
public enum AberrationMode
{
Simple = 0,
Advanced = 1,
}
public AberrationMode mode = AberrationMode.Simple;
public float intensity = 0.375f; // intensity == 0 disables pre pass (optimization)
public float chromaticAberration = 0.2f;
public float axialAberration = 0.5f;
public float blur = 0.0f; // blur == 0 disables blur pass (optimization)
public float blurSpread = 0.75f;
public float luminanceDependency = 0.25f;
public float blurDistance = 2.5f;
public Shader vignetteShader;
public Shader separableBlurShader;
public Shader chromAberrationShader;
private Material m_VignetteMaterial;
private Material m_SeparableBlurMaterial;
private Material m_ChromAberrationMaterial;
public override bool CheckResources ()
{
CheckSupport (false);
m_VignetteMaterial = CheckShaderAndCreateMaterial (vignetteShader, m_VignetteMaterial);
m_SeparableBlurMaterial = CheckShaderAndCreateMaterial (separableBlurShader, m_SeparableBlurMaterial);
m_ChromAberrationMaterial = CheckShaderAndCreateMaterial (chromAberrationShader, m_ChromAberrationMaterial);
if (!isSupported)
ReportAutoDisable ();
return isSupported;
}
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
if ( CheckResources () == false)
{
Graphics.Blit (source, destination);
return;
}
int rtW = source.width;
int rtH = source.height;
bool doPrepass = (Mathf.Abs(blur)>0.0f || Mathf.Abs(intensity)>0.0f);
float widthOverHeight = (1.0f * rtW) / (1.0f * rtH);
const float oneOverBaseSize = 1.0f / 512.0f;
RenderTexture color = null;
RenderTexture color2A = null;
if (doPrepass)
{
color = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
// Blur corners
if (Mathf.Abs (blur)>0.0f)
{
color2A = RenderTexture.GetTemporary (rtW / 2, rtH / 2, 0, source.format);
Graphics.Blit (source, color2A, m_ChromAberrationMaterial, 0);
for(int i = 0; i < 2; i++)
{ // maybe make iteration count tweakable
m_SeparableBlurMaterial.SetVector ("offsets",new Vector4 (0.0f, blurSpread * oneOverBaseSize, 0.0f, 0.0f));
RenderTexture color2B = RenderTexture.GetTemporary (rtW / 2, rtH / 2, 0, source.format);
Graphics.Blit (color2A, color2B, m_SeparableBlurMaterial);
RenderTexture.ReleaseTemporary (color2A);
m_SeparableBlurMaterial.SetVector ("offsets",new Vector4 (blurSpread * oneOverBaseSize / widthOverHeight, 0.0f, 0.0f, 0.0f));
color2A = RenderTexture.GetTemporary (rtW / 2, rtH / 2, 0, source.format);
Graphics.Blit (color2B, color2A, m_SeparableBlurMaterial);
RenderTexture.ReleaseTemporary (color2B);
}
}
m_VignetteMaterial.SetFloat ("_Intensity", intensity); // intensity for vignette
m_VignetteMaterial.SetFloat ("_Blur", blur); // blur intensity
m_VignetteMaterial.SetTexture ("_VignetteTex", color2A); // blurred texture
Graphics.Blit (source, color, m_VignetteMaterial, 0); // prepass blit: darken & blur corners
}
m_ChromAberrationMaterial.SetFloat ("_ChromaticAberration", chromaticAberration);
m_ChromAberrationMaterial.SetFloat ("_AxialAberration", axialAberration);
m_ChromAberrationMaterial.SetVector ("_BlurDistance", new Vector2 (-blurDistance, blurDistance));
m_ChromAberrationMaterial.SetFloat ("_Luminance", 1.0f/Mathf.Max(Mathf.Epsilon, luminanceDependency));
if (doPrepass) color.wrapMode = TextureWrapMode.Clamp;
else source.wrapMode = TextureWrapMode.Clamp;
Graphics.Blit (doPrepass ? color : source, destination, m_ChromAberrationMaterial, mode == AberrationMode.Advanced ? 2 : 1);
RenderTexture.ReleaseTemporary (color);
RenderTexture.ReleaseTemporary (color2A);
}
}
}
fileFormatVersion: 2
guid: dd6d4281e5d7cd44d8c6e38bc2c1b8d8
MonoImporter:
serializedVersion: 2
defaultReferences:
- vignetteShader: {fileID: 4800000, guid: 627943dc7a9a74286b70a4f694a0acd5, type: 3}
- separableBlurShader: {fileID: 4800000, guid: e97c14fbb5ea04c3a902cc533d7fc5d1,
type: 3}
- chromAberrationShader: {fileID: 4800000, guid: 2b4f29398d9484ccfa9fd220449f5eee,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
fileFormatVersion: 2
guid: b2145489f7c704db8acb14a52bddeee9
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
Shader "Hidden/BlendModesOverlay" {
Properties {
_MainTex ("Screen Blended", 2D) = "" {}
_Overlay ("Color", 2D) = "grey" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
sampler2D _Overlay;
sampler2D _MainTex;
half _Intensity;
half4 _MainTex_TexelSize;
half4 _UV_Transform = half4(1, 0, 0, 1);
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = float2(
dot(v.texcoord.xy, _UV_Transform.xy),
dot(v.texcoord.xy, _UV_Transform.zw)
);
#if UNITY_UV_STARTS_AT_TOP
if(_MainTex_TexelSize.y<0.0)
o.uv[0].y = 1.0-o.uv[0].y;
#endif
o.uv[1] = v.texcoord.xy;
return o;
}
half4 fragAddSub (v2f i) : SV_Target {
half4 toAdd = tex2D(_Overlay, i.uv[0]) * _Intensity;
return tex2D(_MainTex, i.uv[1]) + toAdd;
}
half4 fragMultiply (v2f i) : SV_Target {
half4 toBlend = tex2D(_Overlay, i.uv[0]) * _Intensity;
return tex2D(_MainTex, i.uv[1]) * toBlend;
}
half4 fragScreen (v2f i) : SV_Target {
half4 toBlend = (tex2D(_Overlay, i.uv[0]) * _Intensity);
return 1-(1-toBlend)*(1-(tex2D(_MainTex, i.uv[1])));
}
half4 fragOverlay (v2f i) : SV_Target {
half4 m = (tex2D(_Overlay, i.uv[0]));// * 255.0;
half4 color = (tex2D(_MainTex, i.uv[1]));//* 255.0;
// overlay blend mode
//color.rgb = (color.rgb/255.0) * (color.rgb + ((2*m.rgb)/( 255.0 )) * (255.0-color.rgb));
//color.rgb /= 255.0;
/*
if (Target > ½) R = 1 - (1-2x(Target-½)) x (1-Blend)
if (Target <= ½) R = (2xTarget) x Blend
*/
float3 check = step(0.5, color.rgb);
float3 result = 0;
result = check * (half3(1,1,1) - ( (half3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
result += (1-check) * (2*color.rgb) * m.rgb;
return half4(lerp(color.rgb, result.rgb, (_Intensity)), color.a);
}
half4 fragAlphaBlend (v2f i) : SV_Target {
half4 toAdd = tex2D(_Overlay, i.uv[0]) ;
return lerp(tex2D(_MainTex, i.uv[1]), toAdd, toAdd.a);
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
ColorMask RGB
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAddSub
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScreen
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragMultiply
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragOverlay
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAlphaBlend
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 8c81db0e527d24acc9bcec04e87781bd
ShaderImporter:
userData:
Shader "Hidden/BlurEffectConeTap" {
Properties { _MainTex ("", any) = "" {} }
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half2 taps[4] : TEXCOORD1;
};
sampler2D _MainTex;
half4 _MainTex_TexelSize;
half4 _BlurOffsets;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord - _BlurOffsets.xy * _MainTex_TexelSize.xy; // hack, see BlurEffect.cs for the reason for this. let's make a new blur effect soon
o.taps[0] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy;
o.taps[1] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy;
o.taps[2] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
o.taps[3] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
return o;
}
half4 frag(v2f i) : SV_Target {
half4 color = tex2D(_MainTex, i.taps[0]);
color += tex2D(_MainTex, i.taps[1]);
color += tex2D(_MainTex, i.taps[2]);
color += tex2D(_MainTex, i.taps[3]);
return color * 0.25;
}
ENDCG
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 57e6deea7c2924e22a5138e2b70bb4dc
ShaderImporter:
userData:
/*
CAMERA MOTION BLUR IMAGE EFFECTS
Reconstruction Filter:
Based on "Plausible Motion Blur"
http://graphics.cs.williams.edu/papers/MotionBlurI3D12/
CameraMotion:
Based on Alex Vlacho's technique in
http://www.valvesoftware.com/publications/2008/GDC2008_PostProcessingInTheOrangeBox.pdf
SimpleBlur:
Straightforward sampling along velocities
ScatterFromGather:
Combines Reconstruction with depth of field type defocus
*/
Shader "Hidden/CameraMotionBlur" {
Properties {
_MainTex ("-", 2D) = "" {}
_NoiseTex ("-", 2D) = "grey" {}
_VelTex ("-", 2D) = "black" {}
_NeighbourMaxTex ("-", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
// 's' in paper (# of samples for reconstruction)
#define NUM_SAMPLES (11)
// # samples for valve style blur
#define MOTION_SAMPLES (16)
// 'k' in paper
float _MaxRadiusOrKInPaper;
static const int SmallDiscKernelSamples = 12;
static const float2 SmallDiscKernel[SmallDiscKernelSamples] =
{
float2(-0.326212,-0.40581),
float2(-0.840144,-0.07358),
float2(-0.695914,0.457137),
float2(-0.203345,0.620716),
float2(0.96234,-0.194983),
float2(0.473434,-0.480026),
float2(0.519456,0.767022),
float2(0.185461,-0.893124),
float2(0.507431,0.064425),
float2(0.89642,0.412458),
float2(-0.32194,-0.932615),
float2(-0.791559,-0.59771)
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
sampler2D _VelTex;
sampler2D _NeighbourMaxTex;
sampler2D _NoiseTex;
sampler2D _TileTexDebug;
float4 _MainTex_TexelSize;
float4 _CameraDepthTexture_TexelSize;
float4 _VelTex_TexelSize;
float4x4 _InvViewProj; // inverse view-projection matrix
float4x4 _PrevViewProj; // previous view-projection matrix
float4x4 _ToPrevViewProjCombined; // combined
float _Jitter;
float _VelocityScale;
float _DisplayVelocityScale;
float _MaxVelocity;
float _MinVelocity;
float4 _BlurDirectionPacked;
float _SoftZDistance;
v2f vert(appdata_img v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float4 CameraVelocity(v2f i) : SV_Target
{
float2 depth_uv = i.uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
depth_uv.y = 1 - depth_uv.y;
#endif
// read depth
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, depth_uv);
// calculate position from pixel from depth
float3 clipPos = float3(i.uv.x*2.0-1.0, (i.uv.y)*2.0-1.0, d);
// only 1 matrix mul:
float4 prevClipPos = mul(_ToPrevViewProjCombined, float4(clipPos, 1.0));
prevClipPos.xyz /= prevClipPos.w;
/*
float4 ws = mul(_InvViewProj, float4(clipPos, 1.0));
ws /= ws.w;
prevClipPos = mul(_PrevViewProj,ws);
prevClipPos.xyz /= prevClipPos.w;
*/
/*
float2 vel = _VelocityScale *(clipPos.xy - prevClipPos.xy) / 2.f;
// clamp to maximum velocity (in pixels)
float maxVel = length(_MainTex_TexelSize.xy*_MaxVelocity);
if (length(vel) > maxVel) {
vel = normalize(vel) * maxVel;
}
return float4(vel, 0.0, 0.0);
*/
float2 vel = _MainTex_TexelSize.zw * _VelocityScale * (clipPos.xy - prevClipPos.xy) / 2.f;
float vellen = length(vel);
float maxVel = _MaxVelocity;
float2 velOut = vel * max(0.5, min(vellen, maxVel)) / (vellen + 1e-2f);
velOut *= _MainTex_TexelSize.xy;
return float4(velOut, 0.0, 0.0);
}
// vector with largest magnitude
float2 vmax(float2 a, float2 b)
{
float ma = dot(a, a);
float mb = dot(b, b);
return (ma > mb) ? a : b;
}
// find dominant velocity for each tile
float4 TileMax(v2f i) : SV_Target
{
float2 uvCorner = i.uv - _MainTex_TexelSize.xy * (_MaxRadiusOrKInPaper * 0.5);
float2 maxvel = float2(0,0);
float4 baseUv = float4(uvCorner,0,0);
float4 uvScale = float4(_MainTex_TexelSize.xy, 0, 0);
for(int l=0; l<(int)_MaxRadiusOrKInPaper; l++)
{
for(int k=0; k<(int)_MaxRadiusOrKInPaper; k++)
{
maxvel = vmax(maxvel, tex2Dlod(_MainTex, baseUv + float4(l,k,0,0) * uvScale).xy);
}
}
return float4(maxvel, 0, 1);
}
// find maximum velocity in any adjacent tile
float4 NeighbourMax(v2f i) : SV_Target
{
float2 x_ = i.uv;
// to fetch all neighbours, we need 3x3 point filtered samples
float2 nx = tex2D(_MainTex, x_+float2(1.0, 1.0)*_MainTex_TexelSize.xy).xy;
nx = vmax(nx, tex2D(_MainTex, x_+float2(1.0, 0.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(1.0,-1.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0, 1.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0, 0.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0,-1.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0, 1.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0, 0.0)*_MainTex_TexelSize.xy).xy);
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0,-1.0)*_MainTex_TexelSize.xy).xy);
return float4(nx, 0, 0);
}
float4 Debug(v2f i) : SV_Target
{
return saturate( float4(tex2D(_MainTex, i.uv).x,abs(tex2D(_MainTex, i.uv).y),-tex2D(_MainTex, i.uv).xy) * _DisplayVelocityScale);
}
// classification filters
float cone(float2 px, float2 py, float2 v)
{
return clamp(1.0 - (length(px - py) / length(v)), 0.0, 1.0);
}
float cylinder(float2 x, float2 y, float2 v)
{
float lv = length(v);
return 1.0 - smoothstep(0.95*lv, 1.05*lv, length(x - y));
}
// is zb closer than za?
float softDepthCompare(float za, float zb)
{
return clamp(1.0 - (za - zb) / _SoftZDistance, 0.0, 1.0);
}
float4 SimpleBlur (v2f i) : SV_Target
{
float2 x = i.uv;
float2 xf = x;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
xf.y = 1 - xf.y;
#endif
float2 vx = tex2D(_VelTex, xf).xy; // vel at x
float4 sum = float4(0, 0, 0, 0);
for(int l=0; l<NUM_SAMPLES; l++) {
float t = l / (float) (NUM_SAMPLES - 1);
t = t-0.5;
float2 y = x - vx*t;
float4 cy = tex2D(_MainTex, y);
sum += cy;
}
sum /= NUM_SAMPLES;
return sum;
}
float4 ReconstructFilterBlur(v2f i) : SV_Target
{
// uv's
float2 x = i.uv;
float2 xf = x;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
xf.y = 1-xf.y;
#endif
float2 x2 = xf;
float2 vn = tex2Dlod(_NeighbourMaxTex, float4(x2,0,0)).xy; // largest velocity in neighbourhood
float4 cx = tex2Dlod(_MainTex, float4(x,0,0)); // color at x
float2 vx = tex2Dlod(_VelTex, float4(xf,0,0)).xy; // vel at x
float zx = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(x,0,0));
zx = -Linear01Depth(zx);
// random offset [-0.5, 0.5]
float j = (tex2Dlod(_NoiseTex, float4(i.uv,0,0) * 11.0f).r*2-1) * _Jitter;
// sample current pixel
float weight = 0.75; // <= good start weight choice??
float4 sum = cx * weight;
int centerSample = (int)(NUM_SAMPLES-1)/2;
for(int l=0; l<NUM_SAMPLES; l++)
{
float contrib = 1.0f;
#if SHADER_API_D3D11
if (l==centerSample) continue; // skip center sample
#else
if (l==centerSample) contrib = 0.0f; // skip center sample
#endif
float t = lerp(-1.0, 1.0, (l + j) / (-1 + _Jitter + (float)NUM_SAMPLES));
//float t = lerp(-1.0, 1.0, l / (float)(NUM_SAMPLES - 1));
float2 y = x + vn * t;
float2 yf = y;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
yf.y = 1-yf.y;
#endif
// velocity at y
float2 vy = tex2Dlod(_VelTex, float4(yf,0,0)).xy;
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y,0,0));
zy = -Linear01Depth(zy);
float f = softDepthCompare(zx, zy);
float b = softDepthCompare(zy, zx);
float alphay = b * cone(x, y, vx) + f * cone(y, x, vy) + cylinder(y, x, vy) * cylinder(x, y, vx) * 2.0;
float4 cy = tex2Dlod(_MainTex, float4(y,0,0));
sum += cy * alphay * contrib;
weight += alphay * contrib;
}
sum /= weight;
return sum;
}
float4 ReconstructionDiscBlur (v2f i) : SV_Target
{
float2 xf = i.uv;
float2 x = i.uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
xf.y = 1 - xf.y;
#endif
float2 x2 = xf;
float2 vn = tex2Dlod(_NeighbourMaxTex, float4(x2,0,0)).xy; // largest velocity in neighbourhood
float4 cx = tex2Dlod(_MainTex, float4(x,0,0)); // color at x
float2 vx = tex2Dlod(_VelTex, float4(xf,0,0)).xy; // vel at x
float4 noise = tex2Dlod(_NoiseTex, float4(i.uv,0,0)*11.0f)*2-1;
float zx = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(x,0,0));
zx = -Linear01Depth(zx);
noise *= _MainTex_TexelSize.xyxy * _Jitter;
//return abs(blurDir.xyxy)*10 + centerTap;
float weight = 1.0; // <- maybe tweak this: bluriness amount ...
float4 sum = cx * weight;
float4 jitteredDir = vn.xyxy + noise.xyyz;
#ifdef SHADER_API_D3D11
jitteredDir = max(abs(jitteredDir.xyxy), _MainTex_TexelSize.xyxy * _MaxVelocity * 0.5) * sign(jitteredDir.xyxy) * float4(1,1,-1,-1);
#else
jitteredDir = max(abs(jitteredDir.xyxy), _MainTex_TexelSize.xyxy * _MaxVelocity * 0.15) * sign(jitteredDir.xyxy) * float4(1,1,-1,-1);
#endif
for(int l=0; l<SmallDiscKernelSamples; l++)
{
float4 y = i.uv.xyxy + jitteredDir.xyxy * SmallDiscKernel[l].xyxy * float4(1,1,-1,-1);
float4 yf = y;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
yf.yw = 1-yf.yw;
#endif
// velocity at y
float2 vy = tex2Dlod(_VelTex, float4(yf.xy,0,0)).xy;
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y.xy,0,0) );
zy = -Linear01Depth(zy);
float f = softDepthCompare(zx, zy);
float b = softDepthCompare(zy, zx);
float alphay = b * cone(x, y.xy, vx) + f * cone(y.xy, x, vy) + cylinder(y.xy, x, vy) * cylinder(x, y.xy, vx) * 2.0;
float4 cy = tex2Dlod(_MainTex, float4(y.xy,0,0));
sum += cy * alphay;
weight += alphay;
#ifdef SHADER_API_D3D11
vy = tex2Dlod(_VelTex, float4(yf.zw,0,0)).xy;
zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y.zw,0,0) );
zy = -Linear01Depth(zy);
f = softDepthCompare(zx, zy);
b = softDepthCompare(zy, zx);
alphay = b * cone(x, y.zw, vx) + f * cone(y.zw, x, vy) + cylinder(y.zw, x, vy) * cylinder(x, y.zw, vx) * 2.0;
cy = tex2Dlod(_MainTex, float4(y.zw,0,0));
sum += cy * alphay;
weight += alphay;
#endif
}
return sum / weight;
}
float4 MotionVectorBlur (v2f i) : SV_Target
{
float2 x = i.uv;
float2 insideVector = (x*2-1) * float2(1,_MainTex_TexelSize.w/_MainTex_TexelSize.z);
float2 rollVector = float2(insideVector.y, -insideVector.x);
float2 blurDir = _BlurDirectionPacked.x * float2(0,1);
blurDir += _BlurDirectionPacked.y * float2(1,0);
blurDir += _BlurDirectionPacked.z * rollVector;
blurDir += _BlurDirectionPacked.w * insideVector;
blurDir *= _VelocityScale;
// clamp to maximum velocity (in pixels)
float velMag = length(blurDir);
if (velMag > _MaxVelocity) {
blurDir *= (_MaxVelocity / velMag);
velMag = _MaxVelocity;
}
float4 centerTap = tex2D(_MainTex, x);
float4 sum = centerTap;
blurDir *= smoothstep(_MinVelocity * 0.25f, _MinVelocity * 2.5, velMag);
blurDir *= _MainTex_TexelSize.xy;
blurDir /= MOTION_SAMPLES;
for(int i=0; i<MOTION_SAMPLES; i++) {
float4 tap = tex2D(_MainTex, x+i*blurDir);
sum += tap;
}
return sum/(1+MOTION_SAMPLES);
}
ENDCG
Subshader {
// pass 0
Pass {
ZTest Always Cull Off ZWrite On Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment CameraVelocity
ENDCG
}
// pass 1
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment Debug
ENDCG
}
// pass 2
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment TileMax
ENDCG
}
// pass 3
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment NeighbourMax
ENDCG
}
// pass 4
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment ReconstructFilterBlur
ENDCG
}
// pass 5
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment SimpleBlur
ENDCG
}
// pass 6
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment MotionVectorBlur
ENDCG
}
// pass 7
Pass {
ZTest Always Cull Off ZWrite Off Blend Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment ReconstructionDiscBlur
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 85a88efa8c871af4a9d17c64791b6f4f
ShaderImporter:
userData:
/*
NOTES: see CameraMotionBlur.shader
*/
Shader "Hidden/CameraMotionBlurDX11" {
Properties {
_MainTex ("-", 2D) = "" {}
_NoiseTex ("-", 2D) = "grey" {}
_VelTex ("-", 2D) = "black" {}
_NeighbourMaxTex ("-", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
// 'k' in paper
float _MaxRadiusOrKInPaper;
// 's' in paper
#define NUM_SAMPLES (19)
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
sampler2D _VelTex;
sampler2D _NeighbourMaxTex;
sampler2D _NoiseTex;
float4 _MainTex_TexelSize;
float4 _CameraDepthTexture_TexelSize;
float4 _VelTex_TexelSize;
float4x4 _InvViewProj; // inverse view-projection matrix
float4x4 _PrevViewProj; // previous view-projection matrix
float4x4 _ToPrevViewProjCombined; // combined
float _Jitter;
float _VelocityScale;
float _DisplayVelocityScale;
float _MinVelocity;
float _SoftZDistance;
v2f vert(appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
// returns vector with largest magnitude
float2 vmax(float2 a, float2 b)
{
float ma = dot(a, a);
float mb = dot(b, b);
return (ma > mb) ? a : b;
}
// find dominant velocity in each tile
float4 TileMax(v2f i) : SV_Target
{
float2 tilemax = float2(0.0, 0.0);
float2 srcPos = i.uv - _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper * 0.5;
for(int y=0; y<(int)_MaxRadiusOrKInPaper; y++) {
for(int x=0; x<(int)_MaxRadiusOrKInPaper; x++) {
float2 v = tex2D(_MainTex, srcPos + float2(x,y) * _MainTex_TexelSize.xy).xy;
tilemax = vmax(tilemax, v);
}
}
return float4(tilemax, 0, 1);
}
// find maximum velocity in any adjacent tile
float4 NeighbourMax(v2f i) : SV_Target
{
float2 maxvel = float2(0.0, 0.0);
for(int y=-1; y<=1; y++) {
for(int x=-1; x<=1; x++) {
float2 v = tex2D(_MainTex, i.uv + float2(x,y) * _MainTex_TexelSize.xy).xy;
maxvel = vmax(maxvel, v);
}
}
return float4(maxvel, 0, 1);
}
float cone(float2 px, float2 py, float2 v)
{
return clamp(1.0 - (length(px - py) / length(v)), 0.0, 1.0);
}
float cylinder(float2 x, float2 y, float2 v)
{
float lv = length(v);
return 1.0 - smoothstep(0.95*lv, 1.05*lv, length(x - y));
}
float softDepthCompare(float za, float zb)
{
return clamp(1.0 - (za - zb) / _SoftZDistance, 0.0, 1.0);
}
float4 ReconstructFilterBlur(v2f i) : SV_Target
{
float2 x = i.uv;
float2 xf = x;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
xf.y = 1-xf.y;
#endif
float2 x2 = xf;
float2 vn = tex2D(_NeighbourMaxTex, x2).xy; // largest velocity in neighbourhood
float4 cx = tex2D(_MainTex, x); // color at x
float zx = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, x);
zx = -Linear01Depth(zx); // depth at x
float2 vx = tex2D(_VelTex, xf).xy; // vel at x
// random offset [-0.5, 0.5]
float j = (tex2D(_NoiseTex, i.uv * 11.0f ).r*2-1) * _Jitter;
// sample current pixel
float weight = 1.0;
float4 sum = cx * weight;
int centerSample = (int)(NUM_SAMPLES-1) / 2;
// in DX11 county we take more samples and interleave with sampling along vx direction to break up "patternized" look
for(int l=0; l<NUM_SAMPLES; l++)
{
if (l==centerSample) continue; // skip center sample
// Choose evenly placed filter taps along +-vN,
// but jitter the whole filter to prevent ghosting
float t = lerp(-1.0, 1.0, (l + j) / (-1 + _Jitter + (float)NUM_SAMPLES));
//float t = lerp(-1.0, 1.0, l / (float)(NUM_SAMPLES - 1));
float2 velInterlaved = lerp(vn, min(vx, normalize(vx) * _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper), l%2==0);
float2 y = x + velInterlaved * t;
float2 yf = y;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
yf.y = 1-yf.y;
#endif
// velocity at y
float2 vy = tex2Dlod(_VelTex, float4(yf,0,0)).xy;
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y,0,0));
zy = -Linear01Depth(zy);
float f = softDepthCompare(zx, zy);
float b = softDepthCompare(zy, zx);
float alphay = f * cone(y, x, vy) + // blurry y in front of any x
b * cone(x, y, vx) + // any y behing blurry x; estimate background
cylinder(y, x, vy) * cylinder(x, y, vx) * 2.0; // simultaneous blurry x and y
float4 cy = tex2Dlod(_MainTex, float4(y,0,0));
sum += cy * alphay;
weight += alphay;
}
sum /= weight;
return sum;
}
ENDCG
Subshader {
// pass 0
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma fragment TileMax
ENDCG
}
// pass 1
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma fragment NeighbourMax
ENDCG
}
// pass 2
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma fragment ReconstructFilterBlur
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: f1b13d7a80660504a858ea24cfa418c6
ShaderImporter:
userData:
Shader "Hidden/ChromaticAberration" {
Properties {
_MainTex ("Base", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
half _ChromaticAberration;
half _AxialAberration;
half _Luminance;
half2 _BlurDistance;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 fragDs(v2f i) : SV_Target
{
half4 c = tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * 0.5);
c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * 0.5);
c += tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * float2(0.5,-0.5));
c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * float2(0.5,-0.5));
return c/4.0;
}
half4 frag(v2f i) : SV_Target
{
half2 coords = i.uv;
half2 uv = i.uv;
coords = (coords - 0.5) * 2.0;
half coordDot = dot (coords,coords);
half2 uvG = uv - _MainTex_TexelSize.xy * _ChromaticAberration * coords * coordDot;
half4 color = tex2D (_MainTex, uv);
#if SHADER_API_D3D9
// Work around Cg's code generation bug for D3D9 pixel shaders :(
color.g = color.g * 0.0001 + tex2D (_MainTex, uvG).g;
#else
color.g = tex2D (_MainTex, uvG).g;
#endif
return color;
}
// squeezing into SM2.0 with 9 samples:
static const int SmallDiscKernelSamples = 9;
static const half2 SmallDiscKernel[SmallDiscKernelSamples] =
{
half2(-0.926212,-0.40581),
half2(-0.695914,0.457137),
half2(-0.203345,0.820716),
half2(0.96234,-0.194983),
half2(0.473434,-0.480026),
half2(0.519456,0.767022),
half2(0.185461,-0.893124),
half2(0.89642,0.412458),
half2(-0.32194,-0.932615),
};
half4 fragComplex(v2f i) : SV_Target
{
half2 coords = i.uv;
half2 uv = i.uv;
// corner heuristic
coords = (coords - 0.5h) * 2.0h;
half coordDot = dot (coords,coords);
half4 color = tex2D (_MainTex, uv);
half tangentialStrength = _ChromaticAberration * coordDot * coordDot;
half maxOfs = clamp(max(_AxialAberration, tangentialStrength), _BlurDistance.x, _BlurDistance.y);
// we need a blurred sample tap for advanced aberration
// NOTE: it's relatively important that input is HDR
// and if you do have a proper HDR setup, lerping .rb might yield better results than .g
// (see below)
half4 blurredTap = color * 0.1h;
for(int l=0; l < SmallDiscKernelSamples; l++)
{
half2 sampleUV = uv + SmallDiscKernel[l].xy * _MainTex_TexelSize.xy * maxOfs;
half3 tap = tex2D(_MainTex, sampleUV).rgb;
blurredTap.rgb += tap;
}
blurredTap.rgb /= (float)SmallDiscKernelSamples + 0.2h;
// debug:
//return blurredTap;
half lumDiff = Luminance(abs(blurredTap.rgb-color.rgb));
half isEdge = saturate(_Luminance * lumDiff);
// debug #2:
//return isEdge;
color.rb = lerp(color.rb, blurredTap.rb, isEdge);
return color;
}
ENDCG
Subshader {
// 0: box downsample
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragDs
ENDCG
}
// 1: simple chrom aberration
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
// 2: simulates more chromatic aberration effects
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragComplex
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 2b4f29398d9484ccfa9fd220449f5eee
ShaderImporter:
userData:
Shader "Hidden/ColorCorrection3DLut" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler3D _ClutTex;
float _Scale;
float _Offset;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float4 frag(v2f i) : SV_Target
{
float4 c = tex2D(_MainTex, i.uv);
c.rgb = tex3D(_ClutTex, c.rgb * _Scale + _Offset).rgb;
return c;
}
float4 fragLinear(v2f i) : SV_Target
{
float4 c = tex2D(_MainTex, i.uv);
c.rgb= sqrt(c.rgb);
c.rgb = tex3D(_ClutTex, c.rgb * _Scale + _Offset).rgb;
c.rgb = c.rgb*c.rgb;
return c;
}
ENDCG
Subshader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragLinear
#pragma target 3.0
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: b61f0d8d8244b4b28aa66b0c8cb46a8d
ShaderImporter:
userData:
Shader "Hidden/ColorCorrectionCurves" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_RgbTex ("_RgbTex (RGB)", 2D) = "" {}
_ZCurve ("_ZCurve (RGB)", 2D) = "" {}
_RgbDepthTex ("_RgbDepthTex (RGB)", 2D) = "" {}
}
// note: also have a look at ColorCorrectionCurvesSimple
// for a much simpler color correction without use of
// depth texture lookups
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
float4 _CameraDepthTexture_ST;
uniform float4 _MainTex_TexelSize;
sampler2D _RgbTex;
sampler2D _ZCurve;
sampler2D _RgbDepthTex;
fixed _Saturation;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv2 = TRANSFORM_TEX(v.texcoord, _CameraDepthTexture);
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv2.y = 1-o.uv2.y;
#endif
return o;
}
half4 frag(v2f i) : SV_Target
{
half4 color = tex2D(_MainTex, i.uv);
half3 ycoords = half3(0.5,1.5,2.5) * 0.25;
half3 red = tex2D(_RgbTex, half2(color.r, ycoords.x)).rgb * half3(1,0,0);
half3 green = tex2D(_RgbTex, half2(color.g, ycoords.y)).rgb * half3(0,1,0);
half3 blue = tex2D(_RgbTex, half2(color.b, ycoords.z)).rgb * half3(0,0,1);
half theDepth = SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, i.uv2) ;
half zval = tex2D(_ZCurve, half2( Linear01Depth (theDepth), 0.5));
half3 depthRed = tex2D(_RgbDepthTex, half2(color.r, ycoords.x)).rgb * half3(1,0,0);
half3 depthGreen = tex2D(_RgbDepthTex, half2(color.g, ycoords.y)).rgb * half3(0,1,0);
half3 depthBlue = tex2D(_RgbDepthTex, half2(color.b, ycoords.z)).rgb * half3(0,0,1);
color = half4( lerp(red+green+blue, depthRed+depthBlue+depthGreen, zval), color.a);
half lum = Luminance(color.rgb);
color.rgb = lerp(half3(lum,lum,lum), color.rgb, _Saturation);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 62bcade1028c24ca1a39760ed84b9487
ShaderImporter:
userData:
Shader "Hidden/ColorCorrectionCurvesSimple" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_RgbTex ("_RgbTex (RGB)", 2D) = "" {}
}
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _RgbTex;
fixed _Saturation;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
fixed3 red = tex2D(_RgbTex, half2(color.r, 0.5/4.0)).rgb * fixed3(1,0,0);
fixed3 green = tex2D(_RgbTex, half2(color.g, 1.5/4.0)).rgb * fixed3(0,1,0);
fixed3 blue = tex2D(_RgbTex, half2(color.b, 2.5/4.0)).rgb * fixed3(0,0,1);
color = fixed4(red+green+blue, color.a);
fixed lum = Luminance(color.rgb);
color.rgb = lerp(fixed3(lum,lum,lum), color.rgb, _Saturation);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 438ddd58d82c84d9eb1fdc56111702e1
ShaderImporter:
userData:
Shader "Hidden/Color Correction Effect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_RampTex ("Base (RGB)", 2D) = "grayscaleRamp" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _RampTex;
fixed4 frag (v2f_img i) : SV_Target
{
fixed4 orig = tex2D(_MainTex, i.uv);
fixed rr = tex2D(_RampTex, orig.rr).r;
fixed gg = tex2D(_RampTex, orig.gg).g;
fixed bb = tex2D(_RampTex, orig.bb).b;
fixed4 color = fixed4(rr, gg, bb, orig.a);
return color;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 67f8781cad112c75d0008dfa8d76c639
ShaderImporter:
userData:
Shader "Hidden/ColorCorrectionSelective" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 selColor;
float4 targetColor;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
fixed4 frag(v2f i) : SV_Target {
fixed4 color = tex2D (_MainTex, i.uv);
fixed diff = saturate (2.0 * length (color.rgb - selColor.rgb));
color = lerp (targetColor, color, diff);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: e515e0f94cefc4c0db54b45cba621544
ShaderImporter:
userData:
fileFormatVersion: 2
guid: a40c1b84cf7fe418bae97a29041b85a4
folderAsset: yes
timeCreated: 1433531211
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
// Calculates adaptation to minimum/maximum luminance values,
// based on "currently adapted" and "new values to adapt to"
// textures (both 1x1).
Shader "Hidden/Contrast Stretch Adaptation" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_CurTex ("Base (RGB)", 2D) = "white" {}
}
Category {
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex; // currently adapted to
uniform sampler2D _CurTex; // new value to adapt to
uniform float4 _AdaptParams; // x=adaptLerp, y=limitMinimum, z=limitMaximum
float4 frag (v2f_img i) : SV_Target {
// value is: max, min
float2 valAdapted = tex2D(_MainTex, i.uv).xy;
float2 valCur = tex2D(_CurTex, i.uv).xy;
// Calculate new adapted values: interpolate
// from valAdapted to valCur by script-supplied amount.
//
// Because we store adaptation levels in a simple 8 bit/channel
// texture, we might not have enough precision - the interpolation
// amount might be too small to change anything, and we'll never
// arrive at the needed values.
//
// So we make sure the change we do is at least 1/255th of the
// color range - this way we'll always change the value.
const float kMinChange = 1.0/255.0;
float2 delta = (valCur-valAdapted) * _AdaptParams.x;
delta.x = sign(delta.x) * max( kMinChange, abs(delta.x) );
delta.y = sign(delta.y) * max( kMinChange, abs(delta.y) );
float4 valNew;
valNew.xy = valAdapted + delta;
// Impose user limits on maximum/minimum values
valNew.x = max( valNew.x, _AdaptParams.z );
valNew.y = min( valNew.y, _AdaptParams.y );
// Optimization so that our final apply pass is faster:
// z = max-min (plus a small amount to prevent division by zero)
valNew.z = valNew.x - valNew.y + 0.01;
// w = min/(max-min)
valNew.w = valNew.y / valNew.z;
return valNew;
}
ENDCG
}
}
}
Fallback off
}
fileFormatVersion: 2
guid: 257bc83cbeb544540bd0e558aa9b1383
ShaderImporter:
userData:
// Final pass in the contrast stretch effect: apply
// color stretch to the original image, based on currently
// adapted to minimum/maximum luminances.
Shader "Hidden/Contrast Stretch Apply" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AdaptTex ("Base (RGB)", 2D) = "white" {}
}
Category {
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
uniform sampler2D _MainTex;
uniform sampler2D _AdaptTex;
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
o.uv[1] = float2(0.5,0.5);
return o;
}
float4 frag (v2f i) : SV_Target
{
float4 col = tex2D(_MainTex, i.uv[0]);
float4 adapted = tex2D(_AdaptTex, i.uv[1]);
float vmul = 1.0 / adapted.z;
float vadd = -adapted.w;
col.rgb = col.rgb * vmul + vadd;
return col;
}
ENDCG
}
}
}
Fallback off
}
fileFormatVersion: 2
guid: f4901f25d4e1542589348bbb89563d8e
ShaderImporter:
userData:
// Outputs luminance (grayscale) of the input image _MainTex
Shader "Hidden/Contrast Stretch Luminance" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
Category {
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
float4 frag (v2f_img i) : SV_Target
{
float4 col = tex2D(_MainTex, i.uv);
col.rgb = Luminance(col.rgb) * (1+col.a*2);
return col;
}
ENDCG
}
}
}
Fallback off
}
fileFormatVersion: 2
guid: befbb4b9c320b4b18a08ef7afb93b6c9
ShaderImporter:
userData:
// Reduces input image (_MainTex) by 2x2.
// Outputs maximum value in R, minimum in G.
Shader "Hidden/Contrast Stretch Reduction" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
Category {
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 position : SV_POSITION;
float2 uv[4] : TEXCOORD0;
};
uniform sampler2D _MainTex;
v2f vert (appdata_img v) {
v2f o;
o.position = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
// Compute UVs to sample 2x2 pixel block.
o.uv[0] = uv + float2(0,0);
o.uv[1] = uv + float2(0,1);
o.uv[2] = uv + float2(1,0);
o.uv[3] = uv + float2(1,1);
return o;
}
float4 frag (v2f i) : SV_Target
{
// Sample pixel block
float4 v00 = tex2D(_MainTex, i.uv[0]);
float2 v01 = tex2D(_MainTex, i.uv[1]).xy;
float2 v10 = tex2D(_MainTex, i.uv[2]).xy;
float2 v11 = tex2D(_MainTex, i.uv[3]).xy;
float4 res;
// output x: maximum of the four values
res.x = max( max(v00.x,v01.x), max(v10.x,v11.x) );
// output y: minimum of the four values
res.y = min( min(v00.y,v01.y), min(v10.y,v11.y) );
// output zw unchanged from the first pixel
res.zw = v00.zw;
return res;
}
ENDCG
}
}
}
Fallback off
}
fileFormatVersion: 2
guid: 57b33a14b6d5347c5a85c36f6cb3b280
ShaderImporter:
userData:
Shader "Hidden/ContrastComposite" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_MainTexBlurred ("Base Blurred (RGB)", 2D) = "" {}
}
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _MainTexBlurred;
float4 _MainTex_TexelSize;
float intensity;
float threshhold;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv[0].y = 1-o.uv[0].y;
#endif
return o;
}
half4 frag(v2f i) : SV_Target
{
half4 color = tex2D (_MainTex, i.uv[1]);
half4 blurred = tex2D (_MainTexBlurred, (i.uv[0]));
half4 difff = color - blurred;
half4 signs = sign (difff);
difff = saturate ( (color-blurred) - threshhold) * signs * 1.0/(1.0-threshhold);
color += difff * intensity;
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 273404942eede4ea1883ca1fb2942507
ShaderImporter:
userData:
Shader "Hidden/ConvertDepth" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag(v2f i) : SV_Target
{
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
d = Linear01Depth(d);
if(d>0.99999)
return half4(1,1,1,1);
else
return EncodeFloatRGBA(d);
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 14768d3865b1342e3a861fbe19ba2db2
ShaderImporter:
userData:
Shader "Hidden/CreaseApply" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_HrDepthTex ("Base (RGB)", 2D) = "white" {}
_LrDepthTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _HrDepthTex;
sampler2D _LrDepthTex;
uniform float4 _MainTex_TexelSize;
uniform float intensity;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
return o;
}
half4 frag (v2f i) : SV_Target
{
float4 hrDepth = tex2D(_HrDepthTex, i.uv);
float4 lrDepth = tex2D(_LrDepthTex, i.uv);
hrDepth.a = DecodeFloatRGBA(hrDepth);
lrDepth.a = DecodeFloatRGBA(lrDepth);
float4 color = tex2D(_MainTex, i.uv);
return color * (1.0-abs(hrDepth.a-lrDepth.a)*intensity);
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: b59984d82af624bd3b0c777f038276f2
ShaderImporter:
userData:
Shader "Hidden/EdgeDetect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[5] : TEXCOORD0;
};
struct v2fd {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
sampler2D _CameraDepthNormalsTexture;
sampler2D_float _CameraDepthTexture;
uniform half4 _Sensitivity;
uniform half4 _BgColor;
uniform half _BgFade;
uniform half _SampleDistance;
uniform float _Exponent;
uniform float _Threshold;
struct v2flum {
float4 pos : SV_POSITION;
float2 uv[3] : TEXCOORD0;
};
v2flum vertLum (appdata_img v)
{
v2flum o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
o.uv[0] = uv;
o.uv[1] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
o.uv[2] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
return o;
}
fixed4 fragLum (v2flum i) : SV_Target
{
fixed4 original = tex2D(_MainTex, i.uv[0]);
// a very simple cross gradient filter
half3 p1 = original.rgb;
half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;
half3 diff = p1 * 2 - p2 - p3;
half len = dot(diff, diff);
len = step(len, _Threshold);
//if(len >= _Threshold)
// original.rgb = 0;
return len * lerp(original, _BgColor, _BgFade);
}
inline half CheckSame (half2 centerNormal, float centerDepth, half4 theSample)
{
// difference in normals
// do not bother decoding normals - there's no need here
half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
half isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
// difference in depth
float sampleDepth = DecodeFloatRG (theSample.zw);
float zdiff = abs(centerDepth-sampleDepth);
// scale the required threshold by the distance
half isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;
// return:
// 1 - if normals and depth are similar enough
// 0 - otherwise
return isSameNormal * isSameDepth;
}
v2f vertRobert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
o.uv[0] = uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1-uv.y;
#endif
// calc coord for the X pattern
// maybe nicer TODO for the future: 'rotated triangles'
o.uv[1] = uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance;
o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance;
o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance;
o.uv[4] = uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance;
return o;
}
v2f vertThin( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
o.uv[0] = uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1-uv.y;
#endif
o.uv[1] = uv;
o.uv[4] = uv;
// offsets for two additional samples
o.uv[2] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
o.uv[3] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
return o;
}
v2fd vertD( appdata_img v )
{
v2fd o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
o.uv[0] = uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1-uv.y;
#endif
o.uv[1] = uv;
return o;
}
float4 fragDCheap(v2fd i) : SV_Target
{
// inspired by borderlands implementation of popular "sobel filter"
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
float4 depthsDiag;
float4 depthsAxis;
float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
depthsDiag -= centerDepth;
depthsAxis /= centerDepth;
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
const float4 VertDiagCoeff = float4(-1,1,-1,1);
const float4 HorizAxisCoeff = float4(1,0,0,-1);
const float4 VertAxisCoeff = float4(0,1,-1,0);
float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
float SobelX = dot(SobelH, float4(1,1,1,1));
float SobelY = dot(SobelV, float4(1,1,1,1));
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
Sobel = 1.0-pow(saturate(Sobel), _Exponent);
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
}
// pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
// which makes it compatible with other depth based post fx
float4 fragD(v2fd i) : SV_Target
{
// inspired by borderlands implementation of popular "sobel filter"
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
float4 depthsDiag;
float4 depthsAxis;
float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
// make it work nicely with depth based image effects such as depth of field:
depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;
depthsDiag -= centerDepth;
depthsAxis /= centerDepth;
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
const float4 VertDiagCoeff = float4(-1,1,-1,1);
const float4 HorizAxisCoeff = float4(1,0,0,-1);
const float4 VertAxisCoeff = float4(0,1,-1,0);
float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
float SobelX = dot(SobelH, float4(1,1,1,1));
float SobelY = dot(SobelV, float4(1,1,1,1));
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
Sobel = 1.0-pow(saturate(Sobel), _Exponent);
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
}
half4 fragRobert(v2f i) : SV_Target {
half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);
half edge = 1.0;
edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
}
half4 fragThin (v2f i) : SV_Target
{
half4 original = tex2D(_MainTex, i.uv[0]);
half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
// encoded normal
half2 centerNormal = center.xy;
// decoded depth
float centerDepth = DecodeFloatRG (center.zw);
half edge = 1.0;
edge *= CheckSame(centerNormal, centerDepth, sample1);
edge *= CheckSame(centerNormal, centerDepth, sample2);
return edge * lerp(original, _BgColor, _BgFade);
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertThin
#pragma fragment fragThin
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertRobert
#pragma fragment fragRobert
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertD
#pragma fragment fragDCheap
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertD
#pragma fragment fragD
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertLum
#pragma fragment fragLum
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 0d1644bdf064147baa97f235fc5b4903
ShaderImporter:
userData:
Shader "Hidden/FisheyeShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float2 intensity;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag(v2f i) : SV_Target
{
half2 coords = i.uv;
coords = (coords - 0.5) * 2.0;
half2 realCoordOffs;
realCoordOffs.x = (1-coords.y * coords.y) * intensity.y * (coords.x);
realCoordOffs.y = (1-coords.x * coords.x) * intensity.x * (coords.y);
half4 color = tex2D (_MainTex, i.uv - realCoordOffs);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 874ceab4425f64bccb1d14032f4452b1
ShaderImporter:
userData:
Shader "Hidden/GlobalFog" {
Properties {
_MainTex ("Base (RGB)", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D_float _CameraDepthTexture;
// x = fog height
// y = FdotC (CameraY-FogHeight)
// z = k (FdotC > 0.0)
// w = a/2
uniform float4 _HeightParams;
// x = start distance
uniform float4 _DistanceParams;
int4 _SceneFogMode; // x = fog mode, y = use radial flag
float4 _SceneFogParams;
#ifndef UNITY_APPLY_FOG
half4 unity_FogColor;
half4 unity_FogDensity;
#endif
uniform float4 _MainTex_TexelSize;
// for fast world space reconstruction
uniform float4x4 _FrustumCornersWS;
uniform float4 _CameraWS;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv_depth : TEXCOORD1;
float4 interpolatedRay : TEXCOORD2;
};
v2f vert (appdata_img v)
{
v2f o;
half index = v.vertex.z;
v.vertex.z = 0.1;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv_depth = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y = 1-o.uv.y;
#endif
o.interpolatedRay = _FrustumCornersWS[(int)index];
o.interpolatedRay.w = index;
return o;
}
// Applies one of standard fog formulas, given fog coordinate (i.e. distance)
half ComputeFogFactor (float coord)
{
float fogFac = 0.0;
if (_SceneFogMode.x == 1) // linear
{
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
fogFac = coord * _SceneFogParams.z + _SceneFogParams.w;
}
if (_SceneFogMode.x == 2) // exp
{
// factor = exp(-density*z)
fogFac = _SceneFogParams.y * coord; fogFac = exp2(-fogFac);
}
if (_SceneFogMode.x == 3) // exp2
{
// factor = exp(-(density*z)^2)
fogFac = _SceneFogParams.x * coord; fogFac = exp2(-fogFac*fogFac);
}
return saturate(fogFac);
}
// Distance-based fog
float ComputeDistance (float3 camDir, float zdepth)
{
float dist;
if (_SceneFogMode.y == 1)
dist = length(camDir);
else
dist = zdepth * _ProjectionParams.z;
// Built-in fog starts at near plane, so match that by
// subtracting the near value. Not a perfect approximation
// if near plane is very large, but good enough.
dist -= _ProjectionParams.y;
return dist;
}
// Linear half-space fog, from https://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf
float ComputeHalfSpace (float3 wsDir)
{
float3 wpos = _CameraWS + wsDir;
float FH = _HeightParams.x;
float3 C = _CameraWS;
float3 V = wsDir;
float3 P = wpos;
float3 aV = _HeightParams.w * V;
float FdotC = _HeightParams.y;
float k = _HeightParams.z;
float FdotP = P.y-FH;
float FdotV = wsDir.y;
float c1 = k * (FdotP + FdotC);
float c2 = (1-2*k) * FdotP;
float g = min(c2, 0.0);
g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
return g;
}
half4 ComputeFog (v2f i, bool distance, bool height) : SV_Target
{
half4 sceneColor = tex2D(_MainTex, i.uv);
// Reconstruct world space position & direction
// towards this screen pixel.
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
float dpth = Linear01Depth(rawDepth);
float4 wsDir = dpth * i.interpolatedRay;
float4 wsPos = _CameraWS + wsDir;
// Compute fog distance
float g = _DistanceParams.x;
if (distance)
g += ComputeDistance (wsDir, dpth);
if (height)
g += ComputeHalfSpace (wsDir);
// Compute fog amount
half fogFac = ComputeFogFactor (max(0.0,g));
// Do not fog skybox
if (rawDepth >= 0.999999)
fogFac = 1.0;
//return fogFac; // for debugging
// Lerp between fog color & original scene color
// by fog amount
return lerp (unity_FogColor, sceneColor, fogFac);
}
ENDCG
SubShader
{
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
// 0: distance + height
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, true); }
ENDCG
}
// 1: distance
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, false); }
ENDCG
}
// 2: height
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag (v2f i) : SV_Target { return ComputeFog (i, false, true); }
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 70d8568987ac0499f952b54c7c13e265
ShaderImporter:
userData:
Shader "Hidden/Grayscale Effect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_RampTex ("Base (RGB)", 2D) = "grayscaleRamp" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _RampTex;
uniform half _RampOffset;
fixed4 frag (v2f_img i) : SV_Target
{
fixed4 original = tex2D(_MainTex, i.uv);
fixed grayscale = Luminance(original.rgb);
half2 remap = half2 (grayscale + _RampOffset, .5);
fixed4 output = tex2D(_RampTex, remap);
output.a = original.a;
return output;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: daf9781cad112c75d0008dfa8d76c639
ShaderImporter:
userData:
Shader "Hidden/MotionBlur" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AccumOrig("AccumOrig", Float) = 0.65
}
SubShader {
ZTest Always Cull Off ZWrite Off
Pass {
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
BindChannels {
Bind "vertex", vertex
Bind "texcoord", texcoord
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD;
};
float4 _MainTex_ST;
float _AccumOrig;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
sampler2D _MainTex;
half4 frag (v2f i) : SV_Target
{
return half4(tex2D(_MainTex, i.texcoord).rgb, _AccumOrig );
}
ENDCG
}
Pass {
Blend One Zero
ColorMask A
BindChannels {
Bind "vertex", vertex
Bind "texcoord", texcoord
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD;
};
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
sampler2D _MainTex;
half4 frag (v2f i) : SV_Target
{
return tex2D(_MainTex, i.texcoord);
}
ENDCG
}
}
SubShader {
ZTest Always Cull Off ZWrite Off
Pass {
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
SetTexture [_MainTex] {
ConstantColor (0,0,0,[_AccumOrig])
Combine texture, constant
}
}
Pass {
Blend One Zero
ColorMask A
SetTexture [_MainTex] {
Combine texture
}
}
}
Fallback off
}
fileFormatVersion: 2
guid: e9ba2083ad114a07d000fbfb8d76c639
ShaderImporter:
userData:
Shader "Hidden/MotionBlurClear"
{
Properties { }
SubShader {
Pass {
//ZTest LEqual
ZTest Always // lame depth test
ZWrite Off // lame depth test
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vs_input {
float4 vertex : POSITION;
};
struct ps_input {
float4 pos : SV_POSITION;
float4 screen : TEXCOORD0;
};
sampler2D_float _CameraDepthTexture;
ps_input vert (vs_input v)
{
ps_input o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.screen = ComputeScreenPos(o.pos);
COMPUTE_EYEDEPTH(o.screen.z);
return o;
}
float4 frag (ps_input i) : SV_Target
{
// superlame: manual depth test needed as we can't bind depth, FIXME for 4.x
// alternatively implement SM > 3 version where we write out custom depth
float d = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screen));
d = LinearEyeDepth(d);
clip(d - i.screen.z + 1e-2f);
return float4(0, 0, 0, 0);
}
ENDCG
}
}
Fallback Off
}
fileFormatVersion: 2
guid: 7699c5fbfa27745a1abe111ab7bf9785
ShaderImporter:
userData:
Shader "Hidden/NoiseAndGrain" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_NoiseTex ("Noise (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _NoiseTex;
float4 _NoiseTex_TexelSize;
uniform float4 _MainTex_TexelSize;
uniform float3 _NoisePerChannel;
uniform float3 _NoiseTilingPerChannel;
uniform float3 _NoiseAmount;
uniform float3 _ThreshholdRGB;
uniform float3 _MidGrey;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv_screen : TEXCOORD0;
float4 uvRg : TEXCOORD1;
float2 uvB : TEXCOORD2;
};
struct appdata_img2
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
inline float3 Overlay(float3 m, float3 color) {
color = saturate(color);
float3 check = step(float3(0.5,0.5,0.5), color.rgb);
float3 result = check * (float3(1,1,1) - ((float3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
result += (1-check) * (2*color.rgb) * m.rgb;
return result;
}
v2f vert (appdata_img2 v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
#if UNITY_UV_STARTS_AT_TOP
o.uv_screen = v.vertex.xyxy;
if (_MainTex_TexelSize.y < 0)
o.uv_screen.y = 1-o.uv_screen.y;
#else
o.uv_screen = v.vertex.xy;
#endif
// different tiling for 3 channels
o.uvRg = v.texcoord.xyxy + v.texcoord1.xyxy * _NoiseTilingPerChannel.rrgg * _NoiseTex_TexelSize.xyxy;
o.uvB = v.texcoord.xy + v.texcoord1.xy * _NoiseTilingPerChannel.bb * _NoiseTex_TexelSize.xy;
return o;
}
float4 frag ( v2f i ) : SV_Target
{
float4 color = (tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
// fetching & scaling noise (COMPILER BUG WORKAROUND)
float3 m = float3(0,0,0);
m += (tex2D(_NoiseTex, i.uvRg.xy) * float4(1,0,0,0)).rgb;
m += (tex2D(_NoiseTex, i.uvRg.zw) * float4(0,1,0,0)).rgb;
m += (tex2D(_NoiseTex, i.uvB.xy) * float4(0,0,1,0)).rgb;
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * float3(finalIntensity,finalIntensity,finalIntensity) ));
return float4(Overlay(m, color.rgb), color.a);
}
float4 fragTmp ( v2f i ) : SV_Target
{
float4 color = (tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
// fetching & scaling noise (COMPILER BUG WORKAROUND)
float3 m = float3(0,0,0);
m += (tex2D(_NoiseTex, i.uvRg.xy) * float4(1,0,0,0)).rgb;
m += (tex2D(_NoiseTex, i.uvRg.zw) * float4(0,1,0,0)).rgb;
m += (tex2D(_NoiseTex, i.uvB.xy) * float4(0,0,1,0)).rgb;
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * float3(finalIntensity,finalIntensity,finalIntensity)));
return float4(m.rgb, color.a);
}
float4 fragOverlayBlend ( v2f i ) : SV_Target
{
float4 color = tex2D(_MainTex, i.uv_screen.xy);
float4 m = tex2D(_NoiseTex, i.uv_screen.xy);
return float4(Overlay(m, color.rgb), color.a);
}
ENDCG
SubShader {
ZTest Always Cull Off ZWrite Off Blend Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragOverlayBlend
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragTmp
ENDCG
}
}
FallBack Off
}
fileFormatVersion: 2
guid: b0249d8c935344451aa4de6db76f0688
ShaderImporter:
userData:
Shader "Hidden/NoiseAndGrainDX11" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_NoiseTex ("Noise (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _NoiseTex;
float4 _NoiseTex_TexelSize;
uniform float4 _MainTex_TexelSize;
uniform float3 _NoisePerChannel;
uniform float3 _NoiseTilingPerChannel;
uniform float3 _NoiseAmount;
uniform float3 _ThreshholdRGB;
uniform float3 _MidGrey;
uniform float _DX11NoiseTime;
// DX11 noise helper functions, credit: rgba/iq
int ihash(int n)
{
n = (n<<13)^n;
return (n*(n*n*15731+789221)+1376312589) & 2147483647;
}
float frand(int n)
{
return ihash(n) / 2147483647.0;
}
float cellNoise1f(int3 p)
{
return frand(p.z*65536 + p.y*256 + p.x);//*2.0-1.0;
}
float3 cellNoise3f(int3 p)
{
int i = p.z*65536 + p.y*256 + p.x;
return float3(frand(i), frand(i + 57), frand(i + 113));//*2.0-1.0;
}
struct v2f
{
float4 pos : SV_POSITION;
float2 uv_screen : TEXCOORD0;
float4 uvRg : TEXCOORD1;
float2 uvB : TEXCOORD2;
float2 uvOffsets : TEXCOORD4;
};
struct appdata_img2
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
inline float3 Overlay(float3 m, float3 color) {
float3 check = step(0.5, color.rgb);
float3 result = check * (float3(1,1,1) - ((float3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
result += (1-check) * (2*color.rgb) * m.rgb;
return result;
}
v2f vert (appdata_img2 v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
#if UNITY_UV_STARTS_AT_TOP
o.uv_screen = v.vertex.xyxy;
if (_MainTex_TexelSize.y < 0)
o.uv_screen.y = 1-o.uv_screen.y;
#else
o.uv_screen = v.vertex.xy;
#endif
// different tiling for 3 channels
o.uvRg = v.texcoord.xyxy + v.texcoord1.xyxy * _NoiseTilingPerChannel.rrgg * _NoiseTex_TexelSize.xyxy;
o.uvB = v.texcoord.xy + v.texcoord1.xy * _NoiseTilingPerChannel.bb * _NoiseTex_TexelSize.xy;
o.uvOffsets = v.texcoord.xy;
return o;
}
float4 fragDX11 ( v2f i ) : SV_Target
{
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
float3 m = cellNoise3f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * finalIntensity));
return float4(Overlay(m, color.rgb), color.a);
}
float4 fragDX11Monochrome ( v2f i ) : SV_Target
{
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
float3 m = cellNoise1f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
m = saturate(lerp(float3(0.5,0.5,0.5), m, finalIntensity));
return float4(Overlay(m, color.rgb), color.a);
}
float4 fragDX11Tmp ( v2f i ) : SV_Target
{
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
float3 m = cellNoise3f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * finalIntensity));
return float4(m.rgb, color.a);
}
float4 fragDX11MonochromeTmp ( v2f i ) : SV_Target
{
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
// black & white intensities
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
float3 m = cellNoise1f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
m = saturate(lerp(float3(0.5,0.5,0.5), m, finalIntensity));
return float4(m.rgb, color.a);
}
float4 fragOverlayBlend ( v2f i ) : SV_Target
{
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
float4 m = saturate(tex2D (_NoiseTex, i.uv_screen.xy));
return float4(Overlay(m, color.rgb), color.a);
}
ENDCG
SubShader {
ZTest Always Cull Off ZWrite Off Blend Off
Pass {
CGPROGRAM
#pragma exclude_renderers gles xbox360 ps3 d3d9
#pragma target 5.0
#pragma vertex vert
#pragma fragment fragDX11
ENDCG
}
Pass {
CGPROGRAM
#pragma exclude_renderers gles xbox360 ps3 d3d9
#pragma target 5.0
#pragma vertex vert
#pragma fragment fragDX11Monochrome
ENDCG
}
Pass {
CGPROGRAM
#pragma exclude_renderers gles xbox360 ps3 d3d9
#pragma target 5.0
#pragma vertex vert
#pragma fragment fragDX11Tmp
ENDCG
}
Pass {
CGPROGRAM
#pragma exclude_renderers gles xbox360 ps3 d3d9
#pragma target 5.0
#pragma vertex vert
#pragma fragment fragDX11MonochromeTmp
ENDCG
}
Pass {
CGPROGRAM
#pragma exclude_renderers gles xbox360 ps3 d3d9
#pragma target 5.0
#pragma vertex vert
#pragma fragment fragOverlayBlend
ENDCG
}
}
FallBack Off
}
fileFormatVersion: 2
guid: 8b30686bb4322ab42ad5eb50a0210b58
ShaderImporter:
userData:
Shader "Hidden/Noise Shader RGB" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_GrainTex ("Base (RGB)", 2D) = "gray" {}
_ScratchTex ("Base (RGB)", 2D) = "gray" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvg : TEXCOORD1; // grain
float2 uvs : TEXCOORD2; // scratch
};
uniform sampler2D _MainTex;
uniform sampler2D _GrainTex;
uniform sampler2D _ScratchTex;
uniform float4 _GrainOffsetScale;
uniform float4 _ScratchOffsetScale;
uniform fixed4 _Intensity; // x=grain, y=scratch
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
o.uvg = v.texcoord.xy * _GrainOffsetScale.zw + _GrainOffsetScale.xy;
o.uvs = v.texcoord.xy * _ScratchOffsetScale.zw + _ScratchOffsetScale.xy;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// sample noise texture and do a signed add
fixed3 grain = tex2D(_GrainTex, i.uvg).rgb * 2 - 1;
col.rgb += grain * _Intensity.x;
// sample scratch texture and do a signed add
fixed3 scratch = tex2D(_ScratchTex, i.uvs).rgb * 2 - 1;
col.rgb += scratch * _Intensity.y;
return col;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 5d7f4c401ae8946bcb0d6ff68a9e7466
ShaderImporter:
userData:
Shader "Hidden/Noise Shader YUV" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_GrainTex ("Base (RGB)", 2D) = "gray" {}
_ScratchTex ("Base (RGB)", 2D) = "gray" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvg : TEXCOORD1; // grain
float2 uvs : TEXCOORD2; // scratch
};
uniform sampler2D _MainTex;
uniform sampler2D _GrainTex;
uniform sampler2D _ScratchTex;
uniform float4 _GrainOffsetScale;
uniform float4 _ScratchOffsetScale;
uniform fixed4 _Intensity; // x=grain, y=scratch
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
o.uvg = v.texcoord.xy * _GrainOffsetScale.zw + _GrainOffsetScale.xy;
o.uvs = v.texcoord.xy * _ScratchOffsetScale.zw + _ScratchOffsetScale.xy;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// convert to YUV
fixed3 yuv;
yuv.x = dot( col.rgb, half3(0.299,0.587,0.114) );
yuv.y = (col.b-yuv.x)*0.492;
yuv.z = (col.r-yuv.x)*0.877;
// sample noise texture and do a signed add
fixed3 grain = tex2D(_GrainTex, i.uvg).rgb * 2 - 1;
yuv.rgb += grain * _Intensity.x;
// convert back to rgb
col.r = yuv.z * 1.140 + yuv.x;
col.g = yuv.z * (-0.581) + yuv.y * (-0.395) + yuv.x;
col.b = yuv.y * 2.032 + yuv.x;
// sample scratch texture and add
fixed3 scratch = tex2D(_ScratchTex, i.uvs).rgb * 2 - 1;
col.rgb += scratch * _Intensity.y;
return col;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 0e447868506ba49f0a73235b8a8b647a
ShaderImporter:
userData:
Shader "Hidden/PrepareSunShaftsBlur" {
Properties {
_MainTex ("Base", 2D) = "" {}
_Skybox ("Skybox", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _Skybox;
sampler2D_float _CameraDepthTexture;
uniform half _NoSkyBoxMask;
uniform half4 _SunPosition;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half TransformColor (half4 skyboxValue) {
return max (skyboxValue.a, _NoSkyBoxMask * dot (skyboxValue.rgb, float3 (0.59,0.3,0.11)));
}
half4 frag (v2f i) : SV_Target {
float depthSample = SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, i.uv.xy);
half4 tex = tex2D (_MainTex, i.uv.xy);
depthSample = Linear01Depth (depthSample);
// consider maximum radius
half2 vec = _SunPosition.xy - i.uv.xy;
half dist = saturate (_SunPosition.w - length (vec.xy));
half4 outColor = 0;
// consider shafts blockers
if (depthSample > 0.99)
outColor = TransformColor (tex) * dist;
return outColor;
}
half4 fragNoDepthNeeded (v2f i) : SV_Target {
float4 sky = (tex2D (_Skybox, i.uv.xy));
float4 tex = (tex2D (_MainTex, i.uv.xy));
// consider maximum radius
half2 vec = _SunPosition.xy - i.uv.xy;
half dist = saturate (_SunPosition.w - length (vec));
half4 outColor = 0;
if (Luminance ( abs(sky.rgb - tex.rgb)) < 0.2)
outColor = TransformColor (sky) * dist;
return outColor;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragNoDepthNeeded
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 9ad381ed8492840ab9f165df743e4826
ShaderImporter:
userData:
Shader "Hidden/RadialBlur"
{
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
// Shader code pasted into all further CGPROGRAM blocks
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 blurVector : TEXCOORD1;
};
sampler2D _MainTex;
float4 _BlurRadius4;
float4 _SunPosition;
float4 _MainTex_TexelSize;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.blurVector = (_SunPosition.xy - v.texcoord.xy) * _BlurRadius4.xy;
return o;
}
#define SAMPLES_FLOAT 6.0f
#define SAMPLES_INT 6
half4 frag(v2f i) : SV_Target
{
half4 color = half4(0,0,0,0);
for(int j = 0; j < SAMPLES_INT; j++)
{
half4 tmpColor = tex2D(_MainTex, i.uv.xy);
color += tmpColor;
i.uv.xy += i.blurVector;
}
return color / SAMPLES_FLOAT;
}
ENDCG
Subshader
{
Blend One Zero
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
} // Pass
} // Subshader
Fallback off
} // shader
fileFormatVersion: 2
guid: f58445347fe2e4b8396487ed2bfa02ad
ShaderImporter:
userData:
Shader "Hidden/SSAO" {
Properties {
_MainTex ("", 2D) = "" {}
_RandomTexture ("", 2D) = "" {}
_SSAO ("", 2D) = "" {}
}
Subshader {
ZTest Always Cull Off ZWrite Off
CGINCLUDE
// Common code used by several SSAO passes below
#include "UnityCG.cginc"
struct v2f_ao {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvr : TEXCOORD1;
};
uniform float2 _NoiseScale;
float4 _CameraDepthNormalsTexture_ST;
v2f_ao vert_ao (appdata_img v)
{
v2f_ao o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _CameraDepthNormalsTexture);
o.uvr = v.texcoord.xy * _NoiseScale;
return o;
}
sampler2D _CameraDepthNormalsTexture;
sampler2D _RandomTexture;
float4 _Params; // x=radius, y=minz, z=attenuation power, w=SSAO power
// HLSL and GLSL do not support arbitrarily sized arrays as function parameters (eg. float bla[]), whereas Cg does.
#if !defined(UNITY_COMPILER_CG)
# define INPUT_SAMPLE_COUNT 8
# include "frag_ao.cginc"
# undef INPUT_SAMPLE_COUNT
# define INPUT_SAMPLE_COUNT 14
# include "frag_ao.cginc"
# undef INPUT_SAMPLE_COUNT
# define INPUT_SAMPLE_COUNT 26
# include "frag_ao.cginc"
# undef INPUT_SAMPLE_COUNT
# define INPUT_SAMPLE_COUNT 34
# include "frag_ao.cginc"
# undef INPUT_SAMPLE_COUNT
#else
# define INPUT_SAMPLE_COUNT
# include "frag_ao.cginc"
#endif
ENDCG
// ---- SSAO pass, 8 samples
Pass {
CGPROGRAM
#pragma vertex vert_ao
#pragma fragment frag
#pragma target 3.0
half4 frag (v2f_ao i) : SV_Target
{
#define SAMPLE_COUNT 8
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
float3(0.01305719,0.5872321,-0.119337),
float3(0.3230782,0.02207272,-0.4188725),
float3(-0.310725,-0.191367,0.05613686),
float3(-0.4796457,0.09398766,-0.5802653),
float3(0.1399992,-0.3357702,0.5596789),
float3(-0.2484578,0.2555322,0.3489439),
float3(0.1871898,-0.702764,-0.2317479),
float3(0.8849149,0.2842076,0.368524),
};
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
}
ENDCG
}
// ---- SSAO pass, 14 samples
Pass {
CGPROGRAM
#pragma vertex vert_ao
#pragma fragment frag
#pragma target 3.0
half4 frag (v2f_ao i) : SV_Target
{
#define SAMPLE_COUNT 14
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
float3(0.4010039,0.8899381,-0.01751772),
float3(0.1617837,0.1338552,-0.3530486),
float3(-0.2305296,-0.1900085,0.5025396),
float3(-0.6256684,0.1241661,0.1163932),
float3(0.3820786,-0.3241398,0.4112825),
float3(-0.08829653,0.1649759,0.1395879),
float3(0.1891677,-0.1283755,-0.09873557),
float3(0.1986142,0.1767239,0.4380491),
float3(-0.3294966,0.02684341,-0.4021836),
float3(-0.01956503,-0.3108062,-0.410663),
float3(-0.3215499,0.6832048,-0.3433446),
float3(0.7026125,0.1648249,0.02250625),
float3(0.03704464,-0.939131,0.1358765),
float3(-0.6984446,-0.6003422,-0.04016943),
};
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
}
ENDCG
}
// ---- SSAO pass, 26 samples
Pass {
CGPROGRAM
#pragma vertex vert_ao
#pragma fragment frag
#pragma target 3.0
half4 frag (v2f_ao i) : SV_Target
{
#define SAMPLE_COUNT 26
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
float3(0.2196607,0.9032637,0.2254677),
float3(0.05916681,0.2201506,-0.1430302),
float3(-0.4152246,0.1320857,0.7036734),
float3(-0.3790807,0.1454145,0.100605),
float3(0.3149606,-0.1294581,0.7044517),
float3(-0.1108412,0.2162839,0.1336278),
float3(0.658012,-0.4395972,-0.2919373),
float3(0.5377914,0.3112189,0.426864),
float3(-0.2752537,0.07625949,-0.1273409),
float3(-0.1915639,-0.4973421,-0.3129629),
float3(-0.2634767,0.5277923,-0.1107446),
float3(0.8242752,0.02434147,0.06049098),
float3(0.06262707,-0.2128643,-0.03671562),
float3(-0.1795662,-0.3543862,0.07924347),
float3(0.06039629,0.24629,0.4501176),
float3(-0.7786345,-0.3814852,-0.2391262),
float3(0.2792919,0.2487278,-0.05185341),
float3(0.1841383,0.1696993,-0.8936281),
float3(-0.3479781,0.4725766,-0.719685),
float3(-0.1365018,-0.2513416,0.470937),
float3(0.1280388,-0.563242,0.3419276),
float3(-0.4800232,-0.1899473,0.2398808),
float3(0.6389147,0.1191014,-0.5271206),
float3(0.1932822,-0.3692099,-0.6060588),
float3(-0.3465451,-0.1654651,-0.6746758),
float3(0.2448421,-0.1610962,0.1289366),
};
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
}
ENDCG
}
// ---- Blur pass
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
float4 _MainTex_ST;
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _CameraDepthNormalsTexture);
return o;
}
sampler2D _SSAO;
float3 _TexelOffsetScale;
inline half CheckSame (half4 n, half4 nn)
{
// difference in normals
half2 diff = abs(n.xy - nn.xy);
half sn = (diff.x + diff.y) < 0.1;
// difference in depth
float z = DecodeFloatRG (n.zw);
float zz = DecodeFloatRG (nn.zw);
float zdiff = abs(z-zz) * _ProjectionParams.z;
half sz = zdiff < 0.2;
return sn * sz;
}
half4 frag( v2f i ) : SV_Target
{
#define NUM_BLUR_SAMPLES 4
float2 o = _TexelOffsetScale.xy;
half sum = tex2D(_SSAO, i.uv).r * (NUM_BLUR_SAMPLES + 1);
half denom = NUM_BLUR_SAMPLES + 1;
half4 geom = tex2D (_CameraDepthNormalsTexture, i.uv);
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
{
float2 nuv = i.uv + o * (s+1);
half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
sum += tex2D (_SSAO, nuv.xy).r * coef;
denom += coef;
}
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
{
float2 nuv = i.uv - o * (s+1);
half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
sum += tex2D (_SSAO, nuv.xy).r * coef;
denom += coef;
}
return sum / denom;
}
ENDCG
}
// ---- Composite pass
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
o.uv[1] = MultiplyUV (UNITY_MATRIX_TEXTURE1, v.texcoord);
return o;
}
sampler2D _MainTex;
sampler2D _SSAO;
half4 frag( v2f i ) : SV_Target
{
half4 c = tex2D (_MainTex, i.uv[0]);
half ao = tex2D (_SSAO, i.uv[1]).r;
ao = pow (ao, _Params.w);
c.rgb *= ao;
return c;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 43ca18288c424f645aaa1e9e07f04c50
ShaderImporter:
userData:
// This Ambient Occlusion image effect is based on "Scalable Ambient Obscurance":
/**
\author Morgan McGuire and Michael Mara, NVIDIA and Williams College, http://research.nvidia.com, http://graphics.cs.williams.edu
Open Source under the "BSD" license: http://www.opensource.org/licenses/bsd-license.php
Copyright (c) 2011-2012, NVIDIA
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
Shader "Hidden/ScreenSpaceAmbientObscurance"
{
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
#ifdef SHADER_API_D3D11
#define NUM_SAMPLES (15)
#else
#define NUM_SAMPLES (11)
#endif
#define FAR_PLANE_Z (300.0)
#define NUM_SPIRAL_TURNS (7)
#define bias (0.01)
float _Radius;
float _Radius2; // _Radius * _Radius;
float _Intensity;
float4 _ProjInfo;
float4x4 _ProjectionInv; // ref only
sampler2D_float _CameraDepthTexture;
sampler2D _Rand;
sampler2D _AOTex;
sampler2D _MainTex;
float4 _MainTex_TexelSize;
static const float gaussian[5] = { 0.153170, 0.144893, 0.122649, 0.092902, 0.062970 }; // stddev = 2.0
float2 _Axis;
/** Increase to make edges crisper. Decrease to reduce temporal flicker. */
#define EDGE_SHARPNESS (1.0)
float _BlurFilterDistance;
#define SCALE _BlurFilterDistance
/** Filter _Radius in pixels. This will be multiplied by SCALE. */
#define R (4)
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv2 = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv2.y = 1-o.uv2.y;
#endif
return o;
}
float3 ReconstructCSPosition(float2 S, float z)
{
float linEyeZ = LinearEyeDepth(z);
return float3(( ( S.xy * _MainTex_TexelSize.zw) * _ProjInfo.xy + _ProjInfo.zw) * linEyeZ, linEyeZ);
/*
// for reference
float4 clipPos = float4(S*2.0-1.0, (z*2-1), 1);
float4 viewPos;
viewPos.x = dot((float4)_ProjectionInv[0], clipPos);
viewPos.y = dot((float4)_ProjectionInv[1], clipPos);
viewPos.w = dot((float4)_ProjectionInv[3], clipPos);
viewPos.z = z;
viewPos = viewPos/viewPos.w;
return viewPos.xyz;
*/
}
float3 ReconstructCSFaceNormal(float3 C) {
return normalize(cross(ddy(C), ddx(C)));
}
/** Returns a unit vector and a screen-space _Radius for the tap on a unit disk (the caller should scale by the actual disk _Radius) */
float2 TapLocation(int sampleNumber, float spinAngle, out float ssR){
// Radius relative to ssR
float alpha = float(sampleNumber + 0.5) * (1.0 / NUM_SAMPLES);
float angle = alpha * (NUM_SPIRAL_TURNS * 6.28) + spinAngle;
ssR = alpha;
return float2(cos(angle), sin(angle));
}
/** Used for packing Z into the GB channels */
float CSZToKey(float z) {
return saturate(z * (1.0 / FAR_PLANE_Z));
}
/** Used for packing Z into the GB channels */
void packKey(float key, out float2 p) {
// Round to the nearest 1/256.0
float temp = floor(key * 256.0);
// Integer part
p.x = temp * (1.0 / 256.0);
// Fractional part
p.y = key * 256.0 - temp;
}
/** Returns a number on (0, 1) */
float UnpackKey(float2 p)
{
return p.x * (256.0 / 257.0) + p.y * (1.0 / 257.0);
}
/** Read the camera-space position of the point at screen-space pixel ssP */
float3 GetPosition(float2 ssP) {
float3 P;
P.z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssP.xy);
// Offset to pixel center
P = ReconstructCSPosition(float2(ssP) /*+ float2(0.5, 0.5)*/, P.z);
return P;
}
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
float3 GetOffsetPosition(float2 ssC, float2 unitOffset, float ssR)
{
float2 ssP = saturate(float2(ssR*unitOffset) + ssC);
float3 P;
P.z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssP.xy);
// Offset to pixel center
P = ReconstructCSPosition(float2(ssP)/* + float2(0.5, 0.5)*/, P.z);
return P;
}
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling _Radius \a ssDiskRadius */
float SampleAO(in float2 ssC, in float3 C, in float3 n_C, in float ssDiskRadius, in int tapIndex, in float randomPatternRotationAngle)
{
// Offset on the unit disk, spun for this pixel
float ssR;
float2 unitOffset = TapLocation(tapIndex, randomPatternRotationAngle, ssR);
ssR *= ssDiskRadius;
// The occluding point in camera space
float3 Q = GetOffsetPosition(ssC, unitOffset, ssR);
float3 v = Q - C;
float vv = dot(v, v);
float vn = dot(v, n_C);
const float epsilon = 0.01;
float f = max(_Radius2 - vv, 0.0);
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
}
float4 fragAO(v2f i) : SV_Target
{
float4 fragment = fixed4(1,1,1,1);
// Pixel being shaded
float2 ssC = i.uv2.xy;// * _MainTex_TexelSize.zw;
// View space point being shaded
float3 C = GetPosition(ssC);
//return abs(float4(C.xyz,0));
//if(abs(C.z)<0.31)
// return 1;
//return abs(C.z);
packKey(CSZToKey(C.z), fragment.gb);
//packKey(CSZToKey(C.z), bilateralKey);
float randomPatternRotationAngle = 1.0;
#ifdef SHADER_API_D3D11
int2 ssCInt = ssC.xy * _MainTex_TexelSize.zw;
randomPatternRotationAngle = (3 * ssCInt.x ^ ssCInt.y + ssCInt.x * ssCInt.y) * 10;
#else
// TODO: make dx9 rand better
randomPatternRotationAngle = tex2D(_Rand, i.uv*12.0).x * 1000.0;
#endif
// Reconstruct normals from positions. These will lead to 1-pixel black lines
// at depth discontinuities, however the blur will wipe those out so they are not visible
// in the final image.
float3 n_C = ReconstructCSFaceNormal(C);
//return float4((n_C),0);
// Choose the screen-space sample _Radius
// proportional to the projected area of the sphere
float ssDiskRadius = -_Radius / C.z; // -projScale * _Radius / C.z; // <:::::
float sum = 0.0;
for (int l = 0; l < NUM_SAMPLES; ++l) {
sum += SampleAO(ssC, C, n_C, (ssDiskRadius), l, randomPatternRotationAngle);
}
float temp = _Radius2 * _Radius;
sum /= temp * temp;
float A = max(0.0, 1.0 - sum * _Intensity * (5.0 / NUM_SAMPLES));
fragment.ra = float2(A,A);
return fragment;
}
float4 fragUpsample (v2f i) : SV_Target
{
float4 fragment = fixed4(1,1,1,1);
// View space point being shaded
float3 C = GetPosition(i.uv.xy);
packKey(CSZToKey(C.z), fragment.gb);
fragment.ra = tex2D(_MainTex, i.uv.xy).ra;
return fragment;
}
float4 fragApply (v2f i) : SV_Target
{
float4 ao = tex2D(_AOTex, i.uv2.xy);
return tex2D(_MainTex, i.uv.xy) * ao.rrrr;
}
float4 fragApplySoft (v2f i) : SV_Target
{
float4 color = tex2D(_MainTex, i.uv.xy);
float ao = tex2D(_AOTex, i.uv2.xy).r;
ao += tex2D(_AOTex, i.uv2.xy + _MainTex_TexelSize.xy * 0.75).r;
ao += tex2D(_AOTex, i.uv2.xy - _MainTex_TexelSize.xy * 0.75).r;
ao += tex2D(_AOTex, i.uv2.xy + _MainTex_TexelSize.xy * float2(-0.75,0.75)).r;
ao += tex2D(_AOTex, i.uv2.xy - _MainTex_TexelSize.xy * float2(-0.75,0.75)).r;
return color * float4(ao,ao,ao,5)/5;
}
float4 fragBlurBL (v2f i) : SV_Target
{
float4 fragment = float4(1,1,1,1);
float2 ssC = i.uv.xy;
float4 temp = tex2Dlod(_MainTex, float4(i.uv.xy,0,0));
float2 passthrough2 = temp.gb;
float key = UnpackKey(passthrough2);
float sum = temp.r;
/*
if (key >= 0.999) {
// Sky pixel (if you aren't using depth keying, disable this test)
fragment.gb = passthrough2;
return fragment;
}
*/
// Base weight for depth falloff. Increase this for more blurriness, decrease it for better edge discrimination
float BASE = gaussian[0] * 0.5; // ole: i decreased
float totalWeight = BASE;
sum *= totalWeight;
for (int r = -R; r <= R; ++r) {
// We already handled the zero case above. This loop should be unrolled and the branch discarded
if (r != 0) {
temp = tex2Dlod(_MainTex, float4(ssC + _Axis * _MainTex_TexelSize.xy * (r * SCALE),0,0) );
float tapKey = UnpackKey(temp.gb);
float value = temp.r;
// spatial domain: offset gaussian tap
float weight = 0.3 + gaussian[abs(r)];
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
weight *= max(0.0, 1.0 - (2000.0 * EDGE_SHARPNESS) * abs(tapKey - key));
sum += value * weight;
totalWeight += weight;
}
}
const float epsilon = 0.0001;
fragment = sum / (totalWeight + epsilon);
fragment.gb = passthrough2;
return fragment;
}
ENDCG
SubShader {
// 0: get ao
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAO
#pragma target 3.0
ENDCG
}
// 1: bilateral blur
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragBlurBL
#pragma target 3.0
ENDCG
}
// 2: apply ao
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragApply
#pragma target 3.0
ENDCG
}
// 3: apply with a slight box filter
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragApplySoft
#pragma target 3.0
ENDCG
}
// 4: in case you want to blur in high rez for nicer z borders
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragUpsample
#pragma target 3.0
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 95616c020c5604dda96cf76afbbc0272
ShaderImporter:
userData:
Shader "Hidden/Sepiatone Effect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
fixed4 frag (v2f_img i) : SV_Target
{
fixed4 original = tex2D(_MainTex, i.uv);
// get intensity value (Y part of YIQ color space)
fixed Y = dot (fixed3(0.299, 0.587, 0.114), original.rgb);
// Convert to Sepia Tone by adding constant
fixed4 sepiaConvert = float4 (0.191, -0.054, -0.221, 0.0);
fixed4 output = sepiaConvert + Y;
output.a = original.a;
return output;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: b6aa781cad112c75d0008dfa8d76c639
ShaderImporter:
userData:
Shader "Hidden/ShowAlphaChannel" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_EdgeTex ("_EdgeTex", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _EdgeTex;
uniform float4 _MainTex_TexelSize;
float filterRadius;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 color = tex2D(_MainTex, i.uv.xy);
half edges = color.a;
return edges;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: da310021e2a4142429d95c537846dc38
ShaderImporter:
userData:
Shader "Hidden/SimpleClear" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
half4 frag (v2f i) : SV_Target
{
return half4(0,0,0,0);
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: f688f89ed5eb847c5b19c934a0f1e772
ShaderImporter:
userData:
Shader "Hidden/SunShaftsComposite" {
Properties {
_MainTex ("Base", 2D) = "" {}
_ColorBuffer ("Color", 2D) = "" {}
_Skybox ("Skybox", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
#if UNITY_UV_STARTS_AT_TOP
float2 uv1 : TEXCOORD1;
#endif
};
struct v2f_radial {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 blurVector : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _ColorBuffer;
sampler2D _Skybox;
sampler2D_float _CameraDepthTexture;
uniform half4 _SunThreshold;
uniform half4 _SunColor;
uniform half4 _BlurRadius4;
uniform half4 _SunPosition;
uniform half4 _MainTex_TexelSize;
#define SAMPLES_FLOAT 6.0f
#define SAMPLES_INT 6
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
o.uv1 = v.texcoord.xy;
if (_MainTex_TexelSize.y < 0)
o.uv1.y = 1-o.uv1.y;
#endif
return o;
}
half4 fragScreen(v2f i) : SV_Target {
half4 colorA = tex2D (_MainTex, i.uv.xy);
#if UNITY_UV_STARTS_AT_TOP
half4 colorB = tex2D (_ColorBuffer, i.uv1.xy);
#else
half4 colorB = tex2D (_ColorBuffer, i.uv.xy);
#endif
half4 depthMask = saturate (colorB * _SunColor);
return 1.0f - (1.0f-colorA) * (1.0f-depthMask);
}
half4 fragAdd(v2f i) : SV_Target {
half4 colorA = tex2D (_MainTex, i.uv.xy);
#if UNITY_UV_STARTS_AT_TOP
half4 colorB = tex2D (_ColorBuffer, i.uv1.xy);
#else
half4 colorB = tex2D (_ColorBuffer, i.uv.xy);
#endif
half4 depthMask = saturate (colorB * _SunColor);
return colorA + depthMask;
}
v2f_radial vert_radial( appdata_img v ) {
v2f_radial o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.blurVector = (_SunPosition.xy - v.texcoord.xy) * _BlurRadius4.xy;
return o;
}
half4 frag_radial(v2f_radial i) : SV_Target
{
half4 color = half4(0,0,0,0);
for(int j = 0; j < SAMPLES_INT; j++)
{
half4 tmpColor = tex2D(_MainTex, i.uv.xy);
color += tmpColor;
i.uv.xy += i.blurVector;
}
return color / SAMPLES_FLOAT;
}
half TransformColor (half4 skyboxValue) {
return dot(max(skyboxValue.rgb - _SunThreshold.rgb, half3(0,0,0)), half3(1,1,1)); // threshold and convert to greyscale
}
half4 frag_depth (v2f i) : SV_Target {
#if UNITY_UV_STARTS_AT_TOP
float depthSample = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
#else
float depthSample = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
#endif
half4 tex = tex2D (_MainTex, i.uv.xy);
depthSample = Linear01Depth (depthSample);
// consider maximum radius
#if UNITY_UV_STARTS_AT_TOP
half2 vec = _SunPosition.xy - i.uv1.xy;
#else
half2 vec = _SunPosition.xy - i.uv.xy;
#endif
half dist = saturate (_SunPosition.w - length (vec.xy));
half4 outColor = 0;
// consider shafts blockers
if (depthSample > 0.99)
outColor = TransformColor (tex) * dist;
return outColor;
}
half4 frag_nodepth (v2f i) : SV_Target {
#if UNITY_UV_STARTS_AT_TOP
float4 sky = (tex2D (_Skybox, i.uv1.xy));
#else
float4 sky = (tex2D (_Skybox, i.uv.xy));
#endif
float4 tex = (tex2D (_MainTex, i.uv.xy));
// consider maximum radius
#if UNITY_UV_STARTS_AT_TOP
half2 vec = _SunPosition.xy - i.uv1.xy;
#else
half2 vec = _SunPosition.xy - i.uv.xy;
#endif
half dist = saturate (_SunPosition.w - length (vec));
half4 outColor = 0;
// find unoccluded sky pixels
// consider pixel values that differ significantly between framebuffer and sky-only buffer as occluded
if (Luminance ( abs(sky.rgb - tex.rgb)) < 0.2)
outColor = TransformColor (sky) * dist;
return outColor;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScreen
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert_radial
#pragma fragment frag_radial
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_depth
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_nodepth
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAdd
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: d3b1c8c1036784176946f5cfbfb7fe4c
ShaderImporter:
userData:
Shader "Hidden/Tonemapper" {
Properties {
_MainTex ("", 2D) = "black" {}
_SmallTex ("", 2D) = "grey" {}
_Curve ("", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _SmallTex;
sampler2D _Curve;
float4 _HdrParams;
float2 intensity;
float4 _MainTex_TexelSize;
float _AdaptionSpeed;
float _ExposureAdjustment;
float _RangeScale;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float4 fragLog(v2f i) : SV_Target
{
const float DELTA = 0.0001f;
float fLogLumSum = 0.0f;
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,-1)).rgb) + DELTA);
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,1)).rgb) + DELTA);
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,1)).rgb) + DELTA);
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,-1)).rgb) + DELTA);
float avg = fLogLumSum / 4.0;
return float4(avg, avg, avg, avg);
}
float4 fragExp(v2f i) : SV_Target
{
float2 lum = float2(0.0f, 0.0f);
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,-1)).xy;
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,1)).xy;
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,-1)).xy;
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,1)).xy;
lum = exp(lum / 4.0f);
return float4(lum.x, lum.y, lum.x, saturate(0.0125 * _AdaptionSpeed));
}
float3 ToCIE(float3 FullScreenImage)
{
// RGB -> XYZ conversion
// http://www.w3.org/Graphics/Color/sRGB
// The official sRGB to XYZ conversion matrix is (following ITU-R BT.709)
// 0.4125 0.3576 0.1805
// 0.2126 0.7152 0.0722
// 0.0193 0.1192 0.9505
float3x3 RGB2XYZ = {0.5141364, 0.3238786, 0.16036376, 0.265068, 0.67023428, 0.06409157, 0.0241188, 0.1228178, 0.84442666};
float3 XYZ = mul(RGB2XYZ, FullScreenImage.rgb);
// XYZ -> Yxy conversion
float3 Yxy;
Yxy.r = XYZ.g;
// x = X / (X + Y + Z)
// y = X / (X + Y + Z)
float temp = dot(float3(1.0,1.0,1.0), XYZ.rgb);
Yxy.gb = XYZ.rg / temp;
return Yxy;
}
float3 FromCIE(float3 Yxy)
{
float3 XYZ;
// Yxy -> XYZ conversion
XYZ.r = Yxy.r * Yxy.g / Yxy. b;
// X = Y * x / y
XYZ.g = Yxy.r;
// copy luminance Y
XYZ.b = Yxy.r * (1 - Yxy.g - Yxy.b) / Yxy.b;
// Z = Y * (1-x-y) / y
// XYZ -> RGB conversion
// The official XYZ to sRGB conversion matrix is (following ITU-R BT.709)
// 3.2410 -1.5374 -0.4986
// -0.9692 1.8760 0.0416
// 0.0556 -0.2040 1.0570
float3x3 XYZ2RGB = { 2.5651,-1.1665,-0.3986, -1.0217, 1.9777, 0.0439, 0.0753, -0.2543, 1.1892};
return mul(XYZ2RGB, XYZ);
}
// NOTE/OPTIMIZATION: we're not going the extra CIE detour anymore, but
// scale with the OUT/IN luminance ratio,this is sooooo much faster
float4 fragAdaptive(v2f i) : SV_Target
{
float avgLum = tex2D(_SmallTex, i.uv).x;
float4 color = tex2D (_MainTex, i.uv);
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
lumScaled = (lumScaled * (1.0f + lumScaled / (_HdrParams.w)))/(1.0f + lumScaled);
//cie.r = lumScaled;
color.rgb = color.rgb * (lumScaled / cieLum);
//color.rgb = FromCIE(cie);
return color;
}
float4 fragAdaptiveAutoWhite(v2f i) : SV_Target
{
float2 avgLum = tex2D(_SmallTex, i.uv).xy;
float4 color = tex2D(_MainTex, i.uv);
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
lumScaled = (lumScaled * (1.0f + lumScaled / (avgLum.y*avgLum.y)))/(1.0f + lumScaled);
//cie.r = lumScaled;
color.rgb = color.rgb * (lumScaled / cieLum);
//color.rgb = FromCIE(cie);
return color;
}
float4 fragCurve(v2f i) : SV_Target
{
float4 color = tex2D(_MainTex, i.uv);
float3 cie = ToCIE(color.rgb);
// Remap to new lum range
float newLum = tex2D(_Curve, float2(cie.r * _RangeScale, 0.5)).r;
cie.r = newLum;
color.rgb = FromCIE(cie);
return color;
}
float4 fragHable(v2f i) : SV_Target
{
const float A = 0.15;
const float B = 0.50;
const float C = 0.10;
const float D = 0.20;
const float E = 0.02;
const float F = 0.30;
const float W = 11.2;
float3 texColor = tex2D(_MainTex, i.uv).rgb;
texColor *= _ExposureAdjustment;
float ExposureBias = 2.0;
float3 x = ExposureBias*texColor;
float3 curr = ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
x = W;
float3 whiteScale = 1.0f/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);
float3 color = curr*whiteScale;
// float3 retColor = pow(color,1/2.2); // we have SRGB write enabled at this stage
return float4(color, 1.0);
}
// we are doing it on luminance here (better color preservation, but some other problems like very fast saturation)
float4 fragSimpleReinhard(v2f i) : SV_Target
{
float4 texColor = tex2D(_MainTex, i.uv);
float lum = Luminance(texColor.rgb);
float lumTm = lum * _ExposureAdjustment;
float scale = lumTm / (1+lumTm);
return float4(texColor.rgb * scale / lum, texColor.a);
}
float4 fragOptimizedHejiDawson(v2f i) : SV_Target
{
float4 texColor = tex2D(_MainTex, i.uv );
texColor *= _ExposureAdjustment;
float4 X = max(float4(0.0,0.0,0.0,0.0), texColor-0.004);
float4 retColor = (X*(6.2*X+.5))/(X*(6.2*X+1.7)+0.06);
return retColor*retColor;
}
float4 fragPhotographic(v2f i) : SV_Target
{
float4 texColor = tex2D(_MainTex, i.uv);
return 1-exp2(-_ExposureAdjustment * texColor);
}
float4 fragDownsample(v2f i) : SV_Target
{
float4 tapA = tex2D(_MainTex, i.uv + _MainTex_TexelSize * 0.5);
float4 tapB = tex2D(_MainTex, i.uv - _MainTex_TexelSize * 0.5);
float4 tapC = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(0.5,-0.5));
float4 tapD = tex2D(_MainTex, i.uv - _MainTex_TexelSize * float2(0.5,-0.5));
float4 average = (tapA+tapB+tapC+tapD)/4;
average.y = max(max(tapA.y,tapB.y), max(tapC.y,tapD.y));
return average;
}
ENDCG
Subshader {
// adaptive reinhhard apply
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAdaptive
ENDCG
}
// 1
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragLog
ENDCG
}
// 2
Pass {
ZTest Always Cull Off ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment fragExp
ENDCG
}
// 3
Pass {
ZTest Always Cull Off ZWrite Off
Blend Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragExp
ENDCG
}
// 4 user controllable tonemap curve
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragCurve
ENDCG
}
// 5 tonemapping in uncharted
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragHable
ENDCG
}
// 6 simple tonemapping based reinhard
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragSimpleReinhard
ENDCG
}
// 7 OptimizedHejiDawson
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragOptimizedHejiDawson
ENDCG
}
// 8 Photographic
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragPhotographic
ENDCG
}
// 9 Downsample with auto white detection
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragDownsample
ENDCG
}
// 10 adaptive reinhhard apply with auto white
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAdaptiveAutoWhite
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 003377fc2620a44939dadde6fe3f8190
ShaderImporter:
userData:
Shader "Hidden/Twirt Effect Shader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
uniform float4 _CenterRadius;
uniform float4x4 _RotationMatrix;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord - _CenterRadius.xy;
return o;
}
float4 frag (v2f i) : SV_Target
{
float2 offset = i.uv;
float2 distortedOffset = MultiplyUV (_RotationMatrix, offset.xy);
float2 tmp = offset / _CenterRadius.zw;
float t = min (1, length(tmp));
offset = lerp (distortedOffset, offset, t);
offset += _CenterRadius.xy;
return tex2D(_MainTex, offset);
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 641b781cad112c75d0008dfa8d76c639
ShaderImporter:
userData:
Shader "Hidden/Vignetting" {
Properties {
_MainTex ("Base", 2D) = "white" {}
_VignetteTex ("Vignette", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _VignetteTex;
half _Intensity;
half _Blur;
float4 _MainTex_TexelSize;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv2 = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv2.y = 1.0 - o.uv2.y;
#endif
return o;
}
half4 frag(v2f i) : SV_Target {
half2 coords = i.uv;
half2 uv = i.uv;
coords = (coords - 0.5) * 2.0;
half coordDot = dot (coords,coords);
half4 color = tex2D (_MainTex, uv);
float mask = 1.0 - coordDot * _Intensity * 0.1;
half4 colorBlur = tex2D (_VignetteTex, i.uv2);
color = lerp (color, colorBlur, saturate (_Blur * coordDot));
return color * mask;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 627943dc7a9a74286b70a4f694a0acd5
ShaderImporter:
userData:
Shader "Hidden/Twist Effect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float4 _MainTex_TexelSize;
uniform float _Angle;
uniform float4 _CenterRadius;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvOrig : TEXCOORD1;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy - _CenterRadius.xy;
o.uv = TRANSFORM_TEX(uv, _MainTex); //MultiplyUV (UNITY_MATRIX_TEXTURE0, uv);
o.uvOrig = uv;
return o;
}
float4 frag (v2f i) : SV_Target
{
float2 offset = i.uvOrig;
float angle = 1.0 - length(offset / _CenterRadius.zw);
angle = max (0, angle);
angle = angle * angle * _Angle;
float cosLength, sinLength;
sincos (angle, sinLength, cosLength);
float2 uv;
uv.x = cosLength * offset[0] - sinLength * offset[1];
uv.y = sinLength * offset[0] + cosLength * offset[1];
uv += _CenterRadius.xy;
return tex2D(_MainTex, uv);
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 708b781cad112c75d0008dfa8d76c639
ShaderImporter:
userData:
fileFormatVersion: 2
guid: 6d55b5e91b95c41739cdf4f804dd383d
folderAsset: yes
timeCreated: 1433531202
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
//
// modified and adapted DLAA code based on Dmitry Andreev's
// Directionally Localized Anti-Aliasing (DLAA)
//
// as seen in "The Force Unleashed 2"
//
Shader "Hidden/DLAA" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
#define LD( o, dx, dy ) o = tex2D( _MainTex, texCoord + float2( dx, dy ) * _MainTex_TexelSize.xy );
float GetIntensity( float3 col )
{
return dot( col, float3( 0.33f, 0.33f, 0.33f ) );
}
float4 highPassPre( float2 texCoord )
{
LD(float4 sCenter, 0.0,0.0)
LD(float4 sUpLeft, -1.0,-1.0)
LD(float4 sUpRight, 1.0,-1.0)
LD(float4 sDownLeft, -1.0,1.0)
LD(float4 sDownRight, 1.0,1.0)
float4 diff = 4.0f * abs( (sUpLeft + sUpRight + sDownLeft + sDownRight) - 4.0f * sCenter );
float edgeMask = GetIntensity(diff.xyz);
return float4(sCenter.rgb, edgeMask);
}
// Softer (5-pixel wide high-pass)
/*
void HighPassEdgeHV (out float4 edge_h, out float4 edge_v, float4 center, float4 w_h, float4 w_v, float2 texCoord) {
edge_h = abs( w_h - 4.0f * center ) / 4.0f;
edge_v = abs( w_v - 4.0f * center ) / 4.0f;
}
// Sharper (3-pixel wide high-pass)
void EdgeHV (out float4 edge_h, out float4 edge_v, float4 center, float2 texCoord) {
float4 left, right, top, bottom;
LD( left, -1, 0 )
LD( right, 1, 0 )
LD( top, 0, -1 )
LD( bottom, 0, 1 )
edge_h = abs( left + right - 2.0f * center ) / 2.0f;
edge_v = abs( top + bottom - 2.0f * center ) / 2.0f;
}
*/
float4 edgeDetectAndBlur( float2 texCoord )
{
float lambda = 3.0f;
float epsilon = 0.1f;
//
// Short Edges
//
float4 center, left_01, right_01, top_01, bottom_01;
// sample 5x5 cross
LD( center, 0, 0 )
LD( left_01, -1.5, 0 )
LD( right_01, 1.5, 0 )
LD( top_01, 0,-1.5 )
LD( bottom_01, 0, 1.5 )
float4 w_h = 2.0f * ( left_01 + right_01 );
float4 w_v = 2.0f * ( top_01 + bottom_01 );
// Softer (5-pixel wide high-pass)
float4 edge_h = abs( w_h - 4.0f * center ) / 4.0f;
float4 edge_v = abs( w_v - 4.0f * center ) / 4.0f;
float4 blurred_h = ( w_h + 2.0f * center ) / 6.0f;
float4 blurred_v = ( w_v + 2.0f * center ) / 6.0f;
float edge_h_lum = GetIntensity( edge_h.xyz );
float edge_v_lum = GetIntensity( edge_v.xyz );
float blurred_h_lum = GetIntensity( blurred_h.xyz );
float blurred_v_lum = GetIntensity( blurred_v.xyz );
float edge_mask_h = saturate( ( lambda * edge_h_lum - epsilon ) / blurred_v_lum );
float edge_mask_v = saturate( ( lambda * edge_v_lum - epsilon ) / blurred_h_lum );
float4 clr = center;
clr = lerp( clr, blurred_h, edge_mask_v );
clr = lerp( clr, blurred_v, edge_mask_h ); // blurrier version
//
// Long Edges
//
float4 h0, h1, h2, h3, h4, h5, h6, h7;
float4 v0, v1, v2, v3, v4, v5, v6, v7;
// sample 16x16 cross (sparse-sample on X360, incremental kernel update on SPUs)
LD( h0, 1.5, 0 ) LD( h1, 3.5, 0 ) LD( h2, 5.5, 0 ) LD( h3, 7.5, 0 ) LD( h4, -1.5,0 ) LD( h5, -3.5,0 ) LD( h6, -5.5,0 ) LD( h7, -7.5,0 )
LD( v0, 0, 1.5 ) LD( v1, 0, 3.5 ) LD( v2, 0, 5.5 ) LD( v3, 0, 7.5 ) LD( v4, 0,-1.5 ) LD( v5, 0,-3.5 ) LD( v6, 0,-5.5 ) LD( v7, 0,-7.5 )
float long_edge_mask_h = ( h0.a + h1.a + h2.a + h3.a + h4.a + h5.a + h6.a + h7.a ) / 8.0f;
float long_edge_mask_v = ( v0.a + v1.a + v2.a + v3.a + v4.a + v5.a + v6.a + v7.a ) / 8.0f;
long_edge_mask_h = saturate( long_edge_mask_h * 2.0f - 1.0f );
long_edge_mask_v = saturate( long_edge_mask_v * 2.0f - 1.0f );
float4 left, right, top, bottom;
LD( left, -1, 0 )
LD( right, 1, 0 )
LD( top, 0, -1 )
LD( bottom, 0, 1 )
if ( long_edge_mask_h > 0 || long_edge_mask_v > 0 ) // faster but less resistant to noise (TFU2 X360)
//if ( abs( long_edge_mask_h - long_edge_mask_v ) > 0.2f ) // resistant to noise (TFU2 SPUs)
{
float4 long_blurred_h = ( h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 ) / 8.0f;
float4 long_blurred_v = ( v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 ) / 8.0f;
float lb_h_lum = GetIntensity( long_blurred_h.xyz );
float lb_v_lum = GetIntensity( long_blurred_v.xyz );
float center_lum = GetIntensity( center.xyz );
float left_lum = GetIntensity( left.xyz );
float right_lum = GetIntensity( right.xyz );
float top_lum = GetIntensity( top.xyz );
float bottom_lum = GetIntensity( bottom.xyz );
float4 clr_v = center;
float4 clr_h = center;
// we had to hack this because DIV by 0 gives some artefacts on different platforms
float hx = center_lum == top_lum ? 0.0 : saturate( 0 + ( lb_h_lum - top_lum ) / ( center_lum - top_lum ) );
float hy = center_lum == bottom_lum ? 0.0 : saturate( 1 + ( lb_h_lum - center_lum ) / ( center_lum - bottom_lum ) );
float vx = center_lum == left_lum ? 0.0 : saturate( 0 + ( lb_v_lum - left_lum ) / ( center_lum - left_lum ) );
float vy = center_lum == right_lum ? 0.0 : saturate( 1 + ( lb_v_lum - center_lum ) / ( center_lum - right_lum ) );
float4 vhxy = float4( vx, vy, hx, hy );
//vhxy = vhxy == float4( 0, 0, 0, 0 ) ? float4( 1, 1, 1, 1 ) : vhxy;
clr_v = lerp( left , clr_v, vhxy.x );
clr_v = lerp( right , clr_v, vhxy.y );
clr_h = lerp( top , clr_h, vhxy.z );
clr_h = lerp( bottom, clr_h, vhxy.w );
clr = lerp( clr, clr_v, long_edge_mask_v );
clr = lerp( clr, clr_h, long_edge_mask_h );
}
return clr;
}
float4 edgeDetectAndBlurSharper(float2 texCoord)
{
float lambda = 3.0f;
float epsilon = 0.1f;
//
// Short Edges
//
float4 center, left_01, right_01, top_01, bottom_01;
// sample 5x5 cross
LD( center, 0, 0 )
LD( left_01, -1.5, 0 )
LD( right_01, 1.5, 0 )
LD( top_01, 0,-1.5 )
LD( bottom_01, 0, 1.5 )
float4 w_h = 2.0f * ( left_01 + right_01 );
float4 w_v = 2.0f * ( top_01 + bottom_01 );
// Sharper (3-pixel wide high-pass)
float4 left, right, top, bottom;
LD( left, -1, 0 )
LD( right, 1, 0 )
LD( top, 0, -1 )
LD( bottom, 0, 1 )
float4 edge_h = abs( left + right - 2.0f * center ) / 2.0f;
float4 edge_v = abs( top + bottom - 2.0f * center ) / 2.0f;
float4 blurred_h = ( w_h + 2.0f * center ) / 6.0f;
float4 blurred_v = ( w_v + 2.0f * center ) / 6.0f;
float edge_h_lum = GetIntensity( edge_h.xyz );
float edge_v_lum = GetIntensity( edge_v.xyz );
float blurred_h_lum = GetIntensity( blurred_h.xyz );
float blurred_v_lum = GetIntensity( blurred_v.xyz );
float edge_mask_h = saturate( ( lambda * edge_h_lum - epsilon ) / blurred_v_lum );
float edge_mask_v = saturate( ( lambda * edge_v_lum - epsilon ) / blurred_h_lum );
float4 clr = center;
clr = lerp( clr, blurred_h, edge_mask_v );
clr = lerp( clr, blurred_v, edge_mask_h * 0.5f ); // TFU2 uses 1.0f instead of 0.5f
//
// Long Edges
//
float4 h0, h1, h2, h3, h4, h5, h6, h7;
float4 v0, v1, v2, v3, v4, v5, v6, v7;
// sample 16x16 cross (sparse-sample on X360, incremental kernel update on SPUs)
LD( h0, 1.5, 0 ) LD( h1, 3.5, 0 ) LD( h2, 5.5, 0 ) LD( h3, 7.5, 0 ) LD( h4, -1.5,0 ) LD( h5, -3.5,0 ) LD( h6, -5.5,0 ) LD( h7, -7.5,0 )
LD( v0, 0, 1.5 ) LD( v1, 0, 3.5 ) LD( v2, 0, 5.5 ) LD( v3, 0, 7.5 ) LD( v4, 0,-1.5 ) LD( v5, 0,-3.5 ) LD( v6, 0,-5.5 ) LD( v7, 0,-7.5 )
float long_edge_mask_h = ( h0.a + h1.a + h2.a + h3.a + h4.a + h5.a + h6.a + h7.a ) / 8.0f;
float long_edge_mask_v = ( v0.a + v1.a + v2.a + v3.a + v4.a + v5.a + v6.a + v7.a ) / 8.0f;
long_edge_mask_h = saturate( long_edge_mask_h * 2.0f - 1.0f );
long_edge_mask_v = saturate( long_edge_mask_v * 2.0f - 1.0f );
//if ( long_edge_mask_h > 0 || long_edge_mask_v > 0 ) // faster but less resistant to noise (TFU2 X360)
if ( abs( long_edge_mask_h - long_edge_mask_v ) > 0.2f ) // resistant to noise (TFU2 SPUs)
{
float4 long_blurred_h = ( h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 ) / 8.0f;
float4 long_blurred_v = ( v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 ) / 8.0f;
float lb_h_lum = GetIntensity( long_blurred_h.xyz );
float lb_v_lum = GetIntensity( long_blurred_v.xyz );
float center_lum = GetIntensity( center.xyz );
float left_lum = GetIntensity( left.xyz );
float right_lum = GetIntensity( right.xyz );
float top_lum = GetIntensity( top.xyz );
float bottom_lum = GetIntensity( bottom.xyz );
float4 clr_v = center;
float4 clr_h = center;
// we had to hack this because DIV by 0 gives some artefacts on different platforms
float hx = center_lum == top_lum ? 0.0 : saturate( 0 + ( lb_h_lum - top_lum ) / ( center_lum - top_lum ) );
float hy = center_lum == bottom_lum ? 0.0 : saturate( 1 + ( lb_h_lum - center_lum ) / ( center_lum - bottom_lum ) );
float vx = center_lum == left_lum ? 0.0 : saturate( 0 + ( lb_v_lum - left_lum ) / ( center_lum - left_lum ) );
float vy = center_lum == right_lum ? 0.0 : saturate( 1 + ( lb_v_lum - center_lum ) / ( center_lum - right_lum ) );
float4 vhxy = float4( vx, vy, hx, hy );
//vhxy = vhxy == float4( 0, 0, 0, 0 ) ? float4( 1, 1, 1, 1 ) : vhxy;
clr_v = lerp( left , clr_v, vhxy.x );
clr_v = lerp( right , clr_v, vhxy.y );
clr_h = lerp( top , clr_h, vhxy.z );
clr_h = lerp( bottom, clr_h, vhxy.w );
clr = lerp( clr, clr_v, long_edge_mask_v );
clr = lerp( clr, clr_h, long_edge_mask_h );
}
return clr;
}
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
o.uv.xy = uv;
return o;
}
half4 fragFirst (v2f i) : SV_Target {
return highPassPre (i.uv);
}
half4 fragSecond (v2f i) : SV_Target {
return edgeDetectAndBlur( i.uv );
}
half4 fragThird (v2f i) : SV_Target {
return edgeDetectAndBlurSharper( i.uv );
}
ENDCG
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragFirst
#pragma exclude_renderers d3d11_9x
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragSecond
#pragma target 3.0
#pragma exclude_renderers d3d11_9x
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragThird
#pragma target 3.0
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 017ca72b9e8a749058d13ebd527e98fa
ShaderImporter:
userData:
Shader "Hidden/FXAA II" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
#define FXAA_HLSL_3 1
/*============================================================================
FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA
============================================================================*/
/*============================================================================
API PORTING
============================================================================*/
#ifndef FXAA_GLSL_120
#define FXAA_GLSL_120 0
#endif
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#ifndef FXAA_HLSL_3
#define FXAA_HLSL_3 0
#endif
#ifndef FXAA_HLSL_4
#define FXAA_HLSL_4 0
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_120
// Requires,
// #version 120
// #extension GL_EXT_gpu_shader4 : enable
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaSat(a) clamp((a), 0.0, 1.0)
#define FxaaTex sampler2D
#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
// Requires "#version 130" or better
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaSat(a) clamp((a), 0.0, 1.0)
#define FxaaTex sampler2D
#define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_3
#define int2 float2
#define FxaaInt2 float2
#define FxaaFloat2 float2
#define FxaaSat(a) saturate((a))
#define FxaaTex sampler2D
#define FxaaTexLod0(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_4
#define FxaaInt2 int2
#define FxaaFloat2 float2
#define FxaaSat(a) saturate((a))
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexLod0(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
#endif
/*============================================================================
VERTEX SHADER
============================================================================*/
float4 FxaaVertexShader(
float2 pos, // Both x and y range {-1.0 to 1.0 across screen}.
float2 rcpFrame) { // {1.0/frameWidth, 1.0/frameHeight}
/*--------------------------------------------------------------------------*/
#define FXAA_SUBPIX_SHIFT (1.0/4.0)
/*--------------------------------------------------------------------------*/
float4 posPos;
posPos.xy = (pos.xy * 0.5) + 0.5;
posPos.zw = posPos.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT));
return posPos; }
/*============================================================================
PIXEL SHADER
============================================================================*/
float3 FxaaPixelShader(
float4 posPos, // Output of FxaaVertexShader interpolated across screen.
FxaaTex tex, // Input texture.
float2 rcpFrame) { // Constant {1.0/frameWidth, 1.0/frameHeight}.
/*--------------------------------------------------------------------------*/
#define FXAA_REDUCE_MIN (1.0/128.0)
#define FXAA_REDUCE_MUL (1.0/8.0)
#define FXAA_SPAN_MAX 8.0
/*--------------------------------------------------------------------------*/
float3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
float3 rgbNE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;
float3 rgbSW = FxaaTexOff(tex, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;
float3 rgbSE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;
float3 rgbM = FxaaTexLod0(tex, posPos.xy).xyz;
/*--------------------------------------------------------------------------*/
float3 luma = float3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
/*--------------------------------------------------------------------------*/
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
/*--------------------------------------------------------------------------*/
float2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
/*--------------------------------------------------------------------------*/
float dirReduce = max(
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
FXAA_REDUCE_MIN);
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(FxaaFloat2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(FxaaFloat2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * rcpFrame.xy;
/*--------------------------------------------------------------------------*/
float3 rgbA = (1.0/2.0) * (
FxaaTexLod0(tex, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +
FxaaTexLod0(tex, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);
float3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
FxaaTexLod0(tex, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +
FxaaTexLod0(tex, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
float lumaB = dot(rgbB, luma);
if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
return rgbB; }
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
};
float4 _MainTex_TexelSize;
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = FxaaVertexShader (v.texcoord.xy*2-1, _MainTex_TexelSize.xy);
return o;
}
sampler2D _MainTex;
float4 frag (v2f i) : SV_Target
{
return float4(FxaaPixelShader(i.uv, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: cd5b323dcc592457790ff18b528f5e67
ShaderImporter:
userData:
/*============================================================================
source taken from
NVIDIA FXAA 3.11 by TIMOTHY LOTTES
and adapted and ported to Unity by Unity Technologies
------------------------------------------------------------------------------
COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.
------------------------------------------------------------------------------
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA
OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
============================================================================*/
Shader "Hidden/FXAA III (Console)" {
Properties {
_MainTex ("-", 2D) = "white" {}
_EdgeThresholdMin ("Edge threshold min",float) = 0.125
_EdgeThreshold("Edge Threshold", float) = 0.25
_EdgeSharpness("Edge sharpness",float) = 4.0
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform half _EdgeThresholdMin;
uniform half _EdgeThreshold;
uniform half _EdgeSharpness;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 interpolatorA : TEXCOORD1;
float4 interpolatorB : TEXCOORD2;
float4 interpolatorC : TEXCOORD3;
};
float4 _MainTex_TexelSize;
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
float4 extents;
float2 offset = ( _MainTex_TexelSize.xy ) * 0.5f;
extents.xy = v.texcoord.xy - offset;
extents.zw = v.texcoord.xy + offset;
float4 rcpSize;
rcpSize.xy = -_MainTex_TexelSize.xy * 0.5f;
rcpSize.zw = _MainTex_TexelSize.xy * 0.5f;
#if defined (SHADER_API_PSP2)
//cg compiler linker bug workaround
float almostzero = v.texcoord.x*0.000001f;
rcpSize.x += almostzero;
#endif
o.interpolatorA = extents;
o.interpolatorB = rcpSize;
o.interpolatorC = rcpSize;
o.interpolatorC.xy *= 4.0;
o.interpolatorC.zw *= 4.0;
return o;
}
// hacky support for NaCl
#if defined(SHADER_API_GLES) && defined(SHADER_API_DESKTOP)
#define FxaaTexTop(t, p) tex2D(t, p)
#else
#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
#endif
inline half TexLuminance( float2 uv )
{
return Luminance(FxaaTexTop(_MainTex, uv).rgb);
}
half3 FxaaPixelShader(float2 pos, float4 extents, float4 rcpSize, float4 rcpSize2)
{
half lumaNw = TexLuminance(extents.xy);
half lumaSw = TexLuminance(extents.xw);
half lumaNe = TexLuminance(extents.zy);
half lumaSe = TexLuminance(extents.zw);
half3 centre = FxaaTexTop(_MainTex, pos).rgb;
half lumaCentre = Luminance(centre);
half lumaMaxNwSw = max( lumaNw , lumaSw );
lumaNe += 1.0/384.0;
half lumaMinNwSw = min( lumaNw , lumaSw );
half lumaMaxNeSe = max( lumaNe , lumaSe );
half lumaMinNeSe = min( lumaNe , lumaSe );
half lumaMax = max( lumaMaxNeSe, lumaMaxNwSw );
half lumaMin = min( lumaMinNeSe, lumaMinNwSw );
half lumaMaxScaled = lumaMax * _EdgeThreshold;
half lumaMinCentre = min( lumaMin , lumaCentre );
half lumaMaxScaledClamped = max( _EdgeThresholdMin , lumaMaxScaled );
half lumaMaxCentre = max( lumaMax , lumaCentre );
half dirSWMinusNE = lumaSw - lumaNe;
half lumaMaxCMinusMinC = lumaMaxCentre - lumaMinCentre;
half dirSEMinusNW = lumaSe - lumaNw;
if(lumaMaxCMinusMinC < lumaMaxScaledClamped)
return centre;
half2 dir;
dir.x = dirSWMinusNE + dirSEMinusNW;
dir.y = dirSWMinusNE - dirSEMinusNW;
dir = normalize(dir);
half3 col1 = FxaaTexTop(_MainTex, pos.xy - dir * rcpSize.zw).rgb;
half3 col2 = FxaaTexTop(_MainTex, pos.xy + dir * rcpSize.zw).rgb;
half dirAbsMinTimesC = min( abs( dir.x ) , abs( dir.y ) ) * _EdgeSharpness;
dir = clamp(dir.xy/dirAbsMinTimesC, -2.0, 2.0);
half3 col3 = FxaaTexTop(_MainTex, pos.xy - dir * rcpSize2.zw).rgb;
half3 col4 = FxaaTexTop(_MainTex, pos.xy + dir * rcpSize2.zw).rgb;
half3 rgbyA = col1 + col2;
half3 rgbyB = ((col3 + col4) * 0.25) + (rgbyA * 0.25);
if((Luminance(rgbyA) < lumaMin) || (Luminance(rgbyB) > lumaMax))
return rgbyA * 0.5;
else
return rgbyB;
}
half4 frag (v2f i) : SV_Target
{
half3 color = FxaaPixelShader(i.uv, i.interpolatorA, i.interpolatorB, i.interpolatorC);
return half4(color, 1.0);
}
ENDCG
}
}
FallBack Off
}
fileFormatVersion: 2
guid: c547503fff0e8482ea5793727057041c
ShaderImporter:
userData:
Shader "Hidden/FXAA Preset 2" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
// doesn't make sense to have this on consoles, it'll fallback to FXAA2
#pragma exclude_renderers xbox360 ps3 gles
#define FXAA_HLSL_3 1
#define FXAA_PRESET 2
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
//
// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
/*============================================================================
FXAA
============================================================================*/
/*============================================================================
API PORTING
============================================================================*/
#ifndef FXAA_GLSL_120
#define FXAA_GLSL_120 0
#endif
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#ifndef FXAA_HLSL_3
#define FXAA_HLSL_3 0
#endif
#ifndef FXAA_HLSL_4
#define FXAA_HLSL_4 0
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_120
// Requires,
// #version 120
// #extension GL_EXT_gpu_shader4 : enable
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
// Requires "#version 130" or better
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_3
#define int2 float2
#define FxaaInt2 float2
#define FxaaFloat2 float2
#define FxaaFloat3 float3
#define FxaaFloat4 float4
#define FxaaBool2Float(a) (a)
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_4
#define FxaaInt2 int2
#define FxaaFloat2 float2
#define FxaaFloat3 float3
#define FxaaFloat4 float4
#define FxaaBool2Float(a) (a)
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#endif
/*--------------------------------------------------------------------------*/
#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
/*--------------------------------------------------------------------------*/
float4 FxaaTexLod0(FxaaTex tex, float2 pos) {
#if FXAA_GLSL_120
return texture2DLod(tex, pos.xy, 0.0);
#endif
#if FXAA_GLSL_130
return textureLod(tex, pos.xy, 0.0);
#endif
#if FXAA_HLSL_3
return tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
#endif
#if FXAA_HLSL_4
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0);
#endif
}
/*--------------------------------------------------------------------------*/
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
#if FXAA_GLSL_120
return texture2DGrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_GLSL_130
return textureGrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_HLSL_3
return tex2Dgrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_HLSL_4
return tex.tex.SampleGrad(tex.smpl, pos.xy, grad, grad);
#endif
}
/*--------------------------------------------------------------------------*/
float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) {
#if FXAA_GLSL_120
return texture2DLodOffset(tex, pos.xy, 0.0, off.xy);
#endif
#if FXAA_GLSL_130
return textureLodOffset(tex, pos.xy, 0.0, off.xy);
#endif
#if FXAA_HLSL_3
return tex2Dlod(tex, float4(pos.xy + (off * rcpFrame), 0, 0));
#endif
#if FXAA_HLSL_4
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0, off.xy);
#endif
}
/*============================================================================
SRGB KNOBS
------------------------------------------------------------------------------
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
This will do the sRGB to linear transform,
as ROP will expect linear color from this shader,
and this shader works in non-linear color.
============================================================================*/
#define FXAA_SRGB_ROP 0
/*============================================================================
DEBUG KNOBS
------------------------------------------------------------------------------
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
yellow tint on sub-pixel aliasing filtered by FXAA.
FXAA_DEBUG_HORZVERT - Blue for horizontal edges, gold for vertical edges.
FXAA_DEBUG_PAIR - Blue/green for the 2 pixel pair choice.
FXAA_DEBUG_NEGPOS - Red/blue for which side of center of span.
FXAA_DEBUG_OFFSET - Red/blue for -/+ x, gold/skyblue for -/+ y.
============================================================================*/
#ifndef FXAA_DEBUG_PASSTHROUGH
#define FXAA_DEBUG_PASSTHROUGH 0
#endif
#ifndef FXAA_DEBUG_HORZVERT
#define FXAA_DEBUG_HORZVERT 0
#endif
#ifndef FXAA_DEBUG_PAIR
#define FXAA_DEBUG_PAIR 0
#endif
#ifndef FXAA_DEBUG_NEGPOS
#define FXAA_DEBUG_NEGPOS 0
#endif
#ifndef FXAA_DEBUG_OFFSET
#define FXAA_DEBUG_OFFSET 0
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
#define FXAA_DEBUG 1
#endif
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
#define FXAA_DEBUG 1
#endif
#ifndef FXAA_DEBUG
#define FXAA_DEBUG 0
#endif
/*============================================================================
COMPILE-IN KNOBS
------------------------------------------------------------------------------
FXAA_PRESET - Choose compile-in knob preset 0-5.
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
to apply algorithm.
1.0/3.0 - too little
1.0/4.0 - good start
1.0/8.0 - applies to more edges
1.0/16.0 - overkill
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
Perf optimization.
1.0/32.0 - visible limit (smaller isn't visible)
1.0/16.0 - good compromise
1.0/12.0 - upper limit (seeing artifacts)
------------------------------------------------------------------------------
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
------------------------------------------------------------------------------
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
1 - no acceleration
2 - skip by 2 pixels
3 - skip by 3 pixels
4 - skip by 4 pixels
------------------------------------------------------------------------------
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
1.0/4.0 - seems to be the best quality wise
------------------------------------------------------------------------------
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
Not recomended, but used in preset 0.
------------------------------------------------------------------------------
FXAA_SUBPIX - Toggle subpix filtering.
0 - turn off
1 - turn on
2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
------------------------------------------------------------------------------
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
1.0/2.0 - low removal
1.0/3.0 - medium removal
1.0/4.0 - default removal
1.0/8.0 - high removal
0.0 - complete removal
------------------------------------------------------------------------------
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
This is important for the transition of sub-pixel detail,
like fences and wires.
3.0/4.0 - default (medium amount of filtering)
7.0/8.0 - high amount of filtering
1.0 - no capping of sub-pixel aliasing removal
============================================================================*/
#ifndef FXAA_PRESET
#define FXAA_PRESET 3
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 0)
#define FXAA_EDGE_THRESHOLD (1.0/4.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
#define FXAA_SEARCH_STEPS 2
#define FXAA_SEARCH_ACCELERATION 4
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 1
#define FXAA_SUBPIX_CAP (2.0/3.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 1)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
#define FXAA_SEARCH_STEPS 4
#define FXAA_SEARCH_ACCELERATION 3
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 2)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 8
#define FXAA_SEARCH_ACCELERATION 2
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 3)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 16
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 4)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 24
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 5)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 32
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
/*============================================================================
HELPERS
============================================================================*/
// Return the luma, the estimation of luminance from rgb inputs.
// This approximates luma using one FMA instruction,
// skipping normalization and tossing out blue.
// FxaaLuma() will range 0.0 to 2.963210702.
float FxaaLuma(float3 rgb) {
return rgb.y * (0.587/0.299) + rgb.x; }
/*--------------------------------------------------------------------------*/
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
return (FxaaToFloat3(-amountOfA) * b) +
((a * FxaaToFloat3(amountOfA)) + b); }
/*--------------------------------------------------------------------------*/
// Support any extra filtering before returning color.
float3 FxaaFilterReturn(float3 rgb) {
#if FXAA_SRGB_ROP
// Do sRGB encoded value to linear conversion.
return FxaaSel3(
rgb * FxaaToFloat3(1.0/12.92),
FxaaPow3(
rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
FxaaToFloat3(2.4)),
rgb > FxaaToFloat3(0.04045));
#else
return rgb;
#endif
}
/*============================================================================
VERTEX SHADER
============================================================================*/
float2 FxaaVertexShader(
// Both x and y range {-1.0 to 1.0 across screen}.
float2 inPos) {
float2 pos;
pos.xy = (inPos.xy * FxaaFloat2(0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
return pos; }
/*============================================================================
PIXEL SHADER
============================================================================*/
float3 FxaaPixelShader(
// Output of FxaaVertexShader interpolated across screen.
// xy -> actual texture position {0.0 to 1.0}
float2 pos,
// Input texture.
FxaaTex tex,
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// {1.0/frameWidth, 1.0/frameHeight}
float2 rcpFrame) {
/*----------------------------------------------------------------------------
EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
------------------------------------------------------------------------------
Majority of pixels of a typical image do not require filtering,
often pixels are grouped into blocks which could benefit from early exit
right at the beginning of the algorithm.
Given the following neighborhood,
N
W M E
S
If the difference in local maximum and minimum luma (contrast "range")
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
then the shader early exits (no visible aliasing).
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
to avoid processing in really dark areas.
----------------------------------------------------------------------------*/
float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
float lumaN = FxaaLuma(rgbN);
float lumaW = FxaaLuma(rgbW);
float lumaM = FxaaLuma(rgbM);
float lumaE = FxaaLuma(rgbE);
float lumaS = FxaaLuma(rgbS);
float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
float range = rangeMax - rangeMin;
#if FXAA_DEBUG
float lumaO = lumaM / (1.0 + (0.587/0.299));
#endif
if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
#if FXAA_DEBUG
return FxaaFilterReturn(FxaaToFloat3(lumaO));
#endif
return FxaaFilterReturn(rgbM); }
#if FXAA_SUBPIX > 0
#if FXAA_SUBPIX_FASTER
float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
FxaaToFloat3(1.0/5.0);
#else
float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
#endif
#endif
/*----------------------------------------------------------------------------
COMPUTE LOWPASS
------------------------------------------------------------------------------
FXAA computes a local neighborhood lowpass value as follows,
(N + W + E + S)/4
Then uses the ratio of the contrast range of the lowpass
and the range found in the early exit check,
as a sub-pixel aliasing detection filter.
When FXAA detects sub-pixel aliasing (such as single pixel dots),
it later blends in "blendL" amount
of a lowpass value (computed in the next section) to the final result.
----------------------------------------------------------------------------*/
#if FXAA_SUBPIX != 0
float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
float rangeL = abs(lumaL - lumaM);
#endif
#if FXAA_SUBPIX == 1
float blendL = max(0.0,
(rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
blendL = min(FXAA_SUBPIX_CAP, blendL);
#endif
#if FXAA_SUBPIX == 2
float blendL = rangeL / range;
#endif
#if FXAA_DEBUG_PASSTHROUGH
#if FXAA_SUBPIX == 0
float blendL = 0.0;
#endif
return FxaaFilterReturn(
FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
#endif
/*----------------------------------------------------------------------------
CHOOSE VERTICAL OR HORIZONTAL SEARCH
------------------------------------------------------------------------------
FXAA uses the following local neighborhood,
NW N NE
W M E
SW S SE
To compute an edge amount for both vertical and horizontal directions.
Note edge detect filters like Sobel fail on single pixel lines through M.
FXAA takes the weighted average magnitude of the high-pass values
for rows and columns as an indication of local edge amount.
A lowpass value for anti-sub-pixel-aliasing is computed as
(N+W+E+S+M+NW+NE+SW+SE)/9.
This full box pattern has higher quality than other options.
Note following this block, both vertical and horizontal cases
flow in parallel (reusing the horizontal variables).
----------------------------------------------------------------------------*/
float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
#if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
rgbL *= FxaaToFloat3(1.0/9.0);
#endif
float lumaNW = FxaaLuma(rgbNW);
float lumaNE = FxaaLuma(rgbNE);
float lumaSW = FxaaLuma(rgbSW);
float lumaSE = FxaaLuma(rgbSE);
float edgeVert =
abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
float edgeHorz =
abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
bool horzSpan = edgeHorz >= edgeVert;
#if FXAA_DEBUG_HORZVERT
if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
#endif
float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
if(!horzSpan) lumaN = lumaW;
if(!horzSpan) lumaS = lumaE;
float gradientN = abs(lumaN - lumaM);
float gradientS = abs(lumaS - lumaM);
lumaN = (lumaN + lumaM) * 0.5;
lumaS = (lumaS + lumaM) * 0.5;
/*----------------------------------------------------------------------------
CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
------------------------------------------------------------------------------
This chooses a pixel pair.
For "horzSpan == true" this will be a vertical pair,
[N] N
[M] or [M]
S [S]
Note following this block, both {N,M} and {S,M} cases
flow in parallel (reusing the {N,M} variables).
This pair of image rows or columns is searched below
in the positive and negative direction
until edge status changes
(or the maximum number of search steps is reached).
----------------------------------------------------------------------------*/
bool pairN = gradientN >= gradientS;
#if FXAA_DEBUG_PAIR
if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
#endif
if(!pairN) lumaN = lumaS;
if(!pairN) gradientN = gradientS;
if(!pairN) lengthSign *= -1.0;
float2 posN;
posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
/*----------------------------------------------------------------------------
CHOOSE SEARCH LIMITING VALUES
------------------------------------------------------------------------------
Search limit (+/- gradientN) is a function of local gradient.
----------------------------------------------------------------------------*/
gradientN *= FXAA_SEARCH_THRESHOLD;
/*----------------------------------------------------------------------------
SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
------------------------------------------------------------------------------
This loop searches either in vertical or horizontal directions,
and in both the negative and positive direction in parallel.
This loop fusion is faster than searching separately.
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
via anisotropic filtering with specified texture gradients.
----------------------------------------------------------------------------*/
float2 posP = posN;
float2 offNP = horzSpan ?
FxaaFloat2(rcpFrame.x, 0.0) :
FxaaFloat2(0.0f, rcpFrame.y);
float lumaEndN = lumaN;
float lumaEndP = lumaN;
bool doneN = false;
bool doneP = false;
#if FXAA_SEARCH_ACCELERATION == 1
posN += offNP * FxaaFloat2(-1.0, -1.0);
posP += offNP * FxaaFloat2( 1.0, 1.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 2
posN += offNP * FxaaFloat2(-1.5, -1.5);
posP += offNP * FxaaFloat2( 1.5, 1.5);
offNP *= FxaaFloat2(2.0, 2.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 3
posN += offNP * FxaaFloat2(-2.0, -2.0);
posP += offNP * FxaaFloat2( 2.0, 2.0);
offNP *= FxaaFloat2(3.0, 3.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 4
posN += offNP * FxaaFloat2(-2.5, -2.5);
posP += offNP * FxaaFloat2( 2.5, 2.5);
offNP *= FxaaFloat2(4.0, 4.0);
#endif
for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
#if FXAA_SEARCH_ACCELERATION == 1
if(!doneN) lumaEndN =
FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
if(!doneP) lumaEndP =
FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
#else
if(!doneN) lumaEndN =
FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
if(!doneP) lumaEndP =
FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
#endif
doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
if(doneN && doneP) break;
if(!doneN) posN -= offNP;
if(!doneP) posP += offNP; }
/*----------------------------------------------------------------------------
HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
------------------------------------------------------------------------------
FXAA uses the pixel's position in the span
in combination with the values (lumaEnd*) at the ends of the span,
to determine filtering.
This step computes which side of the span the pixel is on.
On negative side if dstN < dstP,
posN pos posP
|-----------|------|------------------|
| | | |
|<--dstN--->|<---------dstP---------->|
|
span center
----------------------------------------------------------------------------*/
float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
bool directionN = dstN < dstP;
#if FXAA_DEBUG_NEGPOS
if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
#endif
lumaEndN = directionN ? lumaEndN : lumaEndP;
/*----------------------------------------------------------------------------
CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
------------------------------------------------------------------------------
If both the pair luma at the end of the span (lumaEndN)
and middle pixel luma (lumaM)
are on the same side of the middle pair average luma (lumaN),
then don't filter.
Cases,
(1.) "L",
lumaM
|
V XXXXXXXX <- other line averaged
XXXXXXX[X]XXXXXXXXXXX <- source pixel line
| . |
--------------------------
[ ]xxxxxx[x]xx[X]XXXXXX <- pair average
--------------------------
^ ^ ^ ^
| | | |
. |<---->|<---------- no filter region
. | | |
. center | |
. | lumaEndN
. | .
. lumaN .
. .
|<--- span -->|
(2.) "^" and "-",
<- other line averaged
XXXXX[X]XXX <- source pixel line
| | |
--------------------------
[ ]xxxx[x]xx[ ] <- pair average
--------------------------
| | |
|<--->|<--->|<---------- filter both sides
(3.) "v" and inverse of "-",
XXXXXX XXXXXXXXX <- other line averaged
XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
| | |
--------------------------
XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
--------------------------
| | |
|<--->|<--->|<---------- don't filter both!
Note the "v" case for FXAA requires no filtering.
This is because the inverse of the "-" case is the "v".
Filtering "v" case turns open spans like this,
XXXXXXXXX
Into this (which is not desired),
x+. .+x
XXXXXXXXX
----------------------------------------------------------------------------*/
if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
lengthSign = 0.0;
/*----------------------------------------------------------------------------
COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
------------------------------------------------------------------------------
FXAA filters using a bilinear texture fetch offset
from the middle pixel M towards the center of the pair (NM below).
Maximum filtering will be half way between pair.
Reminder, at this point in the code,
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
+-------+
| | 0.5 offset
| N | |
| | V
+-------+....---
| |
| M...|....---
| | ^
+-------+ |
. . 0.0 offset
. S .
. .
.........
Position on span is used to compute sub-pixel filter offset using simple ramp,
posN posP
|\ |<------- 0.5 pixel offset into pair pixel
| \ |
| \ |
---.......|...\..........|<------- 0.25 pixel offset into pair pixel
^ | ^\ |
| | | \ |
V | | \ |
---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
^ . | ^ .
| . pos | .
| . . | .
| . . center .
| . . .
| |<->|<---------.-------- dstN
| . . .
| . |<-------->|<------- dstP
| . .
| |<------------>|<------- spanLength
|
subPixelOffset
----------------------------------------------------------------------------*/
float spanLength = (dstP + dstN);
dstN = directionN ? dstN : dstP;
float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
#if FXAA_DEBUG_OFFSET
float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
if(ox < 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(1.0, 0.0, 0.0), -ox));
if(ox > 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(0.0, 0.0, 1.0), ox));
if(oy < 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(1.0, 0.6, 0.2), -oy));
if(oy > 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(0.2, 0.6, 1.0), oy));
return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
#endif
float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
pos.x + (horzSpan ? 0.0 : subPixelOffset),
pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
#if FXAA_SUBPIX == 0
return FxaaFilterReturn(rgbF);
#else
return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
#endif
}
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float4 frag (v2f i) : SV_Target
{
return float4(FxaaPixelShader(i.uv.xy, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
}
ENDCG
}
}
Fallback "Hidden/FXAA II"
}
fileFormatVersion: 2
guid: 6f1418cffd12146f2a83be795f6fa5a7
ShaderImporter:
userData:
Shader "Hidden/FXAA Preset 3" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
// Not very practical on consoles/mobile, and PS3 Cg takes ages to compile this :(
#pragma exclude_renderers xbox360 ps3 gles
#define FXAA_HLSL_3 1
#define FXAA_PRESET 3
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
//
// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
/*============================================================================
FXAA
============================================================================*/
/*============================================================================
API PORTING
============================================================================*/
#ifndef FXAA_GLSL_120
#define FXAA_GLSL_120 0
#endif
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#ifndef FXAA_HLSL_3
#define FXAA_HLSL_3 0
#endif
#ifndef FXAA_HLSL_4
#define FXAA_HLSL_4 0
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_120
// Requires,
// #version 120
// #extension GL_EXT_gpu_shader4 : enable
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
// Requires "#version 130" or better
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_3
#define int2 float2
#define FxaaInt2 float2
#define FxaaFloat2 float2
#define FxaaFloat3 float3
#define FxaaFloat4 float4
#define FxaaBool2Float(a) (a)
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
#define FxaaTex sampler2D
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_HLSL_4
#define FxaaInt2 int2
#define FxaaFloat2 float2
#define FxaaFloat3 float3
#define FxaaFloat4 float4
#define FxaaBool2Float(a) (a)
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#endif
/*--------------------------------------------------------------------------*/
#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
/*--------------------------------------------------------------------------*/
float4 FxaaTexLod0(FxaaTex tex, float2 pos) {
#if FXAA_GLSL_120
return texture2DLod(tex, pos.xy, 0.0);
#endif
#if FXAA_GLSL_130
return textureLod(tex, pos.xy, 0.0);
#endif
#if FXAA_HLSL_3
return tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
#endif
#if FXAA_HLSL_4
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0);
#endif
}
/*--------------------------------------------------------------------------*/
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
#if FXAA_GLSL_120
return texture2DGrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_GLSL_130
return textureGrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_HLSL_3
return tex2Dgrad(tex, pos.xy, grad, grad);
#endif
#if FXAA_HLSL_4
return tex.tex.SampleGrad(tex.smpl, pos.xy, grad, grad);
#endif
}
/*--------------------------------------------------------------------------*/
float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) {
#if FXAA_GLSL_120
return texture2DLodOffset(tex, pos.xy, 0.0, off.xy);
#endif
#if FXAA_GLSL_130
return textureLodOffset(tex, pos.xy, 0.0, off.xy);
#endif
#if FXAA_HLSL_3
return tex2Dlod(tex, float4(pos.xy + (off * rcpFrame), 0, 0));
#endif
#if FXAA_HLSL_4
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0, off.xy);
#endif
}
/*============================================================================
SRGB KNOBS
------------------------------------------------------------------------------
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
This will do the sRGB to linear transform,
as ROP will expect linear color from this shader,
and this shader works in non-linear color.
============================================================================*/
#define FXAA_SRGB_ROP 0
/*============================================================================
DEBUG KNOBS
------------------------------------------------------------------------------
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
yellow tint on sub-pixel aliasing filtered by FXAA.
FXAA_DEBUG_HORZVERT - Blue for horizontal edges, gold for vertical edges.
FXAA_DEBUG_PAIR - Blue/green for the 2 pixel pair choice.
FXAA_DEBUG_NEGPOS - Red/blue for which side of center of span.
FXAA_DEBUG_OFFSET - Red/blue for -/+ x, gold/skyblue for -/+ y.
============================================================================*/
#ifndef FXAA_DEBUG_PASSTHROUGH
#define FXAA_DEBUG_PASSTHROUGH 0
#endif
#ifndef FXAA_DEBUG_HORZVERT
#define FXAA_DEBUG_HORZVERT 0
#endif
#ifndef FXAA_DEBUG_PAIR
#define FXAA_DEBUG_PAIR 0
#endif
#ifndef FXAA_DEBUG_NEGPOS
#define FXAA_DEBUG_NEGPOS 0
#endif
#ifndef FXAA_DEBUG_OFFSET
#define FXAA_DEBUG_OFFSET 0
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
#define FXAA_DEBUG 1
#endif
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
#define FXAA_DEBUG 1
#endif
#ifndef FXAA_DEBUG
#define FXAA_DEBUG 0
#endif
/*============================================================================
COMPILE-IN KNOBS
------------------------------------------------------------------------------
FXAA_PRESET - Choose compile-in knob preset 0-5.
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
to apply algorithm.
1.0/3.0 - too little
1.0/4.0 - good start
1.0/8.0 - applies to more edges
1.0/16.0 - overkill
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
Perf optimization.
1.0/32.0 - visible limit (smaller isn't visible)
1.0/16.0 - good compromise
1.0/12.0 - upper limit (seeing artifacts)
------------------------------------------------------------------------------
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
------------------------------------------------------------------------------
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
1 - no acceleration
2 - skip by 2 pixels
3 - skip by 3 pixels
4 - skip by 4 pixels
------------------------------------------------------------------------------
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
1.0/4.0 - seems to be the best quality wise
------------------------------------------------------------------------------
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
Not recomended, but used in preset 0.
------------------------------------------------------------------------------
FXAA_SUBPIX - Toggle subpix filtering.
0 - turn off
1 - turn on
2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
------------------------------------------------------------------------------
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
1.0/2.0 - low removal
1.0/3.0 - medium removal
1.0/4.0 - default removal
1.0/8.0 - high removal
0.0 - complete removal
------------------------------------------------------------------------------
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
This is important for the transition of sub-pixel detail,
like fences and wires.
3.0/4.0 - default (medium amount of filtering)
7.0/8.0 - high amount of filtering
1.0 - no capping of sub-pixel aliasing removal
============================================================================*/
#ifndef FXAA_PRESET
#define FXAA_PRESET 3
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 0)
#define FXAA_EDGE_THRESHOLD (1.0/4.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
#define FXAA_SEARCH_STEPS 2
#define FXAA_SEARCH_ACCELERATION 4
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 1
#define FXAA_SUBPIX_CAP (2.0/3.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 1)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
#define FXAA_SEARCH_STEPS 4
#define FXAA_SEARCH_ACCELERATION 3
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 2)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 8
#define FXAA_SEARCH_ACCELERATION 2
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 3)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 16
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 4)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 24
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 5)
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
#define FXAA_SEARCH_STEPS 32
#define FXAA_SEARCH_ACCELERATION 1
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
#define FXAA_SUBPIX 1
#define FXAA_SUBPIX_FASTER 0
#define FXAA_SUBPIX_CAP (3.0/4.0)
#define FXAA_SUBPIX_TRIM (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
/*============================================================================
HELPERS
============================================================================*/
// Return the luma, the estimation of luminance from rgb inputs.
// This approximates luma using one FMA instruction,
// skipping normalization and tossing out blue.
// FxaaLuma() will range 0.0 to 2.963210702.
float FxaaLuma(float3 rgb) {
return rgb.y * (0.587/0.299) + rgb.x; }
/*--------------------------------------------------------------------------*/
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
return (FxaaToFloat3(-amountOfA) * b) +
((a * FxaaToFloat3(amountOfA)) + b); }
/*--------------------------------------------------------------------------*/
// Support any extra filtering before returning color.
float3 FxaaFilterReturn(float3 rgb) {
#if FXAA_SRGB_ROP
// Do sRGB encoded value to linear conversion.
return FxaaSel3(
rgb * FxaaToFloat3(1.0/12.92),
FxaaPow3(
rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
FxaaToFloat3(2.4)),
rgb > FxaaToFloat3(0.04045));
#else
return rgb;
#endif
}
/*============================================================================
VERTEX SHADER
============================================================================*/
float2 FxaaVertexShader(
// Both x and y range {-1.0 to 1.0 across screen}.
float2 inPos) {
float2 pos;
pos.xy = (inPos.xy * FxaaFloat2(0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
return pos; }
/*============================================================================
PIXEL SHADER
============================================================================*/
float3 FxaaPixelShader(
// Output of FxaaVertexShader interpolated across screen.
// xy -> actual texture position {0.0 to 1.0}
float2 pos,
// Input texture.
FxaaTex tex,
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// {1.0/frameWidth, 1.0/frameHeight}
float2 rcpFrame) {
/*----------------------------------------------------------------------------
EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
------------------------------------------------------------------------------
Majority of pixels of a typical image do not require filtering,
often pixels are grouped into blocks which could benefit from early exit
right at the beginning of the algorithm.
Given the following neighborhood,
N
W M E
S
If the difference in local maximum and minimum luma (contrast "range")
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
then the shader early exits (no visible aliasing).
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
to avoid processing in really dark areas.
----------------------------------------------------------------------------*/
float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
float lumaN = FxaaLuma(rgbN);
float lumaW = FxaaLuma(rgbW);
float lumaM = FxaaLuma(rgbM);
float lumaE = FxaaLuma(rgbE);
float lumaS = FxaaLuma(rgbS);
float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
float range = rangeMax - rangeMin;
#if FXAA_DEBUG
float lumaO = lumaM / (1.0 + (0.587/0.299));
#endif
if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
#if FXAA_DEBUG
return FxaaFilterReturn(FxaaToFloat3(lumaO));
#endif
return FxaaFilterReturn(rgbM); }
#if FXAA_SUBPIX > 0
#if FXAA_SUBPIX_FASTER
float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
FxaaToFloat3(1.0/5.0);
#else
float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
#endif
#endif
/*----------------------------------------------------------------------------
COMPUTE LOWPASS
------------------------------------------------------------------------------
FXAA computes a local neighborhood lowpass value as follows,
(N + W + E + S)/4
Then uses the ratio of the contrast range of the lowpass
and the range found in the early exit check,
as a sub-pixel aliasing detection filter.
When FXAA detects sub-pixel aliasing (such as single pixel dots),
it later blends in "blendL" amount
of a lowpass value (computed in the next section) to the final result.
----------------------------------------------------------------------------*/
#if FXAA_SUBPIX != 0
float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
float rangeL = abs(lumaL - lumaM);
#endif
#if FXAA_SUBPIX == 1
float blendL = max(0.0,
(rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
blendL = min(FXAA_SUBPIX_CAP, blendL);
#endif
#if FXAA_SUBPIX == 2
float blendL = rangeL / range;
#endif
#if FXAA_DEBUG_PASSTHROUGH
#if FXAA_SUBPIX == 0
float blendL = 0.0;
#endif
return FxaaFilterReturn(
FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
#endif
/*----------------------------------------------------------------------------
CHOOSE VERTICAL OR HORIZONTAL SEARCH
------------------------------------------------------------------------------
FXAA uses the following local neighborhood,
NW N NE
W M E
SW S SE
To compute an edge amount for both vertical and horizontal directions.
Note edge detect filters like Sobel fail on single pixel lines through M.
FXAA takes the weighted average magnitude of the high-pass values
for rows and columns as an indication of local edge amount.
A lowpass value for anti-sub-pixel-aliasing is computed as
(N+W+E+S+M+NW+NE+SW+SE)/9.
This full box pattern has higher quality than other options.
Note following this block, both vertical and horizontal cases
flow in parallel (reusing the horizontal variables).
----------------------------------------------------------------------------*/
float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
#if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
rgbL *= FxaaToFloat3(1.0/9.0);
#endif
float lumaNW = FxaaLuma(rgbNW);
float lumaNE = FxaaLuma(rgbNE);
float lumaSW = FxaaLuma(rgbSW);
float lumaSE = FxaaLuma(rgbSE);
float edgeVert =
abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
float edgeHorz =
abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
bool horzSpan = edgeHorz >= edgeVert;
#if FXAA_DEBUG_HORZVERT
if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
#endif
float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
if(!horzSpan) lumaN = lumaW;
if(!horzSpan) lumaS = lumaE;
float gradientN = abs(lumaN - lumaM);
float gradientS = abs(lumaS - lumaM);
lumaN = (lumaN + lumaM) * 0.5;
lumaS = (lumaS + lumaM) * 0.5;
/*----------------------------------------------------------------------------
CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
------------------------------------------------------------------------------
This chooses a pixel pair.
For "horzSpan == true" this will be a vertical pair,
[N] N
[M] or [M]
S [S]
Note following this block, both {N,M} and {S,M} cases
flow in parallel (reusing the {N,M} variables).
This pair of image rows or columns is searched below
in the positive and negative direction
until edge status changes
(or the maximum number of search steps is reached).
----------------------------------------------------------------------------*/
bool pairN = gradientN >= gradientS;
#if FXAA_DEBUG_PAIR
if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
#endif
if(!pairN) lumaN = lumaS;
if(!pairN) gradientN = gradientS;
if(!pairN) lengthSign *= -1.0;
float2 posN;
posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
/*----------------------------------------------------------------------------
CHOOSE SEARCH LIMITING VALUES
------------------------------------------------------------------------------
Search limit (+/- gradientN) is a function of local gradient.
----------------------------------------------------------------------------*/
gradientN *= FXAA_SEARCH_THRESHOLD;
/*----------------------------------------------------------------------------
SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
------------------------------------------------------------------------------
This loop searches either in vertical or horizontal directions,
and in both the negative and positive direction in parallel.
This loop fusion is faster than searching separately.
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
via anisotropic filtering with specified texture gradients.
----------------------------------------------------------------------------*/
float2 posP = posN;
float2 offNP = horzSpan ?
FxaaFloat2(rcpFrame.x, 0.0) :
FxaaFloat2(0.0f, rcpFrame.y);
float lumaEndN = lumaN;
float lumaEndP = lumaN;
bool doneN = false;
bool doneP = false;
#if FXAA_SEARCH_ACCELERATION == 1
posN += offNP * FxaaFloat2(-1.0, -1.0);
posP += offNP * FxaaFloat2( 1.0, 1.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 2
posN += offNP * FxaaFloat2(-1.5, -1.5);
posP += offNP * FxaaFloat2( 1.5, 1.5);
offNP *= FxaaFloat2(2.0, 2.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 3
posN += offNP * FxaaFloat2(-2.0, -2.0);
posP += offNP * FxaaFloat2( 2.0, 2.0);
offNP *= FxaaFloat2(3.0, 3.0);
#endif
#if FXAA_SEARCH_ACCELERATION == 4
posN += offNP * FxaaFloat2(-2.5, -2.5);
posP += offNP * FxaaFloat2( 2.5, 2.5);
offNP *= FxaaFloat2(4.0, 4.0);
#endif
for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
#if FXAA_SEARCH_ACCELERATION == 1
if(!doneN) lumaEndN =
FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
if(!doneP) lumaEndP =
FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
#else
if(!doneN) lumaEndN =
FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
if(!doneP) lumaEndP =
FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
#endif
doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
if(doneN && doneP) break;
if(!doneN) posN -= offNP;
if(!doneP) posP += offNP; }
/*----------------------------------------------------------------------------
HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
------------------------------------------------------------------------------
FXAA uses the pixel's position in the span
in combination with the values (lumaEnd*) at the ends of the span,
to determine filtering.
This step computes which side of the span the pixel is on.
On negative side if dstN < dstP,
posN pos posP
|-----------|------|------------------|
| | | |
|<--dstN--->|<---------dstP---------->|
|
span center
----------------------------------------------------------------------------*/
float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
bool directionN = dstN < dstP;
#if FXAA_DEBUG_NEGPOS
if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
#endif
lumaEndN = directionN ? lumaEndN : lumaEndP;
/*----------------------------------------------------------------------------
CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
------------------------------------------------------------------------------
If both the pair luma at the end of the span (lumaEndN)
and middle pixel luma (lumaM)
are on the same side of the middle pair average luma (lumaN),
then don't filter.
Cases,
(1.) "L",
lumaM
|
V XXXXXXXX <- other line averaged
XXXXXXX[X]XXXXXXXXXXX <- source pixel line
| . |
--------------------------
[ ]xxxxxx[x]xx[X]XXXXXX <- pair average
--------------------------
^ ^ ^ ^
| | | |
. |<---->|<---------- no filter region
. | | |
. center | |
. | lumaEndN
. | .
. lumaN .
. .
|<--- span -->|
(2.) "^" and "-",
<- other line averaged
XXXXX[X]XXX <- source pixel line
| | |
--------------------------
[ ]xxxx[x]xx[ ] <- pair average
--------------------------
| | |
|<--->|<--->|<---------- filter both sides
(3.) "v" and inverse of "-",
XXXXXX XXXXXXXXX <- other line averaged
XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
| | |
--------------------------
XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
--------------------------
| | |
|<--->|<--->|<---------- don't filter both!
Note the "v" case for FXAA requires no filtering.
This is because the inverse of the "-" case is the "v".
Filtering "v" case turns open spans like this,
XXXXXXXXX
Into this (which is not desired),
x+. .+x
XXXXXXXXX
----------------------------------------------------------------------------*/
if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
lengthSign = 0.0;
/*----------------------------------------------------------------------------
COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
------------------------------------------------------------------------------
FXAA filters using a bilinear texture fetch offset
from the middle pixel M towards the center of the pair (NM below).
Maximum filtering will be half way between pair.
Reminder, at this point in the code,
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
+-------+
| | 0.5 offset
| N | |
| | V
+-------+....---
| |
| M...|....---
| | ^
+-------+ |
. . 0.0 offset
. S .
. .
.........
Position on span is used to compute sub-pixel filter offset using simple ramp,
posN posP
|\ |<------- 0.5 pixel offset into pair pixel
| \ |
| \ |
---.......|...\..........|<------- 0.25 pixel offset into pair pixel
^ | ^\ |
| | | \ |
V | | \ |
---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
^ . | ^ .
| . pos | .
| . . | .
| . . center .
| . . .
| |<->|<---------.-------- dstN
| . . .
| . |<-------->|<------- dstP
| . .
| |<------------>|<------- spanLength
|
subPixelOffset
----------------------------------------------------------------------------*/
float spanLength = (dstP + dstN);
dstN = directionN ? dstN : dstP;
float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
#if FXAA_DEBUG_OFFSET
float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
if(ox < 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(1.0, 0.0, 0.0), -ox));
if(ox > 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(0.0, 0.0, 1.0), ox));
if(oy < 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(1.0, 0.6, 0.2), -oy));
if(oy > 0.0) return FxaaFilterReturn(
FxaaLerp3(FxaaToFloat3(lumaO),
FxaaFloat3(0.2, 0.6, 1.0), oy));
return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
#endif
float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
pos.x + (horzSpan ? 0.0 : subPixelOffset),
pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
#if FXAA_SUBPIX == 0
return FxaaFilterReturn(rgbF);
#else
return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
#endif
}
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float4 frag (v2f i) : SV_Target
{
return float4(FxaaPixelShader(i.uv.xy, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
}
ENDCG
}
}
Fallback "Hidden/FXAA II"
}
fileFormatVersion: 2
guid: c182fa94a5a0a4c02870641efcd38cd5
ShaderImporter:
userData:
Shader "Hidden/NFAA" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_BlurTex ("Base (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
uniform float _OffsetScale;
uniform float _BlurRadius;
struct v2f {
float4 pos : SV_POSITION;
float2 uv[8] : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
float2 up = float2(0.0, _MainTex_TexelSize.y) * _OffsetScale;
float2 right = float2(_MainTex_TexelSize.x, 0.0) * _OffsetScale;
o.uv[0].xy = uv + up;
o.uv[1].xy = uv - up;
o.uv[2].xy = uv + right;
o.uv[3].xy = uv - right;
o.uv[4].xy = uv - right + up;
o.uv[5].xy = uv - right -up;
o.uv[6].xy = uv + right + up;
o.uv[7].xy = uv + right -up;
return o;
}
half4 frag (v2f i) : SV_Target
{
// get luminance values
// maybe: experiment with different luminance calculations
float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
// 2 triangle subtractions
float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
// figure out "normal"
float2 blurDir = half2((sum0-sum1), (sum3-sum2));
blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
// reconstruct normal uv
float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
float4 returnColor = tex2D(_MainTex, uv_);
returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
return returnColor * 0.2;
}
half4 fragDebug (v2f i) : SV_Target
{
// get luminance values
// maybe: experiment with different luminance calculations
float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
// 2 triangle subtractions
float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
// figure out "normal"
float2 blurDir = half2((sum0-sum1), (sum3-sum2));
blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
// reconstruct normal uv
float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
float4 returnColor = tex2D(_MainTex, uv_);
returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
blurDir = half2((sum0-sum1), (sum3-sum2)) * _BlurRadius;
return half4(normalize( half3(blurDir,1) * 0.5 + 0.5), 1);
return returnColor * 0.2;
}
ENDCG
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma exclude_renderers d3d11_9x
ENDCG
}
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragDebug
#pragma exclude_renderers d3d11_9x
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: ce0cb2621f6d84e21a87414e471a3cce
ShaderImporter:
userData:
Shader "Hidden/SSAA" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
// very simple & fast AA by Emmanuel Julien
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
struct v2f {
float4 pos : SV_POSITION;
float2 uv[5] : TEXCOORD0;
};
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
float w = 1.75;
float2 up = float2(0.0, _MainTex_TexelSize.y) * w;
float2 right = float2(_MainTex_TexelSize.x, 0.0) * w;
o.uv[0].xy = uv - up;
o.uv[1].xy = uv - right;
o.uv[2].xy = uv + right;
o.uv[3].xy = uv + up;
o.uv[4].xy = uv;
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 outColor;
float t = Luminance( tex2D( _MainTex, i.uv[0] ).xyz );
float l = Luminance( tex2D( _MainTex, i.uv[1] ).xyz);
float r = Luminance( tex2D( _MainTex, i.uv[2] ).xyz);
float b = Luminance( tex2D( _MainTex, i.uv[3] ).xyz);
half2 n = half2( -( t - b ), r - l );
float nl = length( n );
if ( nl < (1.0 / 16.0) )
outColor = tex2D( _MainTex, i.uv[4] );
else {
n *= _MainTex_TexelSize.xy / nl;
half4 o = tex2D( _MainTex, i.uv[4]);
half4 t0 = tex2D( _MainTex, i.uv[4] + n * 0.5) * 0.9;
half4 t1 = tex2D( _MainTex, i.uv[4] - n * 0.5) * 0.9;
half4 t2 = tex2D( _MainTex, i.uv[4] + n) * 0.75;
half4 t3 = tex2D( _MainTex, i.uv[4] - n) * 0.75;
outColor = (o + t0 + t1 + t2 + t3) / 4.3;
}
return outColor;
}
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: b3728d1488b02490cbd196c7941bf1f8
ShaderImporter:
userData:
fileFormatVersion: 2
guid: d6ef58fc6f637406bbe6814a19c377f8
Shader "Hidden/Blend" {
Properties {
_MainTex ("Screen Blended", 2D) = "" {}
_ColorBuffer ("Color", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
struct v2f_mt {
float4 pos : SV_POSITION;
float2 uv[4] : TEXCOORD0;
};
sampler2D _ColorBuffer;
sampler2D _MainTex;
half _Intensity;
half4 _ColorBuffer_TexelSize;
half4 _MainTex_TexelSize;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_ColorBuffer_TexelSize.y < 0)
o.uv[1].y = 1-o.uv[1].y;
#endif
return o;
}
v2f_mt vertMultiTap( appdata_img v ) {
v2f_mt o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy + _MainTex_TexelSize.xy * 0.5;
o.uv[1] = v.texcoord.xy - _MainTex_TexelSize.xy * 0.5;
o.uv[2] = v.texcoord.xy - _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
o.uv[3] = v.texcoord.xy + _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
return o;
}
half4 fragScreen (v2f i) : SV_Target {
half4 toBlend = saturate (tex2D(_MainTex, i.uv[0]) * _Intensity);
return 1-(1-toBlend)*(1-tex2D(_ColorBuffer, i.uv[1]));
}
half4 fragAdd (v2f i) : SV_Target {
return tex2D(_MainTex, i.uv[0].xy) * _Intensity + tex2D(_ColorBuffer, i.uv[1]);
}
half4 fragVignetteBlend (v2f i) : SV_Target {
return tex2D(_MainTex, i.uv[0].xy) * tex2D(_ColorBuffer, i.uv[0]);
}
half4 fragMultiTap (v2f_mt i) : SV_Target {
half4 outColor = tex2D(_MainTex, i.uv[0].xy);
outColor += tex2D(_MainTex, i.uv[1].xy);
outColor += tex2D(_MainTex, i.uv[2].xy);
outColor += tex2D(_MainTex, i.uv[3].xy);
return outColor * 0.25;
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
// 0: nicer & softer "screen" blend mode
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScreen
ENDCG
}
// 1: simple "add" blend mode
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAdd
ENDCG
}
// 2: used for "stable" downsampling
Pass {
CGPROGRAM
#pragma vertex vertMultiTap
#pragma fragment fragMultiTap
ENDCG
}
// 3: vignette blending
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragVignetteBlend
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 53b3960ee3d3d4a5caa8d5473d120187
ShaderImporter:
userData:
Shader "Hidden/BlendForBloom" {
Properties {
_MainTex ("Screen Blended", 2D) = "" {}
_ColorBuffer ("Color", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[2] : TEXCOORD0;
};
struct v2f_mt {
float4 pos : SV_POSITION;
float2 uv[5] : TEXCOORD0;
};
sampler2D _ColorBuffer;
sampler2D _MainTex;
half _Intensity;
half4 _ColorBuffer_TexelSize;
half4 _MainTex_TexelSize;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_ColorBuffer_TexelSize.y < 0)
o.uv[1].y = 1-o.uv[1].y;
#endif
return o;
}
v2f_mt vertMultiTap( appdata_img v ) {
v2f_mt o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[4] = v.texcoord.xy;
o.uv[0] = v.texcoord.xy + _MainTex_TexelSize.xy * 0.5;
o.uv[1] = v.texcoord.xy - _MainTex_TexelSize.xy * 0.5;
o.uv[2] = v.texcoord.xy - _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
o.uv[3] = v.texcoord.xy + _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
return o;
}
half4 fragScreen (v2f i) : SV_Target {
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy) * _Intensity;
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
return 1-(1-addedbloom)*(1-screencolor);
}
half4 fragScreenCheap(v2f i) : SV_Target {
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy) * _Intensity;
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
return 1-(1-addedbloom)*(1-screencolor);
}
half4 fragAdd (v2f i) : SV_Target {
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy);
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
return _Intensity * addedbloom + screencolor;
}
half4 fragAddCheap (v2f i) : SV_Target {
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy);
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
return _Intensity * addedbloom + screencolor;
}
half4 fragVignetteMul (v2f i) : SV_Target {
return tex2D(_MainTex, i.uv[0].xy) * tex2D(_ColorBuffer, i.uv[0]);
}
half4 fragVignetteBlend (v2f i) : SV_Target {
return half4(1,1,1, tex2D(_ColorBuffer, i.uv[0]).r);
}
half4 fragClear (v2f i) : SV_Target {
return 0;
}
half4 fragAddOneOne (v2f i) : SV_Target {
half4 addedColors = tex2D(_MainTex, i.uv[0].xy);
return addedColors * _Intensity;
}
half4 frag1Tap (v2f i) : SV_Target {
return tex2D(_MainTex, i.uv[0].xy);
}
half4 fragMultiTapMax (v2f_mt i) : SV_Target {
half4 outColor = tex2D(_MainTex, i.uv[4].xy);
outColor = max(outColor, tex2D(_MainTex, i.uv[0].xy));
outColor = max(outColor, tex2D(_MainTex, i.uv[1].xy));
outColor = max(outColor, tex2D(_MainTex, i.uv[2].xy));
outColor = max(outColor, tex2D(_MainTex, i.uv[3].xy));
return outColor;
}
half4 fragMultiTapBlur (v2f_mt i) : SV_Target {
half4 outColor = 0;
outColor += tex2D(_MainTex, i.uv[0].xy);
outColor += tex2D(_MainTex, i.uv[1].xy);
outColor += tex2D(_MainTex, i.uv[2].xy);
outColor += tex2D(_MainTex, i.uv[3].xy);
return outColor/4;
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
// 0: nicer & softer "screen" blend mode
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScreen
ENDCG
}
// 1: "add" blend mode
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAdd
ENDCG
}
// 2: several taps, maxxed
Pass {
CGPROGRAM
#pragma vertex vertMultiTap
#pragma fragment fragMultiTapMax
ENDCG
}
// 3: vignette blending
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragVignetteMul
ENDCG
}
// 4: nicer & softer "screen" blend mode(cheapest)
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScreenCheap
ENDCG
}
// 5: "add" blend mode (cheapest)
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAddCheap
ENDCG
}
// 6: used for "stable" downsampling (blur)
Pass {
CGPROGRAM
#pragma vertex vertMultiTap
#pragma fragment fragMultiTapBlur
ENDCG
}
// 7: vignette blending (blend to dest)
Pass {
Blend Zero SrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment fragVignetteBlend
ENDCG
}
// 8: clear
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragClear
ENDCG
}
// 9: fragAddOneOne
Pass {
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAddOneOne
ENDCG
}
// 10: max blend
Pass {
BlendOp Max
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag1Tap
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 7856cbff0a0ca45c787d5431eb805bb0
ShaderImporter:
userData:
Shader "Hidden/BlendOneOne" {
Properties {
_MainTex ("-", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
half _Intensity;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag(v2f i) : SV_Target {
return tex2D(_MainTex, i.uv) * _Intensity;
}
ENDCG
Subshader {
Pass {
BlendOp Add
Blend One One
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: f7898d203e9b94c0dbe2bf9dd5cb32c0
ShaderImporter:
userData:
Shader "Hidden/BlurAndFlares" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_NonBlurredTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
struct v2f_opts {
half4 pos : SV_POSITION;
half2 uv[7] : TEXCOORD0;
};
struct v2f_blur {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 uv01 : TEXCOORD1;
half4 uv23 : TEXCOORD2;
half4 uv45 : TEXCOORD3;
half4 uv67 : TEXCOORD4;
};
half4 _Offsets;
half4 _TintColor;
half _StretchWidth;
half2 _Threshhold;
half _Saturation;
half4 _MainTex_TexelSize;
sampler2D _MainTex;
sampler2D _NonBlurredTex;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
v2f_blur vertWithMultiCoords2 (appdata_img v) {
v2f_blur o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + _Offsets.xyxy * half4(1,1, -1,-1);
o.uv23 = v.texcoord.xyxy + _Offsets.xyxy * half4(1,1, -1,-1) * 2.0;
o.uv45 = v.texcoord.xyxy + _Offsets.xyxy * half4(1,1, -1,-1) * 3.0;
o.uv67 = v.texcoord.xyxy + _Offsets.xyxy * half4(1,1, -1,-1) * 4.0;
o.uv67 = v.texcoord.xyxy + _Offsets.xyxy * half4(1,1, -1,-1) * 5.0;
return o;
}
v2f_opts vertStretch (appdata_img v) {
v2f_opts o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
half b = _StretchWidth;
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy + b * 2.0 * _Offsets.xy;
o.uv[2] = v.texcoord.xy - b * 2.0 * _Offsets.xy;
o.uv[3] = v.texcoord.xy + b * 4.0 * _Offsets.xy;
o.uv[4] = v.texcoord.xy - b * 4.0 * _Offsets.xy;
o.uv[5] = v.texcoord.xy + b * 6.0 * _Offsets.xy;
o.uv[6] = v.texcoord.xy - b * 6.0 * _Offsets.xy;
return o;
}
v2f_opts vertWithMultiCoords (appdata_img v) {
v2f_opts o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy + 0.5 * _MainTex_TexelSize.xy * _Offsets.xy;
o.uv[2] = v.texcoord.xy - 0.5 * _MainTex_TexelSize.xy * _Offsets.xy;
o.uv[3] = v.texcoord.xy + 1.5 * _MainTex_TexelSize.xy * _Offsets.xy;
o.uv[4] = v.texcoord.xy - 1.5 * _MainTex_TexelSize.xy * _Offsets.xy;
o.uv[5] = v.texcoord.xy + 2.5 * _MainTex_TexelSize.xy * _Offsets.xy;
o.uv[6] = v.texcoord.xy - 2.5 * _MainTex_TexelSize.xy * _Offsets.xy;
return o;
}
half4 fragPostNoBlur (v2f i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv);
return color * 1.0/(1.0 + Luminance(color.rgb) + 0.5); // this also makes it a little noisy
}
half4 fragGaussBlur (v2f_blur i) : SV_Target {
half4 color = half4 (0,0,0,0);
color += 0.225 * tex2D (_MainTex, i.uv);
color += 0.150 * tex2D (_MainTex, i.uv01.xy);
color += 0.150 * tex2D (_MainTex, i.uv01.zw);
color += 0.110 * tex2D (_MainTex, i.uv23.xy);
color += 0.110 * tex2D (_MainTex, i.uv23.zw);
color += 0.075 * tex2D (_MainTex, i.uv45.xy);
color += 0.075 * tex2D (_MainTex, i.uv45.zw);
color += 0.0525 * tex2D (_MainTex, i.uv67.xy);
color += 0.0525 * tex2D (_MainTex, i.uv67.zw);
return color;
}
half4 fragPreAndCut (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color += tex2D (_MainTex, i.uv[1]);
color += tex2D (_MainTex, i.uv[2]);
color += tex2D (_MainTex, i.uv[3]);
color += tex2D (_MainTex, i.uv[4]);
color += tex2D (_MainTex, i.uv[5]);
color += tex2D (_MainTex, i.uv[6]);
color = max(color / 7.0 - _Threshhold.xxxx, float4(0,0,0,0));
half lum = Luminance(color.rgb);
color.rgb = lerp(half3(lum,lum,lum), color.rgb, _Saturation) * _TintColor.rgb;
return color;
}
half4 fragStretch (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color = max (color, tex2D (_MainTex, i.uv[1]));
color = max (color, tex2D (_MainTex, i.uv[2]));
color = max (color, tex2D (_MainTex, i.uv[3]));
color = max (color, tex2D (_MainTex, i.uv[4]));
color = max (color, tex2D (_MainTex, i.uv[5]));
color = max (color, tex2D (_MainTex, i.uv[6]));
return color;
}
half4 fragPost (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color += tex2D (_MainTex, i.uv[1]);
color += tex2D (_MainTex, i.uv[2]);
color += tex2D (_MainTex, i.uv[3]);
color += tex2D (_MainTex, i.uv[4]);
color += tex2D (_MainTex, i.uv[5]);
color += tex2D (_MainTex, i.uv[6]);
return color * 1.0/(7.0 + Luminance(color.rgb) + 0.5); // this also makes it a little noisy
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragPostNoBlur
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vertStretch
#pragma fragment fragStretch
ENDCG
}
// 2
Pass {
CGPROGRAM
#pragma vertex vertWithMultiCoords
#pragma fragment fragPreAndCut
ENDCG
}
// 3
Pass {
CGPROGRAM
#pragma vertex vertWithMultiCoords
#pragma fragment fragPost
ENDCG
}
// 4
Pass {
CGPROGRAM
#pragma vertex vertWithMultiCoords2
#pragma fragment fragGaussBlur
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: be6e39cf196f146d5be72fbefb18ed75
ShaderImporter:
userData:
Shader "Hidden/BrightPassFilterForBloom"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
half4 threshhold;
half useSrcAlphaAsMask;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag(v2f i) : SV_Target
{
half4 color = tex2D(_MainTex, i.uv);
//color = color * saturate((color-threshhold.x) * 75.0); // didn't go well with HDR and din't make sense
color = color * lerp(1.0, color.a, useSrcAlphaAsMask);
color = max(half4(0,0,0,0), color-threshhold.x);
return color;
}
ENDCG
Subshader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 186c4c0d31e314f049595dcbaf4ca129
ShaderImporter:
userData:
Shader "Hidden/BrightPassFilter2"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
half4 _Threshhold;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 fragScalarThresh(v2f i) : SV_Target
{
half4 color = tex2D(_MainTex, i.uv);
color.rgb = color.rgb;
color.rgb = max(half3(0,0,0), color.rgb-_Threshhold.xxx);
return color;
}
half4 fragColorThresh(v2f i) : SV_Target
{
half4 color = tex2D(_MainTex, i.uv);
color.rgb = max(half3(0,0,0), color.rgb-_Threshhold.rgb);
return color;
}
ENDCG
Subshader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragScalarThresh
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragColorThresh
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 0aeaa4cb29f5d4e9c8455f04c8575c8c
ShaderImporter:
userData:
Shader "Hidden/LensFlareCreate" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv[4] : TEXCOORD0;
};
fixed4 colorA;
fixed4 colorB;
fixed4 colorC;
fixed4 colorD;
sampler2D _MainTex;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = ( ( v.texcoord.xy - 0.5 ) * -0.85 ) + 0.5;
o.uv[1] = ( ( v.texcoord.xy - 0.5 ) * -1.45 ) + 0.5;
o.uv[2] = ( ( v.texcoord.xy - 0.5 ) * -2.55 ) + 0.5;
o.uv[3] = ( ( v.texcoord.xy - 0.5 ) * -4.15 ) + 0.5;
return o;
}
fixed4 frag(v2f i) : SV_Target {
fixed4 color = float4 (0,0,0,0);
color += tex2D(_MainTex, i.uv[0] ) * colorA;
color += tex2D(_MainTex, i.uv[1] ) * colorB;
color += tex2D(_MainTex, i.uv[2] ) * colorC;
color += tex2D(_MainTex, i.uv[3] ) * colorD;
return color;
}
ENDCG
Subshader {
Blend One One
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 459fe69d2f6d74ddb92f04dbf45a866b
ShaderImporter:
userData:
Shader "Hidden/FastBloom" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Bloom ("Bloom (RGB)", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Bloom;
uniform half4 _MainTex_TexelSize;
uniform half4 _Parameter;
uniform half4 _OffsetsA;
uniform half4 _OffsetsB;
#define ONE_MINUS_THRESHHOLD_TIMES_INTENSITY _Parameter.w
#define THRESHHOLD _Parameter.z
struct v2f_simple
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
#if UNITY_UV_STARTS_AT_TOP
half2 uv2 : TEXCOORD1;
#endif
};
v2f_simple vertBloom ( appdata_img v )
{
v2f_simple o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
#if UNITY_UV_STARTS_AT_TOP
o.uv2 = v.texcoord;
if (_MainTex_TexelSize.y < 0.0)
o.uv.y = 1.0 - o.uv.y;
#endif
return o;
}
struct v2f_tap
{
float4 pos : SV_POSITION;
half2 uv20 : TEXCOORD0;
half2 uv21 : TEXCOORD1;
half2 uv22 : TEXCOORD2;
half2 uv23 : TEXCOORD3;
};
v2f_tap vert4Tap ( appdata_img v )
{
v2f_tap o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv20 = v.texcoord + _MainTex_TexelSize.xy;
o.uv21 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,-0.5h);
o.uv22 = v.texcoord + _MainTex_TexelSize.xy * half2(0.5h,-0.5h);
o.uv23 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,0.5h);
return o;
}
fixed4 fragBloom ( v2f_simple i ) : SV_Target
{
#if UNITY_UV_STARTS_AT_TOP
fixed4 color = tex2D(_MainTex, i.uv2);
return color + tex2D(_Bloom, i.uv);
#else
fixed4 color = tex2D(_MainTex, i.uv);
return color + tex2D(_Bloom, i.uv);
#endif
}
fixed4 fragDownsample ( v2f_tap i ) : SV_Target
{
fixed4 color = tex2D (_MainTex, i.uv20);
color += tex2D (_MainTex, i.uv21);
color += tex2D (_MainTex, i.uv22);
color += tex2D (_MainTex, i.uv23);
return max(color/4 - THRESHHOLD, 0) * ONE_MINUS_THRESHHOLD_TIMES_INTENSITY;
}
// weight curves
static const half curve[7] = { 0.0205, 0.0855, 0.232, 0.324, 0.232, 0.0855, 0.0205 }; // gauss'ish blur weights
static const half4 curve4[7] = { half4(0.0205,0.0205,0.0205,0), half4(0.0855,0.0855,0.0855,0), half4(0.232,0.232,0.232,0),
half4(0.324,0.324,0.324,1), half4(0.232,0.232,0.232,0), half4(0.0855,0.0855,0.0855,0), half4(0.0205,0.0205,0.0205,0) };
struct v2f_withBlurCoords8
{
float4 pos : SV_POSITION;
half4 uv : TEXCOORD0;
half2 offs : TEXCOORD1;
};
struct v2f_withBlurCoordsSGX
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 offs[3] : TEXCOORD1;
};
v2f_withBlurCoords8 vertBlurHorizontal (appdata_img v)
{
v2f_withBlurCoords8 o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
o.offs = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
return o;
}
v2f_withBlurCoords8 vertBlurVertical (appdata_img v)
{
v2f_withBlurCoords8 o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
o.offs = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
return o;
}
half4 fragBlur8 ( v2f_withBlurCoords8 i ) : SV_Target
{
half2 uv = i.uv.xy;
half2 netFilterWidth = i.offs;
half2 coords = uv - netFilterWidth * 3.0;
half4 color = 0;
for( int l = 0; l < 7; l++ )
{
half4 tap = tex2D(_MainTex, coords);
color += tap * curve4[l];
coords += netFilterWidth;
}
return color;
}
v2f_withBlurCoordsSGX vertBlurHorizontalSGX (appdata_img v)
{
v2f_withBlurCoordsSGX o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
half2 netFilterWidth = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
half4 coords = -netFilterWidth.xyxy * 3.0;
o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
return o;
}
v2f_withBlurCoordsSGX vertBlurVerticalSGX (appdata_img v)
{
v2f_withBlurCoordsSGX o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
half2 netFilterWidth = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
half4 coords = -netFilterWidth.xyxy * 3.0;
o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
return o;
}
half4 fragBlurSGX ( v2f_withBlurCoordsSGX i ) : SV_Target
{
half2 uv = i.uv.xy;
half4 color = tex2D(_MainTex, i.uv) * curve4[3];
for( int l = 0; l < 3; l++ )
{
half4 tapA = tex2D(_MainTex, i.offs[l].xy);
half4 tapB = tex2D(_MainTex, i.offs[l].zw);
color += (tapA + tapB) * curve4[l];
}
return color;
}
ENDCG
SubShader {
ZTest Off Cull Off ZWrite Off Blend Off
// 0
Pass {
CGPROGRAM
#pragma vertex vertBloom
#pragma fragment fragBloom
ENDCG
}
// 1
Pass {
CGPROGRAM
#pragma vertex vert4Tap
#pragma fragment fragDownsample
ENDCG
}
// 2
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurVertical
#pragma fragment fragBlur8
ENDCG
}
// 3
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurHorizontal
#pragma fragment fragBlur8
ENDCG
}
// alternate blur
// 4
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurVerticalSGX
#pragma fragment fragBlurSGX
ENDCG
}
// 5
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurHorizontalSGX
#pragma fragment fragBlurSGX
ENDCG
}
}
FallBack Off
}
fileFormatVersion: 2
guid: 68a00c837b82e4c6d92e7da765dc5f1d
ShaderImporter:
userData:
Shader "Hidden/FastBlur" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Bloom ("Bloom (RGB)", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Bloom;
uniform half4 _MainTex_TexelSize;
uniform half4 _Parameter;
struct v2f_tap
{
float4 pos : SV_POSITION;
half2 uv20 : TEXCOORD0;
half2 uv21 : TEXCOORD1;
half2 uv22 : TEXCOORD2;
half2 uv23 : TEXCOORD3;
};
v2f_tap vert4Tap ( appdata_img v )
{
v2f_tap o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv20 = v.texcoord + _MainTex_TexelSize.xy;
o.uv21 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,-0.5h);
o.uv22 = v.texcoord + _MainTex_TexelSize.xy * half2(0.5h,-0.5h);
o.uv23 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,0.5h);
return o;
}
fixed4 fragDownsample ( v2f_tap i ) : SV_Target
{
fixed4 color = tex2D (_MainTex, i.uv20);
color += tex2D (_MainTex, i.uv21);
color += tex2D (_MainTex, i.uv22);
color += tex2D (_MainTex, i.uv23);
return color / 4;
}
// weight curves
static const half curve[7] = { 0.0205, 0.0855, 0.232, 0.324, 0.232, 0.0855, 0.0205 }; // gauss'ish blur weights
static const half4 curve4[7] = { half4(0.0205,0.0205,0.0205,0), half4(0.0855,0.0855,0.0855,0), half4(0.232,0.232,0.232,0),
half4(0.324,0.324,0.324,1), half4(0.232,0.232,0.232,0), half4(0.0855,0.0855,0.0855,0), half4(0.0205,0.0205,0.0205,0) };
struct v2f_withBlurCoords8
{
float4 pos : SV_POSITION;
half4 uv : TEXCOORD0;
half2 offs : TEXCOORD1;
};
struct v2f_withBlurCoordsSGX
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 offs[3] : TEXCOORD1;
};
v2f_withBlurCoords8 vertBlurHorizontal (appdata_img v)
{
v2f_withBlurCoords8 o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
o.offs = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
return o;
}
v2f_withBlurCoords8 vertBlurVertical (appdata_img v)
{
v2f_withBlurCoords8 o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
o.offs = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
return o;
}
half4 fragBlur8 ( v2f_withBlurCoords8 i ) : SV_Target
{
half2 uv = i.uv.xy;
half2 netFilterWidth = i.offs;
half2 coords = uv - netFilterWidth * 3.0;
half4 color = 0;
for( int l = 0; l < 7; l++ )
{
half4 tap = tex2D(_MainTex, coords);
color += tap * curve4[l];
coords += netFilterWidth;
}
return color;
}
v2f_withBlurCoordsSGX vertBlurHorizontalSGX (appdata_img v)
{
v2f_withBlurCoordsSGX o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
half2 netFilterWidth = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
half4 coords = -netFilterWidth.xyxy * 3.0;
o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
return o;
}
v2f_withBlurCoordsSGX vertBlurVerticalSGX (appdata_img v)
{
v2f_withBlurCoordsSGX o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = half4(v.texcoord.xy,1,1);
half2 netFilterWidth = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
half4 coords = -netFilterWidth.xyxy * 3.0;
o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
coords += netFilterWidth.xyxy;
o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
return o;
}
half4 fragBlurSGX ( v2f_withBlurCoordsSGX i ) : SV_Target
{
half2 uv = i.uv.xy;
half4 color = tex2D(_MainTex, i.uv) * curve4[3];
for( int l = 0; l < 3; l++ )
{
half4 tapA = tex2D(_MainTex, i.offs[l].xy);
half4 tapB = tex2D(_MainTex, i.offs[l].zw);
color += (tapA + tapB) * curve4[l];
}
return color;
}
ENDCG
SubShader {
ZTest Off Cull Off ZWrite Off Blend Off
// 0
Pass {
CGPROGRAM
#pragma vertex vert4Tap
#pragma fragment fragDownsample
ENDCG
}
// 1
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurVertical
#pragma fragment fragBlur8
ENDCG
}
// 2
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurHorizontal
#pragma fragment fragBlur8
ENDCG
}
// alternate blur
// 3
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurVerticalSGX
#pragma fragment fragBlurSGX
ENDCG
}
// 4
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurHorizontalSGX
#pragma fragment fragBlurSGX
ENDCG
}
}
FallBack Off
}
fileFormatVersion: 2
guid: f9d5fa183cd6b45eeb1491f74863cd91
ShaderImporter:
userData:
Shader "Hidden/MultipassHollywoodFlares" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_NonBlurredTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
struct v2f_opts {
half4 pos : SV_POSITION;
half2 uv[7] : TEXCOORD0;
};
half4 offsets;
half4 tintColor;
half stretchWidth;
half2 _Threshhold;
half4 _MainTex_TexelSize;
sampler2D _MainTex;
sampler2D _NonBlurredTex;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
v2f_opts vertStretch (appdata_img v) {
v2f_opts o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
half b = stretchWidth;
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy + b * 2.0 * offsets.xy;
o.uv[2] = v.texcoord.xy - b * 2.0 * offsets.xy;
o.uv[3] = v.texcoord.xy + b * 4.0 * offsets.xy;
o.uv[4] = v.texcoord.xy - b * 4.0 * offsets.xy;
o.uv[5] = v.texcoord.xy + b * 6.0 * offsets.xy;
o.uv[6] = v.texcoord.xy - b * 6.0 * offsets.xy;
return o;
}
v2f_opts vertVerticalCoords (appdata_img v) {
v2f_opts o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv[0] = v.texcoord.xy;
o.uv[1] = v.texcoord.xy + 0.5 * _MainTex_TexelSize.xy * half2(0,1);
o.uv[2] = v.texcoord.xy - 0.5 * _MainTex_TexelSize.xy * half2(0,1);
o.uv[3] = v.texcoord.xy + 1.5 * _MainTex_TexelSize.xy * half2(0,1);
o.uv[4] = v.texcoord.xy - 1.5 * _MainTex_TexelSize.xy * half2(0,1);
o.uv[5] = v.texcoord.xy + 2.5 * _MainTex_TexelSize.xy * half2(0,1);
o.uv[6] = v.texcoord.xy - 2.5 * _MainTex_TexelSize.xy * half2(0,1);
return o;
}
// deprecated
half4 fragPrepare (v2f i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv);
half4 colorNb = tex2D (_NonBlurredTex, i.uv);
return color * tintColor * 0.5 + colorNb * normalize (tintColor) * 0.5;
}
half4 fragPreAndCut (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color += tex2D (_MainTex, i.uv[1]);
color += tex2D (_MainTex, i.uv[2]);
color += tex2D (_MainTex, i.uv[3]);
color += tex2D (_MainTex, i.uv[4]);
color += tex2D (_MainTex, i.uv[5]);
color += tex2D (_MainTex, i.uv[6]);
return max(color / 7.0 - _Threshhold.x, 0.0) * _Threshhold.y * tintColor;
}
half4 fragStretch (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color = max (color, tex2D (_MainTex, i.uv[1]));
color = max (color, tex2D (_MainTex, i.uv[2]));
color = max (color, tex2D (_MainTex, i.uv[3]));
color = max (color, tex2D (_MainTex, i.uv[4]));
color = max (color, tex2D (_MainTex, i.uv[5]));
color = max (color, tex2D (_MainTex, i.uv[6]));
return color;
}
half4 fragPost (v2f_opts i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv[0]);
color += tex2D (_MainTex, i.uv[1]);
color += tex2D (_MainTex, i.uv[2]);
color += tex2D (_MainTex, i.uv[3]);
color += tex2D (_MainTex, i.uv[4]);
color += tex2D (_MainTex, i.uv[5]);
color += tex2D (_MainTex, i.uv[6]);
return color * 1.0/(7.0 + Luminance(color.rgb) + 0.5); // this also makes it a little noisy
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragPrepare
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vertStretch
#pragma fragment fragStretch
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vertVerticalCoords
#pragma fragment fragPreAndCut
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vertVerticalCoords
#pragma fragment fragPost
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: e2baf3cae8edc4daf94c9adc2154be00
ShaderImporter:
userData:
Shader "Hidden/SeparableBlurPlus" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 uv01 : TEXCOORD1;
half4 uv23 : TEXCOORD2;
half4 uv45 : TEXCOORD3;
half4 uv67 : TEXCOORD4;
};
half4 offsets;
sampler2D _MainTex;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1);
o.uv23 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 2.0;
o.uv45 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 3.0;
o.uv67 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 4.5;
o.uv67 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 6.5;
return o;
}
half4 frag (v2f i) : SV_Target {
half4 color = half4 (0,0,0,0);
color += 0.225 * tex2D (_MainTex, i.uv);
color += 0.150 * tex2D (_MainTex, i.uv01.xy);
color += 0.150 * tex2D (_MainTex, i.uv01.zw);
color += 0.110 * tex2D (_MainTex, i.uv23.xy);
color += 0.110 * tex2D (_MainTex, i.uv23.zw);
color += 0.075 * tex2D (_MainTex, i.uv45.xy);
color += 0.075 * tex2D (_MainTex, i.uv45.zw);
color += 0.0525 * tex2D (_MainTex, i.uv67.xy);
color += 0.0525 * tex2D (_MainTex, i.uv67.zw);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: a9df009a214e24a5ebbf271595f8d5b6
ShaderImporter:
userData:
Shader "Hidden/VignetteShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float vignetteIntensity;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
half4 frag(v2f i) : SV_Target {
half2 coords = i.uv;
half2 uv = i.uv;
coords = (coords - 0.5) * 2.0;
half coordDot = dot (coords,coords);
half4 color = tex2D (_MainTex, uv);
float mask = 1.0 - coordDot * vignetteIntensity;
return color * mask;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: 562f620336e024ac99992ff05725a89a
ShaderImporter:
userData:
fileFormatVersion: 2
guid: d9cccf980fcb7441d85b8b3b5c2d2c34
folderAsset: yes
timeCreated: 1433531211
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
Shader "Hidden/Dof/Bokeh34" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Source ("Base (RGB)", 2D) = "black" {}
}
SubShader {
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Source;
uniform half4 _ArScale;
uniform half _Intensity;
uniform half4 _Source_TexelSize;
struct v2f {
half4 pos : SV_POSITION;
half2 uv2 : TEXCOORD0;
half4 source : TEXCOORD1;
};
#define COC bokeh.a
v2f vert (appdata_full v)
{
v2f o;
o.pos = v.vertex;
o.uv2.xy = v.texcoord.xy;// * 2.0; <- needed when using Triangles.js and not Quads.js
#if UNITY_UV_STARTS_AT_TOP
float4 bokeh = tex2Dlod (_Source, half4 (v.texcoord1.xy * half2(1,-1) + half2(0,1), 0, 0));
#else
float4 bokeh = tex2Dlod (_Source, half4 (v.texcoord1.xy, 0, 0));
#endif
o.source = bokeh;
o.pos.xy += (v.texcoord.xy * 2.0 - 1.0) * _ArScale.xy * COC;// + _ArScale.zw * coc;
o.source.rgb *= _Intensity;
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 color = tex2D (_MainTex, i.uv2.xy);
color.rgb *= i.source.rgb;
color.a *= Luminance(i.source.rgb*0.25);
return color;
}
ENDCG
Pass {
Blend OneMinusDstColor One
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 57cdacf9b217546aaa18edf39a6151c0
ShaderImporter:
userData:
Shader "Hidden/Dof/DepthOfField34" {
Properties {
_MainTex ("Base", 2D) = "" {}
_TapLowBackground ("TapLowBackground", 2D) = "" {}
_TapLowForeground ("TapLowForeground", 2D) = "" {}
_TapMedium ("TapMedium", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
half4 pos : SV_POSITION;
half2 uv1 : TEXCOORD0;
};
struct v2fDofApply {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
struct v2fRadius {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 uv1[4] : TEXCOORD1;
};
struct v2fDown {
half4 pos : SV_POSITION;
half2 uv0 : TEXCOORD0;
half2 uv[2] : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
sampler2D _TapLowBackground;
sampler2D _TapLowForeground;
sampler2D _TapMedium;
half4 _CurveParams;
half _ForegroundBlurExtrude;
uniform half3 _Threshhold;
uniform float4 _MainTex_TexelSize;
uniform float2 _InvRenderTargetSize;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv1.xy = v.texcoord.xy;
return o;
}
v2fRadius vertWithRadius( appdata_img v ) {
v2fRadius o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
const half2 blurOffsets[4] = {
half2(-0.5, +1.5),
half2(+0.5, -1.5),
half2(+1.5, +0.5),
half2(-1.5, -0.5)
};
o.uv1[0].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[0];
o.uv1[1].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[1];
o.uv1[2].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[2];
o.uv1[3].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[3];
o.uv1[0].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[0];
o.uv1[1].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[1];
o.uv1[2].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[2];
o.uv1[3].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[3];
return o;
}
v2fDofApply vertDofApply( appdata_img v ) {
v2fDofApply o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
return o;
}
v2fDown vertDownsampleWithCocConserve(appdata_img v) {
v2fDown o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv0.xy = v.texcoord.xy;
o.uv[0].xy = v.texcoord.xy + half2(-1.0,-1.0) * _InvRenderTargetSize;
o.uv[1].xy = v.texcoord.xy + half2(1.0,-1.0) * _InvRenderTargetSize;
return o;
}
half4 BokehPrereqs (sampler2D tex, half4 uv1[4], half4 center, half considerCoc) {
// @NOTE 1:
// we are checking for 3 things in order to create a bokeh.
// goal is to get the highest bang for the buck.
// 1.) contrast/frequency should be very high (otherwise bokeh mostly unvisible)
// 2.) luminance should be high
// 3.) no occluder nearby (stored in alpha channel)
// @NOTE 2: about the alpha channel in littleBlur:
// the alpha channel stores an heuristic on how likely it is
// that there is no bokeh occluder nearby.
// if we didn't' check for that, we'd get very noise bokeh
// popping because of the sudden contrast changes
half4 sampleA = tex2D(tex, uv1[0].zw);
half4 sampleB = tex2D(tex, uv1[1].zw);
half4 sampleC = tex2D(tex, uv1[2].zw);
half4 sampleD = tex2D(tex, uv1[3].zw);
half4 littleBlur = 0.125 * (sampleA + sampleB + sampleC + sampleD);
sampleA = tex2D(tex, uv1[0].xy);
sampleB = tex2D(tex, uv1[1].xy);
sampleC = tex2D(tex, uv1[2].xy);
sampleD = tex2D(tex, uv1[3].xy);
littleBlur += 0.125 * (sampleA + sampleB + sampleC + sampleD);
littleBlur = lerp (littleBlur, center, saturate(100.0 * considerCoc * abs(littleBlur.a - center.a)));
return littleBlur;
}
half4 fragDownsampleWithCocConserve(v2fDown i) : SV_Target {
half2 rowOfs[4];
rowOfs[0] = half2(0.0, 0.0);
rowOfs[1] = half2(0.0, _InvRenderTargetSize.y);
rowOfs[2] = half2(0.0, _InvRenderTargetSize.y) * 2.0;
rowOfs[3] = half2(0.0, _InvRenderTargetSize.y) * 3.0;
half4 color = tex2D(_MainTex, i.uv0.xy);
half4 sampleA = tex2D(_MainTex, i.uv[0].xy + rowOfs[0]);
half4 sampleB = tex2D(_MainTex, i.uv[1].xy + rowOfs[0]);
half4 sampleC = tex2D(_MainTex, i.uv[0].xy + rowOfs[2]);
half4 sampleD = tex2D(_MainTex, i.uv[1].xy + rowOfs[2]);
color += sampleA + sampleB + sampleC + sampleD;
color *= 0.2;
// @NOTE we are doing max on the alpha channel for 2 reasons:
// 1) foreground blur likes a slightly bigger radius
// 2) otherwise we get an ugly outline between high blur- and medium blur-areas
// drawback: we get a little bit of color bleeding
color.a = max(max(sampleA.a, sampleB.a), max(sampleC.a, sampleD.a));
return color;
}
half4 fragDofApplyBg (v2fDofApply i) : SV_Target {
half4 tapHigh = tex2D (_MainTex, i.uv.xy);
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
i.uv.xy = i.uv.xy * half2(1,-1)+half2(0,1);
#endif
half4 tapLow = tex2D (_TapLowBackground, i.uv.xy); // already mixed with medium blur
tapHigh = lerp (tapHigh, tapLow, tapHigh.a);
return tapHigh;
}
half4 fragDofApplyBgDebug (v2fDofApply i) : SV_Target {
half4 tapHigh = tex2D (_MainTex, i.uv.xy);
half4 tapLow = tex2D (_TapLowBackground, i.uv.xy);
half4 tapMedium = tex2D (_TapMedium, i.uv.xy);
tapMedium.rgb = (tapMedium.rgb + half3 (1, 1, 0)) * 0.5;
tapLow.rgb = (tapLow.rgb + half3 (0, 1, 0)) * 0.5;
tapLow = lerp (tapMedium, tapLow, saturate (tapLow.a * tapLow.a));
tapLow = tapLow * 0.5 + tex2D (_TapLowBackground, i.uv.xy) * 0.5;
return lerp (tapHigh, tapLow, tapHigh.a);
}
half4 fragDofApplyFg (v2fDofApply i) : SV_Target {
half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
i.uv.xy = i.uv.xy * half2(1,-1)+half2(0,1);
#endif
half4 fgColor = tex2D(_MainTex,i.uv.xy);
//fgBlur.a = saturate(fgBlur.a*_ForegroundBlurWeight+saturate(fgColor.a-fgBlur.a));
//fgBlur.a = max (fgColor.a, (2.0 * fgBlur.a - fgColor.a)) * _ForegroundBlurExtrude;
fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude); //max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
return lerp (fgColor, fgBlur, saturate(fgBlur.a));
}
half4 fragDofApplyFgDebug (v2fDofApply i) : SV_Target {
half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
half4 fgColor = tex2D(_MainTex,i.uv.xy);
fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude); //max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
half4 tapMedium = half4 (1, 1, 0, fgBlur.a);
tapMedium.rgb = 0.5 * (tapMedium.rgb + fgColor.rgb);
fgBlur.rgb = 0.5 * (fgBlur.rgb + half3(0,1,0));
fgBlur.rgb = lerp (tapMedium.rgb, fgBlur.rgb, saturate (fgBlur.a * fgBlur.a));
return lerp ( fgColor, fgBlur, saturate(fgBlur.a));
}
half4 fragCocBg (v2f i) : SV_Target {
float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
half coc = 0.0;
half focalDistance01 = _CurveParams.w + _CurveParams.z;
if (d > focalDistance01)
coc = (d - focalDistance01);
coc = saturate (coc * _CurveParams.y);
return coc;
}
half4 fragCocFg (v2f i) : SV_Target {
half4 color = tex2D (_MainTex, i.uv1.xy);
color.a = 0.0;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
i.uv1.xy = i.uv1.xy * half2(1,-1)+half2(0,1);
#endif
float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
half focalDistance01 = (_CurveParams.w - _CurveParams.z);
if (d < focalDistance01)
color.a = (focalDistance01 - d);
color.a = saturate (color.a * _CurveParams.x);
return color;
}
// not being used atm
half4 fragMask (v2f i) : SV_Target {
return half4(0,0,0,0);
}
// used for simple one one blend
half4 fragAddBokeh (v2f i) : SV_Target {
half4 from = tex2D( _MainTex, i.uv1.xy );
return from;
}
half4 fragAddFgBokeh (v2f i) : SV_Target {
half4 from = tex2D( _MainTex, i.uv1.xy );
return from;
}
half4 fragDarkenForBokeh(v2fRadius i) : SV_Target {
half4 fromOriginal = tex2D(_MainTex, i.uv.xy);
half4 lowRez = BokehPrereqs (_MainTex, i.uv1, fromOriginal, _Threshhold.z);
half4 outColor = half4(0,0,0, fromOriginal.a);
half modulate = fromOriginal.a;
// this code imitates the if-then-else conditions below
half2 conditionCheck = half2( dot(abs(fromOriginal.rgb-lowRez.rgb), half3(0.3,0.5,0.2)), Luminance(fromOriginal.rgb));
conditionCheck *= fromOriginal.a;
conditionCheck = saturate(_Threshhold.xy - conditionCheck);
outColor = lerp (outColor, fromOriginal, saturate (dot(conditionCheck, half2(1000.0,1000.0))));
/*
if ( abs(dot(fromOriginal.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
outColor = fromOriginal; // no darkening
if (Luminance(fromOriginal.rgb) * modulate < _Threshhold.y)
outColor = fromOriginal; // no darkening
if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
outColor = fromOriginal; // no darkenin
*/
return outColor;
}
half4 fragExtractAndAddToBokeh (v2fRadius i) : SV_Target {
half4 from = tex2D(_MainTex, i.uv.xy);
half4 lowRez = BokehPrereqs(_MainTex, i.uv1, from, _Threshhold.z);
half4 outColor = from;
// this code imitates the if-then-else conditions below
half2 conditionCheck = half2( dot(abs(from.rgb-lowRez.rgb), half3(0.3,0.5,0.2)), Luminance(from.rgb));
conditionCheck *= from.a;
conditionCheck = saturate(_Threshhold.xy - conditionCheck);
outColor = lerp (outColor, half4(0,0,0,0), saturate (dot(conditionCheck, half2(1000.0,1000.0))));
/*
if ( abs(dot(from.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
outColor = half4(0,0,0,0); // don't add
if (Luminance(from.rgb) * modulate < _Threshhold.y)
outColor = half4(0,0,0,0); // don't add
if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
outColor = half4(0,0,0,0); // don't add
*/
return outColor;
}
ENDCG
Subshader {
// pass 0
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertDofApply
#pragma fragment fragDofApplyBg
ENDCG
}
// pass 1
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask RGB
CGPROGRAM
#pragma vertex vertDofApply
#pragma fragment fragDofApplyFgDebug
ENDCG
}
// pass 2
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask RGB
CGPROGRAM
#pragma vertex vertDofApply
#pragma fragment fragDofApplyBgDebug
ENDCG
}
// pass 3
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask A
CGPROGRAM
#pragma vertex vert
#pragma fragment fragCocBg
ENDCG
}
// pass 4
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask RGB
//Blend One One
CGPROGRAM
#pragma vertex vertDofApply
#pragma fragment fragDofApplyFg
ENDCG
}
// pass 5
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask ARGB
CGPROGRAM
#pragma vertex vert
#pragma fragment fragCocFg
ENDCG
}
// pass 6
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertDownsampleWithCocConserve
#pragma fragment fragDownsampleWithCocConserve
ENDCG
}
// pass 7
// not being used atm
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask RGBA
CGPROGRAM
#pragma vertex vert
#pragma fragment fragMask
ENDCG
}
// pass 8
Pass {
ZTest Always Cull Off ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
CGPROGRAM
#pragma vertex vert
#pragma fragment fragAddBokeh
ENDCG
}
// pass 9
Pass {
ZTest Always Cull Off ZWrite Off
Blend One One
ColorMask RGB
CGPROGRAM
#pragma vertex vertWithRadius
#pragma fragment fragExtractAndAddToBokeh
ENDCG
}
// pass 10
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertWithRadius
#pragma fragment fragDarkenForBokeh
ENDCG
}
// pass 11
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vertWithRadius
#pragma fragment fragExtractAndAddToBokeh
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: 987fb0677d01f43ce8a9dbf12271e668
ShaderImporter:
userData:
/*
DX11 Depth Of Field
pretty much just does bokeh texture splatting
basic algorithm:
* find bright spots
* verify high frequency (otherwise dont care)
* if possitive, replace with black pixel and add to append buffer
* box blur buffer (thus smearing black pixels)
* blend bokeh texture sprites via append buffer on top of box blurred buffer
* composite with frame buffer
*/
Shader "Hidden/Dof/DX11Dof"
{
Properties
{
_MainTex ("", 2D) = "white" {}
_BlurredColor ("", 2D) = "white" {}
_FgCocMask ("", 2D) = "white" {}
}
CGINCLUDE
#define BOKEH_ZERO_VEC (float4(0,0,0,0))
#define BOKEH_ONE_VEC (float4(1,1,1,1))
float4 _BokehParams; // legend: dx11BokehScale, dx11BokehIntensity,dx11BokehThreshhold, internalBlurWidth
float4 _MainTex_TexelSize;
float3 _Screen;
float _SpawnHeuristic;
sampler2D_float _CameraDepthTexture;
sampler2D _BlurredColor;
sampler2D _MainTex;
sampler2D _FgCocMask;
struct appendStruct {
float3 pos;
float4 color;
};
struct gs_out {
float4 pos : SV_POSITION;
float3 uv : TEXCOORD0;
float4 color : TEXCOORD1;
float4 misc : TEXCOORD2;
};
// TODO: activate border clamp tex sampler state instead?
inline float4 clampBorderColor(float2 uv)
{
#if 1
if(uv.x<=0) return BOKEH_ZERO_VEC; if(uv.x>=1) return BOKEH_ZERO_VEC;
if(uv.y<=0) return BOKEH_ZERO_VEC; if(uv.y>=1) return BOKEH_ZERO_VEC;
#endif
return BOKEH_ONE_VEC;
}
struct vs_out {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 color : TEXCOORD1;
float cocOverlap : TEXCOORD2;
};
StructuredBuffer<appendStruct> pointBuffer;
vs_out vertApply (uint id : SV_VertexID)
{
vs_out o;
float2 pos = pointBuffer[id].pos.xy ;
o.pos = float4(pos * 2.0 - 1.0, 0, 1);
o.color = pointBuffer[id].color;
#if UNITY_UV_STARTS_AT_TOP
o.pos.y *= -1;
#endif
o.cocOverlap = pointBuffer[id].pos.z;
return o;
}
[maxvertexcount(4)]
void geom (point vs_out input[1], inout TriangleStream<gs_out> outStream)
{
// NEW ENERGY CONSERVATION:
float2 scale2 = _BokehParams.ww * input[0].color.aa * _BokehParams.xx;
float4 offs = 0;
offs.xy = float2(3.0, 3.0) + 2.0f * floor(scale2 + float2(0.5,0.5));
float2 rs = ((float2(1.0, 1.0) + 2.0f * (scale2 + float2(0.5,0.5))));;
float2 f2 = offs.xy / rs;
float energyAdjustment = (_BokehParams.y) / (rs.x*rs.y);
offs.xy *= _Screen.xy;
gs_out output;
output.pos = input[0].pos + offs*float4(-1,1,0,0);
output.misc = float4(f2,0,0);
output.uv = float3(0, 1, input[0].cocOverlap);
output.color = input[0].color * energyAdjustment;
outStream.Append (output);
output.pos = input[0].pos + offs*float4(1,1,0,0);
output.misc = float4(f2,0,0);
output.uv = float3(1, 1, input[0].cocOverlap);
output.color = input[0].color * energyAdjustment;
outStream.Append (output);
output.pos = input[0].pos + offs*float4(-1,-1,0,0);
output.misc = float4(f2,0,0);
output.uv = float3(0, 0, input[0].cocOverlap);
output.color = input[0].color * energyAdjustment;
outStream.Append (output);
output.pos = input[0].pos + offs*float4(1,-1,0,0);
output.misc = float4(f2,0,0);
output.uv = float3(1, 0, input[0].cocOverlap);
output.color = input[0].color * energyAdjustment;
outStream.Append (output);
outStream.RestartStrip();
}
ENDCG
SubShader
{
// pass 0: append buffer "collect"
Pass
{
ZWrite Off ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 5.0
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv_flip : TEXCOORD0;
float2 uv : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.uv_flip = v.texcoord;
#if UNITY_UV_STARTS_AT_TOP
if(_MainTex_TexelSize.y<0)
o.uv_flip.y = 1.0-o.uv_flip.y;
if(_MainTex_TexelSize.y<0)
o.pos.y *= -1.0;
#endif
return o;
}
AppendStructuredBuffer<appendStruct> pointBufferOutput : register(u1);
float4 frag (v2f i) : SV_Target
{
float4 c = tex2D (_MainTex, i.uv_flip);
float lumc = Luminance (c.rgb);
float4 cblurred = tex2D (_BlurredColor, i.uv);
float lumblurred = Luminance (cblurred.rgb);
float fgCoc = tex2D(_FgCocMask, i.uv).a;
[branch]
if (c.a * _BokehParams.w > 1 && cblurred.a > 0.1 && lumc > _BokehParams.z && abs(lumc-lumblurred) > _SpawnHeuristic)
{
appendStruct append;
append.pos = float3(i.uv, fgCoc);
append.color.rgba = float4(c.rgb * saturate(c.a*4), c.a);
pointBufferOutput.Append (append);
return float4(c.rgb * saturate(1-c.a*4), c.a);
}
return c;
}
ENDCG
}
// pass 1: bokeh splatting (low resolution)
Pass {
ZWrite Off ZTest Always Cull Off
Blend One One, One One
ColorMask RGBA
CGPROGRAM
#pragma target 5.0
#pragma vertex vertApply
#pragma geometry geom
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 frag (gs_out i) : SV_Target
{
float2 uv = (i.uv.xy) * i.misc.xy + (float2(1,1)-i.misc.xy) * 0.5; // smooth uv scale
return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
}
ENDCG
}
// pass 2: bokeh splatting (high resolution)
Pass {
ZWrite Off ZTest Always Cull Off
BlendOp Add, Add
Blend DstAlpha One, Zero One
ColorMask RGBA
CGPROGRAM
#pragma target 5.0
#pragma vertex vertApply
#pragma geometry geom
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 frag (gs_out i) : SV_Target
{
float2 uv = (i.uv.xy) * i.misc.xy + (float2(1,1)-i.misc.xy) * 0.5; // smooth uv scale
return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
}
ENDCG
}
}
Fallback Off
}
fileFormatVersion: 2
guid: d8e82664aa8686642a424c88ab10164a
ShaderImporter:
userData:
Shader "Hidden/Dof/DepthOfFieldHdr" {
Properties {
_MainTex ("-", 2D) = "black" {}
_FgOverlap ("-", 2D) = "black" {}
_LowRez ("-", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
};
struct v2fRadius {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 uv1[4] : TEXCOORD1;
};
struct v2fBlur {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 uv01 : TEXCOORD1;
float4 uv23 : TEXCOORD2;
float4 uv45 : TEXCOORD3;
float4 uv67 : TEXCOORD4;
float4 uv89 : TEXCOORD5;
};
uniform sampler2D _MainTex;
uniform sampler2D_float _CameraDepthTexture;
uniform sampler2D _FgOverlap;
uniform sampler2D _LowRez;
uniform float4 _CurveParams;
uniform float4 _MainTex_TexelSize;
uniform float4 _Offsets;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv1.xy = v.texcoord.xy;
o.uv.xy = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y = 1-o.uv.y;
#endif
return o;
}
v2f vertFlip( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv1.xy = v.texcoord.xy;
o.uv.xy = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y = 1-o.uv.y;
if (_MainTex_TexelSize.y < 0)
o.uv1.y = 1-o.uv1.y;
#endif
return o;
}
v2fBlur vertBlurPlusMinus (appdata_img v)
{
v2fBlur o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + _Offsets.xyxy * float4(1,1, -1,-1) * _MainTex_TexelSize.xyxy / 6.0;
o.uv23 = v.texcoord.xyxy + _Offsets.xyxy * float4(2,2, -2,-2) * _MainTex_TexelSize.xyxy / 6.0;
o.uv45 = v.texcoord.xyxy + _Offsets.xyxy * float4(3,3, -3,-3) * _MainTex_TexelSize.xyxy / 6.0;
o.uv67 = v.texcoord.xyxy + _Offsets.xyxy * float4(4,4, -4,-4) * _MainTex_TexelSize.xyxy / 6.0;
o.uv89 = v.texcoord.xyxy + _Offsets.xyxy * float4(5,5, -5,-5) * _MainTex_TexelSize.xyxy / 6.0;
return o;
}
#define SCATTER_OVERLAP_SMOOTH (-0.265)
inline float BokehWeightDisc(float4 theSample, float sampleDistance, float4 centerSample)
{
return smoothstep(SCATTER_OVERLAP_SMOOTH, 0.0, theSample.a - centerSample.a*sampleDistance);
}
inline float2 BokehWeightDisc2(float4 sampleA, float4 sampleB, float2 sampleDistance2, float4 centerSample)
{
return smoothstep(float2(SCATTER_OVERLAP_SMOOTH, SCATTER_OVERLAP_SMOOTH), float2(0.0,0.0), float2(sampleA.a, sampleB.a) - centerSample.aa*sampleDistance2); }
static const int SmallDiscKernelSamples = 12;
static const float2 SmallDiscKernel[SmallDiscKernelSamples] =
{
float2(-0.326212,-0.40581),
float2(-0.840144,-0.07358),
float2(-0.695914,0.457137),
float2(-0.203345,0.620716),
float2(0.96234,-0.194983),
float2(0.473434,-0.480026),
float2(0.519456,0.767022),
float2(0.185461,-0.893124),
float2(0.507431,0.064425),
float2(0.89642,0.412458),
float2(-0.32194,-0.932615),
float2(-0.791559,-0.59771)
};
static const int NumDiscSamples = 28;
static const float3 DiscKernel[NumDiscSamples] =
{
float3(0.62463,0.54337,0.82790),
float3(-0.13414,-0.94488,0.95435),
float3(0.38772,-0.43475,0.58253),
float3(0.12126,-0.19282,0.22778),
float3(-0.20388,0.11133,0.23230),
float3(0.83114,-0.29218,0.88100),
float3(0.10759,-0.57839,0.58831),
float3(0.28285,0.79036,0.83945),
float3(-0.36622,0.39516,0.53876),
float3(0.75591,0.21916,0.78704),
float3(-0.52610,0.02386,0.52664),
float3(-0.88216,-0.24471,0.91547),
float3(-0.48888,-0.29330,0.57011),
float3(0.44014,-0.08558,0.44838),
float3(0.21179,0.51373,0.55567),
float3(0.05483,0.95701,0.95858),
float3(-0.59001,-0.70509,0.91938),
float3(-0.80065,0.24631,0.83768),
float3(-0.19424,-0.18402,0.26757),
float3(-0.43667,0.76751,0.88304),
float3(0.21666,0.11602,0.24577),
float3(0.15696,-0.85600,0.87027),
float3(-0.75821,0.58363,0.95682),
float3(0.99284,-0.02904,0.99327),
float3(-0.22234,-0.57907,0.62029),
float3(0.55052,-0.66984,0.86704),
float3(0.46431,0.28115,0.54280),
float3(-0.07214,0.60554,0.60982),
};
float4 fragBlurInsaneMQ (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
float4 sum = centerTap;
float4 poissonScale = _MainTex_TexelSize.xyxy * centerTap.a * _Offsets.w;
float sampleCount = max(centerTap.a * 0.25, _Offsets.z); // <- weighing with 0.25 looks nicer for small high freq spec
sum *= sampleCount;
float weights = 0;
for(int l=0; l < NumDiscSamples; l++)
{
float2 sampleUV = i.uv1.xy + DiscKernel[l].xy * poissonScale.xy;
float4 sample0 = tex2D(_MainTex, sampleUV.xy);
if( sample0.a > 0.0 )
{
weights = BokehWeightDisc(sample0, DiscKernel[l].z, centerTap);
sum += sample0 * weights;
sampleCount += weights;
}
}
float4 returnValue = sum / sampleCount;
returnValue.a = centerTap.a;
return returnValue;
}
float4 fragBlurInsaneHQ (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
float4 sum = centerTap;
float4 poissonScale = _MainTex_TexelSize.xyxy * centerTap.a * _Offsets.w;
float sampleCount = max(centerTap.a * 0.25, _Offsets.z); // <- weighing with 0.25 looks nicer for small high freq spec
sum *= sampleCount;
float2 weights = 0;
for(int l=0; l < NumDiscSamples; l++)
{
float4 sampleUV = i.uv1.xyxy + DiscKernel[l].xyxy * poissonScale.xyxy / float4(1.2,1.2,DiscKernel[l].zz);
float4 sample0 = tex2D(_MainTex, sampleUV.xy);
float4 sample1 = tex2D(_MainTex, sampleUV.zw);
if( (sample0.a + sample1.a) > 0.0 )
{
weights = BokehWeightDisc2(sample0, sample1, float2(DiscKernel[l].z/1.2, 1.0), centerTap);
sum += sample0 * weights.x + sample1 * weights.y;
sampleCount += dot(weights, 1);
}
}
float4 returnValue = sum / sampleCount;
returnValue.a = centerTap.a;
return returnValue;
}
inline float4 BlendLowWithHighHQ(float coc, float4 low, float4 high)
{
float blend = smoothstep(0.65,0.85, coc);
return lerp(low, high, blend);
}
inline float4 BlendLowWithHighMQ(float coc, float4 low, float4 high)
{
float blend = smoothstep(0.4,0.6, coc);
return lerp(low, high, blend);
}
float4 fragBlurUpsampleCombineHQ (v2f i) : SV_Target
{
float4 bigBlur = tex2D(_LowRez, i.uv1.xy);
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
float4 smallBlur = centerTap;
float4 poissonScale = _MainTex_TexelSize.xyxy * centerTap.a * _Offsets.w ;
float sampleCount = max(centerTap.a * 0.25, 0.1f); // <- weighing with 0.25 looks nicer for small high freq spec
smallBlur *= sampleCount;
for(int l=0; l < NumDiscSamples; l++)
{
float2 sampleUV = i.uv1.xy + DiscKernel[l].xy * poissonScale.xy;
float4 sample0 = tex2D(_MainTex, sampleUV);
float weight0 = BokehWeightDisc(sample0, DiscKernel[l].z, centerTap);
smallBlur += sample0 * weight0; sampleCount += weight0;
}
smallBlur /= (sampleCount+1e-5f);
smallBlur = BlendLowWithHighHQ(centerTap.a, smallBlur, bigBlur);
return centerTap.a < 1e-2f ? centerTap : float4(smallBlur.rgb,centerTap.a);
}
float4 fragBlurUpsampleCombineMQ (v2f i) : SV_Target
{
float4 bigBlur = tex2D(_LowRez, i.uv1.xy);
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
float4 smallBlur = centerTap;
float4 poissonScale = _MainTex_TexelSize.xyxy * centerTap.a * _Offsets.w ;
float sampleCount = max(centerTap.a * 0.25, 0.1f); // <- weighing with 0.25 looks nicer for small high freq spec
smallBlur *= sampleCount;
for(int l=0; l < SmallDiscKernelSamples; l++)
{
float2 sampleUV = i.uv1.xy + SmallDiscKernel[l].xy * poissonScale.xy*1.1;
float4 sample0 = tex2D(_MainTex, sampleUV);
float weight0 = BokehWeightDisc(sample0, length(SmallDiscKernel[l].xy*1.1), centerTap);
smallBlur += sample0 * weight0; sampleCount += weight0;
}
smallBlur /= (sampleCount+1e-5f);
smallBlur = BlendLowWithHighMQ(centerTap.a, smallBlur, bigBlur);
return centerTap.a < 1e-2f ? centerTap : float4(smallBlur.rgb,centerTap.a);
}
float4 fragBlurUpsampleCheap (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
float4 bigBlur = tex2D(_LowRez, i.uv1.xy);
float fgCoc = tex2D(_FgOverlap, i.uv1.xy).a;
float4 smallBlur = lerp(centerTap, bigBlur, saturate( max(centerTap.a,fgCoc)*8.0 ));
return float4(smallBlur.rgb, centerTap.a);
}
float4 fragBlurBox (v2f i) : SV_Target
{
const int TAPS = 12;
float4 centerTap = tex2D(_MainTex, i.uv1.xy);
// TODO: important ? breaks when HR blur is being used
//centerTap.a = max(centerTap.a, 0.1f);
float sampleCount = centerTap.a;
float4 sum = centerTap * sampleCount;
float2 lenStep = centerTap.aa * (1.0 / (TAPS-1.0));
float4 steps = (_Offsets.xyxy * _MainTex_TexelSize.xyxy) * lenStep.xyxy * float4(1,1, -1,-1);
for(int l=1; l<TAPS; l++)
{
float4 sampleUV = i.uv1.xyxy + steps * (float)l;
float4 sample0 = tex2D(_MainTex, sampleUV.xy);
float4 sample1 = tex2D(_MainTex, sampleUV.zw);
float2 maxLen01 = float2(sample0.a, sample1.a);
float2 r = lenStep.xx * (float)l;
float2 weight01 = smoothstep(float2(-0.4,-0.4),float2(0.0,0.0), maxLen01-r);
sum += sample0 * weight01.x + sample1 * weight01.y;
sampleCount += dot(weight01,1);
}
float4 returnValue = sum / (1e-5f + sampleCount);
//returnValue.a = centerTap.a;
//return centerTap.a;
return returnValue;
}
float4 fragVisualize (v2f i) : SV_Target
{
float4 returnValue = tex2D(_MainTex, i.uv1.xy);
returnValue.rgb = lerp(float3(0.0,0.0,0.0), float3(1.0,1.0,1.0), saturate(returnValue.a/_CurveParams.x));
return returnValue;
}
float4 fragBoxDownsample (v2f i) : SV_Target
{
//float4 returnValue = tex2D(_MainTex, i.uv1.xy);
float4 returnValue = tex2D(_MainTex, i.uv1.xy + 0.75*_MainTex_TexelSize.xy);
returnValue += tex2D(_MainTex, i.uv1.xy - 0.75*_MainTex_TexelSize.xy);
returnValue += tex2D(_MainTex, i.uv1.xy + 0.75*_MainTex_TexelSize.xy * float2(1,-1));
returnValue += tex2D(_MainTex, i.uv1.xy - 0.75*_MainTex_TexelSize.xy * float2(1,-1));
return returnValue/4;
}
float4 fragBlurAlphaWeighted (v2fBlur i) : SV_Target
{
const float ALPHA_WEIGHT = 2.0f;
float4 sum = float4 (0,0,0,0);
float w = 0;
float weights = 0;
const float G_WEIGHTS[6] = {1.0, 0.8, 0.675, 0.5, 0.2, 0.075};
float4 sampleA = tex2D(_MainTex, i.uv.xy);
float4 sampleB = tex2D(_MainTex, i.uv01.xy);
float4 sampleC = tex2D(_MainTex, i.uv01.zw);
float4 sampleD = tex2D(_MainTex, i.uv23.xy);
float4 sampleE = tex2D(_MainTex, i.uv23.zw);
float4 sampleF = tex2D(_MainTex, i.uv45.xy);
float4 sampleG = tex2D(_MainTex, i.uv45.zw);
float4 sampleH = tex2D(_MainTex, i.uv67.xy);
float4 sampleI = tex2D(_MainTex, i.uv67.zw);
float4 sampleJ = tex2D(_MainTex, i.uv89.xy);
float4 sampleK = tex2D(_MainTex, i.uv89.zw);
w = sampleA.a * G_WEIGHTS[0]; sum += sampleA * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleB.a) * G_WEIGHTS[1]; sum += sampleB * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleC.a) * G_WEIGHTS[1]; sum += sampleC * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleD.a) * G_WEIGHTS[2]; sum += sampleD * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleE.a) * G_WEIGHTS[2]; sum += sampleE * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleF.a) * G_WEIGHTS[3]; sum += sampleF * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleG.a) * G_WEIGHTS[3]; sum += sampleG * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleH.a) * G_WEIGHTS[4]; sum += sampleH * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleI.a) * G_WEIGHTS[4]; sum += sampleI * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleJ.a) * G_WEIGHTS[5]; sum += sampleJ * w; weights += w;
w = saturate(ALPHA_WEIGHT*sampleK.a) * G_WEIGHTS[5]; sum += sampleK * w; weights += w;
sum /= weights + 1e-4f;
sum.a = sampleA.a;
if(sampleA.a<1e-2f) sum.rgb = sampleA.rgb;
return sum;
}
float4 fragBlurForFgCoc (v2fBlur i) : SV_Target
{
float4 sum = float4 (0,0,0,0);
float w = 0;
float weights = 0;
const float G_WEIGHTS[6] = {1.0, 0.8, 0.675, 0.5, 0.2, 0.075};
float4 sampleA = tex2D(_MainTex, i.uv.xy);
float4 sampleB = tex2D(_MainTex, i.uv01.xy);
float4 sampleC = tex2D(_MainTex, i.uv01.zw);
float4 sampleD = tex2D(_MainTex, i.uv23.xy);
float4 sampleE = tex2D(_MainTex, i.uv23.zw);
float4 sampleF = tex2D(_MainTex, i.uv45.xy);
float4 sampleG = tex2D(_MainTex, i.uv45.zw);
float4 sampleH = tex2D(_MainTex, i.uv67.xy);
float4 sampleI = tex2D(_MainTex, i.uv67.zw);
float4 sampleJ = tex2D(_MainTex, i.uv89.xy);
float4 sampleK = tex2D(_MainTex, i.uv89.zw);
w = sampleA.a * G_WEIGHTS[0]; sum += sampleA * w; weights += w;
w = smoothstep(-0.5,0.0,sampleB.a-sampleA.a) * G_WEIGHTS[1]; sum += sampleB * w; weights += w;
w = smoothstep(-0.5,0.0,sampleC.a-sampleA.a) * G_WEIGHTS[1]; sum += sampleC * w; weights += w;
w = smoothstep(-0.5,0.0,sampleD.a-sampleA.a) * G_WEIGHTS[2]; sum += sampleD * w; weights += w;
w = smoothstep(-0.5,0.0,sampleE.a-sampleA.a) * G_WEIGHTS[2]; sum += sampleE * w; weights += w;
w = smoothstep(-0.5,0.0,sampleF.a-sampleA.a) * G_WEIGHTS[3]; sum += sampleF * w; weights += w;
w = smoothstep(-0.5,0.0,sampleG.a-sampleA.a) * G_WEIGHTS[3]; sum += sampleG * w; weights += w;
w = smoothstep(-0.5,0.0,sampleH.a-sampleA.a) * G_WEIGHTS[4]; sum += sampleH * w; weights += w;
w = smoothstep(-0.5,0.0,sampleI.a-sampleA.a) * G_WEIGHTS[4]; sum += sampleI * w; weights += w;
w = smoothstep(-0.5,0.0,sampleJ.a-sampleA.a) * G_WEIGHTS[5]; sum += sampleJ * w; weights += w;
w = smoothstep(-0.5,0.0,sampleK.a-sampleA.a) * G_WEIGHTS[5]; sum += sampleK * w; weights += w;
sum /= weights + 1e-4f;
return sum;
}
float4 fragGaussBlur (v2fBlur i) : SV_Target
{
float4 sum = float4 (0,0,0,0);
float w = 0;
float weights = 0;
const float G_WEIGHTS[9] = {1.0, 0.8, 0.65, 0.5, 0.4, 0.2, 0.1, 0.05, 0.025};
float4 sampleA = tex2D(_MainTex, i.uv.xy);
float4 sampleB = tex2D(_MainTex, i.uv01.xy);
float4 sampleC = tex2D(_MainTex, i.uv01.zw);
float4 sampleD = tex2D(_MainTex, i.uv23.xy);
float4 sampleE = tex2D(_MainTex, i.uv23.zw);
float4 sampleF = tex2D(_MainTex, i.uv45.xy);
float4 sampleG = tex2D(_MainTex, i.uv45.zw);
float4 sampleH = tex2D(_MainTex, i.uv67.xy);
float4 sampleI = tex2D(_MainTex, i.uv67.zw);
float4 sampleJ = tex2D(_MainTex, i.uv89.xy);
float4 sampleK = tex2D(_MainTex, i.uv89.zw);
w = sampleA.a * G_WEIGHTS[0]; sum += sampleA * w; weights += w;
w = sampleB.a * G_WEIGHTS[1]; sum += sampleB * w; weights += w;
w = sampleC.a * G_WEIGHTS[1]; sum += sampleC * w; weights += w;
w = sampleD.a * G_WEIGHTS[2]; sum += sampleD * w; weights += w;
w = sampleE.a * G_WEIGHTS[2]; sum += sampleE * w; weights += w;
w = sampleF.a * G_WEIGHTS[3]; sum += sampleF * w; weights += w;
w = sampleG.a * G_WEIGHTS[3]; sum += sampleG * w; weights += w;
w = sampleH.a * G_WEIGHTS[4]; sum += sampleH * w; weights += w;
w = sampleI.a * G_WEIGHTS[4]; sum += sampleI * w; weights += w;
w = sampleJ.a * G_WEIGHTS[5]; sum += sampleJ * w; weights += w;
w = sampleK.a * G_WEIGHTS[5]; sum += sampleK * w; weights += w;
sum /= weights + 1e-4f;
return sum;
}
float4 frag4TapBlurForLRSpawn (v2f i) : SV_Target
{
float4 tap = tex2D(_MainTex, i.uv.xy);
float4 tapA = tex2D(_MainTex, i.uv.xy + 0.75 * _MainTex_TexelSize.xy);
float4 tapB = tex2D(_MainTex, i.uv.xy - 0.75 * _MainTex_TexelSize.xy);
float4 tapC = tex2D(_MainTex, i.uv.xy + 0.75 * _MainTex_TexelSize.xy * float2(1,-1));
float4 tapD = tex2D(_MainTex, i.uv.xy - 0.75 * _MainTex_TexelSize.xy * float2(1,-1));
float4 weights = saturate(10.0 * float4(tapA.a, tapB.a, tapC.a, tapD.a));
float sumWeights = dot(weights, 1);
float4 color = (tapA*weights.x + tapB*weights.y + tapC*weights.z + tapD*weights.w);
float4 outColor = tap;
if(tap.a * sumWeights * 8.0 > 1e-5f) outColor.rgb = color.rgb/sumWeights;
return outColor;
}
float4 fragCaptureColorAndSignedCoc (v2f i) : SV_Target
{
float4 color = tex2D (_MainTex, i.uv1.xy);
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
color.a = _CurveParams.z * abs(d - _CurveParams.w) / (d + 1e-5f);
color.a = clamp( max(0.0, color.a - _CurveParams.y), 0.0, _CurveParams.x) * sign(d - _CurveParams.w);
return color;
}
float4 fragCaptureCoc (v2f i) : SV_Target
{
float4 color = float4(0,0,0,0); //tex2D (_MainTex, i.uv1.xy);
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
color.a = _CurveParams.z * abs(d - _CurveParams.w) / (d + 1e-5f);
color.a = clamp( max(0.0, color.a - _CurveParams.y), 0.0, _CurveParams.x);
return color;
}
float4 AddFgCoc (v2f i) : SV_Target
{
return tex2D (_MainTex, i.uv1.xy);
}
float4 fragMergeCoc (v2f i) : SV_Target
{
float4 color = tex2D (_FgOverlap, i.uv1.xy); // this is the foreground overlap value
float fgCoc = color.a;
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
color.a = _CurveParams.z * abs(d - _CurveParams.w) / (d + 1e-5f);
color.a = clamp( max(0.0, color.a - _CurveParams.y), 0.0, _CurveParams.x);
return max(color.aaaa, float4(fgCoc,fgCoc,fgCoc,fgCoc));
}
float4 fragCombineCocWithMaskBlur (v2f i) : SV_Target
{
float bgAndFgCoc = tex2D (_MainTex, i.uv1.xy).a;
float fgOverlapCoc = tex2D (_FgOverlap, i.uv1.xy).a;
return (bgAndFgCoc < 0.01) * saturate(fgOverlapCoc-bgAndFgCoc);
}
float4 fragCaptureForegroundCoc (v2f i) : SV_Target
{
float4 color = float4(0,0,0,0); //tex2D (_MainTex, i.uv1.xy);
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
color.a = _CurveParams.z * (_CurveParams.w-d) / (d + 1e-5f);
color.a = clamp(max(0.0, color.a - _CurveParams.y), 0.0, _CurveParams.x);
return color;
}
float4 fragCaptureForegroundCocMask (v2f i) : SV_Target
{
float4 color = float4(0,0,0,0);
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
d = Linear01Depth (d);
color.a = _CurveParams.z * (_CurveParams.w-d) / (d + 1e-5f);
color.a = clamp(max(0.0, color.a - _CurveParams.y), 0.0, _CurveParams.x);
return color.a > 0;
}
float4 fragBlendInHighRez (v2f i) : SV_Target
{
float4 tapHighRez = tex2D(_MainTex, i.uv.xy);
return float4(tapHighRez.rgb, 1.0-saturate(tapHighRez.a*5.0));
}
float4 fragBlendInLowRezParts (v2f i) : SV_Target
{
float4 from = tex2D(_MainTex, i.uv1.xy);
from.a = saturate(from.a * _Offsets.w) / (_CurveParams.x + 1e-5f);
float square = from.a * from.a;
from.a = square * square * _CurveParams.x;
return from;
}
float4 fragUpsampleWithAlphaMask(v2f i) : SV_Target
{
float4 c = tex2D(_MainTex, i.uv1.xy);
return c;
}
float4 fragAlphaMask(v2f i) : SV_Target
{
float4 c = tex2D(_MainTex, i.uv1.xy);
c.a = saturate(c.a*100.0);
return c;
}
ENDCG
Subshader
{
// pass 0
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask A
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragCaptureCoc
ENDCG
}
// pass 1
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertBlurPlusMinus
#pragma fragment fragGaussBlur
ENDCG
}
// pass 2
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertBlurPlusMinus
#pragma fragment fragBlurForFgCoc
ENDCG
}
// pass 3
Pass
{
ZTest Always Cull Off ZWrite Off
ColorMask A
BlendOp Max, Max
Blend One One, One One
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment AddFgCoc
ENDCG
}
// pass 4
Pass
{
ZTest Always Cull Off ZWrite Off
ColorMask A
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragCaptureForegroundCoc
ENDCG
}
// pass 5
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurBox
ENDCG
}
// pass 6
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag4TapBlurForLRSpawn
ENDCG
}
// pass 7
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlendInHighRez
ENDCG
}
// pass 8
Pass
{
ZTest Always Cull Off ZWrite Off
ColorMask A
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragCaptureForegroundCocMask
ENDCG
}
// pass 9
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurUpsampleCheap
ENDCG
}
// pass 10
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragCaptureColorAndSignedCoc
ENDCG
}
// pass 11
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurInsaneMQ
ENDCG
}
// pass 12
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurUpsampleCombineMQ
ENDCG
}
// pass 13
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask A
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragMergeCoc
ENDCG
}
// pass 14
Pass {
ZTest Always Cull Off ZWrite Off
ColorMask A
BlendOp Max, Max
Blend One One, One One
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragCombineCocWithMaskBlur
ENDCG
}
// pass 15
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBoxDownsample
ENDCG
}
// pass 16
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragVisualize
ENDCG
}
// pass 17
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurInsaneHQ
ENDCG
}
// pass 18
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragBlurUpsampleCombineHQ
ENDCG
}
// pass 19
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vertBlurPlusMinus
#pragma fragment fragBlurAlphaWeighted
ENDCG
}
// pass 20
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragAlphaMask
ENDCG
}
// pass 21
Pass {
ZTest Always Cull Off ZWrite Off
BlendOp Add, Add
Blend DstAlpha OneMinusDstAlpha, Zero One
CGPROGRAM
#pragma target 3.0
#pragma vertex vertFlip
#pragma fragment fragBlurBox
ENDCG
}
// pass 22
Pass {
ZTest Always Cull Off ZWrite Off
// destination alpha needs to stay intact as we have layed alpha before
BlendOp Add, Add
Blend DstAlpha One, Zero One
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragUpsampleWithAlphaMask
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: acd613035ff3e455e8abf23fdc8c8c24
ShaderImporter:
userData:
Shader "Hidden/SeparableBlur" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 uv01 : TEXCOORD1;
float4 uv23 : TEXCOORD2;
float4 uv45 : TEXCOORD3;
};
float4 offsets;
sampler2D _MainTex;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1);
o.uv23 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 2.0;
o.uv45 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 3.0;
return o;
}
half4 frag (v2f i) : SV_Target {
half4 color = float4 (0,0,0,0);
color += 0.40 * tex2D (_MainTex, i.uv);
color += 0.15 * tex2D (_MainTex, i.uv01.xy);
color += 0.15 * tex2D (_MainTex, i.uv01.zw);
color += 0.10 * tex2D (_MainTex, i.uv23.xy);
color += 0.10 * tex2D (_MainTex, i.uv23.zw);
color += 0.05 * tex2D (_MainTex, i.uv45.xy);
color += 0.05 * tex2D (_MainTex, i.uv45.zw);
return color;
}
ENDCG
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: e97c14fbb5ea04c3a902cc533d7fc5d1
ShaderImporter:
userData:
Shader "Hidden/SeparableWeightedBlurDof34" {
Properties {
_MainTex ("Base (RGB)", 2D) = "" {}
_TapMedium ("TapMedium (RGB)", 2D) = "" {}
_TapLow ("TapLow (RGB)", 2D) = "" {}
_TapHigh ("TapHigh (RGB)", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
half4 offsets;
half4 _Threshhold;
sampler2D _MainTex;
sampler2D _TapHigh;
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half4 uv01 : TEXCOORD1;
half4 uv23 : TEXCOORD2;
half4 uv45 : TEXCOORD3;
};
struct v2fSingle {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
//
// VERT PROGRAMS
//
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1);
o.uv23 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 2.0;
o.uv45 = v.texcoord.xyxy + offsets.xyxy * half4(1,1, -1,-1) * 3.0;
return o;
}
v2fSingle vertSingleTex (appdata_img v) {
v2fSingle o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
return o;
}
//
// FRAG PROGRAMS
//
// mostly used for foreground, so more gaussian-like
half4 fragBlurUnweighted (v2f i) : SV_Target {
half4 blurredColor = half4 (0,0,0,0);
half4 sampleA = tex2D(_MainTex, i.uv.xy);
half4 sampleB = tex2D(_MainTex, i.uv01.xy);
half4 sampleC = tex2D(_MainTex, i.uv01.zw);
half4 sampleD = tex2D(_MainTex, i.uv23.xy);
half4 sampleE = tex2D(_MainTex, i.uv23.zw);
blurredColor += sampleA;
blurredColor += sampleB;
blurredColor += sampleC;
blurredColor += sampleD;
blurredColor += sampleE;
blurredColor *= 0.2;
blurredColor.a = max(UNITY_SAMPLE_1CHANNEL(_TapHigh, i.uv.xy), blurredColor.a);
return blurredColor;
}
// used for background, so more bone curve-like
half4 fragBlurWeighted (v2f i) : SV_Target {
half4 blurredColor = half4 (0,0,0,0);
half4 sampleA = tex2D(_MainTex, i.uv.xy);
half4 sampleB = tex2D(_MainTex, i.uv01.xy);
half4 sampleC = tex2D(_MainTex, i.uv01.zw);
half4 sampleD = tex2D(_MainTex, i.uv23.xy);
half4 sampleE = tex2D(_MainTex, i.uv23.zw);
half sum = sampleA.a + dot (half4 (1.25, 1.25, 1.5, 1.5), half4 (sampleB.a,sampleC.a,sampleD.a,sampleE.a));
sampleA.rgb = sampleA.rgb * sampleA.a;
sampleB.rgb = sampleB.rgb * sampleB.a * 1.25;
sampleC.rgb = sampleC.rgb * sampleC.a * 1.25;
sampleD.rgb = sampleD.rgb * sampleD.a * 1.5;
sampleE.rgb = sampleE.rgb * sampleE.a * 1.5;
blurredColor += sampleA;
blurredColor += sampleB;
blurredColor += sampleC;
blurredColor += sampleD;
blurredColor += sampleE;
blurredColor /= sum;
half4 color = blurredColor;
color.a = sampleA.a;
return color;
}
half4 fragBlurDark (v2f i) : SV_Target {
half4 blurredColor = half4 (0,0,0,0);
half4 sampleA = tex2D(_MainTex, i.uv.xy);
half4 sampleB = tex2D(_MainTex, i.uv01.xy);
half4 sampleC = tex2D(_MainTex, i.uv01.zw);
half4 sampleD = tex2D(_MainTex, i.uv23.xy);
half4 sampleE = tex2D(_MainTex, i.uv23.zw);
half sum = sampleA.a + dot (half4 (0.75, 0.75, 0.5, 0.5), half4 (sampleB.a,sampleC.a,sampleD.a,sampleE.a));
sampleA.rgb = sampleA.rgb * sampleA.a;
sampleB.rgb = sampleB.rgb * sampleB.a * 0.75;
sampleC.rgb = sampleC.rgb * sampleC.a * 0.75;
sampleD.rgb = sampleD.rgb * sampleD.a * 0.5;
sampleE.rgb = sampleE.rgb * sampleE.a * 0.5;
blurredColor += sampleA;
blurredColor += sampleB;
blurredColor += sampleC;
blurredColor += sampleD;
blurredColor += sampleE;
blurredColor /= sum;
half4 color = blurredColor;
color.a = sampleA.a;
return color;
}
// not used atm
half4 fragBlurUnweightedDark (v2f i) : SV_Target {
half4 blurredColor = half4 (0,0,0,0);
half4 sampleA = tex2D(_MainTex, i.uv.xy);
half4 sampleB = tex2D(_MainTex, i.uv01.xy);
half4 sampleC = tex2D(_MainTex, i.uv01.zw);
half4 sampleD = tex2D(_MainTex, i.uv23.xy);
half4 sampleE = tex2D(_MainTex, i.uv23.zw);
blurredColor += sampleA;
blurredColor += sampleB * 0.75;
blurredColor += sampleC * 0.75;
blurredColor += sampleD * 0.5;
blurredColor += sampleE * 0.5;
blurredColor /= 3.5;
blurredColor.a = max(UNITY_SAMPLE_1CHANNEL(_TapHigh, i.uv.xy), blurredColor.a);
return blurredColor;
}
// fragMixMediumAndLowTap
// happens before applying final coc/blur result to screen,
// mixes defocus buffers of different resolutions / bluriness
sampler2D _TapMedium;
sampler2D _TapLow;
half4 fragMixMediumAndLowTap (v2fSingle i) : SV_Target
{
half4 tapMedium = tex2D (_TapMedium, i.uv.xy);
half4 tapLow = tex2D (_TapLow, i.uv.xy);
tapMedium.a *= tapMedium.a;
tapLow.rgb = lerp (tapMedium.rgb, tapLow.rgb, (tapMedium.a * tapMedium.a));
return tapLow;
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragBlurWeighted
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragBlurUnweighted
ENDCG
}
// 2
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragBlurUnweightedDark
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vertSingleTex
#pragma fragment fragMixMediumAndLowTap
ENDCG
}
// 4
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment fragBlurDark
ENDCG
}
}
Fallback off
} // shader
fileFormatVersion: 2
guid: bb4af680337344a4abad65a4e8873c50
ShaderImporter:
userData:
Shader "Hidden/Dof/TiltShiftHdrLensBlur" {
Properties {
_MainTex ("-", 2D) = "" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _Blurred;
float4 _MainTex_TexelSize;
float _BlurSize;
float _BlurArea;
#ifdef SHADER_API_D3D11
#define SAMPLE_TEX(sampler, uv) tex2Dlod(sampler, float4(uv,0,1))
#else
#define SAMPLE_TEX(sampler, uv) tex2D(sampler, uv)
#endif
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord;
o.uv1.xy = v.texcoord;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv1.y = 1-o.uv1.y;
#else
#endif
return o;
}
static const int SmallDiscKernelSamples = 12;
static const float2 SmallDiscKernel[SmallDiscKernelSamples] =
{
float2(-0.326212,-0.40581),
float2(-0.840144,-0.07358),
float2(-0.695914,0.457137),
float2(-0.203345,0.620716),
float2(0.96234,-0.194983),
float2(0.473434,-0.480026),
float2(0.519456,0.767022),
float2(0.185461,-0.893124),
float2(0.507431,0.064425),
float2(0.89642,0.412458),
float2(-0.32194,-0.932615),
float2(-0.791559,-0.59771)
};
static const int NumDiscSamples = 28;
static const float3 DiscKernel[NumDiscSamples] =
{
float3(0.62463,0.54337,0.82790),
float3(-0.13414,-0.94488,0.95435),
float3(0.38772,-0.43475,0.58253),
float3(0.12126,-0.19282,0.22778),
float3(-0.20388,0.11133,0.23230),
float3(0.83114,-0.29218,0.88100),
float3(0.10759,-0.57839,0.58831),
float3(0.28285,0.79036,0.83945),
float3(-0.36622,0.39516,0.53876),
float3(0.75591,0.21916,0.78704),
float3(-0.52610,0.02386,0.52664),
float3(-0.88216,-0.24471,0.91547),
float3(-0.48888,-0.29330,0.57011),
float3(0.44014,-0.08558,0.44838),
float3(0.21179,0.51373,0.55567),
float3(0.05483,0.95701,0.95858),
float3(-0.59001,-0.70509,0.91938),
float3(-0.80065,0.24631,0.83768),
float3(-0.19424,-0.18402,0.26757),
float3(-0.43667,0.76751,0.88304),
float3(0.21666,0.11602,0.24577),
float3(0.15696,-0.85600,0.87027),
float3(-0.75821,0.58363,0.95682),
float3(0.99284,-0.02904,0.99327),
float3(-0.22234,-0.57907,0.62029),
float3(0.55052,-0.66984,0.86704),
float3(0.46431,0.28115,0.54280),
float3(-0.07214,0.60554,0.60982),
};
float WeightFieldMode (float2 uv)
{
float2 tapCoord = uv*2.0-1.0;
return (abs(tapCoord.y * _BlurArea));
}
float WeightIrisMode (float2 uv)
{
float2 tapCoord = (uv*2.0-1.0);
return dot(tapCoord, tapCoord) * _BlurArea;
}
float4 fragIrisPreview (v2f i) : SV_Target
{
return WeightIrisMode(i.uv.xy) * 0.5;
}
float4 fragFieldPreview (v2f i) : SV_Target
{
return WeightFieldMode(i.uv.xy) * 0.5;
}
float4 fragUpsample (v2f i) : SV_Target
{
float4 blurred = tex2D(_Blurred, i.uv1.xy);
float4 frame = tex2D(_MainTex, i.uv.xy);
return lerp(frame, blurred, saturate(blurred.a));
}
float4 fragIris (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv.xy);
float4 sum = centerTap;
float w = clamp(WeightIrisMode(i.uv.xy), 0, _BlurSize);
float4 poissonScale = _MainTex_TexelSize.xyxy * w;
#ifndef SHADER_API_D3D9
if(w<1e-2f)
return sum;
#endif
for(int l=0; l<NumDiscSamples; l++)
{
float2 sampleUV = i.uv.xy + DiscKernel[l].xy * poissonScale.xy;
float4 sample0 = SAMPLE_TEX(_MainTex, sampleUV.xy);
sum += sample0;
}
return float4(sum.rgb / (1.0 + NumDiscSamples), w);
}
float4 fragField (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv.xy);
float4 sum = centerTap;
float w = clamp(WeightFieldMode(i.uv.xy), 0, _BlurSize);
float4 poissonScale = _MainTex_TexelSize.xyxy * w;
#ifndef SHADER_API_D3D9
if(w<1e-2f)
return sum;
#endif
for(int l=0; l<NumDiscSamples; l++)
{
float2 sampleUV = i.uv.xy + DiscKernel[l].xy * poissonScale.xy;
float4 sample0 = SAMPLE_TEX(_MainTex, sampleUV.xy);
sum += sample0;
}
return float4(sum.rgb / (1.0 + NumDiscSamples), w);
}
float4 fragIrisHQ (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv.xy);
float4 sum = centerTap;
float w = clamp(WeightIrisMode(i.uv.xy), 0, _BlurSize);
float4 poissonScale = _MainTex_TexelSize.xyxy * float4(1,1,-1,-1) * 2;
#ifndef SHADER_API_D3D9
if(w<1e-2f)
return sum;
#endif
for(int l=0; l<NumDiscSamples; l++)
{
float4 sampleUV = i.uv.xyxy + DiscKernel[l].xyxy * poissonScale;
float4 sample0 = SAMPLE_TEX(_MainTex, sampleUV.xy);
float4 sample1 = SAMPLE_TEX(_MainTex, sampleUV.zw);
sum += sample0 + sample1;
}
return float4(sum.rgb / (1.0 + 2.0 * NumDiscSamples), w);
}
float4 fragFieldHQ (v2f i) : SV_Target
{
float4 centerTap = tex2D(_MainTex, i.uv.xy);
float4 sum = centerTap;
float w = clamp(WeightFieldMode(i.uv.xy), 0, _BlurSize);
float4 poissonScale = _MainTex_TexelSize.xyxy * float4(1,1,-1,-1) * w;
#ifndef SHADER_API_D3D9
if(w<1e-2f)
return sum;
#endif
for(int l=0; l<NumDiscSamples; l++)
{
float4 sampleUV = i.uv.xyxy + DiscKernel[l].xyxy * poissonScale;
float4 sample0 = SAMPLE_TEX(_MainTex, sampleUV.xy);
float4 sample1 = SAMPLE_TEX(_MainTex, sampleUV.zw);
sum += sample0 + sample1;
}
return float4(sum.rgb / (1.0 + 2.0 * NumDiscSamples), w);
}
ENDCG
Subshader {
ZTest Always Cull Off ZWrite Off
Pass { // 0
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragFieldPreview
ENDCG
}
Pass { // 1
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragIrisPreview
ENDCG
}
Pass { // 2
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragField
ENDCG
}
Pass { // 3
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragIris
ENDCG
}
Pass { // 4
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragFieldHQ
ENDCG
}
Pass { // 5
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragIrisHQ
ENDCG
}
Pass { // 6
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragUpsample
ENDCG
}
}
Fallback off
}
fileFormatVersion: 2
guid: bf34d2a25450349699e8ae6456fa7ca9
ShaderImporter:
userData:
half frag_ao (v2f_ao i, int sampleCount, float3 samples[INPUT_SAMPLE_COUNT])
{
// read random normal from noise texture
half3 randN = tex2D (_RandomTexture, i.uvr).xyz * 2.0 - 1.0;
// read scene depth/normal
float4 depthnormal = tex2D (_CameraDepthNormalsTexture, i.uv);
float3 viewNorm;
float depth;
DecodeDepthNormal (depthnormal, depth, viewNorm);
depth *= _ProjectionParams.z;
float scale = _Params.x / depth;
// accumulated occlusion factor
float occ = 0.0;
for (int s = 0; s < sampleCount; ++s)
{
// Reflect sample direction around a random vector
half3 randomDir = reflect(samples[s], randN);
// Make it point to the upper hemisphere
half flip = (dot(viewNorm,randomDir)<0) ? 1.0 : -1.0;
randomDir *= -flip;
// Add a bit of normal to reduce self shadowing
randomDir += viewNorm * 0.3;
float2 offset = randomDir.xy * scale;
float sD = depth - (randomDir.z * _Params.x);
// Sample depth at offset location
float4 sampleND = tex2D (_CameraDepthNormalsTexture, i.uv + offset);
float sampleD;
float3 sampleN;
DecodeDepthNormal (sampleND, sampleD, sampleN);
sampleD *= _ProjectionParams.z;
float zd = saturate(sD-sampleD);
if (zd > _Params.y) {
// This sample occludes, contribute to occlusion
occ += pow(1-zd,_Params.z); // sc2
//occ += 1.0-saturate(pow(1.0 - zd, 11.0) + zd); // nullsq
//occ += 1.0/(1.0+zd*zd*10); // iq
}
}
occ /= sampleCount;
return 1-occ;
}
fileFormatVersion: 2
guid: 51ae11a5cd82fda468a85179946d672a
ShaderImporter:
userData:
fileFormatVersion: 2
guid: f9372f23586ef470b97d53856af88487
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
fileFormatVersion: 2
guid: 95ef4804fe0be4c999ddaa383536cde8
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 1
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: 1
aniso: 1
mipBias: 0
wrapMode: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
textureType: -1
buildTargetSettings: []
userData:
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment