modified maps
modified maps
This commit is contained in:
6
Assets/NatureStarterKit2/Standard Assets/Effects.meta
Normal file
6
Assets/NatureStarterKit2/Standard Assets/Effects.meta
Normal file
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 115d1f9d9bd29064ab981e57c8fc8cdf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c788335fe2df44ca9bbf95bc580ce4d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db69b3da6ede2444b92c479f24b48999
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,50 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 3
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: GlassRefractive
|
||||
m_Shader: {fileID: 4800000, guid: 963484209d11fd7f110076aa44295342, type: 3}
|
||||
m_ShaderKeywords: []
|
||||
m_CustomRenderQueue: -1
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 19555d7d9d114c7f1100f5ab44295342, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 4b8d081e9d114c7f1100f5ab44295342, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _Shininess
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _BumpAmt
|
||||
second: 128
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: .423392087, g: .423392087, b: .423392087, a: 0}
|
||||
data:
|
||||
first:
|
||||
name: _SpecColor
|
||||
second: {r: .981927693, g: .963855445, b: 1, a: 1}
|
||||
--- !u!1002 &2100001
|
||||
EditorExtensionImpl:
|
||||
serializedVersion: 6
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 848918a99d11f25f110026ca44295342
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 194c5f733c7534ed790e101791e86518
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,109 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
// Per pixel bumped refraction.
|
||||
// Uses a normal map to distort the image behind, and
|
||||
// an additional texture to tint the color.
|
||||
|
||||
Shader "FX/Glass/Stained BumpDistort" {
|
||||
Properties {
|
||||
_BumpAmt ("Distortion", range (0,128)) = 10
|
||||
_MainTex ("Tint Color (RGB)", 2D) = "white" {}
|
||||
_BumpMap ("Normalmap", 2D) = "bump" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
|
||||
// We must be transparent, so other objects are drawn before this one.
|
||||
Tags { "Queue"="Transparent" "RenderType"="Opaque" }
|
||||
|
||||
|
||||
SubShader {
|
||||
|
||||
// This pass grabs the screen behind the object into a texture.
|
||||
// We can access the result in the next pass as _GrabTexture
|
||||
GrabPass {
|
||||
Name "BASE"
|
||||
Tags { "LightMode" = "Always" }
|
||||
}
|
||||
|
||||
// Main pass: Take the texture grabbed above and use the bumpmap to perturb it
|
||||
// on to the screen
|
||||
Pass {
|
||||
Name "BASE"
|
||||
Tags { "LightMode" = "Always" }
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fog
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata_t {
|
||||
float4 vertex : POSITION;
|
||||
float2 texcoord: TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 vertex : SV_POSITION;
|
||||
float4 uvgrab : TEXCOORD0;
|
||||
float2 uvbump : TEXCOORD1;
|
||||
float2 uvmain : TEXCOORD2;
|
||||
UNITY_FOG_COORDS(3)
|
||||
};
|
||||
|
||||
float _BumpAmt;
|
||||
float4 _BumpMap_ST;
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
float scale = -1.0;
|
||||
#else
|
||||
float scale = 1.0;
|
||||
#endif
|
||||
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
|
||||
o.uvgrab.zw = o.vertex.zw;
|
||||
o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
|
||||
o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
|
||||
UNITY_TRANSFER_FOG(o,o.vertex);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _GrabTexture;
|
||||
float4 _GrabTexture_TexelSize;
|
||||
sampler2D _BumpMap;
|
||||
sampler2D _MainTex;
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
// calculate perturbed coordinates
|
||||
half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg; // we could optimize this by just reading the x & y without reconstructing the Z
|
||||
float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
|
||||
i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
|
||||
|
||||
half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
|
||||
half4 tint = tex2D(_MainTex, i.uvmain);
|
||||
col *= tint;
|
||||
UNITY_APPLY_FOG(i.fogCoord, col);
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Fallback for older cards and Unity non-Pro
|
||||
|
||||
SubShader {
|
||||
Blend DstColor Zero
|
||||
Pass {
|
||||
Name "BASE"
|
||||
SetTexture [_MainTex] { combine texture }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 963484209d11fd7f110076aa44295342
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8869f43d702ae4d6d8930649833d6bee
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
Binary file not shown.
@ -0,0 +1,52 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19555d7d9d114c7f1100f5ab44295342
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 2
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 8
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 256
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapMode: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: 0
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
Binary file not shown.
@ -0,0 +1,52 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b8d081e9d114c7f1100f5ab44295342
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 2
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 1
|
||||
externalNormalMap: 1
|
||||
heightScale: .117766477
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 8
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 512
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapMode: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: 1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6e0c95a128e14227939c51b5d9ad74e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd3e1490c3d9a7a498538315414d5129
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
public enum AAMode
|
||||
{
|
||||
FXAA2 = 0,
|
||||
FXAA3Console = 1,
|
||||
FXAA1PresetA = 2,
|
||||
FXAA1PresetB = 3,
|
||||
NFAA = 4,
|
||||
SSAA = 5,
|
||||
DLAA = 6,
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof (Camera))]
|
||||
[AddComponentMenu("Image Effects/Other/Antialiasing")]
|
||||
public class Antialiasing : PostEffectsBase
|
||||
{
|
||||
public AAMode mode = AAMode.FXAA3Console;
|
||||
|
||||
public bool showGeneratedNormals = false;
|
||||
public float offsetScale = 0.2f;
|
||||
public float blurRadius = 18.0f;
|
||||
|
||||
public float edgeThresholdMin = 0.05f;
|
||||
public float edgeThreshold = 0.2f;
|
||||
public float edgeSharpness = 4.0f;
|
||||
|
||||
public bool dlaaSharp = false;
|
||||
|
||||
public Shader ssaaShader;
|
||||
private Material ssaa;
|
||||
public Shader dlaaShader;
|
||||
private Material dlaa;
|
||||
public Shader nfaaShader;
|
||||
private Material nfaa;
|
||||
public Shader shaderFXAAPreset2;
|
||||
private Material materialFXAAPreset2;
|
||||
public Shader shaderFXAAPreset3;
|
||||
private Material materialFXAAPreset3;
|
||||
public Shader shaderFXAAII;
|
||||
private Material materialFXAAII;
|
||||
public Shader shaderFXAAIII;
|
||||
private Material materialFXAAIII;
|
||||
|
||||
|
||||
public Material CurrentAAMaterial()
|
||||
{
|
||||
Material returnValue = null;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case AAMode.FXAA3Console:
|
||||
returnValue = materialFXAAIII;
|
||||
break;
|
||||
case AAMode.FXAA2:
|
||||
returnValue = materialFXAAII;
|
||||
break;
|
||||
case AAMode.FXAA1PresetA:
|
||||
returnValue = materialFXAAPreset2;
|
||||
break;
|
||||
case AAMode.FXAA1PresetB:
|
||||
returnValue = materialFXAAPreset3;
|
||||
break;
|
||||
case AAMode.NFAA:
|
||||
returnValue = nfaa;
|
||||
break;
|
||||
case AAMode.SSAA:
|
||||
returnValue = ssaa;
|
||||
break;
|
||||
case AAMode.DLAA:
|
||||
returnValue = dlaa;
|
||||
break;
|
||||
default:
|
||||
returnValue = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources()
|
||||
{
|
||||
CheckSupport(false);
|
||||
|
||||
materialFXAAPreset2 = CreateMaterial(shaderFXAAPreset2, materialFXAAPreset2);
|
||||
materialFXAAPreset3 = CreateMaterial(shaderFXAAPreset3, materialFXAAPreset3);
|
||||
materialFXAAII = CreateMaterial(shaderFXAAII, materialFXAAII);
|
||||
materialFXAAIII = CreateMaterial(shaderFXAAIII, materialFXAAIII);
|
||||
nfaa = CreateMaterial(nfaaShader, nfaa);
|
||||
ssaa = CreateMaterial(ssaaShader, ssaa);
|
||||
dlaa = CreateMaterial(dlaaShader, dlaa);
|
||||
|
||||
if (!ssaaShader.isSupported)
|
||||
{
|
||||
NotSupported();
|
||||
ReportAutoDisable();
|
||||
}
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
public void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// FXAA antialiasing modes
|
||||
|
||||
if (mode == AAMode.FXAA3Console && (materialFXAAIII != null))
|
||||
{
|
||||
materialFXAAIII.SetFloat("_EdgeThresholdMin", edgeThresholdMin);
|
||||
materialFXAAIII.SetFloat("_EdgeThreshold", edgeThreshold);
|
||||
materialFXAAIII.SetFloat("_EdgeSharpness", edgeSharpness);
|
||||
|
||||
Graphics.Blit(source, destination, materialFXAAIII);
|
||||
}
|
||||
else if (mode == AAMode.FXAA1PresetB && (materialFXAAPreset3 != null))
|
||||
{
|
||||
Graphics.Blit(source, destination, materialFXAAPreset3);
|
||||
}
|
||||
else if (mode == AAMode.FXAA1PresetA && materialFXAAPreset2 != null)
|
||||
{
|
||||
source.anisoLevel = 4;
|
||||
Graphics.Blit(source, destination, materialFXAAPreset2);
|
||||
source.anisoLevel = 0;
|
||||
}
|
||||
else if (mode == AAMode.FXAA2 && materialFXAAII != null)
|
||||
{
|
||||
Graphics.Blit(source, destination, materialFXAAII);
|
||||
}
|
||||
else if (mode == AAMode.SSAA && ssaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// SSAA antialiasing
|
||||
Graphics.Blit(source, destination, ssaa);
|
||||
}
|
||||
else if (mode == AAMode.DLAA && dlaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// DLAA antialiasing
|
||||
|
||||
source.anisoLevel = 0;
|
||||
RenderTexture interim = RenderTexture.GetTemporary(source.width, source.height);
|
||||
Graphics.Blit(source, interim, dlaa, 0);
|
||||
Graphics.Blit(interim, destination, dlaa, dlaaSharp ? 2 : 1);
|
||||
RenderTexture.ReleaseTemporary(interim);
|
||||
}
|
||||
else if (mode == AAMode.NFAA && nfaa != null)
|
||||
{
|
||||
// ----------------------------------------------------------------
|
||||
// nfaa antialiasing
|
||||
|
||||
source.anisoLevel = 0;
|
||||
|
||||
nfaa.SetFloat("_OffsetScale", offsetScale);
|
||||
nfaa.SetFloat("_BlurRadius", blurRadius);
|
||||
|
||||
Graphics.Blit(source, destination, nfaa, showGeneratedNormals ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// none of the AA is supported, fallback to a simple blit
|
||||
Graphics.Blit(source, destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 646b5bc27a658f447b1d929fd5ffbd70
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- ssaaShader: {fileID: 4800000, guid: b3728d1488b02490cbd196c7941bf1f8, type: 3}
|
||||
- dlaaShader: {fileID: 4800000, guid: 017ca72b9e8a749058d13ebd527e98fa, type: 3}
|
||||
- nfaaShader: {fileID: 4800000, guid: ce0cb2621f6d84e21a87414e471a3cce, type: 3}
|
||||
- shaderFXAAPreset2: {fileID: 4800000, guid: 6f1418cffd12146f2a83be795f6fa5a7, type: 3}
|
||||
- shaderFXAAPreset3: {fileID: 4800000, guid: c182fa94a5a0a4c02870641efcd38cd5, type: 3}
|
||||
- shaderFXAAII: {fileID: 4800000, guid: cd5b323dcc592457790ff18b528f5e67, type: 3}
|
||||
- shaderFXAAIII: {fileID: 4800000, guid: c547503fff0e8482ea5793727057041c, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,358 @@
|
||||
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>().allowHDR;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
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:
|
@ -0,0 +1,314 @@
|
||||
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>().allowHDR;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
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:
|
@ -0,0 +1,109 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4975a6e437fc3b149a8cd508ce5bdd69
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fastBloomShader: {fileID: 4800000, guid: 68a00c837b82e4c6d92e7da765dc5f1d, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Blur/Blur")]
|
||||
public class Blur : MonoBehaviour
|
||||
{
|
||||
/// Blur iterations - larger number means more blur.
|
||||
[Range(0,10)]
|
||||
public int iterations = 3;
|
||||
|
||||
/// Blur spread for each iteration. Lower values
|
||||
/// give better looking blur, but require more iterations to
|
||||
/// get large blurs. Value is usually between 0.5 and 1.0.
|
||||
[Range(0.0f,1.0f)]
|
||||
public float blurSpread = 0.6f;
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// The blur iteration shader.
|
||||
// Basically it just takes 4 texture samples and averages them.
|
||||
// By applying it repeatedly and spreading out sample locations
|
||||
// we get a Gaussian blur approximation.
|
||||
|
||||
public Shader blurShader = null;
|
||||
|
||||
static Material m_Material = null;
|
||||
protected Material material {
|
||||
get {
|
||||
if (m_Material == null) {
|
||||
m_Material = new Material(blurShader);
|
||||
m_Material.hideFlags = HideFlags.DontSave;
|
||||
}
|
||||
return m_Material;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDisable() {
|
||||
if ( m_Material ) {
|
||||
DestroyImmediate( m_Material );
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
protected void Start()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
// Disable if the shader can't run on the users graphics card
|
||||
if (!blurShader || !material.shader.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Performs one blur iteration.
|
||||
public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration)
|
||||
{
|
||||
float off = 0.5f + iteration*blurSpread;
|
||||
Graphics.BlitMultiTap (source, dest, material,
|
||||
new Vector2(-off, -off),
|
||||
new Vector2(-off, off),
|
||||
new Vector2( off, off),
|
||||
new Vector2( off, -off)
|
||||
);
|
||||
}
|
||||
|
||||
// Downsamples the texture to a quarter resolution.
|
||||
private void DownSample4x (RenderTexture source, RenderTexture dest)
|
||||
{
|
||||
float off = 1.0f;
|
||||
Graphics.BlitMultiTap (source, dest, material,
|
||||
new Vector2(-off, -off),
|
||||
new Vector2(-off, off),
|
||||
new Vector2( off, off),
|
||||
new Vector2( off, -off)
|
||||
);
|
||||
}
|
||||
|
||||
// Called by the camera to apply the image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
int rtW = source.width/4;
|
||||
int rtH = source.height/4;
|
||||
RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
|
||||
|
||||
// Copy source to the 4x4 smaller texture.
|
||||
DownSample4x (source, buffer);
|
||||
|
||||
// Blur the small texture
|
||||
for(int i = 0; i < iterations; i++)
|
||||
{
|
||||
RenderTexture buffer2 = RenderTexture.GetTemporary(rtW, rtH, 0);
|
||||
FourTapCone (buffer, buffer2, i);
|
||||
RenderTexture.ReleaseTemporary(buffer);
|
||||
buffer = buffer2;
|
||||
}
|
||||
Graphics.Blit(buffer, destination);
|
||||
|
||||
RenderTexture.ReleaseTemporary(buffer);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34382083ad114a07d000fbfb8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: 57e6deea7c2924e22a5138e2b70bb4dc, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Blur/Blur (Optimized)")]
|
||||
public class BlurOptimized : PostEffectsBase
|
||||
{
|
||||
|
||||
[Range(0, 2)]
|
||||
public int downsample = 1;
|
||||
|
||||
public enum BlurType {
|
||||
StandardGauss = 0,
|
||||
SgxGauss = 1,
|
||||
}
|
||||
|
||||
[Range(0.0f, 10.0f)]
|
||||
public float blurSize = 3.0f;
|
||||
|
||||
[Range(1, 4)]
|
||||
public int blurIterations = 2;
|
||||
|
||||
public BlurType blurType= BlurType.StandardGauss;
|
||||
|
||||
public Shader blurShader = null;
|
||||
private Material blurMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (false);
|
||||
|
||||
blurMaterial = CheckShaderAndCreateMaterial (blurShader, blurMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public void OnDisable () {
|
||||
if (blurMaterial)
|
||||
DestroyImmediate (blurMaterial);
|
||||
}
|
||||
|
||||
public void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources() == false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
float widthMod = 1.0f / (1.0f * (1<<downsample));
|
||||
|
||||
blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, -blurSize * widthMod, 0.0f, 0.0f));
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
int rtW = source.width >> downsample;
|
||||
int rtH = source.height >> downsample;
|
||||
|
||||
// downsample
|
||||
RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
|
||||
rt.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (source, rt, blurMaterial, 0);
|
||||
|
||||
var passOffs= blurType == BlurType.StandardGauss ? 0 : 2;
|
||||
|
||||
for(int i = 0; i < blurIterations; i++) {
|
||||
float iterationOffs = (i*1.0f);
|
||||
blurMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + iterationOffs, -blurSize * widthMod - iterationOffs, 0.0f, 0.0f));
|
||||
|
||||
// vertical blur
|
||||
RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
rt2.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (rt, rt2, blurMaterial, 1 + passOffs);
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
rt = rt2;
|
||||
|
||||
// horizontal blur
|
||||
rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format);
|
||||
rt2.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (rt, rt2, blurMaterial, 2 + passOffs);
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
rt = rt2;
|
||||
}
|
||||
|
||||
Graphics.Blit (rt, destination);
|
||||
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fc6bde01469c7b4badee5362f191d96
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: f9d5fa183cd6b45eeb1491f74863cd91, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,381 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Camera Motion Blur") ]
|
||||
public class CameraMotionBlur : PostEffectsBase
|
||||
{
|
||||
// make sure to match this to MAX_RADIUS in shader ('k' in paper)
|
||||
static float MAX_RADIUS = 10.0f;
|
||||
|
||||
public enum MotionBlurFilter {
|
||||
CameraMotion = 0, // global screen blur based on cam motion
|
||||
LocalBlur = 1, // cheap blur, no dilation or scattering
|
||||
Reconstruction = 2, // advanced filter (simulates scattering) as in plausible motion blur paper
|
||||
ReconstructionDX11 = 3, // advanced filter (simulates scattering) as in plausible motion blur paper
|
||||
ReconstructionDisc = 4, // advanced filter using scaled poisson disc sampling
|
||||
}
|
||||
|
||||
// settings
|
||||
public MotionBlurFilter filterType = MotionBlurFilter.Reconstruction;
|
||||
public bool preview = false; // show how blur would look like in action ...
|
||||
public Vector3 previewScale = Vector3.one; // ... given this movement vector
|
||||
|
||||
// params
|
||||
public float movementScale = 0.0f;
|
||||
public float rotationScale = 1.0f;
|
||||
public float maxVelocity = 8.0f; // maximum velocity in pixels
|
||||
public float minVelocity = 0.1f; // minimum velocity in pixels
|
||||
public float velocityScale = 0.375f; // global velocity scale
|
||||
public float softZDistance = 0.005f; // for z overlap check softness (reconstruction filter only)
|
||||
public int velocityDownsample = 1; // low resolution velocity buffer? (optimization)
|
||||
public LayerMask excludeLayers = 0;
|
||||
private GameObject tmpCam = null;
|
||||
|
||||
// resources
|
||||
public Shader shader;
|
||||
public Shader dx11MotionBlurShader;
|
||||
public Shader replacementClear;
|
||||
|
||||
private Material motionBlurMaterial = null;
|
||||
private Material dx11MotionBlurMaterial = null;
|
||||
|
||||
public Texture2D noiseTexture = null;
|
||||
public float jitter = 0.05f;
|
||||
|
||||
// (internal) debug
|
||||
public bool showVelocity = false;
|
||||
public float showVelocityScale = 1.0f;
|
||||
|
||||
// camera transforms
|
||||
private Matrix4x4 currentViewProjMat;
|
||||
private Matrix4x4 prevViewProjMat;
|
||||
private int prevFrameCount;
|
||||
private bool wasActive;
|
||||
// shortcuts to calculate global blur direction when using 'CameraMotion'
|
||||
private Vector3 prevFrameForward = Vector3.forward;
|
||||
private Vector3 prevFrameUp = Vector3.up;
|
||||
private Vector3 prevFramePos = Vector3.zero;
|
||||
private Camera _camera;
|
||||
|
||||
|
||||
private void CalculateViewProjection () {
|
||||
Matrix4x4 viewMat = _camera.worldToCameraMatrix;
|
||||
Matrix4x4 projMat = GL.GetGPUProjectionMatrix (_camera.projectionMatrix, true);
|
||||
currentViewProjMat = projMat * viewMat;
|
||||
}
|
||||
|
||||
|
||||
new void Start () {
|
||||
CheckResources ();
|
||||
|
||||
if (_camera == null)
|
||||
_camera = GetComponent<Camera>();
|
||||
|
||||
wasActive = gameObject.activeInHierarchy;
|
||||
CalculateViewProjection ();
|
||||
Remember ();
|
||||
wasActive = false; // hack to fake position/rotation update and prevent bad blurs
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
|
||||
if (_camera == null)
|
||||
_camera = GetComponent<Camera>();
|
||||
|
||||
_camera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (null != motionBlurMaterial) {
|
||||
DestroyImmediate (motionBlurMaterial);
|
||||
motionBlurMaterial = null;
|
||||
}
|
||||
if (null != dx11MotionBlurMaterial) {
|
||||
DestroyImmediate (dx11MotionBlurMaterial);
|
||||
dx11MotionBlurMaterial = null;
|
||||
}
|
||||
if (null != tmpCam) {
|
||||
DestroyImmediate (tmpCam);
|
||||
tmpCam = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true, true); // depth & hdr needed
|
||||
motionBlurMaterial = CheckShaderAndCreateMaterial (shader, motionBlurMaterial);
|
||||
|
||||
if (supportDX11 && filterType == MotionBlurFilter.ReconstructionDX11) {
|
||||
dx11MotionBlurMaterial = CheckShaderAndCreateMaterial (dx11MotionBlurShader, dx11MotionBlurMaterial);
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (false == CheckResources ()) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filterType == MotionBlurFilter.CameraMotion)
|
||||
StartFrame ();
|
||||
|
||||
// use if possible new RG format ... fallback to half otherwise
|
||||
var rtFormat= SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.RGHalf) ? RenderTextureFormat.RGHalf : RenderTextureFormat.ARGBHalf;
|
||||
|
||||
// get temp textures
|
||||
RenderTexture velBuffer = RenderTexture.GetTemporary (divRoundUp (source.width, velocityDownsample), divRoundUp (source.height, velocityDownsample), 0, rtFormat);
|
||||
int tileWidth = 1;
|
||||
int tileHeight = 1;
|
||||
maxVelocity = Mathf.Max (2.0f, maxVelocity);
|
||||
|
||||
float _maxVelocity = maxVelocity; // calculate 'k'
|
||||
// note: 's' is hardcoded in shaders except for DX11 path
|
||||
|
||||
// auto DX11 fallback!
|
||||
bool fallbackFromDX11 = filterType == MotionBlurFilter.ReconstructionDX11 && dx11MotionBlurMaterial == null;
|
||||
|
||||
if (filterType == MotionBlurFilter.Reconstruction || fallbackFromDX11 || filterType == MotionBlurFilter.ReconstructionDisc) {
|
||||
maxVelocity = Mathf.Min (maxVelocity, MAX_RADIUS);
|
||||
tileWidth = divRoundUp (velBuffer.width, (int) maxVelocity);
|
||||
tileHeight = divRoundUp (velBuffer.height, (int) maxVelocity);
|
||||
_maxVelocity = velBuffer.width/tileWidth;
|
||||
}
|
||||
else {
|
||||
tileWidth = divRoundUp (velBuffer.width, (int) maxVelocity);
|
||||
tileHeight = divRoundUp (velBuffer.height, (int) maxVelocity);
|
||||
_maxVelocity = velBuffer.width/tileWidth;
|
||||
}
|
||||
|
||||
RenderTexture tileMax = RenderTexture.GetTemporary (tileWidth, tileHeight, 0, rtFormat);
|
||||
RenderTexture neighbourMax = RenderTexture.GetTemporary (tileWidth, tileHeight, 0, rtFormat);
|
||||
velBuffer.filterMode = FilterMode.Point;
|
||||
tileMax.filterMode = FilterMode.Point;
|
||||
neighbourMax.filterMode = FilterMode.Point;
|
||||
if (noiseTexture) noiseTexture.filterMode = FilterMode.Point;
|
||||
source.wrapMode = TextureWrapMode.Clamp;
|
||||
velBuffer.wrapMode = TextureWrapMode.Clamp;
|
||||
neighbourMax.wrapMode = TextureWrapMode.Clamp;
|
||||
tileMax.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
// calc correct viewprj matrix
|
||||
CalculateViewProjection ();
|
||||
|
||||
// just started up?
|
||||
if (gameObject.activeInHierarchy && !wasActive) {
|
||||
Remember ();
|
||||
}
|
||||
wasActive = gameObject.activeInHierarchy;
|
||||
|
||||
// matrices
|
||||
Matrix4x4 invViewPrj = Matrix4x4.Inverse (currentViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_InvViewProj", invViewPrj);
|
||||
motionBlurMaterial.SetMatrix ("_PrevViewProj", prevViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_ToPrevViewProjCombined", prevViewProjMat * invViewPrj);
|
||||
|
||||
motionBlurMaterial.SetFloat ("_MaxVelocity", _maxVelocity);
|
||||
motionBlurMaterial.SetFloat ("_MaxRadiusOrKInPaper", _maxVelocity);
|
||||
motionBlurMaterial.SetFloat ("_MinVelocity", minVelocity);
|
||||
motionBlurMaterial.SetFloat ("_VelocityScale", velocityScale);
|
||||
motionBlurMaterial.SetFloat ("_Jitter", jitter);
|
||||
|
||||
// texture samplers
|
||||
motionBlurMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
motionBlurMaterial.SetTexture ("_VelTex", velBuffer);
|
||||
motionBlurMaterial.SetTexture ("_NeighbourMaxTex", neighbourMax);
|
||||
motionBlurMaterial.SetTexture ("_TileTexDebug", tileMax);
|
||||
|
||||
if (preview) {
|
||||
// generate an artifical 'previous' matrix to simulate blur look
|
||||
Matrix4x4 viewMat = _camera.worldToCameraMatrix;
|
||||
Matrix4x4 offset = Matrix4x4.identity;
|
||||
offset.SetTRS(previewScale * 0.3333f, Quaternion.identity, Vector3.one); // using only translation
|
||||
Matrix4x4 projMat = GL.GetGPUProjectionMatrix (_camera.projectionMatrix, true);
|
||||
prevViewProjMat = projMat * offset * viewMat;
|
||||
motionBlurMaterial.SetMatrix ("_PrevViewProj", prevViewProjMat);
|
||||
motionBlurMaterial.SetMatrix ("_ToPrevViewProjCombined", prevViewProjMat * invViewPrj);
|
||||
}
|
||||
|
||||
if (filterType == MotionBlurFilter.CameraMotion)
|
||||
{
|
||||
// build blur vector to be used in shader to create a global blur direction
|
||||
Vector4 blurVector = Vector4.zero;
|
||||
|
||||
float lookUpDown = Vector3.Dot (transform.up, Vector3.up);
|
||||
Vector3 distanceVector = prevFramePos-transform.position;
|
||||
|
||||
float distMag = distanceVector.magnitude;
|
||||
|
||||
float farHeur = 1.0f;
|
||||
|
||||
// pitch (vertical)
|
||||
farHeur = (Vector3.Angle (transform.up, prevFrameUp) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.x = rotationScale * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.up, prevFrameUp)));
|
||||
|
||||
// yaw #1 (horizontal, faded by pitch)
|
||||
farHeur = (Vector3.Angle (transform.forward, prevFrameForward) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.y = rotationScale * lookUpDown * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.forward, prevFrameForward)));
|
||||
|
||||
// yaw #2 (when looking down, faded by 1-pitch)
|
||||
farHeur = (Vector3.Angle (transform.forward, prevFrameForward) / _camera.fieldOfView) * (source.width * 0.75f);
|
||||
blurVector.z = rotationScale * (1.0f- lookUpDown) * farHeur;//Mathf.Clamp01((1.0ff-Vector3.Dot(transform.forward, prevFrameForward)));
|
||||
|
||||
if (distMag > Mathf.Epsilon && movementScale > Mathf.Epsilon) {
|
||||
// forward (probably most important)
|
||||
blurVector.w = movementScale * (Vector3.Dot (transform.forward, distanceVector) ) * (source.width * 0.5f);
|
||||
// jump (maybe scale down further)
|
||||
blurVector.x += movementScale * (Vector3.Dot (transform.up, distanceVector) ) * (source.width * 0.5f);
|
||||
// strafe (maybe scale down further)
|
||||
blurVector.y += movementScale * (Vector3.Dot (transform.right, distanceVector) ) * (source.width * 0.5f);
|
||||
}
|
||||
|
||||
if (preview) // crude approximation
|
||||
motionBlurMaterial.SetVector ("_BlurDirectionPacked", new Vector4 (previewScale.y, previewScale.x, 0.0f, previewScale.z) * 0.5f * _camera.fieldOfView);
|
||||
else
|
||||
motionBlurMaterial.SetVector ("_BlurDirectionPacked", blurVector);
|
||||
}
|
||||
else {
|
||||
// generate velocity buffer
|
||||
Graphics.Blit (source, velBuffer, motionBlurMaterial, 0);
|
||||
|
||||
// patch up velocity buffer:
|
||||
|
||||
// exclude certain layers (e.g. skinned objects as we cant really support that atm)
|
||||
|
||||
Camera cam = null;
|
||||
if (excludeLayers.value != 0)// || dynamicLayers.value)
|
||||
cam = GetTmpCam ();
|
||||
|
||||
if (cam && excludeLayers.value != 0 && replacementClear && replacementClear.isSupported) {
|
||||
cam.targetTexture = velBuffer;
|
||||
cam.cullingMask = excludeLayers;
|
||||
cam.RenderWithShader (replacementClear, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (!preview && Time.frameCount != prevFrameCount) {
|
||||
// remember current transformation data for next frame
|
||||
prevFrameCount = Time.frameCount;
|
||||
Remember ();
|
||||
}
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
// debug vel buffer:
|
||||
if (showVelocity) {
|
||||
// generate tile max and neighbour max
|
||||
//Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
//Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
motionBlurMaterial.SetFloat ("_DisplayVelocityScale", showVelocityScale);
|
||||
Graphics.Blit (velBuffer, destination, motionBlurMaterial, 1);
|
||||
}
|
||||
else {
|
||||
if (filterType == MotionBlurFilter.ReconstructionDX11 && !fallbackFromDX11) {
|
||||
// need to reset some parameters for dx11 shader
|
||||
dx11MotionBlurMaterial.SetFloat ("_MinVelocity", minVelocity);
|
||||
dx11MotionBlurMaterial.SetFloat ("_VelocityScale", velocityScale);
|
||||
dx11MotionBlurMaterial.SetFloat ("_Jitter", jitter);
|
||||
|
||||
// texture samplers
|
||||
dx11MotionBlurMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
dx11MotionBlurMaterial.SetTexture ("_VelTex", velBuffer);
|
||||
dx11MotionBlurMaterial.SetTexture ("_NeighbourMaxTex", neighbourMax);
|
||||
|
||||
dx11MotionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
dx11MotionBlurMaterial.SetFloat ("_MaxRadiusOrKInPaper", _maxVelocity);
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, dx11MotionBlurMaterial, 0);
|
||||
Graphics.Blit (tileMax, neighbourMax, dx11MotionBlurMaterial, 1);
|
||||
|
||||
// final blur
|
||||
Graphics.Blit (source, destination, dx11MotionBlurMaterial, 2);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.Reconstruction || fallbackFromDX11) {
|
||||
// 'reconstructing' properly integrated color
|
||||
motionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
|
||||
// final blur
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 4);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.CameraMotion) {
|
||||
// orange box style motion blur
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 6);
|
||||
}
|
||||
else if (filterType == MotionBlurFilter.ReconstructionDisc) {
|
||||
// dof style motion blur defocuing and ellipse around the princical blur direction
|
||||
// 'reconstructing' properly integrated color
|
||||
motionBlurMaterial.SetFloat ("_SoftZDistance", Mathf.Max(0.00025f, softZDistance) );
|
||||
|
||||
// generate tile max and neighbour max
|
||||
Graphics.Blit (velBuffer, tileMax, motionBlurMaterial, 2);
|
||||
Graphics.Blit (tileMax, neighbourMax, motionBlurMaterial, 3);
|
||||
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 7);
|
||||
}
|
||||
else {
|
||||
// simple & fast blur (low quality): just blurring along velocity
|
||||
Graphics.Blit (source, destination, motionBlurMaterial, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
RenderTexture.ReleaseTemporary (velBuffer);
|
||||
RenderTexture.ReleaseTemporary (tileMax);
|
||||
RenderTexture.ReleaseTemporary (neighbourMax);
|
||||
}
|
||||
|
||||
void Remember () {
|
||||
prevViewProjMat = currentViewProjMat;
|
||||
prevFrameForward = transform.forward;
|
||||
prevFrameUp = transform.up;
|
||||
prevFramePos = transform.position;
|
||||
}
|
||||
|
||||
Camera GetTmpCam () {
|
||||
if (tmpCam == null) {
|
||||
string name = "_" + _camera.name + "_MotionBlurTmpCam";
|
||||
GameObject go = GameObject.Find (name);
|
||||
if (null == go) // couldn't find, recreate
|
||||
tmpCam = new GameObject (name, typeof (Camera));
|
||||
else
|
||||
tmpCam = go;
|
||||
}
|
||||
|
||||
tmpCam.hideFlags = HideFlags.DontSave;
|
||||
tmpCam.transform.position = _camera.transform.position;
|
||||
tmpCam.transform.rotation = _camera.transform.rotation;
|
||||
tmpCam.transform.localScale = _camera.transform.localScale;
|
||||
tmpCam.GetComponent<Camera>().CopyFrom(_camera);
|
||||
|
||||
tmpCam.GetComponent<Camera>().enabled = false;
|
||||
tmpCam.GetComponent<Camera>().depthTextureMode = DepthTextureMode.None;
|
||||
tmpCam.GetComponent<Camera>().clearFlags = CameraClearFlags.Nothing;
|
||||
|
||||
return tmpCam.GetComponent<Camera>();
|
||||
}
|
||||
|
||||
void StartFrame () {
|
||||
// take only x% of positional changes into account (camera motion)
|
||||
// TODO: possibly do the same for rotational part
|
||||
prevFramePos = Vector3.Slerp(prevFramePos, transform.position, 0.75f);
|
||||
}
|
||||
|
||||
static int divRoundUp (int x, int d)
|
||||
{
|
||||
return (x + d - 1) / d;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97e9b95cf609d96409b6c40519432957
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 85a88efa8c871af4a9d17c64791b6f4f, type: 3}
|
||||
- dx11MotionBlurShader: {fileID: 4800000, guid: f1b13d7a80660504a858ea24cfa418c6,
|
||||
type: 3}
|
||||
- replacementClear: {fileID: 4800000, guid: 7699c5fbfa27745a1abe111ab7bf9785, type: 3}
|
||||
- noiseTexture: {fileID: 2800000, guid: 31f5a8611c4ed1245b18456206e798dc, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (Curves, Saturation)")]
|
||||
public class ColorCorrectionCurves : PostEffectsBase
|
||||
{
|
||||
public enum ColorCorrectionMode
|
||||
{
|
||||
Simple = 0,
|
||||
Advanced = 1
|
||||
}
|
||||
|
||||
public AnimationCurve redChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve greenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve blueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
|
||||
public bool useDepthCorrection = false;
|
||||
|
||||
public AnimationCurve zCurve = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthRedChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthGreenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
public AnimationCurve depthBlueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
|
||||
|
||||
private Material ccMaterial;
|
||||
private Material ccDepthMaterial;
|
||||
private Material selectiveCcMaterial;
|
||||
|
||||
private Texture2D rgbChannelTex;
|
||||
private Texture2D rgbDepthChannelTex;
|
||||
private Texture2D zCurveTex;
|
||||
|
||||
public float saturation = 1.0f;
|
||||
|
||||
public bool selectiveCc = false;
|
||||
|
||||
public Color selectiveFromColor = Color.white;
|
||||
public Color selectiveToColor = Color.white;
|
||||
|
||||
public ColorCorrectionMode mode;
|
||||
|
||||
public bool updateTextures = true;
|
||||
|
||||
public Shader colorCorrectionCurvesShader = null;
|
||||
public Shader simpleColorCorrectionCurvesShader = null;
|
||||
public Shader colorCorrectionSelectiveShader = null;
|
||||
|
||||
private bool updateTexturesOnStartup = true;
|
||||
|
||||
|
||||
new void Start ()
|
||||
{
|
||||
base.Start ();
|
||||
updateTexturesOnStartup = true;
|
||||
}
|
||||
|
||||
void Awake () { }
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (mode == ColorCorrectionMode.Advanced);
|
||||
|
||||
ccMaterial = CheckShaderAndCreateMaterial (simpleColorCorrectionCurvesShader, ccMaterial);
|
||||
ccDepthMaterial = CheckShaderAndCreateMaterial (colorCorrectionCurvesShader, ccDepthMaterial);
|
||||
selectiveCcMaterial = CheckShaderAndCreateMaterial (colorCorrectionSelectiveShader, selectiveCcMaterial);
|
||||
|
||||
if (!rgbChannelTex)
|
||||
rgbChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
|
||||
if (!rgbDepthChannelTex)
|
||||
rgbDepthChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
|
||||
if (!zCurveTex)
|
||||
zCurveTex = new Texture2D (256, 1, TextureFormat.ARGB32, false, true);
|
||||
|
||||
rgbChannelTex.hideFlags = HideFlags.DontSave;
|
||||
rgbDepthChannelTex.hideFlags = HideFlags.DontSave;
|
||||
zCurveTex.hideFlags = HideFlags.DontSave;
|
||||
|
||||
rgbChannelTex.wrapMode = TextureWrapMode.Clamp;
|
||||
rgbDepthChannelTex.wrapMode = TextureWrapMode.Clamp;
|
||||
zCurveTex.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public void UpdateParameters ()
|
||||
{
|
||||
CheckResources(); // textures might not be created if we're tweaking UI while disabled
|
||||
|
||||
if (redChannel != null && greenChannel != null && blueChannel != null)
|
||||
{
|
||||
for (float i = 0.0f; i <= 1.0f; i += 1.0f / 255.0f)
|
||||
{
|
||||
float rCh = Mathf.Clamp (redChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
float gCh = Mathf.Clamp (greenChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
float bCh = Mathf.Clamp (blueChannel.Evaluate(i), 0.0f, 1.0f);
|
||||
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
|
||||
rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
|
||||
|
||||
float zC = Mathf.Clamp (zCurve.Evaluate(i), 0.0f,1.0f);
|
||||
|
||||
zCurveTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(zC,zC,zC) );
|
||||
|
||||
rCh = Mathf.Clamp (depthRedChannel.Evaluate(i), 0.0f,1.0f);
|
||||
gCh = Mathf.Clamp (depthGreenChannel.Evaluate(i), 0.0f,1.0f);
|
||||
bCh = Mathf.Clamp (depthBlueChannel.Evaluate(i), 0.0f,1.0f);
|
||||
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
|
||||
rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
|
||||
}
|
||||
|
||||
rgbChannelTex.Apply ();
|
||||
rgbDepthChannelTex.Apply ();
|
||||
zCurveTex.Apply ();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTextures ()
|
||||
{
|
||||
UpdateParameters ();
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateTexturesOnStartup)
|
||||
{
|
||||
UpdateParameters ();
|
||||
updateTexturesOnStartup = false;
|
||||
}
|
||||
|
||||
if (useDepthCorrection)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
|
||||
RenderTexture renderTarget2Use = destination;
|
||||
|
||||
if (selectiveCc)
|
||||
{
|
||||
renderTarget2Use = RenderTexture.GetTemporary (source.width, source.height);
|
||||
}
|
||||
|
||||
if (useDepthCorrection)
|
||||
{
|
||||
ccDepthMaterial.SetTexture ("_RgbTex", rgbChannelTex);
|
||||
ccDepthMaterial.SetTexture ("_ZCurve", zCurveTex);
|
||||
ccDepthMaterial.SetTexture ("_RgbDepthTex", rgbDepthChannelTex);
|
||||
ccDepthMaterial.SetFloat ("_Saturation", saturation);
|
||||
|
||||
Graphics.Blit (source, renderTarget2Use, ccDepthMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccMaterial.SetTexture ("_RgbTex", rgbChannelTex);
|
||||
ccMaterial.SetFloat ("_Saturation", saturation);
|
||||
|
||||
Graphics.Blit (source, renderTarget2Use, ccMaterial);
|
||||
}
|
||||
|
||||
if (selectiveCc)
|
||||
{
|
||||
selectiveCcMaterial.SetColor ("selColor", selectiveFromColor);
|
||||
selectiveCcMaterial.SetColor ("targetColor", selectiveToColor);
|
||||
Graphics.Blit (renderTarget2Use, destination, selectiveCcMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (renderTarget2Use);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fd999d1b2cf94a45a5b0a47ce074bef
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- colorCorrectionCurvesShader: {fileID: 4800000, guid: 62bcade1028c24ca1a39760ed84b9487,
|
||||
type: 3}
|
||||
- simpleColorCorrectionCurvesShader: {fileID: 4800000, guid: 438ddd58d82c84d9eb1fdc56111702e1,
|
||||
type: 3}
|
||||
- colorCorrectionSelectiveShader: {fileID: 4800000, guid: e515e0f94cefc4c0db54b45cba621544,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (3D Lookup Texture)")]
|
||||
public class ColorCorrectionLookup : PostEffectsBase
|
||||
{
|
||||
public Shader shader;
|
||||
private Material material;
|
||||
|
||||
// serialize this instead of having another 2d texture ref'ed
|
||||
public Texture3D converted3DLut = null;
|
||||
public string basedOnTempTex = "";
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (false);
|
||||
|
||||
material = CheckShaderAndCreateMaterial (shader, material);
|
||||
|
||||
if (!isSupported || !SystemInfo.supports3DTextures)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (material) {
|
||||
DestroyImmediate (material);
|
||||
material = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy () {
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = null;
|
||||
}
|
||||
|
||||
public void SetIdentityLut () {
|
||||
int dim = 16;
|
||||
var newC = new Color[dim*dim*dim];
|
||||
float oneOverDim = 1.0f / (1.0f * dim - 1.0f);
|
||||
|
||||
for(int i = 0; i < dim; i++) {
|
||||
for(int j = 0; j < dim; j++) {
|
||||
for(int k = 0; k < dim; k++) {
|
||||
newC[i + (j*dim) + (k*dim*dim)] = new Color((i*1.0f)*oneOverDim, (j*1.0f)*oneOverDim, (k*1.0f)*oneOverDim, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
||||
converted3DLut.SetPixels (newC);
|
||||
converted3DLut.Apply ();
|
||||
basedOnTempTex = "";
|
||||
}
|
||||
|
||||
public bool ValidDimensions ( Texture2D tex2d) {
|
||||
if (!tex2d) return false;
|
||||
int h = tex2d.height;
|
||||
if (h != Mathf.FloorToInt(Mathf.Sqrt(tex2d.width))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Convert ( Texture2D temp2DTex, string path) {
|
||||
|
||||
// conversion fun: the given 2D texture needs to be of the format
|
||||
// w * h, wheras h is the 'depth' (or 3d dimension 'dim') and w = dim * dim
|
||||
|
||||
if (temp2DTex) {
|
||||
int dim = temp2DTex.width * temp2DTex.height;
|
||||
dim = temp2DTex.height;
|
||||
|
||||
if (!ValidDimensions(temp2DTex)) {
|
||||
Debug.LogWarning ("The given 2D texture " + temp2DTex.name + " cannot be used as a 3D LUT.");
|
||||
basedOnTempTex = "";
|
||||
return;
|
||||
}
|
||||
|
||||
var c = temp2DTex.GetPixels();
|
||||
var newC = new Color[c.Length];
|
||||
|
||||
for(int i = 0; i < dim; i++) {
|
||||
for(int j = 0; j < dim; j++) {
|
||||
for(int k = 0; k < dim; k++) {
|
||||
int j_ = dim-j-1;
|
||||
newC[i + (j*dim) + (k*dim*dim)] = c[k*dim+i+j_*dim*dim];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (converted3DLut)
|
||||
DestroyImmediate (converted3DLut);
|
||||
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
||||
converted3DLut.SetPixels (newC);
|
||||
converted3DLut.Apply ();
|
||||
basedOnTempTex = path;
|
||||
}
|
||||
else {
|
||||
// error, something went terribly wrong
|
||||
Debug.LogError ("Couldn't color correct with 3D LUT texture. Image Effect will be disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources () == false || !SystemInfo.supports3DTextures) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (converted3DLut == null) {
|
||||
SetIdentityLut ();
|
||||
}
|
||||
|
||||
int lutSize = converted3DLut.width;
|
||||
converted3DLut.wrapMode = TextureWrapMode.Clamp;
|
||||
material.SetFloat("_Scale", (lutSize - 1) / (1.0f*lutSize));
|
||||
material.SetFloat("_Offset", 1.0f / (2.0f * lutSize));
|
||||
material.SetTexture("_ClutTex", converted3DLut);
|
||||
|
||||
Graphics.Blit (source, destination, material, QualitySettings.activeColorSpace == ColorSpace.Linear ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cde8c0fd649d9b46bb403ba5e157391
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: b61f0d8d8244b4b28aa66b0c8cb46a8d, type: 3}
|
||||
- converted3DLut: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Color Correction (Ramp)")]
|
||||
public class ColorCorrectionRamp : ImageEffectBase {
|
||||
public Texture textureRamp;
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
material.SetTexture ("_RampTex", textureRamp);
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea59781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 67f8781cad112c75d0008dfa8d76c639, type: 3}
|
||||
- textureRamp: {fileID: 2800000, guid: d440902fad11e807d00044888d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Contrast Enhance (Unsharp Mask)")]
|
||||
public class ContrastEnhance : PostEffectsBase
|
||||
{
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float intensity = 0.5f;
|
||||
[Range(0.0f,0.999f)]
|
||||
public float threshold = 0.0f;
|
||||
|
||||
private Material separableBlurMaterial;
|
||||
private Material contrastCompositeMaterial;
|
||||
|
||||
[Range(0.0f,1.0f)]
|
||||
public float blurSpread = 1.0f;
|
||||
|
||||
public Shader separableBlurShader = null;
|
||||
public Shader contrastCompositeShader = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
contrastCompositeMaterial = CheckShaderAndCreateMaterial (contrastCompositeShader, contrastCompositeMaterial);
|
||||
separableBlurMaterial = CheckShaderAndCreateMaterial (separableBlurShader, separableBlurMaterial);
|
||||
|
||||
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;
|
||||
|
||||
RenderTexture color2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
|
||||
// downsample
|
||||
|
||||
Graphics.Blit (source, color2);
|
||||
RenderTexture color4a = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color2, color4a);
|
||||
RenderTexture.ReleaseTemporary (color2);
|
||||
|
||||
// blur
|
||||
|
||||
separableBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, (blurSpread * 1.0f) / color4a.height, 0.0f, 0.0f));
|
||||
RenderTexture color4b = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color4a, color4b, separableBlurMaterial);
|
||||
RenderTexture.ReleaseTemporary (color4a);
|
||||
|
||||
separableBlurMaterial.SetVector ("offsets", new Vector4 ((blurSpread * 1.0f) / color4a.width, 0.0f, 0.0f, 0.0f));
|
||||
color4a = RenderTexture.GetTemporary (rtW/4, rtH/4, 0);
|
||||
Graphics.Blit (color4b, color4a, separableBlurMaterial);
|
||||
RenderTexture.ReleaseTemporary (color4b);
|
||||
|
||||
// composite
|
||||
|
||||
contrastCompositeMaterial.SetTexture ("_MainTexBlurred", color4a);
|
||||
contrastCompositeMaterial.SetFloat ("intensity", intensity);
|
||||
contrastCompositeMaterial.SetFloat ("threshold", threshold);
|
||||
Graphics.Blit (source, destination, contrastCompositeMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (color4a);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3309686a9fbbe6e42a182d5e0257704c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- separableBlurShader: {fileID: 4800000, guid: e97c14fbb5ea04c3a902cc533d7fc5d1,
|
||||
type: 3}
|
||||
- contrastCompositeShader: {fileID: 4800000, guid: 273404942eede4ea1883ca1fb2942507,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Contrast Stretch")]
|
||||
public class ContrastStretch : MonoBehaviour
|
||||
{
|
||||
/// Adaptation speed - percents per frame, if playing at 30FPS.
|
||||
/// Default is 0.02 (2% each 1/30s).
|
||||
[Range(0.0001f, 1.0f)]
|
||||
public float adaptationSpeed = 0.02f;
|
||||
|
||||
/// If our scene is really dark (or really bright), we might not want to
|
||||
/// stretch its contrast to the full range.
|
||||
/// limitMinimum=0, limitMaximum=1 is the same as not applying the effect at all.
|
||||
/// limitMinimum=1, limitMaximum=0 is always stretching colors to full range.
|
||||
|
||||
/// The limit on the minimum luminance (0...1) - we won't go above this.
|
||||
[Range(0.0f,1.0f)]
|
||||
public float limitMinimum = 0.2f;
|
||||
|
||||
/// The limit on the maximum luminance (0...1) - we won't go below this.
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float limitMaximum = 0.6f;
|
||||
|
||||
|
||||
// To maintain adaptation levels over time, we need two 1x1 render textures
|
||||
// and ping-pong between them.
|
||||
private RenderTexture[] adaptRenderTex = new RenderTexture[2];
|
||||
private int curAdaptIndex = 0;
|
||||
|
||||
|
||||
// Computes scene luminance (grayscale) image
|
||||
public Shader shaderLum;
|
||||
private Material m_materialLum;
|
||||
protected Material materialLum {
|
||||
get {
|
||||
if ( m_materialLum == null ) {
|
||||
m_materialLum = new Material(shaderLum);
|
||||
m_materialLum.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialLum;
|
||||
}
|
||||
}
|
||||
|
||||
// Reduces size of the image by 2x2, while computing maximum/minimum values.
|
||||
// By repeatedly applying this shader, we reduce the initial luminance image
|
||||
// to 1x1 image with minimum/maximum luminances found.
|
||||
public Shader shaderReduce;
|
||||
private Material m_materialReduce;
|
||||
protected Material materialReduce {
|
||||
get {
|
||||
if ( m_materialReduce == null ) {
|
||||
m_materialReduce = new Material(shaderReduce);
|
||||
m_materialReduce.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialReduce;
|
||||
}
|
||||
}
|
||||
|
||||
// Adaptation shader - gradually "adapts" minimum/maximum luminances,
|
||||
// based on currently adapted 1x1 image and the actual 1x1 image of the current scene.
|
||||
public Shader shaderAdapt;
|
||||
private Material m_materialAdapt;
|
||||
protected Material materialAdapt {
|
||||
get {
|
||||
if ( m_materialAdapt == null ) {
|
||||
m_materialAdapt = new Material(shaderAdapt);
|
||||
m_materialAdapt.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialAdapt;
|
||||
}
|
||||
}
|
||||
|
||||
// Final pass - stretches the color values of the original scene, based on currently
|
||||
// adpated minimum/maximum values.
|
||||
public Shader shaderApply;
|
||||
private Material m_materialApply;
|
||||
protected Material materialApply {
|
||||
get {
|
||||
if ( m_materialApply == null ) {
|
||||
m_materialApply = new Material(shaderApply);
|
||||
m_materialApply.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return m_materialApply;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shaderAdapt.isSupported || !shaderApply.isSupported || !shaderLum.isSupported || !shaderReduce.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
if ( !adaptRenderTex[i] ) {
|
||||
adaptRenderTex[i] = new RenderTexture(1, 1, 0);
|
||||
adaptRenderTex[i].hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
DestroyImmediate( adaptRenderTex[i] );
|
||||
adaptRenderTex[i] = null;
|
||||
}
|
||||
if ( m_materialLum )
|
||||
DestroyImmediate( m_materialLum );
|
||||
if ( m_materialReduce )
|
||||
DestroyImmediate( m_materialReduce );
|
||||
if ( m_materialAdapt )
|
||||
DestroyImmediate( m_materialAdapt );
|
||||
if ( m_materialApply )
|
||||
DestroyImmediate( m_materialApply );
|
||||
}
|
||||
|
||||
|
||||
/// Apply the filter
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
// Blit to smaller RT and convert to luminance on the way
|
||||
const int TEMP_RATIO = 1; // 4x4 smaller
|
||||
RenderTexture rtTempSrc = RenderTexture.GetTemporary(source.width/TEMP_RATIO, source.height/TEMP_RATIO);
|
||||
Graphics.Blit (source, rtTempSrc, materialLum);
|
||||
|
||||
// Repeatedly reduce this image in size, computing min/max luminance values
|
||||
// In the end we'll have 1x1 image with min/max luminances found.
|
||||
const int FINAL_SIZE = 1;
|
||||
//const int FINAL_SIZE = 1;
|
||||
while( rtTempSrc.width > FINAL_SIZE || rtTempSrc.height > FINAL_SIZE )
|
||||
{
|
||||
const int REDUCE_RATIO = 2; // our shader does 2x2 reduction
|
||||
int destW = rtTempSrc.width / REDUCE_RATIO;
|
||||
if ( destW < FINAL_SIZE ) destW = FINAL_SIZE;
|
||||
int destH = rtTempSrc.height / REDUCE_RATIO;
|
||||
if ( destH < FINAL_SIZE ) destH = FINAL_SIZE;
|
||||
RenderTexture rtTempDst = RenderTexture.GetTemporary(destW,destH);
|
||||
Graphics.Blit (rtTempSrc, rtTempDst, materialReduce);
|
||||
|
||||
// Release old src temporary, and make new temporary the source
|
||||
RenderTexture.ReleaseTemporary( rtTempSrc );
|
||||
rtTempSrc = rtTempDst;
|
||||
}
|
||||
|
||||
// Update viewer's adaptation level
|
||||
CalculateAdaptation( rtTempSrc );
|
||||
|
||||
// Apply contrast strech to the original scene, using currently adapted parameters
|
||||
materialApply.SetTexture("_AdaptTex", adaptRenderTex[curAdaptIndex] );
|
||||
Graphics.Blit (source, destination, materialApply);
|
||||
|
||||
RenderTexture.ReleaseTemporary( rtTempSrc );
|
||||
}
|
||||
|
||||
|
||||
/// Helper function to do gradual adaptation to min/max luminances
|
||||
private void CalculateAdaptation( Texture curTexture )
|
||||
{
|
||||
int prevAdaptIndex = curAdaptIndex;
|
||||
curAdaptIndex = (curAdaptIndex+1) % 2;
|
||||
|
||||
// Adaptation speed is expressed in percents/frame, based on 30FPS.
|
||||
// Calculate the adaptation lerp, based on current FPS.
|
||||
float adaptLerp = 1.0f - Mathf.Pow( 1.0f - adaptationSpeed, 30.0f * Time.deltaTime );
|
||||
const float kMinAdaptLerp = 0.01f;
|
||||
adaptLerp = Mathf.Clamp( adaptLerp, kMinAdaptLerp, 1 );
|
||||
|
||||
materialAdapt.SetTexture("_CurTex", curTexture );
|
||||
materialAdapt.SetVector("_AdaptParams", new Vector4(
|
||||
adaptLerp,
|
||||
limitMinimum,
|
||||
limitMaximum,
|
||||
0.0f
|
||||
));
|
||||
// clear destination RT so its contents don't need to be restored
|
||||
Graphics.SetRenderTarget(adaptRenderTex[curAdaptIndex]);
|
||||
GL.Clear(false, true, Color.black);
|
||||
Graphics.Blit (
|
||||
adaptRenderTex[prevAdaptIndex],
|
||||
adaptRenderTex[curAdaptIndex],
|
||||
materialAdapt);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec92b071d2d424aecb3e46f28eb63174
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shaderLum: {fileID: 4800000, guid: befbb4b9c320b4b18a08ef7afb93b6c9, type: 3}
|
||||
- shaderReduce: {fileID: 4800000, guid: 57b33a14b6d5347c5a85c36f6cb3b280, type: 3}
|
||||
- shaderAdapt: {fileID: 4800000, guid: 257bc83cbeb544540bd0e558aa9b1383, type: 3}
|
||||
- shaderApply: {fileID: 4800000, guid: f4901f25d4e1542589348bbb89563d8e, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Edge Detection/Crease Shading")]
|
||||
public class CreaseShading : PostEffectsBase
|
||||
{
|
||||
public float intensity = 0.5f;
|
||||
public int softness = 1;
|
||||
public float spread = 1.0f;
|
||||
|
||||
public Shader blurShader = null;
|
||||
private Material blurMaterial = null;
|
||||
|
||||
public Shader depthFetchShader = null;
|
||||
private Material depthFetchMaterial = null;
|
||||
|
||||
public Shader creaseApplyShader = null;
|
||||
private Material creaseApplyMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
blurMaterial = CheckShaderAndCreateMaterial (blurShader, blurMaterial);
|
||||
depthFetchMaterial = CheckShaderAndCreateMaterial (depthFetchShader, depthFetchMaterial);
|
||||
creaseApplyMaterial = CheckShaderAndCreateMaterial (creaseApplyShader, creaseApplyMaterial);
|
||||
|
||||
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;
|
||||
|
||||
float widthOverHeight = (1.0f * rtW) / (1.0f * rtH);
|
||||
float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
RenderTexture hrTex = RenderTexture.GetTemporary (rtW, rtH, 0);
|
||||
RenderTexture lrTex1 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
|
||||
Graphics.Blit (source,hrTex, depthFetchMaterial);
|
||||
Graphics.Blit (hrTex, lrTex1);
|
||||
|
||||
for(int i = 0; i < softness; i++)
|
||||
{
|
||||
RenderTexture lrTex2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
blurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (lrTex1, lrTex2, blurMaterial);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
lrTex1 = lrTex2;
|
||||
|
||||
lrTex2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0);
|
||||
blurMaterial.SetVector ("offsets", new Vector4 (spread * oneOverBaseSize / widthOverHeight, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (lrTex1, lrTex2, blurMaterial);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
lrTex1 = lrTex2;
|
||||
}
|
||||
|
||||
creaseApplyMaterial.SetTexture ("_HrDepthTex", hrTex);
|
||||
creaseApplyMaterial.SetTexture ("_LrDepthTex", lrTex1);
|
||||
creaseApplyMaterial.SetFloat ("intensity", intensity);
|
||||
Graphics.Blit (source,destination, creaseApplyMaterial);
|
||||
|
||||
RenderTexture.ReleaseTemporary (hrTex);
|
||||
RenderTexture.ReleaseTemporary (lrTex1);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d64b4f3a592f28b44bf19223ac8b6cd2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- blurShader: {fileID: 4800000, guid: e97c14fbb5ea04c3a902cc533d7fc5d1, type: 3}
|
||||
- depthFetchShader: {fileID: 4800000, guid: 14768d3865b1342e3a861fbe19ba2db2, type: 3}
|
||||
- creaseApplyShader: {fileID: 4800000, guid: b59984d82af624bd3b0c777f038276f2, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Depth of Field (Lens Blur, Scatter, DX11)") ]
|
||||
public class DepthOfField : PostEffectsBase {
|
||||
|
||||
public bool visualizeFocus = false;
|
||||
public float focalLength = 10.0f;
|
||||
public float focalSize = 0.05f;
|
||||
public float aperture = 0.5f;
|
||||
public Transform focalTransform = null;
|
||||
public float maxBlurSize = 2.0f;
|
||||
public bool highResolution = false;
|
||||
|
||||
public enum BlurType {
|
||||
DiscBlur = 0,
|
||||
DX11 = 1,
|
||||
}
|
||||
|
||||
public enum BlurSampleCount {
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
public BlurType blurType = BlurType.DiscBlur;
|
||||
public BlurSampleCount blurSampleCount = BlurSampleCount.High;
|
||||
|
||||
public bool nearBlur = false;
|
||||
public float foregroundOverlap = 1.0f;
|
||||
|
||||
public Shader dofHdrShader;
|
||||
private Material dofHdrMaterial = null;
|
||||
|
||||
public Shader dx11BokehShader;
|
||||
private Material dx11bokehMaterial;
|
||||
|
||||
public float dx11BokehThreshold = 0.5f;
|
||||
public float dx11SpawnHeuristic = 0.0875f;
|
||||
public Texture2D dx11BokehTexture = null;
|
||||
public float dx11BokehScale = 1.2f;
|
||||
public float dx11BokehIntensity = 2.5f;
|
||||
|
||||
private float focalDistance01 = 10.0f;
|
||||
private ComputeBuffer cbDrawArgs;
|
||||
private ComputeBuffer cbPoints;
|
||||
private float internalBlurWidth = 1.0f;
|
||||
|
||||
private Camera cachedCamera;
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true); // only requires depth, not HDR
|
||||
|
||||
dofHdrMaterial = CheckShaderAndCreateMaterial (dofHdrShader, dofHdrMaterial);
|
||||
if (supportDX11 && blurType == BlurType.DX11) {
|
||||
dx11bokehMaterial = CheckShaderAndCreateMaterial(dx11BokehShader, dx11bokehMaterial);
|
||||
CreateComputeResources ();
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
cachedCamera = GetComponent<Camera>();
|
||||
cachedCamera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
ReleaseComputeResources ();
|
||||
|
||||
if (dofHdrMaterial) DestroyImmediate(dofHdrMaterial);
|
||||
dofHdrMaterial = null;
|
||||
if (dx11bokehMaterial) DestroyImmediate(dx11bokehMaterial);
|
||||
dx11bokehMaterial = null;
|
||||
}
|
||||
|
||||
void ReleaseComputeResources () {
|
||||
if (cbDrawArgs != null) cbDrawArgs.Release();
|
||||
cbDrawArgs = null;
|
||||
if (cbPoints != null) cbPoints.Release();
|
||||
cbPoints = null;
|
||||
}
|
||||
|
||||
void CreateComputeResources () {
|
||||
if (cbDrawArgs == null)
|
||||
{
|
||||
cbDrawArgs = new ComputeBuffer (1, 16, ComputeBufferType.IndirectArguments);
|
||||
var args= new int[4];
|
||||
args[0] = 0; args[1] = 1; args[2] = 0; args[3] = 0;
|
||||
cbDrawArgs.SetData (args);
|
||||
}
|
||||
if (cbPoints == null)
|
||||
{
|
||||
cbPoints = new ComputeBuffer (90000, 12+16, ComputeBufferType.Append);
|
||||
}
|
||||
}
|
||||
|
||||
float FocalDistance01 ( float worldDist) {
|
||||
return cachedCamera.WorldToViewportPoint((worldDist-cachedCamera.nearClipPlane) * cachedCamera.transform.forward + cachedCamera.transform.position).z / (cachedCamera.farClipPlane-cachedCamera.nearClipPlane);
|
||||
}
|
||||
|
||||
private void WriteCoc ( RenderTexture fromTo, bool fgDilate) {
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", null);
|
||||
|
||||
if (nearBlur && fgDilate) {
|
||||
|
||||
int rtW = fromTo.width/2;
|
||||
int rtH = fromTo.height/2;
|
||||
|
||||
// capture fg coc
|
||||
RenderTexture temp2 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (fromTo, temp2, dofHdrMaterial, 4);
|
||||
|
||||
// special blur
|
||||
float fgAdjustment = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgAdjustment , 0.0f, fgAdjustment));
|
||||
RenderTexture temp1 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (temp2, temp1, dofHdrMaterial, 2);
|
||||
RenderTexture.ReleaseTemporary(temp2);
|
||||
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgAdjustment, 0.0f, 0.0f, fgAdjustment));
|
||||
temp2 = RenderTexture.GetTemporary (rtW, rtH, 0, fromTo.format);
|
||||
Graphics.Blit (temp1, temp2, dofHdrMaterial, 2);
|
||||
RenderTexture.ReleaseTemporary(temp1);
|
||||
|
||||
// "merge up" with background COC
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", temp2);
|
||||
fromTo.MarkRestoreExpected(); // only touching alpha channel, RT restore expected
|
||||
Graphics.Blit (fromTo, fromTo, dofHdrMaterial, 13);
|
||||
RenderTexture.ReleaseTemporary(temp2);
|
||||
}
|
||||
else {
|
||||
// capture full coc in alpha channel (fromTo is not read, but bound to detect screen flip)
|
||||
fromTo.MarkRestoreExpected(); // only touching alpha channel, RT restore expected
|
||||
Graphics.Blit (fromTo, fromTo, dofHdrMaterial, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (!CheckResources ()) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// clamp & prepare values so they make sense
|
||||
|
||||
if (aperture < 0.0f) aperture = 0.0f;
|
||||
if (maxBlurSize < 0.1f) maxBlurSize = 0.1f;
|
||||
focalSize = Mathf.Clamp(focalSize, 0.0f, 2.0f);
|
||||
internalBlurWidth = Mathf.Max(maxBlurSize, 0.0f);
|
||||
|
||||
// focal & coc calculations
|
||||
|
||||
focalDistance01 = (focalTransform) ? (cachedCamera.WorldToViewportPoint (focalTransform.position)).z / (cachedCamera.farClipPlane) : FocalDistance01 (focalLength);
|
||||
dofHdrMaterial.SetVector("_CurveParams", new Vector4(1.0f, focalSize, (1.0f / (1.0f - aperture) - 1.0f), focalDistance01));
|
||||
|
||||
// possible render texture helpers
|
||||
|
||||
RenderTexture rtLow = null;
|
||||
RenderTexture rtLow2 = null;
|
||||
RenderTexture rtSuperLow1 = null;
|
||||
RenderTexture rtSuperLow2 = null;
|
||||
float fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
if (visualizeFocus)
|
||||
{
|
||||
|
||||
//
|
||||
// 2.
|
||||
// visualize coc
|
||||
//
|
||||
//
|
||||
|
||||
WriteCoc (source, true);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, 16);
|
||||
}
|
||||
else if ((blurType == BlurType.DX11) && dx11bokehMaterial)
|
||||
{
|
||||
|
||||
//
|
||||
// 1.
|
||||
// optimized dx11 bokeh scatter
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
if (highResolution) {
|
||||
|
||||
internalBlurWidth = internalBlurWidth < 0.1f ? 0.1f : internalBlurWidth;
|
||||
fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
rtLow = RenderTexture.GetTemporary (source.width, source.height, 0, source.format);
|
||||
|
||||
var dest2= RenderTexture.GetTemporary (source.width, source.height, 0, source.format);
|
||||
|
||||
// capture COC
|
||||
WriteCoc (source, false);
|
||||
|
||||
// blur a bit so we can do a frequency check
|
||||
rtSuperLow1 = RenderTexture.GetTemporary(source.width>>1, source.height>>1, 0, source.format);
|
||||
rtSuperLow2 = RenderTexture.GetTemporary(source.width>>1, source.height>>1, 0, source.format);
|
||||
|
||||
Graphics.Blit(source, rtSuperLow1, dofHdrMaterial, 15);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, 1.5f , 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 19);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (1.5f, 0.0f, 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 19);
|
||||
|
||||
// capture fg coc
|
||||
if (nearBlur)
|
||||
Graphics.Blit (source, rtSuperLow2, dofHdrMaterial, 4);
|
||||
|
||||
dx11bokehMaterial.SetTexture ("_BlurredColor", rtSuperLow1);
|
||||
dx11bokehMaterial.SetFloat ("_SpawnHeuristic", dx11SpawnHeuristic);
|
||||
dx11bokehMaterial.SetVector ("_BokehParams", new Vector4(dx11BokehScale, dx11BokehIntensity, Mathf.Clamp(dx11BokehThreshold, 0.005f, 4.0f), internalBlurWidth));
|
||||
dx11bokehMaterial.SetTexture ("_FgCocMask", nearBlur ? rtSuperLow2 : null);
|
||||
|
||||
// collect bokeh candidates and replace with a darker pixel
|
||||
Graphics.SetRandomWriteTarget (1, cbPoints);
|
||||
Graphics.Blit (source, rtLow, dx11bokehMaterial, 0);
|
||||
Graphics.ClearRandomWriteTargets ();
|
||||
|
||||
// fg coc blur happens here (after collect!)
|
||||
if (nearBlur) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgBlurDist , 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 2);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgBlurDist, 0.0f, 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 2);
|
||||
|
||||
// merge fg coc with bg coc
|
||||
Graphics.Blit (rtSuperLow2, rtLow, dofHdrMaterial, 3);
|
||||
}
|
||||
|
||||
// NEW: LAY OUT ALPHA on destination target so we get nicer outlines for the high rez version
|
||||
Graphics.Blit (rtLow, dest2, dofHdrMaterial, 20);
|
||||
|
||||
// box blur (easier to merge with bokeh buffer)
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (internalBlurWidth, 0.0f , 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow, source, dofHdrMaterial, 5);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (source, dest2, dofHdrMaterial, 21);
|
||||
|
||||
// apply bokeh candidates
|
||||
Graphics.SetRenderTarget (dest2);
|
||||
ComputeBuffer.CopyCount (cbPoints, cbDrawArgs, 0);
|
||||
dx11bokehMaterial.SetBuffer ("pointBuffer", cbPoints);
|
||||
dx11bokehMaterial.SetTexture ("_MainTex", dx11BokehTexture);
|
||||
dx11bokehMaterial.SetVector ("_Screen", new Vector3(1.0f/(1.0f*source.width), 1.0f/(1.0f*source.height), internalBlurWidth));
|
||||
dx11bokehMaterial.SetPass (2);
|
||||
|
||||
Graphics.DrawProceduralIndirectNow (MeshTopology.Points, cbDrawArgs, 0);
|
||||
|
||||
Graphics.Blit (dest2, destination); // hackaround for DX11 high resolution flipfun (OPTIMIZEME)
|
||||
|
||||
RenderTexture.ReleaseTemporary(dest2);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow1);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow2);
|
||||
}
|
||||
else {
|
||||
rtLow = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
rtLow2 = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
|
||||
fgBlurDist = internalBlurWidth * foregroundOverlap;
|
||||
|
||||
// capture COC & color in low resolution
|
||||
WriteCoc (source, false);
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
Graphics.Blit (source, rtLow, dofHdrMaterial, 6);
|
||||
|
||||
// blur a bit so we can do a frequency check
|
||||
rtSuperLow1 = RenderTexture.GetTemporary(rtLow.width>>1, rtLow.height>>1, 0, rtLow.format);
|
||||
rtSuperLow2 = RenderTexture.GetTemporary(rtLow.width>>1, rtLow.height>>1, 0, rtLow.format);
|
||||
|
||||
Graphics.Blit(rtLow, rtSuperLow1, dofHdrMaterial, 15);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, 1.5f , 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow1, rtSuperLow2, dofHdrMaterial, 19);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (1.5f, 0.0f, 0.0f, 1.5f));
|
||||
Graphics.Blit (rtSuperLow2, rtSuperLow1, dofHdrMaterial, 19);
|
||||
|
||||
RenderTexture rtLow3 = null;
|
||||
|
||||
if (nearBlur) {
|
||||
// capture fg coc
|
||||
rtLow3 = RenderTexture.GetTemporary (source.width>>1, source.height>>1, 0, source.format);
|
||||
Graphics.Blit (source, rtLow3, dofHdrMaterial, 4);
|
||||
}
|
||||
|
||||
dx11bokehMaterial.SetTexture ("_BlurredColor", rtSuperLow1);
|
||||
dx11bokehMaterial.SetFloat ("_SpawnHeuristic", dx11SpawnHeuristic);
|
||||
dx11bokehMaterial.SetVector ("_BokehParams", new Vector4(dx11BokehScale, dx11BokehIntensity, Mathf.Clamp(dx11BokehThreshold, 0.005f, 4.0f), internalBlurWidth));
|
||||
dx11bokehMaterial.SetTexture ("_FgCocMask", rtLow3);
|
||||
|
||||
// collect bokeh candidates and replace with a darker pixel
|
||||
Graphics.SetRandomWriteTarget (1, cbPoints);
|
||||
Graphics.Blit (rtLow, rtLow2, dx11bokehMaterial, 0);
|
||||
Graphics.ClearRandomWriteTargets ();
|
||||
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow1);
|
||||
RenderTexture.ReleaseTemporary(rtSuperLow2);
|
||||
|
||||
// fg coc blur happens here (after collect!)
|
||||
if (nearBlur) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, fgBlurDist , 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtLow3, rtLow, dofHdrMaterial, 2);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (fgBlurDist, 0.0f, 0.0f, fgBlurDist));
|
||||
Graphics.Blit (rtLow, rtLow3, dofHdrMaterial, 2);
|
||||
|
||||
// merge fg coc with bg coc
|
||||
Graphics.Blit (rtLow3, rtLow2, dofHdrMaterial, 3);
|
||||
}
|
||||
|
||||
// box blur (easier to merge with bokeh buffer)
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (internalBlurWidth, 0.0f , 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow2, rtLow, dofHdrMaterial, 5);
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.0f, internalBlurWidth));
|
||||
Graphics.Blit (rtLow, rtLow2, dofHdrMaterial, 5);
|
||||
|
||||
// apply bokeh candidates
|
||||
Graphics.SetRenderTarget (rtLow2);
|
||||
ComputeBuffer.CopyCount (cbPoints, cbDrawArgs, 0);
|
||||
dx11bokehMaterial.SetBuffer ("pointBuffer", cbPoints);
|
||||
dx11bokehMaterial.SetTexture ("_MainTex", dx11BokehTexture);
|
||||
dx11bokehMaterial.SetVector ("_Screen", new Vector3(1.0f/(1.0f*rtLow2.width), 1.0f/(1.0f*rtLow2.height), internalBlurWidth));
|
||||
dx11bokehMaterial.SetPass (1);
|
||||
Graphics.DrawProceduralIndirectNow (MeshTopology.Points, cbDrawArgs, 0);
|
||||
|
||||
// upsample & combine
|
||||
dofHdrMaterial.SetTexture ("_LowRez", rtLow2);
|
||||
dofHdrMaterial.SetTexture ("_FgOverlap", rtLow3);
|
||||
dofHdrMaterial.SetVector ("_Offsets", ((1.0f*source.width)/(1.0f*rtLow2.width)) * internalBlurWidth * Vector4.one);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, 9);
|
||||
|
||||
if (rtLow3) RenderTexture.ReleaseTemporary(rtLow3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//
|
||||
// 2.
|
||||
// poisson disc style blur in low resolution
|
||||
//
|
||||
//
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
if (highResolution) internalBlurWidth *= 2.0f;
|
||||
|
||||
WriteCoc (source, true);
|
||||
|
||||
rtLow = RenderTexture.GetTemporary (source.width >> 1, source.height >> 1, 0, source.format);
|
||||
rtLow2 = RenderTexture.GetTemporary (source.width >> 1, source.height >> 1, 0, source.format);
|
||||
|
||||
int blurPass = (blurSampleCount == BlurSampleCount.High || blurSampleCount == BlurSampleCount.Medium) ? 17 : 11;
|
||||
|
||||
if (highResolution) {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.025f, internalBlurWidth));
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, blurPass);
|
||||
}
|
||||
else {
|
||||
dofHdrMaterial.SetVector ("_Offsets", new Vector4 (0.0f, internalBlurWidth, 0.1f, internalBlurWidth));
|
||||
|
||||
// blur
|
||||
Graphics.Blit (source, rtLow, dofHdrMaterial, 6);
|
||||
Graphics.Blit (rtLow, rtLow2, dofHdrMaterial, blurPass);
|
||||
|
||||
// cheaper blur in high resolution, upsample and combine
|
||||
dofHdrMaterial.SetTexture("_LowRez", rtLow2);
|
||||
dofHdrMaterial.SetTexture("_FgOverlap", null);
|
||||
dofHdrMaterial.SetVector ("_Offsets", Vector4.one * ((1.0f*source.width)/(1.0f*rtLow2.width)) * internalBlurWidth);
|
||||
Graphics.Blit (source, destination, dofHdrMaterial, blurSampleCount == BlurSampleCount.High ? 18 : 12);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtLow) RenderTexture.ReleaseTemporary(rtLow);
|
||||
if (rtLow2) RenderTexture.ReleaseTemporary(rtLow2);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd70d448b18cfbc46af26466f752332c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- focalTransform: {instanceID: 0}
|
||||
- dofHdrShader: {fileID: 4800000, guid: acd613035ff3e455e8abf23fdc8c8c24, type: 3}
|
||||
- dx11BokehShader: {fileID: 4800000, guid: d8e82664aa8686642a424c88ab10164a, type: 3}
|
||||
- dx11BokehTexture: {fileID: 2800000, guid: a4cdca73d61814d33ac1587f6c163bca, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Depth of Field (deprecated)") ]
|
||||
public class DepthOfFieldDeprecated : PostEffectsBase
|
||||
{
|
||||
public enum Dof34QualitySetting
|
||||
{
|
||||
OnlyBackground = 1,
|
||||
BackgroundAndForeground = 2,
|
||||
}
|
||||
|
||||
public enum DofResolution
|
||||
{
|
||||
High = 2,
|
||||
Medium = 3,
|
||||
Low = 4,
|
||||
}
|
||||
|
||||
public enum DofBlurriness
|
||||
{
|
||||
Low = 1,
|
||||
High = 2,
|
||||
VeryHigh = 4,
|
||||
}
|
||||
|
||||
public enum BokehDestination
|
||||
{
|
||||
Background = 0x1,
|
||||
Foreground = 0x2,
|
||||
BackgroundAndForeground = 0x3,
|
||||
}
|
||||
|
||||
static private int SMOOTH_DOWNSAMPLE_PASS = 6;
|
||||
static private float BOKEH_EXTRA_BLUR = 2.0f;
|
||||
|
||||
public Dof34QualitySetting quality = Dof34QualitySetting.OnlyBackground;
|
||||
public DofResolution resolution = DofResolution.Low;
|
||||
public bool simpleTweakMode = true;
|
||||
|
||||
public float focalPoint = 1.0f;
|
||||
public float smoothness = 0.5f;
|
||||
|
||||
public float focalZDistance = 0.0f;
|
||||
public float focalZStartCurve = 1.0f;
|
||||
public float focalZEndCurve = 1.0f;
|
||||
|
||||
private float focalStartCurve = 2.0f;
|
||||
private float focalEndCurve = 2.0f;
|
||||
private float focalDistance01 = 0.1f;
|
||||
|
||||
public Transform objectFocus = null;
|
||||
public float focalSize = 0.0f;
|
||||
|
||||
public DofBlurriness bluriness = DofBlurriness.High;
|
||||
public float maxBlurSpread = 1.75f;
|
||||
|
||||
public float foregroundBlurExtrude = 1.15f;
|
||||
|
||||
public Shader dofBlurShader;
|
||||
private Material dofBlurMaterial = null;
|
||||
|
||||
public Shader dofShader;
|
||||
private Material dofMaterial = null;
|
||||
|
||||
public bool visualize = false;
|
||||
public BokehDestination bokehDestination = BokehDestination.Background;
|
||||
|
||||
private float widthOverHeight = 1.25f;
|
||||
private float oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
public bool bokeh = false;
|
||||
public bool bokehSupport = true;
|
||||
public Shader bokehShader;
|
||||
public Texture2D bokehTexture;
|
||||
public float bokehScale = 2.4f;
|
||||
public float bokehIntensity = 0.15f;
|
||||
public float bokehThresholdContrast = 0.1f;
|
||||
public float bokehThresholdLuminance = 0.55f;
|
||||
public int bokehDownsample = 1;
|
||||
private Material bokehMaterial;
|
||||
|
||||
private Camera _camera;
|
||||
|
||||
void CreateMaterials () {
|
||||
dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
|
||||
dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
|
||||
bokehSupport = bokehShader.isSupported;
|
||||
|
||||
if (bokeh && bokehSupport && bokehShader)
|
||||
bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true);
|
||||
|
||||
dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
|
||||
dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
|
||||
bokehSupport = bokehShader.isSupported;
|
||||
|
||||
if (bokeh && bokehSupport && bokehShader)
|
||||
bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
Quads.Cleanup ();
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
_camera = GetComponent<Camera>();
|
||||
_camera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
float FocalDistance01 ( float worldDist) {
|
||||
return _camera.WorldToViewportPoint((worldDist-_camera.nearClipPlane) * _camera.transform.forward + _camera.transform.position).z / (_camera.farClipPlane-_camera.nearClipPlane);
|
||||
}
|
||||
|
||||
int GetDividerBasedOnQuality () {
|
||||
int divider = 1;
|
||||
if (resolution == DofResolution.Medium)
|
||||
divider = 2;
|
||||
else if (resolution == DofResolution.Low)
|
||||
divider = 2;
|
||||
return divider;
|
||||
}
|
||||
|
||||
int GetLowResolutionDividerBasedOnQuality ( int baseDivider) {
|
||||
int lowTexDivider = baseDivider;
|
||||
if (resolution == DofResolution.High)
|
||||
lowTexDivider *= 2;
|
||||
if (resolution == DofResolution.Low)
|
||||
lowTexDivider *= 2;
|
||||
return lowTexDivider;
|
||||
}
|
||||
|
||||
private RenderTexture foregroundTexture = null;
|
||||
private RenderTexture mediumRezWorkTexture = null;
|
||||
private RenderTexture finalDefocus = null;
|
||||
private RenderTexture lowRezWorkTexture = null;
|
||||
private RenderTexture bokehSource = null;
|
||||
private RenderTexture bokehSource2 = null;
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources()==false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (smoothness < 0.1f)
|
||||
smoothness = 0.1f;
|
||||
|
||||
// update needed focal & rt size parameter
|
||||
|
||||
bokeh = bokeh && bokehSupport;
|
||||
float bokehBlurAmplifier = bokeh ? BOKEH_EXTRA_BLUR : 1.0f;
|
||||
|
||||
bool blurForeground = quality > Dof34QualitySetting.OnlyBackground;
|
||||
float focal01Size = focalSize / (_camera.farClipPlane - _camera.nearClipPlane);;
|
||||
|
||||
if (simpleTweakMode) {
|
||||
focalDistance01 = objectFocus ? (_camera.WorldToViewportPoint (objectFocus.position)).z / (_camera.farClipPlane) : FocalDistance01 (focalPoint);
|
||||
focalStartCurve = focalDistance01 * smoothness;
|
||||
focalEndCurve = focalStartCurve;
|
||||
blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
|
||||
}
|
||||
else {
|
||||
if (objectFocus) {
|
||||
var vpPoint= _camera.WorldToViewportPoint (objectFocus.position);
|
||||
vpPoint.z = (vpPoint.z) / (_camera.farClipPlane);
|
||||
focalDistance01 = vpPoint.z;
|
||||
}
|
||||
else
|
||||
focalDistance01 = FocalDistance01 (focalZDistance);
|
||||
|
||||
focalStartCurve = focalZStartCurve;
|
||||
focalEndCurve = focalZEndCurve;
|
||||
blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
|
||||
}
|
||||
|
||||
widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
|
||||
oneOverBaseSize = 1.0f / 512.0f;
|
||||
|
||||
dofMaterial.SetFloat ("_ForegroundBlurExtrude", foregroundBlurExtrude);
|
||||
dofMaterial.SetVector ("_CurveParams", new Vector4 (simpleTweakMode ? 1.0f / focalStartCurve : focalStartCurve, simpleTweakMode ? 1.0f / focalEndCurve : focalEndCurve, focal01Size * 0.5f, focalDistance01));
|
||||
dofMaterial.SetVector ("_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * source.width), 1.0f / (1.0f * source.height),0.0f,0.0f));
|
||||
|
||||
int divider = GetDividerBasedOnQuality ();
|
||||
int lowTexDivider = GetLowResolutionDividerBasedOnQuality (divider);
|
||||
|
||||
AllocateTextures (blurForeground, source, divider, lowTexDivider);
|
||||
|
||||
// WRITE COC to alpha channel
|
||||
// source is only being bound to detect y texcoord flip
|
||||
Graphics.Blit (source, source, dofMaterial, 3);
|
||||
|
||||
// better DOWNSAMPLE (could actually be weighted for higher quality)
|
||||
Downsample (source, mediumRezWorkTexture);
|
||||
|
||||
// BLUR A LITTLE first, which has two purposes
|
||||
// 1.) reduce jitter, noise, aliasing
|
||||
// 2.) produce the little-blur buffer used in composition later
|
||||
Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
{
|
||||
dofMaterial.SetVector ("_Threshhold", new Vector4(bokehThresholdContrast, bokehThresholdLuminance, 0.95f, 0.0f));
|
||||
|
||||
// add and mark the parts that should end up as bokeh shapes
|
||||
Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
|
||||
|
||||
// remove those parts (maybe even a little tittle bittle more) from the regurlarly blurred buffer
|
||||
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
|
||||
Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);//, dofMaterial, 10);
|
||||
|
||||
// maybe you want to reblur the small blur ... but not really needed.
|
||||
//Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread);
|
||||
|
||||
// bigger BLUR
|
||||
Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread * bokehBlurAmplifier);
|
||||
}
|
||||
else {
|
||||
// bigger BLUR
|
||||
Downsample (mediumRezWorkTexture, lowRezWorkTexture);
|
||||
Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread);
|
||||
}
|
||||
|
||||
dofBlurMaterial.SetTexture ("_TapLow", lowRezWorkTexture);
|
||||
dofBlurMaterial.SetTexture ("_TapMedium", mediumRezWorkTexture);
|
||||
Graphics.Blit (null, finalDefocus, dofBlurMaterial, 3);
|
||||
|
||||
// we are only adding bokeh now if the background is the only part we have to deal with
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
AddBokeh (bokehSource2, bokehSource, finalDefocus);
|
||||
|
||||
dofMaterial.SetTexture ("_TapLowBackground", finalDefocus);
|
||||
dofMaterial.SetTexture ("_TapMedium", mediumRezWorkTexture); // needed for debugging/visualization
|
||||
|
||||
// FINAL DEFOCUS (background)
|
||||
Graphics.Blit (source, blurForeground ? foregroundTexture : destination, dofMaterial, visualize ? 2 : 0);
|
||||
|
||||
// FINAL DEFOCUS (foreground)
|
||||
if (blurForeground) {
|
||||
// WRITE COC to alpha channel
|
||||
Graphics.Blit (foregroundTexture, source, dofMaterial, 5);
|
||||
|
||||
// DOWNSAMPLE (unweighted)
|
||||
Downsample (source, mediumRezWorkTexture);
|
||||
|
||||
// BLUR A LITTLE first, which has two purposes
|
||||
// 1.) reduce jitter, noise, aliasing
|
||||
// 2.) produce the little-blur buffer used in composition later
|
||||
BlurFg (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 2, maxBlurSpread);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
{
|
||||
dofMaterial.SetVector ("_Threshhold", new Vector4(bokehThresholdContrast * 0.5f, bokehThresholdLuminance, 0.0f, 0.0f));
|
||||
|
||||
// add and mark the parts that should end up as bokeh shapes
|
||||
Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
|
||||
|
||||
// remove the parts (maybe even a little tittle bittle more) that will end up in bokeh space
|
||||
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
|
||||
Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);//, dofMaterial, 10);
|
||||
|
||||
// big BLUR
|
||||
BlurFg (lowRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread * bokehBlurAmplifier);
|
||||
}
|
||||
else {
|
||||
// big BLUR
|
||||
BlurFg (mediumRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread);
|
||||
}
|
||||
|
||||
// simple upsample once
|
||||
Graphics.Blit (lowRezWorkTexture, finalDefocus);
|
||||
|
||||
dofMaterial.SetTexture ("_TapLowForeground", finalDefocus);
|
||||
Graphics.Blit (source, destination, dofMaterial, visualize ? 1 : 4);
|
||||
|
||||
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
|
||||
AddBokeh (bokehSource2, bokehSource, destination);
|
||||
}
|
||||
|
||||
ReleaseTextures ();
|
||||
}
|
||||
|
||||
void Blur ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
|
||||
RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
|
||||
if ((int)iterations > 1) {
|
||||
BlurHex (from, to, blurPass, spread, tmp);
|
||||
if ((int)iterations > 2) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (tmp);
|
||||
}
|
||||
|
||||
void BlurFg ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
|
||||
// we want a nice, big coc, hence we need to tap once from this (higher resolution) texture
|
||||
dofBlurMaterial.SetTexture ("_TapHigh", from);
|
||||
|
||||
RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
|
||||
if ((int)iterations > 1) {
|
||||
BlurHex (from, to, blurPass, spread, tmp);
|
||||
if ((int)iterations > 2) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary (tmp);
|
||||
}
|
||||
|
||||
void BlurHex ( RenderTexture from, RenderTexture to, int blurPass, float spread, RenderTexture tmp) {
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (from, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
|
||||
dofBlurMaterial.SetVector ("offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, -spread * oneOverBaseSize, 0.0f, 0.0f));
|
||||
Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
|
||||
}
|
||||
|
||||
void Downsample ( RenderTexture from, RenderTexture to) {
|
||||
dofMaterial.SetVector ("_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * to.width), 1.0f / (1.0f * to.height), 0.0f, 0.0f));
|
||||
Graphics.Blit (from, to, dofMaterial, SMOOTH_DOWNSAMPLE_PASS);
|
||||
}
|
||||
|
||||
void AddBokeh ( RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget) {
|
||||
if (bokehMaterial) {
|
||||
var meshes = Quads.GetMeshes (tempTex.width, tempTex.height); // quads: exchanging more triangles with less overdraw
|
||||
|
||||
RenderTexture.active = tempTex;
|
||||
GL.Clear (false, true, new Color (0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
GL.PushMatrix ();
|
||||
GL.LoadIdentity ();
|
||||
|
||||
// point filter mode is important, otherwise we get bokeh shape & size artefacts
|
||||
bokehInfo.filterMode = FilterMode.Point;
|
||||
|
||||
float arW = (bokehInfo.width * 1.0f) / (bokehInfo.height * 1.0f);
|
||||
float sc = 2.0f / (1.0f * bokehInfo.width);
|
||||
sc += bokehScale * maxBlurSpread * BOKEH_EXTRA_BLUR * oneOverBaseSize;
|
||||
|
||||
bokehMaterial.SetTexture ("_Source", bokehInfo);
|
||||
bokehMaterial.SetTexture ("_MainTex", bokehTexture);
|
||||
bokehMaterial.SetVector ("_ArScale",new Vector4 (sc, sc * arW, 0.5f, 0.5f * arW));
|
||||
bokehMaterial.SetFloat ("_Intensity", bokehIntensity);
|
||||
bokehMaterial.SetPass (0);
|
||||
|
||||
foreach(Mesh m in meshes)
|
||||
if (m) Graphics.DrawMeshNow (m, Matrix4x4.identity);
|
||||
|
||||
GL.PopMatrix ();
|
||||
|
||||
Graphics.Blit (tempTex, finalTarget, dofMaterial, 8);
|
||||
|
||||
// important to set back as we sample from this later on
|
||||
bokehInfo.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReleaseTextures () {
|
||||
if (foregroundTexture) RenderTexture.ReleaseTemporary (foregroundTexture);
|
||||
if (finalDefocus) RenderTexture.ReleaseTemporary (finalDefocus);
|
||||
if (mediumRezWorkTexture) RenderTexture.ReleaseTemporary (mediumRezWorkTexture);
|
||||
if (lowRezWorkTexture) RenderTexture.ReleaseTemporary (lowRezWorkTexture);
|
||||
if (bokehSource) RenderTexture.ReleaseTemporary (bokehSource);
|
||||
if (bokehSource2) RenderTexture.ReleaseTemporary (bokehSource2);
|
||||
}
|
||||
|
||||
void AllocateTextures ( bool blurForeground, RenderTexture source, int divider, int lowTexDivider) {
|
||||
foregroundTexture = null;
|
||||
if (blurForeground)
|
||||
foregroundTexture = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
mediumRezWorkTexture = RenderTexture.GetTemporary (source.width / divider, source.height / divider, 0);
|
||||
finalDefocus = RenderTexture.GetTemporary (source.width / divider, source.height / divider, 0);
|
||||
lowRezWorkTexture = RenderTexture.GetTemporary (source.width / lowTexDivider, source.height / lowTexDivider, 0);
|
||||
bokehSource = null;
|
||||
bokehSource2 = null;
|
||||
if (bokeh) {
|
||||
bokehSource = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf);
|
||||
bokehSource2 = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf);
|
||||
bokehSource.filterMode = FilterMode.Bilinear;
|
||||
bokehSource2.filterMode = FilterMode.Bilinear;
|
||||
RenderTexture.active = bokehSource2;
|
||||
GL.Clear (false, true, new Color(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
// to make sure: always use bilinear filter setting
|
||||
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
finalDefocus.filterMode = FilterMode.Bilinear;
|
||||
mediumRezWorkTexture.filterMode = FilterMode.Bilinear;
|
||||
lowRezWorkTexture.filterMode = FilterMode.Bilinear;
|
||||
if (foregroundTexture)
|
||||
foregroundTexture.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83d8db0ec466c14429f58c68c16398a1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- objectFocus: {instanceID: 0}
|
||||
- dofBlurShader: {fileID: 4800000, guid: bb4af680337344a4abad65a4e8873c50, type: 3}
|
||||
- dofShader: {fileID: 4800000, guid: 987fb0677d01f43ce8a9dbf12271e668, type: 3}
|
||||
- bokehShader: {fileID: 4800000, guid: 57cdacf9b217546aaa18edf39a6151c0, type: 3}
|
||||
- bokehTexture: {fileID: 2800000, guid: fc00ec05a89da4ff695a4273715cd5ce, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof (Camera))]
|
||||
[AddComponentMenu ("Image Effects/Edge Detection/Edge Detection")]
|
||||
public class EdgeDetection : PostEffectsBase
|
||||
{
|
||||
public enum EdgeDetectMode
|
||||
{
|
||||
TriangleDepthNormals = 0,
|
||||
RobertsCrossDepthNormals = 1,
|
||||
SobelDepth = 2,
|
||||
SobelDepthThin = 3,
|
||||
TriangleLuminance = 4,
|
||||
}
|
||||
|
||||
|
||||
public EdgeDetectMode mode = EdgeDetectMode.SobelDepthThin;
|
||||
public float sensitivityDepth = 1.0f;
|
||||
public float sensitivityNormals = 1.0f;
|
||||
public float lumThreshold = 0.2f;
|
||||
public float edgeExp = 1.0f;
|
||||
public float sampleDist = 1.0f;
|
||||
public float edgesOnly = 0.0f;
|
||||
public Color edgesOnlyBgColor = Color.white;
|
||||
|
||||
public Shader edgeDetectShader;
|
||||
private Material edgeDetectMaterial = null;
|
||||
private EdgeDetectMode oldMode = EdgeDetectMode.SobelDepthThin;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
edgeDetectMaterial = CheckShaderAndCreateMaterial (edgeDetectShader,edgeDetectMaterial);
|
||||
if (mode != oldMode)
|
||||
SetCameraFlag ();
|
||||
|
||||
oldMode = mode;
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
new void Start ()
|
||||
{
|
||||
oldMode = mode;
|
||||
}
|
||||
|
||||
void SetCameraFlag ()
|
||||
{
|
||||
if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
else if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
|
||||
}
|
||||
|
||||
void OnEnable ()
|
||||
{
|
||||
SetCameraFlag();
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources () == false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 sensitivity = new Vector2 (sensitivityDepth, sensitivityNormals);
|
||||
edgeDetectMaterial.SetVector ("_Sensitivity", new Vector4 (sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
|
||||
edgeDetectMaterial.SetFloat ("_BgFade", edgesOnly);
|
||||
edgeDetectMaterial.SetFloat ("_SampleDistance", sampleDist);
|
||||
edgeDetectMaterial.SetVector ("_BgColor", edgesOnlyBgColor);
|
||||
edgeDetectMaterial.SetFloat ("_Exponent", edgeExp);
|
||||
edgeDetectMaterial.SetFloat ("_Threshold", lumThreshold);
|
||||
|
||||
Graphics.Blit (source, destination, edgeDetectMaterial, (int) mode);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 730475ee64f9a894bbac0d9e6f22e813
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- edgeDetectShader: {fileID: 4800000, guid: 0d1644bdf064147baa97f235fc5b4903, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Displacement/Fisheye")]
|
||||
public class Fisheye : PostEffectsBase
|
||||
{
|
||||
[Range(0.0f, 1.5f)]
|
||||
public float strengthX = 0.05f;
|
||||
[Range(0.0f, 1.5f)]
|
||||
public float strengthY = 0.05f;
|
||||
|
||||
public Shader fishEyeShader = null;
|
||||
private Material fisheyeMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
fisheyeMaterial = CheckShaderAndCreateMaterial(fishEyeShader,fisheyeMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
float oneOverBaseSize = 80.0f / 512.0f; // to keep values more like in the old version of fisheye
|
||||
|
||||
float ar = (source.width * 1.0f) / (source.height * 1.0f);
|
||||
|
||||
fisheyeMaterial.SetVector ("intensity", new Vector4 (strengthX * ar * oneOverBaseSize, strengthY * oneOverBaseSize, strengthX * ar * oneOverBaseSize, strengthY * oneOverBaseSize));
|
||||
Graphics.Blit (source, destination, fisheyeMaterial);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4739c22ef73ad62488fe344c8fe9addd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fishEyeShader: {fileID: 4800000, guid: 874ceab4425f64bccb1d14032f4452b1, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Rendering/Global Fog")]
|
||||
class GlobalFog : PostEffectsBase
|
||||
{
|
||||
[Tooltip("Apply distance-based fog?")]
|
||||
public bool distanceFog = true;
|
||||
[Tooltip("Exclude far plane pixels from distance-based fog? (Skybox or clear color)")]
|
||||
public bool excludeFarPixels = true;
|
||||
[Tooltip("Distance fog is based on radial distance from camera when checked")]
|
||||
public bool useRadialDistance = false;
|
||||
[Tooltip("Apply height-based fog?")]
|
||||
public bool heightFog = true;
|
||||
[Tooltip("Fog top Y coordinate")]
|
||||
public float height = 1.0f;
|
||||
[Range(0.001f,10.0f)]
|
||||
public float heightDensity = 2.0f;
|
||||
[Tooltip("Push fog away from the camera by this amount")]
|
||||
public float startDistance = 0.0f;
|
||||
|
||||
public Shader fogShader = null;
|
||||
private Material fogMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (true);
|
||||
|
||||
fogMaterial = CheckShaderAndCreateMaterial (fogShader, fogMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false || (!distanceFog && !heightFog))
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Camera cam = GetComponent<Camera>();
|
||||
Transform camtr = cam.transform;
|
||||
float camNear = cam.nearClipPlane;
|
||||
float camFar = cam.farClipPlane;
|
||||
float camFov = cam.fieldOfView;
|
||||
float camAspect = cam.aspect;
|
||||
|
||||
Matrix4x4 frustumCorners = Matrix4x4.identity;
|
||||
|
||||
float fovWHalf = camFov * 0.5f;
|
||||
|
||||
Vector3 toRight = camtr.right * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * camAspect;
|
||||
Vector3 toTop = camtr.up * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
|
||||
|
||||
Vector3 topLeft = (camtr.forward * camNear - toRight + toTop);
|
||||
float camScale = topLeft.magnitude * camFar/camNear;
|
||||
|
||||
topLeft.Normalize();
|
||||
topLeft *= camScale;
|
||||
|
||||
Vector3 topRight = (camtr.forward * camNear + toRight + toTop);
|
||||
topRight.Normalize();
|
||||
topRight *= camScale;
|
||||
|
||||
Vector3 bottomRight = (camtr.forward * camNear + toRight - toTop);
|
||||
bottomRight.Normalize();
|
||||
bottomRight *= camScale;
|
||||
|
||||
Vector3 bottomLeft = (camtr.forward * camNear - toRight - toTop);
|
||||
bottomLeft.Normalize();
|
||||
bottomLeft *= camScale;
|
||||
|
||||
frustumCorners.SetRow (0, topLeft);
|
||||
frustumCorners.SetRow (1, topRight);
|
||||
frustumCorners.SetRow (2, bottomRight);
|
||||
frustumCorners.SetRow (3, bottomLeft);
|
||||
|
||||
var camPos= camtr.position;
|
||||
float FdotC = camPos.y-height;
|
||||
float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f);
|
||||
float excludeDepth = (excludeFarPixels ? 1.0f : 2.0f);
|
||||
fogMaterial.SetMatrix ("_FrustumCornersWS", frustumCorners);
|
||||
fogMaterial.SetVector ("_CameraWS", camPos);
|
||||
fogMaterial.SetVector ("_HeightParams", new Vector4 (height, FdotC, paramK, heightDensity*0.5f));
|
||||
fogMaterial.SetVector ("_DistanceParams", new Vector4 (-Mathf.Max(startDistance,0.0f), excludeDepth, 0, 0));
|
||||
|
||||
var sceneMode= RenderSettings.fogMode;
|
||||
var sceneDensity= RenderSettings.fogDensity;
|
||||
var sceneStart= RenderSettings.fogStartDistance;
|
||||
var sceneEnd= RenderSettings.fogEndDistance;
|
||||
Vector4 sceneParams;
|
||||
bool linear = (sceneMode == FogMode.Linear);
|
||||
float diff = linear ? sceneEnd - sceneStart : 0.0f;
|
||||
float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f;
|
||||
sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode
|
||||
sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode
|
||||
sceneParams.z = linear ? -invDiff : 0.0f;
|
||||
sceneParams.w = linear ? sceneEnd * invDiff : 0.0f;
|
||||
fogMaterial.SetVector ("_SceneFogParams", sceneParams);
|
||||
fogMaterial.SetVector ("_SceneFogMode", new Vector4((int)sceneMode, useRadialDistance ? 1 : 0, 0, 0));
|
||||
|
||||
int pass = 0;
|
||||
if (distanceFog && heightFog)
|
||||
pass = 0; // distance + height
|
||||
else if (distanceFog)
|
||||
pass = 1; // distance only
|
||||
else
|
||||
pass = 2; // height only
|
||||
CustomGraphicsBlit (source, destination, fogMaterial, pass);
|
||||
}
|
||||
|
||||
static void CustomGraphicsBlit (RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
|
||||
{
|
||||
RenderTexture.active = dest;
|
||||
|
||||
fxMaterial.SetTexture ("_MainTex", source);
|
||||
|
||||
GL.PushMatrix ();
|
||||
GL.LoadOrtho ();
|
||||
|
||||
fxMaterial.SetPass (passNr);
|
||||
|
||||
GL.Begin (GL.QUADS);
|
||||
|
||||
GL.MultiTexCoord2 (0, 0.0f, 0.0f);
|
||||
GL.Vertex3 (0.0f, 0.0f, 3.0f); // BL
|
||||
|
||||
GL.MultiTexCoord2 (0, 1.0f, 0.0f);
|
||||
GL.Vertex3 (1.0f, 0.0f, 2.0f); // BR
|
||||
|
||||
GL.MultiTexCoord2 (0, 1.0f, 1.0f);
|
||||
GL.Vertex3 (1.0f, 1.0f, 1.0f); // TR
|
||||
|
||||
GL.MultiTexCoord2 (0, 0.0f, 1.0f);
|
||||
GL.Vertex3 (0.0f, 1.0f, 0.0f); // TL
|
||||
|
||||
GL.End ();
|
||||
GL.PopMatrix ();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76b5ec6153a1d55438228df10fe66844
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- fogShader: {fileID: 4800000, guid: 70d8568987ac0499f952b54c7c13e265, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Grayscale")]
|
||||
public class Grayscale : ImageEffectBase {
|
||||
public Texture textureRamp;
|
||||
|
||||
[Range(-1.0f,1.0f)]
|
||||
public float rampOffset;
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
material.SetTexture("_RampTex", textureRamp);
|
||||
material.SetFloat("_RampOffset", rampOffset);
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 243a781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: daf9781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,55 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6469eb0ad1119d6d00011d98d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,42 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
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:
|
@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
// This class implements simple ghosting type Motion Blur.
|
||||
// If Extra Blur is selected, the scene will allways be a little blurred,
|
||||
// as it is scaled to a smaller resolution.
|
||||
// The effect works by accumulating the previous frames in an accumulation
|
||||
// texture.
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Blur/Motion Blur (Color Accumulation)")]
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class MotionBlur : ImageEffectBase
|
||||
{
|
||||
[Range(0.0f, 0.92f)]
|
||||
public float blurAmount = 0.8f;
|
||||
public bool extraBlur = false;
|
||||
|
||||
private RenderTexture accumTexture;
|
||||
|
||||
override protected void Start()
|
||||
{
|
||||
if (!SystemInfo.supportsRenderTextures)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
base.Start();
|
||||
}
|
||||
|
||||
override protected void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
DestroyImmediate(accumTexture);
|
||||
}
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
// Create the accumulation texture
|
||||
if (accumTexture == null || accumTexture.width != source.width || accumTexture.height != source.height)
|
||||
{
|
||||
DestroyImmediate(accumTexture);
|
||||
accumTexture = new RenderTexture(source.width, source.height, 0);
|
||||
accumTexture.hideFlags = HideFlags.HideAndDontSave;
|
||||
Graphics.Blit( source, accumTexture );
|
||||
}
|
||||
|
||||
// If Extra Blur is selected, downscale the texture to 4x4 smaller resolution.
|
||||
if (extraBlur)
|
||||
{
|
||||
RenderTexture blurbuffer = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
|
||||
accumTexture.MarkRestoreExpected();
|
||||
Graphics.Blit(accumTexture, blurbuffer);
|
||||
Graphics.Blit(blurbuffer,accumTexture);
|
||||
RenderTexture.ReleaseTemporary(blurbuffer);
|
||||
}
|
||||
|
||||
// Clamp the motion blur variable, so it can never leave permanent trails in the image
|
||||
blurAmount = Mathf.Clamp( blurAmount, 0.0f, 0.92f );
|
||||
|
||||
// Setup the texture and floating point values in the shader
|
||||
material.SetTexture("_MainTex", accumTexture);
|
||||
material.SetFloat("_AccumOrig", 1.0F-blurAmount);
|
||||
|
||||
// We are accumulating motion over frames without clear/discard
|
||||
// by design, so silence any performance warnings from Unity
|
||||
accumTexture.MarkRestoreExpected();
|
||||
|
||||
// Render the image using the motion blur shader
|
||||
Graphics.Blit (source, accumTexture, material);
|
||||
Graphics.Blit (accumTexture, destination);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 478a2083ad114a07d000fbfb8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: e9ba2083ad114a07d000fbfb8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Noise/Noise And Grain (Filmic)")]
|
||||
public class NoiseAndGrain : PostEffectsBase
|
||||
{
|
||||
|
||||
public float intensityMultiplier = 0.25f;
|
||||
|
||||
public float generalIntensity = 0.5f;
|
||||
public float blackIntensity = 1.0f;
|
||||
public float whiteIntensity = 1.0f;
|
||||
public float midGrey = 0.2f;
|
||||
|
||||
public bool dx11Grain = false;
|
||||
public float softness = 0.0f;
|
||||
public bool monochrome = false;
|
||||
|
||||
public Vector3 intensities = new Vector3(1.0f, 1.0f, 1.0f);
|
||||
public Vector3 tiling = new Vector3(64.0f, 64.0f, 64.0f);
|
||||
public float monochromeTiling = 64.0f;
|
||||
|
||||
public FilterMode filterMode = FilterMode.Bilinear;
|
||||
|
||||
public Texture2D noiseTexture;
|
||||
|
||||
public Shader noiseShader;
|
||||
private Material noiseMaterial = null;
|
||||
|
||||
public Shader dx11NoiseShader;
|
||||
private Material dx11NoiseMaterial = null;
|
||||
|
||||
private static float TILE_AMOUNT = 64.0f;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
noiseMaterial = CheckShaderAndCreateMaterial (noiseShader, noiseMaterial);
|
||||
|
||||
if (dx11Grain && supportDX11)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
dx11NoiseShader = Shader.Find("Hidden/NoiseAndGrainDX11");
|
||||
#endif
|
||||
dx11NoiseMaterial = CheckShaderAndCreateMaterial (dx11NoiseShader, dx11NoiseMaterial);
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources()==false || (null==noiseTexture))
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
if (null==noiseTexture) {
|
||||
Debug.LogWarning("Noise & Grain effect failing as noise texture is not assigned. please assign.", transform);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
softness = Mathf.Clamp(softness, 0.0f, 0.99f);
|
||||
|
||||
if (dx11Grain && supportDX11)
|
||||
{
|
||||
// We have a fancy, procedural noise pattern in this version, so no texture needed
|
||||
|
||||
dx11NoiseMaterial.SetFloat("_DX11NoiseTime", Time.frameCount);
|
||||
dx11NoiseMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
dx11NoiseMaterial.SetVector ("_NoisePerChannel", monochrome ? Vector3.one : intensities);
|
||||
dx11NoiseMaterial.SetVector ("_MidGrey", new Vector3(midGrey, 1.0f/(1.0f-midGrey), -1.0f/midGrey));
|
||||
dx11NoiseMaterial.SetVector ("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
|
||||
|
||||
if (softness > Mathf.Epsilon)
|
||||
{
|
||||
RenderTexture rt = RenderTexture.GetTemporary((int) (source.width * (1.0f-softness)), (int) (source.height * (1.0f-softness)));
|
||||
DrawNoiseQuadGrid (source, rt, dx11NoiseMaterial, noiseTexture, monochrome ? 3 : 2);
|
||||
dx11NoiseMaterial.SetTexture("_NoiseTex", rt);
|
||||
Graphics.Blit(source, destination, dx11NoiseMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
else
|
||||
DrawNoiseQuadGrid (source, destination, dx11NoiseMaterial, noiseTexture, (monochrome ? 1 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal noise (DX9 style)
|
||||
|
||||
if (noiseTexture) {
|
||||
noiseTexture.wrapMode = TextureWrapMode.Repeat;
|
||||
noiseTexture.filterMode = filterMode;
|
||||
}
|
||||
|
||||
noiseMaterial.SetTexture ("_NoiseTex", noiseTexture);
|
||||
noiseMaterial.SetVector ("_NoisePerChannel", monochrome ? Vector3.one : intensities);
|
||||
noiseMaterial.SetVector ("_NoiseTilingPerChannel", monochrome ? Vector3.one * monochromeTiling : tiling);
|
||||
noiseMaterial.SetVector ("_MidGrey", new Vector3(midGrey, 1.0f/(1.0f-midGrey), -1.0f/midGrey));
|
||||
noiseMaterial.SetVector ("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
|
||||
|
||||
if (softness > Mathf.Epsilon)
|
||||
{
|
||||
RenderTexture rt2 = RenderTexture.GetTemporary((int) (source.width * (1.0f-softness)), (int) (source.height * (1.0f-softness)));
|
||||
DrawNoiseQuadGrid (source, rt2, noiseMaterial, noiseTexture, 2);
|
||||
noiseMaterial.SetTexture("_NoiseTex", rt2);
|
||||
Graphics.Blit(source, destination, noiseMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary(rt2);
|
||||
}
|
||||
else
|
||||
DrawNoiseQuadGrid (source, destination, noiseMaterial, noiseTexture, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawNoiseQuadGrid (RenderTexture source, RenderTexture dest, Material fxMaterial, Texture2D noise, int passNr)
|
||||
{
|
||||
RenderTexture.active = dest;
|
||||
|
||||
float noiseSize = (noise.width * 1.0f);
|
||||
float subDs = (1.0f * source.width) / TILE_AMOUNT;
|
||||
|
||||
fxMaterial.SetTexture ("_MainTex", source);
|
||||
|
||||
GL.PushMatrix ();
|
||||
GL.LoadOrtho ();
|
||||
|
||||
float aspectCorrection = (1.0f * source.width) / (1.0f * source.height);
|
||||
float stepSizeX = 1.0f / subDs;
|
||||
float stepSizeY = stepSizeX * aspectCorrection;
|
||||
float texTile = noiseSize / (noise.width * 1.0f);
|
||||
|
||||
fxMaterial.SetPass (passNr);
|
||||
|
||||
GL.Begin (GL.QUADS);
|
||||
|
||||
for (float x1 = 0.0f; x1 < 1.0f; x1 += stepSizeX)
|
||||
{
|
||||
for (float y1 = 0.0f; y1 < 1.0f; y1 += stepSizeY)
|
||||
{
|
||||
float tcXStart = Random.Range (0.0f, 1.0f);
|
||||
float tcYStart = Random.Range (0.0f, 1.0f);
|
||||
|
||||
//Vector3 v3 = Random.insideUnitSphere;
|
||||
//Color c = new Color(v3.x, v3.y, v3.z);
|
||||
|
||||
tcXStart = Mathf.Floor(tcXStart*noiseSize) / noiseSize;
|
||||
tcYStart = Mathf.Floor(tcYStart*noiseSize) / noiseSize;
|
||||
|
||||
float texTileMod = 1.0f / noiseSize;
|
||||
|
||||
GL.MultiTexCoord2 (0, tcXStart, tcYStart);
|
||||
GL.MultiTexCoord2 (1, 0.0f, 0.0f);
|
||||
//GL.Color( c );
|
||||
GL.Vertex3 (x1, y1, 0.1f);
|
||||
GL.MultiTexCoord2 (0, tcXStart + texTile * texTileMod, tcYStart);
|
||||
GL.MultiTexCoord2 (1, 1.0f, 0.0f);
|
||||
//GL.Color( c );
|
||||
GL.Vertex3 (x1 + stepSizeX, y1, 0.1f);
|
||||
GL.MultiTexCoord2 (0, tcXStart + texTile * texTileMod, tcYStart + texTile * texTileMod);
|
||||
GL.MultiTexCoord2 (1, 1.0f, 1.0f);
|
||||
//GL.Color( c );
|
||||
GL.Vertex3 (x1 + stepSizeX, y1 + stepSizeY, 0.1f);
|
||||
GL.MultiTexCoord2 (0, tcXStart, tcYStart + texTile * texTileMod);
|
||||
GL.MultiTexCoord2 (1, 0.0f, 1.0f);
|
||||
//GL.Color( c );
|
||||
GL.Vertex3 (x1, y1 + stepSizeY, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
GL.End ();
|
||||
GL.PopMatrix ();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9191284b058eef549b7108b5f04e1117
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- noiseTexture: {fileID: 2800000, guid: 7a632f967e8ad42f5bd275898151ab6a, type: 3}
|
||||
- noiseShader: {fileID: 4800000, guid: b0249d8c935344451aa4de6db76f0688, type: 3}
|
||||
- dx11NoiseShader: {fileID: 4800000, guid: 8b30686bb4322ab42ad5eb50a0210b58, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Noise/Noise and Scratches")]
|
||||
public class NoiseAndScratches : MonoBehaviour
|
||||
{
|
||||
/// Monochrome noise just adds grain. Non-monochrome noise
|
||||
/// more resembles VCR as it adds noise in YUV color space,
|
||||
/// thus introducing magenta/green colors.
|
||||
public bool monochrome = true;
|
||||
private bool rgbFallback = false;
|
||||
|
||||
// Noise grain takes random intensity from Min to Max.
|
||||
[Range(0.0f,5.0f)]
|
||||
public float grainIntensityMin = 0.1f;
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float grainIntensityMax = 0.2f;
|
||||
|
||||
/// The size of the noise grains (1 = one pixel).
|
||||
[Range(0.1f, 50.0f)]
|
||||
public float grainSize = 2.0f;
|
||||
|
||||
// Scratches take random intensity from Min to Max.
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float scratchIntensityMin = 0.05f;
|
||||
[Range(0.0f, 5.0f)]
|
||||
public float scratchIntensityMax = 0.25f;
|
||||
|
||||
/// Scratches jump to another locations at this times per second.
|
||||
[Range(1.0f, 30.0f)]
|
||||
public float scratchFPS = 10.0f;
|
||||
/// While scratches are in the same location, they jitter a bit.
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float scratchJitter = 0.01f;
|
||||
|
||||
public Texture grainTexture;
|
||||
public Texture scratchTexture;
|
||||
public Shader shaderRGB;
|
||||
public Shader shaderYUV;
|
||||
private Material m_MaterialRGB;
|
||||
private Material m_MaterialYUV;
|
||||
|
||||
private float scratchTimeLeft = 0.0f;
|
||||
private float scratchX, scratchY;
|
||||
|
||||
protected void Start ()
|
||||
{
|
||||
// Disable if we don't support image effects
|
||||
if (!SystemInfo.supportsImageEffects) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( shaderRGB == null || shaderYUV == null )
|
||||
{
|
||||
Debug.Log( "Noise shaders are not set up! Disabling noise effect." );
|
||||
enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !shaderRGB.isSupported ) // disable effect if RGB shader is not supported
|
||||
enabled = false;
|
||||
else if ( !shaderYUV.isSupported ) // fallback to RGB if YUV is not supported
|
||||
rgbFallback = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Material material {
|
||||
get {
|
||||
if ( m_MaterialRGB == null ) {
|
||||
m_MaterialRGB = new Material( shaderRGB );
|
||||
m_MaterialRGB.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
if ( m_MaterialYUV == null && !rgbFallback ) {
|
||||
m_MaterialYUV = new Material( shaderYUV );
|
||||
m_MaterialYUV.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
return (!rgbFallback && !monochrome) ? m_MaterialYUV : m_MaterialRGB;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDisable() {
|
||||
if ( m_MaterialRGB )
|
||||
DestroyImmediate( m_MaterialRGB );
|
||||
if ( m_MaterialYUV )
|
||||
DestroyImmediate( m_MaterialYUV );
|
||||
}
|
||||
|
||||
private void SanitizeParameters()
|
||||
{
|
||||
grainIntensityMin = Mathf.Clamp( grainIntensityMin, 0.0f, 5.0f );
|
||||
grainIntensityMax = Mathf.Clamp( grainIntensityMax, 0.0f, 5.0f );
|
||||
scratchIntensityMin = Mathf.Clamp( scratchIntensityMin, 0.0f, 5.0f );
|
||||
scratchIntensityMax = Mathf.Clamp( scratchIntensityMax, 0.0f, 5.0f );
|
||||
scratchFPS = Mathf.Clamp( scratchFPS, 1, 30 );
|
||||
scratchJitter = Mathf.Clamp( scratchJitter, 0.0f, 1.0f );
|
||||
grainSize = Mathf.Clamp( grainSize, 0.1f, 50.0f );
|
||||
}
|
||||
|
||||
// Called by the camera to apply the image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
SanitizeParameters();
|
||||
|
||||
if ( scratchTimeLeft <= 0.0f )
|
||||
{
|
||||
scratchTimeLeft = Random.value * 2 / scratchFPS; // we have sanitized it earlier, won't be zero
|
||||
scratchX = Random.value;
|
||||
scratchY = Random.value;
|
||||
}
|
||||
scratchTimeLeft -= Time.deltaTime;
|
||||
|
||||
Material mat = material;
|
||||
|
||||
mat.SetTexture("_GrainTex", grainTexture);
|
||||
mat.SetTexture("_ScratchTex", scratchTexture);
|
||||
float grainScale = 1.0f / grainSize; // we have sanitized it earlier, won't be zero
|
||||
mat.SetVector("_GrainOffsetScale", new Vector4(
|
||||
Random.value,
|
||||
Random.value,
|
||||
(float)Screen.width / (float)grainTexture.width * grainScale,
|
||||
(float)Screen.height / (float)grainTexture.height * grainScale
|
||||
));
|
||||
mat.SetVector("_ScratchOffsetScale", new Vector4(
|
||||
scratchX + Random.value*scratchJitter,
|
||||
scratchY + Random.value*scratchJitter,
|
||||
(float)Screen.width / (float) scratchTexture.width,
|
||||
(float)Screen.height / (float) scratchTexture.height
|
||||
));
|
||||
mat.SetVector("_Intensity", new Vector4(
|
||||
Random.Range(grainIntensityMin, grainIntensityMax),
|
||||
Random.Range(scratchIntensityMin, scratchIntensityMax),
|
||||
0, 0 ));
|
||||
Graphics.Blit (source, destination, mat);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a88a26a276b4e47619ce2c5adad33fab
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- grainTexture: {fileID: 2800000, guid: ffa9c02760c2b4e8eb9814ec06c4b05b, type: 3}
|
||||
- scratchTexture: {fileID: 2800000, guid: 6205c27cc031f4e66b8ea90d1bfaa158, type: 3}
|
||||
- shaderRGB: {fileID: 4800000, guid: 5d7f4c401ae8946bcb0d6ff68a9e7466, type: 3}
|
||||
- shaderYUV: {fileID: 4800000, guid: 0e447868506ba49f0a73235b8a8b647a, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,243 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6f4318ec6c2bf643a0f9edfeeaba0ec
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,188 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b03df8f04b5c441aaac5b7fccb4734
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,125 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a20852ce049f64e4695a48b6a354be83
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Other/Screen Overlay")]
|
||||
public class ScreenOverlay : PostEffectsBase
|
||||
{
|
||||
public enum OverlayBlendMode
|
||||
{
|
||||
Additive = 0,
|
||||
ScreenBlend = 1,
|
||||
Multiply = 2,
|
||||
Overlay = 3,
|
||||
AlphaBlend = 4,
|
||||
}
|
||||
|
||||
public OverlayBlendMode blendMode = OverlayBlendMode.Overlay;
|
||||
public float intensity = 1.0f;
|
||||
public Texture2D texture = null;
|
||||
|
||||
public Shader overlayShader = null;
|
||||
private Material overlayMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources ()
|
||||
{
|
||||
CheckSupport (false);
|
||||
|
||||
overlayMaterial = CheckShaderAndCreateMaterial (overlayShader, overlayMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector4 UV_Transform = new Vector4(1, 0, 0, 1);
|
||||
|
||||
#if UNITY_WP8
|
||||
// WP8 has no OS support for rotating screen with device orientation,
|
||||
// so we do those transformations ourselves.
|
||||
if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
|
||||
UV_Transform = new Vector4(0, -1, 1, 0);
|
||||
}
|
||||
if (Screen.orientation == ScreenOrientation.LandscapeRight) {
|
||||
UV_Transform = new Vector4(0, 1, -1, 0);
|
||||
}
|
||||
if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
UV_Transform = new Vector4(-1, 0, 0, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
overlayMaterial.SetVector("_UV_Transform", UV_Transform);
|
||||
overlayMaterial.SetFloat ("_Intensity", intensity);
|
||||
overlayMaterial.SetTexture ("_Overlay", texture);
|
||||
Graphics.Blit (source, destination, overlayMaterial, (int) blendMode);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f19108706fdce9469603d07980eb8ad
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- texture: {instanceID: 0}
|
||||
- overlayShader: {fileID: 4800000, guid: 8c81db0e527d24acc9bcec04e87781bd, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Rendering/Screen Space Ambient Obscurance")]
|
||||
class ScreenSpaceAmbientObscurance : PostEffectsBase {
|
||||
[Range (0,3)]
|
||||
public float intensity = 0.5f;
|
||||
[Range (0.1f,3)]
|
||||
public float radius = 0.2f;
|
||||
[Range (0,3)]
|
||||
public int blurIterations = 1;
|
||||
[Range (0,5)]
|
||||
public float blurFilterDistance = 1.25f;
|
||||
[Range (0,1)]
|
||||
public int downsample = 0;
|
||||
|
||||
public Texture2D rand = null;
|
||||
public Shader aoShader= null;
|
||||
|
||||
private Material aoMaterial = null;
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true);
|
||||
|
||||
aoMaterial = CheckShaderAndCreateMaterial (aoShader, aoMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (aoMaterial)
|
||||
DestroyImmediate (aoMaterial);
|
||||
aoMaterial = null;
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources () == false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4 P = GetComponent<Camera>().projectionMatrix;
|
||||
var invP= P.inverse;
|
||||
Vector4 projInfo = new Vector4
|
||||
((-2.0f / (Screen.width * P[0])),
|
||||
(-2.0f / (Screen.height * P[5])),
|
||||
((1.0f - P[2]) / P[0]),
|
||||
((1.0f + P[6]) / P[5]));
|
||||
|
||||
aoMaterial.SetVector ("_ProjInfo", projInfo); // used for unprojection
|
||||
aoMaterial.SetMatrix ("_ProjectionInv", invP); // only used for reference
|
||||
aoMaterial.SetTexture ("_Rand", rand); // not needed for DX11 :)
|
||||
aoMaterial.SetFloat ("_Radius", radius);
|
||||
aoMaterial.SetFloat ("_Radius2", radius*radius);
|
||||
aoMaterial.SetFloat ("_Intensity", intensity);
|
||||
aoMaterial.SetFloat ("_BlurFilterDistance", blurFilterDistance);
|
||||
|
||||
int rtW = source.width;
|
||||
int rtH = source.height;
|
||||
|
||||
RenderTexture tmpRt = RenderTexture.GetTemporary (rtW>>downsample, rtH>>downsample);
|
||||
RenderTexture tmpRt2;
|
||||
|
||||
Graphics.Blit (source, tmpRt, aoMaterial, 0);
|
||||
|
||||
if (downsample > 0) {
|
||||
tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit(tmpRt, tmpRt2, aoMaterial, 4);
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
tmpRt = tmpRt2;
|
||||
|
||||
// @NOTE: it's probably worth a shot to blur in low resolution
|
||||
// instead with a bilat-upsample afterwards ...
|
||||
}
|
||||
|
||||
for (int i = 0; i < blurIterations; i++) {
|
||||
aoMaterial.SetVector("_Axis", new Vector2(1.0f,0.0f));
|
||||
tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit (tmpRt, tmpRt2, aoMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
|
||||
aoMaterial.SetVector("_Axis", new Vector2(0.0f,1.0f));
|
||||
tmpRt = RenderTexture.GetTemporary (rtW, rtH);
|
||||
Graphics.Blit (tmpRt2, tmpRt, aoMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (tmpRt2);
|
||||
}
|
||||
|
||||
aoMaterial.SetTexture ("_AOTex", tmpRt);
|
||||
Graphics.Blit (source, destination, aoMaterial, 2);
|
||||
|
||||
RenderTexture.ReleaseTemporary (tmpRt);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75febd242c999f04d9654522a10c006b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- rand: {fileID: 2800000, guid: a181ca8e3c62f3e4b8f183f6c586b032, type: 3}
|
||||
- aoShader: {fileID: 4800000, guid: 95616c020c5604dda96cf76afbbc0272, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu("Image Effects/Rendering/Screen Space Ambient Occlusion")]
|
||||
public class ScreenSpaceAmbientOcclusion : MonoBehaviour
|
||||
{
|
||||
public enum SSAOSamples
|
||||
{
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
[Range(0.05f, 1.0f)]
|
||||
public float m_Radius = 0.4f;
|
||||
public SSAOSamples m_SampleCount = SSAOSamples.Medium;
|
||||
[Range(0.5f, 4.0f)]
|
||||
public float m_OcclusionIntensity = 1.5f;
|
||||
[Range(0, 4)]
|
||||
public int m_Blur = 2;
|
||||
[Range(1,6)]
|
||||
public int m_Downsampling = 2;
|
||||
[Range(0.2f, 2.0f)]
|
||||
public float m_OcclusionAttenuation = 1.0f;
|
||||
[Range(0.00001f, 0.5f)]
|
||||
public float m_MinZ = 0.01f;
|
||||
|
||||
public Shader m_SSAOShader;
|
||||
private Material m_SSAOMaterial;
|
||||
|
||||
public Texture2D m_RandomTexture;
|
||||
|
||||
private bool m_Supported;
|
||||
|
||||
private static Material CreateMaterial (Shader shader)
|
||||
{
|
||||
if (!shader)
|
||||
return null;
|
||||
Material m = new Material (shader);
|
||||
m.hideFlags = HideFlags.HideAndDontSave;
|
||||
return m;
|
||||
}
|
||||
private static void DestroyMaterial (Material mat)
|
||||
{
|
||||
if (mat)
|
||||
{
|
||||
DestroyImmediate (mat);
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
DestroyMaterial (m_SSAOMaterial);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (!SystemInfo.supportsImageEffects || !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
|
||||
{
|
||||
m_Supported = false;
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CreateMaterials ();
|
||||
if (!m_SSAOMaterial || m_SSAOMaterial.passCount != 5)
|
||||
{
|
||||
m_Supported = false;
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//CreateRandomTable (26, 0.2f);
|
||||
|
||||
m_Supported = true;
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
|
||||
}
|
||||
|
||||
private void CreateMaterials ()
|
||||
{
|
||||
if (!m_SSAOMaterial && m_SSAOShader.isSupported)
|
||||
{
|
||||
m_SSAOMaterial = CreateMaterial (m_SSAOShader);
|
||||
m_SSAOMaterial.SetTexture ("_RandomTexture", m_RandomTexture);
|
||||
}
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (!m_Supported || !m_SSAOShader.isSupported) {
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
CreateMaterials ();
|
||||
|
||||
m_Downsampling = Mathf.Clamp (m_Downsampling, 1, 6);
|
||||
m_Radius = Mathf.Clamp (m_Radius, 0.05f, 1.0f);
|
||||
m_MinZ = Mathf.Clamp (m_MinZ, 0.00001f, 0.5f);
|
||||
m_OcclusionIntensity = Mathf.Clamp (m_OcclusionIntensity, 0.5f, 4.0f);
|
||||
m_OcclusionAttenuation = Mathf.Clamp (m_OcclusionAttenuation, 0.2f, 2.0f);
|
||||
m_Blur = Mathf.Clamp (m_Blur, 0, 4);
|
||||
|
||||
// Render SSAO term into a smaller texture
|
||||
RenderTexture rtAO = RenderTexture.GetTemporary (source.width / m_Downsampling, source.height / m_Downsampling, 0);
|
||||
float fovY = GetComponent<Camera>().fieldOfView;
|
||||
float far = GetComponent<Camera>().farClipPlane;
|
||||
float y = Mathf.Tan (fovY * Mathf.Deg2Rad * 0.5f) * far;
|
||||
float x = y * GetComponent<Camera>().aspect;
|
||||
m_SSAOMaterial.SetVector ("_FarCorner", new Vector3(x,y,far));
|
||||
int noiseWidth, noiseHeight;
|
||||
if (m_RandomTexture) {
|
||||
noiseWidth = m_RandomTexture.width;
|
||||
noiseHeight = m_RandomTexture.height;
|
||||
} else {
|
||||
noiseWidth = 1; noiseHeight = 1;
|
||||
}
|
||||
m_SSAOMaterial.SetVector ("_NoiseScale", new Vector3 ((float)rtAO.width / noiseWidth, (float)rtAO.height / noiseHeight, 0.0f));
|
||||
m_SSAOMaterial.SetVector ("_Params", new Vector4(
|
||||
m_Radius,
|
||||
m_MinZ,
|
||||
1.0f / m_OcclusionAttenuation,
|
||||
m_OcclusionIntensity));
|
||||
|
||||
bool doBlur = m_Blur > 0;
|
||||
Graphics.Blit (doBlur ? null : source, rtAO, m_SSAOMaterial, (int)m_SampleCount);
|
||||
|
||||
if (doBlur)
|
||||
{
|
||||
// Blur SSAO horizontally
|
||||
RenderTexture rtBlurX = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
||||
new Vector4 ((float)m_Blur / source.width, 0,0,0));
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
||||
Graphics.Blit (null, rtBlurX, m_SSAOMaterial, 3);
|
||||
RenderTexture.ReleaseTemporary (rtAO); // original rtAO not needed anymore
|
||||
|
||||
// Blur SSAO vertically
|
||||
RenderTexture rtBlurY = RenderTexture.GetTemporary (source.width, source.height, 0);
|
||||
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
||||
new Vector4 (0, (float)m_Blur/source.height, 0,0));
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtBlurX);
|
||||
Graphics.Blit (source, rtBlurY, m_SSAOMaterial, 3);
|
||||
RenderTexture.ReleaseTemporary (rtBlurX); // blurX RT not needed anymore
|
||||
|
||||
rtAO = rtBlurY; // AO is the blurred one now
|
||||
}
|
||||
|
||||
// Modulate scene rendering with SSAO
|
||||
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
||||
Graphics.Blit (source, destination, m_SSAOMaterial, 4);
|
||||
|
||||
RenderTexture.ReleaseTemporary (rtAO);
|
||||
}
|
||||
|
||||
/*
|
||||
private void CreateRandomTable (int count, float minLength)
|
||||
{
|
||||
Random.seed = 1337;
|
||||
Vector3[] samples = new Vector3[count];
|
||||
// initial samples
|
||||
for (int i = 0; i < count; ++i)
|
||||
samples[i] = Random.onUnitSphere;
|
||||
// energy minimization: push samples away from others
|
||||
int iterations = 100;
|
||||
while (iterations-- > 0) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Vector3 vec = samples[i];
|
||||
Vector3 res = Vector3.zero;
|
||||
// minimize with other samples
|
||||
for (int j = 0; j < count; ++j) {
|
||||
Vector3 force = vec - samples[j];
|
||||
float fac = Vector3.Dot (force, force);
|
||||
if (fac > 0.00001f)
|
||||
res += force * (1.0f / fac);
|
||||
}
|
||||
samples[i] = (samples[i] + res * 0.5f).normalized;
|
||||
}
|
||||
}
|
||||
// now scale samples between minLength and 1.0
|
||||
for (int i = 0; i < count; ++i) {
|
||||
samples[i] = samples[i] * Random.Range (minLength, 1.0f);
|
||||
}
|
||||
|
||||
string table = string.Format ("#define SAMPLE_COUNT {0}\n", count);
|
||||
table += "const float3 RAND_SAMPLES[SAMPLE_COUNT] = {\n";
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Vector3 v = samples[i];
|
||||
table += string.Format("\tfloat3({0},{1},{2}),\n", v.x, v.y, v.z);
|
||||
}
|
||||
table += "};\n";
|
||||
Debug.Log (table);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0923359e9e352a4b9b11c7b7161ad67
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_SSAOShader: {fileID: 4800000, guid: 43ca18288c424f645aaa1e9e07f04c50, type: 3}
|
||||
- m_RandomTexture: {fileID: 2800000, guid: a181ca8e3c62f3e4b8f183f6c586b032, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Sepia Tone")]
|
||||
public class SepiaTone : ImageEffectBase
|
||||
{
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
Graphics.Blit (source, destination, material);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a07a781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: b6aa781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Rendering/Sun Shafts")]
|
||||
public class SunShafts : PostEffectsBase
|
||||
{
|
||||
public enum SunShaftsResolution
|
||||
{
|
||||
Low = 0,
|
||||
Normal = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
public enum ShaftsScreenBlendMode
|
||||
{
|
||||
Screen = 0,
|
||||
Add = 1,
|
||||
}
|
||||
|
||||
|
||||
public SunShaftsResolution resolution = SunShaftsResolution.Normal;
|
||||
public ShaftsScreenBlendMode screenBlendMode = ShaftsScreenBlendMode.Screen;
|
||||
|
||||
public Transform sunTransform;
|
||||
public int radialBlurIterations = 2;
|
||||
public Color sunColor = Color.white;
|
||||
public Color sunThreshold = new Color(0.87f,0.74f,0.65f);
|
||||
public float sunShaftBlurRadius = 2.5f;
|
||||
public float sunShaftIntensity = 1.15f;
|
||||
|
||||
public float maxRadius = 0.75f;
|
||||
|
||||
public bool useDepthTexture = true;
|
||||
|
||||
public Shader sunShaftsShader;
|
||||
private Material sunShaftsMaterial;
|
||||
|
||||
public Shader simpleClearShader;
|
||||
private Material simpleClearMaterial;
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (useDepthTexture);
|
||||
|
||||
sunShaftsMaterial = CheckShaderAndCreateMaterial (sunShaftsShader, sunShaftsMaterial);
|
||||
simpleClearMaterial = CheckShaderAndCreateMaterial (simpleClearShader, simpleClearMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources()==false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
// we actually need to check this every frame
|
||||
if (useDepthTexture)
|
||||
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
|
||||
|
||||
int divider = 4;
|
||||
if (resolution == SunShaftsResolution.Normal)
|
||||
divider = 2;
|
||||
else if (resolution == SunShaftsResolution.High)
|
||||
divider = 1;
|
||||
|
||||
Vector3 v = Vector3.one * 0.5f;
|
||||
if (sunTransform)
|
||||
v = GetComponent<Camera>().WorldToViewportPoint (sunTransform.position);
|
||||
else
|
||||
v = new Vector3(0.5f, 0.5f, 0.0f);
|
||||
|
||||
int rtW = source.width / divider;
|
||||
int rtH = source.height / divider;
|
||||
|
||||
RenderTexture lrColorB;
|
||||
RenderTexture lrDepthBuffer = RenderTexture.GetTemporary (rtW, rtH, 0);
|
||||
|
||||
// mask out everything except the skybox
|
||||
// we have 2 methods, one of which requires depth buffer support, the other one is just comparing images
|
||||
|
||||
sunShaftsMaterial.SetVector ("_BlurRadius4", new Vector4 (1.0f, 1.0f, 0.0f, 0.0f) * sunShaftBlurRadius );
|
||||
sunShaftsMaterial.SetVector ("_SunPosition", new Vector4 (v.x, v.y, v.z, maxRadius));
|
||||
sunShaftsMaterial.SetVector ("_SunThreshold", sunThreshold);
|
||||
|
||||
if (!useDepthTexture) {
|
||||
var format= GetComponent<Camera>().allowHDR ? RenderTextureFormat.DefaultHDR: RenderTextureFormat.Default;
|
||||
RenderTexture tmpBuffer = RenderTexture.GetTemporary (source.width, source.height, 0, format);
|
||||
RenderTexture.active = tmpBuffer;
|
||||
GL.ClearWithSkybox (false, GetComponent<Camera>());
|
||||
|
||||
sunShaftsMaterial.SetTexture ("_Skybox", tmpBuffer);
|
||||
Graphics.Blit (source, lrDepthBuffer, sunShaftsMaterial, 3);
|
||||
RenderTexture.ReleaseTemporary (tmpBuffer);
|
||||
}
|
||||
else {
|
||||
Graphics.Blit (source, lrDepthBuffer, sunShaftsMaterial, 2);
|
||||
}
|
||||
|
||||
// paint a small black small border to get rid of clamping problems
|
||||
DrawBorder (lrDepthBuffer, simpleClearMaterial);
|
||||
|
||||
// radial blur:
|
||||
|
||||
radialBlurIterations = Mathf.Clamp (radialBlurIterations, 1, 4);
|
||||
|
||||
float ofs = sunShaftBlurRadius * (1.0f / 768.0f);
|
||||
|
||||
sunShaftsMaterial.SetVector ("_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f));
|
||||
sunShaftsMaterial.SetVector ("_SunPosition", new Vector4 (v.x, v.y, v.z, maxRadius));
|
||||
|
||||
for (int it2 = 0; it2 < radialBlurIterations; it2++ ) {
|
||||
// each iteration takes 2 * 6 samples
|
||||
// we update _BlurRadius each time to cheaply get a very smooth look
|
||||
|
||||
lrColorB = RenderTexture.GetTemporary (rtW, rtH, 0);
|
||||
Graphics.Blit (lrDepthBuffer, lrColorB, sunShaftsMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (lrDepthBuffer);
|
||||
ofs = sunShaftBlurRadius * (((it2 * 2.0f + 1.0f) * 6.0f)) / 768.0f;
|
||||
sunShaftsMaterial.SetVector ("_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f) );
|
||||
|
||||
lrDepthBuffer = RenderTexture.GetTemporary (rtW, rtH, 0);
|
||||
Graphics.Blit (lrColorB, lrDepthBuffer, sunShaftsMaterial, 1);
|
||||
RenderTexture.ReleaseTemporary (lrColorB);
|
||||
ofs = sunShaftBlurRadius * (((it2 * 2.0f + 2.0f) * 6.0f)) / 768.0f;
|
||||
sunShaftsMaterial.SetVector ("_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f) );
|
||||
}
|
||||
|
||||
// put together:
|
||||
|
||||
if (v.z >= 0.0f)
|
||||
sunShaftsMaterial.SetVector ("_SunColor", new Vector4 (sunColor.r, sunColor.g, sunColor.b, sunColor.a) * sunShaftIntensity);
|
||||
else
|
||||
sunShaftsMaterial.SetVector ("_SunColor", Vector4.zero); // no backprojection !
|
||||
sunShaftsMaterial.SetTexture ("_ColorBuffer", lrDepthBuffer);
|
||||
Graphics.Blit (source, destination, sunShaftsMaterial, (screenBlendMode == ShaftsScreenBlendMode.Screen) ? 0 : 4);
|
||||
|
||||
RenderTexture.ReleaseTemporary (lrDepthBuffer);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60e318a6043c1cb4a8ce1c8805bab930
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- sunTransform: {instanceID: 0}
|
||||
- sunShaftsShader: {fileID: 4800000, guid: d3b1c8c1036784176946f5cfbfb7fe4c, type: 3}
|
||||
- simpleClearShader: {fileID: 4800000, guid: f688f89ed5eb847c5b19c934a0f1e772, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[RequireComponent (typeof(Camera))]
|
||||
[AddComponentMenu ("Image Effects/Camera/Tilt Shift (Lens Blur)")]
|
||||
class TiltShift : PostEffectsBase {
|
||||
public enum TiltShiftMode
|
||||
{
|
||||
TiltShiftMode,
|
||||
IrisMode,
|
||||
}
|
||||
public enum TiltShiftQuality
|
||||
{
|
||||
Preview,
|
||||
Normal,
|
||||
High,
|
||||
}
|
||||
|
||||
public TiltShiftMode mode = TiltShiftMode.TiltShiftMode;
|
||||
public TiltShiftQuality quality = TiltShiftQuality.Normal;
|
||||
|
||||
[Range(0.0f, 15.0f)]
|
||||
public float blurArea = 1.0f;
|
||||
|
||||
[Range(0.0f, 25.0f)]
|
||||
public float maxBlurSize = 5.0f;
|
||||
|
||||
[Range(0, 1)]
|
||||
public int downsample = 0;
|
||||
|
||||
public Shader tiltShiftShader = null;
|
||||
private Material tiltShiftMaterial = null;
|
||||
|
||||
|
||||
public override bool CheckResources () {
|
||||
CheckSupport (true);
|
||||
|
||||
tiltShiftMaterial = CheckShaderAndCreateMaterial (tiltShiftShader, tiltShiftMaterial);
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable ();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination) {
|
||||
if (CheckResources() == false) {
|
||||
Graphics.Blit (source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
tiltShiftMaterial.SetFloat("_BlurSize", maxBlurSize < 0.0f ? 0.0f : maxBlurSize);
|
||||
tiltShiftMaterial.SetFloat("_BlurArea", blurArea);
|
||||
source.filterMode = FilterMode.Bilinear;
|
||||
|
||||
RenderTexture rt = destination;
|
||||
if (downsample > 0f) {
|
||||
rt = RenderTexture.GetTemporary (source.width>>downsample, source.height>>downsample, 0, source.format);
|
||||
rt.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
|
||||
int basePassNr = (int) quality; basePassNr *= 2;
|
||||
Graphics.Blit (source, rt, tiltShiftMaterial, mode == TiltShiftMode.TiltShiftMode ? basePassNr : basePassNr + 1);
|
||||
|
||||
if (downsample > 0) {
|
||||
tiltShiftMaterial.SetTexture ("_Blurred", rt);
|
||||
Graphics.Blit (source, destination, tiltShiftMaterial, 6);
|
||||
}
|
||||
|
||||
if (rt != destination)
|
||||
RenderTexture.ReleaseTemporary (rt);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a22b3a7095a744a428c134b5e26ad68e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- tiltShiftShader: {fileID: 4800000, guid: bf34d2a25450349699e8ae6456fa7ca9, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,274 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof (Camera))]
|
||||
[AddComponentMenu("Image Effects/Color Adjustments/Tonemapping")]
|
||||
public class Tonemapping : PostEffectsBase
|
||||
{
|
||||
public enum TonemapperType
|
||||
{
|
||||
SimpleReinhard,
|
||||
UserCurve,
|
||||
Hable,
|
||||
Photographic,
|
||||
OptimizedHejiDawson,
|
||||
AdaptiveReinhard,
|
||||
AdaptiveReinhardAutoWhite,
|
||||
};
|
||||
|
||||
public enum AdaptiveTexSize
|
||||
{
|
||||
Square16 = 16,
|
||||
Square32 = 32,
|
||||
Square64 = 64,
|
||||
Square128 = 128,
|
||||
Square256 = 256,
|
||||
Square512 = 512,
|
||||
Square1024 = 1024,
|
||||
};
|
||||
|
||||
public TonemapperType type = TonemapperType.Photographic;
|
||||
public AdaptiveTexSize adaptiveTextureSize = AdaptiveTexSize.Square256;
|
||||
|
||||
// CURVE parameter
|
||||
public AnimationCurve remapCurve;
|
||||
private Texture2D curveTex = null;
|
||||
|
||||
// UNCHARTED parameter
|
||||
public float exposureAdjustment = 1.5f;
|
||||
|
||||
// REINHARD parameter
|
||||
public float middleGrey = 0.4f;
|
||||
public float white = 2.0f;
|
||||
public float adaptionSpeed = 1.5f;
|
||||
|
||||
// usual & internal stuff
|
||||
public Shader tonemapper = null;
|
||||
public bool validRenderTextureFormat = true;
|
||||
private Material tonemapMaterial = null;
|
||||
private RenderTexture rt = null;
|
||||
private RenderTextureFormat rtFormat = RenderTextureFormat.ARGBHalf;
|
||||
|
||||
|
||||
public override bool CheckResources()
|
||||
{
|
||||
CheckSupport(false, true);
|
||||
|
||||
tonemapMaterial = CheckShaderAndCreateMaterial(tonemapper, tonemapMaterial);
|
||||
if (!curveTex && type == TonemapperType.UserCurve)
|
||||
{
|
||||
curveTex = new Texture2D(256, 1, TextureFormat.ARGB32, false, true);
|
||||
curveTex.filterMode = FilterMode.Bilinear;
|
||||
curveTex.wrapMode = TextureWrapMode.Clamp;
|
||||
curveTex.hideFlags = HideFlags.DontSave;
|
||||
}
|
||||
|
||||
if (!isSupported)
|
||||
ReportAutoDisable();
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
|
||||
public float UpdateCurve()
|
||||
{
|
||||
float range = 1.0f;
|
||||
if (remapCurve.keys.Length < 1)
|
||||
remapCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(2, 1));
|
||||
if (remapCurve != null)
|
||||
{
|
||||
if (remapCurve.length > 0)
|
||||
range = remapCurve[remapCurve.length - 1].time;
|
||||
for (float i = 0.0f; i <= 1.0f; i += 1.0f/255.0f)
|
||||
{
|
||||
float c = remapCurve.Evaluate(i*1.0f*range);
|
||||
curveTex.SetPixel((int) Mathf.Floor(i*255.0f), 0, new Color(c, c, c));
|
||||
}
|
||||
curveTex.Apply();
|
||||
}
|
||||
return 1.0f/range;
|
||||
}
|
||||
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (rt)
|
||||
{
|
||||
DestroyImmediate(rt);
|
||||
rt = null;
|
||||
}
|
||||
if (tonemapMaterial)
|
||||
{
|
||||
DestroyImmediate(tonemapMaterial);
|
||||
tonemapMaterial = null;
|
||||
}
|
||||
if (curveTex)
|
||||
{
|
||||
DestroyImmediate(curveTex);
|
||||
curveTex = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool CreateInternalRenderTexture()
|
||||
{
|
||||
if (rt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
rtFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf) ? RenderTextureFormat.RGHalf : RenderTextureFormat.ARGBHalf;
|
||||
rt = new RenderTexture(1, 1, 0, rtFormat);
|
||||
rt.hideFlags = HideFlags.DontSave;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// attribute indicates that the image filter chain will continue in LDR
|
||||
[ImageEffectTransformsToLDR]
|
||||
private void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if (CheckResources() == false)
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
validRenderTextureFormat = true;
|
||||
if (source.format != RenderTextureFormat.ARGBHalf)
|
||||
{
|
||||
validRenderTextureFormat = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// clamp some values to not go out of a valid range
|
||||
|
||||
exposureAdjustment = exposureAdjustment < 0.001f ? 0.001f : exposureAdjustment;
|
||||
|
||||
// SimpleReinhard tonemappers (local, non adaptive)
|
||||
|
||||
if (type == TonemapperType.UserCurve)
|
||||
{
|
||||
float rangeScale = UpdateCurve();
|
||||
tonemapMaterial.SetFloat("_RangeScale", rangeScale);
|
||||
tonemapMaterial.SetTexture("_Curve", curveTex);
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == TonemapperType.SimpleReinhard)
|
||||
{
|
||||
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 6);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == TonemapperType.Hable)
|
||||
{
|
||||
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == TonemapperType.Photographic)
|
||||
{
|
||||
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == TonemapperType.OptimizedHejiDawson)
|
||||
{
|
||||
tonemapMaterial.SetFloat("_ExposureAdjustment", 0.5f*exposureAdjustment);
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 7);
|
||||
return;
|
||||
}
|
||||
|
||||
// still here?
|
||||
// => adaptive tone mapping:
|
||||
// builds an average log luminance, tonemaps according to
|
||||
// middle grey and white values (user controlled)
|
||||
|
||||
// AdaptiveReinhardAutoWhite will calculate white value automagically
|
||||
|
||||
bool freshlyBrewedInternalRt = CreateInternalRenderTexture(); // this retrieves rtFormat, so should happen before rt allocations
|
||||
|
||||
RenderTexture rtSquared = RenderTexture.GetTemporary((int) adaptiveTextureSize, (int) adaptiveTextureSize, 0, rtFormat);
|
||||
Graphics.Blit(source, rtSquared);
|
||||
|
||||
int downsample = (int) Mathf.Log(rtSquared.width*1.0f, 2);
|
||||
|
||||
int div = 2;
|
||||
var rts = new RenderTexture[downsample];
|
||||
for (int i = 0; i < downsample; i++)
|
||||
{
|
||||
rts[i] = RenderTexture.GetTemporary(rtSquared.width/div, rtSquared.width/div, 0, rtFormat);
|
||||
div *= 2;
|
||||
}
|
||||
|
||||
// downsample pyramid
|
||||
|
||||
var lumRt = rts[downsample - 1];
|
||||
Graphics.Blit(rtSquared, rts[0], tonemapMaterial, 1);
|
||||
if (type == TonemapperType.AdaptiveReinhardAutoWhite)
|
||||
{
|
||||
for (int i = 0; i < downsample - 1; i++)
|
||||
{
|
||||
Graphics.Blit(rts[i], rts[i + 1], tonemapMaterial, 9);
|
||||
lumRt = rts[i + 1];
|
||||
}
|
||||
}
|
||||
else if (type == TonemapperType.AdaptiveReinhard)
|
||||
{
|
||||
for (int i = 0; i < downsample - 1; i++)
|
||||
{
|
||||
Graphics.Blit(rts[i], rts[i + 1]);
|
||||
lumRt = rts[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// we have the needed values, let's apply adaptive tonemapping
|
||||
|
||||
adaptionSpeed = adaptionSpeed < 0.001f ? 0.001f : adaptionSpeed;
|
||||
tonemapMaterial.SetFloat("_AdaptionSpeed", adaptionSpeed);
|
||||
|
||||
rt.MarkRestoreExpected(); // keeping luminance values between frames, RT restore expected
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isPlaying && !freshlyBrewedInternalRt)
|
||||
Graphics.Blit(lumRt, rt, tonemapMaterial, 2);
|
||||
else
|
||||
Graphics.Blit(lumRt, rt, tonemapMaterial, 3);
|
||||
#else
|
||||
Graphics.Blit (lumRt, rt, tonemapMaterial, freshlyBrewedInternalRt ? 3 : 2);
|
||||
#endif
|
||||
|
||||
middleGrey = middleGrey < 0.001f ? 0.001f : middleGrey;
|
||||
tonemapMaterial.SetVector("_HdrParams", new Vector4(middleGrey, middleGrey, middleGrey, white*white));
|
||||
tonemapMaterial.SetTexture("_SmallTex", rt);
|
||||
if (type == TonemapperType.AdaptiveReinhard)
|
||||
{
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 0);
|
||||
}
|
||||
else if (type == TonemapperType.AdaptiveReinhardAutoWhite)
|
||||
{
|
||||
Graphics.Blit(source, destination, tonemapMaterial, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("No valid adaptive tonemapper type found!");
|
||||
Graphics.Blit(source, destination); // at least we get the TransformToLDR effect
|
||||
}
|
||||
|
||||
// cleanup for adaptive
|
||||
|
||||
for (int i = 0; i < downsample; i++)
|
||||
{
|
||||
RenderTexture.ReleaseTemporary(rts[i]);
|
||||
}
|
||||
RenderTexture.ReleaseTemporary(rtSquared);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e50e925fb93c78246bf995d9dc3a2330
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- tonemapper: {fileID: 4800000, guid: 003377fc2620a44939dadde6fe3f8190, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,112 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18b91636de2ba3445913e4cf38528dc8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Displacement/Twirl")]
|
||||
public class Twirl : ImageEffectBase
|
||||
{
|
||||
public Vector2 radius = new Vector2(0.3F,0.3F);
|
||||
[Range(0.0f,360.0f)]
|
||||
public float angle = 50;
|
||||
public Vector2 center = new Vector2 (0.5F, 0.5F);
|
||||
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
ImageEffects.RenderDistortion (material, source, destination, angle, center, radius);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdda781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 641b781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,114 @@
|
||||
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.036f; // 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", (1.0f / (1.0f - intensity) - 1.0f)); // intensity for vignette
|
||||
m_VignetteMaterial.SetFloat("_Blur", (1.0f / (1.0f - blur)) - 1.0f); // 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
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:
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.ImageEffects
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Image Effects/Displacement/Vortex")]
|
||||
public class Vortex : ImageEffectBase
|
||||
{
|
||||
public Vector2 radius = new Vector2(0.4F,0.4F);
|
||||
public float angle = 50;
|
||||
public Vector2 center = new Vector2(0.5F, 0.5F);
|
||||
|
||||
// Called by camera to apply image effect
|
||||
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
ImageEffects.RenderDistortion (material, source, destination, angle, center, radius);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a94b781cad112c75d0008dfa8d76c639
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- shader: {fileID: 4800000, guid: 708b781cad112c75d0008dfa8d76c639, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2145489f7c704db8acb14a52bddeee9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,135 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
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 = UnityObjectToClipPos(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 * _Intensity);
|
||||
}
|
||||
|
||||
|
||||
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
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c81db0e527d24acc9bcec04e87781bd
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,44 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
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 = UnityObjectToClipPos(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
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57e6deea7c2924e22a5138e2b70bb4dc
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,518 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
/*
|
||||
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 = UnityObjectToClipPos(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
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85a88efa8c871af4a9d17c64791b6f4f
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,223 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
/*
|
||||
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 = UnityObjectToClipPos (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
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1b13d7a80660504a858ea24cfa418c6
|
||||
ShaderImporter:
|
||||
userData:
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user