diff --git a/Assets/Materials/Chapter14/ToonShading.mat b/Assets/Materials/Chapter14/ToonShading.mat new file mode 100644 index 0000000..8eec8c7 --- /dev/null +++ b/Assets/Materials/Chapter14/ToonShading.mat @@ -0,0 +1,84 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: ToonShading + m_Shader: {fileID: 4800000, guid: c7003a2e6a2f78542a4f7afbb06ffd7c, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Ramp: + m_Texture: {fileID: 2800000, guid: f628a9d765d21417995f27cbf8e44c2c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Outline: 0.04 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SpecularScale: 0.018 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.9411765, g: 0.8235294, b: 0.63529414, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _OutlineColor: {r: 0, g: 0, b: 0, a: 1} + - _Specular: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/Materials/Chapter14/ToonShading.mat.meta b/Assets/Materials/Chapter14/ToonShading.mat.meta new file mode 100644 index 0000000..da4238b --- /dev/null +++ b/Assets/Materials/Chapter14/ToonShading.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c2d1637ec0ee6b4799a5e53092c18f9 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing.meta b/Assets/PostProcessing.meta new file mode 100644 index 0000000..c0e385f --- /dev/null +++ b/Assets/PostProcessing.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2c2094cc4b5d0cb41bc93a3e50e98d9f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources.meta b/Assets/PostProcessing/Editor Resources.meta new file mode 100644 index 0000000..fc44a55 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 83715878d3a8db441aa5636641db69a3 +folderAsset: yes +timeCreated: 1476176392 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors.meta b/Assets/PostProcessing/Editor Resources/Monitors.meta new file mode 100644 index 0000000..2be84db --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e7358848dd8737c459f4636f1c075835 +folderAsset: yes +timeCreated: 1460361782 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute b/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute new file mode 100644 index 0000000..da7507b --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute @@ -0,0 +1,91 @@ +#include "UnityCG.cginc" + +RWStructuredBuffer _Histogram; +Texture2D _Source; + +CBUFFER_START (Params) + uint _IsLinear; + float4 _Res; + uint4 _Channels; +CBUFFER_END + +groupshared uint4 gs_histogram[256]; + +#define GROUP_SIZE 16 + +#pragma kernel KHistogramGather +[numthreads(GROUP_SIZE, GROUP_SIZE,1)] +void KHistogramGather(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID) +{ + const uint localThreadId = groupThreadId.y * GROUP_SIZE + groupThreadId.x; + + if (localThreadId < 256) + gs_histogram[localThreadId] = uint4(0, 0, 0, 0); + + GroupMemoryBarrierWithGroupSync(); + + if (dispatchThreadId.x < (uint)_Res.x && dispatchThreadId.y < (uint)_Res.y) + { + // We want a gamma histogram (like Photoshop & all) + float3 color = saturate(_Source[dispatchThreadId].xyz); + if (_IsLinear > 0) + color = LinearToGammaSpace(color); + + // Convert color & luminance to histogram bin + uint3 idx_c = (uint3)(round(color * 255.0)); + uint idx_l = (uint)(round(dot(color.rgb, float3(0.2125, 0.7154, 0.0721)) * 255.0)); + + // Fill the group shared histogram + if (_Channels.x > 0u) InterlockedAdd(gs_histogram[idx_c.x].x, 1); // Red + if (_Channels.y > 0u) InterlockedAdd(gs_histogram[idx_c.y].y, 1); // Green + if (_Channels.z > 0u) InterlockedAdd(gs_histogram[idx_c.z].z, 1); // Blue + if (_Channels.w > 0u) InterlockedAdd(gs_histogram[idx_l].w, 1); // Luminance + } + + GroupMemoryBarrierWithGroupSync(); + + // Merge + if (localThreadId < 256) + { + uint4 h = gs_histogram[localThreadId]; + if (_Channels.x > 0u && h.x > 0) InterlockedAdd(_Histogram[localThreadId].x, h.x); // Red + if (_Channels.y > 0u && h.y > 0) InterlockedAdd(_Histogram[localThreadId].y, h.y); // Green + if (_Channels.z > 0u && h.z > 0) InterlockedAdd(_Histogram[localThreadId].z, h.z); // Blue + if (_Channels.w > 0u && h.w > 0) InterlockedAdd(_Histogram[localThreadId].w, h.w); // Luminance + } +} + +// Scaling pass +groupshared uint4 gs_pyramid[256]; + +#pragma kernel KHistogramScale +[numthreads(16,16,1)] +void KHistogramScale(uint2 groupThreadId : SV_GroupThreadID) +{ + const uint localThreadId = groupThreadId.y * 16 + groupThreadId.x; + gs_pyramid[localThreadId] = _Histogram[localThreadId]; + + GroupMemoryBarrierWithGroupSync(); + + // Parallel reduction to find the max value + UNITY_UNROLL + for(uint i = 256 >> 1; i > 0; i >>= 1) + { + if(localThreadId < i) + gs_pyramid[localThreadId] = max(gs_pyramid[localThreadId], gs_pyramid[localThreadId + i]); + + GroupMemoryBarrierWithGroupSync(); + } + + // Actual scaling + float4 factor = _Res.y / (float4)gs_pyramid[0]; + _Histogram[localThreadId] = (uint4)round(_Histogram[localThreadId] * factor); +} + +#pragma kernel KHistogramClear +[numthreads(GROUP_SIZE, GROUP_SIZE, 1)] +void KHistogramClear(uint2 dispatchThreadId : SV_DispatchThreadID) +{ + if (dispatchThreadId.x < (uint)_Res.x && dispatchThreadId.y < (uint)_Res.y) + _Histogram[dispatchThreadId.y * _Res.x + dispatchThreadId.x] = uint4(0u, 0u, 0u, 0u); +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute.meta b/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute.meta new file mode 100644 index 0000000..caa08a8 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/HistogramCompute.compute.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 51b7e4b4448c98f4a849081110fd6212 +timeCreated: 1459956391 +licenseType: Store +ComputeShaderImporter: + currentAPIMask: 4 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader b/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader new file mode 100644 index 0000000..c69cf75 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader @@ -0,0 +1,141 @@ +Shader "Hidden/Post FX/Monitors/Histogram Render" +{ + SubShader + { + ZTest Always Cull Off ZWrite Off + Fog { Mode off } + + CGINCLUDE + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma target 5.0 + #include "UnityCG.cginc" + + StructuredBuffer _Histogram; + float2 _Size; + uint _Channel; + float4 _ColorR; + float4 _ColorG; + float4 _ColorB; + float4 _ColorL; + + float4 FragSingleChannel(v2f_img i) : SV_Target + { + const float4 COLORS[4] = { _ColorR, _ColorG, _ColorB, _ColorL }; + + float remapI = i.uv.x * 255.0; + uint index = floor(remapI); + float delta = frac(remapI); + float v1 = _Histogram[index][_Channel]; + float v2 = _Histogram[min(index + 1, 255)][_Channel]; + float h = v1 * (1.0 - delta) + v2 * delta; + uint y = (uint)round(i.uv.y * _Size.y); + + float4 color = float4(0.1, 0.1, 0.1, 1.0); + float fill = step(y, h); + color = lerp(color, COLORS[_Channel], fill); + return color; + } + + float4 FragRgbMerged(v2f_img i) : SV_Target + { + const float4 COLORS[3] = { _ColorR, _ColorG, _ColorB }; + + float4 targetColor = float4(0.1, 0.1, 0.1, 1.0); + float4 emptyColor = float4(0.0, 0.0, 0.0, 1.0); + + float remapI = i.uv.x * 255.0; + uint index = floor(remapI); + float delta = frac(remapI); + + for (int j = 0; j < 3; j++) + { + float v1 = _Histogram[index][j]; + float v2 = _Histogram[min(index + 1, 255)][j]; + float h = v1 * (1.0 - delta) + v2 * delta; + uint y = (uint)round(i.uv.y * _Size.y); + float fill = step(y, h); + float4 color = lerp(emptyColor, COLORS[j], fill); + targetColor += color; + } + + return saturate(targetColor); + } + + float4 FragRgbSplitted(v2f_img i) : SV_Target + { + const float4 COLORS[3] = {_ColorR, _ColorG, _ColorB}; + + const float limitB = round(_Size.y / 3.0); + const float limitG = limitB * 2; + + float4 color = float4(0.1, 0.1, 0.1, 1.0); + uint channel; + float offset; + + if (i.pos.y < limitB) + { + channel = 2; + offset = 0.0; + } + else if (i.pos.y < limitG) + { + channel = 1; + offset = limitB; + } + else + { + channel = 0; + offset = limitG; + } + + float remapI = i.uv.x * 255.0; + uint index = floor(remapI); + float delta = frac(remapI); + float v1 = offset + _Histogram[index][channel] / 3.0; + float v2 = offset + _Histogram[min(index + 1, 255)][channel] / 3.0; + float h = v1 * (1.0 - delta) + v2 * delta; + uint y = (uint)round(i.uv.y * _Size.y); + + float fill = step(y, h); + color = lerp(color, COLORS[channel], fill); + return color; + } + + ENDCG + + // (0) Channel + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragSingleChannel + + ENDCG + } + + // (1) RGB merged + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragRgbMerged + + ENDCG + } + + // (2) RGB splitted + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragRgbSplitted + + ENDCG + } + } + FallBack off +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader.meta b/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader.meta new file mode 100644 index 0000000..2b4b4e7 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/HistogramRender.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 965efa32cf2345647a1c987546e08f86 +timeCreated: 1459956391 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader b/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader new file mode 100644 index 0000000..3ff1ca6 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader @@ -0,0 +1,76 @@ +Shader "Hidden/Post FX/Monitors/Parade Render" +{ + SubShader + { + ZTest Always Cull Off ZWrite Off + Fog { Mode off } + + CGINCLUDE + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma target 5.0 + #include "UnityCG.cginc" + + StructuredBuffer _Waveform; + float4 _Size; + float _Exposure; + + float3 Tonemap(float3 x, float exposure) + { + const float a = 6.2; + const float b = 0.5; + const float c = 1.7; + const float d = 0.06; + x *= exposure; + x = max((0.0).xxx, x - (0.004).xxx); + x = (x * (a * x + b)) / (x * (a * x + c) + d); + return x * x; + } + + float4 FragParade(v2f_img i) : SV_Target + { + const float3 red = float3(1.8, 0.03, 0.02); + const float3 green = float3(0.02, 1.3, 0.05); + const float3 blue = float3(0.0, 0.45, 1.75); + float3 color = float3(0.0, 0.0, 0.0); + + const uint limitR = _Size.x / 3; + const uint limitG = limitR * 2; + + if (i.pos.x < (float)limitR) + { + uint2 uvI = i.pos.xy; + color = _Waveform[uvI.y + uvI.x * _Size.y].r * red; + } + else if (i.pos.x < (float)limitG) + { + uint2 uvI = uint2(i.pos.x - limitR, i.pos.y); + color = _Waveform[uvI.y + uvI.x * _Size.y].g * green; + } + else + { + uint2 uvI = uint2(i.pos.x - limitG, i.pos.y); + color = _Waveform[uvI.y + uvI.x * _Size.y].b * blue; + } + + color = Tonemap(color, _Exposure); + color += (0.1).xxx; + + return float4(saturate(color), 1.0); + } + + ENDCG + + // (0) + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragParade + + ENDCG + } + } + FallBack off +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader.meta b/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader.meta new file mode 100644 index 0000000..9570da9 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/ParadeRender.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5ae1bfc1dd20ac04e8b74aa0f2f12eea +timeCreated: 1459956391 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute new file mode 100644 index 0000000..c5c61d0 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute @@ -0,0 +1,49 @@ +#include "UnityCG.cginc" + +RWStructuredBuffer _Vectorscope; +Texture2D _Source; + +CBUFFER_START (Params) + uint _IsLinear; + float4 _Res; +CBUFFER_END + +#define GROUP_SIZE 32 + +float3 RgbToYUV(float3 c) +{ + float Y = 0.299 * c.r + 0.587 * c.g + 0.114 * c.b; + float U = -0.169 * c.r - 0.331 * c.g + 0.500 * c.b; + float V = 0.500 * c.r - 0.419 * c.g - 0.081 * c.b; + return float3(Y, U, V); +} + +#pragma kernel KVectorscope +[numthreads(GROUP_SIZE,GROUP_SIZE,1)] +void KVectorscope(uint2 dispatchThreadId : SV_DispatchThreadID) +{ + if (dispatchThreadId.x < (uint)_Res.x && dispatchThreadId.y < (uint)_Res.y) + { + float3 color = saturate(_Source[dispatchThreadId].xyz); + if (_IsLinear > 0) + color = LinearToGammaSpace(color); + + float3 yuv = RgbToYUV(color); + + if (length(yuv.yz) > 0.49) + yuv.yz = normalize(yuv.yz) * 0.49; + + yuv.yz += (0.5).xx; + uint u = (uint)floor(yuv.y * _Res.x); + uint v = (uint)floor(yuv.z * _Res.y); + InterlockedAdd(_Vectorscope[v * _Res.x + u], 1); + } +} + +#pragma kernel KVectorscopeClear +[numthreads(GROUP_SIZE,GROUP_SIZE,1)] +void KVectorscopeClear(uint2 dispatchThreadId : SV_DispatchThreadID) +{ + if (dispatchThreadId.x < (uint)_Res.x && dispatchThreadId.y < (uint)_Res.y) + _Vectorscope[dispatchThreadId.y * _Res.x + dispatchThreadId.x] = 0u; +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute.meta b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute.meta new file mode 100644 index 0000000..3d6b3ac --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeCompute.compute.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 45de9ff58691e934c9810dc23de2ba50 +timeCreated: 1459956391 +licenseType: Store +ComputeShaderImporter: + currentAPIMask: 4 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader new file mode 100644 index 0000000..62a7a03 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader @@ -0,0 +1,101 @@ +Shader "Hidden/Post FX/Monitors/Vectorscope Render" +{ + SubShader + { + ZTest Always Cull Off ZWrite Off + Fog { Mode off } + + CGINCLUDE + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma target 5.0 + #include "UnityCG.cginc" + + StructuredBuffer _Vectorscope; + float2 _Size; + float _Exposure; + + float Tonemap(float x, float exposure) + { + const float a = 6.2; + const float b = 0.5; + const float c = 1.7; + const float d = 0.06; + x *= exposure; + x = max(0.0, x - 0.004); + x = (x * (a * x + b)) / (x * (a * x + c) + d); + return x * x; + } + + float3 YuvToRgb(float3 c) + { + float R = c.x + 0.000 * c.y + 1.403 * c.z; + float G = c.x - 0.344 * c.y - 0.714 * c.z; + float B = c.x - 1.773 * c.y + 0.000 * c.z; + return float3(R, G, B); + } + + float4 FragBackground(v2f_img i) : SV_Target + { + i.uv.x = 1.0 - i.uv.x; + float2 uv = i.uv - (0.5).xx; + float3 c = YuvToRgb(float3(0.5, uv.x, uv.y)); + + float dist = sqrt(dot(uv, uv)); + float delta = fwidth(dist); + float alphaOut = 1.0 - smoothstep(0.5 - delta, 0.5 + delta, dist); + float alphaIn = smoothstep(0.495 - delta, 0.495 + delta, dist); + + uint2 uvI = i.pos.xy; + uint v = _Vectorscope[uvI.x + uvI.y * _Size.x]; + float vt = saturate(Tonemap(v, _Exposure)); + + float4 color = float4(lerp(c, (0.0).xxx, vt), alphaOut); + color.rgb += alphaIn; + return color; + } + + float4 FragNoBackground(v2f_img i) : SV_Target + { + i.uv.x = 1.0 - i.uv.x; + float2 uv = i.uv - (0.5).xx; + + float dist = sqrt(dot(uv, uv)); + float delta = fwidth(dist); + float alphaOut = 1.0 - smoothstep(0.5 - delta, 0.5 + delta, dist); + float alphaIn = smoothstep(0.495 - delta, 0.495 + delta, dist); + + uint2 uvI = i.pos.xy; + uint v = _Vectorscope[uvI.x + uvI.y * _Size.x]; + float vt = saturate(Tonemap(v, _Exposure)); + + float4 color = float4((1.0).xxx, vt + alphaIn * alphaOut); + return color; + } + + ENDCG + + // (0) + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragBackground + + ENDCG + } + + // (1) + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragNoBackground + + ENDCG + } + } + FallBack off +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader.meta b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader.meta new file mode 100644 index 0000000..5493b16 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/VectorscopeRender.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1c4298cd35ef7834e892898e49d61ecd +timeCreated: 1461756159 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute b/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute new file mode 100644 index 0000000..cc79b15 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute @@ -0,0 +1,42 @@ +#include "UnityCG.cginc" + +RWStructuredBuffer _Waveform; +Texture2D _Source; + +CBUFFER_START (Params) + uint _IsLinear; + uint4 _Channels; +CBUFFER_END + +#define COLUMNS 384 + +#pragma kernel KWaveform +[numthreads(1,COLUMNS,1)] +void KWaveform(uint2 dispatchThreadId : SV_DispatchThreadID) +{ + // We want a gamma corrected colors + float3 color = _Source[dispatchThreadId].rgb; + if (_IsLinear > 0u) + color = LinearToGammaSpace(color); + + color = saturate(color); + + // Convert color & luminance to histogram bins + const float kColumnsMinusOne = COLUMNS - 1.0; + uint3 idx_c = (uint3)(round(color * kColumnsMinusOne)); + uint idx_l = (uint)(round(dot(color.rgb, float3(0.2126, 0.7152, 0.0722)) * kColumnsMinusOne)); + + // A lot of atomic operations will be skipped so there's no need to over-think this one. + uint j = dispatchThreadId.x * COLUMNS; + if (_Channels.x > 0u && idx_c.x > 0u) InterlockedAdd(_Waveform[j + idx_c.x].x, 1u); // Red + if (_Channels.y > 0u && idx_c.y > 0u) InterlockedAdd(_Waveform[j + idx_c.y].y, 1u); // Green + if (_Channels.z > 0u && idx_c.z > 0u) InterlockedAdd(_Waveform[j + idx_c.z].z, 1u); // Blue + if (_Channels.w > 0u) InterlockedAdd(_Waveform[j + idx_l].w, 1u); // Luminance +} + +#pragma kernel KWaveformClear +[numthreads(1, COLUMNS, 1)] +void KWaveformClear(uint2 dispatchThreadId : SV_DispatchThreadID) +{ + _Waveform[dispatchThreadId.x * COLUMNS + dispatchThreadId.y] = uint4(0u, 0u, 0u, 0u); +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute.meta b/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute.meta new file mode 100644 index 0000000..c85ca93 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/WaveformCompute.compute.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9d9b886f7a8fe7b4baf56624c42e3420 +timeCreated: 1459956392 +licenseType: Store +ComputeShaderImporter: + currentAPIMask: 4 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader b/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader new file mode 100644 index 0000000..39cffd7 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader @@ -0,0 +1,65 @@ +Shader "Hidden/Post FX/Monitors/Waveform Render" +{ + SubShader + { + ZTest Always Cull Off ZWrite Off + Fog { Mode off } + + CGINCLUDE + + #pragma fragmentoption ARB_precision_hint_fastest + #pragma target 5.0 + #include "UnityCG.cginc" + + StructuredBuffer _Waveform; + float2 _Size; + float4 _Channels; + float _Exposure; + + float3 Tonemap(float3 x, float exposure) + { + const float a = 6.2; + const float b = 0.5; + const float c = 1.7; + const float d = 0.06; + x *= exposure; + x = max((0.0).xxx, x - (0.004).xxx); + x = (x * (a * x + b)) / (x * (a * x + c) + d); + return x * x; + } + + float4 FragWaveform(v2f_img i) : SV_Target + { + const float3 red = float3(1.4, 0.03, 0.02); + const float3 green = float3(0.02, 1.1, 0.05); + const float3 blue = float3(0.0, 0.25, 1.5); + float3 color = float3(0.0, 0.0, 0.0); + + uint2 uvI = i.pos.xy; + float4 w = _Waveform[uvI.y + uvI.x * _Size.y]; // Waveform data is stored in columns instead of rows + + color += red * w.r * _Channels.r; + color += green * w.g * _Channels.g; + color += blue * w.b * _Channels.b; + color += w.aaa * _Channels.a * 1.5; + color = Tonemap(color, _Exposure); + color += (0.1).xxx; + + return float4(saturate(color), 1.0); + } + + ENDCG + + // (0) + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragWaveform + + ENDCG + } + } + FallBack off +} diff --git a/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader.meta b/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader.meta new file mode 100644 index 0000000..3a6eb4e --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/Monitors/WaveformRender.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8b3e43c50424ab2428a9c172843bc66d +timeCreated: 1459956391 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/UI.meta b/Assets/PostProcessing/Editor Resources/UI.meta new file mode 100644 index 0000000..2856c53 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: df37d60cc69b7b04d9705a74938179e7 +folderAsset: yes +timeCreated: 1460627771 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader b/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader new file mode 100644 index 0000000..b4f20b2 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader @@ -0,0 +1,63 @@ +Shader "Hidden/Post FX/UI/Curve Background" +{ + CGINCLUDE + + #pragma target 3.0 + #include "UnityCG.cginc" + + float _DisabledState; + + float3 HsvToRgb(float3 c) + { + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); + } + + float4 FragHue(v2f_img i) : SV_Target + { + float3 hsv = HsvToRgb(float3(i.uv.x, 1.0, 0.2)); + float4 color = float4((0.0).xxx, 1.0); + color.rgb = lerp(color.rgb, hsv, smoothstep(0.5, 1.1, 1.0 - i.uv.y)) + lerp(color.rgb, hsv, smoothstep(0.5, 1.1, i.uv.y)); + color.rgb += (0.15).xxx; + return float4(color.rgb, color.a * _DisabledState); + } + + float4 FragSat(v2f_img i) : SV_Target + { + float4 color = float4((0.0).xxx, 1.0); + float sat = i.uv.x / 2; + color.rgb += lerp(color.rgb, (sat).xxx, smoothstep(0.5, 1.2, 1.0 - i.uv.y)) + lerp(color.rgb, (sat).xxx, smoothstep(0.5, 1.2, i.uv.y)); + color.rgb += (0.15).xxx; + return float4(color.rgb, color.a * _DisabledState); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) Hue + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragHue + + ENDCG + } + + // (1) Sat/lum + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragSat + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader.meta b/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader.meta new file mode 100644 index 0000000..d459ca5 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI/CurveBackground.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b1b2bfb2897659e45983f0c3e7dda2c8 +timeCreated: 1460970196 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png b/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png new file mode 100644 index 0000000..91de8db Binary files /dev/null and b/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png differ diff --git a/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png.meta b/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png.meta new file mode 100644 index 0000000..c7e1ebe --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI/MotionBlendingIcon.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: c0fa58091049bd24394fa15b0b6d4c5a +timeCreated: 1468326774 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor Resources/UI/Trackball.shader b/Assets/PostProcessing/Editor Resources/UI/Trackball.shader new file mode 100644 index 0000000..264c6a1 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI/Trackball.shader @@ -0,0 +1,118 @@ +Shader "Hidden/Post FX/UI/Trackball" +{ + CGINCLUDE + + #include "UnityCG.cginc" + + #define PI 3.14159265359 + #define PI2 6.28318530718 + + float _Offset; + float _DisabledState; + float2 _Resolution; // x: size, y: size / 2 + + float3 HsvToRgb(float3 c) + { + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); + } + + float4 CreateWheel(v2f_img i, float crossColor, float offsetColor) + { + const float kHueOuterRadius = 0.45; + const float kHueInnerRadius = 0.38; + const float kLumOuterRadius = 0.495; + const float kLumInnerRadius = 0.48; + + float4 color = (0.0).xxxx; + float2 uvc = i.uv - (0.5).xx; + float dist = sqrt(dot(uvc, uvc)); + float delta = fwidth(dist); + float angle = atan2(uvc.x, uvc.y); + + // Cross + { + float radius = (0.5 - kHueInnerRadius) * _Resolution.x + 1.0; + float2 pixel = (_Resolution.xx - 1.0) * i.uv + 1.0; + + float vline = step(floor(fmod(pixel.x, _Resolution.y)), 0.0); + vline *= step(radius, pixel.y) * step(pixel.y, _Resolution.x - radius); + + float hline = step(floor(fmod(pixel.y, _Resolution.y)), 0.0); + hline *= step(radius, pixel.x) * step(pixel.x, _Resolution.x - radius); + + color += hline.xxxx * (1.0).xxxx; + color += vline.xxxx * (1.0).xxxx; + color = saturate(color); + color *= half4((crossColor).xxx, 0.05); + } + + // Hue + { + float alphaOut = smoothstep(kHueOuterRadius - delta, kHueOuterRadius + delta, dist); + float alphaIn = smoothstep(kHueInnerRadius - delta, kHueInnerRadius + delta, dist); + + float hue = angle; + hue = 1.0 - ((hue > 0.0) ? hue : PI2 + hue) / PI2; + float4 c = float4(HsvToRgb(float3(hue, 1.0, 1.0)), 1.0); + color += lerp((0.0).xxxx, c, alphaIn - alphaOut); + } + + // Offset + { + float alphaOut = smoothstep(kLumOuterRadius - delta, kLumOuterRadius + delta, dist); + float alphaIn = smoothstep(kLumInnerRadius - delta, kLumInnerRadius + delta / 2, dist); + float4 c = float4((offsetColor).xxx, 1.0); + + float a = PI * _Offset; + if (_Offset >= 0 && angle < a && angle > 0.0) + c = float4((1.0).xxx, 0.5); + else if (angle > a && angle < 0.0) + c = float4((1.0).xxx, 0.5); + + color += lerp((0.0).xxxx, c, alphaIn - alphaOut); + } + + return color * _DisabledState; + } + + float4 FragTrackballDark(v2f_img i) : SV_Target + { + return CreateWheel(i, 1.0, 0.15); + } + + float4 FragTrackballLight(v2f_img i) : SV_Target + { + return CreateWheel(i, 0.0, 0.3); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) Dark skin + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragTrackballDark + + ENDCG + } + + // (1) Light skin + Pass + { + CGPROGRAM + + #pragma vertex vert_img + #pragma fragment FragTrackballLight + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Editor Resources/UI/Trackball.shader.meta b/Assets/PostProcessing/Editor Resources/UI/Trackball.shader.meta new file mode 100644 index 0000000..09dcd75 --- /dev/null +++ b/Assets/PostProcessing/Editor Resources/UI/Trackball.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4bf49309c7ab9eb42a86774d2c09b4fa +timeCreated: 1460627788 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor.meta b/Assets/PostProcessing/Editor.meta new file mode 100644 index 0000000..11b8014 --- /dev/null +++ b/Assets/PostProcessing/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e0e418747b892364db5c5f4451e67ede +folderAsset: yes +timeCreated: 1466586258 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Attributes.meta b/Assets/PostProcessing/Editor/Attributes.meta new file mode 100644 index 0000000..ed3547a --- /dev/null +++ b/Assets/PostProcessing/Editor/Attributes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: cc5c690f549b4704eb992a9be781554d +folderAsset: yes +timeCreated: 1466769698 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs b/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs new file mode 100644 index 0000000..13e4819 --- /dev/null +++ b/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace UnityEditor.PostProcessing +{ + public class PostProcessingModelEditorAttribute : Attribute + { + public readonly Type type; + public readonly bool alwaysEnabled; + + public PostProcessingModelEditorAttribute(Type type, bool alwaysEnabled = false) + { + this.type = type; + this.alwaysEnabled = alwaysEnabled; + } + } +} diff --git a/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs.meta b/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs.meta new file mode 100644 index 0000000..4484ca1 --- /dev/null +++ b/Assets/PostProcessing/Editor/Attributes/PostProcessingModelEditorAttribute.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c21938aa988055347a2271f03a3e731e +timeCreated: 1466769734 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models.meta b/Assets/PostProcessing/Editor/Models.meta new file mode 100644 index 0000000..a00a2be --- /dev/null +++ b/Assets/PostProcessing/Editor/Models.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d5341d31985da604db4b100f174142ad +folderAsset: yes +timeCreated: 1466769808 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs b/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs new file mode 100644 index 0000000..fef389e --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs @@ -0,0 +1,42 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = AmbientOcclusionModel.Settings; + + [PostProcessingModelEditor(typeof(AmbientOcclusionModel))] + public class AmbientOcclusionModelEditor : PostProcessingModelEditor + { + SerializedProperty m_Intensity; + SerializedProperty m_Radius; + SerializedProperty m_SampleCount; + SerializedProperty m_Downsampling; + SerializedProperty m_ForceForwardCompatibility; + SerializedProperty m_AmbientOnly; + SerializedProperty m_HighPrecision; + + public override void OnEnable() + { + m_Intensity = FindSetting((Settings x) => x.intensity); + m_Radius = FindSetting((Settings x) => x.radius); + m_SampleCount = FindSetting((Settings x) => x.sampleCount); + m_Downsampling = FindSetting((Settings x) => x.downsampling); + m_ForceForwardCompatibility = FindSetting((Settings x) => x.forceForwardCompatibility); + m_AmbientOnly = FindSetting((Settings x) => x.ambientOnly); + m_HighPrecision = FindSetting((Settings x) => x.highPrecision); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.PropertyField(m_Intensity); + EditorGUILayout.PropertyField(m_Radius); + EditorGUILayout.PropertyField(m_SampleCount); + EditorGUILayout.PropertyField(m_Downsampling); + EditorGUILayout.PropertyField(m_ForceForwardCompatibility); + EditorGUILayout.PropertyField(m_HighPrecision, EditorGUIHelper.GetContent("High Precision (Forward)")); + + using (new EditorGUI.DisabledGroupScope(m_ForceForwardCompatibility.boolValue)) + EditorGUILayout.PropertyField(m_AmbientOnly, EditorGUIHelper.GetContent("Ambient Only (Deferred + HDR)")); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs.meta new file mode 100644 index 0000000..a78b9d5 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/AmbientOcclusionModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9fcb710e23a5a0546a3b8b0ca28c1720 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs b/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs new file mode 100644 index 0000000..6f773a5 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs @@ -0,0 +1,71 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Method = AntialiasingModel.Method; + using Settings = AntialiasingModel.Settings; + + [PostProcessingModelEditor(typeof(AntialiasingModel))] + public class AntialiasingModelEditor : PostProcessingModelEditor + { + SerializedProperty m_Method; + + SerializedProperty m_FxaaPreset; + + SerializedProperty m_TaaJitterSpread; + SerializedProperty m_TaaSharpen; + SerializedProperty m_TaaStationaryBlending; + SerializedProperty m_TaaMotionBlending; + + static string[] s_MethodNames = + { + "Fast Approximate Anti-aliasing", + "Temporal Anti-aliasing" + }; + + public override void OnEnable() + { + m_Method = FindSetting((Settings x) => x.method); + + m_FxaaPreset = FindSetting((Settings x) => x.fxaaSettings.preset); + + m_TaaJitterSpread = FindSetting((Settings x) => x.taaSettings.jitterSpread); + m_TaaSharpen = FindSetting((Settings x) => x.taaSettings.sharpen); + m_TaaStationaryBlending = FindSetting((Settings x) => x.taaSettings.stationaryBlending); + m_TaaMotionBlending = FindSetting((Settings x) => x.taaSettings.motionBlending); + } + + public override void OnInspectorGUI() + { + m_Method.intValue = EditorGUILayout.Popup("Method", m_Method.intValue, s_MethodNames); + + if (m_Method.intValue == (int)Method.Fxaa) + { + EditorGUILayout.PropertyField(m_FxaaPreset); + } + else if (m_Method.intValue == (int)Method.Taa) + { + if (QualitySettings.antiAliasing > 1) + EditorGUILayout.HelpBox("Temporal Anti-Aliasing doesn't work correctly when MSAA is enabled.", MessageType.Warning); + + EditorGUILayout.LabelField("Jitter", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_TaaJitterSpread, EditorGUIHelper.GetContent("Spread")); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Blending", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_TaaStationaryBlending, EditorGUIHelper.GetContent("Stationary")); + EditorGUILayout.PropertyField(m_TaaMotionBlending, EditorGUIHelper.GetContent("Motion")); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_TaaSharpen); + } + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs.meta new file mode 100644 index 0000000..a988444 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/AntialiasingModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2451939fe695c1a408ba688219837667 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs b/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs new file mode 100644 index 0000000..7359627 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs @@ -0,0 +1,204 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = BloomModel.Settings; + + [PostProcessingModelEditor(typeof(BloomModel))] + public class BloomModelEditor : PostProcessingModelEditor + { + struct BloomSettings + { + public SerializedProperty intensity; + public SerializedProperty threshold; + public SerializedProperty softKnee; + public SerializedProperty radius; + public SerializedProperty antiFlicker; + } + + struct LensDirtSettings + { + public SerializedProperty texture; + public SerializedProperty intensity; + } + + BloomSettings m_Bloom; + LensDirtSettings m_LensDirt; + + public override void OnEnable() + { + m_Bloom = new BloomSettings + { + intensity = FindSetting((Settings x) => x.bloom.intensity), + threshold = FindSetting((Settings x) => x.bloom.threshold), + softKnee = FindSetting((Settings x) => x.bloom.softKnee), + radius = FindSetting((Settings x) => x.bloom.radius), + antiFlicker = FindSetting((Settings x) => x.bloom.antiFlicker) + }; + + m_LensDirt = new LensDirtSettings + { + texture = FindSetting((Settings x) => x.lensDirt.texture), + intensity = FindSetting((Settings x) => x.lensDirt.intensity) + }; + } + + public override void OnInspectorGUI() + { + EditorGUILayout.Space(); + PrepareGraph(); + DrawGraph(); + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_Bloom.intensity); + EditorGUILayout.PropertyField(m_Bloom.threshold, EditorGUIHelper.GetContent("Threshold (Gamma)")); + EditorGUILayout.PropertyField(m_Bloom.softKnee); + EditorGUILayout.PropertyField(m_Bloom.radius); + EditorGUILayout.PropertyField(m_Bloom.antiFlicker); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Dirt", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_LensDirt.texture); + EditorGUILayout.PropertyField(m_LensDirt.intensity); + EditorGUI.indentLevel--; + } + + #region Graph + + float m_GraphThreshold; + float m_GraphKnee; + float m_GraphIntensity; + + // Number of vertices in curve + const int k_CurveResolution = 48; + + // Vertex buffers + Vector3[] m_RectVertices = new Vector3[4]; + Vector3[] m_LineVertices = new Vector3[2]; + Vector3[] m_CurveVertices = new Vector3[k_CurveResolution]; + + Rect m_RectGraph; + float m_RangeX; + float m_RangeY; + + float ResponseFunction(float x) + { + var rq = Mathf.Clamp(x - m_GraphThreshold + m_GraphKnee, 0, m_GraphKnee * 2); + rq = rq * rq * 0.25f / m_GraphKnee; + return Mathf.Max(rq, x - m_GraphThreshold) * m_GraphIntensity; + } + + // Transform a point into the graph rect + Vector3 PointInRect(float x, float y) + { + x = Mathf.Lerp(m_RectGraph.x, m_RectGraph.xMax, x / m_RangeX); + y = Mathf.Lerp(m_RectGraph.yMax, m_RectGraph.y, y / m_RangeY); + return new Vector3(x, y, 0); + } + + // Draw a line in the graph rect + void DrawLine(float x1, float y1, float x2, float y2, float grayscale) + { + m_LineVertices[0] = PointInRect(x1, y1); + m_LineVertices[1] = PointInRect(x2, y2); + Handles.color = Color.white * grayscale; + Handles.DrawAAPolyLine(2.0f, m_LineVertices); + } + + // Draw a rect in the graph rect + void DrawRect(float x1, float y1, float x2, float y2, float fill, float line) + { + m_RectVertices[0] = PointInRect(x1, y1); + m_RectVertices[1] = PointInRect(x2, y1); + m_RectVertices[2] = PointInRect(x2, y2); + m_RectVertices[3] = PointInRect(x1, y2); + + Handles.DrawSolidRectangleWithOutline( + m_RectVertices, + fill < 0 ? Color.clear : Color.white * fill, + line < 0 ? Color.clear : Color.white * line + ); + } + + // Update internal state with a given bloom instance + public void PrepareGraph() + { + var bloom = (BloomModel)target; + m_RangeX = 5f; + m_RangeY = 2f; + + m_GraphThreshold = bloom.settings.bloom.thresholdLinear; + m_GraphKnee = bloom.settings.bloom.softKnee * m_GraphThreshold + 1e-5f; + + // Intensity is capped to prevent sampling errors + m_GraphIntensity = Mathf.Min(bloom.settings.bloom.intensity, 10f); + } + + // Draw the graph at the current position + public void DrawGraph() + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.Space(EditorGUI.indentLevel * 15f); + m_RectGraph = GUILayoutUtility.GetRect(128, 80); + } + + // Background + DrawRect(0, 0, m_RangeX, m_RangeY, 0.1f, 0.4f); + + // Soft-knee range + DrawRect(m_GraphThreshold - m_GraphKnee, 0, m_GraphThreshold + m_GraphKnee, m_RangeY, 0.25f, -1); + + // Horizontal lines + for (var i = 1; i < m_RangeY; i++) + DrawLine(0, i, m_RangeX, i, 0.4f); + + // Vertical lines + for (var i = 1; i < m_RangeX; i++) + DrawLine(i, 0, i, m_RangeY, 0.4f); + + // Label + Handles.Label( + PointInRect(0, m_RangeY) + Vector3.right, + "Brightness Response (linear)", EditorStyles.miniLabel + ); + + // Threshold line + DrawLine(m_GraphThreshold, 0, m_GraphThreshold, m_RangeY, 0.6f); + + // Response curve + var vcount = 0; + while (vcount < k_CurveResolution) + { + var x = m_RangeX * vcount / (k_CurveResolution - 1); + var y = ResponseFunction(x); + if (y < m_RangeY) + { + m_CurveVertices[vcount++] = PointInRect(x, y); + } + else + { + if (vcount > 1) + { + // Extend the last segment to the top edge of the rect. + var v1 = m_CurveVertices[vcount - 2]; + var v2 = m_CurveVertices[vcount - 1]; + var clip = (m_RectGraph.y - v1.y) / (v2.y - v1.y); + m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip; + } + break; + } + } + + if (vcount > 1) + { + Handles.color = Color.white * 0.9f; + Handles.DrawAAPolyLine(2.0f, vcount, m_CurveVertices); + } + } + + #endregion + } +} diff --git a/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs.meta new file mode 100644 index 0000000..f4f31de --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/BloomModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a95f3f10e7e437c49ade656f531b30d2 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs b/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs new file mode 100644 index 0000000..eefc102 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs @@ -0,0 +1,106 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Mode = BuiltinDebugViewsModel.Mode; + using Settings = BuiltinDebugViewsModel.Settings; + + [PostProcessingModelEditor(typeof(BuiltinDebugViewsModel), alwaysEnabled: true)] + public class BuiltinDebugViewsEditor : PostProcessingModelEditor + { + struct DepthSettings + { + public SerializedProperty scale; + } + + struct MotionVectorsSettings + { + public SerializedProperty sourceOpacity; + public SerializedProperty motionImageOpacity; + public SerializedProperty motionImageAmplitude; + public SerializedProperty motionVectorsOpacity; + public SerializedProperty motionVectorsResolution; + public SerializedProperty motionVectorsAmplitude; + } + + SerializedProperty m_Mode; + DepthSettings m_Depth; + MotionVectorsSettings m_MotionVectors; + + public override void OnEnable() + { + m_Mode = FindSetting((Settings x) => x.mode); + + m_Depth = new DepthSettings + { + scale = FindSetting((Settings x) => x.depth.scale) + }; + + m_MotionVectors = new MotionVectorsSettings + { + sourceOpacity = FindSetting((Settings x) => x.motionVectors.sourceOpacity), + motionImageOpacity = FindSetting((Settings x) => x.motionVectors.motionImageOpacity), + motionImageAmplitude = FindSetting((Settings x) => x.motionVectors.motionImageAmplitude), + motionVectorsOpacity = FindSetting((Settings x) => x.motionVectors.motionVectorsOpacity), + motionVectorsResolution = FindSetting((Settings x) => x.motionVectors.motionVectorsResolution), + motionVectorsAmplitude = FindSetting((Settings x) => x.motionVectors.motionVectorsAmplitude), + }; + } + + public override void OnInspectorGUI() + { + EditorGUILayout.PropertyField(m_Mode); + + int mode = m_Mode.intValue; + + if (mode == (int)Mode.Depth) + { + EditorGUILayout.PropertyField(m_Depth.scale); + } + else if (mode == (int)Mode.MotionVectors) + { + EditorGUILayout.HelpBox("Switch to play mode to see motion vectors.", MessageType.Info); + + EditorGUILayout.LabelField("Source Image", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_MotionVectors.sourceOpacity, EditorGUIHelper.GetContent("Opacity")); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Motion Vectors (overlay)", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + + if (m_MotionVectors.motionImageOpacity.floatValue > 0f) + EditorGUILayout.HelpBox("Please keep opacity to 0 if you're subject to motion sickness.", MessageType.Warning); + + EditorGUILayout.PropertyField(m_MotionVectors.motionImageOpacity, EditorGUIHelper.GetContent("Opacity")); + EditorGUILayout.PropertyField(m_MotionVectors.motionImageAmplitude, EditorGUIHelper.GetContent("Amplitude")); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Motion Vectors (arrows)", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_MotionVectors.motionVectorsOpacity, EditorGUIHelper.GetContent("Opacity")); + EditorGUILayout.PropertyField(m_MotionVectors.motionVectorsResolution, EditorGUIHelper.GetContent("Resolution")); + EditorGUILayout.PropertyField(m_MotionVectors.motionVectorsAmplitude, EditorGUIHelper.GetContent("Amplitude")); + EditorGUI.indentLevel--; + } + else + { + CheckActiveEffect(mode == (int)Mode.AmbientOcclusion && !profile.ambientOcclusion.enabled, "Ambient Occlusion"); + CheckActiveEffect(mode == (int)Mode.FocusPlane && !profile.depthOfField.enabled, "Depth Of Field"); + CheckActiveEffect(mode == (int)Mode.EyeAdaptation && !profile.eyeAdaptation.enabled, "Eye Adaptation"); + CheckActiveEffect((mode == (int)Mode.LogLut || mode == (int)Mode.PreGradingLog) && !profile.colorGrading.enabled, "Color Grading"); + CheckActiveEffect(mode == (int)Mode.UserLut && !profile.userLut.enabled, "User Lut"); + } + } + + void CheckActiveEffect(bool expr, string name) + { + if (expr) + EditorGUILayout.HelpBox(string.Format("{0} isn't enabled, the debug view won't work.", name), MessageType.Warning); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs.meta b/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs.meta new file mode 100644 index 0000000..b961b65 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/BuiltinDebugViewsEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 760ffebbef2ed644c87940a699eb7fe6 +timeCreated: 1468237035 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs b/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs new file mode 100644 index 0000000..2337de0 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs @@ -0,0 +1,9 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [PostProcessingModelEditor(typeof(ChromaticAberrationModel))] + public class ChromaticaAberrationModelEditor : DefaultPostFxModelEditor + { + } +} diff --git a/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs.meta b/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs.meta new file mode 100644 index 0000000..8c65150 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ChromaticAberrationEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8a713f71a0169794a915a081f6242f60 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs b/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs new file mode 100644 index 0000000..8d73982 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs @@ -0,0 +1,672 @@ +using UnityEngine; +using UnityEngine.PostProcessing; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace UnityEditor.PostProcessing +{ + using Settings = ColorGradingModel.Settings; + using Tonemapper = ColorGradingModel.Tonemapper; + using ColorWheelMode = ColorGradingModel.ColorWheelMode; + + [PostProcessingModelEditor(typeof(ColorGradingModel))] + public class ColorGradingModelEditor : PostProcessingModelEditor + { + static GUIContent[] s_Tonemappers = + { + new GUIContent("None"), + new GUIContent("Filmic (ACES)"), + new GUIContent("Neutral") + }; + + struct TonemappingSettings + { + public SerializedProperty tonemapper; + public SerializedProperty neutralBlackIn; + public SerializedProperty neutralWhiteIn; + public SerializedProperty neutralBlackOut; + public SerializedProperty neutralWhiteOut; + public SerializedProperty neutralWhiteLevel; + public SerializedProperty neutralWhiteClip; + } + + struct BasicSettings + { + public SerializedProperty exposure; + public SerializedProperty temperature; + public SerializedProperty tint; + public SerializedProperty hueShift; + public SerializedProperty saturation; + public SerializedProperty contrast; + } + + struct ChannelMixerSettings + { + public SerializedProperty[] channels; + public SerializedProperty currentEditingChannel; + } + + struct ColorWheelsSettings + { + public SerializedProperty mode; + public SerializedProperty log; + public SerializedProperty linear; + } + + static GUIContent[] s_Curves = + { + new GUIContent("YRGB"), + new GUIContent("Hue VS Hue"), + new GUIContent("Hue VS Sat"), + new GUIContent("Sat VS Sat"), + new GUIContent("Lum VS Sat") + }; + + struct CurvesSettings + { + public SerializedProperty master; + public SerializedProperty red; + public SerializedProperty green; + public SerializedProperty blue; + + public SerializedProperty hueVShue; + public SerializedProperty hueVSsat; + public SerializedProperty satVSsat; + public SerializedProperty lumVSsat; + + public SerializedProperty currentEditingCurve; + public SerializedProperty curveY; + public SerializedProperty curveR; + public SerializedProperty curveG; + public SerializedProperty curveB; + } + + TonemappingSettings m_Tonemapping; + BasicSettings m_Basic; + ChannelMixerSettings m_ChannelMixer; + ColorWheelsSettings m_ColorWheels; + CurvesSettings m_Curves; + + CurveEditor m_CurveEditor; + Dictionary m_CurveDict; + + // Neutral tonemapping curve helper + const int k_CurveResolution = 24; + const float k_NeutralRangeX = 2f; + const float k_NeutralRangeY = 1f; + Vector3[] m_RectVertices = new Vector3[4]; + Vector3[] m_LineVertices = new Vector3[2]; + Vector3[] m_CurveVertices = new Vector3[k_CurveResolution]; + Rect m_NeutralCurveRect; + + public override void OnEnable() + { + // Tonemapping settings + m_Tonemapping = new TonemappingSettings + { + tonemapper = FindSetting((Settings x) => x.tonemapping.tonemapper), + neutralBlackIn = FindSetting((Settings x) => x.tonemapping.neutralBlackIn), + neutralWhiteIn = FindSetting((Settings x) => x.tonemapping.neutralWhiteIn), + neutralBlackOut = FindSetting((Settings x) => x.tonemapping.neutralBlackOut), + neutralWhiteOut = FindSetting((Settings x) => x.tonemapping.neutralWhiteOut), + neutralWhiteLevel = FindSetting((Settings x) => x.tonemapping.neutralWhiteLevel), + neutralWhiteClip = FindSetting((Settings x) => x.tonemapping.neutralWhiteClip) + }; + + // Basic settings + m_Basic = new BasicSettings + { + exposure = FindSetting((Settings x) => x.basic.postExposure), + temperature = FindSetting((Settings x) => x.basic.temperature), + tint = FindSetting((Settings x) => x.basic.tint), + hueShift = FindSetting((Settings x) => x.basic.hueShift), + saturation = FindSetting((Settings x) => x.basic.saturation), + contrast = FindSetting((Settings x) => x.basic.contrast) + }; + + // Channel mixer + m_ChannelMixer = new ChannelMixerSettings + { + channels = new[] + { + FindSetting((Settings x) => x.channelMixer.red), + FindSetting((Settings x) => x.channelMixer.green), + FindSetting((Settings x) => x.channelMixer.blue) + }, + currentEditingChannel = FindSetting((Settings x) => x.channelMixer.currentEditingChannel) + }; + + // Color wheels + m_ColorWheels = new ColorWheelsSettings + { + mode = FindSetting((Settings x) => x.colorWheels.mode), + log = FindSetting((Settings x) => x.colorWheels.log), + linear = FindSetting((Settings x) => x.colorWheels.linear) + }; + + // Curves + m_Curves = new CurvesSettings + { + master = FindSetting((Settings x) => x.curves.master.curve), + red = FindSetting((Settings x) => x.curves.red.curve), + green = FindSetting((Settings x) => x.curves.green.curve), + blue = FindSetting((Settings x) => x.curves.blue.curve), + + hueVShue = FindSetting((Settings x) => x.curves.hueVShue.curve), + hueVSsat = FindSetting((Settings x) => x.curves.hueVSsat.curve), + satVSsat = FindSetting((Settings x) => x.curves.satVSsat.curve), + lumVSsat = FindSetting((Settings x) => x.curves.lumVSsat.curve), + + currentEditingCurve = FindSetting((Settings x) => x.curves.e_CurrentEditingCurve), + curveY = FindSetting((Settings x) => x.curves.e_CurveY), + curveR = FindSetting((Settings x) => x.curves.e_CurveR), + curveG = FindSetting((Settings x) => x.curves.e_CurveG), + curveB = FindSetting((Settings x) => x.curves.e_CurveB) + }; + + // Prepare the curve editor and extract curve display settings + m_CurveDict = new Dictionary(); + + var settings = CurveEditor.Settings.defaultSettings; + + m_CurveEditor = new CurveEditor(settings); + AddCurve(m_Curves.master, new Color(1f, 1f, 1f), 2, false); + AddCurve(m_Curves.red, new Color(1f, 0f, 0f), 2, false); + AddCurve(m_Curves.green, new Color(0f, 1f, 0f), 2, false); + AddCurve(m_Curves.blue, new Color(0f, 0.5f, 1f), 2, false); + AddCurve(m_Curves.hueVShue, new Color(1f, 1f, 1f), 0, true); + AddCurve(m_Curves.hueVSsat, new Color(1f, 1f, 1f), 0, true); + AddCurve(m_Curves.satVSsat, new Color(1f, 1f, 1f), 0, false); + AddCurve(m_Curves.lumVSsat, new Color(1f, 1f, 1f), 0, false); + } + + void AddCurve(SerializedProperty prop, Color color, uint minPointCount, bool loop) + { + var state = CurveEditor.CurveState.defaultState; + state.color = color; + state.visible = false; + state.minPointCount = minPointCount; + state.onlyShowHandlesOnSelection = true; + state.zeroKeyConstantValue = 0.5f; + state.loopInBounds = loop; + m_CurveEditor.Add(prop, state); + m_CurveDict.Add(prop, color); + } + + public override void OnDisable() + { + m_CurveEditor.RemoveAll(); + } + + public override void OnInspectorGUI() + { + DoGUIFor("Tonemapping", DoTonemappingGUI); + EditorGUILayout.Space(); + DoGUIFor("Basic", DoBasicGUI); + EditorGUILayout.Space(); + DoGUIFor("Channel Mixer", DoChannelMixerGUI); + EditorGUILayout.Space(); + DoGUIFor("Trackballs", DoColorWheelsGUI); + EditorGUILayout.Space(); + DoGUIFor("Grading Curves", DoCurvesGUI); + } + + void DoGUIFor(string title, Action func) + { + EditorGUILayout.LabelField(title, EditorStyles.boldLabel); + EditorGUI.indentLevel++; + func(); + EditorGUI.indentLevel--; + } + + void DoTonemappingGUI() + { + int tid = EditorGUILayout.Popup(EditorGUIHelper.GetContent("Tonemapper"), m_Tonemapping.tonemapper.intValue, s_Tonemappers); + + if (tid == (int)Tonemapper.Neutral) + { + DrawNeutralTonemappingCurve(); + + EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackIn, EditorGUIHelper.GetContent("Black In")); + EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteIn, EditorGUIHelper.GetContent("White In")); + EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackOut, EditorGUIHelper.GetContent("Black Out")); + EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteOut, EditorGUIHelper.GetContent("White Out")); + EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteLevel, EditorGUIHelper.GetContent("White Level")); + EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteClip, EditorGUIHelper.GetContent("White Clip")); + } + + m_Tonemapping.tonemapper.intValue = tid; + } + + void DrawNeutralTonemappingCurve() + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.Space(EditorGUI.indentLevel * 15f); + m_NeutralCurveRect = GUILayoutUtility.GetRect(128, 80); + } + + // Background + m_RectVertices[0] = PointInRect( 0f, 0f); + m_RectVertices[1] = PointInRect(k_NeutralRangeX, 0f); + m_RectVertices[2] = PointInRect(k_NeutralRangeX, k_NeutralRangeY); + m_RectVertices[3] = PointInRect( 0f, k_NeutralRangeY); + + Handles.DrawSolidRectangleWithOutline( + m_RectVertices, + Color.white * 0.1f, + Color.white * 0.4f + ); + + // Horizontal lines + for (var i = 1; i < k_NeutralRangeY; i++) + DrawLine(0, i, k_NeutralRangeX, i, 0.4f); + + // Vertical lines + for (var i = 1; i < k_NeutralRangeX; i++) + DrawLine(i, 0, i, k_NeutralRangeY, 0.4f); + + // Label + Handles.Label( + PointInRect(0, k_NeutralRangeY) + Vector3.right, + "Neutral Tonemapper", EditorStyles.miniLabel + ); + + // Precompute some values + var tonemap = ((ColorGradingModel)target).settings.tonemapping; + + const float scaleFactor = 20f; + const float scaleFactorHalf = scaleFactor * 0.5f; + + float inBlack = tonemap.neutralBlackIn * scaleFactor + 1f; + float outBlack = tonemap.neutralBlackOut * scaleFactorHalf + 1f; + float inWhite = tonemap.neutralWhiteIn / scaleFactor; + float outWhite = 1f - tonemap.neutralWhiteOut / scaleFactor; + float blackRatio = inBlack / outBlack; + float whiteRatio = inWhite / outWhite; + + const float a = 0.2f; + float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio)); + float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio); + float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio)); + const float e = 0.02f; + const float f = 0.30f; + float whiteLevel = tonemap.neutralWhiteLevel; + float whiteClip = tonemap.neutralWhiteClip / scaleFactorHalf; + + // Tonemapping curve + var vcount = 0; + while (vcount < k_CurveResolution) + { + float x = k_NeutralRangeX * vcount / (k_CurveResolution - 1); + float y = NeutralTonemap(x, a, b, c, d, e, f, whiteLevel, whiteClip); + + if (y < k_NeutralRangeY) + { + m_CurveVertices[vcount++] = PointInRect(x, y); + } + else + { + if (vcount > 1) + { + // Extend the last segment to the top edge of the rect. + var v1 = m_CurveVertices[vcount - 2]; + var v2 = m_CurveVertices[vcount - 1]; + var clip = (m_NeutralCurveRect.y - v1.y) / (v2.y - v1.y); + m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip; + } + break; + } + } + + if (vcount > 1) + { + Handles.color = Color.white * 0.9f; + Handles.DrawAAPolyLine(2.0f, vcount, m_CurveVertices); + } + } + + void DrawLine(float x1, float y1, float x2, float y2, float grayscale) + { + m_LineVertices[0] = PointInRect(x1, y1); + m_LineVertices[1] = PointInRect(x2, y2); + Handles.color = Color.white * grayscale; + Handles.DrawAAPolyLine(2f, m_LineVertices); + } + + Vector3 PointInRect(float x, float y) + { + x = Mathf.Lerp(m_NeutralCurveRect.x, m_NeutralCurveRect.xMax, x / k_NeutralRangeX); + y = Mathf.Lerp(m_NeutralCurveRect.yMax, m_NeutralCurveRect.y, y / k_NeutralRangeY); + return new Vector3(x, y, 0); + } + + float NeutralCurve(float x, float a, float b, float c, float d, float e, float f) + { + return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f; + } + + float NeutralTonemap(float x, float a, float b, float c, float d, float e, float f, float whiteLevel, float whiteClip) + { + x = Mathf.Max(0f, x); + + // Tonemap + float whiteScale = 1f / NeutralCurve(whiteLevel, a, b, c, d, e, f); + x = NeutralCurve(x * whiteScale, a, b, c, d, e, f); + x *= whiteScale; + + // Post-curve white point adjustment + x /= whiteClip; + + return x; + } + + void DoBasicGUI() + { + EditorGUILayout.PropertyField(m_Basic.exposure, EditorGUIHelper.GetContent("Post Exposure (EV)")); + EditorGUILayout.PropertyField(m_Basic.temperature); + EditorGUILayout.PropertyField(m_Basic.tint); + EditorGUILayout.PropertyField(m_Basic.hueShift); + EditorGUILayout.PropertyField(m_Basic.saturation); + EditorGUILayout.PropertyField(m_Basic.contrast); + } + + void DoChannelMixerGUI() + { + int currentChannel = m_ChannelMixer.currentEditingChannel.intValue; + + EditorGUI.BeginChangeCheck(); + { + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.PrefixLabel("Channel"); + if (GUILayout.Toggle(currentChannel == 0, EditorGUIHelper.GetContent("Red|Red output channel."), EditorStyles.miniButtonLeft)) currentChannel = 0; + if (GUILayout.Toggle(currentChannel == 1, EditorGUIHelper.GetContent("Green|Green output channel."), EditorStyles.miniButtonMid)) currentChannel = 1; + if (GUILayout.Toggle(currentChannel == 2, EditorGUIHelper.GetContent("Blue|Blue output channel."), EditorStyles.miniButtonRight)) currentChannel = 2; + } + } + if (EditorGUI.EndChangeCheck()) + { + GUI.FocusControl(null); + } + + var serializedChannel = m_ChannelMixer.channels[currentChannel]; + m_ChannelMixer.currentEditingChannel.intValue = currentChannel; + + var v = serializedChannel.vector3Value; + v.x = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Red|Modify influence of the red channel within the overall mix."), v.x, -2f, 2f); + v.y = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Green|Modify influence of the green channel within the overall mix."), v.y, -2f, 2f); + v.z = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Blue|Modify influence of the blue channel within the overall mix."), v.z, -2f, 2f); + serializedChannel.vector3Value = v; + } + + void DoColorWheelsGUI() + { + int wheelMode = m_ColorWheels.mode.intValue; + + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.Space(15); + if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Linear, "Linear", EditorStyles.miniButtonLeft)) wheelMode = (int)ColorWheelMode.Linear; + if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Log, "Log", EditorStyles.miniButtonRight)) wheelMode = (int)ColorWheelMode.Log; + } + + m_ColorWheels.mode.intValue = wheelMode; + EditorGUILayout.Space(); + + if (wheelMode == (int)ColorWheelMode.Linear) + { + EditorGUILayout.PropertyField(m_ColorWheels.linear); + WheelSetTitle(GUILayoutUtility.GetLastRect(), "Linear Controls"); + } + else if (wheelMode == (int)ColorWheelMode.Log) + { + EditorGUILayout.PropertyField(m_ColorWheels.log); + WheelSetTitle(GUILayoutUtility.GetLastRect(), "Log Controls"); + } + } + + static void WheelSetTitle(Rect position, string label) + { + var matrix = GUI.matrix; + var rect = new Rect(position.x - 10f, position.y, TrackballGroupDrawer.m_Size, TrackballGroupDrawer.m_Size); + GUIUtility.RotateAroundPivot(-90f, rect.center); + GUI.Label(rect, label, FxStyles.centeredMiniLabel); + GUI.matrix = matrix; + } + + void ResetVisibleCurves() + { + foreach (var curve in m_CurveDict) + { + var state = m_CurveEditor.GetCurveState(curve.Key); + state.visible = false; + m_CurveEditor.SetCurveState(curve.Key, state); + } + } + + void SetCurveVisible(SerializedProperty prop) + { + var state = m_CurveEditor.GetCurveState(prop); + state.visible = true; + m_CurveEditor.SetCurveState(prop, state); + } + + bool SpecialToggle(bool value, string name, out bool rightClicked) + { + var rect = GUILayoutUtility.GetRect(EditorGUIHelper.GetContent(name), EditorStyles.toolbarButton); + + var e = Event.current; + rightClicked = (e.type == EventType.MouseUp && rect.Contains(e.mousePosition) && e.button == 1); + + return GUI.Toggle(rect, value, name, EditorStyles.toolbarButton); + } + + static Material s_MaterialSpline; + + void DoCurvesGUI() + { + EditorGUILayout.Space(); + EditorGUI.indentLevel -= 2; + ResetVisibleCurves(); + + using (new EditorGUI.DisabledGroupScope(serializedProperty.serializedObject.isEditingMultipleObjects)) + { + int curveEditingId = 0; + + // Top toolbar + using (new GUILayout.HorizontalScope(EditorStyles.toolbar)) + { + curveEditingId = EditorGUILayout.Popup(m_Curves.currentEditingCurve.intValue, s_Curves, EditorStyles.toolbarPopup, GUILayout.MaxWidth(150f)); + bool y = false, r = false, g = false, b = false; + + if (curveEditingId == 0) + { + EditorGUILayout.Space(); + + bool rightClickedY, rightClickedR, rightClickedG, rightClickedB; + + y = SpecialToggle(m_Curves.curveY.boolValue, "Y", out rightClickedY); + r = SpecialToggle(m_Curves.curveR.boolValue, "R", out rightClickedR); + g = SpecialToggle(m_Curves.curveG.boolValue, "G", out rightClickedG); + b = SpecialToggle(m_Curves.curveB.boolValue, "B", out rightClickedB); + + if (!y && !r && !g && !b) + { + r = g = b = false; + y = true; + } + + if (rightClickedY || rightClickedR || rightClickedG || rightClickedB) + { + y = rightClickedY; + r = rightClickedR; + g = rightClickedG; + b = rightClickedB; + } + + if (y) SetCurveVisible(m_Curves.master); + if (r) SetCurveVisible(m_Curves.red); + if (g) SetCurveVisible(m_Curves.green); + if (b) SetCurveVisible(m_Curves.blue); + + m_Curves.curveY.boolValue = y; + m_Curves.curveR.boolValue = r; + m_Curves.curveG.boolValue = g; + m_Curves.curveB.boolValue = b; + } + else + { + switch (curveEditingId) + { + case 1: SetCurveVisible(m_Curves.hueVShue); + break; + case 2: SetCurveVisible(m_Curves.hueVSsat); + break; + case 3: SetCurveVisible(m_Curves.satVSsat); + break; + case 4: SetCurveVisible(m_Curves.lumVSsat); + break; + } + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Reset", EditorStyles.toolbarButton)) + { + switch (curveEditingId) + { + case 0: + if (y) m_Curves.master.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); + if (r) m_Curves.red.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); + if (g) m_Curves.green.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); + if (b) m_Curves.blue.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); + break; + case 1: m_Curves.hueVShue.animationCurveValue = new AnimationCurve(); + break; + case 2: m_Curves.hueVSsat.animationCurveValue = new AnimationCurve(); + break; + case 3: m_Curves.satVSsat.animationCurveValue = new AnimationCurve(); + break; + case 4: m_Curves.lumVSsat.animationCurveValue = new AnimationCurve(); + break; + } + } + + m_Curves.currentEditingCurve.intValue = curveEditingId; + } + + // Curve area + var settings = m_CurveEditor.settings; + var rect = GUILayoutUtility.GetAspectRect(2f); + var innerRect = settings.padding.Remove(rect); + + if (Event.current.type == EventType.Repaint) + { + // Background + EditorGUI.DrawRect(rect, new Color(0.15f, 0.15f, 0.15f, 1f)); + + if (s_MaterialSpline == null) + s_MaterialSpline = new Material(Shader.Find("Hidden/Post FX/UI/Curve Background")) { hideFlags = HideFlags.HideAndDontSave }; + + if (curveEditingId == 1 || curveEditingId == 2) + DrawBackgroundTexture(innerRect, 0); + else if (curveEditingId == 3 || curveEditingId == 4) + DrawBackgroundTexture(innerRect, 1); + + // Bounds + Handles.color = Color.white; + Handles.DrawSolidRectangleWithOutline(innerRect, Color.clear, new Color(0.8f, 0.8f, 0.8f, 0.5f)); + + // Grid setup + Handles.color = new Color(1f, 1f, 1f, 0.05f); + int hLines = (int)Mathf.Sqrt(innerRect.width); + int vLines = (int)(hLines / (innerRect.width / innerRect.height)); + + // Vertical grid + int gridOffset = Mathf.FloorToInt(innerRect.width / hLines); + int gridPadding = ((int)(innerRect.width) % hLines) / 2; + + for (int i = 1; i < hLines; i++) + { + var offset = i * Vector2.right * gridOffset; + offset.x += gridPadding; + Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.x, innerRect.yMax - 1) + offset); + } + + // Horizontal grid + gridOffset = Mathf.FloorToInt(innerRect.height / vLines); + gridPadding = ((int)(innerRect.height) % vLines) / 2; + + for (int i = 1; i < vLines; i++) + { + var offset = i * Vector2.up * gridOffset; + offset.y += gridPadding; + Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.xMax - 1, innerRect.y) + offset); + } + } + + // Curve editor + if (m_CurveEditor.OnGUI(rect)) + { + Repaint(); + GUI.changed = true; + } + + if (Event.current.type == EventType.Repaint) + { + // Borders + Handles.color = Color.black; + Handles.DrawLine(new Vector2(rect.x, rect.y - 18f), new Vector2(rect.xMax, rect.y - 18f)); + Handles.DrawLine(new Vector2(rect.x, rect.y - 19f), new Vector2(rect.x, rect.yMax)); + Handles.DrawLine(new Vector2(rect.x, rect.yMax), new Vector2(rect.xMax, rect.yMax)); + Handles.DrawLine(new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax, rect.y - 18f)); + + // Selection info + var selection = m_CurveEditor.GetSelection(); + + if (selection.curve != null && selection.keyframeIndex > -1) + { + var key = selection.keyframe.Value; + var infoRect = innerRect; + infoRect.x += 5f; + infoRect.width = 100f; + infoRect.height = 30f; + GUI.Label(infoRect, string.Format("{0}\n{1}", key.time.ToString("F3"), key.value.ToString("F3")), FxStyles.preLabel); + } + } + } + + /* + EditorGUILayout.HelpBox( + @"Curve editor cheat sheet: +- [Del] or [Backspace] to remove a key +- [Ctrl] to break a tangent handle +- [Shift] to align tangent handles +- [Double click] to create a key on the curve(s) at mouse position +- [Alt] + [Double click] to create a key on the curve(s) at a given time", + MessageType.Info); + */ + + EditorGUILayout.Space(); + EditorGUI.indentLevel += 2; + } + + void DrawBackgroundTexture(Rect rect, int pass) + { + float scale = EditorGUIUtility.pixelsPerPoint; + + var oldRt = RenderTexture.active; + var rt = RenderTexture.GetTemporary(Mathf.CeilToInt(rect.width * scale), Mathf.CeilToInt(rect.height * scale), 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); + s_MaterialSpline.SetFloat("_DisabledState", GUI.enabled ? 1f : 0.5f); + s_MaterialSpline.SetFloat("_PixelScaling", EditorGUIUtility.pixelsPerPoint); + + Graphics.Blit(null, rt, s_MaterialSpline, pass); + RenderTexture.active = oldRt; + + GUI.DrawTexture(rect, rt); + RenderTexture.ReleaseTemporary(rt); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs.meta new file mode 100644 index 0000000..5449051 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ColorGradingModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c3e3bce1d5c900d4fa7aa0f2b21814cf +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs b/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs new file mode 100644 index 0000000..06c1c22 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace UnityEditor.PostProcessing +{ + public class DefaultPostFxModelEditor : PostProcessingModelEditor + { + List m_Properties = new List(); + + public override void OnEnable() + { + var iter = m_SettingsProperty.Copy().GetEnumerator(); + while (iter.MoveNext()) + m_Properties.Add(((SerializedProperty)iter.Current).Copy()); + } + + public override void OnInspectorGUI() + { + foreach (var property in m_Properties) + EditorGUILayout.PropertyField(property); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs.meta new file mode 100644 index 0000000..44902c6 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DefaultPostFxModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c15016a7fef58974f91a6a4d6b132d94 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs b/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs new file mode 100644 index 0000000..0f253fc --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs @@ -0,0 +1,37 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = DepthOfFieldModel.Settings; + + [PostProcessingModelEditor(typeof(DepthOfFieldModel))] + public class DepthOfFieldModelEditor : PostProcessingModelEditor + { + SerializedProperty m_FocusDistance; + SerializedProperty m_Aperture; + SerializedProperty m_FocalLength; + SerializedProperty m_UseCameraFov; + SerializedProperty m_KernelSize; + + public override void OnEnable() + { + m_FocusDistance = FindSetting((Settings x) => x.focusDistance); + m_Aperture = FindSetting((Settings x) => x.aperture); + m_FocalLength = FindSetting((Settings x) => x.focalLength); + m_UseCameraFov = FindSetting((Settings x) => x.useCameraFov); + m_KernelSize = FindSetting((Settings x) => x.kernelSize); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.PropertyField(m_FocusDistance); + EditorGUILayout.PropertyField(m_Aperture, EditorGUIHelper.GetContent("Aperture (f-stop)")); + + EditorGUILayout.PropertyField(m_UseCameraFov, EditorGUIHelper.GetContent("Use Camera FOV")); + if (!m_UseCameraFov.boolValue) + EditorGUILayout.PropertyField(m_FocalLength, EditorGUIHelper.GetContent("Focal Length (mm)")); + + EditorGUILayout.PropertyField(m_KernelSize); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs.meta new file mode 100644 index 0000000..2fd54fa --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DepthOfFieldModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dc2f388440e9f8b4f8fc7bb43c01cc7d +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs b/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs new file mode 100644 index 0000000..af4751f --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs @@ -0,0 +1,16 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [PostProcessingModelEditor(typeof(DitheringModel))] + public class DitheringModelEditor : PostProcessingModelEditor + { + public override void OnInspectorGUI() + { + if (profile.grain.enabled && target.enabled) + EditorGUILayout.HelpBox("Grain is enabled, you probably don't need dithering !", MessageType.Warning); + else + EditorGUILayout.HelpBox("Nothing to configure !", MessageType.Info); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs.meta new file mode 100644 index 0000000..f4beb49 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/DitheringModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 87377c86d84f49a4e912d37d28353e7f +timeCreated: 1485179854 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs b/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs new file mode 100644 index 0000000..94c49f2 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs @@ -0,0 +1,86 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = EyeAdaptationModel.Settings; + + [PostProcessingModelEditor(typeof(EyeAdaptationModel))] + public class EyeAdaptationModelEditor : PostProcessingModelEditor + { + SerializedProperty m_LowPercent; + SerializedProperty m_HighPercent; + SerializedProperty m_MinLuminance; + SerializedProperty m_MaxLuminance; + SerializedProperty m_KeyValue; + SerializedProperty m_DynamicKeyValue; + SerializedProperty m_AdaptationType; + SerializedProperty m_SpeedUp; + SerializedProperty m_SpeedDown; + SerializedProperty m_LogMin; + SerializedProperty m_LogMax; + + public override void OnEnable() + { + m_LowPercent = FindSetting((Settings x) => x.lowPercent); + m_HighPercent = FindSetting((Settings x) => x.highPercent); + m_MinLuminance = FindSetting((Settings x) => x.minLuminance); + m_MaxLuminance = FindSetting((Settings x) => x.maxLuminance); + m_KeyValue = FindSetting((Settings x) => x.keyValue); + m_DynamicKeyValue = FindSetting((Settings x) => x.dynamicKeyValue); + m_AdaptationType = FindSetting((Settings x) => x.adaptationType); + m_SpeedUp = FindSetting((Settings x) => x.speedUp); + m_SpeedDown = FindSetting((Settings x) => x.speedDown); + m_LogMin = FindSetting((Settings x) => x.logMin); + m_LogMax = FindSetting((Settings x) => x.logMax); + } + + public override void OnInspectorGUI() + { + if (!GraphicsUtils.supportsDX11) + EditorGUILayout.HelpBox("This effect requires support for compute shaders. Enabling it won't do anything on unsupported platforms.", MessageType.Warning); + + EditorGUILayout.LabelField("Luminosity range", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_LogMin, EditorGUIHelper.GetContent("Minimum (EV)")); + EditorGUILayout.PropertyField(m_LogMax, EditorGUIHelper.GetContent("Maximum (EV)")); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Auto exposure", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + float low = m_LowPercent.floatValue; + float high = m_HighPercent.floatValue; + + EditorGUILayout.MinMaxSlider(EditorGUIHelper.GetContent("Histogram filtering|These values are the lower and upper percentages of the histogram that will be used to find a stable average luminance. Values outside of this range will be discarded and won't contribute to the average luminance."), ref low, ref high, 1f, 99f); + + m_LowPercent.floatValue = low; + m_HighPercent.floatValue = high; + + EditorGUILayout.PropertyField(m_MinLuminance, EditorGUIHelper.GetContent("Minimum (EV)")); + EditorGUILayout.PropertyField(m_MaxLuminance, EditorGUIHelper.GetContent("Maximum (EV)")); + EditorGUILayout.PropertyField(m_DynamicKeyValue); + + if (!m_DynamicKeyValue.boolValue) + EditorGUILayout.PropertyField(m_KeyValue); + + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Adaptation", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(m_AdaptationType, EditorGUIHelper.GetContent("Type")); + + if (m_AdaptationType.intValue == (int)EyeAdaptationModel.EyeAdaptationType.Progressive) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_SpeedUp); + EditorGUILayout.PropertyField(m_SpeedDown); + EditorGUI.indentLevel--; + } + + EditorGUI.indentLevel--; + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs.meta new file mode 100644 index 0000000..8b78c92 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/EyeAdaptationModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 489b5c785ba0f614d90c322fa0827216 +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/FogModelEditor.cs b/Assets/PostProcessing/Editor/Models/FogModelEditor.cs new file mode 100644 index 0000000..b5b17c4 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/FogModelEditor.cs @@ -0,0 +1,24 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = FogModel.Settings; + + [PostProcessingModelEditor(typeof(FogModel))] + public class FogModelEditor : PostProcessingModelEditor + { + SerializedProperty m_ExcludeSkybox; + + public override void OnEnable() + { + m_ExcludeSkybox = FindSetting((Settings x) => x.excludeSkybox); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.HelpBox("This effect adds fog compatibility to the deferred rendering path; enabling it with the forward rendering path won't have any effect. Actual fog settings should be set in the Lighting panel.", MessageType.Info); + EditorGUILayout.PropertyField(m_ExcludeSkybox); + EditorGUI.indentLevel--; + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/FogModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/FogModelEditor.cs.meta new file mode 100644 index 0000000..cd8d2cd --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/FogModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 44a64b44ec891d24b96ed84d958c3d4f +timeCreated: 1487335049 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs b/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs new file mode 100644 index 0000000..9c7d169 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs @@ -0,0 +1,31 @@ +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = GrainModel.Settings; + + [PostProcessingModelEditor(typeof(GrainModel))] + public class GrainModelEditor : PostProcessingModelEditor + { + SerializedProperty m_Colored; + SerializedProperty m_Intensity; + SerializedProperty m_Size; + SerializedProperty m_LuminanceContribution; + + public override void OnEnable() + { + m_Colored = FindSetting((Settings x) => x.colored); + m_Intensity = FindSetting((Settings x) => x.intensity); + m_Size = FindSetting((Settings x) => x.size); + m_LuminanceContribution = FindSetting((Settings x) => x.luminanceContribution); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.PropertyField(m_Intensity); + EditorGUILayout.PropertyField(m_LuminanceContribution); + EditorGUILayout.PropertyField(m_Size); + EditorGUILayout.PropertyField(m_Colored); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs.meta new file mode 100644 index 0000000..0fe7d1b --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/GrainModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8330694e2c90c284f81153ac83b3cb4a +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs b/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs new file mode 100644 index 0000000..dac86e7 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs @@ -0,0 +1,197 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = MotionBlurModel.Settings; + + [PostProcessingModelEditor(typeof(MotionBlurModel))] + public class MotionBlurModelEditor : PostProcessingModelEditor + { + SerializedProperty m_ShutterAngle; + SerializedProperty m_SampleCount; + SerializedProperty m_FrameBlending; + + GraphDrawer m_GraphDrawer; + + class GraphDrawer + { + const float k_Height = 32f; + + Texture m_BlendingIcon; + + GUIStyle m_LowerCenterStyle; + GUIStyle m_MiddleCenterStyle; + + Color m_ColorDark; + Color m_ColorGray; + + Vector3[] m_RectVertices = new Vector3[4]; + + public GraphDrawer() + { + m_BlendingIcon = EditorResources.Load("UI/MotionBlendingIcon.png"); + + m_LowerCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.LowerCenter }; + m_MiddleCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.MiddleCenter }; + + if (EditorGUIUtility.isProSkin) + { + m_ColorDark = new Color(0.18f, 0.18f, 0.18f); + m_ColorGray = new Color(0.43f, 0.43f, 0.43f); + } + else + { + m_ColorDark = new Color(0.64f, 0.64f, 0.64f); + m_ColorGray = new Color(0.92f, 0.92f, 0.92f); + } + } + + public void DrawShutterGraph(float angle) + { + var center = GUILayoutUtility.GetRect(128, k_Height).center; + + // Parameters used to make transitions smooth. + var zeroWhenOff = Mathf.Min(1f, angle * 0.1f); + var zeroWhenFull = Mathf.Min(1f, (360f - angle) * 0.02f); + + // Shutter angle graph + var discCenter = center - new Vector2(k_Height * 2.4f, 0f); + // - exposure duration indicator + DrawDisc(discCenter, k_Height * Mathf.Lerp(0.5f, 0.38f, zeroWhenFull), m_ColorGray); + // - shutter disc + DrawDisc(discCenter, k_Height * 0.16f * zeroWhenFull, m_ColorDark); + // - shutter blade + DrawArc(discCenter, k_Height * 0.5f, 360f - angle, m_ColorDark); + // - shutter axis + DrawDisc(discCenter, zeroWhenOff, m_ColorGray); + + // Shutter label (off/full) + var labelSize = new Vector2(k_Height, k_Height); + var labelOrigin = discCenter - labelSize * 0.5f; + var labelRect = new Rect(labelOrigin, labelSize); + + if (Mathf.Approximately(angle, 0f)) + GUI.Label(labelRect, "Off", m_MiddleCenterStyle); + else if (Mathf.Approximately(angle, 360f)) + GUI.Label(labelRect, "Full", m_MiddleCenterStyle); + + // Exposure time bar graph + var outerBarSize = new Vector2(4.75f, 0.5f) * k_Height; + var innerBarSize = outerBarSize; + innerBarSize.x *= angle / 360f; + + var barCenter = center + new Vector2(k_Height * 0.9f, 0f); + var barOrigin = barCenter - outerBarSize * 0.5f; + + DrawRect(barOrigin, outerBarSize, m_ColorDark); + DrawRect(barOrigin, innerBarSize, m_ColorGray); + + var barText = "Exposure time = " + (angle / 3.6f).ToString("0") + "% of ΔT"; + GUI.Label(new Rect(barOrigin, outerBarSize), barText, m_MiddleCenterStyle); + } + + public void DrawBlendingGraph(float strength) + { + var center = GUILayoutUtility.GetRect(128, k_Height).center; + + var iconSize = new Vector2(k_Height, k_Height); + var iconStride = new Vector2(k_Height * 0.9f, 0f); + var iconOrigin = center - iconSize * 0.5f - iconStride * 2f; + + for (var i = 0; i < 5; i++) + { + var weight = BlendingWeight(strength, i / 60f); + var rect = new Rect(iconOrigin + iconStride * i, iconSize); + + var color = m_ColorGray; + color.a = weight; + + GUI.color = color; + GUI.Label(rect, m_BlendingIcon); + + GUI.color = Color.white; + GUI.Label(rect, (weight * 100).ToString("0") + "%", m_LowerCenterStyle); + } + // EditorGUIUtility.isProSkin + } + + // Weight function for multi frame blending + float BlendingWeight(float strength, float time) + { + if (strength > 0f || Mathf.Approximately(time, 0f)) + return Mathf.Exp(-time * Mathf.Lerp(80f, 10f, strength)); + + return 0; + } + + // Draw a solid disc in the graph rect. + void DrawDisc(Vector2 center, float radius, Color fill) + { + Handles.color = fill; + Handles.DrawSolidDisc(center, Vector3.forward, radius); + } + + // Draw an arc in the graph rect. + void DrawArc(Vector2 center, float radius, float angle, Color fill) + { + var start = new Vector2( + -Mathf.Cos(Mathf.Deg2Rad * angle / 2f), + Mathf.Sin(Mathf.Deg2Rad * angle / 2f) + ); + + Handles.color = fill; + Handles.DrawSolidArc(center, Vector3.forward, start, angle, radius); + } + + // Draw a rectangle in the graph rect. + void DrawRect(Vector2 origin, Vector2 size, Color color) + { + var p0 = origin; + var p1 = origin + size; + + m_RectVertices[0] = p0; + m_RectVertices[1] = new Vector2(p1.x, p0.y); + m_RectVertices[2] = p1; + m_RectVertices[3] = new Vector2(p0.x, p1.y); + + Handles.color = Color.white; + Handles.DrawSolidRectangleWithOutline(m_RectVertices, color, Color.clear); + } + } + + public override void OnEnable() + { + m_ShutterAngle = FindSetting((Settings x) => x.shutterAngle); + m_SampleCount = FindSetting((Settings x) => x.sampleCount); + m_FrameBlending = FindSetting((Settings x) => x.frameBlending); + } + + public override void OnInspectorGUI() + { + if (m_GraphDrawer == null) + m_GraphDrawer = new GraphDrawer(); + + EditorGUILayout.LabelField("Shutter Speed Simulation", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + m_GraphDrawer.DrawShutterGraph(m_ShutterAngle.floatValue); + EditorGUILayout.PropertyField(m_ShutterAngle); + EditorGUILayout.PropertyField(m_SampleCount); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Multiple Frame Blending", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + + float fbValue = m_FrameBlending.floatValue; + m_GraphDrawer.DrawBlendingGraph(fbValue); + EditorGUILayout.PropertyField(m_FrameBlending); + + if (fbValue > 0f) + EditorGUILayout.HelpBox("Multi-Frame Blending lowers precision of the final picture for optimization purposes.", MessageType.Info); + + + EditorGUI.indentLevel--; + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs.meta new file mode 100644 index 0000000..e1d3fb3 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/MotionBlurModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 870806eda355b5144879155e2ba37eb6 +timeCreated: 1468325681 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs b/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs new file mode 100644 index 0000000..8904c7e --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs @@ -0,0 +1,100 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = ScreenSpaceReflectionModel.Settings; + + [PostProcessingModelEditor(typeof(ScreenSpaceReflectionModel))] + public class ScreenSpaceReflectionModelEditor : PostProcessingModelEditor + { + struct IntensitySettings + { + public SerializedProperty reflectionMultiplier; + public SerializedProperty fadeDistance; + public SerializedProperty fresnelFade; + public SerializedProperty fresnelFadePower; + } + + struct ReflectionSettings + { + public SerializedProperty blendType; + public SerializedProperty reflectionQuality; + public SerializedProperty maxDistance; + public SerializedProperty iterationCount; + public SerializedProperty stepSize; + public SerializedProperty widthModifier; + public SerializedProperty reflectionBlur; + public SerializedProperty reflectBackfaces; + } + + struct ScreenEdgeMask + { + public SerializedProperty intensity; + } + + IntensitySettings m_Intensity; + ReflectionSettings m_Reflection; + ScreenEdgeMask m_ScreenEdgeMask; + + public override void OnEnable() + { + m_Intensity = new IntensitySettings + { + reflectionMultiplier = FindSetting((Settings x) => x.intensity.reflectionMultiplier), + fadeDistance = FindSetting((Settings x) => x.intensity.fadeDistance), + fresnelFade = FindSetting((Settings x) => x.intensity.fresnelFade), + fresnelFadePower = FindSetting((Settings x) => x.intensity.fresnelFadePower) + }; + + m_Reflection = new ReflectionSettings + { + blendType = FindSetting((Settings x) => x.reflection.blendType), + reflectionQuality = FindSetting((Settings x) => x.reflection.reflectionQuality), + maxDistance = FindSetting((Settings x) => x.reflection.maxDistance), + iterationCount = FindSetting((Settings x) => x.reflection.iterationCount), + stepSize = FindSetting((Settings x) => x.reflection.stepSize), + widthModifier = FindSetting((Settings x) => x.reflection.widthModifier), + reflectionBlur = FindSetting((Settings x) => x.reflection.reflectionBlur), + reflectBackfaces = FindSetting((Settings x) => x.reflection.reflectBackfaces) + }; + + m_ScreenEdgeMask = new ScreenEdgeMask + { + intensity = FindSetting((Settings x) => x.screenEdgeMask.intensity) + }; + } + + public override void OnInspectorGUI() + { + EditorGUILayout.HelpBox("This effect only works with the deferred rendering path.", MessageType.Info); + + EditorGUILayout.LabelField("Reflection", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_Reflection.blendType); + EditorGUILayout.PropertyField(m_Reflection.reflectionQuality); + EditorGUILayout.PropertyField(m_Reflection.maxDistance); + EditorGUILayout.PropertyField(m_Reflection.iterationCount); + EditorGUILayout.PropertyField(m_Reflection.stepSize); + EditorGUILayout.PropertyField(m_Reflection.widthModifier); + EditorGUILayout.PropertyField(m_Reflection.reflectionBlur); + EditorGUILayout.PropertyField(m_Reflection.reflectBackfaces); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Intensity", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_Intensity.reflectionMultiplier); + EditorGUILayout.PropertyField(m_Intensity.fadeDistance); + EditorGUILayout.PropertyField(m_Intensity.fresnelFade); + EditorGUILayout.PropertyField(m_Intensity.fresnelFadePower); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Screen Edge Mask", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_ScreenEdgeMask.intensity); + EditorGUI.indentLevel--; + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs.meta new file mode 100644 index 0000000..a291c26 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/ScreenSpaceReflectionModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57bbe1f20eec7bb4d9bc90fc65ef381b +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs b/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs new file mode 100644 index 0000000..39c96ba --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs @@ -0,0 +1,87 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using Settings = UserLutModel.Settings; + + [PostProcessingModelEditor(typeof(UserLutModel))] + public class UserLutModelEditor : PostProcessingModelEditor + { + SerializedProperty m_Texture; + SerializedProperty m_Contribution; + + public override void OnEnable() + { + m_Texture = FindSetting((Settings x) => x.lut); + m_Contribution = FindSetting((Settings x) => x.contribution); + } + + public override void OnInspectorGUI() + { + var lut = (target as UserLutModel).settings.lut; + + // Checks import settings on the lut, offers to fix them if invalid + if (lut != null) + { + var importer = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(lut)); + + if (importer != null) // Fails when using an internal texture + { +#if UNITY_5_5_OR_NEWER + bool valid = importer.anisoLevel == 0 + && importer.mipmapEnabled == false + && importer.sRGBTexture == false + && (importer.textureCompression == TextureImporterCompression.Uncompressed); +#else + bool valid = importer.anisoLevel == 0 + && importer.mipmapEnabled == false + && importer.linearTexture == true + && (importer.textureFormat == TextureImporterFormat.RGB24 || importer.textureFormat == TextureImporterFormat.AutomaticTruecolor); +#endif + + if (!valid) + { + EditorGUILayout.HelpBox("Invalid LUT import settings.", MessageType.Warning); + + GUILayout.Space(-32); + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Fix", GUILayout.Width(60))) + { + SetLUTImportSettings(importer); + AssetDatabase.Refresh(); + } + GUILayout.Space(8); + } + GUILayout.Space(11); + } + } + else + { + m_Texture.objectReferenceValue = null; + } + } + + EditorGUILayout.PropertyField(m_Texture); + EditorGUILayout.PropertyField(m_Contribution); + } + + void SetLUTImportSettings(TextureImporter importer) + { +#if UNITY_5_5_OR_NEWER + importer.textureType = TextureImporterType.Default; + importer.sRGBTexture = false; + importer.textureCompression = TextureImporterCompression.Uncompressed; +#else + importer.textureType = TextureImporterType.Advanced; + importer.linearTexture = true; + importer.textureFormat = TextureImporterFormat.RGB24; +#endif + importer.anisoLevel = 0; + importer.mipmapEnabled = false; + importer.SaveAndReimport(); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs.meta new file mode 100644 index 0000000..d6355a1 --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/UserLutModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b235eb1c486b38c4fa06470234bbfd32 +timeCreated: 1466769818 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs b/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs new file mode 100644 index 0000000..a9e231f --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs @@ -0,0 +1,118 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using VignetteMode = VignetteModel.Mode; + using Settings = VignetteModel.Settings; + + [PostProcessingModelEditor(typeof(VignetteModel))] + public class VignetteModelEditor : PostProcessingModelEditor + { + SerializedProperty m_Mode; + SerializedProperty m_Color; + SerializedProperty m_Center; + SerializedProperty m_Intensity; + SerializedProperty m_Smoothness; + SerializedProperty m_Roundness; + SerializedProperty m_Mask; + SerializedProperty m_Opacity; + SerializedProperty m_Rounded; + + public override void OnEnable() + { + m_Mode = FindSetting((Settings x) => x.mode); + m_Color = FindSetting((Settings x) => x.color); + m_Center = FindSetting((Settings x) => x.center); + m_Intensity = FindSetting((Settings x) => x.intensity); + m_Smoothness = FindSetting((Settings x) => x.smoothness); + m_Roundness = FindSetting((Settings x) => x.roundness); + m_Mask = FindSetting((Settings x) => x.mask); + m_Opacity = FindSetting((Settings x) => x.opacity); + m_Rounded = FindSetting((Settings x) => x.rounded); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.PropertyField(m_Mode); + EditorGUILayout.PropertyField(m_Color); + + if (m_Mode.intValue < (int)VignetteMode.Masked) + { + EditorGUILayout.PropertyField(m_Center); + EditorGUILayout.PropertyField(m_Intensity); + EditorGUILayout.PropertyField(m_Smoothness); + EditorGUILayout.PropertyField(m_Roundness); + EditorGUILayout.PropertyField(m_Rounded); + } + else + { + var mask = (target as VignetteModel).settings.mask; + + // Checks import settings on the mask, offers to fix them if invalid + if (mask != null) + { + var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(mask)) as TextureImporter; + + if (importer != null) // Fails when using an internal texture + { +#if UNITY_5_5_OR_NEWER + bool valid = importer.anisoLevel == 0 + && importer.mipmapEnabled == false + //&& importer.alphaUsage == TextureImporterAlphaUsage.FromGrayScale + && importer.alphaSource == TextureImporterAlphaSource.FromGrayScale + && importer.textureCompression == TextureImporterCompression.Uncompressed + && importer.wrapMode == TextureWrapMode.Clamp; +#else + bool valid = importer.anisoLevel == 0 + && importer.mipmapEnabled == false + && importer.grayscaleToAlpha == true + && importer.textureFormat == TextureImporterFormat.Alpha8 + && importer.wrapMode == TextureWrapMode.Clamp; +#endif + + if (!valid) + { + EditorGUILayout.HelpBox("Invalid mask import settings.", MessageType.Warning); + + GUILayout.Space(-32); + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Fix", GUILayout.Width(60))) + { + SetMaskImportSettings(importer); + AssetDatabase.Refresh(); + } + GUILayout.Space(8); + } + GUILayout.Space(11); + } + } + } + + EditorGUILayout.PropertyField(m_Mask); + EditorGUILayout.PropertyField(m_Opacity); + } + } + + void SetMaskImportSettings(TextureImporter importer) + { +#if UNITY_5_5_OR_NEWER + importer.textureType = TextureImporterType.SingleChannel; + //importer.alphaUsage = TextureImporterAlphaUsage.FromGrayScale; + importer.alphaSource = TextureImporterAlphaSource.FromGrayScale; + importer.textureCompression = TextureImporterCompression.Uncompressed; +#else + importer.textureType = TextureImporterType.Advanced; + importer.grayscaleToAlpha = true; + importer.textureFormat = TextureImporterFormat.Alpha8; +#endif + + importer.anisoLevel = 0; + importer.mipmapEnabled = false; + importer.wrapMode = TextureWrapMode.Clamp; + importer.SaveAndReimport(); + } + } +} diff --git a/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs.meta b/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs.meta new file mode 100644 index 0000000..40c13ca --- /dev/null +++ b/Assets/PostProcessing/Editor/Models/VignetteModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 745ad42620dabf04b94761acc86189ba +timeCreated: 1467190133 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Monitors.meta b/Assets/PostProcessing/Editor/Monitors.meta new file mode 100644 index 0000000..a142631 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e31078d57ac582944ad5e1e76a84f36a +folderAsset: yes +timeCreated: 1467188891 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs b/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs new file mode 100644 index 0000000..3748a68 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs @@ -0,0 +1,338 @@ +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + using HistogramMode = PostProcessingProfile.MonitorSettings.HistogramMode; + + public class HistogramMonitor : PostProcessingMonitor + { + static GUIContent s_MonitorTitle = new GUIContent("Histogram"); + + ComputeShader m_ComputeShader; + ComputeBuffer m_Buffer; + Material m_Material; + RenderTexture m_HistogramTexture; + Rect m_MonitorAreaRect; + + public HistogramMonitor() + { + m_ComputeShader = EditorResources.Load("Monitors/HistogramCompute.compute"); + } + + public override void Dispose() + { + GraphicsUtils.Destroy(m_Material); + GraphicsUtils.Destroy(m_HistogramTexture); + + if (m_Buffer != null) + m_Buffer.Release(); + + m_Material = null; + m_HistogramTexture = null; + m_Buffer = null; + } + + public override bool IsSupported() + { + return m_ComputeShader != null && GraphicsUtils.supportsDX11; + } + + public override GUIContent GetMonitorTitle() + { + return s_MonitorTitle; + } + + public override void OnMonitorSettings() + { + EditorGUI.BeginChangeCheck(); + + bool refreshOnPlay = m_MonitorSettings.refreshOnPlay; + var mode = m_MonitorSettings.histogramMode; + + refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the histogram in play mode; this may impact performances."), FxStyles.preButton); + mode = (HistogramMode)EditorGUILayout.EnumPopup(mode, FxStyles.preDropdown, GUILayout.MaxWidth(100f)); + + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Histogram Settings Changed"); + m_MonitorSettings.refreshOnPlay = refreshOnPlay; + m_MonitorSettings.histogramMode = mode; + InternalEditorUtility.RepaintAllViews(); + } + } + + public override void OnMonitorGUI(Rect r) + { + if (Event.current.type == EventType.Repaint) + { + // If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the histogram data + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0)) + InternalEditorUtility.RepaintAllViews(); + + // Sizing + float width = m_HistogramTexture != null + ? Mathf.Min(m_HistogramTexture.width, r.width - 65f) + : r.width; + float height = m_HistogramTexture != null + ? Mathf.Min(m_HistogramTexture.height, r.height - 45f) + : r.height; + + m_MonitorAreaRect = new Rect( + Mathf.Floor(r.x + r.width / 2f - width / 2f), + Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f), + width, height + ); + + if (m_HistogramTexture != null) + { + Graphics.DrawTexture(m_MonitorAreaRect, m_HistogramTexture); + + var color = Color.white; + const float kTickSize = 5f; + + // Rect, lines & ticks points + if (m_MonitorSettings.histogramMode == HistogramMode.RGBSplit) + { + // A B C D E + // N F + // M G + // L K J I H + + var A = new Vector3(m_MonitorAreaRect.x - 1f, m_MonitorAreaRect.y - 1f); + var E = new Vector3(A.x + m_MonitorAreaRect.width + 2f, m_MonitorAreaRect.y - 1f); + var H = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 2f); + var L = new Vector3(A.x, H.y); + + var N = new Vector3(A.x, A.y + (L.y - A.y) / 3f); + var M = new Vector3(A.x, A.y + (L.y - A.y) * 2f / 3f); + var F = new Vector3(E.x, E.y + (H.y - E.y) / 3f); + var G = new Vector3(E.x, E.y + (H.y - E.y) * 2f / 3f); + + var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y); + var J = new Vector3(L.x + (H.x - L.x) / 2f, L.y); + + var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y); + var D = new Vector3(C.x + (E.x - C.x) / 2f, C.y); + var I = new Vector3(J.x + (H.x - J.x) / 2f, J.y); + var K = new Vector3(L.x + (J.x - L.x) / 2f, L.y); + + // Borders + Handles.color = color; + Handles.DrawLine(A, E); + Handles.DrawLine(E, H); + Handles.DrawLine(H, L); + Handles.DrawLine(L, new Vector3(A.x, A.y - 1f)); + + // Vertical ticks + Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y)); + Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y)); + Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y)); + Handles.DrawLine(L, new Vector3(L.x - kTickSize, L.y)); + + Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y)); + Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y)); + Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y)); + Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y)); + + // Horizontal ticks + Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize)); + Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize)); + Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize)); + Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize)); + Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize)); + + Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize)); + Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize)); + Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize)); + Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize)); + Handles.DrawLine(H, new Vector3(H.x, H.y + kTickSize)); + + // Separators + Handles.DrawLine(N, F); + Handles.DrawLine(M, G); + + // Labels + GUI.color = color; + GUI.Label(new Rect(L.x - 15f, L.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter); + GUI.Label(new Rect(J.x - 15f, J.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter); + GUI.Label(new Rect(H.x - 15f, H.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter); + } + else + { + // A B C D E + // P F + // O G + // N H + // M L K J I + + var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y); + var E = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y); + var I = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 1f); + var M = new Vector3(A.x, I.y); + + var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y); + var G = new Vector3(E.x, E.y + (I.y - E.y) / 2f); + var K = new Vector3(M.x + (I.x - M.x) / 2f, M.y); + var O = new Vector3(A.x, A.y + (M.y - A.y) / 2f); + + var P = new Vector3(A.x, A.y + (O.y - A.y) / 2f); + var F = new Vector3(E.x, E.y + (G.y - E.y) / 2f); + var N = new Vector3(A.x, O.y + (M.y - O.y) / 2f); + var H = new Vector3(E.x, G.y + (I.y - G.y) / 2f); + + var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y); + var L = new Vector3(M.x + (K.x - M.x) / 2f, M.y); + var D = new Vector3(C.x + (E.x - C.x) / 2f, A.y); + var J = new Vector3(K.x + (I.x - K.x) / 2f, M.y); + + // Borders + Handles.color = color; + Handles.DrawLine(A, E); + Handles.DrawLine(E, I); + Handles.DrawLine(I, M); + Handles.DrawLine(M, new Vector3(A.x, A.y - 1f)); + + // Vertical ticks + Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y)); + Handles.DrawLine(P, new Vector3(P.x - kTickSize, P.y)); + Handles.DrawLine(O, new Vector3(O.x - kTickSize, O.y)); + Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y)); + Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y)); + + Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y)); + Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y)); + Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y)); + Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y)); + Handles.DrawLine(I, new Vector3(I.x + kTickSize, I.y)); + + // Horizontal ticks + Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize)); + Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize)); + Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize)); + Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize)); + Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize)); + + Handles.DrawLine(M, new Vector3(M.x, M.y + kTickSize)); + Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize)); + Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize)); + Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize)); + Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize)); + + // Labels + GUI.color = color; + GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight); + GUI.Label(new Rect(O.x - kTickSize - 34f, O.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight); + GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight); + + GUI.Label(new Rect(E.x + kTickSize + 4f, E.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft); + GUI.Label(new Rect(G.x + kTickSize + 4f, G.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft); + GUI.Label(new Rect(I.x + kTickSize + 4f, I.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft); + + GUI.Label(new Rect(M.x - 15f, M.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter); + GUI.Label(new Rect(K.x - 15f, K.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter); + GUI.Label(new Rect(I.x - 15f, I.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter); + } + } + } + } + + public override void OnFrameData(RenderTexture source) + { + if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay) + return; + + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0)) + return; + + float ratio = (float)source.width / (float)source.height; + int h = 512; + int w = Mathf.FloorToInt(h * ratio); + + var rt = RenderTexture.GetTemporary(w, h, 0, source.format); + Graphics.Blit(source, rt); + ComputeHistogram(rt); + m_BaseEditor.Repaint(); + RenderTexture.ReleaseTemporary(rt); + } + + void CreateBuffer(int width, int height) + { + m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2); + } + + void ComputeHistogram(RenderTexture source) + { + if (m_Buffer == null) + { + CreateBuffer(256, 1); + } + else if (m_Buffer.count != 256) + { + m_Buffer.Release(); + CreateBuffer(256, 1); + } + + if (m_Material == null) + { + m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Histogram Render")) { hideFlags = HideFlags.DontSave }; + } + + var channels = Vector4.zero; + switch (m_MonitorSettings.histogramMode) + { + case HistogramMode.Red: channels.x = 1f; break; + case HistogramMode.Green: channels.y = 1f; break; + case HistogramMode.Blue: channels.z = 1f; break; + case HistogramMode.Luminance: channels.w = 1f; break; + default: channels = new Vector4(1f, 1f, 1f, 0f); break; + } + + var cs = m_ComputeShader; + + int kernel = cs.FindKernel("KHistogramClear"); + cs.SetBuffer(kernel, "_Histogram", m_Buffer); + cs.Dispatch(kernel, 1, 1, 1); + + kernel = cs.FindKernel("KHistogramGather"); + cs.SetBuffer(kernel, "_Histogram", m_Buffer); + cs.SetTexture(kernel, "_Source", source); + cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0); + cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f)); + cs.SetVector("_Channels", channels); + cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 16f), Mathf.CeilToInt(source.height / 16f), 1); + + kernel = cs.FindKernel("KHistogramScale"); + cs.SetBuffer(kernel, "_Histogram", m_Buffer); + cs.Dispatch(kernel, 1, 1, 1); + + if (m_HistogramTexture == null || m_HistogramTexture.width != source.width || m_HistogramTexture.height != source.height) + { + GraphicsUtils.Destroy(m_HistogramTexture); + m_HistogramTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.DontSave, + wrapMode = TextureWrapMode.Clamp, + filterMode = FilterMode.Bilinear + }; + } + + m_Material.SetBuffer("_Histogram", m_Buffer); + m_Material.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height)); + m_Material.SetColor("_ColorR", new Color(1f, 0f, 0f, 1f)); + m_Material.SetColor("_ColorG", new Color(0f, 1f, 0f, 1f)); + m_Material.SetColor("_ColorB", new Color(0f, 0f, 1f, 1f)); + m_Material.SetColor("_ColorL", new Color(1f, 1f, 1f, 1f)); + m_Material.SetInt("_Channel", (int)m_MonitorSettings.histogramMode); + + int pass = 0; + if (m_MonitorSettings.histogramMode == HistogramMode.RGBMerged) + pass = 1; + else if (m_MonitorSettings.histogramMode == HistogramMode.RGBSplit) + pass = 2; + + Graphics.Blit(null, m_HistogramTexture, m_Material, pass); + } + } +} diff --git a/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs.meta b/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs.meta new file mode 100644 index 0000000..a88031e --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/HistogramMonitor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4581c45ac4aa2264187087659a4cc252 +timeCreated: 1460031632 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs b/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs new file mode 100644 index 0000000..03494b1 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs @@ -0,0 +1,257 @@ +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + public class ParadeMonitor : PostProcessingMonitor + { + static GUIContent s_MonitorTitle = new GUIContent("Parade"); + + ComputeShader m_ComputeShader; + ComputeBuffer m_Buffer; + Material m_Material; + RenderTexture m_WaveformTexture; + Rect m_MonitorAreaRect; + + public ParadeMonitor() + { + m_ComputeShader = EditorResources.Load("Monitors/WaveformCompute.compute"); + } + + public override void Dispose() + { + GraphicsUtils.Destroy(m_Material); + GraphicsUtils.Destroy(m_WaveformTexture); + + if (m_Buffer != null) + m_Buffer.Release(); + + m_Material = null; + m_WaveformTexture = null; + m_Buffer = null; + } + + public override bool IsSupported() + { + return m_ComputeShader != null && GraphicsUtils.supportsDX11; + } + + public override GUIContent GetMonitorTitle() + { + return s_MonitorTitle; + } + + public override void OnMonitorSettings() + { + EditorGUI.BeginChangeCheck(); + + bool refreshOnPlay = m_MonitorSettings.refreshOnPlay; + float exposure = m_MonitorSettings.paradeExposure; + + refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the parade in play mode; this may impact performances."), FxStyles.preButton); + exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f)); + + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Parade Settings Changed"); + m_MonitorSettings.refreshOnPlay = refreshOnPlay; + m_MonitorSettings.paradeExposure = exposure; + InternalEditorUtility.RepaintAllViews(); + } + } + + public override void OnMonitorGUI(Rect r) + { + if (Event.current.type == EventType.Repaint) + { + // If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the waveform data + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0)) + InternalEditorUtility.RepaintAllViews(); + + // Sizing + float width = m_WaveformTexture != null + ? Mathf.Min(m_WaveformTexture.width, r.width - 65f) + : r.width; + float height = m_WaveformTexture != null + ? Mathf.Min(m_WaveformTexture.height, r.height - 45f) + : r.height; + + m_MonitorAreaRect = new Rect( + Mathf.Floor(r.x + r.width / 2f - width / 2f), + Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f), + width, height + ); + + if (m_WaveformTexture != null) + { + m_Material.SetFloat("_Exposure", m_MonitorSettings.paradeExposure); + + var oldActive = RenderTexture.active; + Graphics.Blit(null, m_WaveformTexture, m_Material, 0); + RenderTexture.active = oldActive; + + Graphics.DrawTexture(m_MonitorAreaRect, m_WaveformTexture); + + var color = Color.white; + const float kTickSize = 5f; + + // Rect, lines & ticks points + // A O B P C Q D + // N E + // M F + // L G + // K T J S I R H + + var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y); + var D = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y); + var H = new Vector3(D.x, D.y + m_MonitorAreaRect.height + 1f); + var K = new Vector3(A.x, H.y); + + var F = new Vector3(D.x, D.y + (H.y - D.y) / 2f); + var M = new Vector3(A.x, A.y + (K.y - A.y) / 2f); + + var B = new Vector3(A.x + (D.x - A.x) / 3f, A.y); + var C = new Vector3(A.x + (D.x - A.x) * 2f / 3f, A.y); + var I = new Vector3(K.x + (H.x - K.x) * 2f / 3f, K.y); + var J = new Vector3(K.x + (H.x - K.x) / 3f, K.y); + + var N = new Vector3(A.x, A.y + (M.y - A.y) / 2f); + var L = new Vector3(A.x, M.y + (K.y - M.y) / 2f); + var E = new Vector3(D.x, D.y + (F.y - D.y) / 2f); + var G = new Vector3(D.x, F.y + (H.y - F.y) / 2f); + + var O = new Vector3(A.x + (B.x - A.x) / 2f, A.y); + var P = new Vector3(B.x + (C.x - B.x) / 2f, B.y); + var Q = new Vector3(C.x + (D.x - C.x) / 2f, C.y); + + var R = new Vector3(I.x + (H.x - I.x) / 2f, I.y); + var S = new Vector3(J.x + (I.x - J.x) / 2f, J.y); + var T = new Vector3(K.x + (J.x - K.x) / 2f, K.y); + + // Borders + Handles.color = color; + Handles.DrawLine(A, D); + Handles.DrawLine(D, H); + Handles.DrawLine(H, K); + Handles.DrawLine(K, new Vector3(A.x, A.y - 1f)); + + Handles.DrawLine(B, J); + Handles.DrawLine(C, I); + + // Vertical ticks + Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y)); + Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y)); + Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y)); + Handles.DrawLine(L, new Vector3(L.x - kTickSize, L.y)); + Handles.DrawLine(K, new Vector3(K.x - kTickSize, K.y)); + + Handles.DrawLine(D, new Vector3(D.x + kTickSize, D.y)); + Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y)); + Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y)); + Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y)); + Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y)); + + // Horizontal ticks + Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize)); + Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize)); + Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize)); + Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize)); + Handles.DrawLine(O, new Vector3(O.x, O.y - kTickSize)); + Handles.DrawLine(P, new Vector3(P.x, P.y - kTickSize)); + Handles.DrawLine(Q, new Vector3(Q.x, Q.y - kTickSize)); + + Handles.DrawLine(H, new Vector3(H.x, H.y + kTickSize)); + Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize)); + Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize)); + Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize)); + Handles.DrawLine(R, new Vector3(R.x, R.y + kTickSize)); + Handles.DrawLine(S, new Vector3(S.x, S.y + kTickSize)); + Handles.DrawLine(T, new Vector3(T.x, T.y + kTickSize)); + + // Labels + GUI.color = color; + GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight); + GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight); + GUI.Label(new Rect(K.x - kTickSize - 34f, K.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight); + + GUI.Label(new Rect(D.x + kTickSize + 4f, D.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft); + GUI.Label(new Rect(F.x + kTickSize + 4f, F.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft); + GUI.Label(new Rect(H.x + kTickSize + 4f, H.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft); + } + } + } + + public override void OnFrameData(RenderTexture source) + { + if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay) + return; + + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0)) + return; + + float ratio = ((float)source.width / (float)source.height) / 3f; + int h = 384; + int w = Mathf.FloorToInt(h * ratio); + + var rt = RenderTexture.GetTemporary(w, h, 0, source.format); + Graphics.Blit(source, rt); + ComputeWaveform(rt); + m_BaseEditor.Repaint(); + RenderTexture.ReleaseTemporary(rt); + } + + void CreateBuffer(int width, int height) + { + m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2); + } + + void ComputeWaveform(RenderTexture source) + { + if (m_Buffer == null) + { + CreateBuffer(source.width, source.height); + } + else if (m_Buffer.count != (source.width * source.height)) + { + m_Buffer.Release(); + CreateBuffer(source.width, source.height); + } + + var channels = m_MonitorSettings.waveformY + ? new Vector4(0f, 0f, 0f, 1f) + : new Vector4(m_MonitorSettings.waveformR ? 1f : 0f, m_MonitorSettings.waveformG ? 1f : 0f, m_MonitorSettings.waveformB ? 1f : 0f, 0f); + + var cs = m_ComputeShader; + + int kernel = cs.FindKernel("KWaveformClear"); + cs.SetBuffer(kernel, "_Waveform", m_Buffer); + cs.Dispatch(kernel, source.width, 1, 1); + + kernel = cs.FindKernel("KWaveform"); + cs.SetBuffer(kernel, "_Waveform", m_Buffer); + cs.SetTexture(kernel, "_Source", source); + cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0); + cs.SetVector("_Channels", channels); + cs.Dispatch(kernel, source.width, 1, 1); + + if (m_WaveformTexture == null || m_WaveformTexture.width != (source.width * 3) || m_WaveformTexture.height != source.height) + { + GraphicsUtils.Destroy(m_WaveformTexture); + m_WaveformTexture = new RenderTexture(source.width * 3, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.DontSave, + wrapMode = TextureWrapMode.Clamp, + filterMode = FilterMode.Bilinear + }; + } + + if (m_Material == null) + m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Parade Render")) { hideFlags = HideFlags.DontSave }; + + m_Material.SetBuffer("_Waveform", m_Buffer); + m_Material.SetVector("_Size", new Vector2(m_WaveformTexture.width, m_WaveformTexture.height)); + m_Material.SetVector("_Channels", channels); + } + } +} diff --git a/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs.meta b/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs.meta new file mode 100644 index 0000000..41ba865 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/ParadeMonitor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b1f878f3742072e40a280683573bd0ee +timeCreated: 1460031643 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs b/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs new file mode 100644 index 0000000..8514549 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs @@ -0,0 +1,241 @@ +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + public class VectorscopeMonitor : PostProcessingMonitor + { + static GUIContent s_MonitorTitle = new GUIContent("Vectorscope"); + + ComputeShader m_ComputeShader; + ComputeBuffer m_Buffer; + Material m_Material; + RenderTexture m_VectorscopeTexture; + Rect m_MonitorAreaRect; + + public VectorscopeMonitor() + { + m_ComputeShader = EditorResources.Load("Monitors/VectorscopeCompute.compute"); + } + + public override void Dispose() + { + GraphicsUtils.Destroy(m_Material); + GraphicsUtils.Destroy(m_VectorscopeTexture); + + if (m_Buffer != null) + m_Buffer.Release(); + + m_Material = null; + m_VectorscopeTexture = null; + m_Buffer = null; + } + + public override bool IsSupported() + { + return m_ComputeShader != null && GraphicsUtils.supportsDX11; + } + + public override GUIContent GetMonitorTitle() + { + return s_MonitorTitle; + } + + public override void OnMonitorSettings() + { + EditorGUI.BeginChangeCheck(); + + bool refreshOnPlay = m_MonitorSettings.refreshOnPlay; + float exposure = m_MonitorSettings.vectorscopeExposure; + bool showBackground = m_MonitorSettings.vectorscopeShowBackground; + + refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the vectorscope in play mode; this may impact performances."), FxStyles.preButton); + exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f)); + showBackground = GUILayout.Toggle(showBackground, new GUIContent(FxStyles.checkerIcon, "Show an YUV background in the vectorscope."), FxStyles.preButton); + + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Vectorscope Settings Changed"); + m_MonitorSettings.refreshOnPlay = refreshOnPlay; + m_MonitorSettings.vectorscopeExposure = exposure; + m_MonitorSettings.vectorscopeShowBackground = showBackground; + InternalEditorUtility.RepaintAllViews(); + } + } + + public override void OnMonitorGUI(Rect r) + { + if (Event.current.type == EventType.Repaint) + { + // If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the vectoscope data + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0)) + InternalEditorUtility.RepaintAllViews(); + + // Sizing + float size = 0f; + + if (r.width < r.height) + { + size = m_VectorscopeTexture != null + ? Mathf.Min(m_VectorscopeTexture.width, r.width - 35f) + : r.width; + } + else + { + size = m_VectorscopeTexture != null + ? Mathf.Min(m_VectorscopeTexture.height, r.height - 25f) + : r.height; + } + + m_MonitorAreaRect = new Rect( + Mathf.Floor(r.x + r.width / 2f - size / 2f), + Mathf.Floor(r.y + r.height / 2f - size / 2f - 5f), + size, size + ); + + if (m_VectorscopeTexture != null) + { + m_Material.SetFloat("_Exposure", m_MonitorSettings.vectorscopeExposure); + + var oldActive = RenderTexture.active; + Graphics.Blit(null, m_VectorscopeTexture, m_Material, m_MonitorSettings.vectorscopeShowBackground ? 0 : 1); + RenderTexture.active = oldActive; + + Graphics.DrawTexture(m_MonitorAreaRect, m_VectorscopeTexture); + + var color = Color.white; + const float kTickSize = 10f; + const int kTickCount = 24; + + float radius = m_MonitorAreaRect.width / 2f; + float midX = m_MonitorAreaRect.x + radius; + float midY = m_MonitorAreaRect.y + radius; + var center = new Vector2(midX, midY); + + // Cross + color.a *= 0.5f; + Handles.color = color; + Handles.DrawLine(new Vector2(midX, m_MonitorAreaRect.y), new Vector2(midX, m_MonitorAreaRect.y + m_MonitorAreaRect.height)); + Handles.DrawLine(new Vector2(m_MonitorAreaRect.x, midY), new Vector2(m_MonitorAreaRect.x + m_MonitorAreaRect.width, midY)); + + if (m_MonitorAreaRect.width > 100f) + { + color.a = 1f; + + // Ticks + Handles.color = color; + for (int i = 0; i < kTickCount; i++) + { + float a = (float)i / (float)kTickCount; + float theta = a * (Mathf.PI * 2f); + float tx = Mathf.Cos(theta + (Mathf.PI / 2f)); + float ty = Mathf.Sin(theta - (Mathf.PI / 2f)); + var innerVec = center + new Vector2(tx, ty) * (radius - kTickSize); + var outerVec = center + new Vector2(tx, ty) * radius; + Handles.DrawAAPolyLine(3f, innerVec, outerVec); + } + + // Labels (where saturation reaches 75%) + color.a = 1f; + var oldColor = GUI.color; + GUI.color = color * 2f; + + var point = new Vector2(-0.254f, -0.750f) * radius + center; + var rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[R]", FxStyles.tickStyleCenter); + + point = new Vector2(-0.497f, 0.629f) * radius + center; + rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[G]", FxStyles.tickStyleCenter); + + point = new Vector2(0.750f, 0.122f) * radius + center; + rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[B]", FxStyles.tickStyleCenter); + + point = new Vector2(-0.750f, -0.122f) * radius + center; + rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[Y]", FxStyles.tickStyleCenter); + + point = new Vector2(0.254f, 0.750f) * radius + center; + rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[C]", FxStyles.tickStyleCenter); + + point = new Vector2(0.497f, -0.629f) * radius + center; + rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f); + GUI.Label(rect, "[M]", FxStyles.tickStyleCenter); + GUI.color = oldColor; + } + } + } + } + + public override void OnFrameData(RenderTexture source) + { + if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay) + return; + + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0)) + return; + + float ratio = (float)source.width / (float)source.height; + int h = 384; + int w = Mathf.FloorToInt(h * ratio); + + var rt = RenderTexture.GetTemporary(w, h, 0, source.format); + Graphics.Blit(source, rt); + ComputeVectorscope(rt); + m_BaseEditor.Repaint(); + RenderTexture.ReleaseTemporary(rt); + } + + void CreateBuffer(int width, int height) + { + m_Buffer = new ComputeBuffer(width * height, sizeof(uint)); + } + + void ComputeVectorscope(RenderTexture source) + { + if (m_Buffer == null) + { + CreateBuffer(source.width, source.height); + } + else if (m_Buffer.count != (source.width * source.height)) + { + m_Buffer.Release(); + CreateBuffer(source.width, source.height); + } + + var cs = m_ComputeShader; + + int kernel = cs.FindKernel("KVectorscopeClear"); + cs.SetBuffer(kernel, "_Vectorscope", m_Buffer); + cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f)); + cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1); + + kernel = cs.FindKernel("KVectorscope"); + cs.SetBuffer(kernel, "_Vectorscope", m_Buffer); + cs.SetTexture(kernel, "_Source", source); + cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0); + cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f)); + cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1); + + if (m_VectorscopeTexture == null || m_VectorscopeTexture.width != source.width || m_VectorscopeTexture.height != source.height) + { + GraphicsUtils.Destroy(m_VectorscopeTexture); + m_VectorscopeTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.DontSave, + wrapMode = TextureWrapMode.Clamp, + filterMode = FilterMode.Bilinear + }; + } + + if (m_Material == null) + m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Vectorscope Render")) { hideFlags = HideFlags.DontSave }; + + m_Material.SetBuffer("_Vectorscope", m_Buffer); + m_Material.SetVector("_Size", new Vector2(m_VectorscopeTexture.width, m_VectorscopeTexture.height)); + } + } +} diff --git a/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs.meta b/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs.meta new file mode 100644 index 0000000..b700f61 --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 805119df0d94800418006c621cc99cc2 +timeCreated: 1461748750 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs b/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs new file mode 100644 index 0000000..98d3f8e --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs @@ -0,0 +1,280 @@ +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + public class WaveformMonitor : PostProcessingMonitor + { + static GUIContent s_MonitorTitle = new GUIContent("Waveform"); + + ComputeShader m_ComputeShader; + ComputeBuffer m_Buffer; + Material m_Material; + RenderTexture m_WaveformTexture; + Rect m_MonitorAreaRect; + + public WaveformMonitor() + { + m_ComputeShader = EditorResources.Load("Monitors/WaveformCompute.compute"); + } + + public override void Dispose() + { + GraphicsUtils.Destroy(m_Material); + GraphicsUtils.Destroy(m_WaveformTexture); + + if (m_Buffer != null) + m_Buffer.Release(); + + m_Material = null; + m_WaveformTexture = null; + m_Buffer = null; + } + + public override bool IsSupported() + { + return m_ComputeShader != null && GraphicsUtils.supportsDX11; + } + + public override GUIContent GetMonitorTitle() + { + return s_MonitorTitle; + } + + public override void OnMonitorSettings() + { + EditorGUI.BeginChangeCheck(); + + bool refreshOnPlay = m_MonitorSettings.refreshOnPlay; + float exposure = m_MonitorSettings.waveformExposure; + bool Y = m_MonitorSettings.waveformY; + bool R = m_MonitorSettings.waveformR; + bool G = m_MonitorSettings.waveformG; + bool B = m_MonitorSettings.waveformB; + + refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the waveform in play mode; this may impact performances."), FxStyles.preButton); + + exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f)); + + Y = GUILayout.Toggle(Y, new GUIContent("Y", "Show the luminance waveform only."), FxStyles.preButton); + + if (Y) + { + R = false; + G = false; + B = false; + } + + R = GUILayout.Toggle(R, new GUIContent("R", "Show the red waveform."), FxStyles.preButton); + G = GUILayout.Toggle(G, new GUIContent("G", "Show the green waveform."), FxStyles.preButton); + B = GUILayout.Toggle(B, new GUIContent("B", "Show the blue waveform."), FxStyles.preButton); + + if (R || G || B) + Y = false; + + if (!Y && !R && !G && !B) + { + R = true; + G = true; + B = true; + } + + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Waveforme Settings Changed"); + m_MonitorSettings.refreshOnPlay = refreshOnPlay; + m_MonitorSettings.waveformExposure = exposure; + m_MonitorSettings.waveformY = Y; + m_MonitorSettings.waveformR = R; + m_MonitorSettings.waveformG = G; + m_MonitorSettings.waveformB = B; + InternalEditorUtility.RepaintAllViews(); + } + } + + public override void OnMonitorGUI(Rect r) + { + if (Event.current.type == EventType.Repaint) + { + // If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the waveform data + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0)) + InternalEditorUtility.RepaintAllViews(); + + // Sizing + float width = m_WaveformTexture != null + ? Mathf.Min(m_WaveformTexture.width, r.width - 65f) + : r.width; + float height = m_WaveformTexture != null + ? Mathf.Min(m_WaveformTexture.height, r.height - 45f) + : r.height; + + m_MonitorAreaRect = new Rect( + Mathf.Floor(r.x + r.width / 2f - width / 2f), + Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f), + width, height + ); + + if (m_WaveformTexture != null) + { + m_Material.SetFloat("_Exposure", m_MonitorSettings.waveformExposure); + + var oldActive = RenderTexture.active; + Graphics.Blit(null, m_WaveformTexture, m_Material, 0); + RenderTexture.active = oldActive; + + Graphics.DrawTexture(m_MonitorAreaRect, m_WaveformTexture); + + var color = Color.white; + const float kTickSize = 5f; + + // Rect, lines & ticks points + // A B C D E + // P F + // O G + // N H + // M L K J I + + var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y); + var E = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y); + var I = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 1f); + var M = new Vector3(A.x, I.y); + + var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y); + var G = new Vector3(E.x, E.y + (I.y - E.y) / 2f); + var K = new Vector3(M.x + (I.x - M.x) / 2f, M.y); + var O = new Vector3(A.x, A.y + (M.y - A.y) / 2f); + + var P = new Vector3(A.x, A.y + (O.y - A.y) / 2f); + var F = new Vector3(E.x, E.y + (G.y - E.y) / 2f); + var N = new Vector3(A.x, O.y + (M.y - O.y) / 2f); + var H = new Vector3(E.x, G.y + (I.y - G.y) / 2f); + + var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y); + var L = new Vector3(M.x + (K.x - M.x) / 2f, M.y); + var D = new Vector3(C.x + (E.x - C.x) / 2f, A.y); + var J = new Vector3(K.x + (I.x - K.x) / 2f, M.y); + + // Borders + Handles.color = color; + Handles.DrawLine(A, E); + Handles.DrawLine(E, I); + Handles.DrawLine(I, M); + Handles.DrawLine(M, new Vector3(A.x, A.y - 1f)); + + // Vertical ticks + Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y)); + Handles.DrawLine(P, new Vector3(P.x - kTickSize, P.y)); + Handles.DrawLine(O, new Vector3(O.x - kTickSize, O.y)); + Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y)); + Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y)); + + Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y)); + Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y)); + Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y)); + Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y)); + Handles.DrawLine(I, new Vector3(I.x + kTickSize, I.y)); + + // Horizontal ticks + Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize)); + Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize)); + Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize)); + Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize)); + Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize)); + + Handles.DrawLine(M, new Vector3(M.x, M.y + kTickSize)); + Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize)); + Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize)); + Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize)); + Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize)); + + // Labels + GUI.color = color; + GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight); + GUI.Label(new Rect(O.x - kTickSize - 34f, O.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight); + GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight); + + GUI.Label(new Rect(E.x + kTickSize + 4f, E.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft); + GUI.Label(new Rect(G.x + kTickSize + 4f, G.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft); + GUI.Label(new Rect(I.x + kTickSize + 4f, I.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft); + + GUI.Label(new Rect(M.x - 15f, M.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter); + GUI.Label(new Rect(K.x - 15f, K.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter); + GUI.Label(new Rect(I.x - 15f, I.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter); + } + } + } + + public override void OnFrameData(RenderTexture source) + { + if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay) + return; + + if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0)) + return; + + float ratio = (float)source.width / (float)source.height; + int h = 384; + int w = Mathf.FloorToInt(h * ratio); + + var rt = RenderTexture.GetTemporary(w, h, 0, source.format); + Graphics.Blit(source, rt); + ComputeWaveform(rt); + m_BaseEditor.Repaint(); + RenderTexture.ReleaseTemporary(rt); + } + + void CreateBuffer(int width, int height) + { + m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2); + } + + void ComputeWaveform(RenderTexture source) + { + if (m_Buffer == null) + { + CreateBuffer(source.width, source.height); + } + else if (m_Buffer.count != (source.width * source.height)) + { + m_Buffer.Release(); + CreateBuffer(source.width, source.height); + } + + var channels = m_MonitorSettings.waveformY + ? new Vector4(0f, 0f, 0f, 1f) + : new Vector4(m_MonitorSettings.waveformR ? 1f : 0f, m_MonitorSettings.waveformG ? 1f : 0f, m_MonitorSettings.waveformB ? 1f : 0f, 0f); + + var cs = m_ComputeShader; + + int kernel = cs.FindKernel("KWaveformClear"); + cs.SetBuffer(kernel, "_Waveform", m_Buffer); + cs.Dispatch(kernel, source.width, 1, 1); + + kernel = cs.FindKernel("KWaveform"); + cs.SetBuffer(kernel, "_Waveform", m_Buffer); + cs.SetTexture(kernel, "_Source", source); + cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0); + cs.SetVector("_Channels", channels); + cs.Dispatch(kernel, source.width, 1, 1); + + if (m_WaveformTexture == null || m_WaveformTexture.width != source.width || m_WaveformTexture.height != source.height) + { + GraphicsUtils.Destroy(m_WaveformTexture); + m_WaveformTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.DontSave, + wrapMode = TextureWrapMode.Clamp, + filterMode = FilterMode.Bilinear + }; + } + + if (m_Material == null) + m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Waveform Render")) { hideFlags = HideFlags.DontSave }; + + m_Material.SetBuffer("_Waveform", m_Buffer); + m_Material.SetVector("_Size", new Vector2(m_WaveformTexture.width, m_WaveformTexture.height)); + m_Material.SetVector("_Channels", channels); + } + } +} diff --git a/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs.meta b/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs.meta new file mode 100644 index 0000000..0c44bce --- /dev/null +++ b/Assets/PostProcessing/Editor/Monitors/WaveformMonitor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2d45bc7edb5916446b4fa1ae1b6f9065 +timeCreated: 1459957472 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs b/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs new file mode 100644 index 0000000..08550b2 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs @@ -0,0 +1,31 @@ +using System; +using System.Linq.Expressions; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [CustomEditor(typeof(PostProcessingBehaviour))] + public class PostProcessingBehaviourEditor : Editor + { + SerializedProperty m_Profile; + + public void OnEnable() + { + m_Profile = FindSetting((PostProcessingBehaviour x) => x.profile); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_Profile); + + serializedObject.ApplyModifiedProperties(); + } + + SerializedProperty FindSetting(Expression> expr) + { + return serializedObject.FindProperty(ReflectionUtils.GetFieldPath(expr)); + } + } +} diff --git a/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs.meta b/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs.meta new file mode 100644 index 0000000..5506e9d --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingBehaviourEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0c12e797b02402246a52aa270c45059b +timeCreated: 1476193645 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PostProcessingFactory.cs b/Assets/PostProcessing/Editor/PostProcessingFactory.cs new file mode 100644 index 0000000..6ac50f2 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingFactory.cs @@ -0,0 +1,35 @@ +using UnityEngine; +using UnityEngine.PostProcessing; +using UnityEditor.ProjectWindowCallback; +using System.IO; + +namespace UnityEditor.PostProcessing +{ + public class PostProcessingFactory + { + [MenuItem("Assets/Create/Post-Processing Profile", priority = 201)] + static void MenuCreatePostProcessingProfile() + { + var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon"); + ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance(), "New Post-Processing Profile.asset", icon, null); + } + + internal static PostProcessingProfile CreatePostProcessingProfileAtPath(string path) + { + var profile = ScriptableObject.CreateInstance(); + profile.name = Path.GetFileName(path); + profile.fog.enabled = true; + AssetDatabase.CreateAsset(profile, path); + return profile; + } + } + + class DoCreatePostProcessingProfile : EndNameEditAction + { + public override void Action(int instanceId, string pathName, string resourceFile) + { + PostProcessingProfile profile = PostProcessingFactory.CreatePostProcessingProfileAtPath(pathName); + ProjectWindowUtil.ShowCreatedAsset(profile); + } + } +} diff --git a/Assets/PostProcessing/Editor/PostProcessingFactory.cs.meta b/Assets/PostProcessing/Editor/PostProcessingFactory.cs.meta new file mode 100644 index 0000000..e723364 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0dfcadb180d67014cb0a6e18d6b11f90 +timeCreated: 1466586271 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PostProcessingInspector.cs b/Assets/PostProcessing/Editor/PostProcessingInspector.cs new file mode 100644 index 0000000..b2baa94 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingInspector.cs @@ -0,0 +1,208 @@ +using UnityEngine; +using UnityEngine.PostProcessing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace UnityEditor.PostProcessing +{ + //[CanEditMultipleObjects] + [CustomEditor(typeof(PostProcessingProfile))] + public class PostProcessingInspector : Editor + { + static GUIContent s_PreviewTitle = new GUIContent("Monitors"); + + PostProcessingProfile m_ConcreteTarget + { + get { return target as PostProcessingProfile; } + } + + int m_CurrentMonitorID + { + get { return m_ConcreteTarget.monitors.currentMonitorID; } + set { m_ConcreteTarget.monitors.currentMonitorID = value; } + } + + List m_Monitors; + GUIContent[] m_MonitorNames; + Dictionary m_CustomEditors = new Dictionary(); + + public bool IsInteractivePreviewOpened { get; private set; } + + void OnEnable() + { + if (target == null) + return; + + // Aggregate custom post-fx editors + var assembly = Assembly.GetAssembly(typeof(PostProcessingInspector)); + + var editorTypes = assembly.GetTypes() + .Where(x => x.IsDefined(typeof(PostProcessingModelEditorAttribute), false)); + + var customEditors = new Dictionary(); + foreach (var editor in editorTypes) + { + var attr = (PostProcessingModelEditorAttribute)editor.GetCustomAttributes(typeof(PostProcessingModelEditorAttribute), false)[0]; + var effectType = attr.type; + var alwaysEnabled = attr.alwaysEnabled; + + var editorInst = (PostProcessingModelEditor)Activator.CreateInstance(editor); + editorInst.alwaysEnabled = alwaysEnabled; + editorInst.profile = target as PostProcessingProfile; + editorInst.inspector = this; + customEditors.Add(effectType, editorInst); + } + + // ... and corresponding models + var baseType = target.GetType(); + var property = serializedObject.GetIterator(); + + while (property.Next(true)) + { + if (!property.hasChildren) + continue; + + var type = baseType; + var srcObject = ReflectionUtils.GetFieldValueFromPath(serializedObject.targetObject, ref type, property.propertyPath); + + if (srcObject == null) + continue; + + PostProcessingModelEditor editor; + if (customEditors.TryGetValue(type, out editor)) + { + var effect = (PostProcessingModel)srcObject; + + if (editor.alwaysEnabled) + effect.enabled = editor.alwaysEnabled; + + m_CustomEditors.Add(editor, effect); + editor.target = effect; + editor.serializedProperty = property.Copy(); + editor.OnPreEnable(); + } + } + + // Prepare monitors + m_Monitors = new List(); + + var monitors = new List + { + new HistogramMonitor(), + new WaveformMonitor(), + new ParadeMonitor(), + new VectorscopeMonitor() + }; + + var monitorNames = new List(); + + foreach (var monitor in monitors) + { + if (monitor.IsSupported()) + { + monitor.Init(m_ConcreteTarget.monitors, this); + m_Monitors.Add(monitor); + monitorNames.Add(monitor.GetMonitorTitle()); + } + } + + m_MonitorNames = monitorNames.ToArray(); + + if (m_Monitors.Count > 0) + m_ConcreteTarget.monitors.onFrameEndEditorOnly = OnFrameEnd; + } + + void OnDisable() + { + if (m_CustomEditors != null) + { + foreach (var editor in m_CustomEditors.Keys) + editor.OnDisable(); + + m_CustomEditors.Clear(); + } + + if (m_Monitors != null) + { + foreach (var monitor in m_Monitors) + monitor.Dispose(); + + m_Monitors.Clear(); + } + + if (m_ConcreteTarget != null) + m_ConcreteTarget.monitors.onFrameEndEditorOnly = null; + } + + void OnFrameEnd(RenderTexture source) + { + if (!IsInteractivePreviewOpened) + return; + + if (m_CurrentMonitorID < m_Monitors.Count) + m_Monitors[m_CurrentMonitorID].OnFrameData(source); + + IsInteractivePreviewOpened = false; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + // Handles undo/redo events first (before they get used by the editors' widgets) + var e = Event.current; + if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed") + { + foreach (var editor in m_CustomEditors) + editor.Value.OnValidate(); + } + + if (!m_ConcreteTarget.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.None)) + EditorGUILayout.HelpBox("A debug view is currently enabled. Changes done to an effect might not be visible.", MessageType.Info); + + foreach (var editor in m_CustomEditors) + { + EditorGUI.BeginChangeCheck(); + + editor.Key.OnGUI(); + + if (EditorGUI.EndChangeCheck()) + editor.Value.OnValidate(); + } + + serializedObject.ApplyModifiedProperties(); + } + + public override GUIContent GetPreviewTitle() + { + return s_PreviewTitle; + } + + public override bool HasPreviewGUI() + { + return GraphicsUtils.supportsDX11 && m_Monitors.Count > 0; + } + + public override void OnPreviewSettings() + { + using (new EditorGUILayout.HorizontalScope()) + { + if (m_CurrentMonitorID < m_Monitors.Count) + m_Monitors[m_CurrentMonitorID].OnMonitorSettings(); + + GUILayout.Space(5); + m_CurrentMonitorID = EditorGUILayout.Popup(m_CurrentMonitorID, m_MonitorNames, FxStyles.preDropdown, GUILayout.MaxWidth(100f)); + } + } + + public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) + { + IsInteractivePreviewOpened = true; + + if (m_CurrentMonitorID < m_Monitors.Count) + m_Monitors[m_CurrentMonitorID].OnMonitorGUI(r); + } + } +} diff --git a/Assets/PostProcessing/Editor/PostProcessingInspector.cs.meta b/Assets/PostProcessing/Editor/PostProcessingInspector.cs.meta new file mode 100644 index 0000000..19a89a9 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 27fa95984763d9d47bbad59e7fdb66fe +timeCreated: 1467188923 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs b/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs new file mode 100644 index 0000000..844f9e8 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs @@ -0,0 +1,79 @@ +using UnityEngine; +using UnityEngine.PostProcessing; +using System; +using System.Linq.Expressions; + +namespace UnityEditor.PostProcessing +{ + public class PostProcessingModelEditor + { + public PostProcessingModel target { get; internal set; } + public SerializedProperty serializedProperty { get; internal set; } + + protected SerializedProperty m_SettingsProperty; + protected SerializedProperty m_EnabledProperty; + + internal bool alwaysEnabled = false; + internal PostProcessingProfile profile; + internal PostProcessingInspector inspector; + + internal void OnPreEnable() + { + m_SettingsProperty = serializedProperty.FindPropertyRelative("m_Settings"); + m_EnabledProperty = serializedProperty.FindPropertyRelative("m_Enabled"); + + OnEnable(); + } + + public virtual void OnEnable() + {} + + public virtual void OnDisable() + {} + + internal void OnGUI() + { + GUILayout.Space(5); + + var display = alwaysEnabled + ? EditorGUIHelper.Header(serializedProperty.displayName, m_SettingsProperty, Reset) + : EditorGUIHelper.Header(serializedProperty.displayName, m_SettingsProperty, m_EnabledProperty, Reset); + + if (display) + { + EditorGUI.indentLevel++; + using (new EditorGUI.DisabledGroupScope(!m_EnabledProperty.boolValue)) + { + OnInspectorGUI(); + } + EditorGUI.indentLevel--; + } + } + + void Reset() + { + var obj = serializedProperty.serializedObject; + Undo.RecordObject(obj.targetObject, "Reset"); + target.Reset(); + EditorUtility.SetDirty(obj.targetObject); + } + + public virtual void OnInspectorGUI() + {} + + public void Repaint() + { + inspector.Repaint(); + } + + protected SerializedProperty FindSetting(Expression> expr) + { + return m_SettingsProperty.FindPropertyRelative(ReflectionUtils.GetFieldPath(expr)); + } + + protected SerializedProperty FindSetting(SerializedProperty prop, Expression> expr) + { + return prop.FindPropertyRelative(ReflectionUtils.GetFieldPath(expr)); + } + } +} diff --git a/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs.meta b/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs.meta new file mode 100644 index 0000000..d7d393b --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: afe296d4ede60a0479734dc8c7df82c2 +timeCreated: 1467188923 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PostProcessingMonitor.cs b/Assets/PostProcessing/Editor/PostProcessingMonitor.cs new file mode 100644 index 0000000..04edf84 --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingMonitor.cs @@ -0,0 +1,34 @@ +using System; +using UnityEngine; + +namespace UnityEditor.PostProcessing +{ + using MonitorSettings = UnityEngine.PostProcessing.PostProcessingProfile.MonitorSettings; + + public abstract class PostProcessingMonitor : IDisposable + { + protected MonitorSettings m_MonitorSettings; + protected PostProcessingInspector m_BaseEditor; + + public void Init(MonitorSettings monitorSettings, PostProcessingInspector baseEditor) + { + m_MonitorSettings = monitorSettings; + m_BaseEditor = baseEditor; + } + + public abstract bool IsSupported(); + + public abstract GUIContent GetMonitorTitle(); + + public virtual void OnMonitorSettings() + {} + + public abstract void OnMonitorGUI(Rect r); + + public virtual void OnFrameData(RenderTexture source) + {} + + public virtual void Dispose() + {} + } +} diff --git a/Assets/PostProcessing/Editor/PostProcessingMonitor.cs.meta b/Assets/PostProcessing/Editor/PostProcessingMonitor.cs.meta new file mode 100644 index 0000000..ac6616f --- /dev/null +++ b/Assets/PostProcessing/Editor/PostProcessingMonitor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 801186e9e649457469bcddd8ee391c71 +timeCreated: 1467188912 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PropertyDrawers.meta b/Assets/PostProcessing/Editor/PropertyDrawers.meta new file mode 100644 index 0000000..a44f9e2 --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ced92f1cc2085ae48acacc79a2b8e196 +folderAsset: yes +timeCreated: 1467189428 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs b/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs new file mode 100644 index 0000000..a56c201 --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs @@ -0,0 +1,36 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [CustomPropertyDrawer(typeof(GetSetAttribute))] + sealed class GetSetDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + var attribute = (GetSetAttribute)base.attribute; + + EditorGUI.BeginChangeCheck(); + EditorGUI.PropertyField(position, property, label); + + if (EditorGUI.EndChangeCheck()) + { + attribute.dirty = true; + } + else if (attribute.dirty) + { + var parent = ReflectionUtils.GetParentObject(property.propertyPath, property.serializedObject.targetObject); + + var type = parent.GetType(); + var info = type.GetProperty(attribute.name); + + if (info == null) + Debug.LogError("Invalid property name \"" + attribute.name + "\""); + else + info.SetValue(parent, fieldInfo.GetValue(parent), null); + + attribute.dirty = false; + } + } + } +} diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs.meta b/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs.meta new file mode 100644 index 0000000..4322afd --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/GetSetDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e1a43b92f2bbd914ca2e6b4c6a5dba48 +timeCreated: 1460383963 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs b/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs new file mode 100644 index 0000000..59791f5 --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [CustomPropertyDrawer(typeof(MinAttribute))] + sealed class MinDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + MinAttribute attribute = (MinAttribute)base.attribute; + + if (property.propertyType == SerializedPropertyType.Integer) + { + int v = EditorGUI.IntField(position, label, property.intValue); + property.intValue = (int)Mathf.Max(v, attribute.min); + } + else if (property.propertyType == SerializedPropertyType.Float) + { + float v = EditorGUI.FloatField(position, label, property.floatValue); + property.floatValue = Mathf.Max(v, attribute.min); + } + else + { + EditorGUI.LabelField(position, label.text, "Use Min with float or int."); + } + } + } +} diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs.meta b/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs.meta new file mode 100644 index 0000000..488609b --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/MinDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8995f52f410f0fb4cb1bdaa71a16e04e +timeCreated: 1467364278 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs b/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs new file mode 100644 index 0000000..c86c88f --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs @@ -0,0 +1,244 @@ +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + [CustomPropertyDrawer(typeof(TrackballGroupAttribute))] + sealed class TrackballGroupDrawer : PropertyDrawer + { + static Material s_Material; + + const int k_MinWheelSize = 80; + const int k_MaxWheelSize = 256; + + bool m_ResetState; + + // Cached trackball computation methods (for speed reasons) + static Dictionary m_TrackballMethods = new Dictionary(); + + internal static int m_Size + { + get + { + int size = Mathf.FloorToInt(EditorGUIUtility.currentViewWidth / 3f) - 18; + size = Mathf.Clamp(size, k_MinWheelSize, k_MaxWheelSize); + return size; + } + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + if (s_Material == null) + s_Material = new Material(Shader.Find("Hidden/Post FX/UI/Trackball")) { hideFlags = HideFlags.HideAndDontSave }; + + position = new Rect(position.x, position.y, position.width / 3f, position.height); + int size = m_Size; + position.x += 5f; + + var enumerator = property.GetEnumerator(); + while (enumerator.MoveNext()) + { + var prop = enumerator.Current as SerializedProperty; + if (prop == null || prop.propertyType != SerializedPropertyType.Color) + continue; + + OnWheelGUI(position, size, prop.Copy()); + position.x += position.width; + } + } + + void OnWheelGUI(Rect position, int size, SerializedProperty property) + { + if (Event.current.type == EventType.Layout) + return; + + var value = property.colorValue; + float offset = value.a; + + var wheelDrawArea = position; + wheelDrawArea.height = size; + + if (wheelDrawArea.width > wheelDrawArea.height) + { + wheelDrawArea.x += (wheelDrawArea.width - wheelDrawArea.height) / 2.0f; + wheelDrawArea.width = position.height; + } + + wheelDrawArea.width = wheelDrawArea.height; + + float hsize = size / 2f; + float radius = 0.38f * size; + Vector3 hsv; + Color.RGBToHSV(value, out hsv.x, out hsv.y, out hsv.z); + + if (Event.current.type == EventType.Repaint) + { + float scale = EditorGUIUtility.pixelsPerPoint; + + // Wheel texture + var oldRT = RenderTexture.active; + var rt = RenderTexture.GetTemporary((int)(size * scale), (int)(size * scale), 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); + s_Material.SetFloat("_Offset", offset); + s_Material.SetFloat("_DisabledState", GUI.enabled ? 1f : 0.5f); + s_Material.SetVector("_Resolution", new Vector2(size * scale, size * scale / 2f)); + Graphics.Blit(null, rt, s_Material, EditorGUIUtility.isProSkin ? 0 : 1); + RenderTexture.active = oldRT; + + GUI.DrawTexture(wheelDrawArea, rt); + RenderTexture.ReleaseTemporary(rt); + + // Thumb + var thumbPos = Vector2.zero; + float theta = hsv.x * (Mathf.PI * 2f); + float len = hsv.y * radius; + thumbPos.x = Mathf.Cos(theta + (Mathf.PI / 2f)); + thumbPos.y = Mathf.Sin(theta - (Mathf.PI / 2f)); + thumbPos *= len; + var thumbSize = FxStyles.wheelThumbSize; + var thumbSizeH = thumbSize / 2f; + FxStyles.wheelThumb.Draw(new Rect(wheelDrawArea.x + hsize + thumbPos.x - thumbSizeH.x, wheelDrawArea.y + hsize + thumbPos.y - thumbSizeH.y, thumbSize.x, thumbSize.y), false, false, false, false); + } + + var bounds = wheelDrawArea; + bounds.x += hsize - radius; + bounds.y += hsize - radius; + bounds.width = bounds.height = radius * 2f; + hsv = GetInput(bounds, hsv, radius); + value = Color.HSVToRGB(hsv.x, hsv.y, 1f); + value.a = offset; + + // Luminosity booster + position = wheelDrawArea; + float oldX = position.x; + float oldW = position.width; + position.y += position.height + 4f; + position.x += (position.width - (position.width * 0.75f)) / 2f; + position.width = position.width * 0.75f; + position.height = EditorGUIUtility.singleLineHeight; + value.a = GUI.HorizontalSlider(position, value.a, -1f, 1f); + + // Advanced controls + var data = Vector3.zero; + + if (TryGetDisplayValue(value, property, out data)) + { + position.x = oldX; + position.y += position.height; + position.width = oldW / 3f; + + using (new EditorGUI.DisabledGroupScope(true)) + { + GUI.Label(position, data.x.ToString("F2"), EditorStyles.centeredGreyMiniLabel); + position.x += position.width; + GUI.Label(position, data.y.ToString("F2"), EditorStyles.centeredGreyMiniLabel); + position.x += position.width; + GUI.Label(position, data.z.ToString("F2"), EditorStyles.centeredGreyMiniLabel); + position.x += position.width; + } + } + + // Title + position.x = oldX; + position.y += position.height; + position.width = oldW; + GUI.Label(position, property.displayName, EditorStyles.centeredGreyMiniLabel); + + if (m_ResetState) + { + value = Color.clear; + m_ResetState = false; + } + + property.colorValue = value; + } + + bool TryGetDisplayValue(Color color, SerializedProperty property, out Vector3 output) + { + output = Vector3.zero; + MethodInfo method; + + if (!m_TrackballMethods.TryGetValue(property.name, out method)) + { + var field = ReflectionUtils.GetFieldInfoFromPath(property.serializedObject.targetObject, property.propertyPath); + + if (!field.IsDefined(typeof(TrackballAttribute), false)) + return false; + + var attr = (TrackballAttribute)field.GetCustomAttributes(typeof(TrackballAttribute), false)[0]; + const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; + method = typeof(ColorGradingComponent).GetMethod(attr.method, flags); + m_TrackballMethods.Add(property.name, method); + } + + if (method == null) + return false; + + output = (Vector3)method.Invoke(property.serializedObject.targetObject, new object[] { color }); + return true; + } + + static readonly int k_ThumbHash = "colorWheelThumb".GetHashCode(); + + Vector3 GetInput(Rect bounds, Vector3 hsv, float radius) + { + var e = Event.current; + var id = GUIUtility.GetControlID(k_ThumbHash, FocusType.Passive, bounds); + + var mousePos = e.mousePosition; + var relativePos = mousePos - new Vector2(bounds.x, bounds.y); + + if (e.type == EventType.MouseDown && GUIUtility.hotControl == 0 && bounds.Contains(mousePos)) + { + if (e.button == 0) + { + var center = new Vector2(bounds.x + radius, bounds.y + radius); + float dist = Vector2.Distance(center, mousePos); + + if (dist <= radius) + { + e.Use(); + GetWheelHueSaturation(relativePos.x, relativePos.y, radius, out hsv.x, out hsv.y); + GUIUtility.hotControl = id; + GUI.changed = true; + } + } + else if (e.button == 1) + { + e.Use(); + GUI.changed = true; + m_ResetState = true; + } + } + else if (e.type == EventType.MouseDrag && e.button == 0 && GUIUtility.hotControl == id) + { + e.Use(); + GUI.changed = true; + GetWheelHueSaturation(relativePos.x, relativePos.y, radius, out hsv.x, out hsv.y); + } + else if (e.rawType == EventType.MouseUp && e.button == 0 && GUIUtility.hotControl == id) + { + e.Use(); + GUIUtility.hotControl = 0; + } + + return hsv; + } + + void GetWheelHueSaturation(float x, float y, float radius, out float hue, out float saturation) + { + float dx = (x - radius) / radius; + float dy = (y - radius) / radius; + float d = Mathf.Sqrt(dx * dx + dy * dy); + hue = Mathf.Atan2(dx, -dy); + hue = 1f - ((hue > 0) ? hue : (Mathf.PI * 2f) + hue) / (Mathf.PI * 2f); + saturation = Mathf.Clamp01(d); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return m_Size + 4f * 2f + EditorGUIUtility.singleLineHeight * 3f; + } + } +} diff --git a/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs.meta b/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs.meta new file mode 100644 index 0000000..7566a8b --- /dev/null +++ b/Assets/PostProcessing/Editor/PropertyDrawers/TrackballGroupDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a668d493c5ed56d448b53c19b2c3dfd2 +timeCreated: 1460563239 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils.meta b/Assets/PostProcessing/Editor/Utils.meta new file mode 100644 index 0000000..7d88e96 --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b52c69ccefdae7545bfb4d0bf9b7df71 +folderAsset: yes +timeCreated: 1467189428 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils/CurveEditor.cs b/Assets/PostProcessing/Editor/Utils/CurveEditor.cs new file mode 100644 index 0000000..98bd4de --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/CurveEditor.cs @@ -0,0 +1,847 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.PostProcessing +{ + public sealed class CurveEditor + { + #region Enums + + enum EditMode + { + None, + Moving, + TangentEdit + } + + enum Tangent + { + In, + Out + } + #endregion + + #region Structs + public struct Settings + { + public Rect bounds; + public RectOffset padding; + public Color selectionColor; + public float curvePickingDistance; + public float keyTimeClampingDistance; + + public static Settings defaultSettings + { + get + { + return new Settings + { + bounds = new Rect(0f, 0f, 1f, 1f), + padding = new RectOffset(10, 10, 10, 10), + selectionColor = Color.yellow, + curvePickingDistance = 6f, + keyTimeClampingDistance = 1e-4f + }; + } + } + } + + public struct CurveState + { + public bool visible; + public bool editable; + public uint minPointCount; + public float zeroKeyConstantValue; + public Color color; + public float width; + public float handleWidth; + public bool showNonEditableHandles; + public bool onlyShowHandlesOnSelection; + public bool loopInBounds; + + public static CurveState defaultState + { + get + { + return new CurveState + { + visible = true, + editable = true, + minPointCount = 2, + zeroKeyConstantValue = 0f, + color = Color.white, + width = 2f, + handleWidth = 2f, + showNonEditableHandles = true, + onlyShowHandlesOnSelection = false, + loopInBounds = false + }; + } + } + } + + public struct Selection + { + public SerializedProperty curve; + public int keyframeIndex; + public Keyframe? keyframe; + + public Selection(SerializedProperty curve, int keyframeIndex, Keyframe? keyframe) + { + this.curve = curve; + this.keyframeIndex = keyframeIndex; + this.keyframe = keyframe; + } + } + + internal struct MenuAction + { + internal SerializedProperty curve; + internal int index; + internal Vector3 position; + + internal MenuAction(SerializedProperty curve) + { + this.curve = curve; + this.index = -1; + this.position = Vector3.zero; + } + + internal MenuAction(SerializedProperty curve, int index) + { + this.curve = curve; + this.index = index; + this.position = Vector3.zero; + } + + internal MenuAction(SerializedProperty curve, Vector3 position) + { + this.curve = curve; + this.index = -1; + this.position = position; + } + } + #endregion + + #region Fields & properties + public Settings settings { get; private set; } + + Dictionary m_Curves; + Rect m_CurveArea; + + SerializedProperty m_SelectedCurve; + int m_SelectedKeyframeIndex = -1; + + EditMode m_EditMode = EditMode.None; + Tangent m_TangentEditMode; + + bool m_Dirty; + #endregion + + #region Constructors & destructors + public CurveEditor() + : this(Settings.defaultSettings) + {} + + public CurveEditor(Settings settings) + { + this.settings = settings; + m_Curves = new Dictionary(); + } + + #endregion + + #region Public API + public void Add(params SerializedProperty[] curves) + { + foreach (var curve in curves) + Add(curve, CurveState.defaultState); + } + + public void Add(SerializedProperty curve) + { + Add(curve, CurveState.defaultState); + } + + public void Add(SerializedProperty curve, CurveState state) + { + // Make sure the property is in fact an AnimationCurve + var animCurve = curve.animationCurveValue; + if (animCurve == null) + throw new ArgumentException("curve"); + + if (m_Curves.ContainsKey(curve)) + Debug.LogWarning("Curve has already been added to the editor"); + + m_Curves.Add(curve, state); + } + + public void Remove(SerializedProperty curve) + { + m_Curves.Remove(curve); + } + + public void RemoveAll() + { + m_Curves.Clear(); + } + + public CurveState GetCurveState(SerializedProperty curve) + { + CurveState state; + if (!m_Curves.TryGetValue(curve, out state)) + throw new KeyNotFoundException("curve"); + + return state; + } + + public void SetCurveState(SerializedProperty curve, CurveState state) + { + if (!m_Curves.ContainsKey(curve)) + throw new KeyNotFoundException("curve"); + + m_Curves[curve] = state; + } + + public Selection GetSelection() + { + Keyframe? key = null; + if (m_SelectedKeyframeIndex > -1) + { + var curve = m_SelectedCurve.animationCurveValue; + + if (m_SelectedKeyframeIndex >= curve.length) + m_SelectedKeyframeIndex = -1; + else + key = curve[m_SelectedKeyframeIndex]; + } + + return new Selection(m_SelectedCurve, m_SelectedKeyframeIndex, key); + } + + public void SetKeyframe(SerializedProperty curve, int keyframeIndex, Keyframe keyframe) + { + var animCurve = curve.animationCurveValue; + SetKeyframe(animCurve, keyframeIndex, keyframe); + SaveCurve(curve, animCurve); + } + + public bool OnGUI(Rect rect) + { + if (Event.current.type == EventType.Repaint) + m_Dirty = false; + + GUI.BeginClip(rect); + { + var area = new Rect(Vector2.zero, rect.size); + m_CurveArea = settings.padding.Remove(area); + + foreach (var curve in m_Curves) + OnCurveGUI(area, curve.Key, curve.Value); + + OnGeneralUI(area); + } + GUI.EndClip(); + + return m_Dirty; + } + + #endregion + + #region UI & events + + void OnCurveGUI(Rect rect, SerializedProperty curve, CurveState state) + { + // Discard invisible curves + if (!state.visible) + return; + + var animCurve = curve.animationCurveValue; + var keys = animCurve.keys; + var length = keys.Length; + + // Curve drawing + // Slightly dim non-editable curves + var color = state.color; + if (!state.editable) + color.a *= 0.5f; + + Handles.color = color; + var bounds = settings.bounds; + + if (length == 0) + { + var p1 = CurveToCanvas(new Vector3(bounds.xMin, state.zeroKeyConstantValue)); + var p2 = CurveToCanvas(new Vector3(bounds.xMax, state.zeroKeyConstantValue)); + Handles.DrawAAPolyLine(state.width, p1, p2); + } + else if (length == 1) + { + var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value)); + var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[0].value)); + Handles.DrawAAPolyLine(state.width, p1, p2); + } + else + { + var prevKey = keys[0]; + for (int k = 1; k < length; k++) + { + var key = keys[k]; + var pts = BezierSegment(prevKey, key); + + if (float.IsInfinity(prevKey.outTangent) || float.IsInfinity(key.inTangent)) + { + var s = HardSegment(prevKey, key); + Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]); + } + else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width); + + prevKey = key; + } + + // Curve extents & loops + if (keys[0].time > bounds.xMin) + { + if (state.loopInBounds) + { + var p1 = keys[length - 1]; + p1.time -= settings.bounds.width; + var p2 = keys[0]; + var pts = BezierSegment(p1, p2); + + if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent)) + { + var s = HardSegment(p1, p2); + Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]); + } + else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width); + } + else + { + var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value)); + var p2 = CurveToCanvas(keys[0]); + Handles.DrawAAPolyLine(state.width, p1, p2); + } + } + + if (keys[length - 1].time < bounds.xMax) + { + if (state.loopInBounds) + { + var p1 = keys[length - 1]; + var p2 = keys[0]; + p2.time += settings.bounds.width; + var pts = BezierSegment(p1, p2); + + if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent)) + { + var s = HardSegment(p1, p2); + Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]); + } + else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width); + } + else + { + var p1 = CurveToCanvas(keys[length - 1]); + var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[length - 1].value)); + Handles.DrawAAPolyLine(state.width, p1, p2); + } + } + } + + // Make sure selection is correct (undo can break it) + bool isCurrentlySelectedCurve = curve == m_SelectedCurve; + + if (isCurrentlySelectedCurve && m_SelectedKeyframeIndex >= length) + m_SelectedKeyframeIndex = -1; + + // Handles & keys + for (int k = 0; k < length; k++) + { + bool isCurrentlySelectedKeyframe = k == m_SelectedKeyframeIndex; + var e = Event.current; + + var pos = CurveToCanvas(keys[k]); + var hitRect = new Rect(pos.x - 8f, pos.y - 8f, 16f, 16f); + var offset = isCurrentlySelectedCurve + ? new RectOffset(5, 5, 5, 5) + : new RectOffset(6, 6, 6, 6); + + var outTangent = pos + CurveTangentToCanvas(keys[k].outTangent).normalized * 40f; + var inTangent = pos - CurveTangentToCanvas(keys[k].inTangent).normalized * 40f; + var inTangentHitRect = new Rect(inTangent.x - 7f, inTangent.y - 7f, 14f, 14f); + var outTangentHitrect = new Rect(outTangent.x - 7f, outTangent.y - 7f, 14f, 14f); + + // Draw + if (state.showNonEditableHandles) + { + if (e.type == EventType.Repaint) + { + var selectedColor = (isCurrentlySelectedCurve && isCurrentlySelectedKeyframe) + ? settings.selectionColor + : state.color; + + // Keyframe + EditorGUI.DrawRect(offset.Remove(hitRect), selectedColor); + + // Tangents + if (isCurrentlySelectedCurve && (!state.onlyShowHandlesOnSelection || (state.onlyShowHandlesOnSelection && isCurrentlySelectedKeyframe))) + { + Handles.color = selectedColor; + + if (k > 0 || state.loopInBounds) + { + Handles.DrawAAPolyLine(state.handleWidth, pos, inTangent); + EditorGUI.DrawRect(offset.Remove(inTangentHitRect), selectedColor); + } + + if (k < length - 1 || state.loopInBounds) + { + Handles.DrawAAPolyLine(state.handleWidth, pos, outTangent); + EditorGUI.DrawRect(offset.Remove(outTangentHitrect), selectedColor); + } + } + } + } + + // Events + if (state.editable) + { + // Keyframe move + if (m_EditMode == EditMode.Moving && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe) + { + EditMoveKeyframe(animCurve, keys, k); + } + + // Tangent editing + if (m_EditMode == EditMode.TangentEdit && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe) + { + bool alreadyBroken = !(Mathf.Approximately(keys[k].inTangent, keys[k].outTangent) || (float.IsInfinity(keys[k].inTangent) && float.IsInfinity(keys[k].outTangent))); + EditMoveTangent(animCurve, keys, k, m_TangentEditMode, e.shift || !(alreadyBroken || e.control)); + } + + // Keyframe selection & context menu + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + if (hitRect.Contains(e.mousePosition)) + { + if (e.button == 0) + { + SelectKeyframe(curve, k); + m_EditMode = EditMode.Moving; + e.Use(); + } + else if (e.button == 1) + { + // Keyframe context menu + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("Delete Key"), false, (x) => + { + var action = (MenuAction)x; + var curveValue = action.curve.animationCurveValue; + action.curve.serializedObject.Update(); + RemoveKeyframe(curveValue, action.index); + m_SelectedKeyframeIndex = -1; + SaveCurve(action.curve, curveValue); + action.curve.serializedObject.ApplyModifiedProperties(); + }, new MenuAction(curve, k)); + menu.ShowAsContext(); + e.Use(); + } + } + } + + // Tangent selection & edit mode + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + if (inTangentHitRect.Contains(e.mousePosition) && (k > 0 || state.loopInBounds)) + { + SelectKeyframe(curve, k); + m_EditMode = EditMode.TangentEdit; + m_TangentEditMode = Tangent.In; + e.Use(); + } + else if (outTangentHitrect.Contains(e.mousePosition) && (k < length - 1 || state.loopInBounds)) + { + SelectKeyframe(curve, k); + m_EditMode = EditMode.TangentEdit; + m_TangentEditMode = Tangent.Out; + e.Use(); + } + } + + // Mouse up - clean up states + if (e.rawType == EventType.MouseUp && m_EditMode != EditMode.None) + { + m_EditMode = EditMode.None; + } + + // Set cursors + { + EditorGUIUtility.AddCursorRect(hitRect, MouseCursor.MoveArrow); + + if (k > 0 || state.loopInBounds) + EditorGUIUtility.AddCursorRect(inTangentHitRect, MouseCursor.RotateArrow); + + if (k < length - 1 || state.loopInBounds) + EditorGUIUtility.AddCursorRect(outTangentHitrect, MouseCursor.RotateArrow); + } + } + } + + Handles.color = Color.white; + SaveCurve(curve, animCurve); + } + + void OnGeneralUI(Rect rect) + { + var e = Event.current; + + // Selection + if (e.type == EventType.MouseDown) + { + GUI.FocusControl(null); + m_SelectedCurve = null; + m_SelectedKeyframeIndex = -1; + bool used = false; + + var hit = CanvasToCurve(e.mousePosition); + float curvePickValue = CurveToCanvas(hit).y; + + // Try and select a curve + foreach (var curve in m_Curves) + { + if (!curve.Value.editable || !curve.Value.visible) + continue; + + var prop = curve.Key; + var state = curve.Value; + var animCurve = prop.animationCurveValue; + float hitY = animCurve.length == 0 + ? state.zeroKeyConstantValue + : animCurve.Evaluate(hit.x); + + var curvePos = CurveToCanvas(new Vector3(hit.x, hitY)); + + if (Mathf.Abs(curvePos.y - curvePickValue) < settings.curvePickingDistance) + { + m_SelectedCurve = prop; + + if (e.clickCount == 2 && e.button == 0) + { + // Create a keyframe on double-click on this curve + EditCreateKeyframe(animCurve, hit, true, state.zeroKeyConstantValue); + SaveCurve(prop, animCurve); + } + else if (e.button == 1) + { + // Curve context menu + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("Add Key"), false, (x) => + { + var action = (MenuAction)x; + var curveValue = action.curve.animationCurveValue; + action.curve.serializedObject.Update(); + EditCreateKeyframe(curveValue, hit, true, 0f); + SaveCurve(action.curve, curveValue); + action.curve.serializedObject.ApplyModifiedProperties(); + }, new MenuAction(prop, hit)); + menu.ShowAsContext(); + e.Use(); + used = true; + } + } + } + + if (e.clickCount == 2 && e.button == 0 && m_SelectedCurve == null) + { + // Create a keyframe on every curve on double-click + foreach (var curve in m_Curves) + { + if (!curve.Value.editable || !curve.Value.visible) + continue; + + var prop = curve.Key; + var state = curve.Value; + var animCurve = prop.animationCurveValue; + EditCreateKeyframe(animCurve, hit, e.alt, state.zeroKeyConstantValue); + SaveCurve(prop, animCurve); + } + } + else if (!used && e.button == 1) + { + // Global context menu + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("Add Key At Position"), false, () => ContextMenuAddKey(hit, false)); + menu.AddItem(new GUIContent("Add Key On Curves"), false, () => ContextMenuAddKey(hit, true)); + menu.ShowAsContext(); + } + + e.Use(); + } + + // Delete selected key(s) + if (e.type == EventType.KeyDown && (e.keyCode == KeyCode.Delete || e.keyCode == KeyCode.Backspace)) + { + if (m_SelectedKeyframeIndex != -1 && m_SelectedCurve != null) + { + var animCurve = m_SelectedCurve.animationCurveValue; + var length = animCurve.length; + + if (m_Curves[m_SelectedCurve].minPointCount < length && length >= 0) + { + EditDeleteKeyframe(animCurve, m_SelectedKeyframeIndex); + m_SelectedKeyframeIndex = -1; + SaveCurve(m_SelectedCurve, animCurve); + } + + e.Use(); + } + } + } + + void SaveCurve(SerializedProperty prop, AnimationCurve curve) + { + prop.animationCurveValue = curve; + } + + void Invalidate() + { + m_Dirty = true; + } + + #endregion + + #region Keyframe manipulations + + void SelectKeyframe(SerializedProperty curve, int keyframeIndex) + { + m_SelectedKeyframeIndex = keyframeIndex; + m_SelectedCurve = curve; + Invalidate(); + } + + void ContextMenuAddKey(Vector3 hit, bool createOnCurve) + { + SerializedObject serializedObject = null; + + foreach (var curve in m_Curves) + { + if (!curve.Value.editable || !curve.Value.visible) + continue; + + var prop = curve.Key; + var state = curve.Value; + + if (serializedObject == null) + { + serializedObject = prop.serializedObject; + serializedObject.Update(); + } + + var animCurve = prop.animationCurveValue; + EditCreateKeyframe(animCurve, hit, createOnCurve, state.zeroKeyConstantValue); + SaveCurve(prop, animCurve); + } + + if (serializedObject != null) + serializedObject.ApplyModifiedProperties(); + + Invalidate(); + } + + void EditCreateKeyframe(AnimationCurve curve, Vector3 position, bool createOnCurve, float zeroKeyConstantValue) + { + float tangent = EvaluateTangent(curve, position.x); + + if (createOnCurve) + { + position.y = curve.length == 0 + ? zeroKeyConstantValue + : curve.Evaluate(position.x); + } + + AddKeyframe(curve, new Keyframe(position.x, position.y, tangent, tangent)); + } + + void EditDeleteKeyframe(AnimationCurve curve, int keyframeIndex) + { + RemoveKeyframe(curve, keyframeIndex); + } + + void AddKeyframe(AnimationCurve curve, Keyframe newValue) + { + curve.AddKey(newValue); + Invalidate(); + } + + void RemoveKeyframe(AnimationCurve curve, int keyframeIndex) + { + curve.RemoveKey(keyframeIndex); + Invalidate(); + } + + void SetKeyframe(AnimationCurve curve, int keyframeIndex, Keyframe newValue) + { + var keys = curve.keys; + + if (keyframeIndex > 0) + newValue.time = Mathf.Max(keys[keyframeIndex - 1].time + settings.keyTimeClampingDistance, newValue.time); + + if (keyframeIndex < keys.Length - 1) + newValue.time = Mathf.Min(keys[keyframeIndex + 1].time - settings.keyTimeClampingDistance, newValue.time); + + curve.MoveKey(keyframeIndex, newValue); + Invalidate(); + } + + void EditMoveKeyframe(AnimationCurve curve, Keyframe[] keys, int keyframeIndex) + { + var key = CanvasToCurve(Event.current.mousePosition); + float inTgt = keys[keyframeIndex].inTangent; + float outTgt = keys[keyframeIndex].outTangent; + SetKeyframe(curve, keyframeIndex, new Keyframe(key.x, key.y, inTgt, outTgt)); + } + + void EditMoveTangent(AnimationCurve curve, Keyframe[] keys, int keyframeIndex, Tangent targetTangent, bool linkTangents) + { + var pos = CanvasToCurve(Event.current.mousePosition); + + float time = keys[keyframeIndex].time; + float value = keys[keyframeIndex].value; + + pos -= new Vector3(time, value); + + if (targetTangent == Tangent.In && pos.x > 0f) + pos.x = 0f; + + if (targetTangent == Tangent.Out && pos.x < 0f) + pos.x = 0f; + + float tangent; + + if (Mathf.Approximately(pos.x, 0f)) + tangent = pos.y < 0f ? float.PositiveInfinity : float.NegativeInfinity; + else + tangent = pos.y / pos.x; + + float inTangent = keys[keyframeIndex].inTangent; + float outTangent = keys[keyframeIndex].outTangent; + + if (targetTangent == Tangent.In || linkTangents) + inTangent = tangent; + if (targetTangent == Tangent.Out || linkTangents) + outTangent = tangent; + + SetKeyframe(curve, keyframeIndex, new Keyframe(time, value, inTangent, outTangent)); + } + + #endregion + + #region Maths utilities + + Vector3 CurveToCanvas(Keyframe keyframe) + { + return CurveToCanvas(new Vector3(keyframe.time, keyframe.value)); + } + + Vector3 CurveToCanvas(Vector3 position) + { + var bounds = settings.bounds; + var output = new Vector3((position.x - bounds.x) / (bounds.xMax - bounds.x), (position.y - bounds.y) / (bounds.yMax - bounds.y)); + output.x = output.x * (m_CurveArea.xMax - m_CurveArea.xMin) + m_CurveArea.xMin; + output.y = (1f - output.y) * (m_CurveArea.yMax - m_CurveArea.yMin) + m_CurveArea.yMin; + return output; + } + + Vector3 CanvasToCurve(Vector3 position) + { + var bounds = settings.bounds; + var output = position; + output.x = (output.x - m_CurveArea.xMin) / (m_CurveArea.xMax - m_CurveArea.xMin); + output.y = (output.y - m_CurveArea.yMin) / (m_CurveArea.yMax - m_CurveArea.yMin); + output.x = Mathf.Lerp(bounds.x, bounds.xMax, output.x); + output.y = Mathf.Lerp(bounds.yMax, bounds.y, output.y); + return output; + } + + Vector3 CurveTangentToCanvas(float tangent) + { + if (!float.IsInfinity(tangent)) + { + var bounds = settings.bounds; + float ratio = (m_CurveArea.width / m_CurveArea.height) / ((bounds.xMax - bounds.x) / (bounds.yMax - bounds.y)); + return new Vector3(1f, -tangent / ratio).normalized; + } + + return float.IsPositiveInfinity(tangent) ? Vector3.up : Vector3.down; + } + + Vector3[] BezierSegment(Keyframe start, Keyframe end) + { + var segment = new Vector3[4]; + + segment[0] = CurveToCanvas(new Vector3(start.time, start.value)); + segment[3] = CurveToCanvas(new Vector3(end.time, end.value)); + + float middle = start.time + ((end.time - start.time) * 0.333333f); + float middle2 = start.time + ((end.time - start.time) * 0.666666f); + + segment[1] = CurveToCanvas(new Vector3(middle, ProjectTangent(start.time, start.value, start.outTangent, middle))); + segment[2] = CurveToCanvas(new Vector3(middle2, ProjectTangent(end.time, end.value, end.inTangent, middle2))); + + return segment; + } + + Vector3[] HardSegment(Keyframe start, Keyframe end) + { + var segment = new Vector3[3]; + + segment[0] = CurveToCanvas(start); + segment[1] = CurveToCanvas(new Vector3(end.time, start.value)); + segment[2] = CurveToCanvas(end); + + return segment; + } + + float ProjectTangent(float inPosition, float inValue, float inTangent, float projPosition) + { + return inValue + ((projPosition - inPosition) * inTangent); + } + + float EvaluateTangent(AnimationCurve curve, float time) + { + int prev = -1, next = 0; + for (int i = 0; i < curve.keys.Length; i++) + { + if (time > curve.keys[i].time) + { + prev = i; + next = i + 1; + } + else break; + } + + if (next == 0) + return 0f; + + if (prev == curve.keys.Length - 1) + return 0f; + + const float kD = 1e-3f; + float tp = Mathf.Max(time - kD, curve.keys[prev].time); + float tn = Mathf.Min(time + kD, curve.keys[next].time); + + float vp = curve.Evaluate(tp); + float vn = curve.Evaluate(tn); + + if (Mathf.Approximately(tn, tp)) + return (vn - vp > 0f) ? float.PositiveInfinity : float.NegativeInfinity; + + return (vn - vp) / (tn - tp); + } + + #endregion + } +} diff --git a/Assets/PostProcessing/Editor/Utils/CurveEditor.cs.meta b/Assets/PostProcessing/Editor/Utils/CurveEditor.cs.meta new file mode 100644 index 0000000..284d6c7 --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/CurveEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: afb349ef0bffd144db2bdd25630f648e +timeCreated: 1472650750 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs b/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs new file mode 100644 index 0000000..c0d4e1e --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs @@ -0,0 +1,194 @@ +using System; +using UnityEngine; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using UnityEngine.PostProcessing; + +namespace UnityEditor.PostProcessing +{ + public static class EditorGUIHelper + { + static EditorGUIHelper() + { + s_GUIContentCache = new Dictionary(); + } + + #region GUIContent caching + + static Dictionary s_GUIContentCache; + + public static GUIContent GetContent(string textAndTooltip) + { + if (string.IsNullOrEmpty(textAndTooltip)) + return GUIContent.none; + + GUIContent content; + + if (!s_GUIContentCache.TryGetValue(textAndTooltip, out content)) + { + var s = textAndTooltip.Split('|'); + content = new GUIContent(s[0]); + + if (s.Length > 1 && !string.IsNullOrEmpty(s[1])) + content.tooltip = s[1]; + + s_GUIContentCache.Add(textAndTooltip, content); + } + + return content; + } + + #endregion + + public static bool Header(string title, SerializedProperty group, Action resetAction) + { + var rect = GUILayoutUtility.GetRect(16f, 22f, FxStyles.header); + GUI.Box(rect, title, FxStyles.header); + + var display = group == null || group.isExpanded; + + var foldoutRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f); + var e = Event.current; + + var popupRect = new Rect(rect.x + rect.width - FxStyles.paneOptionsIcon.width - 5f, rect.y + FxStyles.paneOptionsIcon.height / 2f + 1f, FxStyles.paneOptionsIcon.width, FxStyles.paneOptionsIcon.height); + GUI.DrawTexture(popupRect, FxStyles.paneOptionsIcon); + + if (e.type == EventType.Repaint) + FxStyles.headerFoldout.Draw(foldoutRect, false, false, display, false); + + if (e.type == EventType.MouseDown) + { + if (popupRect.Contains(e.mousePosition)) + { + var popup = new GenericMenu(); + popup.AddItem(GetContent("Reset"), false, () => resetAction()); + popup.AddSeparator(string.Empty); + popup.AddItem(GetContent("Copy Settings"), false, () => CopySettings(group)); + + if (CanPaste(group)) + popup.AddItem(GetContent("Paste Settings"), false, () => PasteSettings(group)); + else + popup.AddDisabledItem(GetContent("Paste Settings")); + + popup.ShowAsContext(); + } + else if (rect.Contains(e.mousePosition) && group != null) + { + display = !display; + + if (group != null) + group.isExpanded = !group.isExpanded; + + e.Use(); + } + } + + return display; + } + + public static bool Header(string title, SerializedProperty group, SerializedProperty enabledField, Action resetAction) + { + var field = ReflectionUtils.GetFieldInfoFromPath(enabledField.serializedObject.targetObject, enabledField.propertyPath); + object parent = null; + PropertyInfo prop = null; + + if (field != null && field.IsDefined(typeof(GetSetAttribute), false)) + { + var attr = (GetSetAttribute)field.GetCustomAttributes(typeof(GetSetAttribute), false)[0]; + parent = ReflectionUtils.GetParentObject(enabledField.propertyPath, enabledField.serializedObject.targetObject); + prop = parent.GetType().GetProperty(attr.name); + } + + var display = group == null || group.isExpanded; + var enabled = enabledField.boolValue; + + var rect = GUILayoutUtility.GetRect(16f, 22f, FxStyles.header); + GUI.Box(rect, title, FxStyles.header); + + var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f); + var e = Event.current; + + var popupRect = new Rect(rect.x + rect.width - FxStyles.paneOptionsIcon.width - 5f, rect.y + FxStyles.paneOptionsIcon.height / 2f + 1f, FxStyles.paneOptionsIcon.width, FxStyles.paneOptionsIcon.height); + GUI.DrawTexture(popupRect, FxStyles.paneOptionsIcon); + + if (e.type == EventType.Repaint) + FxStyles.headerCheckbox.Draw(toggleRect, false, false, enabled, false); + + if (e.type == EventType.MouseDown) + { + const float kOffset = 2f; + toggleRect.x -= kOffset; + toggleRect.y -= kOffset; + toggleRect.width += kOffset * 2f; + toggleRect.height += kOffset * 2f; + + if (toggleRect.Contains(e.mousePosition)) + { + enabledField.boolValue = !enabledField.boolValue; + + if (prop != null) + prop.SetValue(parent, enabledField.boolValue, null); + + e.Use(); + } + else if (popupRect.Contains(e.mousePosition)) + { + var popup = new GenericMenu(); + popup.AddItem(GetContent("Reset"), false, () => resetAction()); + popup.AddSeparator(string.Empty); + popup.AddItem(GetContent("Copy Settings"), false, () => CopySettings(group)); + + if (CanPaste(group)) + popup.AddItem(GetContent("Paste Settings"), false, () => PasteSettings(group)); + else + popup.AddDisabledItem(GetContent("Paste Settings")); + + popup.ShowAsContext(); + } + else if (rect.Contains(e.mousePosition) && group != null) + { + display = !display; + group.isExpanded = !group.isExpanded; + e.Use(); + } + } + + return display; + } + + static void CopySettings(SerializedProperty settings) + { + var t = typeof(PostProcessingProfile); + var settingsStruct = ReflectionUtils.GetFieldValueFromPath(settings.serializedObject.targetObject, ref t, settings.propertyPath); + var serializedString = t.ToString() + '|' + JsonUtility.ToJson(settingsStruct); + EditorGUIUtility.systemCopyBuffer = serializedString; + } + + static bool CanPaste(SerializedProperty settings) + { + var data = EditorGUIUtility.systemCopyBuffer; + + if (string.IsNullOrEmpty(data)) + return false; + + var parts = data.Split('|'); + + if (string.IsNullOrEmpty(parts[0])) + return false; + + var field = ReflectionUtils.GetFieldInfoFromPath(settings.serializedObject.targetObject, settings.propertyPath); + return parts[0] == field.FieldType.ToString(); + } + + static void PasteSettings(SerializedProperty settings) + { + Undo.RecordObject(settings.serializedObject.targetObject, "Paste effect settings"); + var field = ReflectionUtils.GetFieldInfoFromPath(settings.serializedObject.targetObject, settings.propertyPath); + var json = EditorGUIUtility.systemCopyBuffer.Substring(field.FieldType.ToString().Length + 1); + var obj = JsonUtility.FromJson(json, field.FieldType); + var parent = ReflectionUtils.GetParentObject(settings.propertyPath, settings.serializedObject.targetObject); + field.SetValue(parent, obj, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CultureInfo.CurrentCulture); + } + } +} diff --git a/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs.meta b/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs.meta new file mode 100644 index 0000000..fcd783e --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/EditorGUIHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7226e17fa48c86148a3d15584e21b4cb +timeCreated: 1460477750 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils/EditorResources.cs b/Assets/PostProcessing/Editor/Utils/EditorResources.cs new file mode 100644 index 0000000..aea193c --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/EditorResources.cs @@ -0,0 +1,58 @@ +using UnityEngine; + +namespace UnityEditor.PostProcessing +{ + using UnityObject = Object; + + static class EditorResources + { + static string m_EditorResourcesPath = string.Empty; + + internal static string editorResourcesPath + { + get + { + if (string.IsNullOrEmpty(m_EditorResourcesPath)) + { + string path; + + if (SearchForEditorResourcesPath(out path)) + m_EditorResourcesPath = path; + else + Debug.LogError("Unable to locate editor resources. Make sure the PostProcessing package has been installed correctly."); + } + + return m_EditorResourcesPath; + } + } + + internal static T Load(string name) + where T : UnityObject + { + return AssetDatabase.LoadAssetAtPath(editorResourcesPath + name); + } + + static bool SearchForEditorResourcesPath(out string path) + { + path = string.Empty; + + string searchStr = "/PostProcessing/Editor Resources/"; + string str = null; + + foreach (var assetPath in AssetDatabase.GetAllAssetPaths()) + { + if (assetPath.Contains(searchStr)) + { + str = assetPath; + break; + } + } + + if (str == null) + return false; + + path = str.Substring(0, str.LastIndexOf(searchStr) + searchStr.Length); + return true; + } + } +} diff --git a/Assets/PostProcessing/Editor/Utils/EditorResources.cs.meta b/Assets/PostProcessing/Editor/Utils/EditorResources.cs.meta new file mode 100644 index 0000000..4bfe35e --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/EditorResources.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a66d7b0165140a1439be89b5afc000fb +timeCreated: 1476177015 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils/FxStyles.cs b/Assets/PostProcessing/Editor/Utils/FxStyles.cs new file mode 100644 index 0000000..e3a4dff --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/FxStyles.cs @@ -0,0 +1,111 @@ +using UnityEngine; + +namespace UnityEditor.PostProcessing +{ + public static class FxStyles + { + public static GUIStyle tickStyleRight; + public static GUIStyle tickStyleLeft; + public static GUIStyle tickStyleCenter; + + public static GUIStyle preSlider; + public static GUIStyle preSliderThumb; + public static GUIStyle preButton; + public static GUIStyle preDropdown; + + public static GUIStyle preLabel; + public static GUIStyle hueCenterCursor; + public static GUIStyle hueRangeCursor; + + public static GUIStyle centeredBoldLabel; + public static GUIStyle wheelThumb; + public static Vector2 wheelThumbSize; + + public static GUIStyle header; + public static GUIStyle headerCheckbox; + public static GUIStyle headerFoldout; + + public static Texture2D playIcon; + public static Texture2D checkerIcon; + public static Texture2D paneOptionsIcon; + + public static GUIStyle centeredMiniLabel; + + static FxStyles() + { + tickStyleRight = new GUIStyle("Label") + { + alignment = TextAnchor.MiddleRight, + fontSize = 9 + }; + + tickStyleLeft = new GUIStyle("Label") + { + alignment = TextAnchor.MiddleLeft, + fontSize = 9 + }; + + tickStyleCenter = new GUIStyle("Label") + { + alignment = TextAnchor.MiddleCenter, + fontSize = 9 + }; + + preSlider = new GUIStyle("PreSlider"); + preSliderThumb = new GUIStyle("PreSliderThumb"); + preButton = new GUIStyle("PreButton"); + preDropdown = new GUIStyle("preDropdown"); + + preLabel = new GUIStyle("ShurikenLabel"); + + hueCenterCursor = new GUIStyle("ColorPicker2DThumb") + { + normal = { background = (Texture2D)EditorGUIUtility.LoadRequired("Builtin Skins/DarkSkin/Images/ShurikenPlus.png") }, + fixedWidth = 6, + fixedHeight = 6 + }; + + hueRangeCursor = new GUIStyle(hueCenterCursor) + { + normal = { background = (Texture2D)EditorGUIUtility.LoadRequired("Builtin Skins/DarkSkin/Images/CircularToggle_ON.png") } + }; + + wheelThumb = new GUIStyle("ColorPicker2DThumb"); + + centeredBoldLabel = new GUIStyle(GUI.skin.GetStyle("Label")) + { + alignment = TextAnchor.UpperCenter, + fontStyle = FontStyle.Bold + }; + + centeredMiniLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel) + { + alignment = TextAnchor.UpperCenter + }; + + wheelThumbSize = new Vector2( + !Mathf.Approximately(wheelThumb.fixedWidth, 0f) ? wheelThumb.fixedWidth : wheelThumb.padding.horizontal, + !Mathf.Approximately(wheelThumb.fixedHeight, 0f) ? wheelThumb.fixedHeight : wheelThumb.padding.vertical + ); + + header = new GUIStyle("ShurikenModuleTitle") + { + font = (new GUIStyle("Label")).font, + border = new RectOffset(15, 7, 4, 4), + fixedHeight = 22, + contentOffset = new Vector2(20f, -2f) + }; + + headerCheckbox = new GUIStyle("ShurikenCheckMark"); + headerFoldout = new GUIStyle("Foldout"); + + playIcon = (Texture2D)EditorGUIUtility.LoadRequired("Builtin Skins/DarkSkin/Images/IN foldout act.png"); + checkerIcon = (Texture2D)EditorGUIUtility.LoadRequired("Icons/CheckerFloor.png"); + + if (EditorGUIUtility.isProSkin) + paneOptionsIcon = (Texture2D)EditorGUIUtility.LoadRequired("Builtin Skins/DarkSkin/Images/pane options.png"); + else + paneOptionsIcon = (Texture2D)EditorGUIUtility.LoadRequired("Builtin Skins/LightSkin/Images/pane options.png"); + } + } +} diff --git a/Assets/PostProcessing/Editor/Utils/FxStyles.cs.meta b/Assets/PostProcessing/Editor/Utils/FxStyles.cs.meta new file mode 100644 index 0000000..c9c6a7e --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/FxStyles.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8f31cf52f05e80c4ea48570d0c3c8f59 +timeCreated: 1461744717 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs b/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs new file mode 100644 index 0000000..0dd92d1 --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace UnityEditor.PostProcessing +{ + public static class ReflectionUtils + { + static Dictionary, FieldInfo> s_FieldInfoFromPaths = new Dictionary, FieldInfo>(); + + public static FieldInfo GetFieldInfoFromPath(object source, string path) + { + FieldInfo field = null; + var kvp = new KeyValuePair(source, path); + + if (!s_FieldInfoFromPaths.TryGetValue(kvp, out field)) + { + var splittedPath = path.Split('.'); + var type = source.GetType(); + + foreach (var t in splittedPath) + { + field = type.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + + if (field == null) + break; + + type = field.FieldType; + } + + s_FieldInfoFromPaths.Add(kvp, field); + } + + return field; + } + + public static string GetFieldPath(Expression> expr) + { + MemberExpression me; + switch (expr.Body.NodeType) + { + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + var ue = expr.Body as UnaryExpression; + me = (ue != null ? ue.Operand : null) as MemberExpression; + break; + default: + me = expr.Body as MemberExpression; + break; + } + + var members = new List(); + while (me != null) + { + members.Add(me.Member.Name); + me = me.Expression as MemberExpression; + } + + var sb = new StringBuilder(); + for (int i = members.Count - 1; i >= 0; i--) + { + sb.Append(members[i]); + if (i > 0) sb.Append('.'); + } + + return sb.ToString(); + } + + public static object GetFieldValue(object source, string name) + { + var type = source.GetType(); + + while (type != null) + { + var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (f != null) + return f.GetValue(source); + + type = type.BaseType; + } + + return null; + } + + public static object GetFieldValueFromPath(object source, ref Type baseType, string path) + { + var splittedPath = path.Split('.'); + object srcObject = source; + + foreach (var t in splittedPath) + { + var fieldInfo = baseType.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + + if (fieldInfo == null) + { + baseType = null; + break; + } + + baseType = fieldInfo.FieldType; + srcObject = GetFieldValue(srcObject, t); + } + + return baseType == null + ? null + : srcObject; + } + + public static object GetParentObject(string path, object obj) + { + var fields = path.Split('.'); + + if (fields.Length == 1) + return obj; + + var info = obj.GetType().GetField(fields[0], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + obj = info.GetValue(obj); + + return GetParentObject(string.Join(".", fields, 1, fields.Length - 1), obj); + } + } +} diff --git a/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs.meta b/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs.meta new file mode 100644 index 0000000..1d4e656 --- /dev/null +++ b/Assets/PostProcessing/Editor/Utils/ReflectionUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 71f7e805a7fc35046afbcf5c2639d116 +timeCreated: 1466604313 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources.meta b/Assets/PostProcessing/Resources.meta new file mode 100644 index 0000000..5c37245 --- /dev/null +++ b/Assets/PostProcessing/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 52380717b4884c04ebc31c46dda84909 +folderAsset: yes +timeCreated: 1466585230 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64.meta b/Assets/PostProcessing/Resources/Bluenoise64.meta new file mode 100644 index 0000000..ef44148 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2be7cf05ee8fb17438022d4869299900 +folderAsset: yes +timeCreated: 1485107615 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt b/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt.meta b/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt.meta new file mode 100644 index 0000000..acd4f45 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/COPYING.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fa3fc398fe396744c9299e70b63bfdd7 +timeCreated: 1485181015 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png new file mode 100644 index 0000000..d1920c6 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png.meta new file mode 100644 index 0000000..b65139e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_0.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 50b54341495978843a6f85583ed4417d +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png new file mode 100644 index 0000000..9d525e5 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png.meta new file mode 100644 index 0000000..a9c0293 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_1.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 3c2f1fb7e4b66e74191b7c328ada52d9 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png new file mode 100644 index 0000000..ecadafb Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png.meta new file mode 100644 index 0000000..0934dc5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_10.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: afe1e502240079342a0a980484b6da8b +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png new file mode 100644 index 0000000..923292a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png.meta new file mode 100644 index 0000000..2d497fa --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_11.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 771903fe7b4674445829e52e91cff019 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png new file mode 100644 index 0000000..2077a1a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png.meta new file mode 100644 index 0000000..2dd880b --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_12.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 980acadb960f8424c94307ec0e585b4e +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png new file mode 100644 index 0000000..491f4c0 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png.meta new file mode 100644 index 0000000..6daf2ab --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_13.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 68613e6a221be1a4b9f31d7fa1c2d1bf +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png new file mode 100644 index 0000000..3093572 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png.meta new file mode 100644 index 0000000..529e811 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_14.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: f6439b54b28f3884eb67579dec0b6f21 +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png new file mode 100644 index 0000000..ece485d Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png.meta new file mode 100644 index 0000000..25becd6 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_15.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 2ee161d8945169243b5698fec114e1b7 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png new file mode 100644 index 0000000..8750ad6 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png.meta new file mode 100644 index 0000000..43426f2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_16.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 153f7d6dfbe713d4884df0f1e243ba92 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png new file mode 100644 index 0000000..bdee0f8 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png.meta new file mode 100644 index 0000000..5adee25 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_17.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: bf95b6fdc179b0e4f890c841406193fc +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png new file mode 100644 index 0000000..30c49f3 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png.meta new file mode 100644 index 0000000..1135a8c --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_18.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 74aca53eb7273624baffc2bf5e5cc173 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png new file mode 100644 index 0000000..5180f1a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png.meta new file mode 100644 index 0000000..ccce5c9 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_19.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 729a3ae164bcb3b4380459386adcf331 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png new file mode 100644 index 0000000..f5912ee Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png.meta new file mode 100644 index 0000000..1283494 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_2.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: a469f920b21fc7c4fb5b950917ce2fb2 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png new file mode 100644 index 0000000..1424899 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png.meta new file mode 100644 index 0000000..9e235dc --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_20.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 6dda07f1420a968449cf4c6620c44d9f +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png new file mode 100644 index 0000000..d634013 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png.meta new file mode 100644 index 0000000..986f773 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_21.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: b7f000750830ddb4bbc80065b9314ce9 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png new file mode 100644 index 0000000..cb0a0ae Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png.meta new file mode 100644 index 0000000..1a6a185 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_22.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: df01d03f056c6f445b4b8a0ae054207c +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png new file mode 100644 index 0000000..b063795 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png.meta new file mode 100644 index 0000000..13d7512 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_23.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: bfe953600e8fb1849a804ee08ace7b4c +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png new file mode 100644 index 0000000..f4debb8 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png.meta new file mode 100644 index 0000000..d7c7d4e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_24.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 32c6a5f7143b86c44bd5cdee2ff3f8ad +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png new file mode 100644 index 0000000..c20d7b2 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png.meta new file mode 100644 index 0000000..7533669 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_25.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: f4b8ab78b57749d4e96d36f6d8a395d0 +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png new file mode 100644 index 0000000..930ec4e Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png.meta new file mode 100644 index 0000000..dfd8eaf --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_26.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 09f6c01f98a3ded4daf1afc52a3c260f +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png new file mode 100644 index 0000000..06949cf Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png.meta new file mode 100644 index 0000000..a5c9c77 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_27.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: bdd06fb88ef36ed4a85dd506352c2d80 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png new file mode 100644 index 0000000..9807e41 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png.meta new file mode 100644 index 0000000..14d96b5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_28.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 02c0a84bd64c6f044954d8bde9b46ec8 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png new file mode 100644 index 0000000..413a86e Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png.meta new file mode 100644 index 0000000..4104931 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_29.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: aa80dc44aa4fe4c43bb9d51d90cf2958 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png new file mode 100644 index 0000000..767fc58 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png.meta new file mode 100644 index 0000000..239bbfd --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_3.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 373f9bf6b0841af4ebf26d25e4a3f4e2 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png new file mode 100644 index 0000000..a1da55b Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png.meta new file mode 100644 index 0000000..ce3ec24 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_30.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 0fa10b21877c61b4db40ba5708815f81 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png new file mode 100644 index 0000000..e2961b5 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png.meta new file mode 100644 index 0000000..4e19af5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_31.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 6b0a189df0bd4d5448eaefb4e673ace8 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png new file mode 100644 index 0000000..24d31e9 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png.meta new file mode 100644 index 0000000..44cfe5b --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_32.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 87a5e40cc271ea648b583616f6ebe7fe +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png new file mode 100644 index 0000000..3403d4d Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png.meta new file mode 100644 index 0000000..daa5a68 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_33.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: b71bb466b71fd13449dd736f63caeb67 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png new file mode 100644 index 0000000..2022cd9 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png.meta new file mode 100644 index 0000000..d4cfe74 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_34.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 319b8e66db3faa4438cf6982e9c89b2f +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png new file mode 100644 index 0000000..bd9359c Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png.meta new file mode 100644 index 0000000..9a07c27 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_35.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 0a79c155edf9b2d429d4736abee5acdb +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png new file mode 100644 index 0000000..22ed73a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png.meta new file mode 100644 index 0000000..12a99a1 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_36.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 351e95d0e20a54849bd4ce5f9b498934 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png new file mode 100644 index 0000000..6f84bb7 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png.meta new file mode 100644 index 0000000..b7f4b8e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_37.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 1d6958e30e40a254dbe5a54c573eeb3c +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png new file mode 100644 index 0000000..d9c27fb Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png.meta new file mode 100644 index 0000000..da23fcd --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_38.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 9660a4ca1ca8425408ac25c641932977 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png new file mode 100644 index 0000000..2610149 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png.meta new file mode 100644 index 0000000..14a039a --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_39.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 547dbd5f858c74047ba3f213e4408307 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png new file mode 100644 index 0000000..81cdc3d Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png.meta new file mode 100644 index 0000000..b93c605 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_4.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 6fa5cf178eaaa5f42b820f636bb6e0bd +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png new file mode 100644 index 0000000..8d95446 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png.meta new file mode 100644 index 0000000..ea422e4 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_40.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 1a9ce5640cde5934aae0022f020464a6 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png new file mode 100644 index 0000000..f6c01a6 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png.meta new file mode 100644 index 0000000..24ebca6 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_41.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: cd9006dc442cc244e89b3f492384d46a +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png new file mode 100644 index 0000000..1d42c2f Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png.meta new file mode 100644 index 0000000..19a265b --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_42.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: b266511438fae724f9d3ce6bd26583e8 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png new file mode 100644 index 0000000..2f5c591 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png.meta new file mode 100644 index 0000000..09b45ca --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_43.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 71bc1b6b66e8b784b972199b7e90204e +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png new file mode 100644 index 0000000..765c014 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png.meta new file mode 100644 index 0000000..2eba296 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_44.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 15e54aa23a938444389469d53765d741 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png new file mode 100644 index 0000000..f335132 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png.meta new file mode 100644 index 0000000..76e8fb2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_45.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: b9960364038cbfa4aa49d7b2032d3110 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png new file mode 100644 index 0000000..5118df3 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png.meta new file mode 100644 index 0000000..50f5f42 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_46.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 8ecbbcae4cc747a4abbc4adce795d25e +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png new file mode 100644 index 0000000..c22a632 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png.meta new file mode 100644 index 0000000..ce122b4 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_47.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 1378a33cdd085d64c9da863d2484ff21 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png new file mode 100644 index 0000000..782c380 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png.meta new file mode 100644 index 0000000..c58166c --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_48.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: aff59c63d25d43f4c938f248837c30fb +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png new file mode 100644 index 0000000..34d36e6 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png.meta new file mode 100644 index 0000000..e9e2603 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_49.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 3f7c3687170b90e4a8d2ee6b142670f4 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png new file mode 100644 index 0000000..90a715a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png.meta new file mode 100644 index 0000000..bbdc30e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_5.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: a1ae041906217ae44a774d4ca139af50 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png new file mode 100644 index 0000000..df80595 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png.meta new file mode 100644 index 0000000..49bace2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_50.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: d8c290e38ff0425409d0ae6a98c95e41 +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png new file mode 100644 index 0000000..ed9f2d3 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png.meta new file mode 100644 index 0000000..1780727 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_51.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: d5a51525b27e3ee4aadbeb39cbcf0750 +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png new file mode 100644 index 0000000..be2c6fe Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png.meta new file mode 100644 index 0000000..357d7a6 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_52.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: d2e8e90fac2e6a341a38e1c3963c218d +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png new file mode 100644 index 0000000..c226491 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png.meta new file mode 100644 index 0000000..549202e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_53.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: c94b57b5a32a22d43ade66e09f6a4bd2 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png new file mode 100644 index 0000000..3b6bbb8 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png.meta new file mode 100644 index 0000000..685fd4d --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_54.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 936dea238abb0864ab3985a995e16a29 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png new file mode 100644 index 0000000..261291a Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png.meta new file mode 100644 index 0000000..6984f50 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_55.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 5e542d0126a2c7848b66bffc428905fd +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png new file mode 100644 index 0000000..7d8b298 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png.meta new file mode 100644 index 0000000..dbd357e --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_56.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 70f23eaf7d8ae9147aa542d20e93733b +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png new file mode 100644 index 0000000..97fe687 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png.meta new file mode 100644 index 0000000..b8079c2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_57.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: e138166e7a7c70f49943be7edda35d35 +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png new file mode 100644 index 0000000..9c01659 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png.meta new file mode 100644 index 0000000..3f67926 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_58.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 85a45a6d8b2ffb84987d2b028ecfb220 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png new file mode 100644 index 0000000..805a44e Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png.meta new file mode 100644 index 0000000..0c184ba --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_59.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: d96974690c77f50489eb60ec84bd8dac +timeCreated: 1485107929 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png new file mode 100644 index 0000000..326b1d3 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png.meta new file mode 100644 index 0000000..9b2fbd1 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_6.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 79b86f3419b87f3429164a956da8cfab +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png new file mode 100644 index 0000000..5307242 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png.meta new file mode 100644 index 0000000..b5b66af --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_60.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 404fa8def46b1c447817e1ebdaa7144e +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png new file mode 100644 index 0000000..623794c Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png.meta new file mode 100644 index 0000000..4b92f40 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_61.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 119591e0bb084e848835d237546b3882 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png new file mode 100644 index 0000000..d4b4f70 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png.meta new file mode 100644 index 0000000..5a8b32a --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_62.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: a03c400b0e3959f428ee99dfc6cfc263 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png new file mode 100644 index 0000000..1746cc1 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png.meta new file mode 100644 index 0000000..92c4160 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_63.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 4a11d65ce13d5f542a0ff136cc2f3fba +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png new file mode 100644 index 0000000..0a396d3 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png.meta new file mode 100644 index 0000000..2557bbf --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_7.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 3ac02e7e783571c468f9c086d2384ba7 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png new file mode 100644 index 0000000..0b5d32e Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png.meta new file mode 100644 index 0000000..515707a --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_8.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: c55042318a938344ab23cd7f09dd0076 +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png new file mode 100644 index 0000000..2beb747 Binary files /dev/null and b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png differ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png.meta b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png.meta new file mode 100644 index 0000000..447cd83 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LDR_LLL1_9.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 71583cfd8899717428d5b1a95fa39cda +timeCreated: 1485107928 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: 0 + aniso: -1 + mipBias: -1 + wrapMode: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 2 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 10 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 64 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt b/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt new file mode 100644 index 0000000..661457b --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt @@ -0,0 +1,9 @@ +To the extent possible under law, Christoph Peters has waived all copyright and +related or neighboring rights to the files in this directory and its +subdirectories. This work is published from: Germany. + +The work is made available under the terms of the Creative Commons CC0 Public +Domain Dedication. + +For more information please visit: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt.meta b/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt.meta new file mode 100644 index 0000000..406f923 --- /dev/null +++ b/Assets/PostProcessing/Resources/Bluenoise64/LICENSE.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48ffda675aa0afa4f9eec3a5d5487aeb +timeCreated: 1485181015 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders.meta b/Assets/PostProcessing/Resources/Shaders.meta new file mode 100644 index 0000000..d7992c8 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e039bcc30d13c9341aa224f4e89f21b3 +folderAsset: yes +timeCreated: 1462199729 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/ACES.cginc b/Assets/PostProcessing/Resources/Shaders/ACES.cginc new file mode 100644 index 0000000..fa996b9 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ACES.cginc @@ -0,0 +1,1333 @@ +#ifndef __ACES__ +#define __ACES__ + +/** + * https://github.com/ampas/aces-dev + * + * Academy Color Encoding System (ACES) software and tools are provided by the + * Academy under the following terms and conditions: A worldwide, royalty-free, + * non-exclusive right to copy, modify, create derivatives, and use, in source and + * binary forms, is hereby granted, subject to acceptance of this license. + * + * Copyright 2015 Academy of Motion Picture Arts and Sciences (A.M.P.A.S.). + * Portions contributed by others as indicated. All rights reserved. + * + * Performance of any of the aforementioned acts indicates acceptance to be bound + * by the following terms and conditions: + * + * * Copies of source code, in whole or in part, must retain the above copyright + * notice, this list of conditions and the Disclaimer of Warranty. + * + * * Use in binary form must retain the above copyright notice, this list of + * conditions and the Disclaimer of Warranty in the documentation and/or other + * materials provided with the distribution. + * + * * Nothing in this license shall be deemed to grant any rights to trademarks, + * copyrights, patents, trade secrets or any other intellectual property of + * A.M.P.A.S. or any contributors, except as expressly stated herein. + * + * * Neither the name "A.M.P.A.S." nor the name of any other contributors to this + * software may be used to endorse or promote products derivative of or based on + * this software without express prior written permission of A.M.P.A.S. or the + * contributors, as appropriate. + * + * This license shall be construed pursuant to the laws of the State of + * California, and any disputes related thereto shall be subject to the + * jurisdiction of the courts therein. + * + * Disclaimer of Warranty: THIS SOFTWARE IS PROVIDED BY A.M.P.A.S. AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL A.M.P.A.S., OR ANY + * CONTRIBUTORS OR DISTRIBUTORS, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, RESITUTIONARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE ACADEMY SPECIFICALLY + * DISCLAIMS ANY REPRESENTATIONS OR WARRANTIES WHATSOEVER RELATED TO PATENT OR + * OTHER INTELLECTUAL PROPERTY RIGHTS IN THE ACADEMY COLOR ENCODING SYSTEM, OR + * APPLICATIONS THEREOF, HELD BY PARTIES OTHER THAN A.M.P.A.S.,WHETHER DISCLOSED OR + * UNDISCLOSED. + */ + +//#define CUSTOM_WHITE_POINT + +/* + Basic usage : + + half4 color = tex2D(_MainTex, i.uv); + half3 aces = unity_to_ACES(color.rgb); + half3 oces = RRT(aces); + half3 odt = ODT_RGBmonitor_100nits_dim(oces); + return half4(odt, color.a); + + If you want to customize the white point, uncomment the previous define and set uniforms accordingly: + + float whitePoint = 48f; // Default ACES value + material.SetFloat("CINEMA_WHITE", whitePoint); + material.SetFloat("CINEMA_DARK", whitePoint / 2400f); + */ + +#include "Common.cginc" + +#define ACEScc_MAX 1.4679964 +#define ACEScc_MIDGRAY 0.4135884 + +// +// Precomputed matrices (pre-transposed) +// See https://github.com/ampas/aces-dev/blob/master/transforms/ctl/README-MATRIX.md +// +static const half3x3 sRGB_2_AP0 = { + 0.4397010, 0.3829780, 0.1773350, + 0.0897923, 0.8134230, 0.0967616, + 0.0175440, 0.1115440, 0.8707040 +}; + +static const half3x3 sRGB_2_AP1 = { + 0.61319, 0.33951, 0.04737, + 0.07021, 0.91634, 0.01345, + 0.02062, 0.10957, 0.86961 +}; + +static const half3x3 AP0_2_sRGB = { + 2.52169, -1.13413, -0.38756, + -0.27648, 1.37272, -0.09624, + -0.01538, -0.15298, 1.16835, +}; + +static const half3x3 AP1_2_sRGB = { + 1.70505, -0.62179, -0.08326, + -0.13026, 1.14080, -0.01055, + -0.02400, -0.12897, 1.15297, +}; + +static const half3x3 AP0_2_AP1_MAT = { + 1.4514393161, -0.2365107469, -0.2149285693, + -0.0765537734, 1.1762296998, -0.0996759264, + 0.0083161484, -0.0060324498, 0.9977163014 +}; + +static const half3x3 AP1_2_AP0_MAT = { + 0.6954522414, 0.1406786965, 0.1638690622, + 0.0447945634, 0.8596711185, 0.0955343182, + -0.0055258826, 0.0040252103, 1.0015006723 +}; + +static const half3x3 AP1_2_XYZ_MAT = { + 0.6624541811, 0.1340042065, 0.1561876870, + 0.2722287168, 0.6740817658, 0.0536895174, + -0.0055746495, 0.0040607335, 1.0103391003 +}; + +static const half3x3 XYZ_2_AP1_MAT = { + 1.6410233797, -0.3248032942, -0.2364246952, + -0.6636628587, 1.6153315917, 0.0167563477, + 0.0117218943, -0.0082844420, 0.9883948585 +}; + +static const half3x3 XYZ_2_REC709_MAT = { + 3.2409699419, -1.5373831776, -0.4986107603, + -0.9692436363, 1.8759675015, 0.0415550574, + 0.0556300797, -0.2039769589, 1.0569715142 +}; + +static const half3x3 XYZ_2_REC2020_MAT = { + 1.7166511880, -0.3556707838, -0.2533662814, + -0.6666843518, 1.6164812366, 0.0157685458, + 0.0176398574, -0.0427706133, 0.9421031212 +}; + +static const half3x3 XYZ_2_DCIP3_MAT = { + 2.7253940305, -1.0180030062, -0.4401631952, + -0.7951680258, 1.6897320548, 0.0226471906, + 0.0412418914, -0.0876390192, 1.1009293786 +}; + +static const half3 AP1_RGB2Y = half3(0.272229, 0.674082, 0.0536895); + +static const half3x3 RRT_SAT_MAT = { + 0.9708890, 0.0269633, 0.00214758, + 0.0108892, 0.9869630, 0.00214758, + 0.0108892, 0.0269633, 0.96214800 +}; + +static const half3x3 ODT_SAT_MAT = { + 0.949056, 0.0471857, 0.00375827, + 0.019056, 0.9771860, 0.00375827, + 0.019056, 0.0471857, 0.93375800 +}; + +static const half3x3 D60_2_D65_CAT = { + 0.98722400, -0.00611327, 0.0159533, + -0.00759836, 1.00186000, 0.0053302, + 0.00307257, -0.00509595, 1.0816800 +}; + +// +// Unity to ACES +// +// converts Unity raw (sRGB primaries) to +// ACES2065-1 (AP0 w/ linear encoding) +// +half3 unity_to_ACES(half3 x) +{ + x = mul(sRGB_2_AP0, x); + return x; +} + +// +// ACES to Unity +// +// converts ACES2065-1 (AP0 w/ linear encoding) +// Unity raw (sRGB primaries) to +// +half3 ACES_to_unity(half3 x) +{ + x = mul(AP0_2_sRGB, x); + return x; +} + +// +// Unity to ACEScg +// +// converts Unity raw (sRGB primaries) to +// ACEScg (AP1 w/ linear encoding) +// +half3 unity_to_ACEScg(half3 x) +{ + x = mul(sRGB_2_AP1, x); + return x; +} + +// +// ACEScg to Unity +// +// converts ACEScg (AP1 w/ linear encoding) to +// Unity raw (sRGB primaries) +// +half3 ACEScg_to_unity(half3 x) +{ + x = mul(AP1_2_sRGB, x); + return x; +} + +// +// ACES Color Space Conversion - ACES to ACEScc +// +// converts ACES2065-1 (AP0 w/ linear encoding) to +// ACEScc (AP1 w/ logarithmic encoding) +// +// This transform follows the formulas from section 4.4 in S-2014-003 +// +half ACES_to_ACEScc(half x) +{ + if (x <= 0.0) + return -0.35828683; // = (log2(pow(2.0, -15.0) * 0.5) + 9.72) / 17.52 + else if (x < pow(2.0, -15.0)) + return (log2(pow(2.0, -16.0) + x * 0.5) + 9.72) / 17.52; + else // (x >= pow(2.0, -15.0)) + return (log2(x) + 9.72) / 17.52; +} + +half3 ACES_to_ACEScc(half3 x) +{ + x = clamp(x, 0.0, HALF_MAX); + + // x is clamped to [0, HALF_MAX], skip the <= 0 check + return (x < 0.00003051757) ? (log2(0.00001525878 + x * 0.5) + 9.72) / 17.52 : (log2(x) + 9.72) / 17.52; + + /* + return half3( + ACES_to_ACEScc(x.r), + ACES_to_ACEScc(x.g), + ACES_to_ACEScc(x.b) + ); + */ +} + +// +// ACES Color Space Conversion - ACEScc to ACES +// +// converts ACEScc (AP1 w/ ACESlog encoding) to +// ACES2065-1 (AP0 w/ linear encoding) +// +// This transform follows the formulas from section 4.4 in S-2014-003 +// +half ACEScc_to_ACES(half x) +{ + // TODO: Optimize me + if (x < -0.3013698630) // (9.72 - 15) / 17.52 + return (pow(2.0, x * 17.52 - 9.72) - pow(2.0, -16.0)) * 2.0; + else if (x < (log2(HALF_MAX) + 9.72) / 17.52) + return pow(2.0, x * 17.52 - 9.72); + else // (x >= (log2(HALF_MAX) + 9.72) / 17.52) + return HALF_MAX; +} + +half3 ACEScc_to_ACES(half3 x) +{ + return half3( + ACEScc_to_ACES(x.r), + ACEScc_to_ACES(x.g), + ACEScc_to_ACES(x.b) + ); +} + +// +// ACES Color Space Conversion - ACES to ACEScg +// +// converts ACES2065-1 (AP0 w/ linear encoding) to +// ACEScg (AP1 w/ linear encoding) +// +half3 ACES_to_ACEScg(half3 x) +{ + return mul(AP0_2_AP1_MAT, x); +} + +// +// ACES Color Space Conversion - ACEScg to ACES +// +// converts ACEScg (AP1 w/ linear encoding) to +// ACES2065-1 (AP0 w/ linear encoding) +// +half3 ACEScg_to_ACES(half3 x) +{ + return mul(AP1_2_AP0_MAT, x); +} + +// +// Reference Rendering Transform (RRT) +// +// Input is ACES +// Output is OCES +// +half rgb_2_saturation(half3 rgb) +{ + const half TINY = 1e-10; + half mi = Min3(rgb); + half ma = Max3(rgb); + return (max(ma, TINY) - max(mi, TINY)) / max(ma, 1e-2); +} + +half rgb_2_yc(half3 rgb) +{ + const half ycRadiusWeight = 1.75; + + // Converts RGB to a luminance proxy, here called YC + // YC is ~ Y + K * Chroma + // Constant YC is a cone-shaped surface in RGB space, with the tip on the + // neutral axis, towards white. + // YC is normalized: RGB 1 1 1 maps to YC = 1 + // + // ycRadiusWeight defaults to 1.75, although can be overridden in function + // call to rgb_2_yc + // ycRadiusWeight = 1 -> YC for pure cyan, magenta, yellow == YC for neutral + // of same value + // ycRadiusWeight = 2 -> YC for pure red, green, blue == YC for neutral of + // same value. + + half r = rgb.x; + half g = rgb.y; + half b = rgb.z; + half chroma = sqrt(b * (b - g) + g * (g - r) + r * (r - b)); + return (b + g + r + ycRadiusWeight * chroma) / 3.0; +} + +half rgb_2_hue(half3 rgb) +{ + // Returns a geometric hue angle in degrees (0-360) based on RGB values. + // For neutral colors, hue is undefined and the function will return a quiet NaN value. + half hue; + if (rgb.x == rgb.y && rgb.y == rgb.z) + hue = 0.0; // RGB triplets where RGB are equal have an undefined hue + else + hue = (180.0 / UNITY_PI) * atan2(sqrt(3.0) * (rgb.y - rgb.z), 2.0 * rgb.x - rgb.y - rgb.z); + + if (hue < 0.0) hue = hue + 360.0; + + return hue; +} + +half center_hue(half hue, half centerH) +{ + half hueCentered = hue - centerH; + if (hueCentered < -180.0) hueCentered = hueCentered + 360.0; + else if (hueCentered > 180.0) hueCentered = hueCentered - 360.0; + return hueCentered; +} + +half sigmoid_shaper(half x) +{ + // Sigmoid function in the range 0 to 1 spanning -2 to +2. + + half t = max(1.0 - abs(x / 2.0), 0.0); + half y = 1.0 + sign(x) * (1.0 - t * t); + + return y / 2.0; +} + +half glow_fwd(half ycIn, half glowGainIn, half glowMid) +{ + half glowGainOut; + + if (ycIn <= 2.0 / 3.0 * glowMid) + glowGainOut = glowGainIn; + else if (ycIn >= 2.0 * glowMid) + glowGainOut = 0.0; + else + glowGainOut = glowGainIn * (glowMid / ycIn - 1.0 / 2.0); + + return glowGainOut; +} + +/* +half cubic_basis_shaper +( + half x, + half w // full base width of the shaper function (in degrees) +) +{ + half M[4][4] = { + { -1.0 / 6, 3.0 / 6, -3.0 / 6, 1.0 / 6 }, + { 3.0 / 6, -6.0 / 6, 3.0 / 6, 0.0 / 6 }, + { -3.0 / 6, 0.0 / 6, 3.0 / 6, 0.0 / 6 }, + { 1.0 / 6, 4.0 / 6, 1.0 / 6, 0.0 / 6 } + }; + + half knots[5] = { + -w / 2.0, + -w / 4.0, + 0.0, + w / 4.0, + w / 2.0 + }; + + half y = 0.0; + if ((x > knots[0]) && (x < knots[4])) + { + half knot_coord = (x - knots[0]) * 4.0 / w; + int j = knot_coord; + half t = knot_coord - j; + + half monomials[4] = { t*t*t, t*t, t, 1.0 }; + + // (if/else structure required for compatibility with CTL < v1.5.) + if (j == 3) + { + y = monomials[0] * M[0][0] + monomials[1] * M[1][0] + + monomials[2] * M[2][0] + monomials[3] * M[3][0]; + } + else if (j == 2) + { + y = monomials[0] * M[0][1] + monomials[1] * M[1][1] + + monomials[2] * M[2][1] + monomials[3] * M[3][1]; + } + else if (j == 1) + { + y = monomials[0] * M[0][2] + monomials[1] * M[1][2] + + monomials[2] * M[2][2] + monomials[3] * M[3][2]; + } + else if (j == 0) + { + y = monomials[0] * M[0][3] + monomials[1] * M[1][3] + + monomials[2] * M[2][3] + monomials[3] * M[3][3]; + } + else + { + y = 0.0; + } + } + + return y * 3.0 / 2.0; +} +*/ + +static const half3x3 M = { + 0.5, -1.0, 0.5, + -1.0, 1.0, 0.0, + 0.5, 0.5, 0.0 +}; + +half segmented_spline_c5_fwd(half x) +{ + const half coefsLow[6] = { -4.0000000000, -4.0000000000, -3.1573765773, -0.4852499958, 1.8477324706, 1.8477324706 }; // coefs for B-spline between minPoint and midPoint (units of log luminance) + const half coefsHigh[6] = { -0.7185482425, 2.0810307172, 3.6681241237, 4.0000000000, 4.0000000000, 4.0000000000 }; // coefs for B-spline between midPoint and maxPoint (units of log luminance) + const half2 minPoint = half2(0.18 * exp2(-15.0), 0.0001); // {luminance, luminance} linear extension below this + const half2 midPoint = half2(0.18, 0.48); // {luminance, luminance} + const half2 maxPoint = half2(0.18 * exp2(18.0), 10000.0); // {luminance, luminance} linear extension above this + const half slopeLow = 0.0; // log-log slope of low linear extension + const half slopeHigh = 0.0; // log-log slope of high linear extension + + const int N_KNOTS_LOW = 4; + const int N_KNOTS_HIGH = 4; + + // Check for negatives or zero before taking the log. If negative or zero, + // set to ACESMIN.1 + float xCheck = x; + if (xCheck <= 0.0) xCheck = 0.00006103515; // = pow(2.0, -14.0); + + half logx = log10(xCheck); + half logy; + + if (logx <= log10(minPoint.x)) + { + logy = logx * slopeLow + (log10(minPoint.y) - slopeLow * log10(minPoint.x)); + } + else if ((logx > log10(minPoint.x)) && (logx < log10(midPoint.x))) + { + half knot_coord = (N_KNOTS_LOW - 1) * (logx - log10(minPoint.x)) / (log10(midPoint.x) - log10(minPoint.x)); + int j = knot_coord; + half t = knot_coord - j; + + half3 cf = half3(coefsLow[j], coefsLow[j + 1], coefsLow[j + 2]); + half3 monomials = half3(t * t, t, 1.0); + logy = dot(monomials, mul(M, cf)); + } + else if ((logx >= log10(midPoint.x)) && (logx < log10(maxPoint.x))) + { + half knot_coord = (N_KNOTS_HIGH - 1) * (logx - log10(midPoint.x)) / (log10(maxPoint.x) - log10(midPoint.x)); + int j = knot_coord; + half t = knot_coord - j; + + half3 cf = half3(coefsHigh[j], coefsHigh[j + 1], coefsHigh[j + 2]); + half3 monomials = half3(t * t, t, 1.0); + logy = dot(monomials, mul(M, cf)); + } + else + { //if (logIn >= log10(maxPoint.x)) { + logy = logx * slopeHigh + (log10(maxPoint.y) - slopeHigh * log10(maxPoint.x)); + } + + return pow(10.0, logy); +} + +half segmented_spline_c9_fwd(half x) +{ + const half coefsLow[10] = { -1.6989700043, -1.6989700043, -1.4779000000, -1.2291000000, -0.8648000000, -0.4480000000, 0.0051800000, 0.4511080334, 0.9113744414, 0.9113744414 }; // coefs for B-spline between minPoint and midPoint (units of log luminance) + const half coefsHigh[10] = { 0.5154386965, 0.8470437783, 1.1358000000, 1.3802000000, 1.5197000000, 1.5985000000, 1.6467000000, 1.6746091357, 1.6878733390, 1.6878733390 }; // coefs for B-spline between midPoint and maxPoint (units of log luminance) + const half2 minPoint = half2(segmented_spline_c5_fwd(0.18 * exp2(-6.5)), 0.02); // {luminance, luminance} linear extension below this + const half2 midPoint = half2(segmented_spline_c5_fwd(0.18), 4.8); // {luminance, luminance} + const half2 maxPoint = half2(segmented_spline_c5_fwd(0.18 * exp2(6.5)), 48.0); // {luminance, luminance} linear extension above this + const half slopeLow = 0.0; // log-log slope of low linear extension + const half slopeHigh = 0.04; // log-log slope of high linear extension + + const int N_KNOTS_LOW = 8; + const int N_KNOTS_HIGH = 8; + + // Check for negatives or zero before taking the log. If negative or zero, + // set to OCESMIN. + half xCheck = x; + if (xCheck <= 0.0) xCheck = 1e-4; + + half logx = log10(xCheck); + half logy; + + if (logx <= log10(minPoint.x)) + { + logy = logx * slopeLow + (log10(minPoint.y) - slopeLow * log10(minPoint.x)); + } + else if ((logx > log10(minPoint.x)) && (logx < log10(midPoint.x))) + { + half knot_coord = (N_KNOTS_LOW - 1) * (logx - log10(minPoint.x)) / (log10(midPoint.x) - log10(minPoint.x)); + int j = knot_coord; + half t = knot_coord - j; + + half3 cf = half3(coefsLow[j], coefsLow[j + 1], coefsLow[j + 2]); + half3 monomials = half3(t * t, t, 1.0); + logy = dot(monomials, mul(M, cf)); + } + else if ((logx >= log10(midPoint.x)) && (logx < log10(maxPoint.x))) + { + half knot_coord = (N_KNOTS_HIGH - 1) * (logx - log10(midPoint.x)) / (log10(maxPoint.x) - log10(midPoint.x)); + int j = knot_coord; + half t = knot_coord - j; + + half3 cf = half3(coefsHigh[j], coefsHigh[j + 1], coefsHigh[j + 2]); + half3 monomials = half3(t * t, t, 1.0); + logy = dot(monomials, mul(M, cf)); + } + else + { //if (logIn >= log10(maxPoint.x)) { + logy = logx * slopeHigh + (log10(maxPoint.y) - slopeHigh * log10(maxPoint.x)); + } + + return pow(10.0, logy); +} + +static const half RRT_GLOW_GAIN = 0.05; +static const half RRT_GLOW_MID = 0.08; + +static const half RRT_RED_SCALE = 0.82; +static const half RRT_RED_PIVOT = 0.03; +static const half RRT_RED_HUE = 0.0; +static const half RRT_RED_WIDTH = 135.0; + +static const half RRT_SAT_FACTOR = 0.96; + +half3 RRT(half3 aces) +{ + // --- Glow module --- // + half saturation = rgb_2_saturation(aces); + half ycIn = rgb_2_yc(aces); + half s = sigmoid_shaper((saturation - 0.4) / 0.2); + half addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID); + aces *= addedGlow; + + // --- Red modifier --- // + half hue = rgb_2_hue(aces); + half centeredHue = center_hue(hue, RRT_RED_HUE); + half hueWeight; + { + //hueWeight = cubic_basis_shaper(centeredHue, RRT_RED_WIDTH); + hueWeight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH)); + hueWeight *= hueWeight; + } + + aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE); + + // --- ACES to RGB rendering space --- // + aces = clamp(aces, 0.0, HALF_MAX); // avoids saturated negative colors from becoming positive in the matrix + half3 rgbPre = mul(AP0_2_AP1_MAT, aces); + rgbPre = clamp(rgbPre, 0, HALF_MAX); + + // --- Global desaturation --- // + //rgbPre = mul(RRT_SAT_MAT, rgbPre); + rgbPre = lerp(dot(rgbPre, AP1_RGB2Y).xxx, rgbPre, RRT_SAT_FACTOR.xxx); + + // --- Apply the tonescale independently in rendering-space RGB --- // + half3 rgbPost; + rgbPost.x = segmented_spline_c5_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c5_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c5_fwd(rgbPre.z); + + // --- RGB rendering space to OCES --- // + half3 rgbOces = mul(AP1_2_AP0_MAT, rgbPost); + + return rgbOces; +} + +// +// Output Device Transform +// +half3 Y_2_linCV(half3 Y, half Ymax, half Ymin) +{ + return (Y - Ymin) / (Ymax - Ymin); +} + +half3 XYZ_2_xyY(half3 XYZ) +{ + half divisor = max(dot(XYZ, (1.0).xxx), 1e-4); + return half3(XYZ.xy / divisor, XYZ.y); +} + +half3 xyY_2_XYZ(half3 xyY) +{ + half m = xyY.z / max(xyY.y, 1e-4); + half3 XYZ = half3(xyY.xz, (1.0 - xyY.x - xyY.y)); + XYZ.xz *= m; + return XYZ; +} + +static const half DIM_SURROUND_GAMMA = 0.9811; + +half3 darkSurround_to_dimSurround(half3 linearCV) +{ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + half3 xyY = XYZ_2_xyY(XYZ); + xyY.z = clamp(xyY.z, 0.0, HALF_MAX); + xyY.z = pow(xyY.z, DIM_SURROUND_GAMMA); + XYZ = xyY_2_XYZ(xyY); + + return mul(XYZ_2_AP1_MAT, XYZ); +} + +half moncurve_r(half y, half gamma, half offs) +{ + // Reverse monitor curve + half x; + const half yb = pow(offs * gamma / ((gamma - 1.0) * (1.0 + offs)), gamma); + const half rs = pow((gamma - 1.0) / offs, gamma - 1.0) * pow((1.0 + offs) / gamma, gamma); + if (y >= yb) + x = (1.0 + offs) * pow(y, 1.0 / gamma) - offs; + else + x = y * rs; + return x; +} + +half bt1886_r(half L, half gamma, half Lw, half Lb) +{ + // The reference EOTF specified in Rec. ITU-R BT.1886 + // L = a(max[(V+b),0])^g + half a = pow(pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma), gamma); + half b = pow(Lb, 1.0 / gamma) / (pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma)); + half V = pow(max(L / a, 0.0), 1.0 / gamma) - b; + return V; +} + +half roll_white_fwd( + half x, // color value to adjust (white scaled to around 1.0) + half new_wht, // white adjustment (e.g. 0.9 for 10% darkening) + half width // adjusted width (e.g. 0.25 for top quarter of the tone scale) + ) +{ + const half x0 = -1.0; + const half x1 = x0 + width; + const half y0 = -new_wht; + const half y1 = x1; + const half m1 = (x1 - x0); + const half a = y0 - y1 + m1; + const half b = 2.0 * (y1 - y0) - m1; + const half c = y0; + const half t = (-x - x0) / (x1 - x0); + half o = 0.0; + if (t < 0.0) + o = -(t * b + c); + else if (t > 1.0) + o = x; + else + o = -((t * a + b) * t + c); + return o; +} + +half3 linear_to_sRGB(half3 x) +{ + return (x <= 0.0031308 ? (x * 12.9232102) : 1.055 * pow(x, 1.0 / 2.4) - 0.055); +} + +half3 linear_to_bt1886(half3 x, half gamma, half Lw, half Lb) +{ + // Good enough approximation for now, may consider using the exact formula instead + // TODO: Experiment + return pow(max(x, 0.0), 1.0 / 2.4); + + // Correct implementation (Reference EOTF specified in Rec. ITU-R BT.1886) : + // L = a(max[(V+b),0])^g + half invgamma = 1.0 / gamma; + half p_Lw = pow(Lw, invgamma); + half p_Lb = pow(Lb, invgamma); + half3 a = pow(p_Lw - p_Lb, gamma).xxx; + half3 b = (p_Lb / p_Lw - p_Lb).xxx; + half3 V = pow(max(x / a, 0.0), invgamma.xxx) - b; + return V; +} + +#if defined(CUSTOM_WHITE_POINT) +half CINEMA_WHITE; +half CINEMA_BLACK; +#else +static const half CINEMA_WHITE = 48.0; +static const half CINEMA_BLACK = CINEMA_WHITE / 2400.0; +#endif + +static const half ODT_SAT_FACTOR = 0.93; + +// ODT.Academy.RGBmonitor_100nits_dim.a1.0.3 +// ACES 1.0 Output - sRGB + +// +// Output Device Transform - RGB computer monitor +// + +// +// Summary : +// This transform is intended for mapping OCES onto a desktop computer monitor +// typical of those used in motion picture visual effects production. These +// monitors may occasionally be referred to as "sRGB" displays, however, the +// monitor for which this transform is designed does not exactly match the +// specifications in IEC 61966-2-1:1999. +// +// The assumed observer adapted white is D65, and the viewing environment is +// that of a dim surround. +// +// The monitor specified is intended to be more typical of those found in +// visual effects production. +// +// Device Primaries : +// Primaries are those specified in Rec. ITU-R BT.709 +// CIE 1931 chromaticities: x y Y +// Red: 0.64 0.33 +// Green: 0.3 0.6 +// Blue: 0.15 0.06 +// White: 0.3127 0.329 100 cd/m^2 +// +// Display EOTF : +// The reference electro-optical transfer function specified in +// IEC 61966-2-1:1999. +// +// Signal Range: +// This transform outputs full range code values. +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.3127 0.329 +// +// Viewing Environment: +// This ODT has a compensation for viewing environment variables more typical +// of those associated with video mastering. +// +half3 ODT_RGBmonitor_100nits_dim(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // Apply gamma adjustment to compensate for dim surround + linearCV = darkSurround_to_dimSurround(linearCV); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, linearCV); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // Apply CAT from ACES white point to assumed observer adapted white point + XYZ = mul(D60_2_D65_CAT, XYZ); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC709_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // TODO: Revisit when it is possible to deactivate Unity default framebuffer encoding + // with sRGB opto-electrical transfer function (OETF). + /* + // Encode linear code values with transfer function + half3 outputCV; + // moncurve_r with gamma of 2.4 and offset of 0.055 matches the EOTF found in IEC 61966-2-1:1999 (sRGB) + const half DISPGAMMA = 2.4; + const half OFFSET = 0.055; + outputCV.x = moncurve_r(linearCV.x, DISPGAMMA, OFFSET); + outputCV.y = moncurve_r(linearCV.y, DISPGAMMA, OFFSET); + outputCV.z = moncurve_r(linearCV.z, DISPGAMMA, OFFSET); + + outputCV = linear_to_sRGB(linearCV); + */ + + // Unity already draws to a sRGB target + return linearCV; +} + +// ODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 +// ACES 1.0 Output - sRGB (D60 sim.) + +// +// Output Device Transform - RGB computer monitor (D60 simulation) +// + +// +// Summary : +// This transform is intended for mapping OCES onto a desktop computer monitor +// typical of those used in motion picture visual effects production. These +// monitors may occasionally be referred to as "sRGB" displays, however, the +// monitor for which this transform is designed does not exactly match the +// specifications in IEC 61966-2-1:1999. +// +// The assumed observer adapted white is D60, and the viewing environment is +// that of a dim surround. +// +// The monitor specified is intended to be more typical of those found in +// visual effects production. +// +// Device Primaries : +// Primaries are those specified in Rec. ITU-R BT.709 +// CIE 1931 chromaticities: x y Y +// Red: 0.64 0.33 +// Green: 0.3 0.6 +// Blue: 0.15 0.06 +// White: 0.3127 0.329 100 cd/m^2 +// +// Display EOTF : +// The reference electro-optical transfer function specified in +// IEC 61966-2-1:1999. +// +// Signal Range: +// This transform outputs full range code values. +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.32168 0.33767 +// +// Viewing Environment: +// This ODT has a compensation for viewing environment variables more typical +// of those associated with video mastering. +// +half3 ODT_RGBmonitor_D60sim_100nits_dim(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // --- Compensate for different white point being darker --- // + // This adjustment is to correct an issue that exists in ODTs where the device + // is calibrated to a white chromaticity other than D60. In order to simulate + // D60 on such devices, unequal code values are sent to the display to achieve + // neutrals at D60. In order to produce D60 on a device calibrated to the DCI + // white point (i.e. equal code values yield CIE x,y chromaticities of 0.314, + // 0.351) the red channel is higher than green and blue to compensate for the + // "greenish" DCI white. This is the correct behavior but it means that as + // highlight increase, the red channel will hit the device maximum first and + // clip, resulting in a chromaticity shift as the green and blue channels + // continue to increase. + // To avoid this clipping error, a slight scale factor is applied to allow the + // ODTs to simulate D60 within the D65 calibration white point. + + // Scale and clamp white to avoid casted highlights due to D60 simulation + const half SCALE = 0.955; + linearCV = min(linearCV, 1.0) * SCALE; + + // Apply gamma adjustment to compensate for dim surround + linearCV = darkSurround_to_dimSurround(linearCV); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, linearCV); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC709_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // TODO: Revisit when it is possible to deactivate Unity default framebuffer encoding + // with sRGB opto-electrical transfer function (OETF). + /* + // Encode linear code values with transfer function + half3 outputCV; + // moncurve_r with gamma of 2.4 and offset of 0.055 matches the EOTF found in IEC 61966-2-1:1999 (sRGB) + const half DISPGAMMA = 2.4; + const half OFFSET = 0.055; + outputCV.x = moncurve_r(linearCV.x, DISPGAMMA, OFFSET); + outputCV.y = moncurve_r(linearCV.y, DISPGAMMA, OFFSET); + outputCV.z = moncurve_r(linearCV.z, DISPGAMMA, OFFSET); + + outputCV = linear_to_sRGB(linearCV); + */ + + // Unity already draws to a sRGB target + return linearCV; +} + +// ODT.Academy.Rec709_100nits_dim.a1.0.3 +// ACES 1.0 Output - Rec.709 + +// +// Output Device Transform - Rec709 +// + +// +// Summary : +// This transform is intended for mapping OCES onto a Rec.709 broadcast monitor +// that is calibrated to a D65 white point at 100 cd/m^2. The assumed observer +// adapted white is D65, and the viewing environment is a dim surround. +// +// A possible use case for this transform would be HDTV/video mastering. +// +// Device Primaries : +// Primaries are those specified in Rec. ITU-R BT.709 +// CIE 1931 chromaticities: x y Y +// Red: 0.64 0.33 +// Green: 0.3 0.6 +// Blue: 0.15 0.06 +// White: 0.3127 0.329 100 cd/m^2 +// +// Display EOTF : +// The reference electro-optical transfer function specified in +// Rec. ITU-R BT.1886. +// +// Signal Range: +// By default, this transform outputs full range code values. If instead a +// SMPTE "legal" signal is desired, there is a runtime flag to output +// SMPTE legal signal. In ctlrender, this can be achieved by appending +// '-param1 legalRange 1' after the '-ctl odt.ctl' string. +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.3127 0.329 +// +// Viewing Environment: +// This ODT has a compensation for viewing environment variables more typical +// of those associated with video mastering. +// +half3 ODT_Rec709_100nits_dim(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // Apply gamma adjustment to compensate for dim surround + linearCV = darkSurround_to_dimSurround(linearCV); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, linearCV); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // Apply CAT from ACES white point to assumed observer adapted white point + XYZ = mul(D60_2_D65_CAT, XYZ); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC709_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // Encode linear code values with transfer function + const half DISPGAMMA = 2.4; + const half L_W = 1.0; + const half L_B = 0.0; + half3 outputCV = linear_to_bt1886(linearCV, DISPGAMMA, L_W, L_B); + + // TODO: Implement support for legal range. + + // NOTE: Unity framebuffer encoding is encoded with sRGB opto-electrical transfer function (OETF) + // by default which will result in double perceptual encoding, thus for now if one want to use + // this ODT, he needs to decode its output with sRGB electro-optical transfer function (EOTF) to + // compensate for Unity default behaviour. + + return outputCV; +} + +// ODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 +// ACES 1.0 Output - Rec.709 (D60 sim.) + +// +// Output Device Transform - Rec709 (D60 simulation) +// + +// +// Summary : +// This transform is intended for mapping OCES onto a Rec.709 broadcast monitor +// that is calibrated to a D65 white point at 100 cd/m^2. The assumed observer +// adapted white is D60, and the viewing environment is a dim surround. +// +// A possible use case for this transform would be cinema "soft-proofing". +// +// Device Primaries : +// Primaries are those specified in Rec. ITU-R BT.709 +// CIE 1931 chromaticities: x y Y +// Red: 0.64 0.33 +// Green: 0.3 0.6 +// Blue: 0.15 0.06 +// White: 0.3127 0.329 100 cd/m^2 +// +// Display EOTF : +// The reference electro-optical transfer function specified in +// Rec. ITU-R BT.1886. +// +// Signal Range: +// By default, this transform outputs full range code values. If instead a +// SMPTE "legal" signal is desired, there is a runtime flag to output +// SMPTE legal signal. In ctlrender, this can be achieved by appending +// '-param1 legalRange 1' after the '-ctl odt.ctl' string. +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.32168 0.33767 +// +// Viewing Environment: +// This ODT has a compensation for viewing environment variables more typical +// of those associated with video mastering. +// +half3 ODT_Rec709_D60sim_100nits_dim(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // --- Compensate for different white point being darker --- // + // This adjustment is to correct an issue that exists in ODTs where the device + // is calibrated to a white chromaticity other than D60. In order to simulate + // D60 on such devices, unequal code values must be sent to the display to achieve + // the chromaticities of D60. More specifically, in order to produce D60 on a device + // calibrated to a D65 white point (i.e. equal code values yield CIE x,y + // chromaticities of 0.3127, 0.329) the red channel must be slightly higher than + // that of green and blue in order to compensate for the relatively more "blue-ish" + // D65 white. This unequalness of color channels is the correct behavior but it + // means that as neutral highlights increase, the red channel will hit the + // device maximum first and clip, resulting in a small chromaticity shift as the + // green and blue channels continue to increase to their maximums. + // To avoid this clipping error, a slight scale factor is applied to allow the + // ODTs to simulate D60 within the D65 calibration white point. + + // Scale and clamp white to avoid casted highlights due to D60 simulation + const half SCALE = 0.955; + linearCV = min(linearCV, 1.0) * SCALE; + + // Apply gamma adjustment to compensate for dim surround + linearCV = darkSurround_to_dimSurround(linearCV); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, linearCV); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC709_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // Encode linear code values with transfer function + const half DISPGAMMA = 2.4; + const half L_W = 1.0; + const half L_B = 0.0; + half3 outputCV = linear_to_bt1886(linearCV, DISPGAMMA, L_W, L_B); + + // TODO: Implement support for legal range. + + // NOTE: Unity framebuffer encoding is encoded with sRGB opto-electrical transfer function (OETF) + // by default which will result in double perceptual encoding, thus for now if one want to use + // this ODT, he needs to decode its output with sRGB electro-optical transfer function (EOTF) to + // compensate for Unity default behaviour. + + return outputCV; +} + +// ODT.Academy.Rec2020_100nits_dim.a1.0.3 +// ACES 1.0 Output - Rec.2020 + +// +// Output Device Transform - Rec2020 +// + +// +// Summary : +// This transform is intended for mapping OCES onto a Rec.2020 broadcast +// monitor that is calibrated to a D65 white point at 100 cd/m^2. The assumed +// observer adapted white is D65, and the viewing environment is that of a dim +// surround. +// +// A possible use case for this transform would be UHDTV/video mastering. +// +// Device Primaries : +// Primaries are those specified in Rec. ITU-R BT.2020 +// CIE 1931 chromaticities: x y Y +// Red: 0.708 0.292 +// Green: 0.17 0.797 +// Blue: 0.131 0.046 +// White: 0.3127 0.329 100 cd/m^2 +// +// Display EOTF : +// The reference electro-optical transfer function specified in +// Rec. ITU-R BT.1886. +// +// Signal Range: +// By default, this transform outputs full range code values. If instead a +// SMPTE "legal" signal is desired, there is a runtime flag to output +// SMPTE legal signal. In ctlrender, this can be achieved by appending +// '-param1 legalRange 1' after the '-ctl odt.ctl' string. +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.3127 0.329 +// +// Viewing Environment: +// This ODT has a compensation for viewing environment variables more typical +// of those associated with video mastering. +// + +half3 ODT_Rec2020_100nits_dim(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // Apply gamma adjustment to compensate for dim surround + linearCV = darkSurround_to_dimSurround(linearCV); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, linearCV); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // Apply CAT from ACES white point to assumed observer adapted white point + XYZ = mul(D60_2_D65_CAT, XYZ); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC2020_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // Encode linear code values with transfer function + const half DISPGAMMA = 2.4; + const half L_W = 1.0; + const half L_B = 0.0; + half3 outputCV = linear_to_bt1886(linearCV, DISPGAMMA, L_W, L_B); + + // TODO: Implement support for legal range. + + // NOTE: Unity framebuffer encoding is encoded with sRGB opto-electrical transfer function (OETF) + // by default which will result in double perceptual encoding, thus for now if one want to use + // this ODT, he needs to decode its output with sRGB electro-optical transfer function (EOTF) to + // compensate for Unity default behaviour. + + return outputCV; +} + +// ODT.Academy.P3DCI_48nits.a1.0.3 +// ACES 1.0 Output - P3-DCI + +// +// Output Device Transform - P3DCI (D60 Simulation) +// + +// +// Summary : +// This transform is intended for mapping OCES onto a P3 digital cinema +// projector that is calibrated to a DCI white point at 48 cd/m^2. The assumed +// observer adapted white is D60, and the viewing environment is that of a dark +// theater. +// +// Device Primaries : +// CIE 1931 chromaticities: x y Y +// Red: 0.68 0.32 +// Green: 0.265 0.69 +// Blue: 0.15 0.06 +// White: 0.314 0.351 48 cd/m^2 +// +// Display EOTF : +// Gamma: 2.6 +// +// Assumed observer adapted white point: +// CIE 1931 chromaticities: x y +// 0.32168 0.33767 +// +// Viewing Environment: +// Environment specified in SMPTE RP 431-2-2007 +// +half3 ODT_P3DCI_48nits(half3 oces) +{ + // OCES to RGB rendering space + half3 rgbPre = mul(AP0_2_AP1_MAT, oces); + + // Apply the tonescale independently in rendering-space RGB + half3 rgbPost; + rgbPost.x = segmented_spline_c9_fwd(rgbPre.x); + rgbPost.y = segmented_spline_c9_fwd(rgbPre.y); + rgbPost.z = segmented_spline_c9_fwd(rgbPre.z); + + // Scale luminance to linear code value + half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // --- Compensate for different white point being darker --- // + // This adjustment is to correct an issue that exists in ODTs where the device + // is calibrated to a white chromaticity other than D60. In order to simulate + // D60 on such devices, unequal code values are sent to the display to achieve + // neutrals at D60. In order to produce D60 on a device calibrated to the DCI + // white point (i.e. equal code values yield CIE x,y chromaticities of 0.314, + // 0.351) the red channel is higher than green and blue to compensate for the + // "greenish" DCI white. This is the correct behavior but it means that as + // highlight increase, the red channel will hit the device maximum first and + // clip, resulting in a chromaticity shift as the green and blue channels + // continue to increase. + // To avoid this clipping error, a slight scale factor is applied to allow the + // ODTs to simulate D60 within the D65 calibration white point. However, the + // magnitude of the scale factor required for the P3DCI ODT was considered too + // large. Therefore, the scale factor was reduced and the additional required + // compression was achieved via a reshaping of the highlight rolloff in + // conjunction with the scale. The shape of this rolloff was determined + // throught subjective experiments and deemed to best reproduce the + // "character" of the highlights in the P3D60 ODT. + + // Roll off highlights to avoid need for as much scaling + const half NEW_WHT = 0.918; + const half ROLL_WIDTH = 0.5; + linearCV.x = roll_white_fwd(linearCV.x, NEW_WHT, ROLL_WIDTH); + linearCV.y = roll_white_fwd(linearCV.y, NEW_WHT, ROLL_WIDTH); + linearCV.z = roll_white_fwd(linearCV.z, NEW_WHT, ROLL_WIDTH); + + // Scale and clamp white to avoid casted highlights due to D60 simulation + const half SCALE = 0.96; + linearCV = min(linearCV, NEW_WHT) * SCALE; + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_DCIP3_MAT, XYZ); + + // Handle out-of-gamut values + // Clip values < 0 or > 1 (i.e. projecting outside the display primaries) + linearCV = saturate(linearCV); + + // Encode linear code values with transfer function + const half DISPGAMMA = 2.6; + half3 outputCV = pow(linearCV, 1.0 / DISPGAMMA); + + // NOTE: Unity framebuffer encoding is encoded with sRGB opto-electrical transfer function (OETF) + // by default which will result in double perceptual encoding, thus for now if one want to use + // this ODT, he needs to decode its output with sRGB electro-optical transfer function (EOTF) to + // compensate for Unity default behaviour. + + return outputCV; +} + +#endif // __ACES__ diff --git a/Assets/PostProcessing/Resources/Shaders/ACES.cginc.meta b/Assets/PostProcessing/Resources/Shaders/ACES.cginc.meta new file mode 100644 index 0000000..3e3471e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ACES.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b8d56fc3449f426408c23c723b58d7b5 +timeCreated: 1460363486 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc new file mode 100644 index 0000000..5a66bc1 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc @@ -0,0 +1,500 @@ +// Upgrade NOTE: commented out 'float4x4 _WorldToCamera', a built-in variable +// Upgrade NOTE: replaced '_WorldToCamera' with 'unity_WorldToCamera' + +#ifndef __AMBIENT_OCCLUSION__ +#define __AMBIENT_OCCLUSION__ + +#include "UnityCG.cginc" +#include "Common.cginc" + +// -------- +// Options for further customization +// -------- + +// By default, a 5-tap Gaussian with the linear sampling technique is used +// in the bilateral noise filter. It can be replaced with a 7-tap Gaussian +// with adaptive sampling by enabling the macro below. Although the +// differences are not noticeable in most cases, it may provide preferable +// results with some special usage (e.g. NPR without textureing). +// #define BLUR_HIGH_QUALITY + +// By default, a fixed sampling pattern is used in the AO estimator. Although +// this gives preferable results in most cases, a completely random sampling +// pattern could give aesthetically better results. Disable the macro below +// to use such a random pattern instead of the fixed one. +#define FIX_SAMPLING_PATTERN + +// The SampleNormal function normalizes samples from G-buffer because +// they're possibly unnormalized. We can eliminate this if it can be said +// that there is no wrong shader that outputs unnormalized normals. +// #define VALIDATE_NORMALS + +// The constant below determines the contrast of occlusion. This allows +// users to control over/under occlusion. At the moment, this is not exposed +// to the editor because it�s rarely useful. +static const float kContrast = 0.6; + +// The constant below controls the geometry-awareness of the bilateral +// filter. The higher value, the more sensitive it is. +static const float kGeometryCoeff = 0.8; + +// The constants below are used in the AO estimator. Beta is mainly used +// for suppressing self-shadowing noise, and Epsilon is used to prevent +// calculation underflow. See the paper (Morgan 2011 http://goo.gl/2iz3P) +// for further details of these constants. +static const float kBeta = 0.002; + +// -------- + +// System built-in variables +sampler2D _CameraGBufferTexture2; +sampler2D_float _CameraDepthTexture; +sampler2D _CameraDepthNormalsTexture; + +float4 _CameraDepthTexture_ST; + +// Sample count +#if !defined(SHADER_API_GLES) +int _SampleCount; +#else +// GLES2: In many cases, dynamic looping is not supported. +static const int _SampleCount = 3; +#endif + +// Source texture properties +sampler2D _OcclusionTexture; +float4 _OcclusionTexture_TexelSize; + +// Other parameters +half _Intensity; +float _Radius; +float _Downsample; +float3 _FogParams; // x: density, y: start, z: end + +// Accessors for packed AO/normal buffer +fixed4 PackAONormal(fixed ao, fixed3 n) +{ + return fixed4(ao, n * 0.5 + 0.5); +} + +fixed GetPackedAO(fixed4 p) +{ + return p.r; +} + +fixed3 GetPackedNormal(fixed4 p) +{ + return p.gba * 2.0 - 1.0; +} + +// Boundary check for depth sampler +// (returns a very large value if it lies out of bounds) +float CheckBounds(float2 uv, float d) +{ + float ob = any(uv < 0) + any(uv > 1); +#if defined(UNITY_REVERSED_Z) + ob += (d <= 0.00001); +#else + ob += (d >= 0.99999); +#endif + return ob * 1e8; +} + +// Depth/normal sampling functions +float SampleDepth(float2 uv) +{ +#if defined(SOURCE_GBUFFER) || defined(SOURCE_DEPTH) + float d = LinearizeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); +#else + float4 cdn = tex2D(_CameraDepthNormalsTexture, uv); + float d = DecodeFloatRG(cdn.zw); +#endif + return d * _ProjectionParams.z + CheckBounds(uv, d); +} + +float3 SampleNormal(float2 uv) +{ +#if defined(SOURCE_GBUFFER) + float3 norm = tex2D(_CameraGBufferTexture2, uv).xyz; + norm = norm * 2 - any(norm); // gets (0,0,0) when norm == 0 + norm = mul((float3x3)unity_WorldToCamera, norm); +#if defined(VALIDATE_NORMALS) + norm = normalize(norm); +#endif + return norm; +#else + float4 cdn = tex2D(_CameraDepthNormalsTexture, uv); + return DecodeViewNormalStereo(cdn) * float3(1.0, 1.0, -1.0); +#endif +} + +float SampleDepthNormal(float2 uv, out float3 normal) +{ +#if defined(SOURCE_GBUFFER) || defined(SOURCE_DEPTH) + normal = SampleNormal(uv); + return SampleDepth(uv); +#else + float4 cdn = tex2D(_CameraDepthNormalsTexture, uv); + normal = DecodeViewNormalStereo(cdn) * float3(1.0, 1.0, -1.0); + float d = DecodeFloatRG(cdn.zw); + return d * _ProjectionParams.z + CheckBounds(uv, d); +#endif +} + +// Normal vector comparer (for geometry-aware weighting) +half CompareNormal(half3 d1, half3 d2) +{ + return smoothstep(kGeometryCoeff, 1.0, dot(d1, d2)); +} + +// Common vertex shader +struct VaryingsMultitex +{ + float4 pos : SV_POSITION; + half2 uv : TEXCOORD0; // Original UV + half2 uv01 : TEXCOORD1; // Alternative UV (supports v-flip case) + half2 uvSPR : TEXCOORD2; // Single pass stereo rendering UV +}; + +VaryingsMultitex VertMultitex(AttributesDefault v) +{ + half2 uvAlt = v.texcoord.xy; + +#if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0.0) uvAlt.y = 1.0 - uvAlt.y; +#endif + + VaryingsMultitex o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.uv01 = uvAlt; + o.uvSPR = UnityStereoTransformScreenSpaceTex(uvAlt); + + return o; +} + +// Trigonometric function utility +float2 CosSin(float theta) +{ + float sn, cs; + sincos(theta, sn, cs); + return float2(cs, sn); +} + +// Pseudo random number generator with 2D coordinates +float UVRandom(float u, float v) +{ + float f = dot(float2(12.9898, 78.233), float2(u, v)); + return frac(43758.5453 * sin(f)); +} + +// Check if the camera is perspective. +// (returns 1.0 when orthographic) +float CheckPerspective(float x) +{ + return lerp(x, 1.0, unity_OrthoParams.w); +} + +// Reconstruct view-space position from UV and depth. +// p11_22 = (unity_CameraProjection._11, unity_CameraProjection._22) +// p13_31 = (unity_CameraProjection._13, unity_CameraProjection._23) +float3 ReconstructViewPos(float2 uv, float depth, float2 p11_22, float2 p13_31) +{ + return float3((uv * 2.0 - 1.0 - p13_31) / p11_22 * CheckPerspective(depth), depth); +} + +// Sample point picker +float3 PickSamplePoint(float2 uv, float index) +{ + // Uniformaly distributed points on a unit sphere http://goo.gl/X2F1Ho +#if defined(FIX_SAMPLING_PATTERN) + float gn = GradientNoise(uv * _Downsample); + // FIXME: This was added to avoid a NVIDIA driver issue. + // vvvvvvvvvvvv + float u = frac(UVRandom(0.0, index + uv.x * 1e-10) + gn) * 2.0 - 1.0; + float theta = (UVRandom(1.0, index + uv.x * 1e-10) + gn) * UNITY_PI_2; +#else + float u = UVRandom(uv.x + _Time.x, uv.y + index) * 2.0 - 1.0; + float theta = UVRandom(-uv.x - _Time.x, uv.y + index) * UNITY_PI_2; +#endif + float3 v = float3(CosSin(theta) * sqrt(1.0 - u * u), u); + // Make them distributed between [0, _Radius] + float l = sqrt((index + 1.0) / _SampleCount) * _Radius; + return v * l; +} + +// Fog handling in forward +half ComputeFog(float z) +{ + half fog = 0.0; +#if FOG_LINEAR + fog = (_FogParams.z - z) / (_FogParams.z - _FogParams.y); +#elif FOG_EXP + fog = exp2(-_FogParams.x * z); +#else // FOG_EXP2 + fog = _FogParams.x * z; + fog = exp2(-fog * fog); +#endif + return saturate(fog); +} + +float ComputeDistance(float depth) +{ + float dist = depth * _ProjectionParams.z; + dist -= _ProjectionParams.y; + return dist; +} + +// +// Distance-based AO estimator based on Morgan 2011 http://goo.gl/2iz3P +// +half4 FragAO(VaryingsMultitex i) : SV_Target +{ + float2 uv = i.uv; + + // Parameters used in coordinate conversion + float3x3 proj = (float3x3)unity_CameraProjection; + float2 p11_22 = float2(unity_CameraProjection._11, unity_CameraProjection._22); + float2 p13_31 = float2(unity_CameraProjection._13, unity_CameraProjection._23); + + // View space normal and depth + float3 norm_o; + float depth_o = SampleDepthNormal(UnityStereoScreenSpaceUVAdjust(uv, _CameraDepthTexture_ST), norm_o); + +#if defined(SOURCE_DEPTHNORMALS) + // Offset the depth value to avoid precision error. + // (depth in the DepthNormals mode has only 16-bit precision) + depth_o -= _ProjectionParams.z / 65536; +#endif + + // Reconstruct the view-space position. + float3 vpos_o = ReconstructViewPos(i.uv01, depth_o, p11_22, p13_31); + + float ao = 0.0; + + for (int s = 0; s < _SampleCount; s++) + { + // Sample point +#if defined(SHADER_API_D3D11) + // This 'floor(1.0001 * s)' operation is needed to avoid a NVidia + // shader issue. This issue is only observed on DX11. + float3 v_s1 = PickSamplePoint(uv, floor(1.0001 * s)); +#else + float3 v_s1 = PickSamplePoint(uv, s); +#endif + v_s1 = faceforward(v_s1, -norm_o, v_s1); + float3 vpos_s1 = vpos_o + v_s1; + + // Reproject the sample point + float3 spos_s1 = mul(proj, vpos_s1); + float2 uv_s1_01 = (spos_s1.xy / CheckPerspective(vpos_s1.z) + 1.0) * 0.5; + + // Depth at the sample point + float depth_s1 = SampleDepth(UnityStereoScreenSpaceUVAdjust(uv_s1_01, _CameraDepthTexture_ST)); + + // Relative position of the sample point + float3 vpos_s2 = ReconstructViewPos(uv_s1_01, depth_s1, p11_22, p13_31); + float3 v_s2 = vpos_s2 - vpos_o; + + // Estimate the obscurance value + float a1 = max(dot(v_s2, norm_o) - kBeta * depth_o, 0.0); + float a2 = dot(v_s2, v_s2) + EPSILON; + ao += a1 / a2; + } + + ao *= _Radius; // intensity normalization + + // Apply other parameters. + ao = pow(ao * _Intensity / _SampleCount, kContrast); + + // Apply fog when enabled (forward-only) +#if !FOG_OFF + float d = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); + d = ComputeDistance(d); + ao *= ComputeFog(d); +#endif + + return PackAONormal(ao, norm_o); +} + +// Geometry-aware separable bilateral filter +half4 FragBlur(VaryingsMultitex i) : SV_Target +{ +#if defined(BLUR_HORIZONTAL) + // Horizontal pass: Always use 2 texels interval to match to + // the dither pattern. + float2 delta = float2(_MainTex_TexelSize.x * 2.0, 0.0); +#else + // Vertical pass: Apply _Downsample to match to the dither + // pattern in the original occlusion buffer. + float2 delta = float2(0.0, _MainTex_TexelSize.y / _Downsample * 2.0); +#endif + +#if defined(BLUR_HIGH_QUALITY) + + // High quality 7-tap Gaussian with adaptive sampling + + fixed4 p0 = tex2D(_MainTex, i.uvSPR); + fixed4 p1a = tex2D(_MainTex, i.uvSPR - delta); + fixed4 p1b = tex2D(_MainTex, i.uvSPR + delta); + fixed4 p2a = tex2D(_MainTex, i.uvSPR - delta * 2.0); + fixed4 p2b = tex2D(_MainTex, i.uvSPR + delta * 2.0); + fixed4 p3a = tex2D(_MainTex, i.uvSPR - delta * 3.2307692308); + fixed4 p3b = tex2D(_MainTex, i.uvSPR + delta * 3.2307692308); + +#if defined(BLUR_SAMPLE_CENTER_NORMAL) + fixed3 n0 = SampleNormal(i.uvSPR); +#else + fixed3 n0 = GetPackedNormal(p0); +#endif + + half w0 = 0.37004405286; + half w1a = CompareNormal(n0, GetPackedNormal(p1a)) * 0.31718061674; + half w1b = CompareNormal(n0, GetPackedNormal(p1b)) * 0.31718061674; + half w2a = CompareNormal(n0, GetPackedNormal(p2a)) * 0.19823788546; + half w2b = CompareNormal(n0, GetPackedNormal(p2b)) * 0.19823788546; + half w3a = CompareNormal(n0, GetPackedNormal(p3a)) * 0.11453744493; + half w3b = CompareNormal(n0, GetPackedNormal(p3b)) * 0.11453744493; + + half s; + s = GetPackedAO(p0) * w0; + s += GetPackedAO(p1a) * w1a; + s += GetPackedAO(p1b) * w1b; + s += GetPackedAO(p2a) * w2a; + s += GetPackedAO(p2b) * w2b; + s += GetPackedAO(p3a) * w3a; + s += GetPackedAO(p3b) * w3b; + + s /= w0 + w1a + w1b + w2a + w2b + w3a + w3b; + +#else + + // Fater 5-tap Gaussian with linear sampling + fixed4 p0 = tex2D(_MainTex, i.uvSPR); + fixed4 p1a = tex2D(_MainTex, i.uvSPR - delta * 1.3846153846); + fixed4 p1b = tex2D(_MainTex, i.uvSPR + delta * 1.3846153846); + fixed4 p2a = tex2D(_MainTex, i.uvSPR - delta * 3.2307692308); + fixed4 p2b = tex2D(_MainTex, i.uvSPR + delta * 3.2307692308); + +#if defined(BLUR_SAMPLE_CENTER_NORMAL) + fixed3 n0 = SampleNormal(i.uvSPR); +#else + fixed3 n0 = GetPackedNormal(p0); +#endif + + half w0 = 0.2270270270; + half w1a = CompareNormal(n0, GetPackedNormal(p1a)) * 0.3162162162; + half w1b = CompareNormal(n0, GetPackedNormal(p1b)) * 0.3162162162; + half w2a = CompareNormal(n0, GetPackedNormal(p2a)) * 0.0702702703; + half w2b = CompareNormal(n0, GetPackedNormal(p2b)) * 0.0702702703; + + half s; + s = GetPackedAO(p0) * w0; + s += GetPackedAO(p1a) * w1a; + s += GetPackedAO(p1b) * w1b; + s += GetPackedAO(p2a) * w2a; + s += GetPackedAO(p2b) * w2b; + + s /= w0 + w1a + w1b + w2a + w2b; + +#endif + + return PackAONormal(s, n0); +} + +// Gamma encoding (only needed in gamma lighting mode) +half EncodeAO(half x) +{ + half x_g = 1.0 - max(1.055 * pow(1.0 - x, 0.416666667) - 0.055, 0.0); + // ColorSpaceLuminance.w == 0 (gamma) or 1 (linear) + return lerp(x_g, x, unity_ColorSpaceLuminance.w); +} + +// Geometry-aware bilateral filter (single pass/small kernel) +half BlurSmall(sampler2D tex, float2 uv, float2 delta) +{ + fixed4 p0 = tex2D(tex, uv); + fixed4 p1 = tex2D(tex, uv + float2(-delta.x, -delta.y)); + fixed4 p2 = tex2D(tex, uv + float2(+delta.x, -delta.y)); + fixed4 p3 = tex2D(tex, uv + float2(-delta.x, +delta.y)); + fixed4 p4 = tex2D(tex, uv + float2(+delta.x, +delta.y)); + + fixed3 n0 = GetPackedNormal(p0); + + half w0 = 1.0; + half w1 = CompareNormal(n0, GetPackedNormal(p1)); + half w2 = CompareNormal(n0, GetPackedNormal(p2)); + half w3 = CompareNormal(n0, GetPackedNormal(p3)); + half w4 = CompareNormal(n0, GetPackedNormal(p4)); + + half s; + s = GetPackedAO(p0) * w0; + s += GetPackedAO(p1) * w1; + s += GetPackedAO(p2) * w2; + s += GetPackedAO(p3) * w3; + s += GetPackedAO(p4) * w4; + + return s / (w0 + w1 + w2 + w3 + w4); +} + +// Final composition shader +half4 FragComposition(VaryingsMultitex i) : SV_Target +{ + float2 delta = _MainTex_TexelSize.xy / _Downsample; + half ao = BlurSmall(_OcclusionTexture, i.uvSPR, delta); + half4 color = tex2D(_MainTex, i.uvSPR); + +#if !defined(DEBUG_COMPOSITION) + color.rgb *= 1.0 - EncodeAO(ao); +#else + color.rgb = 1.0 - EncodeAO(ao); +#endif + + return color; +} + +// Final composition shader (ambient-only mode) +VaryingsDefault VertCompositionGBuffer(AttributesDefault v) +{ + VaryingsDefault o; + o.pos = v.vertex; +#if UNITY_UV_STARTS_AT_TOP + o.uv = v.texcoord.xy * float2(1.0, -1.0) + float2(0.0, 1.0); +#else + o.uv = v.texcoord.xy; +#endif + o.uvSPR = UnityStereoTransformScreenSpaceTex(o.uv); + return o; +} + +#if !SHADER_API_GLES // excluding the MRT pass under GLES2 + +struct CompositionOutput +{ + half4 gbuffer0 : SV_Target0; + half4 gbuffer3 : SV_Target1; +}; + +CompositionOutput FragCompositionGBuffer(VaryingsDefault i) +{ + // Workaround: _OcclusionTexture_Texelsize hasn't been set properly + // for some reasons. Use _ScreenParams instead. + float2 delta = (_ScreenParams.zw - 1.0) / _Downsample; + half ao = BlurSmall(_OcclusionTexture, i.uvSPR, delta); + + CompositionOutput o; + o.gbuffer0 = half4(0.0, 0.0, 0.0, ao); + o.gbuffer3 = half4((half3)EncodeAO(ao), 0.0); + return o; +} + +#else + +fixed4 FragCompositionGBuffer(VaryingsDefault i) : SV_Target0 +{ + return 0.0; +} + +#endif + +#endif // __AMBIENT_OCCLUSION__ diff --git a/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc.meta b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc.meta new file mode 100644 index 0000000..897e89d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 447591ee3d9d4204899be5fe25968ea0 +timeCreated: 1473323470 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader new file mode 100644 index 0000000..40bdf7b --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader @@ -0,0 +1,119 @@ +Shader "Hidden/Post FX/Ambient Occlusion" +{ + CGINCLUDE + + #pragma target 3.0 + + ENDCG + + SubShader + { + ZTest Always Cull Off ZWrite Off + + // 0: Occlusion estimation with CameraDepthTexture + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragAO + #pragma multi_compile FOG_OFF FOG_LINEAR FOG_EXP FOG_EXP2 + #define SOURCE_DEPTH + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 1: Occlusion estimation with CameraDepthNormalsTexture + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragAO + #pragma multi_compile FOG_OFF FOG_LINEAR FOG_EXP FOG_EXP2 + #define SOURCE_DEPTHNORMALS + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 2: Occlusion estimation with G-Buffer + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragAO + #pragma multi_compile FOG_OFF FOG_LINEAR FOG_EXP FOG_EXP2 + #define SOURCE_GBUFFER + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 3: Separable blur (horizontal pass) with CameraDepthNormalsTexture + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragBlur + #define SOURCE_DEPTHNORMALS + #define BLUR_HORIZONTAL + #define BLUR_SAMPLE_CENTER_NORMAL + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 4: Separable blur (horizontal pass) with G-Buffer + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragBlur + #define SOURCE_GBUFFER + #define BLUR_HORIZONTAL + #define BLUR_SAMPLE_CENTER_NORMAL + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 5: Separable blur (vertical pass) + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragBlur + #define BLUR_VERTICAL + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 6: Final composition + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragComposition + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 7: Final composition (ambient only mode) + Pass + { + Blend Zero OneMinusSrcColor, Zero OneMinusSrcAlpha + + CGPROGRAM + #pragma vertex VertCompositionGBuffer + #pragma fragment FragCompositionGBuffer + #include "AmbientOcclusion.cginc" + ENDCG + } + + // 8: Debug visualization + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragComposition + #define DEBUG_COMPOSITION + #include "AmbientOcclusion.cginc" + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader.meta b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader.meta new file mode 100644 index 0000000..8194433 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/AmbientOcclusion.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e881ae5627d1cc84395303acfbca6fb2 +timeCreated: 1462280790 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Blit.shader b/Assets/PostProcessing/Resources/Shaders/Blit.shader new file mode 100644 index 0000000..3a6c07f --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Blit.shader @@ -0,0 +1,49 @@ +Shader "Hidden/Post FX/Blit" +{ + Properties + { + _MainTex("Main Texture", 2D) = "white" {} + } + + CGINCLUDE + + #include "UnityCG.cginc" + #include "Common.cginc" + + struct Varyings + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + Varyings VertBlit(AttributesDefault v) + { + Varyings o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST); + return o; + } + + half4 FragBlit(Varyings i) : SV_Target + { + half4 col = tex2D(_MainTex, i.uv); + return col; + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + + #pragma vertex VertBlit + #pragma fragment FragBlit + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/Blit.shader.meta b/Assets/PostProcessing/Resources/Shaders/Blit.shader.meta new file mode 100644 index 0000000..b131559 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Blit.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7d89469544dfa214eabdbf37fca76f40 +timeCreated: 1474297975 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Bloom.cginc b/Assets/PostProcessing/Resources/Shaders/Bloom.cginc new file mode 100644 index 0000000..6e1086a --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Bloom.cginc @@ -0,0 +1,86 @@ +#ifndef __BLOOM__ +#define __BLOOM__ + +#include "Common.cginc" + +// Brightness function +half Brightness(half3 c) +{ + return Max3(c); +} + +// 3-tap median filter +half3 Median(half3 a, half3 b, half3 c) +{ + return a + b + c - min(min(a, b), c) - max(max(a, b), c); +} + +// Downsample with a 4x4 box filter +half3 DownsampleFilter(sampler2D tex, float2 uv, float2 texelSize) +{ + float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0); + + half3 s; + s = DecodeHDR(tex2D(tex, uv + d.xy)); + s += DecodeHDR(tex2D(tex, uv + d.zy)); + s += DecodeHDR(tex2D(tex, uv + d.xw)); + s += DecodeHDR(tex2D(tex, uv + d.zw)); + + return s * (1.0 / 4.0); +} + +// Downsample with a 4x4 box filter + anti-flicker filter +half3 DownsampleAntiFlickerFilter(sampler2D tex, float2 uv, float2 texelSize) +{ + float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0); + + half3 s1 = DecodeHDR(tex2D(tex, uv + d.xy)); + half3 s2 = DecodeHDR(tex2D(tex, uv + d.zy)); + half3 s3 = DecodeHDR(tex2D(tex, uv + d.xw)); + half3 s4 = DecodeHDR(tex2D(tex, uv + d.zw)); + + // Karis's luma weighted average (using brightness instead of luma) + half s1w = 1.0 / (Brightness(s1) + 1.0); + half s2w = 1.0 / (Brightness(s2) + 1.0); + half s3w = 1.0 / (Brightness(s3) + 1.0); + half s4w = 1.0 / (Brightness(s4) + 1.0); + half one_div_wsum = 1.0 / (s1w + s2w + s3w + s4w); + + return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum; +} + +half3 UpsampleFilter(sampler2D tex, float2 uv, float2 texelSize, float sampleScale) +{ +#if MOBILE_OR_CONSOLE + // 4-tap bilinear upsampler + float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0) * (sampleScale * 0.5); + + half3 s; + s = DecodeHDR(tex2D(tex, uv + d.xy)); + s += DecodeHDR(tex2D(tex, uv + d.zy)); + s += DecodeHDR(tex2D(tex, uv + d.xw)); + s += DecodeHDR(tex2D(tex, uv + d.zw)); + + return s * (1.0 / 4.0); +#else + // 9-tap bilinear upsampler (tent filter) + float4 d = texelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0) * sampleScale; + + half3 s; + s = DecodeHDR(tex2D(tex, uv - d.xy)); + s += DecodeHDR(tex2D(tex, uv - d.wy)) * 2.0; + s += DecodeHDR(tex2D(tex, uv - d.zy)); + + s += DecodeHDR(tex2D(tex, uv + d.zw)) * 2.0; + s += DecodeHDR(tex2D(tex, uv)) * 4.0; + s += DecodeHDR(tex2D(tex, uv + d.xw)) * 2.0; + + s += DecodeHDR(tex2D(tex, uv + d.zy)); + s += DecodeHDR(tex2D(tex, uv + d.wy)) * 2.0; + s += DecodeHDR(tex2D(tex, uv + d.xy)); + + return s * (1.0 / 16.0); +#endif +} + +#endif // __BLOOM__ diff --git a/Assets/PostProcessing/Resources/Shaders/Bloom.cginc.meta b/Assets/PostProcessing/Resources/Shaders/Bloom.cginc.meta new file mode 100644 index 0000000..ba45918 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Bloom.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7d1f4dd94c8e6e940b0730076ea7d6d9 +timeCreated: 1462980395 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Bloom.shader b/Assets/PostProcessing/Resources/Shaders/Bloom.shader new file mode 100644 index 0000000..d3004bb --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Bloom.shader @@ -0,0 +1,182 @@ +// +// Kino/Bloom v2 - Bloom filter for Unity +// +// Copyright (C) 2015, 2016 Keijiro Takahashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +Shader "Hidden/Post FX/Bloom" +{ + Properties + { + _MainTex ("", 2D) = "" {} + _BaseTex ("", 2D) = "" {} + _AutoExposure ("", 2D) = "" {} + } + + CGINCLUDE + + #pragma target 3.0 + #include "UnityCG.cginc" + #include "Bloom.cginc" + #include "Common.cginc" + + sampler2D _BaseTex; + float2 _BaseTex_TexelSize; + + sampler2D _AutoExposure; + + float _PrefilterOffs; + float _Threshold; + float3 _Curve; + float _SampleScale; + + // ----------------------------------------------------------------------------- + // Vertex shaders + + struct VaryingsMultitex + { + float4 pos : SV_POSITION; + float2 uvMain : TEXCOORD0; + float2 uvBase : TEXCOORD1; + }; + + VaryingsMultitex VertMultitex(AttributesDefault v) + { + VaryingsMultitex o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uvMain = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST); + o.uvBase = o.uvMain; + + #if UNITY_UV_STARTS_AT_TOP + if (_BaseTex_TexelSize.y < 0.0) + o.uvBase.y = 1.0 - o.uvBase.y; + #endif + + return o; + } + + // ----------------------------------------------------------------------------- + // Fragment shaders + + half4 FetchAutoExposed(sampler2D tex, float2 uv) + { + float autoExposure = 1.0; + uv = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST); + autoExposure = tex2D(_AutoExposure, uv).r; + return tex2D(tex, uv) * autoExposure; + } + + half4 FragPrefilter(VaryingsDefault i) : SV_Target + { + float2 uv = i.uv + _MainTex_TexelSize.xy * _PrefilterOffs; + + #if ANTI_FLICKER + float3 d = _MainTex_TexelSize.xyx * float3(1.0, 1.0, 0.0); + half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv)); + half3 s1 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.xz).rgb); + half3 s2 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.xz).rgb); + half3 s3 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.zy).rgb); + half3 s4 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.zy).rgb); + half3 m = Median(Median(s0.rgb, s1, s2), s3, s4); + #else + half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv)); + half3 m = s0.rgb; + #endif + + #if UNITY_COLORSPACE_GAMMA + m = GammaToLinearSpace(m); + #endif + + // Pixel brightness + half br = Brightness(m); + + // Under-threshold part: quadratic curve + half rq = clamp(br - _Curve.x, 0.0, _Curve.y); + rq = _Curve.z * rq * rq; + + // Combine and apply the brightness response curve. + m *= max(rq, br - _Threshold) / max(br, 1e-5); + + return EncodeHDR(m); + } + + half4 FragDownsample1(VaryingsDefault i) : SV_Target + { + #if ANTI_FLICKER + return EncodeHDR(DownsampleAntiFlickerFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); + #else + return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); + #endif + } + + half4 FragDownsample2(VaryingsDefault i) : SV_Target + { + return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); + } + + half4 FragUpsample(VaryingsMultitex i) : SV_Target + { + half3 base = DecodeHDR(tex2D(_BaseTex, i.uvBase)); + half3 blur = UpsampleFilter(_MainTex, i.uvMain, _MainTex_TexelSize.xy, _SampleScale); + return EncodeHDR(base + blur); + } + + ENDCG + + SubShader + { + ZTest Always Cull Off ZWrite Off + + Pass + { + CGPROGRAM + #pragma multi_compile __ ANTI_FLICKER + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #pragma vertex VertDefault + #pragma fragment FragPrefilter + ENDCG + } + + Pass + { + CGPROGRAM + #pragma multi_compile __ ANTI_FLICKER + #pragma vertex VertDefault + #pragma fragment FragDownsample1 + ENDCG + } + + Pass + { + CGPROGRAM + #pragma vertex VertDefault + #pragma fragment FragDownsample2 + ENDCG + } + + Pass + { + CGPROGRAM + #pragma vertex VertMultitex + #pragma fragment FragUpsample + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/Bloom.shader.meta b/Assets/PostProcessing/Resources/Shaders/Bloom.shader.meta new file mode 100644 index 0000000..8e255a2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Bloom.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4ceb73bc148699b469361531d6062548 +timeCreated: 1462953634 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader b/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader new file mode 100644 index 0000000..337128e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader @@ -0,0 +1,257 @@ +Shader "Hidden/Post FX/Builtin Debug Views" +{ + CGINCLUDE + + #include "UnityCG.cginc" + #include "Common.cginc" + + #pragma exclude_renderers d3d11_9x + + sampler2D_float _CameraDepthTexture; + sampler2D_float _CameraDepthNormalsTexture; + sampler2D_float _CameraMotionVectorsTexture; + + float4 _CameraDepthTexture_ST; + float4 _CameraDepthNormalsTexture_ST; + float4 _CameraMotionVectorsTexture_ST; + + #if SOURCE_GBUFFER + sampler2D _CameraGBufferTexture2; + float4 _CameraGBufferTexture2_ST; + #endif + + // ----------------------------------------------------------------------------- + // Depth + + float _DepthScale; + + float4 FragDepth(VaryingsDefault i) : SV_Target + { + float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv, _CameraDepthTexture_ST)); + depth = Linear01Depth(depth) * _DepthScale; + float3 d = depth.xxx; + + #if !UNITY_COLORSPACE_GAMMA + d = GammaToLinearSpace(d); + #endif + + return float4(d, 1.0); + } + + // ----------------------------------------------------------------------------- + // Normals + + float3 SampleNormal(float2 uv) + { + #if SOURCE_GBUFFER + float3 norm = tex2D(_CameraGBufferTexture2, uv).xyz * 2.0 - 1.0; + return mul((float3x3)unity_WorldToCamera, norm); + #else + float4 cdn = tex2D(_CameraDepthNormalsTexture, uv); + return DecodeViewNormalStereo(cdn) * float3(1.0, 1.0, -1.0); + #endif + } + + float4 FragNormals(VaryingsDefault i) : SV_Target + { + float3 n = SampleNormal(UnityStereoScreenSpaceUVAdjust(i.uv, _CameraDepthNormalsTexture_ST)); + + #if UNITY_COLORSPACE_GAMMA + n = LinearToGammaSpace(n); + #endif + + return float4(n, 1.0); + } + + // ----------------------------------------------------------------------------- + // Motion vectors + + float _Opacity; + float _Amplitude; + float4 _Scale; + + float4 FragMovecsOpacity(VaryingsDefault i) : SV_Target + { + float4 src = tex2D(_MainTex, i.uv); + return float4(src.rgb * _Opacity, src.a); + } + + // Convert a motion vector into RGBA color. + float4 VectorToColor(float2 mv) + { + float phi = atan2(mv.x, mv.y); + float hue = (phi / UNITY_PI + 1.0) * 0.5; + + float r = abs(hue * 6.0 - 3.0) - 1.0; + float g = 2.0 - abs(hue * 6.0 - 2.0); + float b = 2.0 - abs(hue * 6.0 - 4.0); + float a = length(mv); + + return saturate(float4(r, g, b, a)); + } + + float4 FragMovecsImaging(VaryingsDefault i) : SV_Target + { + float4 src = tex2D(_MainTex, i.uv); + + float2 mv = tex2D(_CameraMotionVectorsTexture, i.uv).rg * _Amplitude; + + #if UNITY_UV_STARTS_AT_TOP + mv.y *= -1.0; + #endif + + float4 mc = VectorToColor(mv); + + float3 rgb = src.rgb; + + #if !UNITY_COLORSPACE_GAMMA + rgb = LinearToGammaSpace(rgb); + #endif + + rgb = lerp(rgb, mc.rgb, mc.a * _Opacity); + + #if !UNITY_COLORSPACE_GAMMA + rgb = GammaToLinearSpace(rgb); + #endif + + return float4(rgb, src.a); + } + + struct VaryingsArrows + { + float4 vertex : SV_POSITION; + float2 scoord : TEXCOORD; + float4 color : COLOR; + }; + + VaryingsArrows VertArrows(AttributesDefault v) + { + // Retrieve the motion vector. + float4 uv = float4(v.texcoord.xy, 0.0, 0.0); + + #if UNITY_UV_STARTS_AT_TOP + uv.y = 1.0 - uv.y; + #endif + + float2 mv = tex2Dlod(_CameraMotionVectorsTexture, uv).rg * _Amplitude; + + #if UNITY_UV_STARTS_AT_TOP + mv.y *= -1.0; + #endif + + // Arrow color + float4 color = VectorToColor(mv); + + // Make a rotation matrix based on the motion vector. + float2x2 rot = float2x2(mv.y, mv.x, -mv.x, mv.y); + + // Rotate and scale the body of the arrow. + float2 pos = mul(rot, v.vertex.zy) * _Scale.xy; + + // Normalized variant of the motion vector and the rotation matrix. + float2 mv_n = normalize(mv); + float2x2 rot_n = float2x2(mv_n.y, mv_n.x, -mv_n.x, mv_n.y); + + // Rotate and scale the head of the arrow. + float2 head = float2(v.vertex.x, -abs(v.vertex.x)) * 0.3; + head *= saturate(color.a); + pos += mul(rot_n, head) * _Scale.xy; + + // Offset the arrow position. + pos += v.texcoord.xy * 2.0 - 1.0; + + // Convert to the screen coordinates. + float2 scoord = (pos + 1.0) * 0.5 * _ScreenParams.xy; + + // Snap to a pixel-perfect position. + scoord = round(scoord); + + // Bring back to the normalized screen space. + pos = (scoord + 0.5) * (_ScreenParams.zw - 1.0) * 2.0 - 1.0; + + // Color tweaks + color.rgb = GammaToLinearSpace(lerp(color.rgb, 1.0, 0.5)); + color.a *= _Opacity; + + // Output + VaryingsArrows o; + o.vertex = float4(pos, 0.0, 1.0); + o.scoord = scoord; + o.color = saturate(color); + return o; + } + + float4 FragMovecsArrows(VaryingsArrows i) : SV_Target + { + // Pseudo anti-aliasing. + float aa = length(frac(i.scoord) - 0.5) / 0.707; + aa *= (aa * (aa * 0.305306011 + 0.682171111) + 0.012522878); // gamma + return float4(i.color.rgb, i.color.a * aa); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) - Depth + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragDepth + + ENDCG + } + + // (1) - Normals + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragNormals + #pragma multi_compile __ SOURCE_GBUFFER + + ENDCG + } + + // (2) - Motion vectors - Opacity + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragMovecsOpacity + + ENDCG + } + + // (3) - Motion vectors - Imaging + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragMovecsImaging + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + + ENDCG + } + + // (4) - Motion vectors - Arrows + Pass + { + Blend SrcAlpha OneMinusSrcAlpha + + CGPROGRAM + + #pragma vertex VertArrows + #pragma fragment FragMovecsArrows + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader.meta b/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader.meta new file mode 100644 index 0000000..a6417c0 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/BuiltinDebugViews.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 72127ba7dd8c6b04bb3f29c7ee669813 +timeCreated: 1468224802 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc b/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc new file mode 100644 index 0000000..2a8c5a3 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc @@ -0,0 +1,290 @@ +#ifndef __COLOR_GRADING__ +#define __COLOR_GRADING__ + +#include "ACES.cginc" +#include "Common.cginc" + +// Set to 1 to use more precise but more expensive log/linear conversions. I haven't found a proper +// use case for the high precision version yet so I'm leaving this to 0. +#define COLOR_GRADING_PRECISE_LOG 0 + +// +// Alexa LogC converters (El 1000) +// See http://www.vocas.nl/webfm_send/964 +// It's a good fit to store HDR values in log as the range is pretty wide (1 maps to ~58.85666) and +// is quick enough to compute. +// +struct ParamsLogC +{ + half cut; + half a, b, c, d, e, f; +}; + +static const ParamsLogC LogC = +{ + 0.011361, // cut + 5.555556, // a + 0.047996, // b + 0.244161, // c + 0.386036, // d + 5.301883, // e + 0.092819 // f +}; + +half LinearToLogC_Precise(half x) +{ + half o; + if (x > LogC.cut) + o = LogC.c * log10(LogC.a * x + LogC.b) + LogC.d; + else + o = LogC.e * x + LogC.f; + return o; +} + +half3 LinearToLogC(half3 x) +{ +#if COLOR_GRADING_PRECISE_LOG + return half3( + LinearToLogC_Precise(x.x), + LinearToLogC_Precise(x.y), + LinearToLogC_Precise(x.z) + ); +#else + return LogC.c * log10(LogC.a * x + LogC.b) + LogC.d; +#endif +} + +half LogCToLinear_Precise(half x) +{ + half o; + if (x > LogC.e * LogC.cut + LogC.f) + o = (pow(10.0, (x - LogC.d) / LogC.c) - LogC.b) / LogC.a; + else + o = (x - LogC.f) / LogC.e; + return o; +} + +half3 LogCToLinear(half3 x) +{ +#if COLOR_GRADING_PRECISE_LOG + return half3( + LogCToLinear_Precise(x.x), + LogCToLinear_Precise(x.y), + LogCToLinear_Precise(x.z) + ); +#else + return (pow(10.0, (x - LogC.d) / LogC.c) - LogC.b) / LogC.a; +#endif +} + +// +// White balance +// Recommended workspace: ACEScg (linear) +// +static const half3x3 LIN_2_LMS_MAT = { + 3.90405e-1, 5.49941e-1, 8.92632e-3, + 7.08416e-2, 9.63172e-1, 1.35775e-3, + 2.31082e-2, 1.28021e-1, 9.36245e-1 +}; + +static const half3x3 LMS_2_LIN_MAT = { + 2.85847e+0, -1.62879e+0, -2.48910e-2, + -2.10182e-1, 1.15820e+0, 3.24281e-4, + -4.18120e-2, -1.18169e-1, 1.06867e+0 +}; + +half3 WhiteBalance(half3 c, half3 balance) +{ + half3 lms = mul(LIN_2_LMS_MAT, c); + lms *= balance; + return mul(LMS_2_LIN_MAT, lms); +} + +// +// Luminance (Rec.709 primaries according to ACES specs) +// +half AcesLuminance(half3 c) +{ + return dot(c, half3(0.2126, 0.7152, 0.0722)); +} + +// +// Offset, Power, Slope (ASC-CDL) +// Works in Log & Linear. Results will be different but still correct. +// +half3 OffsetPowerSlope(half3 c, half3 offset, half3 power, half3 slope) +{ + half3 so = c * slope + offset; + so = so > (0.0).xxx ? pow(so, power) : so; + return so; +} + +// +// Lift, Gamma (pre-inverted), Gain +// Recommended workspace: ACEScg (linear) +// +half3 LiftGammaGain(half3 c, half3 lift, half3 invgamma, half3 gain) +{ + //return gain * (lift * (1.0 - c) + pow(max(c, kEpsilon), invgamma)); + //return pow(gain * (c + lift * (1.0 - c)), invgamma); + + half3 power = invgamma; + half3 offset = lift * gain; + half3 slope = ((1.0).xxx - lift) * gain; + return OffsetPowerSlope(c, offset, power, slope); +} + +// +// Saturation (should be used after offset/power/slope) +// Recommended workspace: ACEScc (log) +// Optimal range: [0.0, 2.0] +// +half3 Saturation(half3 c, half sat) +{ + half luma = AcesLuminance(c); + return luma.xxx + sat * (c - luma.xxx); +} + +// +// Basic contrast curve +// Recommended workspace: ACEScc (log) +// Optimal range: [0.0, 2.0] +// +half3 ContrastLog(half3 c, half con) +{ + return (c - ACEScc_MIDGRAY) * con + ACEScc_MIDGRAY; +} + +// +// Hue, Saturation, Value +// Ranges: +// Hue [0.0, 1.0] +// Sat [0.0, 1.0] +// Lum [0.0, HALF_MAX] +// +half3 RgbToHsv(half3 c) +{ + half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g)); + half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r)); + half d = q.x - min(q.w, q.y); + half e = EPSILON; + return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +half3 HsvToRgb(half3 c) +{ + half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); +} + +half RotateHue(half value, half low, half hi) +{ + return (value < low) + ? value + hi + : (value > hi) + ? value - hi + : value; +} + +// +// Remaps Y/R/G/B values +// +half3 YrgbCurve(half3 c, sampler2D curveTex) +{ + const float kHalfPixel = (1.0 / 128.0) / 2.0; + + // Y + c += kHalfPixel.xxx; + float mr = tex2D(curveTex, float2(c.r, 0.75)).a; + float mg = tex2D(curveTex, float2(c.g, 0.75)).a; + float mb = tex2D(curveTex, float2(c.b, 0.75)).a; + c = saturate(float3(mr, mg, mb)); + + // RGB + c += kHalfPixel.xxx; + float r = tex2D(curveTex, float2(c.r, 0.75)).r; + float g = tex2D(curveTex, float2(c.g, 0.75)).g; + float b = tex2D(curveTex, float2(c.b, 0.75)).b; + return saturate(half3(r, g, b)); +} + +// +// (X) Hue VS Hue - Remaps hue on a curve according to the current hue +// Input is Hue [0.0, 1.0] +// Output is Hue [0.0, 1.0] +// +half SecondaryHueHue(half hue, sampler2D curveTex) +{ + half offset = saturate(tex2D(curveTex, half2(hue, 0.25)).x) - 0.5; + hue += offset; + hue = RotateHue(hue, 0.0, 1.0); + return hue; +} + +// +// (Y) Hue VS Saturation - Remaps saturation on a curve according to the current hue +// Input is Hue [0.0, 1.0] +// Output is Saturation multiplier [0.0, 2.0] +// +half SecondaryHueSat(half hue, sampler2D curveTex) +{ + return saturate(tex2D(curveTex, half2(hue, 0.25)).y) * 2.0; +} + +// +// (Z) Saturation VS Saturation - Remaps saturation on a curve according to the current saturation +// Input is Saturation [0.0, 1.0] +// Output is Saturation multiplier [0.0, 2.0] +// +half SecondarySatSat(half sat, sampler2D curveTex) +{ + return saturate(tex2D(curveTex, half2(sat, 0.25)).z) * 2.0; +} + +// +// (W) Luminance VS Saturation - Remaps saturation on a curve according to the current luminance +// Input is Luminance [0.0, 1.0] +// Output is Saturation multiplier [0.0, 2.0] +// +half SecondaryLumSat(half lum, sampler2D curveTex) +{ + return saturate(tex2D(curveTex, half2(lum, 0.25)).w) * 2.0; +} + +// +// Channel mixing (same as Photoshop's and DaVinci's Resolve) +// Recommended workspace: ACEScg (linear) +// Input mixers should be in range [-2.0;2.0] +// +half3 ChannelMixer(half3 c, half3 red, half3 green, half3 blue) +{ + return half3( + dot(c, red), + dot(c, green), + dot(c, blue) + ); +} + +// +// LUT grading +// scaleOffset = (1 / lut_width, 1 / lut_height, lut_height - 1) +// +half3 ApplyLut2d(sampler2D tex, half3 uvw, half3 scaleOffset) +{ + // Strip format where `height = sqrt(width)` + uvw.z *= scaleOffset.z; + half shift = floor(uvw.z); + uvw.xy = uvw.xy * scaleOffset.z * scaleOffset.xy + scaleOffset.xy * 0.5; + uvw.x += shift * scaleOffset.y; + uvw.xyz = lerp(tex2D(tex, uvw.xy).rgb, tex2D(tex, uvw.xy + half2(scaleOffset.y, 0)).rgb, uvw.z - shift); + return uvw; +} + +half3 ApplyLut3d(sampler3D tex, half3 uvw) +{ + return tex3D(tex, uvw).rgb; +} + +#endif // __COLOR_GRADING__ diff --git a/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc.meta b/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc.meta new file mode 100644 index 0000000..4ef7d6d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ColorGrading.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 26a62c2e30be83547bdfa9fe837165e3 +timeCreated: 1460363486 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Common.cginc b/Assets/PostProcessing/Resources/Shaders/Common.cginc new file mode 100644 index 0000000..20280ff --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Common.cginc @@ -0,0 +1,166 @@ +#ifndef __COMMON__ +#define __COMMON__ + +#include "UnityCG.cginc" + +// Mobile: use RGBM instead of float/half RGB +#define USE_RGBM defined(SHADER_API_MOBILE) + +#define MOBILE_OR_CONSOLE (defined(SHADER_API_MOBILE) || defined(SHADER_API_PSSL) || defined(SHADER_API_XBOXONE) || defined(SHADER_API_WIIU)) + +#if defined(SHADER_API_PSSL) +// No support for sampler2D_half on PS4 in 5.4 +#define sampler2D_half sampler2D_float +#endif + +// ----------------------------------------------------------------------------- +// Uniforms + +#if defined(SEPARATE_TEXTURE_SAMPLER) +Texture2D _MainTex; +SamplerState sampler_MainTex; +#else +sampler2D _MainTex; +#endif +float4 _MainTex_TexelSize; +float4 _MainTex_ST; + +// ----------------------------------------------------------------------------- +// Vertex shaders + +struct AttributesDefault +{ + float4 vertex : POSITION; + float4 texcoord : TEXCOORD0; +}; + +struct VaryingsDefault +{ + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float2 uvSPR : TEXCOORD1; // Single Pass Stereo UVs +}; + +VaryingsDefault VertDefault(AttributesDefault v) +{ + VaryingsDefault o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.uvSPR = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST); + return o; +} + +// ----------------------------------------------------------------------------- +// Maths stuff + +#define HALF_MAX 65504.0 +#define EPSILON 1.0e-4 +#define UNITY_PI_2 (UNITY_PI * 2.0) + +inline half Min3(half3 x) { return min(x.x, min(x.y, x.z)); } +inline half Min3(half x, half y, half z) { return min(x, min(y, z)); } + +inline half Max3(half3 x) { return max(x.x, max(x.y, x.z)); } +inline half Max3(half x, half y, half z) { return max(x, max(y, z)); } + +inline half Min4(half4 x) { return min(x.x, min(x.y, min(x.z, x.w))); } +inline half Min4(half x, half y, half z, half w) { return min(x, min(y, min(z, w))); } + +inline half Max4(half4 x) { return max(x.x, max(x.y, max(x.z, x.w))); } +inline half Max4(half x, half y, half z, half w) { return max(x, max(y, min(z, w))); } + +inline half Pow2(half x) { return x * x; } +inline half2 Pow2(half2 x) { return x * x; } +inline half3 Pow2(half3 x) { return x * x; } +inline half4 Pow2(half4 x) { return x * x; } + +inline half Pow3(half x) { return x * x * x; } +inline half2 Pow3(half2 x) { return x * x * x; } +inline half3 Pow3(half3 x) { return x * x * x; } +inline half4 Pow3(half4 x) { return x * x * x; } + +#ifndef UNITY_STANDARD_BRDF_INCLUDED +inline half Pow4(half x) { return x * x * x * x; } +inline half2 Pow4(half2 x) { return x * x * x * x; } +inline half3 Pow4(half3 x) { return x * x * x * x; } +inline half4 Pow4(half4 x) { return x * x * x * x; } +#endif + +// Returns the largest vector of v1 and v2 +inline half2 MaxV(half2 v1, half2 v2) { return dot(v1, v1) < dot(v2, v2) ? v2 : v1; } +inline half3 MaxV(half3 v1, half3 v2) { return dot(v1, v1) < dot(v2, v2) ? v2 : v1; } +inline half4 MaxV(half4 v1, half4 v2) { return dot(v1, v1) < dot(v2, v2) ? v2 : v1; } + +// Clamp HDR value within a safe range +inline half SafeHDR(half c) { return min(c, HALF_MAX); } +inline half2 SafeHDR(half2 c) { return min(c, HALF_MAX); } +inline half3 SafeHDR(half3 c) { return min(c, HALF_MAX); } +inline half4 SafeHDR(half4 c) { return min(c, HALF_MAX); } + +// Compatibility function +#if (SHADER_TARGET < 50 && !defined(SHADER_API_PSSL)) +float rcp(float value) +{ + return 1.0 / value; +} +#endif + +// Tonemapper from http://gpuopen.com/optimized-reversible-tonemapper-for-resolve/ +float4 FastToneMap(in float4 color) +{ + return float4(color.rgb * rcp(Max3(color.rgb) + 1.), color.a); +} + +float4 FastToneMap(in float4 color, in float weight) +{ + return float4(color.rgb * rcp(weight * Max3(color.rgb) + 1.), color.a); +} + +float4 FastToneUnmap(in float4 color) +{ + return float4(color.rgb * rcp(1. - Max3(color.rgb)), color.a); +} + +// Interleaved gradient function from Jimenez 2014 http://goo.gl/eomGso +float GradientNoise(float2 uv) +{ + uv = floor(uv * _ScreenParams.xy); + float f = dot(float2(0.06711056, 0.00583715), uv); + return frac(52.9829189 * frac(f)); +} + +// Z buffer depth to linear 0-1 depth +// Handles orthographic projection correctly +float LinearizeDepth(float z) +{ + float isOrtho = unity_OrthoParams.w; + float isPers = 1.0 - unity_OrthoParams.w; + z *= _ZBufferParams.x; + return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y); +} + +// ----------------------------------------------------------------------------- +// RGBM encoding/decoding + +half4 EncodeHDR(float3 rgb) +{ +#if USE_RGBM + rgb *= 1.0 / 8.0; + float m = max(max(rgb.r, rgb.g), max(rgb.b, 1e-6)); + m = ceil(m * 255.0) / 255.0; + return half4(rgb / m, m); +#else + return half4(rgb, 0.0); +#endif +} + +float3 DecodeHDR(half4 rgba) +{ +#if USE_RGBM + return rgba.rgb * rgba.a * 8.0; +#else + return rgba.rgb; +#endif +} + +#endif // __COMMON__ diff --git a/Assets/PostProcessing/Resources/Shaders/Common.cginc.meta b/Assets/PostProcessing/Resources/Shaders/Common.cginc.meta new file mode 100644 index 0000000..9ab4a80 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Common.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: eb88496804341c648b32a75843d92ccb +timeCreated: 1465205118 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc b/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc new file mode 100644 index 0000000..dad9b4e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc @@ -0,0 +1,243 @@ +#ifndef __DEPTH_OF_FIELD__ +#define __DEPTH_OF_FIELD__ + +#if SHADER_TARGET >= 50 + // Use separate texture/sampler objects on Shader Model 5.0 + #define SEPARATE_TEXTURE_SAMPLER + #define DOF_DECL_TEX2D(tex) Texture2D tex; SamplerState sampler##tex + #define DOF_TEX2D(tex, coord) tex.Sample(sampler##tex, coord) +#else + #define DOF_DECL_TEX2D(tex) sampler2D tex + #define DOF_TEX2D(tex, coord) tex2D(tex, coord) +#endif + +#include "Common.cginc" +#include "DiskKernels.cginc" + +DOF_DECL_TEX2D(_CameraDepthTexture); +DOF_DECL_TEX2D(_CameraMotionVectorsTexture); +DOF_DECL_TEX2D(_CoCTex); + +// Camera parameters +float _Distance; +float _LensCoeff; // f^2 / (N * (S1 - f) * film_width * 2) +float _MaxCoC; +float _RcpMaxCoC; +float _RcpAspect; +half3 _TaaParams; // Jitter.x, Jitter.y, Blending + +struct VaryingsDOF +{ + float4 pos : SV_POSITION; + half2 uv : TEXCOORD0; + half2 uvAlt : TEXCOORD1; +}; + +// Common vertex shader with single pass stereo rendering support +VaryingsDOF VertDOF(AttributesDefault v) +{ + half2 uvAlt = v.texcoord; +#if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0.0) uvAlt.y = 1.0 - uvAlt.y; +#endif + + VaryingsDOF o; + o.pos = UnityObjectToClipPos(v.vertex); + +#if defined(UNITY_SINGLE_PASS_STEREO) + o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST); + o.uvAlt = UnityStereoScreenSpaceUVAdjust(uvAlt, _MainTex_ST); +#else + o.uv = v.texcoord; + o.uvAlt = uvAlt; +#endif + + return o; +} + +// CoC calculation +half4 FragCoC(VaryingsDOF i) : SV_Target +{ + float depth = LinearEyeDepth(DOF_TEX2D(_CameraDepthTexture, i.uv)); + half coc = (depth - _Distance) * _LensCoeff / max(depth, 1e-5); + return saturate(coc * 0.5 * _RcpMaxCoC + 0.5); +} + +// Temporal filter +half4 FragTempFilter(VaryingsDOF i) : SV_Target +{ + float3 uvOffs = _MainTex_TexelSize.xyy * float3(1, 1, 0); + +#if defined(SEPARATE_TEXTURE_SAMPLER) + + half4 cocTL = _CoCTex.GatherRed(sampler_CoCTex, i.uv - uvOffs.xy * 0.5); // top-left + half4 cocBR = _CoCTex.GatherRed(sampler_CoCTex, i.uv + uvOffs.xy * 0.5); // bottom-right + half coc1 = cocTL.x; // top + half coc2 = cocTL.z; // left + half coc3 = cocBR.x; // bottom + half coc4 = cocBR.z; // right + +#else + + half coc1 = DOF_TEX2D(_CoCTex, i.uv - uvOffs.xz).r; // top + half coc2 = DOF_TEX2D(_CoCTex, i.uv - uvOffs.zy).r; // left + half coc3 = DOF_TEX2D(_CoCTex, i.uv + uvOffs.zy).r; // bottom + half coc4 = DOF_TEX2D(_CoCTex, i.uv + uvOffs.xz).r; // right + +#endif + + // Dejittered center sample. + half coc0 = DOF_TEX2D(_CoCTex, i.uv - _TaaParams.xy).r; + + // CoC dilation: determine the closest point in the four neighbors. + float3 closest = float3(0, 0, coc0); + closest = coc1 < closest.z ? float3(-uvOffs.xz, coc1) : closest; + closest = coc2 < closest.z ? float3(-uvOffs.zy, coc2) : closest; + closest = coc3 < closest.z ? float3(+uvOffs.zy, coc3) : closest; + closest = coc4 < closest.z ? float3(+uvOffs.xz, coc4) : closest; + + // Sample the history buffer with the motion vector at the closest point. + float2 motion = DOF_TEX2D(_CameraMotionVectorsTexture, i.uv + closest.xy).xy; + half cocHis = DOF_TEX2D(_MainTex, i.uv - motion).r; + + // Neighborhood clamping. + half cocMin = closest.z; + half cocMax = max(max(max(max(coc0, coc1), coc2), coc3), coc4); + cocHis = clamp(cocHis, cocMin, cocMax); + + // Blend with the history. + return lerp(coc0, cocHis, _TaaParams.z); +} + +// Prefilter: downsampling and premultiplying. +half4 FragPrefilter(VaryingsDOF i) : SV_Target +{ +#if defined(SEPARATE_TEXTURE_SAMPLER) + + // Sample source colors. + half4 c_r = _MainTex.GatherRed (sampler_MainTex, i.uv); + half4 c_g = _MainTex.GatherGreen(sampler_MainTex, i.uv); + half4 c_b = _MainTex.GatherBlue (sampler_MainTex, i.uv); + + half3 c0 = half3(c_r.x, c_g.x, c_b.x); + half3 c1 = half3(c_r.y, c_g.y, c_b.y); + half3 c2 = half3(c_r.z, c_g.z, c_b.z); + half3 c3 = half3(c_r.w, c_g.w, c_b.w); + + // Sample CoCs. + half4 cocs = _CoCTex.Gather(sampler_CoCTex, i.uvAlt) * 2.0 - 1.0; + half coc0 = cocs.x; + half coc1 = cocs.y; + half coc2 = cocs.z; + half coc3 = cocs.w; + +#else + + float3 duv = _MainTex_TexelSize.xyx * float3(0.5, 0.5, -0.5); + + // Sample source colors. + half3 c0 = DOF_TEX2D(_MainTex, i.uv - duv.xy).rgb; + half3 c1 = DOF_TEX2D(_MainTex, i.uv - duv.zy).rgb; + half3 c2 = DOF_TEX2D(_MainTex, i.uv + duv.zy).rgb; + half3 c3 = DOF_TEX2D(_MainTex, i.uv + duv.xy).rgb; + + // Sample CoCs. + half coc0 = DOF_TEX2D(_CoCTex, i.uvAlt - duv.xy).r * 2.0 - 1.0; + half coc1 = DOF_TEX2D(_CoCTex, i.uvAlt - duv.zy).r * 2.0 - 1.0; + half coc2 = DOF_TEX2D(_CoCTex, i.uvAlt + duv.zy).r * 2.0 - 1.0; + half coc3 = DOF_TEX2D(_CoCTex, i.uvAlt + duv.xy).r * 2.0 - 1.0; + +#endif + + // Apply CoC and luma weights to reduce bleeding and flickering. + float w0 = abs(coc0) / (Max3(c0) + 1.0); + float w1 = abs(coc1) / (Max3(c1) + 1.0); + float w2 = abs(coc2) / (Max3(c2) + 1.0); + float w3 = abs(coc3) / (Max3(c3) + 1.0); + + // Weighted average of the color samples + half3 avg = c0 * w0 + c1 * w1 + c2 * w2 + c3 * w3; + avg /= max(w0 + w1 + w2 + w3, 1e-5); + + // Select the largest CoC value. + half coc_min = Min4(coc0, coc1, coc2, coc3); + half coc_max = Max4(coc0, coc1, coc2, coc3); + half coc = (-coc_min > coc_max ? coc_min : coc_max) * _MaxCoC; + + // Premultiply CoC again. + avg *= smoothstep(0, _MainTex_TexelSize.y * 2, abs(coc)); + +#if defined(UNITY_COLORSPACE_GAMMA) + avg = GammaToLinearSpace(avg); +#endif + + return half4(avg, coc); +} + +// Bokeh filter with disk-shaped kernels +half4 FragBlur(VaryingsDOF i) : SV_Target +{ + half4 samp0 = DOF_TEX2D(_MainTex, i.uv); + + half4 bgAcc = 0.0; // Background: far field bokeh + half4 fgAcc = 0.0; // Foreground: near field bokeh + + UNITY_LOOP for (int si = 0; si < kSampleCount; si++) + { + float2 disp = kDiskKernel[si] * _MaxCoC; + float dist = length(disp); + + float2 duv = float2(disp.x * _RcpAspect, disp.y); + half4 samp = DOF_TEX2D(_MainTex, i.uv + duv); + + // BG: Compare CoC of the current sample and the center sample + // and select smaller one. + half bgCoC = max(min(samp0.a, samp.a), 0.0); + + // Compare the CoC to the sample distance. + // Add a small margin to smooth out. + const half margin = _MainTex_TexelSize.y * 2; + half bgWeight = saturate((bgCoC - dist + margin) / margin); + half fgWeight = saturate((-samp.a - dist + margin) / margin); + + // Cut influence from focused areas because they're darkened by CoC + // premultiplying. This is only needed for near field. + fgWeight *= step(_MainTex_TexelSize.y, -samp.a); + + // Accumulation + bgAcc += half4(samp.rgb, 1.0) * bgWeight; + fgAcc += half4(samp.rgb, 1.0) * fgWeight; + } + + // Get the weighted average. + bgAcc.rgb /= bgAcc.a + (bgAcc.a == 0.0); // zero-div guard + fgAcc.rgb /= fgAcc.a + (fgAcc.a == 0.0); + + // BG: Calculate the alpha value only based on the center CoC. + // This is a rather aggressive approximation but provides stable results. + bgAcc.a = smoothstep(_MainTex_TexelSize.y, _MainTex_TexelSize.y * 2.0, samp0.a); + + // FG: Normalize the total of the weights. + fgAcc.a *= UNITY_PI / kSampleCount; + + // Alpha premultiplying + half alpha = saturate(fgAcc.a); + half3 rgb = lerp(bgAcc.rgb, fgAcc.rgb, alpha); + + return half4(rgb, alpha); +} + +// Postfilter blur +half4 FragPostBlur(VaryingsDOF i) : SV_Target +{ + // 9 tap tent filter with 4 bilinear samples + const float4 duv = _MainTex_TexelSize.xyxy * float4(0.5, 0.5, -0.5, 0); + half4 acc; + acc = DOF_TEX2D(_MainTex, i.uv - duv.xy); + acc += DOF_TEX2D(_MainTex, i.uv - duv.zy); + acc += DOF_TEX2D(_MainTex, i.uv + duv.zy); + acc += DOF_TEX2D(_MainTex, i.uv + duv.xy); + return acc / 4.0; +} + +#endif // __DEPTH_OF_FIELD__ diff --git a/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc.meta b/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc.meta new file mode 100644 index 0000000..a811949 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DepthOfField.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ddc2c19b8a216d748a357ffe32ba4dc1 +timeCreated: 1472211508 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader b/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader new file mode 100644 index 0000000..ca9830c --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader @@ -0,0 +1,212 @@ +Shader "Hidden/Post FX/Depth Of Field" +{ + Properties + { + _MainTex ("", 2D) = "black" + } + + CGINCLUDE + #pragma exclude_renderers d3d11_9x + ENDCG + + // SubShader with SM 5.0 support + // Gather intrinsics are used to reduce texture sample count. + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass // 0 + { + Name "CoC Calculation" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragCoC + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 1 + { + Name "CoC Temporal Filter" + CGPROGRAM + #pragma target 5.0 + #pragma vertex VertDOF + #pragma fragment FragTempFilter + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 2 + { + Name "Downsample and Prefilter" + CGPROGRAM + #pragma target 5.0 + #pragma vertex VertDOF + #pragma fragment FragPrefilter + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 3 + { + Name "Bokeh Filter (small)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_SMALL + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 4 + { + Name "Bokeh Filter (medium)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_MEDIUM + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 5 + { + Name "Bokeh Filter (large)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_LARGE + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 6 + { + Name "Bokeh Filter (very large)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_VERYLARGE + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 7 + { + Name "Postfilter" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragPostBlur + #include "DepthOfField.cginc" + ENDCG + } + } + + // Fallback SubShader with SM 3.0 + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass // 0 + { + Name "CoC Calculation" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragCoC + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 1 + { + Name "CoC Temporal Filter" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragTempFilter + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 2 + { + Name "Downsample and Prefilter" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragPrefilter + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 3 + { + Name "Bokeh Filter (small)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_SMALL + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 4 + { + Name "Bokeh Filter (medium)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_MEDIUM + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 5 + { + Name "Bokeh Filter (large)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_LARGE + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 6 + { + Name "Bokeh Filter (very large)" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragBlur + #define KERNEL_VERYLARGE + #include "DepthOfField.cginc" + ENDCG + } + + Pass // 7 + { + Name "Postfilter" + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDOF + #pragma fragment FragPostBlur + #include "DepthOfField.cginc" + ENDCG + } + } + + FallBack Off +} diff --git a/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader.meta b/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader.meta new file mode 100644 index 0000000..2abcd4e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DepthOfField.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ac8ed710934a3564686a096bb351caee +timeCreated: 1465484939 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc b/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc new file mode 100644 index 0000000..6a8d12e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc @@ -0,0 +1,204 @@ +#ifndef __DISK_KERNELS__ +#define __DISK_KERNELS__ + +#if !defined(KERNEL_SMALL) && !defined(KERNEL_MEDIUM) && \ + !defined(KERNEL_LARGE) && !defined(KERNEL_VERYLARGE) + +static const int kSampleCount = 1; +static const float2 kDiskKernel[1] = { float2(0, 0) }; + +#endif + +#if defined(KERNEL_SMALL) + +// rings = 2 +// points per ring = 5 +static const int kSampleCount = 16; +static const float2 kDiskKernel[kSampleCount] = { + float2(0,0), + float2(0.54545456,0), + float2(0.16855472,0.5187581), + float2(-0.44128203,0.3206101), + float2(-0.44128197,-0.3206102), + float2(0.1685548,-0.5187581), + float2(1,0), + float2(0.809017,0.58778524), + float2(0.30901697,0.95105654), + float2(-0.30901703,0.9510565), + float2(-0.80901706,0.5877852), + float2(-1,0), + float2(-0.80901694,-0.58778536), + float2(-0.30901664,-0.9510566), + float2(0.30901712,-0.9510565), + float2(0.80901694,-0.5877853), +}; + +#endif + +#if defined(KERNEL_MEDIUM) + +// rings = 3 +// points per ring = 7 +static const int kSampleCount = 22; +static const float2 kDiskKernel[kSampleCount] = { + float2(0,0), + float2(0.53333336,0), + float2(0.3325279,0.4169768), + float2(-0.11867785,0.5199616), + float2(-0.48051673,0.2314047), + float2(-0.48051673,-0.23140468), + float2(-0.11867763,-0.51996166), + float2(0.33252785,-0.4169769), + float2(1,0), + float2(0.90096885,0.43388376), + float2(0.6234898,0.7818315), + float2(0.22252098,0.9749279), + float2(-0.22252095,0.9749279), + float2(-0.62349,0.7818314), + float2(-0.90096885,0.43388382), + float2(-1,0), + float2(-0.90096885,-0.43388376), + float2(-0.6234896,-0.7818316), + float2(-0.22252055,-0.974928), + float2(0.2225215,-0.9749278), + float2(0.6234897,-0.7818316), + float2(0.90096885,-0.43388376), +}; + +#endif + +#if defined(KERNEL_LARGE) + +// rings = 4 +// points per ring = 7 +static const int kSampleCount = 43; +static const float2 kDiskKernel[kSampleCount] = { + float2(0,0), + float2(0.36363637,0), + float2(0.22672357,0.28430238), + float2(-0.08091671,0.35451925), + float2(-0.32762504,0.15777594), + float2(-0.32762504,-0.15777591), + float2(-0.08091656,-0.35451928), + float2(0.22672352,-0.2843024), + float2(0.6818182,0), + float2(0.614297,0.29582983), + float2(0.42510667,0.5330669), + float2(0.15171885,0.6647236), + float2(-0.15171883,0.6647236), + float2(-0.4251068,0.53306687), + float2(-0.614297,0.29582986), + float2(-0.6818182,0), + float2(-0.614297,-0.29582983), + float2(-0.42510656,-0.53306705), + float2(-0.15171856,-0.66472363), + float2(0.1517192,-0.6647235), + float2(0.4251066,-0.53306705), + float2(0.614297,-0.29582983), + float2(1,0), + float2(0.9555728,0.2947552), + float2(0.82623875,0.5633201), + float2(0.6234898,0.7818315), + float2(0.36534098,0.93087375), + float2(0.07473,0.9972038), + float2(-0.22252095,0.9749279), + float2(-0.50000006,0.8660254), + float2(-0.73305196,0.6801727), + float2(-0.90096885,0.43388382), + float2(-0.98883086,0.14904208), + float2(-0.9888308,-0.14904249), + float2(-0.90096885,-0.43388376), + float2(-0.73305184,-0.6801728), + float2(-0.4999999,-0.86602545), + float2(-0.222521,-0.9749279), + float2(0.07473029,-0.99720377), + float2(0.36534148,-0.9308736), + float2(0.6234897,-0.7818316), + float2(0.8262388,-0.56332), + float2(0.9555729,-0.29475483), +}; + +#endif + +#if defined(KERNEL_VERYLARGE) + +// rings = 5 +// points per ring = 7 +static const int kSampleCount = 71; +static const float2 kDiskKernel[kSampleCount] = { + float2(0,0), + float2(0.2758621,0), + float2(0.1719972,0.21567768), + float2(-0.061385095,0.26894566), + float2(-0.24854316,0.1196921), + float2(-0.24854316,-0.11969208), + float2(-0.061384983,-0.2689457), + float2(0.17199717,-0.21567771), + float2(0.51724136,0), + float2(0.46601835,0.22442262), + float2(0.32249472,0.40439558), + float2(0.11509705,0.50427306), + float2(-0.11509704,0.50427306), + float2(-0.3224948,0.40439552), + float2(-0.46601835,0.22442265), + float2(-0.51724136,0), + float2(-0.46601835,-0.22442262), + float2(-0.32249463,-0.40439564), + float2(-0.11509683,-0.5042731), + float2(0.11509732,-0.504273), + float2(0.32249466,-0.40439564), + float2(0.46601835,-0.22442262), + float2(0.7586207,0), + float2(0.7249173,0.22360738), + float2(0.6268018,0.4273463), + float2(0.47299224,0.59311354), + float2(0.27715522,0.7061801), + float2(0.056691725,0.75649947), + float2(-0.168809,0.7396005), + float2(-0.3793104,0.65698475), + float2(-0.55610836,0.51599306), + float2(-0.6834936,0.32915324), + float2(-0.7501475,0.113066405), + float2(-0.7501475,-0.11306671), + float2(-0.6834936,-0.32915318), + float2(-0.5561083,-0.5159932), + float2(-0.37931028,-0.6569848), + float2(-0.16880904,-0.7396005), + float2(0.056691945,-0.7564994), + float2(0.2771556,-0.7061799), + float2(0.47299215,-0.59311366), + float2(0.62680185,-0.4273462), + float2(0.72491735,-0.22360711), + float2(1,0), + float2(0.9749279,0.22252093), + float2(0.90096885,0.43388376), + float2(0.7818315,0.6234898), + float2(0.6234898,0.7818315), + float2(0.43388364,0.9009689), + float2(0.22252098,0.9749279), + float2(0,1), + float2(-0.22252095,0.9749279), + float2(-0.43388385,0.90096885), + float2(-0.62349,0.7818314), + float2(-0.7818317,0.62348956), + float2(-0.90096885,0.43388382), + float2(-0.9749279,0.22252093), + float2(-1,0), + float2(-0.9749279,-0.22252087), + float2(-0.90096885,-0.43388376), + float2(-0.7818314,-0.6234899), + float2(-0.6234896,-0.7818316), + float2(-0.43388346,-0.900969), + float2(-0.22252055,-0.974928), + float2(0,-1), + float2(0.2225215,-0.9749278), + float2(0.4338835,-0.90096897), + float2(0.6234897,-0.7818316), + float2(0.78183144,-0.62348986), + float2(0.90096885,-0.43388376), + float2(0.9749279,-0.22252086), +}; + +#endif + +#endif // __DISK_KERNELS__ diff --git a/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc.meta b/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc.meta new file mode 100644 index 0000000..442620c --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/DiskKernels.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: faeb738b5a2c3ff43bd104dd5b1a275c +timeCreated: 1476954194 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc new file mode 100644 index 0000000..f2d1e1d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc @@ -0,0 +1,22 @@ +#ifndef __EYE_ADAPTATION__ +#define __EYE_ADAPTATION__ + +// Optimal values for PS4/GCN +// Using a group size of 32x32 seems to be a bit faster on Kepler/Maxwell +// Don't forget to update 'EyeAdaptationController.cs' if you change these values ! +#define HISTOGRAM_BINS 64 +#define HISTOGRAM_TEXELS HISTOGRAM_BINS / 4 +#define HISTOGRAM_THREAD_X 16 +#define HISTOGRAM_THREAD_Y 16 + +float GetHistogramBinFromLuminance(float value, float2 scaleOffset) +{ + return saturate(log2(value) * scaleOffset.x + scaleOffset.y); +} + +float GetLuminanceFromHistogramBin(float bin, float2 scaleOffset) +{ + return exp2((bin - scaleOffset.y) / scaleOffset.x); +} + +#endif // __EYE_ADAPTATION__ diff --git a/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc.meta b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc.meta new file mode 100644 index 0000000..23aa134 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d2f406cad28afda489b94594fb3ce0af +timeCreated: 1465898178 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader new file mode 100644 index 0000000..8ec509d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader @@ -0,0 +1,218 @@ +Shader "Hidden/Post FX/Eye Adaptation" +{ + Properties + { + _MainTex("Texture", 2D) = "white" {} + } + + CGINCLUDE + + #pragma target 4.5 + #pragma multi_compile __ AUTO_KEY_VALUE + #include "UnityCG.cginc" + #include "Common.cginc" + #include "EyeAdaptation.cginc" + + // Eye adaptation pass + float4 _Params; // x: lowPercent, y: highPercent, z: minBrightness, w: maxBrightness + float2 _Speed; // x: down, y: up + float4 _ScaleOffsetRes; // x: scale, y: offset, w: histogram pass width, h: histogram pass height + float _ExposureCompensation; + + StructuredBuffer _Histogram; + + float GetBinValue(uint index, float maxHistogramValue) + { + return float(_Histogram[index]) * maxHistogramValue; + } + + // Done in the vertex shader + float FindMaxHistogramValue() + { + uint maxValue = 0u; + + for (uint i = 0; i < HISTOGRAM_BINS; i++) + { + uint h = _Histogram[i]; + maxValue = max(maxValue, h); + } + + return float(maxValue); + } + + void FilterLuminance(uint i, float maxHistogramValue, inout float4 filter) + { + float binValue = GetBinValue(i, maxHistogramValue); + + // Filter dark areas + float offset = min(filter.z, binValue); + binValue -= offset; + filter.zw -= offset.xx; + + // Filter highlights + binValue = min(filter.w, binValue); + filter.w -= binValue; + + // Luminance at the bin + float luminance = GetLuminanceFromHistogramBin(float(i) / float(HISTOGRAM_BINS), _ScaleOffsetRes.xy); + + filter.xy += float2(luminance * binValue, binValue); + } + + float GetAverageLuminance(float maxHistogramValue) + { + // Sum of all bins + uint i; + float totalSum = 0.0; + + UNITY_LOOP + for (i = 0; i < HISTOGRAM_BINS; i++) + totalSum += GetBinValue(i, maxHistogramValue); + + // Skip darker and lighter parts of the histogram to stabilize the auto exposure + // x: filtered sum + // y: accumulator + // zw: fractions + float4 filter = float4(0.0, 0.0, totalSum * _Params.xy); + + UNITY_LOOP + for (i = 0; i < HISTOGRAM_BINS; i++) + FilterLuminance(i, maxHistogramValue, filter); + + // Clamp to user brightness range + return clamp(filter.x / max(filter.y, EPSILON), _Params.z, _Params.w); + } + + float GetExposureMultiplier(float avgLuminance) + { + avgLuminance = max(EPSILON, avgLuminance); + + #if AUTO_KEY_VALUE + half keyValue = 1.03 - (2.0 / (2.0 + log2(avgLuminance + 1.0))); + #else + half keyValue = _ExposureCompensation; + #endif + + half exposure = keyValue / avgLuminance; + + return exposure; + } + + float InterpolateExposure(float newExposure, float oldExposure) + { + float delta = newExposure - oldExposure; + float speed = delta > 0.0 ? _Speed.x : _Speed.y; + float exposure = oldExposure + delta * (1.0 - exp2(-unity_DeltaTime.x * speed)); + //float exposure = oldExposure + delta * (unity_DeltaTime.x * speed); + return exposure; + } + + float4 FragAdaptProgressive(VaryingsDefault i) : SV_Target + { + float maxValue = 1.0 / FindMaxHistogramValue(); + float avgLuminance = GetAverageLuminance(maxValue); + float exposure = GetExposureMultiplier(avgLuminance); + float prevExposure = tex2D(_MainTex, (0.5).xx); + exposure = InterpolateExposure(exposure, prevExposure); + return exposure.xxxx; + } + + float4 FragAdaptFixed(VaryingsDefault i) : SV_Target + { + float maxValue = 1.0 / FindMaxHistogramValue(); + float avgLuminance = GetAverageLuminance(maxValue); + float exposure = GetExposureMultiplier(avgLuminance); + return exposure.xxxx; + } + + // ---- Editor stuff + int _DebugWidth; + + struct VaryingsEditorHisto + { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float maxValue : TEXCOORD1; + float avgLuminance : TEXCOORD2; + }; + + VaryingsEditorHisto VertEditorHisto(AttributesDefault v) + { + VaryingsEditorHisto o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.maxValue = 1.0 / FindMaxHistogramValue(); + o.avgLuminance = GetAverageLuminance(o.maxValue); + return o; + } + + float4 FragEditorHisto(VaryingsEditorHisto i) : SV_Target + { + const float3 kRangeColor = float3(0.05, 0.4, 0.6); + const float3 kAvgColor = float3(0.8, 0.3, 0.05); + + float4 color = float4(0.0, 0.0, 0.0, 0.7); + + uint ix = (uint)(round(i.uv.x * HISTOGRAM_BINS)); + float bin = saturate(float(_Histogram[ix]) * i.maxValue); + float fill = step(i.uv.y, bin); + + // Min / max brightness markers + float luminanceMin = GetHistogramBinFromLuminance(_Params.z, _ScaleOffsetRes.xy); + float luminanceMax = GetHistogramBinFromLuminance(_Params.w, _ScaleOffsetRes.xy); + + color.rgb += fill.rrr; + + if (i.uv.x > luminanceMin && i.uv.x < luminanceMax) + { + color.rgb = fill.rrr * kRangeColor; + color.rgb += kRangeColor; + } + + // Current average luminance marker + float luminanceAvg = GetHistogramBinFromLuminance(i.avgLuminance, _ScaleOffsetRes.xy); + float avgPx = luminanceAvg * _DebugWidth; + + if (abs(i.pos.x - avgPx) < 2) + color.rgb = kAvgColor; + + return color; + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragAdaptProgressive + + ENDCG + } + + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragAdaptFixed + + ENDCG + } + + Pass + { + CGPROGRAM + + #pragma vertex VertEditorHisto + #pragma fragment FragEditorHisto + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader.meta b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader.meta new file mode 100644 index 0000000..74684fe --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeAdaptation.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 81899cddfbc72494497a6db0ae045f2c +timeCreated: 1465903628 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute b/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute new file mode 100644 index 0000000..d36ddc5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute @@ -0,0 +1,58 @@ +// Put the following line to 0 or comment it to disable vignette weighting +#define USE_VIGNETTE_WEIGHTING 1 + +#include "Common.cginc" +#include "EyeAdaptation.cginc" + +RWStructuredBuffer _Histogram; +Texture2D _Source; + +CBUFFER_START(Params) + float4 _ScaleOffsetRes; // x: scale, y: offset, z: width, w: height +CBUFFER_END + +groupshared uint gs_histogram[HISTOGRAM_BINS]; + +#pragma kernel KEyeHistogram +[numthreads(HISTOGRAM_THREAD_X,HISTOGRAM_THREAD_Y,1)] +void KEyeHistogram(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID) +{ + // Pretty straightforward implementation of histogram gathering using atomic ops. + // I tried a few methods (no atomic ops / heavy LDS leveraging) but this one turned out to be + // the fastest on desktop (Nvidia - Kepler/Maxwell) and PS4. Still need to try it on GCN/desktop + // but considering it runs very fast on PS4 we can expect it to run well (?). + + const uint localThreadId = groupThreadId.y * HISTOGRAM_THREAD_X + groupThreadId.x; + + // Clears the shared memory + if (localThreadId < HISTOGRAM_BINS) + gs_histogram[localThreadId] = 0u; + + GroupMemoryBarrierWithGroupSync(); + + // Gather local group histogram + if (dispatchThreadId.x < (uint)_ScaleOffsetRes.z && dispatchThreadId.y < (uint)_ScaleOffsetRes.w) + { +#if USE_VIGNETTE_WEIGHTING + // Vignette weighting to put more focus on what's in the center of the screen + float2 uv01 = float2(dispatchThreadId) / float2(_ScaleOffsetRes.z, _ScaleOffsetRes.w); + float2 d = abs(uv01 - (0.5).xx); + float vfactor = Pow2(saturate(1.0 - dot(d, d))); + uint weight = (uint)(64.0 * vfactor); +#else + uint weight = 1u; +#endif + + float3 color = _Source[dispatchThreadId].xyz; + float luminance = Max3(color); // Looks more natural than using a Rec.709 luminance for some reason + float logLuminance = GetHistogramBinFromLuminance(luminance, _ScaleOffsetRes.xy); + uint idx = (uint)(logLuminance * (HISTOGRAM_BINS - 1u)); + InterlockedAdd(gs_histogram[idx], weight); + } + + GroupMemoryBarrierWithGroupSync(); + + // Merge everything + if (localThreadId < HISTOGRAM_BINS) + InterlockedAdd(_Histogram[localThreadId], gs_histogram[localThreadId]); +} diff --git a/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute.meta b/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute.meta new file mode 100644 index 0000000..df8c12d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/EyeHistogram.compute.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e213272ad8ff213409a6e13b5c26b4e4 +timeCreated: 1464341416 +licenseType: Store +ComputeShaderImporter: + currentAPIMask: 4 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/FXAA.shader b/Assets/PostProcessing/Resources/Shaders/FXAA.shader new file mode 100644 index 0000000..bc5f88d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/FXAA.shader @@ -0,0 +1,85 @@ +Shader "Hidden/Post FX/FXAA" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + + CGINCLUDE + + #include "UnityCG.cginc" + #include "Common.cginc" + #include "UberSecondPass.cginc" + #pragma multi_compile __ GRAIN + #pragma multi_compile __ DITHERING + + #if defined(SHADER_API_PS3) + #define FXAA_PS3 1 + + // Shaves off 2 cycles from the shader + #define FXAA_EARLY_EXIT 0 + #elif defined(SHADER_API_XBOX360) + #define FXAA_360 1 + + // Shaves off 10ms from the shader's execution time + #define FXAA_EARLY_EXIT 1 + #else + #define FXAA_PC 1 + #endif + + #define FXAA_HLSL_3 1 + #define FXAA_QUALITY__PRESET 39 + + #define FXAA_GREEN_AS_LUMA 1 + + #pragma target 3.0 + #include "FXAA3.cginc" + + float3 _QualitySettings; + float4 _ConsoleSettings; + + half4 Frag(VaryingsDefault i) : SV_Target + { + const float4 consoleUV = i.uv.xyxy + 0.5 * float4(-_MainTex_TexelSize.xy, _MainTex_TexelSize.xy); + const float4 consoleSubpixelFrame = _ConsoleSettings.x * float4(-1.0, -1.0, 1.0, 1.0) * + _MainTex_TexelSize.xyxy; + + const float4 consoleSubpixelFramePS3 = float4(-2.0, -2.0, 2.0, 2.0) * _MainTex_TexelSize.xyxy; + const float4 consoleSubpixelFrameXBOX = float4(8.0, 8.0, -4.0, -4.0) * _MainTex_TexelSize.xyxy; + + #if defined(SHADER_API_XBOX360) + const float4 consoleConstants = float4(1.0, -1.0, 0.25, -0.25); + #else + const float4 consoleConstants = float4(0.0, 0.0, 0.0, 0.0); + #endif + + half4 color = FxaaPixelShader( + UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST), + UnityStereoScreenSpaceUVAdjust(consoleUV, _MainTex_ST), + _MainTex, _MainTex, _MainTex, _MainTex_TexelSize.xy, + consoleSubpixelFrame, consoleSubpixelFramePS3, consoleSubpixelFrameXBOX, + _QualitySettings.x, _QualitySettings.y, _QualitySettings.z, + _ConsoleSettings.y, _ConsoleSettings.z, _ConsoleSettings.w, consoleConstants); + + color.rgb = UberSecondPass(color.rgb, i.uv); + + return half4(color.rgb, 1.0); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment Frag + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/FXAA.shader.meta b/Assets/PostProcessing/Resources/Shaders/FXAA.shader.meta new file mode 100644 index 0000000..d796d06 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/FXAA.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 291f0d5b6045f4646847c59b4ce13ac5 +timeCreated: 1462350540 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc b/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc new file mode 100644 index 0000000..8b70f5d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc @@ -0,0 +1,2073 @@ +#ifndef __FXAA3_INC__ +#define __FXAA3_INC__ + +/*============================================================================ + + +NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ +INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + +#define FXAA_PC 1 +#define FXAA_HLSL_5 1 +#define FXAA_QUALITY__PRESET 12 + +Or, + +#define FXAA_360 1 + +Or, + +#define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + +#include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + +return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + +#define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + +FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2, +FxaaFloat4 fxaaConsole360RcpFrameOpt2, +FxaaFloat fxaaQualitySubpix, +FxaaFloat fxaaQualityEdgeThreshold, +FxaaFloat fxaaQualityEdgeThresholdMin, +FxaaFloat fxaaConsoleEdgeSharpness, +FxaaFloat fxaaConsoleEdgeThreshold, +FxaaFloat fxaaConsoleEdgeThresholdMin, +FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + +// {xy} = center of pixel +FxaaFloat2 pos, + +// {xy__} = upper left of pixel +// {__zw} = lower right of pixel +FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ +INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + +#define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + +color.rgb = ToneMap(color.rgb); // linear color output +color.rgb = sqrt(color.rgb); // gamma 2.0 color output +return color; + +To use FXAA, + +color.rgb = ToneMap(color.rgb); // linear color output +color.rgb = sqrt(color.rgb); // gamma 2.0 color output +color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma +return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + +color.rgb = ToneMap(color.rgb); // linear color output +return color; + +To use FXAA, + +color.rgb = ToneMap(color.rgb); // linear color output +color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma +return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ +BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ +COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, +have the pass write out luma into alpha. +Then blend into RGB only. +FXAA should be able to run ok +assuming the blending pass did not any add aliasing. +This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + +INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 +#define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 +#define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT +#define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC +// +// FXAA Quality +// The high quality PC algorithm. +// +#define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE +// +// The console algorithm for PC is included +// for developers targeting really low spec machines. +// Likely better to just run FXAA_PC, and use a really low preset. +// +#define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 +#define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 +#define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 +#define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 +#define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 +#define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA +// +// For those using non-linear color, +// and either not able to get luma in alpha, or not wanting to, +// this enables FXAA to run using green as a proxy for luma. +// So with this enabled, no need to pack luma in alpha. +// +// This will turn off AA on anything which lacks some amount of green. +// Pure red and blue or combination of only R and B, will get no AA. +// +// Might want to lower the settings for both, +// fxaaConsoleEdgeThresholdMin +// fxaaQualityEdgeThresholdMin +// In order to insure AA does not get turned off on colors +// which contain a minor amount of green. +// +// 1 = On. +// 0 = Off. +// +#define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT +// +// Controls algorithm's early exit path. +// On PS3 turning this ON adds 2 cycles to the shader. +// On 360 turning this OFF adds 10ths of a millisecond to the shader. +// Turning this off on console will result in a more blurry image. +// So this defaults to on. +// +// 1 = On. +// 0 = Off. +// +#define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD +// +// Only valid for PC OpenGL currently. +// Probably will not work when FXAA_GREEN_AS_LUMA = 1. +// +// 1 = Use discard on pixels which don't need AA. +// For APIs which enable concurrent TEX+ROP from same surface. +// 0 = Return unchanged color on pixels which don't need AA. +// +#define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET +// +// Used for GLSL 120 only. +// +// 1 = GL API supports fast pixel offsets +// 0 = do not use fast pixel offsets +// +#ifdef GL_EXT_gpu_shader4 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifdef GL_NV_gpu_shader5 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifdef GL_ARB_gpu_shader5 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifndef FXAA_FAST_PIXEL_OFFSET +#define FXAA_FAST_PIXEL_OFFSET 0 +#endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA +// +// 1 = API supports gather4 on alpha channel. +// 0 = API does not support gather4 on alpha channel. +// +#if (FXAA_HLSL_5 == 1) +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifdef GL_ARB_gpu_shader5 +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifdef GL_NV_gpu_shader5 +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifndef FXAA_GATHER4_ALPHA +#define FXAA_GATHER4_ALPHA 0 +#endif +#endif + +/*============================================================================ +FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS +// +// Consoles the sharpness of edges on PS3 only. +// Non-PS3 tuning is done with shader input. +// +// Due to the PS3 being ALU bound, +// there are only two safe values here: 4 and 8. +// These options use the shaders ability to a free *|/ by 2|4|8. +// +// 8.0 is sharper +// 4.0 is softer +// 2.0 is really soft (good for vector graphics inputs) +// +#if 1 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 +#endif +#if 0 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 +#endif +#if 0 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 +#endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD +// +// Only effects PS3. +// Non-PS3 tuning is done with shader input. +// +// The minimum amount of local contrast required to apply algorithm. +// The console setting has a different mapping than the quality setting. +// +// This only applies when FXAA_EARLY_EXIT is 1. +// +// Due to the PS3 being ALU bound, +// there are only two safe values here: 0.25 and 0.125. +// These options use the shaders ability to a free *|/ by 2|4|8. +// +// 0.125 leaves less aliasing, but is softer +// 0.25 leaves more aliasing, and is sharper +// +#if 1 +#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 +#else +#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 +#endif +#endif + +/*============================================================================ +FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET +// +// Choose the quality preset. +// This needs to be compiled into the shader as it effects code. +// Best option to include multiple presets is to +// in each shader define the preset, then include this file. +// +// OPTIONS +// ----------------------------------------------------------------------- +// 10 to 15 - default medium dither (10=fastest, 15=highest quality) +// 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) +// 39 - no dither, very expensive +// +// NOTES +// ----------------------------------------------------------------------- +// 12 = slightly faster then FXAA 3.9 and higher edge quality (default) +// 13 = about same speed as FXAA 3.9 and better than 12 +// 23 = closest to FXAA 3.9 visually and performance wise +// _ = the lowest digit is directly related to performance +// _ = the highest digit is directly related to style +// +#define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + +FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ +FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) +#define FXAA_QUALITY__PS 3 +#define FXAA_QUALITY__P0 1.5 +#define FXAA_QUALITY__P1 3.0 +#define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) +#define FXAA_QUALITY__PS 4 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 3.0 +#define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) +#define FXAA_QUALITY__PS 5 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 4.0 +#define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) +#define FXAA_QUALITY__PS 6 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 4.0 +#define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) +#define FXAA_QUALITY__PS 7 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 4.0 +#define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) +#define FXAA_QUALITY__PS 8 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 4.0 +#define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ +FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) +#define FXAA_QUALITY__PS 3 +#define FXAA_QUALITY__P0 1.5 +#define FXAA_QUALITY__P1 2.0 +#define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) +#define FXAA_QUALITY__PS 4 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) +#define FXAA_QUALITY__PS 5 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) +#define FXAA_QUALITY__PS 6 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) +#define FXAA_QUALITY__PS 7 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 3.0 +#define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) +#define FXAA_QUALITY__PS 8 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 4.0 +#define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) +#define FXAA_QUALITY__PS 9 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 4.0 +#define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) +#define FXAA_QUALITY__PS 10 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 4.0 +#define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) +#define FXAA_QUALITY__PS 11 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 4.0 +#define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) +#define FXAA_QUALITY__PS 12 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 2.0 +#define FXAA_QUALITY__P10 4.0 +#define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ +FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) +#define FXAA_QUALITY__PS 12 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.0 +#define FXAA_QUALITY__P2 1.0 +#define FXAA_QUALITY__P3 1.0 +#define FXAA_QUALITY__P4 1.0 +#define FXAA_QUALITY__P5 1.5 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 2.0 +#define FXAA_QUALITY__P10 4.0 +#define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + +API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) +#define FxaaBool bool +#define FxaaDiscard discard +#define FxaaFloat float +#define FxaaFloat2 vec2 +#define FxaaFloat3 vec3 +#define FxaaFloat4 vec4 +#define FxaaHalf float +#define FxaaHalf2 vec2 +#define FxaaHalf3 vec3 +#define FxaaHalf4 vec4 +#define FxaaInt2 ivec2 +#define FxaaSat(x) clamp(x, 0.0, 1.0) +#define FxaaTex sampler2D +#else +#define FxaaBool bool +#define FxaaDiscard clip(-1) +#define FxaaFloat float +#define FxaaFloat2 float2 +#define FxaaFloat3 float3 +#define FxaaFloat4 float4 +#define FxaaHalf half +#define FxaaHalf2 half2 +#define FxaaHalf3 half3 +#define FxaaHalf4 half4 +#define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) +// Requires, +// #version 120 +// And at least, +// #extension GL_EXT_gpu_shader4 : enable +// (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) +#define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) +#if (FXAA_FAST_PIXEL_OFFSET == 1) +#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) +#else +#define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) +#endif +#if (FXAA_GATHER4_ALPHA == 1) +// use #extension GL_ARB_gpu_shader5 : enable +#define FxaaTexAlpha4(t, p) textureGather(t, p, 3) +#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) +#define FxaaTexGreen4(t, p) textureGather(t, p, 1) +#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) +#endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) +// Requires "#version 130" or better +#define FxaaTexTop(t, p) textureLod(t, p, 0.0) +#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) +#if (FXAA_GATHER4_ALPHA == 1) +// use #extension GL_ARB_gpu_shader5 : enable +#define FxaaTexAlpha4(t, p) textureGather(t, p, 3) +#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) +#define FxaaTexGreen4(t, p) textureGather(t, p, 1) +#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) +#endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) +#define FxaaInt2 float2 +#define FxaaTex sampler2D +#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) +#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) +#define FxaaInt2 int2 +struct FxaaTex { SamplerState smpl; Texture2D tex; }; +#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) +#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) +#define FxaaInt2 int2 +struct FxaaTex { SamplerState smpl; Texture2D tex; }; +#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) +#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) +#define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) +#define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) +#define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ +GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) +FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else +FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + +FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { + /*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; +#if (FXAA_GATHER4_ALPHA == 1) +#if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); +#if (FXAA_GREEN_AS_LUMA == 0) +#define lumaM rgbyM.w +#else +#define lumaM rgbyM.y +#endif +#endif +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); +#else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); +#endif +#if (FXAA_DISCARD == 1) +#define lumaM luma4A.w +#endif +#define lumaE luma4A.z +#define lumaS luma4A.x +#define lumaSE luma4A.y +#define lumaNW luma4B.w +#define lumaN luma4B.z +#define lumaW luma4B.x +#else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); +#if (FXAA_GREEN_AS_LUMA == 0) +#define lumaM rgbyM.w +#else +#define lumaM rgbyM.y +#endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); +#endif + /*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; + /*--------------------------------------------------------------------------*/ + if (earlyExit) +#if (FXAA_DISCARD == 1) + FxaaDiscard; +#else + return rgbyM; +#endif + /*--------------------------------------------------------------------------*/ +#if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); +#else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); +#endif + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0 / range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; + /*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; + /*--------------------------------------------------------------------------*/ + if (!horzSpan) lumaN = lumaW; + if (!horzSpan) lumaS = lumaE; + if (horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0 / 12.0)) - lumaM; + /*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if (pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); + /*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = (horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if (!horzSpan) posB.x += lengthSign * 0.5; + if (horzSpan) posB.y += lengthSign * 0.5; + /*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); + /*--------------------------------------------------------------------------*/ + if (!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0 / 4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; + /*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; + /*--------------------------------------------------------------------------*/ + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 3) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 4) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 5) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 6) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 7) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 8) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 9) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 10) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 11) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; + /*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 12) + if (doneNP) + { + if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } +#endif + /*--------------------------------------------------------------------------*/ + } + /*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if (!horzSpan) dstN = posM.y - posN.y; + if (!horzSpan) dstP = posP.y - posM.y; + /*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0 / spanLength; + /*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; + /*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if (!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if (horzSpan) posM.y += pixelOffsetSubpix * lengthSign; +#if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); +#else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); +#endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + +FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with +#define FXAA_QUALITY__PRESET 10 +Or +#define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) +{ + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); + /*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; +#else + FxaaFloat lumaM = rgbyM.y; +#endif + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0 / 384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; + /*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if (lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; + /*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; + /*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); + /*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); + /*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); + /*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); + /*--------------------------------------------------------------------------*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); +#else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); +#endif + if (twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; +} +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) +{ + /*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; +#if (FXAA_GREEN_AS_LUMA == 0) + asm + { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD = false + }; +#else + asm + { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD = false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD = false + }; +#endif + /*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0 / 384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); + /*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); +#if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); +#else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); +#endif + if ((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; + /*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); + /*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; + /*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; + /*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); + /*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; + /*--------------------------------------------------------------------------*/ + float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; +} +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + +--fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ +NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: +0: texpkb h0.w(TRUE), v5.zyxx, #0 +2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x +4: texpkb h0.w(TRUE), v5.xwxx, #0 +6: addh h0.z(TRUE), -h2, h0.w +7: texpkb h1.w(TRUE), v5, #0 +9: addh h0.x(TRUE), h0.z, -h1.w +10: addh h3.w(TRUE), h0.z, h1 +11: texpkb h2.w(TRUE), v5.zwzz, #0 +13: addh h0.z(TRUE), h3.w, -h2.w +14: addh h0.x(TRUE), h2.w, h0 +15: nrmh h1.xz(TRUE), h0_n +16: minh_m8 h0.x(TRUE), |h1|, |h1.z| +17: maxh h4.w(TRUE), h0, h1 +18: divx h2.xy(TRUE), h1_n.xzzw, h0_n +19: movr r1.zw(TRUE), v4.xxxy +20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww +22: minh h5.w(TRUE), h0, h1 +23: texpkb h0(TRUE), r2.xzxx, #0 +25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 +27: maxh h4.x(TRUE), h2.z, h2.w +28: texpkb h1(TRUE), r0.zwzz, #0 +30: addh_d2 h1(TRUE), h0, h1 +31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +33: texpkb h0(TRUE), r0, #0 +35: minh h4.z(TRUE), h2, h2.w +36: fenct TRUE +37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +39: texpkb h2(TRUE), r1, #0 +41: addh_d2 h0(TRUE), h0, h2 +42: maxh h2.w(TRUE), h4, h4.x +43: minh h2.x(TRUE), h5.w, h4.z +44: addh_d2 h0(TRUE), h0, h1 +45: slth h2.x(TRUE), h0.w, h2 +46: sgth h2.w(TRUE), h0, h2 +47: movh h0(TRUE), h0 +48: addx.c0 rc(TRUE), h2, h2.w +49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- +1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; +| | | +2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; +| TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; +| SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; +| | | +3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; +| TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; +| SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; +| SCB1 | add | 10: ADDh h3.w, h0.---z, h1; +| | | +4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| SCB0 | add | 14: ADDh h0.x, h2.w---, h0; +| SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; +| | | +5 | SCT1 | mov | 15: NRMh h1.xz, h0; +| SRB | nrm | 15: NRMh h1.xz, h0; +| SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; +| SCB1 | max | 17: MAXh h4.w, h0, h1; +| | | +6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; +| SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; +| SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; +| SCB1 | min | 22: MINh h5.w, h0, h1; +| | | +7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; +| TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; +| SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; +| SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; +| | | +8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; +| TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; +| SCB0/1 | add | 30: ADDh/2 h1, h0, h1; +| | | +9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; +| SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; +| TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; +| SCB1 | min | 35: MINh h4.z, h2, h2.--w-; +| | | +10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; +| SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; +| TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; +| SCB0/1 | add | 41: ADDh/2 h0, h0, h2; +| | | +11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; +| SCT1 | max | 42: MAXh h2.w, h4, h4.---x; +| SCB0/1 | add | 44: ADDh/2 h0, h0, h1; +| | | +12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; +| SCT1 | set | 46: SGTh h2.w, h0, h2; +| SCB0/1 | mul | 47: MOVh h0, h0; +| | | +13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; +| SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB +1: 0% 100% 25% +2: 0% 100% 25% +3: 0% 100% 50% +4: 0% 100% 50% +5: 0% 0% 50% +6: 100% 0% 75% +7: 0% 100% 75% +8: 0% 100% 100% +9: 0% 100% 25% +10: 0% 100% 100% +11: 50% 0% 100% +12: 50% 0% 100% +13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 +1: 0% 0% 100% 0% 100% +2: 0% 0% 100% 0% 100% +3: 0% 0% 100% 100% 100% +4: 0% 0% 100% 100% 100% +5: 0% 0% 0% 100% 100% +6: 100% 100% 0% 100% 100% +7: 0% 0% 100% 100% 100% +8: 0% 0% 100% 100% 100% +9: 0% 0% 100% 0% 100% +10: 0% 0% 100% 100% 100% +11: 100% 100% 0% 100% 100% +12: 100% 100% 0% 100% 100% +13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) +{ + /*--------------------------------------------------------------------------*/ + // (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0 / 512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; +#else + lumaNe.y += half(1.0 / 512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; +#endif + /*--------------------------------------------------------------------------*/ + // (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; +#else + dir.x += lumaSw.y; + dir.z += lumaSw.y; +#endif + /*--------------------------------------------------------------------------*/ + // (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; +#else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; +#endif + /*--------------------------------------------------------------------------*/ + // (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; +#else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; +#endif + /*--------------------------------------------------------------------------*/ + // (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); + /*--------------------------------------------------------------------------*/ + // (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + /*--------------------------------------------------------------------------*/ + // (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + /*--------------------------------------------------------------------------*/ + // (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; + /*--------------------------------------------------------------------------*/ + // (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + /*--------------------------------------------------------------------------*/ + // (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; + /*--------------------------------------------------------------------------*/ + // (11) + // compilier moves these scalar ops up to other cycles +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); +#else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); +#endif + rgby2 = (rgby2 + rgby1) * 0.5; + /*--------------------------------------------------------------------------*/ + // (12) +#if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; +#else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; +#endif + /*--------------------------------------------------------------------------*/ + // (13) + if (twoTapLt || twoTapGt) rgby2 = rgby1; + /*--------------------------------------------------------------------------*/ + return rgby2; +} +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + +--fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ +NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: +0: texpkb h0.w(TRUE), v5.zyxx, #0 +2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x +4: texpkb h1.w(TRUE), v5.xwxx, #0 +6: addh h0.x(TRUE), h1.w, -h2.y +7: texpkb h2.w(TRUE), v5.zwzz, #0 +9: minh h4.w(TRUE), h2.y, h2 +10: maxh h5.x(TRUE), h2.y, h2.w +11: texpkb h0.w(TRUE), v5, #0 +13: addh h3.w(TRUE), -h0, h0.x +14: addh h0.x(TRUE), h0.w, h0 +15: addh h0.z(TRUE), -h2.w, h0.x +16: addh h0.x(TRUE), h2.w, h3.w +17: minh h5.y(TRUE), h0.w, h1.w +18: nrmh h2.xz(TRUE), h0_n +19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| +20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w +21: movr r1.zw(TRUE), v4.xxxy +22: maxh h2.w(TRUE), h0, h1 +23: fenct TRUE +24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz +26: texpkb h0(TRUE), r0, #0 +28: maxh h5.x(TRUE), h2.w, h5 +29: minh h5.w(TRUE), h5.y, h4 +30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz +32: texpkb h2(TRUE), r1, #0 +34: addh_d2 h2(TRUE), h0, h2 +35: texpkb h1(TRUE), v4, #0 +37: maxh h5.y(TRUE), h5.x, h1.w +38: minh h4.w(TRUE), h1, h5 +39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +41: texpkb h0(TRUE), r0, #0 +43: addh_m8 h5.z(TRUE), h5.y, -h4.w +44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +46: texpkb h3(TRUE), r2, #0 +48: addh_d2 h0(TRUE), h0, h3 +49: addh_d2 h3(TRUE), h0, h2 +50: movh h0(TRUE), h3 +51: slth h3.x(TRUE), h3.w, h5.w +52: sgth h3.w(TRUE), h3, h5.x +53: addx.c0 rc(TRUE), h3.x, h3 +54: slth.c0 rc(TRUE), h5.z, h5 +55: movh h0(c0.NE.w), h2 +56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- +1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; +| | | +2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; +| TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; +| SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; +| | | +3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; +| SCB1 | min | 9: MINh h4.w, h2.---y, h2; +| | | +4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; +| TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; +| SCB0 | add | 14: ADDh h0.x, h0.w---, h0; +| SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; +| | | +5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; +| SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; +| SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; +| | | +6 | SCT1 | mov | 18: NRMh h2.xz, h0; +| SRB | nrm | 18: NRMh h2.xz, h0; +| SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; +| | | +7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; +| SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; +| SCB1 | max | 22: MAXh h2.w, h0, h1; +| | | +8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; +| SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; +| TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; +| SCB0 | max | 28: MAXh h5.x, h2.w---, h5; +| SCB1 | min | 29: MINh h5.w, h5.---y, h4; +| | | +9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; +| SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; +| TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; +| SCB0/1 | add | 34: ADDh/2 h2, h0, h2; +| | | +10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; +| TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; +| SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; +| SCB1 | min | 38: MINh h4.w, h1, h5; +| | | +11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; +| SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; +| TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; +| SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; +| SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; +| | | +12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; +| TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; +| SCB0/1 | add | 48: ADDh/2 h0, h0, h3; +| | | +13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; +| SCB0/1 | mul | 50: MOVh h0, h3; +| | | +14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; +| SCT1 | set | 52: SGTh h3.w, h3, h5.---x; +| SCB0 | set | 54: SLThc0 rc, h5.z---, h5; +| SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; +| | | +15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; +| SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB +1: 0% 100% 25% +2: 0% 100% 25% +3: 0% 100% 50% +4: 0% 100% 50% +5: 50% 0% 25% +6: 0% 0% 25% +7: 100% 0% 25% +8: 0% 100% 50% +9: 0% 100% 100% +10: 0% 100% 50% +11: 0% 100% 75% +12: 0% 100% 100% +13: 100% 0% 100% +14: 50% 0% 50% +15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 +1: 0% 0% 100% 100% 0% +2: 0% 0% 100% 100% 0% +3: 0% 0% 100% 100% 100% +4: 0% 0% 100% 100% 100% +5: 100% 100% 0% 100% 0% +6: 0% 0% 0% 0% 100% +7: 100% 100% 0% 0% 100% +8: 0% 0% 100% 100% 100% +9: 0% 0% 100% 100% 100% +10: 0% 0% 100% 100% 100% +11: 0% 0% 100% 100% 100% +12: 0% 0% 100% 100% 100% +13: 100% 100% 0% 100% 100% +14: 100% 100% 0% 100% 100% +15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) +{ + /*--------------------------------------------------------------------------*/ + // (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0 / 512.0); +#else + half lumaNe = rgbyNe.y + half(1.0 / 512.0); +#endif + /*--------------------------------------------------------------------------*/ + // (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; +#else + half lumaSwNegNe = lumaSw.y - lumaNe; +#endif + /*--------------------------------------------------------------------------*/ + // (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); +#else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); +#endif + /*--------------------------------------------------------------------------*/ + // (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; +#else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; +#endif + /*--------------------------------------------------------------------------*/ + // (5) + half3 dir; + dir.y = 0.0; +#if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); +#else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); +#endif + /*--------------------------------------------------------------------------*/ + // (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); + /*--------------------------------------------------------------------------*/ + // (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); +#else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); +#endif + /*--------------------------------------------------------------------------*/ + // (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); + /*--------------------------------------------------------------------------*/ + // (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; + /*--------------------------------------------------------------------------*/ + // (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); +#if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); +#else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); +#endif + /*--------------------------------------------------------------------------*/ + // (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; + /*--------------------------------------------------------------------------*/ + // (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; + /*--------------------------------------------------------------------------*/ + // (13) + rgby2 = (rgby2 + rgby1) * 0.5; + /*--------------------------------------------------------------------------*/ + // (14) +#if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; +#else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; +#endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; + /*--------------------------------------------------------------------------*/ + // (15) + if (twoTap) rgby2 = rgby1; + if (earlyExit) rgby2 = rgbyM; + /*--------------------------------------------------------------------------*/ + return rgby2; +} +/*==========================================================================*/ +#endif + +#endif // __FXAA3_INC__ diff --git a/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc.meta b/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc.meta new file mode 100644 index 0000000..323e52b --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/FXAA3.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 613b4036a9f55c34fb054bde02455e46 +timeCreated: 1462350552 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Fog.shader b/Assets/PostProcessing/Resources/Shaders/Fog.shader new file mode 100644 index 0000000..b607a64 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Fog.shader @@ -0,0 +1,109 @@ +Shader "Hidden/Post FX/Fog" +{ + Properties + { + _MainTex("Main Texture", 2D) = "white" {} + } + + CGINCLUDE + + #pragma multi_compile __ FOG_LINEAR FOG_EXP FOG_EXP2 + #include "UnityCG.cginc" + #include "Common.cginc" + + #define SKYBOX_THREASHOLD_VALUE 0.9999 + + struct Varyings + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + Varyings VertFog(AttributesDefault v) + { + Varyings o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST); + return o; + } + + sampler2D _CameraDepthTexture; + + half4 _FogColor; + float _Density; + float _Start; + float _End; + + half ComputeFog(float z) + { + half fog = 0.0; + #if FOG_LINEAR + fog = (_End - z) / (_End - _Start); + #elif FOG_EXP + fog = exp2(-_Density * z); + #else // FOG_EXP2 + fog = _Density * z; + fog = exp2(-fog * fog); + #endif + return saturate(fog); + } + + float ComputeDistance(float depth) + { + float dist = depth * _ProjectionParams.z; + dist -= _ProjectionParams.y; + return dist; + } + + half4 FragFog(Varyings i) : SV_Target + { + half4 color = tex2D(_MainTex, i.uv); + + float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); + depth = Linear01Depth(depth); + float dist = ComputeDistance(depth); + half fog = 1.0 - ComputeFog(dist); + + return lerp(color, _FogColor, fog); + } + + half4 FragFogExcludeSkybox(Varyings i) : SV_Target + { + half4 color = tex2D(_MainTex, i.uv); + + float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); + depth = Linear01Depth(depth); + float skybox = depth < SKYBOX_THREASHOLD_VALUE; + float dist = ComputeDistance(depth); + half fog = 1.0 - ComputeFog(dist); + + return lerp(color, _FogColor, fog * skybox); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + + #pragma vertex VertFog + #pragma fragment FragFog + + ENDCG + } + + Pass + { + CGPROGRAM + + #pragma vertex VertFog + #pragma fragment FragFogExcludeSkybox + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/Fog.shader.meta b/Assets/PostProcessing/Resources/Shaders/Fog.shader.meta new file mode 100644 index 0000000..19ca28e --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Fog.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2a72fc91cbae3cc4686a6143e8517993 +timeCreated: 1487335480 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/GrainGen.shader b/Assets/PostProcessing/Resources/Shaders/GrainGen.shader new file mode 100644 index 0000000..0c1bc81 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/GrainGen.shader @@ -0,0 +1,104 @@ +Shader "Hidden/Post FX/Grain Generator" +{ + CGINCLUDE + + #pragma exclude_renderers d3d11_9x + #pragma target 3.0 + #include "UnityCG.cginc" + #include "Common.cginc" + + float _Phase; + + // Implementation based on Timothy Lottes' "Large Grain" + // Reference code: https://www.shadertoy.com/view/4sSXDW + // Other article of interest: http://devlog-martinsh.blogspot.fr/2013/05/image-imperfections-and-film-grain-post.html + float Noise(float2 n, float x) + { + n += x; + return frac(sin(dot(n.xy, float2(12.9898, 78.233))) * 43758.5453); + } + + float Step1(float2 uv, float n) + { + float b = 2.0, c = -12.0; + return (1.0 / (4.0 + b * 4.0 + abs(c))) * ( + Noise(uv + float2(-1.0, -1.0), n) + + Noise(uv + float2( 0.0, -1.0), n) * b + + Noise(uv + float2( 1.0, -1.0), n) + + Noise(uv + float2(-1.0, 0.0), n) * b + + Noise(uv + float2( 0.0, 0.0), n) * c + + Noise(uv + float2( 1.0, 0.0), n) * b + + Noise(uv + float2(-1.0, 1.0), n) + + Noise(uv + float2( 0.0, 1.0), n) * b + + Noise(uv + float2( 1.0, 1.0), n) + ); + } + + float Step2(float2 uv, float n) + { + float b = 2.0, c = 4.0; + return (1.0 / (4.0 + b * 4.0 + abs(c))) * ( + Step1(uv + float2(-1.0, -1.0), n) + + Step1(uv + float2( 0.0, -1.0), n) * b + + Step1(uv + float2( 1.0, -1.0), n) + + Step1(uv + float2(-1.0, 0.0), n) * b + + Step1(uv + float2( 0.0, 0.0), n) * c + + Step1(uv + float2( 1.0, 0.0), n) * b + + Step1(uv + float2(-1.0, 1.0), n) + + Step1(uv + float2( 0.0, 1.0), n) * b + + Step1(uv + float2( 1.0, 1.0), n) + ); + } + + float Step3BW(float2 uv) + { + return Step2(uv, frac(_Phase)); + } + + float3 Step3(float2 uv) + { + float a = Step2(uv, 0.07 * frac(_Phase)); + float b = Step2(uv, 0.11 * frac(_Phase)); + float c = Step2(uv, 0.13 * frac(_Phase)); + return float3(a, b, c); + } + + float4 FragGrain(VaryingsDefault i) : SV_Target + { + float grain = Step3BW(i.uv * float2(192.0, 192.0)); + return float4(grain.xxx, 1.0); + } + + float4 FragGrainColored(VaryingsDefault i) : SV_Target + { + float3 grain = Step3(i.uv * float2(192.0, 192.0)); + return float4(grain, 1.0); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragGrain + + ENDCG + } + + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragGrainColored + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/GrainGen.shader.meta b/Assets/PostProcessing/Resources/Shaders/GrainGen.shader.meta new file mode 100644 index 0000000..86193be --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/GrainGen.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 11852d1b1b034654bb03e7c8fda28fbf +timeCreated: 1476347976 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/LutGen.shader b/Assets/PostProcessing/Resources/Shaders/LutGen.shader new file mode 100644 index 0000000..659ab54 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/LutGen.shader @@ -0,0 +1,128 @@ +Shader "Hidden/Post FX/Lut Generator" +{ + CGINCLUDE + + #pragma target 3.0 + #pragma multi_compile __ TONEMAPPING_NEUTRAL TONEMAPPING_FILMIC + + #include "UnityCG.cginc" + #include "ACES.cginc" + #include "Common.cginc" + #include "ColorGrading.cginc" + #include "Tonemapping.cginc" + + half3 _Balance; + + half3 _Lift; + half3 _InvGamma; + half3 _Gain; + + half3 _Offset; + half3 _Power; + half3 _Slope; + + half _HueShift; + half _Saturation; + half _Contrast; + + half3 _ChannelMixerRed; + half3 _ChannelMixerGreen; + half3 _ChannelMixerBlue; + + half4 _NeutralTonemapperParams1; + half4 _NeutralTonemapperParams2; + + sampler2D _Curves; + + half4 _LutParams; + + half3 ColorGrade(half3 color) + { + half3 aces = unity_to_ACES(color); + + // ACEScc (log) space + half3 acescc = ACES_to_ACEScc(aces); + + acescc = OffsetPowerSlope(acescc, _Offset, _Power, _Slope); + + half2 hs = RgbToHsv(acescc).xy; + half satMultiplier = SecondaryHueSat(hs.x, _Curves); + satMultiplier *= SecondarySatSat(hs.y, _Curves); + satMultiplier *= SecondaryLumSat(AcesLuminance(acescc), _Curves); + + acescc = Saturation(acescc, _Saturation * satMultiplier); + acescc = ContrastLog(acescc, _Contrast); + + aces = ACEScc_to_ACES(acescc); + + // ACEScg (linear) space + half3 acescg = ACES_to_ACEScg(aces); + + acescg = WhiteBalance(acescg, _Balance); + acescg = LiftGammaGain(acescg, _Lift, _InvGamma, _Gain); + + half3 hsv = RgbToHsv(max(acescg, 0.0)); + hsv.x = SecondaryHueHue(hsv.x + _HueShift, _Curves); + acescg = HsvToRgb(hsv); + + acescg = ChannelMixer(acescg, _ChannelMixerRed, _ChannelMixerGreen, _ChannelMixerBlue); + + #if TONEMAPPING_FILMIC + + aces = ACEScg_to_ACES(acescg); + color = FilmicTonemap(aces); + + #elif TONEMAPPING_NEUTRAL + + color = ACEScg_to_unity(acescg); + color = NeutralTonemap(color, _NeutralTonemapperParams1, _NeutralTonemapperParams2); + + #else + + color = ACEScg_to_unity(acescg); + + #endif + + // YRGB curves (done in linear/LDR for now) + color = YrgbCurve(color, _Curves); + + return color; + } + + half4 FragCreateLut(VaryingsDefault i) : SV_Target + { + // 2D strip lut + half2 uv = i.uv - _LutParams.yz; + half3 color; + color.r = frac(uv.x * _LutParams.x); + color.b = uv.x - color.r / _LutParams.x; + color.g = uv.y; + + // Lut is in LogC + half3 colorLogC = color * _LutParams.w; + + // Switch back to unity linear and color grade + half3 colorLinear = LogCToLinear(colorLogC); + half3 graded = ColorGrade(colorLinear); + + return half4(graded, 1.0); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) + Pass + { + CGPROGRAM + + #pragma vertex VertDefault + #pragma fragment FragCreateLut + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/LutGen.shader.meta b/Assets/PostProcessing/Resources/Shaders/LutGen.shader.meta new file mode 100644 index 0000000..f1eda40 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/LutGen.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d248d4d1588851f43a9fa18a4e6f0209 +timeCreated: 1460361871 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc b/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc new file mode 100644 index 0000000..eca446a --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc @@ -0,0 +1,420 @@ +#ifndef __MOTION_BLUR__ +#define __MOTION_BLUR__ + +#include "UnityCG.cginc" +#include "Common.cginc" + +// Camera depth texture +sampler2D_float _CameraDepthTexture; + +// Camera motion vectors texture +sampler2D_half _CameraMotionVectorsTexture; +float4 _CameraMotionVectorsTexture_TexelSize; + +// Packed velocity texture (2/10/10/10) +sampler2D_half _VelocityTex; +float2 _VelocityTex_TexelSize; + +// NeighborMax texture +sampler2D_half _NeighborMaxTex; +float2 _NeighborMaxTex_TexelSize; + +// Velocity scale factor +float _VelocityScale; + +// TileMax filter parameters +int _TileMaxLoop; +float2 _TileMaxOffs; + +// Maximum blur radius (in pixels) +half _MaxBlurRadius; +float _RcpMaxBlurRadius; + +// Filter parameters/coefficients +half _LoopCount; + +// History buffer for frame blending +sampler2D _History1LumaTex; +sampler2D _History2LumaTex; +sampler2D _History3LumaTex; +sampler2D _History4LumaTex; + +sampler2D _History1ChromaTex; +sampler2D _History2ChromaTex; +sampler2D _History3ChromaTex; +sampler2D _History4ChromaTex; + +half _History1Weight; +half _History2Weight; +half _History3Weight; +half _History4Weight; + +struct VaryingsMultitex +{ + float4 pos : SV_POSITION; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; +}; + +VaryingsMultitex VertMultitex(AttributesDefault v) +{ + VaryingsMultitex o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv0 = v.texcoord.xy; + o.uv1 = v.texcoord.xy; + +#if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0.0) + o.uv1.y = 1.0 - v.texcoord.y; +#endif + + return o; +} + +// ----------------------------------------------------------------------------- +// Prefilter + +// Velocity texture setup +half4 FragVelocitySetup(VaryingsDefault i) : SV_Target +{ + // Sample the motion vector. + float2 v = tex2D(_CameraMotionVectorsTexture, i.uv).rg; + + // Apply the exposure time and convert to the pixel space. + v *= (_VelocityScale * 0.5) * _CameraMotionVectorsTexture_TexelSize.zw; + + // Clamp the vector with the maximum blur radius. + v /= max(1.0, length(v) * _RcpMaxBlurRadius); + + // Sample the depth of the pixel. + half d = LinearizeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv)); + + // Pack into 10/10/10/2 format. + return half4((v * _RcpMaxBlurRadius + 1.0) * 0.5, d, 0.0); +} + +// TileMax filter (2 pixel width with normalization) +half4 FragTileMax1(VaryingsDefault i) : SV_Target +{ + float4 d = _MainTex_TexelSize.xyxy * float4(-0.5, -0.5, 0.5, 0.5); + + half2 v1 = tex2D(_MainTex, i.uv + d.xy).rg; + half2 v2 = tex2D(_MainTex, i.uv + d.zy).rg; + half2 v3 = tex2D(_MainTex, i.uv + d.xw).rg; + half2 v4 = tex2D(_MainTex, i.uv + d.zw).rg; + + v1 = (v1 * 2.0 - 1.0) * _MaxBlurRadius; + v2 = (v2 * 2.0 - 1.0) * _MaxBlurRadius; + v3 = (v3 * 2.0 - 1.0) * _MaxBlurRadius; + v4 = (v4 * 2.0 - 1.0) * _MaxBlurRadius; + + return half4(MaxV(MaxV(MaxV(v1, v2), v3), v4), 0.0, 0.0); +} + +// TileMax filter (2 pixel width) +half4 FragTileMax2(VaryingsDefault i) : SV_Target +{ + float4 d = _MainTex_TexelSize.xyxy * float4(-0.5, -0.5, 0.5, 0.5); + + half2 v1 = tex2D(_MainTex, i.uv + d.xy).rg; + half2 v2 = tex2D(_MainTex, i.uv + d.zy).rg; + half2 v3 = tex2D(_MainTex, i.uv + d.xw).rg; + half2 v4 = tex2D(_MainTex, i.uv + d.zw).rg; + + return half4(MaxV(MaxV(MaxV(v1, v2), v3), v4), 0.0, 0.0); +} + +// TileMax filter (variable width) +half4 FragTileMaxV(VaryingsDefault i) : SV_Target +{ + float2 uv0 = i.uv + _MainTex_TexelSize.xy * _TileMaxOffs.xy; + + float2 du = float2(_MainTex_TexelSize.x, 0.0); + float2 dv = float2(0, _MainTex_TexelSize.y); + + half2 vo = 0; + + UNITY_LOOP + for (int ix = 0; ix < _TileMaxLoop; ix++) + { + UNITY_LOOP + for (int iy = 0; iy < _TileMaxLoop; iy++) + { + float2 uv = uv0 + du * ix + dv * iy; + vo = MaxV(vo, tex2D(_MainTex, uv).rg); + } + } + + return half4(vo, 0.0, 0.0); +} + +// NeighborMax filter +half4 FragNeighborMax(VaryingsDefault i) : SV_Target +{ + const half cw = 1.01; // Center weight tweak + + float4 d = _MainTex_TexelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0); + + half2 v1 = tex2D(_MainTex, i.uv - d.xy).rg; + half2 v2 = tex2D(_MainTex, i.uv - d.wy).rg; + half2 v3 = tex2D(_MainTex, i.uv - d.zy).rg; + + half2 v4 = tex2D(_MainTex, i.uv - d.xw).rg; + half2 v5 = tex2D(_MainTex, i.uv).rg * cw; + half2 v6 = tex2D(_MainTex, i.uv + d.xw).rg; + + half2 v7 = tex2D(_MainTex, i.uv + d.zy).rg; + half2 v8 = tex2D(_MainTex, i.uv + d.wy).rg; + half2 v9 = tex2D(_MainTex, i.uv + d.xy).rg; + + half2 va = MaxV(v1, MaxV(v2, v3)); + half2 vb = MaxV(v4, MaxV(v5, v6)); + half2 vc = MaxV(v7, MaxV(v8, v9)); + + return half4(MaxV(va, MaxV(vb, vc)) * (1.0 / cw), 0.0, 0.0); +} + +// ----------------------------------------------------------------------------- +// Reconstruction + +// Returns true or false with a given interval. +bool Interval(half phase, half interval) +{ + return frac(phase / interval) > 0.499; +} + +// Jitter function for tile lookup +float2 JitterTile(float2 uv) +{ + float rx, ry; + sincos(GradientNoise(uv + float2(2.0, 0.0)) * UNITY_PI_2, ry, rx); + return float2(rx, ry) * _NeighborMaxTex_TexelSize.xy * 0.25; +} + +// Velocity sampling function +half3 SampleVelocity(float2 uv) +{ + half3 v = tex2Dlod(_VelocityTex, float4(uv, 0.0, 0.0)).xyz; + return half3((v.xy * 2.0 - 1.0) * _MaxBlurRadius, v.z); +} + +// Reconstruction filter +half4 FragReconstruction(VaryingsMultitex i) : SV_Target +{ + // Color sample at the center point + const half4 c_p = tex2D(_MainTex, i.uv0); + + // Velocity/Depth sample at the center point + const half3 vd_p = SampleVelocity(i.uv1); + const half l_v_p = max(length(vd_p.xy), 0.5); + const half rcp_d_p = 1.0 / vd_p.z; + + // NeighborMax vector sample at the center point + const half2 v_max = tex2D(_NeighborMaxTex, i.uv1 + JitterTile(i.uv1)).xy; + const half l_v_max = length(v_max); + const half rcp_l_v_max = 1.0 / l_v_max; + + // Escape early if the NeighborMax vector is small enough. + if (l_v_max < 2.0) return c_p; + + // Use V_p as a secondary sampling direction except when it's too small + // compared to V_max. This vector is rescaled to be the length of V_max. + const half2 v_alt = (l_v_p * 2.0 > l_v_max) ? vd_p.xy * (l_v_max / l_v_p) : v_max; + + // Determine the sample count. + const half sc = floor(min(_LoopCount, l_v_max * 0.5)); + + // Loop variables (starts from the outermost sample) + const half dt = 1.0 / sc; + const half t_offs = (GradientNoise(i.uv0) - 0.5) * dt; + half t = 1.0 - dt * 0.5; + half count = 0.0; + + // Background velocity + // This is used for tracking the maximum velocity in the background layer. + half l_v_bg = max(l_v_p, 1.0); + + // Color accumlation + half4 acc = 0.0; + + UNITY_LOOP while (t > dt * 0.25) + { + // Sampling direction (switched per every two samples) + const half2 v_s = Interval(count, 4.0) ? v_alt : v_max; + + // Sample position (inverted per every sample) + const half t_s = (Interval(count, 2.0) ? -t : t) + t_offs; + + // Distance to the sample position + const half l_t = l_v_max * abs(t_s); + + // UVs for the sample position + const float2 uv0 = i.uv0 + v_s * t_s * _MainTex_TexelSize.xy; + const float2 uv1 = i.uv1 + v_s * t_s * _VelocityTex_TexelSize.xy; + + // Color sample + const half3 c = tex2Dlod(_MainTex, float4(uv0, 0.0, 0.0)).rgb; + + // Velocity/Depth sample + const half3 vd = SampleVelocity(uv1); + + // Background/Foreground separation + const half fg = saturate((vd_p.z - vd.z) * 20.0 * rcp_d_p); + + // Length of the velocity vector + const half l_v = lerp(l_v_bg, length(vd.xy), fg); + + // Sample weight + // (Distance test) * (Spreading out by motion) * (Triangular window) + const half w = saturate(l_v - l_t) / l_v * (1.2 - t); + + // Color accumulation + acc += half4(c, 1.0) * w; + + // Update the background velocity. + l_v_bg = max(l_v_bg, l_v); + + // Advance to the next sample. + t = Interval(count, 2.0) ? t - dt : t; + count += 1.0; + } + + // Add the center sample. + acc += half4(c_p.rgb, 1.0) * (1.2 / (l_v_bg * sc * 2.0)); + + return half4(acc.rgb / acc.a, c_p.a); +} + +// ----------------------------------------------------------------------------- +// Frame blending + +VaryingsDefault VertFrameCompress(AttributesDefault v) +{ + VaryingsDefault o; + o.pos = v.vertex; + o.uvSPR = 0; +#if UNITY_UV_STARTS_AT_TOP + o.uv = v.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0); +#else + o.uv = v.texcoord; +#endif + return o; +} + +#if !SHADER_API_GLES + +// MRT output struct for the compressor +struct CompressorOutput +{ + half4 luma : SV_Target0; + half4 chroma : SV_Target1; +}; + +// Frame compression fragment shader +CompressorOutput FragFrameCompress(VaryingsDefault i) +{ + float sw = _ScreenParams.x; // Screen width + float pw = _ScreenParams.z - 1; // Pixel width + + // RGB to YCbCr convertion matrix + const half3 kY = half3( 0.299 , 0.587 , 0.114 ); + const half3 kCB = half3(-0.168736, -0.331264, 0.5 ); + const half3 kCR = half3( 0.5 , -0.418688, -0.081312); + + // 0: even column, 1: odd column + half odd = frac(i.uv.x * sw * 0.5) > 0.5; + + // Calculate UV for chroma componetns. + // It's between the even and odd columns. + float2 uv_c = i.uv.xy; + uv_c.x = (floor(uv_c.x * sw * 0.5) * 2.0 + 1.0) * pw; + + // Sample the source texture. + half3 rgb_y = tex2D(_MainTex, i.uv).rgb; + half3 rgb_c = tex2D(_MainTex, uv_c).rgb; + + #if !UNITY_COLORSPACE_GAMMA + rgb_y = LinearToGammaSpace(rgb_y); + rgb_c = LinearToGammaSpace(rgb_c); + #endif + + // Convertion and subsampling + CompressorOutput o; + o.luma = dot(kY, rgb_y); + o.chroma = dot(lerp(kCB, kCR, odd), rgb_c) + 0.5; + return o; +} + +#else + +// MRT might not be supported. Replace it with a null shader. +half4 FragFrameCompress(VaryingsDefault i) : SV_Target +{ + return 0; +} + +#endif + +// Sample luma-chroma textures and convert to RGB +half3 DecodeHistory(float2 uvLuma, float2 uvCb, float2 uvCr, sampler2D lumaTex, sampler2D chromaTex) +{ + half y = tex2D(lumaTex, uvLuma).r; + half cb = tex2D(chromaTex, uvCb).r - 0.5; + half cr = tex2D(chromaTex, uvCr).r - 0.5; + return y + half3(1.402 * cr, -0.34414 * cb - 0.71414 * cr, 1.772 * cb); +} + +// Frame blending fragment shader +half4 FragFrameBlending(VaryingsMultitex i) : SV_Target +{ + float sw = _MainTex_TexelSize.z; // Texture width + float pw = _MainTex_TexelSize.x; // Texel width + + // UV for luma + float2 uvLuma = i.uv1; + + // UV for Cb (even columns) + float2 uvCb = i.uv1; + uvCb.x = (floor(uvCb.x * sw * 0.5) * 2.0 + 0.5) * pw; + + // UV for Cr (even columns) + float2 uvCr = uvCb; + uvCr.x += pw; + + // Sample from the source image + half4 src = tex2D(_MainTex, i.uv0); + + // Sampling and blending + #if UNITY_COLORSPACE_GAMMA + half3 acc = src.rgb; + #else + half3 acc = LinearToGammaSpace(src.rgb); + #endif + + acc += DecodeHistory(uvLuma, uvCb, uvCr, _History1LumaTex, _History1ChromaTex) * _History1Weight; + acc += DecodeHistory(uvLuma, uvCb, uvCr, _History2LumaTex, _History2ChromaTex) * _History2Weight; + acc += DecodeHistory(uvLuma, uvCb, uvCr, _History3LumaTex, _History3ChromaTex) * _History3Weight; + acc += DecodeHistory(uvLuma, uvCb, uvCr, _History4LumaTex, _History4ChromaTex) * _History4Weight; + acc /= 1.0 + _History1Weight + _History2Weight +_History3Weight +_History4Weight; + + #if !UNITY_COLORSPACE_GAMMA + acc = GammaToLinearSpace(acc); + #endif + + return half4(acc, src.a); +} + +// Frame blending fragment shader (without chroma subsampling) +half4 FragFrameBlendingRaw(VaryingsMultitex i) : SV_Target +{ + half4 src = tex2D(_MainTex, i.uv0); + half3 acc = src.rgb; + acc += tex2D(_History1LumaTex, i.uv0) * _History1Weight; + acc += tex2D(_History2LumaTex, i.uv0) * _History2Weight; + acc += tex2D(_History3LumaTex, i.uv0) * _History3Weight; + acc += tex2D(_History4LumaTex, i.uv0) * _History4Weight; + acc /= 1.0 + _History1Weight + _History2Weight +_History3Weight +_History4Weight; + return half4(acc, src.a); +} + +#endif // __MOTION_BLUR__ diff --git a/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc.meta b/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc.meta new file mode 100644 index 0000000..6e4c810 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/MotionBlur.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c83956915580e42489479d2a109470ab +timeCreated: 1470404606 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader b/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader new file mode 100644 index 0000000..a5ab97d --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader @@ -0,0 +1,123 @@ +Shader "Hidden/Post FX/Motion Blur" +{ + CGINCLUDE + + #pragma target 3.0 + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) Velocity texture setup + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertDefault + #pragma fragment FragVelocitySetup + + ENDCG + } + + // (1) TileMax filter (2 pixel width with normalization) + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertDefault + #pragma fragment FragTileMax1 + + ENDCG + } + + // (2) TileMax filter (2 pixel width) + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertDefault + #pragma fragment FragTileMax2 + + ENDCG + } + + // (3) TileMax filter (variable width) + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertDefault + #pragma fragment FragTileMaxV + + ENDCG + } + + // (4) NeighborMax filter + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertDefault + #pragma fragment FragNeighborMax + + ENDCG + } + + // (5) Reconstruction filter + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertMultitex + #pragma fragment FragReconstruction + + ENDCG + } + + // (6) Frame compression + Pass + { + CGPROGRAM + + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #include "MotionBlur.cginc" + #pragma vertex VertFrameCompress + #pragma fragment FragFrameCompress + + ENDCG + } + + // (7) Frame blending + Pass + { + CGPROGRAM + + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #include "MotionBlur.cginc" + #pragma vertex VertMultitex + #pragma fragment FragFrameBlending + + ENDCG + } + + // (8) Frame blending (without chroma subsampling) + Pass + { + CGPROGRAM + + #include "MotionBlur.cginc" + #pragma vertex VertMultitex + #pragma fragment FragFrameBlendingRaw + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader.meta b/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader.meta new file mode 100644 index 0000000..2f1d02c --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/MotionBlur.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6ab8493603d8f8e408750b81666a95f1 +timeCreated: 1468327385 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc new file mode 100644 index 0000000..ac7abf2 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc @@ -0,0 +1,238 @@ +/** +\author Michael Mara and Morgan McGuire, Casual Effects. 2015. +*/ + +#ifndef __SCREEN_SPACE_RAYTRACE__ +#define __SCREEN_SPACE_RAYTRACE__ + +sampler2D_float _CameraDepthTexture; + +float distanceSquared(float2 A, float2 B) +{ + A -= B; + return dot(A, A); +} + +float distanceSquared(float3 A, float3 B) +{ + A -= B; + return dot(A, A); +} + +void swap(inout float v0, inout float v1) +{ + float temp = v0; + v0 = v1; + v1 = temp; +} + +bool isIntersecting(float rayZMin, float rayZMax, float sceneZ, float layerThickness) +{ + return (rayZMax >= sceneZ - layerThickness) && (rayZMin <= sceneZ); +} + +void rayIterations(in bool traceBehindObjects, inout float2 P, inout float stepDirection, inout float end, inout int stepCount, inout int maxSteps, inout bool intersecting, + inout float sceneZ, inout float2 dP, inout float3 Q, inout float3 dQ, inout float k, inout float dk, + inout float rayZMin, inout float rayZMax, inout float prevZMaxEstimate, inout bool permute, inout float2 hitPixel, + inout float2 invSize, inout float layerThickness) +{ + bool stop = intersecting; + + UNITY_LOOP + for (; (P.x * stepDirection) <= end && stepCount < maxSteps && !stop; P += dP, Q.z += dQ.z, k += dk, stepCount += 1) + { + // The depth range that the ray covers within this loop iteration. + // Assume that the ray is moving in increasing z and swap if backwards. + rayZMin = prevZMaxEstimate; + //rayZMin = (dQ.z * -0.5 + Q.z) / (dk * -0.5 + k); + // Compute the value at 1/2 pixel into the future + rayZMax = (dQ.z * 0.5 + Q.z) / (dk * 0.5 + k); + prevZMaxEstimate = rayZMax; + + if (rayZMin > rayZMax) + { + swap(rayZMin, rayZMax); + } + + // Undo the homogeneous operation to obtain the camera-space + // Q at each point + hitPixel = permute ? P.yx : P; + + sceneZ = tex2Dlod(_CameraDepthTexture, float4(hitPixel * invSize,0,0)).r; + sceneZ = -LinearEyeDepth(sceneZ); + + bool isBehind = (rayZMin <= sceneZ); + intersecting = isBehind && (rayZMax >= sceneZ - layerThickness); + stop = traceBehindObjects ? intersecting : isBehind; + + } // pixel on ray + + P -= dP, Q.z -= dQ.z, k -= dk; +} + +/** + \param csOrigin must have z < -0.01, and project within the valid screen rectangle + \param stepRate Set to 1.0 by default, higher to step faster + */ +bool castDenseScreenSpaceRay + (float3 csOrigin, + float3 csDirection, + float4x4 projectToPixelMatrix, + float2 csZBufferSize, + float3 clipInfo, + float jitterFraction, + int maxSteps, + float layerThickness, + float maxRayTraceDistance, + out float2 hitPixel, + int stepRate, + bool traceBehindObjects, + out float3 csHitPoint, + out float stepCount) { + + float2 invSize = float2(1.0 / csZBufferSize.x, 1.0 / csZBufferSize.y); + + // Initialize to off screen + hitPixel = float2(-1, -1); + + float nearPlaneZ = -0.01; + // Clip ray to a near plane in 3D (doesn't have to be *the* near plane, although that would be a good idea) + float rayLength = ((csOrigin.z + csDirection.z * maxRayTraceDistance) > nearPlaneZ) ? + ((nearPlaneZ - csOrigin.z) / csDirection.z) : + maxRayTraceDistance; + + float3 csEndPoint = csDirection * rayLength + csOrigin; + + // Project into screen space + // This matrix has a lot of zeroes in it. We could expand + // out these multiplies to avoid multiplying by zero + // ...but 16 MADDs are not a big deal compared to what's ahead + float4 H0 = mul(projectToPixelMatrix, float4(csOrigin, 1.0)); + float4 H1 = mul(projectToPixelMatrix, float4(csEndPoint, 1.0)); + + // There are a lot of divisions by w that can be turned into multiplications + // at some minor precision loss...and we need to interpolate these 1/w values + // anyway. + // + // Because the caller was required to clip to the near plane, + // this homogeneous division (projecting from 4D to 2D) is guaranteed + // to succeed. + float k0 = 1.0 / H0.w; + float k1 = 1.0 / H1.w; + + // Screen-space endpoints + float2 P0 = H0.xy * k0; + float2 P1 = H1.xy * k1; + + // Switch the original points to values that interpolate linearly in 2D: + float3 Q0 = csOrigin * k0; + float3 Q1 = csEndPoint * k1; + +#if 1 // Clipping to the screen coordinates. We could simply modify maxSteps instead + float yMax = csZBufferSize.y - 0.5; + float yMin = 0.5; + float xMax = csZBufferSize.x - 0.5; + float xMin = 0.5; + + // 2D interpolation parameter + float alpha = 0.0; + // P0 must be in bounds + if (P1.y > yMax || P1.y < yMin) { + float yClip = (P1.y > yMax) ? yMax : yMin; + float yAlpha = (P1.y - yClip) / (P1.y - P0.y); // Denominator is not zero, since P0 != P1 (or P0 would have been clipped!) + alpha = yAlpha; + } + + // P0 must be in bounds + if (P1.x > xMax || P1.x < xMin) { + float xClip = (P1.x > xMax) ? xMax : xMin; + float xAlpha = (P1.x - xClip) / (P1.x - P0.x); // Denominator is not zero, since P0 != P1 (or P0 would have been clipped!) + alpha = max(alpha, xAlpha); + } + + // These are all in homogeneous space, so they interpolate linearly + P1 = lerp(P1, P0, alpha); + k1 = lerp(k1, k0, alpha); + Q1 = lerp(Q1, Q0, alpha); +#endif + + // We're doing this to avoid divide by zero (rays exactly parallel to an eye ray) + P1 = (distanceSquared(P0, P1) < 0.0001) ? P0 + float2(0.01, 0.01) : P1; + + float2 delta = P1 - P0; + + // Assume horizontal + bool permute = false; + if (abs(delta.x) < abs(delta.y)) { + // More-vertical line. Create a permutation that swaps x and y in the output + permute = true; + + // Directly swizzle the inputs + delta = delta.yx; + P1 = P1.yx; + P0 = P0.yx; + } + + // From now on, "x" is the primary iteration direction and "y" is the secondary one + + float stepDirection = sign(delta.x); + float invdx = stepDirection / delta.x; + float2 dP = float2(stepDirection, invdx * delta.y); + + // Track the derivatives of Q and k + float3 dQ = (Q1 - Q0) * invdx; + float dk = (k1 - k0) * invdx; + + dP *= stepRate; + dQ *= stepRate; + dk *= stepRate; + + P0 += dP * jitterFraction; + Q0 += dQ * jitterFraction; + k0 += dk * jitterFraction; + + // Slide P from P0 to P1, (now-homogeneous) Q from Q0 to Q1, and k from k0 to k1 + float3 Q = Q0; + float k = k0; + + // We track the ray depth at +/- 1/2 pixel to treat pixels as clip-space solid + // voxels. Because the depth at -1/2 for a given pixel will be the same as at + // +1/2 for the previous iteration, we actually only have to compute one value + // per iteration. + float prevZMaxEstimate = csOrigin.z; + stepCount = 0.0; + float rayZMax = prevZMaxEstimate, rayZMin = prevZMaxEstimate; + float sceneZ = 100000; + + // P1.x is never modified after this point, so pre-scale it by + // the step direction for a signed comparison + float end = P1.x * stepDirection; + + bool intersecting = isIntersecting(rayZMin, rayZMax, sceneZ, layerThickness); + // We only advance the z field of Q in the inner loop, since + // Q.xy is never used until after the loop terminates + + //int rayIterations = min(maxSteps, stepsToGetOffscreen); + + + float2 P = P0; + + int originalStepCount = 0; + rayIterations(traceBehindObjects, P, stepDirection, end, originalStepCount, maxSteps, intersecting, + sceneZ, dP, Q, dQ, k, dk, + rayZMin, rayZMax, prevZMaxEstimate, permute, hitPixel, + invSize, layerThickness); + + + stepCount = originalStepCount; + + // Loop only advanced the Z component. Now that we know where we are going + // update xy + Q.xy += dQ.xy * stepCount; + // Q is a vector, so we are trying to get by with 1 division instead of 3. + csHitPoint = Q * (1.0 / k); + + return intersecting; +} + +#endif // __SCREEN_SPACE_RAYTRACE__ diff --git a/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc.meta b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc.meta new file mode 100644 index 0000000..d9b8807 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceRaytrace.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a92d6fdbe2c35f94190497c18b88f9af +timeCreated: 1464350148 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader new file mode 100644 index 0000000..f6b3b4f --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader @@ -0,0 +1,929 @@ +/** +\author Michael Mara and Morgan McGuire, Casual Effects. 2015. +*/ +Shader "Hidden/Post FX/Screen Space Reflection" +{ + Properties + { + _MainTex ("Base (RGB)", 2D) = "white" {} + } + + CGINCLUDE + + #pragma target 3.0 + #include "UnityCG.cginc" + #include "UnityPBSLighting.cginc" + #include "UnityStandardBRDF.cginc" + #include "UnityStandardUtils.cginc" + #include "Common.cginc" + #include "ScreenSpaceRaytrace.cginc" + + float4 _ProjInfo; + float4x4 _WorldToCameraMatrix; + float4x4 _CameraToWorldMatrix; + float4x4 _ProjectToPixelMatrix; + float2 _ScreenSize; + float2 _ReflectionBufferSize; + float2 _InvScreenSize; + float3 _CameraClipInfo; + + sampler2D _CameraGBufferTexture0; + sampler2D _CameraGBufferTexture1; + sampler2D _CameraGBufferTexture2; + sampler2D _CameraGBufferTexture3; + sampler2D _CameraReflectionsTexture; + + float _CurrentMipLevel; + float _RayStepSize; + float _MaxRayTraceDistance; + float _LayerThickness; + float _FresnelFade; + float _FresnelFadePower; + float _ReflectionBlur; + + + int _HalfResolution; + int _TreatBackfaceHitAsMiss; + int _AllowBackwardsRays; + + + // RG: SS Hitpoint of ray + // B: distance ray travelled, used for mip-selection in the final resolve + // A: confidence value + sampler2D _HitPointTexture; + sampler2D _FinalReflectionTexture; + + // RGB: camera-space normal (encoded in [0-1]) + // A: Roughness + sampler2D _NormalAndRoughnessTexture; + + int _EnableRefine; + int _AdditiveReflection; + + float _ScreenEdgeFading; + + int _MaxSteps; + + int _BilateralUpsampling; + + float _MaxRoughness; + float _RoughnessFalloffRange; + float _SSRMultiplier; + + float _FadeDistance; + + int _TraceBehindObjects; + int _UseEdgeDetector; + int _HighlightSuppression; + + /** The height in pixels of a 1m object if viewed from 1m away. */ + float _PixelsPerMeterAtOneMeter; + + // For temporal filtering: + float4x4 _CurrentCameraToPreviousCamera; + sampler2D _PreviousReflectionTexture; + sampler2D _PreviousCSZBuffer; + float _TemporalAlpha; + int _UseTemporalConfidence; + + struct v2f + { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float2 uv2 : TEXCOORD1; + }; + + v2f vert( appdata_img v ) + { + v2f o; + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.uv2 = v.texcoord.xy; + + #if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0) + o.uv2.y = 1.0 - o.uv2.y; + #endif + + return o; + } + + float2 mipToSize(int mip) + { + return floor(_ReflectionBufferSize * exp2(-mip)); + } + + float3 ReconstructCSPosition(float2 S, float z) + { + float linEyeZ = -LinearEyeDepth(z); + return float3((((S.xy * _MainTex_TexelSize.zw)) * _ProjInfo.xy + _ProjInfo.zw) * linEyeZ, linEyeZ); + } + + /** Read the camera-space position of the point at screen-space pixel ssP */ + float3 GetPosition(float2 ssP) + { + float3 P; + + P.z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssP.xy); + + // Offset to pixel center + P = ReconstructCSPosition(float2(ssP) /*+ float2(0.5, 0.5)*/, P.z); + return P; + } + + float applyEdgeFade(float2 tsP, float fadeStrength) + { + float maxFade = 0.1; + + float2 itsP = float2(1.0, 1.0) - tsP; + float dist = min(min(itsP.x, itsP.y), min(tsP.x, tsP.x)); + float fade = dist / (maxFade*fadeStrength + 0.001); + fade = max(min(fade, 1.0), 0.0); + fade = pow(fade, 0.2); + + return fade; + } + + float3 csMirrorVector(float3 csPosition, float3 csN) + { + float3 csE = -normalize(csPosition.xyz); + float cos_o = dot(csN, csE); + float3 c_mi = normalize((csN * (2.0 * cos_o)) - csE); + + return c_mi; + } + + float4 fragRaytrace(v2f i, int stepRate) + { + float2 ssP = i.uv2.xy; + float3 csPosition = GetPosition(ssP); + + float smoothness = tex2D(_CameraGBufferTexture1, ssP).a; + if (csPosition.z < -100.0 || smoothness == 0.0) + { + return float4(0.0,0.0,0.0,0.0); + } + + float3 wsNormal = tex2D(_CameraGBufferTexture2, ssP).rgb * 2.0 - 1.0; + + int2 ssC = int2(ssP * _ScreenSize); + + float3 csN = mul((float3x3)(_WorldToCameraMatrix), wsNormal); + float3 csRayDirection = csMirrorVector(csPosition, csN); + + if (_AllowBackwardsRays == 0 && csRayDirection.z > 0.0) + { + return float4(0.0, 0.0, 0.0, 0.0); + } + + float maxRayTraceDistance = _MaxRayTraceDistance; + float jitterFraction = 0.0f; + float layerThickness = _LayerThickness; + + int maxSteps = _MaxSteps; + + // Bump the ray more in world space as it gets farther away (and so each pixel covers more WS distance) + float rayBump = max(-0.01*csPosition.z, 0.001); + float2 hitPixel; + float3 csHitPoint; + float stepCount; + + bool wasHit = castDenseScreenSpaceRay + (csPosition + (csN) * rayBump, + csRayDirection, + _ProjectToPixelMatrix, + _ScreenSize, + _CameraClipInfo, + jitterFraction, + maxSteps, + layerThickness, + maxRayTraceDistance, + hitPixel, + stepRate, + _TraceBehindObjects == 1, + csHitPoint, + stepCount); + + float2 tsPResult = hitPixel / _ScreenSize; + + float rayDist = dot(csHitPoint - csPosition, csRayDirection); + float confidence = 0.0; + + if (wasHit) + { + confidence = Pow2(1.0 - max(2.0*float(stepCount) / float(maxSteps) - 1.0, 0.0)); + confidence *= clamp(((_MaxRayTraceDistance - rayDist) / _FadeDistance), 0.0, 1.0); + + // Fake fresnel fade + float3 csE = -normalize(csPosition.xyz); + confidence *= max(0.0, lerp(pow(abs(dot(csRayDirection, -csE)), _FresnelFadePower), 1, 1.0 - _FresnelFade)); + + if (_TreatBackfaceHitAsMiss > 0) + { + float3 wsHitNormal = tex2Dlod(_CameraGBufferTexture2, float4(tsPResult, 0, 0)).rgb * 2.0 - 1.0; + float3 wsRayDirection = mul(_CameraToWorldMatrix, float4(csRayDirection, 0)).xyz; + + if (dot(wsHitNormal, wsRayDirection) > 0) + { + confidence = 0.0; + } + } + } + + // Fade out reflections that hit near edge of screen, to prevent abrupt appearance/disappearance when object go off screen + // Fade out reflections that hit near edge of screen, + // to prevent abrupt appearance/disappearance when object go off screen + float vignette = applyEdgeFade(tsPResult, _ScreenEdgeFading); + confidence *= vignette; + confidence *= vignette; + + return float4(tsPResult, rayDist, confidence); + } + + float4 fragComposite(v2f i) : SV_Target + { + // Pixel being shaded + float2 tsP = i.uv2.xy; + + // View space point being shaded + float3 C = GetPosition(tsP); + + // Final image before this pass + float4 gbuffer3 = tex2D(_MainTex, i.uv); + + float4 specEmission = float4(0.0,0.0,0.0,0.0); + float3 specColor = tex2D(_CameraGBufferTexture1, tsP).rgb; + + float roughness = tex2D(_CameraGBufferTexture1, tsP).a; + + float4 reflectionTexel = tex2D(_FinalReflectionTexture, tsP); + + float4 gbuffer0 = tex2D(_CameraGBufferTexture0, tsP); + // Let core Unity functions do the dirty work of applying the BRDF + float3 baseColor = gbuffer0.rgb; + float occlusion = gbuffer0.a; + float oneMinusReflectivity; + baseColor = EnergyConservationBetweenDiffuseAndSpecular(baseColor, specColor, oneMinusReflectivity); + + float3 wsNormal = tex2D(_CameraGBufferTexture2, tsP).rgb * 2.0 - 1.0; + + float3 csEyeVec = normalize(C); + float3 eyeVec = mul(_CameraToWorldMatrix, float4(csEyeVec, 0)).xyz; + + float3 worldPos = mul(_CameraToWorldMatrix, float4(C, 1)).xyz; + + float cos_o = dot(wsNormal, eyeVec); + float3 w_mi = -normalize((wsNormal * (2.0 * cos_o)) - eyeVec); + + float3 incomingRadiance = reflectionTexel.rgb; + + UnityLight light; + light.color = 0; + light.dir = 0; + #if UNITY_VERSION < 550 + light.ndotl = 0; + #endif + + UnityIndirect ind; + ind.diffuse = 0; + ind.specular = incomingRadiance; + + float3 ssrResult = UNITY_BRDF_PBS (0, specColor, oneMinusReflectivity, roughness, wsNormal, -eyeVec, light, ind).rgb * _SSRMultiplier; + float confidence = reflectionTexel.a; + + specEmission.rgb = tex2D(_CameraReflectionsTexture, tsP).rgb; + float3 finalGlossyTerm; + + // Subtract out Unity's glossy result: (we're just applying the delta) + if (_AdditiveReflection == 0) + { + gbuffer3 -= specEmission; + // We may have blown out our dynamic range by adding then subtracting the reflection probes. + // As a half-measure to fix this, simply clamp to zero + gbuffer3 = max(gbuffer3, 0); + finalGlossyTerm = lerp(specEmission.rgb, ssrResult, saturate(confidence)); + } + else + { + finalGlossyTerm = ssrResult*saturate(confidence); + } + + finalGlossyTerm *= occlusion; + + // Additively blend the glossy GI result with the output buffer + return gbuffer3 + float4(finalGlossyTerm, 0); + } + + float roughnessWeight(float midpointRoughness, float tapRoughness) + { + return (1.0 - sqrt(sqrt(abs(midpointRoughness-tapRoughness)))); + } + + float normalWeight(float3 midpointNormal, float3 tapNormal) + { + return clamp(dot(midpointNormal, tapNormal), 0, 1); + } + + float highlightDecompression(float x) + { + return x / (1.0 - x); + } + + float3 highlightDecompression(float3 x) + { + return float3( + highlightDecompression(x.x), + highlightDecompression(x.y), + highlightDecompression(x.z) + ); + } + + float highlightCompression(float x) + { + return x / (1.0 + x); + } + + float3 highlightCompression(float3 x) + { + return float3( + highlightCompression(x.x), + highlightCompression(x.y), + highlightCompression(x.z) + ); + } + + float4 _Axis; + float4 fragGBlur(v2f i) : SV_Target + { + int radius = 4; + + // Pixel being shaded + float2 tsP = i.uv2.xy; + + float weightSum = 0.0; + float gaussWeights[5] = { 0.225, 0.150, 0.110, 0.075, 0.0525 };//{0.225, 0.150, 0.110, 0.075, 0.0525}; + float4 resultSum = float4(0.0, 0.0, 0.0, 0.0); + float4 unweightedResultSum = float4(0.0, 0.0, 0.0, 0.0); + float4 nAndRough = tex2D(_NormalAndRoughnessTexture, tsP); + float midpointRoughness = nAndRough.a; + float3 midpointNormal = nAndRough.rgb * 2 - 1; + + for (int i = -radius; i <= radius; ++i) + { + float4 temp; + float tapRoughness; + float3 tapNormal; + float2 tsTap = tsP + (_Axis.xy * _MainTex_TexelSize.xy * float2(i,i)*2.0); + + temp = tex2D(_MainTex, tsTap); + + float weight = temp.a * gaussWeights[abs(i)]; + // Bilateral filtering + // if (_ImproveCorners) + // { + nAndRough = tex2D(_NormalAndRoughnessTexture, tsTap); + tapRoughness = nAndRough.a; + tapNormal = nAndRough.rgb * 2 - 1; + weight *= normalWeight(midpointNormal, tapNormal); + // } + + weightSum += weight; + + if (_HighlightSuppression) + { + temp.rgb = highlightCompression(temp.rgb); + } + + unweightedResultSum += temp; + resultSum += temp*weight; + } + + if (weightSum > 0.01) + { + float invWeightSum = (1.0/weightSum); + // Adding the sqrt seems to decrease temporal flickering at the expense + // of having larger "halos" of fallback on rough surfaces + // Subject to change with testing. Sqrt around only half the expression is *intentional*. + float confidence = min(resultSum.a * sqrt(max(invWeightSum, 2.0)), 1.0); + float3 finalColor = resultSum.rgb * invWeightSum; + + if (_HighlightSuppression) + { + finalColor = highlightDecompression(finalColor); + } + + return float4(finalColor, confidence); + } + else + { + float3 finalColor = unweightedResultSum.rgb / (2 * radius + 1); + + if (_HighlightSuppression) + { + finalColor = highlightDecompression(finalColor); + } + + return float4(finalColor, 0.0); + } + } + + sampler2D _ReflectionTexture0; + sampler2D _ReflectionTexture1; + sampler2D _ReflectionTexture2; + sampler2D _ReflectionTexture3; + sampler2D _ReflectionTexture4; + + // Simulate mip maps, since we don't have NPOT mip-chains + float4 getReflectionValue(float2 tsP, int mip) + { + float4 coord = float4(tsP,0,0); + if (mip == 0) + { + return tex2Dlod(_ReflectionTexture0, coord); + } + else if (mip == 1) + { + return tex2Dlod(_ReflectionTexture1, coord); + } + else if (mip == 2) + { + return tex2Dlod(_ReflectionTexture2, coord); + } + else if (mip == 3) + { + return tex2Dlod(_ReflectionTexture3, coord); + } + else + { + return tex2Dlod(_ReflectionTexture4, coord); + } + } + + sampler2D _EdgeTexture0; + sampler2D _EdgeTexture1; + sampler2D _EdgeTexture2; + sampler2D _EdgeTexture3; + sampler2D _EdgeTexture4; + + // Simulate mip maps, since we don't have NPOT mip-chains + float4 getEdgeValue(float2 tsP, int mip) + { + float4 coord = float4(tsP + float2(1.0/(2 * mipToSize(mip))),0,0); + + if (mip == 0) + { + return tex2Dlod(_EdgeTexture0, coord); + } + else if (mip == 1) + { + return tex2Dlod(_EdgeTexture1, coord); + } + else if (mip == 2) + { + return tex2Dlod(_EdgeTexture2, coord); + } + else if (mip == 3) + { + return tex2Dlod(_EdgeTexture3, coord); + } + else + { + return tex2Dlod(_EdgeTexture4, coord); + } + } + + float2 centerPixel(float2 inputP) + { + return floor(inputP - float2(0.5,0.5)) + float2(0.5,0.5); + } + + float2 snapToTexelCenter(float2 inputP, float2 texSize, float2 texSizeInv) + { + return centerPixel(inputP * texSize) * texSizeInv; + } + + float4 bilateralUpsampleReflection(float2 tsP, int mip) + { + float2 smallTexSize = mipToSize(mip); + float2 smallPixelPos = tsP * smallTexSize; + float2 smallPixelPosi = centerPixel(smallPixelPos); + float2 smallTexSizeInv = 1.0 / smallTexSize; + + + float2 p0 = smallPixelPosi * smallTexSizeInv; + float2 p3 = (smallPixelPosi + float2(1.0, 1.0)) * smallTexSizeInv; + float2 p1 = float2(p3.x, p0.y); + float2 p2 = float2(p0.x, p3.y); + + float4 V0 = getReflectionValue(p0.xy, mip); + float4 V1 = getReflectionValue(p1.xy, mip); + float4 V2 = getReflectionValue(p2.xy, mip); + float4 V3 = getReflectionValue(p3.xy, mip); + + // Bilateral weights: + // Bilinear interpolation (filter distance) + float2 smallPixelPosf = smallPixelPos - smallPixelPosi; + float a0 = (1.0 - smallPixelPosf.x) * (1.0 - smallPixelPosf.y); + float a1 = smallPixelPosf.x * (1.0 - smallPixelPosf.y); + float a2 = (1.0 - smallPixelPosf.x) * smallPixelPosf.y; + float a3 = smallPixelPosf.x * smallPixelPosf.y; + + float2 fullTexSize = _ReflectionBufferSize; + float2 fullTexSizeInv = 1.0 / fullTexSize; + + float4 hiP0 = float4(snapToTexelCenter(p0, fullTexSize, fullTexSizeInv), 0,0); + float4 hiP3 = float4(snapToTexelCenter(p3, fullTexSize, fullTexSizeInv), 0,0); + float4 hiP1 = float4(snapToTexelCenter(p1, fullTexSize, fullTexSizeInv), 0,0); + float4 hiP2 = float4(snapToTexelCenter(p2, fullTexSize, fullTexSizeInv), 0,0); + + float4 tempCenter = tex2Dlod(_NormalAndRoughnessTexture, float4(tsP, 0, 0)); + float3 n = tempCenter.xyz * 2 - 1; + + float4 temp0 = tex2Dlod(_NormalAndRoughnessTexture, hiP0); + float4 temp1 = tex2Dlod(_NormalAndRoughnessTexture, hiP1); + float4 temp2 = tex2Dlod(_NormalAndRoughnessTexture, hiP2); + float4 temp3 = tex2Dlod(_NormalAndRoughnessTexture, hiP3); + + float3 n0 = temp0.xyz * 2 - 1; + float3 n1 = temp1.xyz * 2 - 1; + float3 n2 = temp2.xyz * 2 - 1; + float3 n3 = temp3.xyz * 2 - 1; + + a0 *= normalWeight(n, n0); + a1 *= normalWeight(n, n1); + a2 *= normalWeight(n, n2); + a3 *= normalWeight(n, n3); + + float r = tempCenter.a; + float r0 = temp0.a; + float r1 = temp1.a; + float r2 = temp2.a; + float r3 = temp3.a; + + a0 *= roughnessWeight(r, r0); + a1 *= roughnessWeight(r, r1); + a2 *= roughnessWeight(r, r2); + a3 *= roughnessWeight(r, r3); + + // Slightly offset from zero + a0 = max(a0, 0.001); + a1 = max(a1, 0.001); + a2 = max(a2, 0.001); + a3 = max(a3, 0.001); + + // Nearest neighbor + // a0 = a1 = a2 = a3 = 1.0; + + // Normalize the blending weights (weights were chosen so that + // the denominator can never be zero) + float norm = 1.0 / (a0 + a1 + a2 + a3); + + // Blend + float4 value = (V0 * a0 + V1 * a1 + V2 * a2 + V3 * a3) * norm; + //return V0; + return value; + } + + /** Explicit bilinear fetches; must be used if the reflection buffer is bound using point sampling */ + float4 bilinearUpsampleReflection(float2 tsP, int mip) + { + float2 smallTexSize = mipToSize(mip); + float2 smallPixelPos = tsP * smallTexSize; + float2 smallPixelPosi = centerPixel(smallPixelPos); + float2 smallTexSizeInv = 1.0 / smallTexSize; + + + float2 p0 = smallPixelPosi * smallTexSizeInv; + float2 p3 = (smallPixelPosi + float2(1.0, 1.0)) * smallTexSizeInv; + float2 p1 = float2(p3.x, p0.y); + float2 p2 = float2(p0.x, p3.y); + + float4 V0 = getReflectionValue(p0.xy, mip); + float4 V1 = getReflectionValue(p1.xy, mip); + float4 V2 = getReflectionValue(p2.xy, mip); + float4 V3 = getReflectionValue(p3.xy, mip); + + float a0 = 1.0; + float a1 = 1.0; + float a2 = 1.0; + float a3 = 1.0; + + // Bilateral weights: + // Bilinear interpolation (filter distance) + float2 smallPixelPosf = smallPixelPos - smallPixelPosi; + a0 = (1.0 - smallPixelPosf.x) * (1.0 - smallPixelPosf.y); + a1 = smallPixelPosf.x * (1.0 - smallPixelPosf.y); + a2 = (1.0 - smallPixelPosf.x) * smallPixelPosf.y; + a3 = smallPixelPosf.x * smallPixelPosf.y; + + // Blend + float4 value = (V0 * a0 + V1 * a1 + V2 * a2 + V3 * a3); + return value; + } + + // Unity's roughness is GGX roughness squared + float roughnessToBlinnPhongExponent(float roughness) + { + float r2 = roughness*roughness; + return 2.0f / r2*r2 - 2.0f; + } + + float glossyLobeSlope(float roughness) + { + return pow(roughness, 4.0/3.0); + } + + // Empirically based on our filter: + // Mip | Pixels + // -------------- + // 0 | 1 no filter, so single pixel + // 1 | 17 2r + 1 filter applied once, grabbing from pixels r away in either direction (r=8, four samples times stride of 2) + // 2 | 50 2r + 1 filter applied on double size pixels, and each of those pixels had reached another r out to the side 2(2r + 1) + m_1 + // 3 | 118 4(2r + 1) + m_2 + // 4 | 254 8(2r + 1) + m_3 + // + // Approximated by pixels = 16*2^mip-15 + // rearranging we get mip = log_2((pixels + 15) / 16) + // + float filterFootprintInPixelsToMip(float footprint) + { + return log2((footprint + 15) / 16); + } + + float3 ansiGradient(float t) + { + //return float3(t, t, t); + return fmod(floor(t * float3(8.0, 4.0, 2.0)), 2.0); + } + + float4 fragCompositeSSR(v2f i) : SV_Target + { + // Pixel being shaded + float2 tsP = i.uv2.xy; + + float roughness = 1.0-tex2D(_CameraGBufferTexture1, tsP).a; + + float rayDistance = tex2D(_HitPointTexture, tsP).z; + + // Get the camera space position of the reflection hit + float3 csPosition = GetPosition(tsP); + float3 wsNormal = tex2D(_CameraGBufferTexture2, tsP).rgb * 2.0 - 1.0; + float3 csN = mul((float3x3)(_WorldToCameraMatrix), wsNormal); + float3 c_mi = csMirrorVector(csPosition, csN); + float3 csHitpoint = c_mi * rayDistance + csPosition; + + + float gatherFootprintInMeters = glossyLobeSlope(roughness) * rayDistance; + // We could add a term that incorporates the normal + // This approximation assumes reflections happen at a glancing angle + float filterFootprintInPixels = gatherFootprintInMeters * _PixelsPerMeterAtOneMeter / csHitpoint.z; + if (_HalfResolution == 1) + { + filterFootprintInPixels *= 0.5; + } + + float mip = filterFootprintInPixelsToMip(filterFootprintInPixels); + + float nonPhysicalMip = pow(roughness, 3.0 / 4.0) * UNITY_SPECCUBE_LOD_STEPS; + + if (_HalfResolution == 1) + { + nonPhysicalMip = nonPhysicalMip * 0.7; + } + + mip = max(0, min(4, mip)); + + float4 result = 0.; + + { + int mipMin = int(mip); + int mipMax = min(mipMin + 1, 4); + float mipLerp = mip-mipMin; + + if (_BilateralUpsampling == 1) + { + result = lerp(bilateralUpsampleReflection(tsP, mipMin), bilateralUpsampleReflection(tsP, mipMax), mipLerp); + } + else + { + float4 minResult = getReflectionValue(tsP, mipMin); + float4 maxResult = getReflectionValue(tsP, mipMax); + result = lerp(minResult, maxResult, mipLerp); + result.a = min(minResult.a, maxResult.a); + } + } + + result.a = min(result.a, 1.0); + float vignette = applyEdgeFade(tsP, _ScreenEdgeFading); + result.a *= vignette; + + + // THIS MIGHT BE SLIGHTLY WRONG, TRY STEP() + float alphaModifier = 1.0 - clamp(roughness * .3, 0., 1.); + result.a *= alphaModifier; + return result; + } + + int _LastMip; + + float4 fragMin(v2f i) : SV_Target + { + float2 tsP = i.uv2.xy; + float2 lastTexSize = mipToSize(_LastMip); + float2 lastTexSizeInv = 1.0 / lastTexSize; + float2 p00 = snapToTexelCenter(tsP, lastTexSize, lastTexSizeInv); + float2 p11 = p00 + lastTexSizeInv; + + return min( + min(tex2D(_MainTex, p00), tex2D(_MainTex, p11)), + min(tex2D(_MainTex, float2(p00.x, p11.y)), tex2D(_MainTex, float2(p11.x, p00.y))) + ); + } + + float4 fragResolveHitPoints(v2f i) : SV_Target + { + float2 tsP = i.uv2.xy; + float4 temp = tex2D(_HitPointTexture, tsP); + float2 hitPoint = temp.xy; + float confidence = temp.w; + float3 colorResult = confidence > 0.0 ? tex2D(_MainTex, hitPoint).rgb : tex2D(_CameraReflectionsTexture, tsP).rgb; + + if (any(isnan(colorResult))) + colorResult = float3(0.0, 0.0, 0.0); + + // As of 11/29/2015, on Unity 5.3 on a Windows 8.1 computer with a NVIDIA GeForce 980, + // with driver 347.62, the above check does not actually work to get rid of NaNs! + // So we add this "redundant" check. + if (!all(isfinite(colorResult))) + colorResult = float3(0.0, 0.0, 0.0); + + return float4(colorResult, confidence); + } + + float4 fragBilatKeyPack(v2f i) : SV_Target + { + float2 tsP = i.uv2.xy; + float3 csN = tex2D(_CameraGBufferTexture2, tsP).xyz; + float roughness = tex2D(_CameraGBufferTexture1, tsP).a; + return float4(csN, roughness); + } + + float4 fragDepthToCSZ(v2f i) : SV_Target + { + float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv2.xy); + return float4(-LinearEyeDepth(depth), 0.0, 0.0, 0.0); + } + + static const int NUM_POISSON_TAPS = 12; + // Same as used in CameraMotionBlur.shader + static const float2 poissonSamples[NUM_POISSON_TAPS] = + { + 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) + }; + + float4 fragFilterSharpReflections(v2f i) : SV_Target + { + // Could improve perf by not computing blur when we won't be sampling the highest level anyways + float2 tsP = i.uv2.xy; + float4 sum = 0.0; + float sampleRadius = _MainTex_TexelSize.xy * _ReflectionBlur; + + for (int i = 0; i < NUM_POISSON_TAPS; i++) + { + float2 p = tsP + poissonSamples[i] * sampleRadius; + + float4 tap = tex2D(_MainTex, p); + if (_HighlightSuppression) + { + tap.rgb = highlightCompression(tap.rgb); + } + + sum += tap; + } + + float4 result = sum / float(NUM_POISSON_TAPS); + + if (_HighlightSuppression) + { + result.rgb = highlightDecompression(result.rgb); + } + + return result; + } + + ENDCG + + SubShader + { + ZTest Always Cull Off ZWrite Off + + // 0: Raytrace + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragRaytrace1 + + float4 fragRaytrace1(v2f i) : SV_Target + { + return fragRaytrace(i, _RayStepSize); + } + ENDCG + } + + // 1: Composite + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragComposite + ENDCG + } + + // 2: GBlur + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragGBlur + ENDCG + } + + // 3: CompositeSSR + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragCompositeSSR + ENDCG + } + + // 4: Min mip generation + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragMin + ENDCG + } + + // 5: Hit point texture to reflection buffer + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragResolveHitPoints + ENDCG + } + + // 6: Pack Bilateral Filter Keys in single buffer + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragBilatKeyPack + ENDCG + } + + // 7: Blit depth information as camera space Z + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragDepthToCSZ + ENDCG + } + + // 8: Filter the highest quality reflection buffer + Pass + { + CGPROGRAM + #pragma exclude_renderers gles xbox360 ps3 + #pragma vertex vert + #pragma fragment fragFilterSharpReflections + ENDCG + } + } + + Fallback "Diffuse" +} diff --git a/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader.meta b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader.meta new file mode 100644 index 0000000..d6e7c70 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/ScreenSpaceReflection.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 607a5643efb168f429e438f7d6ad270a +timeCreated: 1464350149 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/TAA.cginc b/Assets/PostProcessing/Resources/Shaders/TAA.cginc new file mode 100644 index 0000000..041f8ed --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/TAA.cginc @@ -0,0 +1,206 @@ +#ifndef __TAA__ +#define __TAA__ + +#pragma only_renderers ps4 xboxone d3d11 d3d9 xbox360 opengl glcore +#pragma exclude_renderers gles + +#include "UnityCG.cginc" +#include "Common.cginc" + +// ----------------------------------------------------------------------------- +// Solver + +#define TAA_USE_STABLE_BUT_GHOSTY_VARIANT 0 + +#if !defined(TAA_DILATE_MOTION_VECTOR_SAMPLE) + #define TAA_DILATE_MOTION_VECTOR_SAMPLE 1 +#endif + +#define TAA_FRAGMENT_MOTION_HISTORY_DECAY 0.85 + +#define TAA_FINAL_BLEND_STATIC_FACTOR _FinalBlendParameters.x +#define TAA_FINAL_BLEND_DYNAMIC_FACTOR _FinalBlendParameters.y +#define TAA_MOTION_AMPLIFICATION _FinalBlendParameters.z + +struct VaryingsSolver +{ + float4 vertex : SV_POSITION; + float4 uv : TEXCOORD0; // [xy: _MainTex.uv, zw: _HistoryTex.uv] +}; + +struct OutputSolver +{ + float4 destination : SV_Target0; + float4 history : SV_Target1; +}; + +sampler2D _HistoryTex; + +sampler2D _CameraMotionVectorsTexture; +sampler2D _CameraDepthTexture; + +float4 _HistoryTex_TexelSize; +float4 _CameraDepthTexture_TexelSize; + +float2 _Jitter; +float4 _SharpenParameters; +float4 _FinalBlendParameters; + +VaryingsSolver VertSolver(AttributesDefault input) +{ + VaryingsSolver output; + + float4 vertex = UnityObjectToClipPos(input.vertex); + + output.vertex = vertex; + output.uv = input.texcoord.xyxy; + +#if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0) + output.uv.y = 1.0 - input.texcoord.y; +#endif + + return output; +} + +float2 GetClosestFragment(float2 uv) +{ + const float2 k = _CameraDepthTexture_TexelSize.xy; + const float4 neighborhood = float4( + SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv - k), + SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv + float2(k.x, -k.y)), + SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv + float2(-k.x, k.y)), + SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv + k) + ); + +#if defined(UNITY_REVERSED_Z) + #define COMPARE_DEPTH(a, b) step(b, a) +#else + #define COMPARE_DEPTH(a, b) step(a, b) +#endif + + float3 result = float3(0.0, 0.0, SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); + result = lerp(result, float3(-1.0, -1.0, neighborhood.x), COMPARE_DEPTH(neighborhood.x, result.z)); + result = lerp(result, float3( 1.0, -1.0, neighborhood.y), COMPARE_DEPTH(neighborhood.y, result.z)); + result = lerp(result, float3(-1.0, 1.0, neighborhood.z), COMPARE_DEPTH(neighborhood.z, result.z)); + result = lerp(result, float3( 1.0, 1.0, neighborhood.w), COMPARE_DEPTH(neighborhood.w, result.z)); + + return (uv + result.xy * k); +} + +// Adapted from Playdead's TAA implementation +// https://github.com/playdeadgames/temporal +float4 ClipToAABB(float4 color, float p, float3 minimum, float3 maximum) +{ + // note: only clips towards aabb center (but fast!) + float3 center = 0.5 * (maximum + minimum); + float3 extents = 0.5 * (maximum - minimum); + + // This is actually `distance`, however the keyword is reserved + float4 offset = color - float4(center, p); + float3 repeat = abs(offset.xyz / extents); + + repeat.x = max(repeat.x, max(repeat.y, repeat.z)); + + if (repeat.x > 1.0) + { + // `color` is not intersecting (nor inside) the AABB; it's clipped to the closest extent + return float4(center, p) + offset / repeat.x; + } + else + { + // `color` is intersecting (or inside) the AABB. + + // Note: for whatever reason moving this return statement from this else into a higher + // scope makes the NVIDIA drivers go beyond bonkers + return color; + } +} + +OutputSolver FragSolver(VaryingsSolver input) +{ +#if TAA_DILATE_MOTION_VECTOR_SAMPLE + float2 motion = tex2D(_CameraMotionVectorsTexture, GetClosestFragment(input.uv.zw)).xy; +#else + // Don't dilate in ortho ! + float2 motion = tex2D(_CameraMotionVectorsTexture, input.uv.zw).xy; +#endif + + const float2 k = _MainTex_TexelSize.xy; + float2 uv = input.uv.xy; + +#if UNITY_UV_STARTS_AT_TOP + uv -= _MainTex_TexelSize.y < 0 ? _Jitter * float2(1.0, -1.0) : _Jitter; +#else + uv -= _Jitter; +#endif + + float4 color = tex2D(_MainTex, uv); + + float4 topLeft = tex2D(_MainTex, uv - k * 0.5); + float4 bottomRight = tex2D(_MainTex, uv + k * 0.5); + + float4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color; + + // Sharpen output + color += (color - (corners * 0.166667)) * 2.718282 * _SharpenParameters.x; + color = max(0.0, color); + + // Tonemap color and history samples + float4 average = FastToneMap((corners + color) * 0.142857); + + topLeft = FastToneMap(topLeft); + bottomRight = FastToneMap(bottomRight); + + color = FastToneMap(color); + + float4 history = tex2D(_HistoryTex, input.uv.zw - motion); + +// Only use this variant for arch viz or scenes that don't have any animated objects (camera animation is fine) +#if TAA_USE_STABLE_BUT_GHOSTY_VARIANT + float4 luma = float4(Luminance(topLeft.rgb), Luminance(bottomRight.rgb), Luminance(average.rgb), Luminance(color.rgb)); + float nudge = lerp(6.28318530718, 0.5, saturate(2.0 * history.a)) * max(abs(luma.z - luma.w), abs(luma.x - luma.y)); + + float4 minimum = lerp(bottomRight, topLeft, step(luma.x, luma.y)) - nudge; + float4 maximum = lerp(topLeft, bottomRight, step(luma.x, luma.y)) + nudge; +#else + float2 luma = float2(Luminance(average.rgb), Luminance(color.rgb)); + float nudge = 4.0 * abs(luma.x - luma.y); + + float4 minimum = min(bottomRight, topLeft) - nudge; + float4 maximum = max(topLeft, bottomRight) + nudge; +#endif + + history = FastToneMap(history); + + // Clip history samples + history = ClipToAABB(history, history.a, minimum.xyz, maximum.xyz); + + // Store fragment motion history + color.a = saturate(smoothstep(0.002 * _MainTex_TexelSize.z, 0.0035 * _MainTex_TexelSize.z, length(motion))); + + // Blend method + float weight = clamp(lerp(TAA_FINAL_BLEND_STATIC_FACTOR, TAA_FINAL_BLEND_DYNAMIC_FACTOR, + length(motion) * TAA_MOTION_AMPLIFICATION), TAA_FINAL_BLEND_DYNAMIC_FACTOR, TAA_FINAL_BLEND_STATIC_FACTOR); + + color = FastToneUnmap(lerp(color, history, weight)); + + OutputSolver output; + + output.destination = color; + color.a *= TAA_FRAGMENT_MOTION_HISTORY_DECAY; + + output.history = color; + + return output; +} + +// ----------------------------------------------------------------------------- +// Alpha clearance + +float4 FragAlphaClear(VaryingsDefault input) : SV_Target +{ + return float4(tex2D(_MainTex, input.uv).rgb, 0.0); +} + +#endif // __TAA__ diff --git a/Assets/PostProcessing/Resources/Shaders/TAA.cginc.meta b/Assets/PostProcessing/Resources/Shaders/TAA.cginc.meta new file mode 100644 index 0000000..55c7eaa --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/TAA.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 241b7a6a033e9dc4da9d2595cef7f477 +timeCreated: 1472807158 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/TAA.shader b/Assets/PostProcessing/Resources/Shaders/TAA.shader new file mode 100644 index 0000000..5d11264 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/TAA.shader @@ -0,0 +1,85 @@ +Shader "Hidden/Post FX/Temporal Anti-aliasing" +{ + Properties + { + _MainTex("", 2D) = "black" + } + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // Perspective + Pass + { + CGPROGRAM + #pragma target 5.0 + #pragma vertex VertSolver + #pragma fragment FragSolver + #include "TAA.cginc" + ENDCG + } + + // Ortho + Pass + { + CGPROGRAM + #pragma target 5.0 + #pragma vertex VertSolver + #pragma fragment FragSolver + #define TAA_DILATE_MOTION_VECTOR_SAMPLE 0 + #include "TAA.cginc" + ENDCG + } + + // Alpha Clear + Pass + { + CGPROGRAM + #pragma target 5.0 + #pragma vertex VertDefault + #pragma fragment FragAlphaClear + #include "TAA.cginc" + ENDCG + } + } + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // Perspective + Pass + { + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertSolver + #pragma fragment FragSolver + #include "TAA.cginc" + ENDCG + } + + // Ortho + Pass + { + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertSolver + #pragma fragment FragSolver + #define TAA_DILATE_MOTION_VECTOR_SAMPLE 0 + #include "TAA.cginc" + ENDCG + } + + // Alpha Clear + Pass + { + CGPROGRAM + #pragma target 3.0 + #pragma vertex VertDefault + #pragma fragment FragAlphaClear + #include "TAA.cginc" + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/TAA.shader.meta b/Assets/PostProcessing/Resources/Shaders/TAA.shader.meta new file mode 100644 index 0000000..2d157b5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/TAA.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ec6c5af987867f54aa08fba81ee279bd +timeCreated: 1472807140 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc b/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc new file mode 100644 index 0000000..d33f45f --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc @@ -0,0 +1,120 @@ +#ifndef __TONEMAPPING__ +#define __TONEMAPPING__ + +#include "ACES.cginc" + +// Set to 1 to use the full reference ACES tonemapper. This should only be used for research +// purposes and it's quite heavy and generally overkill. +#define TONEMAPPING_USE_FULL_ACES 0 + +// +// Neutral tonemapping (Hable/Hejl/Frostbite) +// Input is linear RGB +// +half3 NeutralCurve(half3 x, half a, half b, half c, half d, half e, half f) +{ + return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f; +} + +half3 NeutralTonemap(half3 x, half4 params1, half4 params2) +{ + // ACES supports negative color values and WILL output negative values when coming from ACES or ACEScg + // Make sure negative channels are clamped to 0.0 as this neutral tonemapper can't deal with them properly + x = max((0.0).xxx, x); + + // Tonemap + half a = params1.x; + half b = params1.y; + half c = params1.z; + half d = params1.w; + half e = params2.x; + half f = params2.y; + half whiteLevel = params2.z; + half whiteClip = params2.w; + + half3 whiteScale = (1.0).xxx / NeutralCurve(whiteLevel, a, b, c, d, e, f); + x = NeutralCurve(x * whiteScale, a, b, c, d, e, f); + x *= whiteScale; + + // Post-curve white point adjustment + x /= whiteClip.xxx; + + return x; +} + +// +// Filmic tonemapping (ACES fitting, unless TONEMAPPING_USE_FULL_ACES is set to 1) +// Input is ACES2065-1 (AP0 w/ linear encoding) +// +half3 FilmicTonemap(half3 aces) +{ +#if TONEMAPPING_USE_FULL_ACES + + half3 oces = RRT(aces); + half3 odt = ODT_RGBmonitor_100nits_dim(oces); + return odt; + +#else + + // --- Glow module --- // + half saturation = rgb_2_saturation(aces); + half ycIn = rgb_2_yc(aces); + half s = sigmoid_shaper((saturation - 0.4) / 0.2); + half addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID); + aces *= addedGlow; + + // --- Red modifier --- // + half hue = rgb_2_hue(aces); + half centeredHue = center_hue(hue, RRT_RED_HUE); + half hueWeight; + { + //hueWeight = cubic_basis_shaper(centeredHue, RRT_RED_WIDTH); + hueWeight = Pow2(smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH))); + } + + aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE); + + // --- ACES to RGB rendering space --- // + half3 acescg = max(0.0, ACES_to_ACEScg(aces)); + + // --- Global desaturation --- // + //acescg = mul(RRT_SAT_MAT, acescg); + acescg = lerp(dot(acescg, AP1_RGB2Y).xxx, acescg, RRT_SAT_FACTOR.xxx); + + // Luminance fitting of *RRT.a1.0.3 + ODT.Academy.RGBmonitor_100nits_dim.a1.0.3*. + // https://github.com/colour-science/colour-unity/blob/master/Assets/Colour/Notebooks/CIECAM02_Unity.ipynb + // RMSE: 0.0012846272106 + const half a = 278.5085; + const half b = 10.7772; + const half c = 293.6045; + const half d = 88.7122; + const half e = 80.6889; + half3 x = acescg; + half3 rgbPost = (x * (a * x + b)) / (x * (c * x + d) + e); + + // Scale luminance to linear code value + // half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK); + + // Apply gamma adjustment to compensate for dim surround + half3 linearCV = darkSurround_to_dimSurround(rgbPost); + + // Apply desaturation to compensate for luminance difference + //linearCV = mul(ODT_SAT_MAT, color); + linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx); + + // Convert to display primary encoding + // Rendering space RGB to XYZ + half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV); + + // Apply CAT from ACES white point to assumed observer adapted white point + XYZ = mul(D60_2_D65_CAT, XYZ); + + // CIE XYZ to display primaries + linearCV = mul(XYZ_2_REC709_MAT, XYZ); + + return linearCV; + +#endif +} + +#endif // __TONEMAPPING__ diff --git a/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc.meta b/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc.meta new file mode 100644 index 0000000..ca485b5 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Tonemapping.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0a999e641c982a14d9c68dfd53a98afc +timeCreated: 1469104178 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/Uber.shader b/Assets/PostProcessing/Resources/Shaders/Uber.shader new file mode 100644 index 0000000..dbfee42 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Uber.shader @@ -0,0 +1,330 @@ +Shader "Hidden/Post FX/Uber Shader" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _AutoExposure ("", 2D) = "" {} + _BloomTex ("", 2D) = "" {} + _Bloom_DirtTex ("", 2D) = "" {} + _GrainTex ("", 2D) = "" {} + _LogLut ("", 2D) = "" {} + _UserLut ("", 2D) = "" {} + _Vignette_Mask ("", 2D) = "" {} + _ChromaticAberration_Spectrum ("", 2D) = "" {} + _DitheringTex ("", 2D) = "" {} + } + + CGINCLUDE + + #pragma target 3.0 + + #pragma multi_compile __ UNITY_COLORSPACE_GAMMA + #pragma multi_compile __ CHROMATIC_ABERRATION + #pragma multi_compile __ DEPTH_OF_FIELD DEPTH_OF_FIELD_COC_VIEW + #pragma multi_compile __ BLOOM BLOOM_LENS_DIRT + #pragma multi_compile __ COLOR_GRADING COLOR_GRADING_LOG_VIEW + #pragma multi_compile __ USER_LUT + #pragma multi_compile __ GRAIN + #pragma multi_compile __ VIGNETTE_CLASSIC VIGNETTE_MASKED + #pragma multi_compile __ DITHERING + + #include "UnityCG.cginc" + #include "Bloom.cginc" + #include "ColorGrading.cginc" + #include "UberSecondPass.cginc" + + // Auto exposure / eye adaptation + sampler2D _AutoExposure; + + // Chromatic aberration + half _ChromaticAberration_Amount; + sampler2D _ChromaticAberration_Spectrum; + + // Depth of field + sampler2D_float _CameraDepthTexture; + sampler2D _DepthOfFieldTex; + sampler2D _DepthOfFieldCoCTex; + float4 _DepthOfFieldTex_TexelSize; + float3 _DepthOfFieldParams; // x: distance, y: f^2 / (N * (S1 - f) * film_width * 2), z: max coc + + // Bloom + sampler2D _BloomTex; + float4 _BloomTex_TexelSize; + half2 _Bloom_Settings; // x: sampleScale, y: bloom.intensity + + sampler2D _Bloom_DirtTex; + half _Bloom_DirtIntensity; + + // Color grading & tonemapping + sampler2D _LogLut; + half3 _LogLut_Params; // x: 1 / lut_width, y: 1 / lut_height, z: lut_height - 1 + half _ExposureEV; // EV (exp2) + + // User lut + sampler2D _UserLut; + half4 _UserLut_Params; // @see _LogLut_Params + + // Vignette + half3 _Vignette_Color; + half2 _Vignette_Center; // UV space + half4 _Vignette_Settings; // x: intensity, y: smoothness, z: roundness, w: rounded + sampler2D _Vignette_Mask; + half _Vignette_Opacity; // [0;1] + + struct VaryingsFlipped + { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float2 uvSPR : TEXCOORD1; // Single Pass Stereo UVs + float2 uvFlipped : TEXCOORD2; // Flipped UVs (DX/MSAA/Forward) + float2 uvFlippedSPR : TEXCOORD3; // Single Pass Stereo flipped UVs + }; + + VaryingsFlipped VertUber(AttributesDefault v) + { + VaryingsFlipped o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy; + o.uvSPR = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST); + o.uvFlipped = v.texcoord.xy; + + #if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0.0) + o.uvFlipped.y = 1.0 - o.uvFlipped.y; + #endif + + o.uvFlippedSPR = UnityStereoScreenSpaceUVAdjust(o.uvFlipped, _MainTex_ST); + + return o; + } + + half4 FragUber(VaryingsFlipped i) : SV_Target + { + float2 uv = i.uv; + half autoExposure = tex2D(_AutoExposure, uv).r; + + half3 color = (0.0).xxx; + #if DEPTH_OF_FIELD && CHROMATIC_ABERRATION + half4 dof = (0.0).xxxx; + half ffa = 0.0; // far field alpha + #endif + + // + // HDR effects + // --------------------------------------------------------- + + // Chromatic Aberration + // Inspired by the method described in "Rendering Inside" [Playdead 2016] + // https://twitter.com/pixelmager/status/717019757766123520 + #if CHROMATIC_ABERRATION + { + float2 coords = 2.0 * uv - 1.0; + float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount; + + float2 diff = end - uv; + int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, 16); + float2 delta = diff / samples; + float2 pos = uv; + half3 sum = (0.0).xxx, filterSum = (0.0).xxx; + + #if DEPTH_OF_FIELD + float2 dofDelta = delta; + float2 dofPos = pos; + if (_MainTex_TexelSize.y < 0.0) + { + dofDelta.y = -dofDelta.y; + dofPos.y = 1.0 - dofPos.y; + } + half4 dofSum = (0.0).xxxx; + half ffaSum = 0.0; + #endif + + for (int i = 0; i < samples; i++) + { + half t = (i + 0.5) / samples; + half3 s = tex2Dlod(_MainTex, float4(UnityStereoScreenSpaceUVAdjust(pos, _MainTex_ST), 0, 0)).rgb; + half3 filter = tex2Dlod(_ChromaticAberration_Spectrum, float4(t, 0, 0, 0)).rgb; + + sum += s * filter; + filterSum += filter; + pos += delta; + + #if DEPTH_OF_FIELD + float4 uvDof = float4(UnityStereoScreenSpaceUVAdjust(dofPos, _MainTex_ST), 0, 0); + half4 sdof = tex2Dlod(_DepthOfFieldTex, uvDof).rgba; + half scoc = tex2Dlod(_DepthOfFieldCoCTex, uvDof).r; + scoc = (scoc - 0.5) * 2 * _DepthOfFieldParams.z; + dofSum += sdof * half4(filter, 1); + ffaSum += smoothstep(_MainTex_TexelSize.y * 2, _MainTex_TexelSize.y * 4, scoc); + dofPos += dofDelta; + #endif + } + + color = sum / filterSum; + #if DEPTH_OF_FIELD + dof = dofSum / half4(filterSum, samples); + ffa = ffaSum / samples; + #endif + } + #else + { + color = tex2D(_MainTex, i.uvSPR).rgb; + } + #endif + + // Apply auto exposure if any + color *= autoExposure; + + // Gamma space... Gah. + #if UNITY_COLORSPACE_GAMMA + { + color = GammaToLinearSpace(color); + } + #endif + + // Depth of field + #if DEPTH_OF_FIELD_COC_VIEW + { + // Calculate the radiuses of CoC. + half4 src = tex2D(_DepthOfFieldTex, uv); + float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uvFlippedSPR)); + float coc = (depth - _DepthOfFieldParams.x) * _DepthOfFieldParams.y / depth; + coc *= 80; + + // Visualize CoC (white -> red -> gray) + half3 rgb = lerp(half3(1, 0, 0), half3(1.0, 1.0, 1.0), saturate(-coc)); + rgb = lerp(rgb, half3(0.4, 0.4, 0.4), saturate(coc)); + + // Black and white image overlay + rgb *= AcesLuminance(color) + 0.5; + + // Gamma correction + #if !UNITY_COLORSPACE_GAMMA + { + rgb = GammaToLinearSpace(rgb); + } + #endif + + color = rgb; + } + #elif DEPTH_OF_FIELD + { + #if !CHROMATIC_ABERRATION + half4 dof = tex2D(_DepthOfFieldTex, i.uvFlippedSPR); + half coc = tex2D(_DepthOfFieldCoCTex, i.uvFlippedSPR); + coc = (coc - 0.5) * 2 * _DepthOfFieldParams.z; + // Convert CoC to far field alpha value. + float ffa = smoothstep(_MainTex_TexelSize.y * 2, _MainTex_TexelSize.y * 4, coc); + #endif + // lerp(lerp(color, dof, ffa), dof, dof.a) + color = lerp(color, dof.rgb * autoExposure, ffa + dof.a - ffa * dof.a); + } + #endif + + // HDR Bloom + #if BLOOM || BLOOM_LENS_DIRT + { + half3 bloom = UpsampleFilter(_BloomTex, i.uvFlippedSPR, _BloomTex_TexelSize.xy, _Bloom_Settings.x) * _Bloom_Settings.y; + color += bloom; + + #if BLOOM_LENS_DIRT + { + half3 dirt = tex2D(_Bloom_DirtTex, i.uvFlipped).rgb * _Bloom_DirtIntensity; + color += bloom * dirt; + } + #endif + } + #endif + + // Procedural vignette + #if VIGNETTE_CLASSIC + { + half2 d = abs(uv - _Vignette_Center) * _Vignette_Settings.x; + d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w); + d = pow(d, _Vignette_Settings.z); // Roundness + half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y); + color *= lerp(_Vignette_Color, (1.0).xxx, vfactor); + } + + // Masked vignette + #elif VIGNETTE_MASKED + { + half vfactor = tex2D(_Vignette_Mask, uv).a; + half3 new_color = color * lerp(_Vignette_Color, (1.0).xxx, vfactor); + color = lerp(color, new_color, _Vignette_Opacity); + } + #endif + + // HDR color grading & tonemapping + #if COLOR_GRADING_LOG_VIEW + { + color *= _ExposureEV; + color = saturate(LinearToLogC(color)); + } + #elif COLOR_GRADING + { + color *= _ExposureEV; // Exposure is in ev units (or 'stops') + + half3 colorLogC = saturate(LinearToLogC(color)); + color = ApplyLut2d(_LogLut, colorLogC, _LogLut_Params); + } + #endif + + // + // All the following effects happen in LDR + // --------------------------------------------------------- + + color = saturate(color); + + // Back to gamma space if needed + #if UNITY_COLORSPACE_GAMMA + { + color = LinearToGammaSpace(color); + } + #endif + + // LDR user lut + #if USER_LUT + { + color = saturate(color); + half3 colorGraded; + + #if !UNITY_COLORSPACE_GAMMA + { + colorGraded = ApplyLut2d(_UserLut, LinearToGammaSpace(color), _UserLut_Params.xyz); + colorGraded = GammaToLinearSpace(colorGraded); + } + #else + { + colorGraded = ApplyLut2d(_UserLut, color, _UserLut_Params.xyz); + } + #endif + + color = lerp(color, colorGraded, _UserLut_Params.w); + } + #endif + + color = UberSecondPass(color, uv); + + // Done ! + return half4(color, 1.0); + } + + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always + + // (0) + Pass + { + CGPROGRAM + + #pragma vertex VertUber + #pragma fragment FragUber + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Resources/Shaders/Uber.shader.meta b/Assets/PostProcessing/Resources/Shaders/Uber.shader.meta new file mode 100644 index 0000000..014f889 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/Uber.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8ce0a6f4c8cae334d8a5617f302b6769 +timeCreated: 1459956426 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc b/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc new file mode 100644 index 0000000..4a53822 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc @@ -0,0 +1,39 @@ +#include "ColorGrading.cginc" + +// Grain +half2 _Grain_Params1; // x: lum_contrib, y: intensity +half4 _Grain_Params2; // x: xscale, h: yscale, z: xoffset, w: yoffset +sampler2D _GrainTex; + +// Dithering +sampler2D _DitheringTex; +float4 _DitheringCoords; + +float3 UberSecondPass(half3 color, float2 uv) +{ + // Grain + #if GRAIN + { + float3 grain = tex2D(_GrainTex, uv * _Grain_Params2.xy + _Grain_Params2.zw).rgb; + + // Noisiness response curve based on scene luminance + float lum = 1.0 - sqrt(AcesLuminance(color)); + lum = lerp(1.0, lum, _Grain_Params1.x); + + color += color * grain * _Grain_Params1.y * lum; + } + #endif + + // Blue noise dithering + #if DITHERING + { + // Symmetric triangular distribution on [-1,1] with maximal density at 0 + float noise = tex2D(_DitheringTex, uv * _DitheringCoords.xy + _DitheringCoords.zw).a * 2.0 - 1.0; + noise = sign(noise) * (1.0 - sqrt(1.0 - abs(noise))) / 255.0; + + color += noise; + } + #endif + + return color; +} diff --git a/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc.meta b/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc.meta new file mode 100644 index 0000000..acf9294 --- /dev/null +++ b/Assets/PostProcessing/Resources/Shaders/UberSecondPass.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b6e42614562a56445ba4b5d90301f06f +timeCreated: 1487080088 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime.meta b/Assets/PostProcessing/Runtime.meta new file mode 100644 index 0000000..56a4721 --- /dev/null +++ b/Assets/PostProcessing/Runtime.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4b79d54138d9d1a498085393504c7d02 +folderAsset: yes +timeCreated: 1466585248 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Attributes.meta b/Assets/PostProcessing/Runtime/Attributes.meta new file mode 100644 index 0000000..fca7c01 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 68327f748e8ffd94889a47317b7d327b +folderAsset: yes +timeCreated: 1460383911 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs b/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs new file mode 100644 index 0000000..cc1bf41 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs @@ -0,0 +1,13 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class GetSetAttribute : PropertyAttribute + { + public readonly string name; + public bool dirty; + + public GetSetAttribute(string name) + { + this.name = name; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs.meta b/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs.meta new file mode 100644 index 0000000..9730ca3 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/GetSetAttribute.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f17e8602928ea02419dae051ec79c5a2 +timeCreated: 1460383955 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs b/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs new file mode 100644 index 0000000..34144ce --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs @@ -0,0 +1,12 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class MinAttribute : PropertyAttribute + { + public readonly float min; + + public MinAttribute(float min) + { + this.min = min; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs.meta b/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs.meta new file mode 100644 index 0000000..a095a0b --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/MinAttribute.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9af2f505033843c46a362e251937acb1 +timeCreated: 1462281908 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs b/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs new file mode 100644 index 0000000..9acf912 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs @@ -0,0 +1,12 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class TrackballAttribute : PropertyAttribute + { + public readonly string method; + + public TrackballAttribute(string method) + { + this.method = method; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs.meta b/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs.meta new file mode 100644 index 0000000..fe2ebc6 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/TrackballAttribute.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 65e30143f4e114f45b84a1d9cba8f469 +timeCreated: 1463400829 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs b/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs new file mode 100644 index 0000000..c29c03d --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs @@ -0,0 +1,6 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class TrackballGroupAttribute : PropertyAttribute + { + } +} diff --git a/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs.meta b/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs.meta new file mode 100644 index 0000000..74724e1 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Attributes/TrackballGroupAttribute.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aa62a51ebe4821e4b89a64d267b30a27 +timeCreated: 1460563239 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components.meta b/Assets/PostProcessing/Runtime/Components.meta new file mode 100644 index 0000000..bbf2a04 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c1f765b2bd3d2ad49b2677f6478a9ba3 +folderAsset: yes +timeCreated: 1466585494 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs b/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs new file mode 100644 index 0000000..45ca0bb --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs @@ -0,0 +1,185 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using DebugMode = BuiltinDebugViewsModel.Mode; + + public sealed class AmbientOcclusionComponent : PostProcessingComponentCommandBuffer + { + static class Uniforms + { + internal static readonly int _Intensity = Shader.PropertyToID("_Intensity"); + internal static readonly int _Radius = Shader.PropertyToID("_Radius"); + internal static readonly int _FogParams = Shader.PropertyToID("_FogParams"); + internal static readonly int _Downsample = Shader.PropertyToID("_Downsample"); + internal static readonly int _SampleCount = Shader.PropertyToID("_SampleCount"); + internal static readonly int _OcclusionTexture1 = Shader.PropertyToID("_OcclusionTexture1"); + internal static readonly int _OcclusionTexture2 = Shader.PropertyToID("_OcclusionTexture2"); + internal static readonly int _OcclusionTexture = Shader.PropertyToID("_OcclusionTexture"); + internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); + internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); + } + + const string k_BlitShaderString = "Hidden/Post FX/Blit"; + const string k_ShaderString = "Hidden/Post FX/Ambient Occlusion"; + + readonly RenderTargetIdentifier[] m_MRT = + { + BuiltinRenderTextureType.GBuffer0, // Albedo, Occ + BuiltinRenderTextureType.CameraTarget // Ambient + }; + + enum OcclusionSource + { + DepthTexture, + DepthNormalsTexture, + GBuffer + } + + OcclusionSource occlusionSource + { + get + { + if (context.isGBufferAvailable && !model.settings.forceForwardCompatibility) + return OcclusionSource.GBuffer; + + if (model.settings.highPrecision && (!context.isGBufferAvailable || model.settings.forceForwardCompatibility)) + return OcclusionSource.DepthTexture; + + return OcclusionSource.DepthNormalsTexture; + } + } + + bool ambientOnlySupported + { + get { return context.isHdr && model.settings.ambientOnly && context.isGBufferAvailable && !model.settings.forceForwardCompatibility; } + } + + public override bool active + { + get + { + return model.enabled + && model.settings.intensity > 0f + && !context.interrupted; + } + } + + public override DepthTextureMode GetCameraFlags() + { + var flags = DepthTextureMode.None; + + if (occlusionSource == OcclusionSource.DepthTexture) + flags |= DepthTextureMode.Depth; + + if (occlusionSource != OcclusionSource.GBuffer) + flags |= DepthTextureMode.DepthNormals; + + return flags; + } + + public override string GetName() + { + return "Ambient Occlusion"; + } + + public override CameraEvent GetCameraEvent() + { + return ambientOnlySupported && !context.profile.debugViews.IsModeActive(DebugMode.AmbientOcclusion) + ? CameraEvent.BeforeReflections + : CameraEvent.BeforeImageEffectsOpaque; + } + + public override void PopulateCommandBuffer(CommandBuffer cb) + { + var settings = model.settings; + + // Material setup + var blitMaterial = context.materialFactory.Get(k_BlitShaderString); + + var material = context.materialFactory.Get(k_ShaderString); + material.shaderKeywords = null; + material.SetFloat(Uniforms._Intensity, settings.intensity); + material.SetFloat(Uniforms._Radius, settings.radius); + material.SetFloat(Uniforms._Downsample, settings.downsampling ? 0.5f : 1f); + material.SetInt(Uniforms._SampleCount, (int)settings.sampleCount); + + if (!context.isGBufferAvailable && RenderSettings.fog) + { + material.SetVector(Uniforms._FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance)); + + switch (RenderSettings.fogMode) + { + case FogMode.Linear: + material.EnableKeyword("FOG_LINEAR"); + break; + case FogMode.Exponential: + material.EnableKeyword("FOG_EXP"); + break; + case FogMode.ExponentialSquared: + material.EnableKeyword("FOG_EXP2"); + break; + } + } + else + { + material.EnableKeyword("FOG_OFF"); + } + + int tw = context.width; + int th = context.height; + int ts = settings.downsampling ? 2 : 1; + const RenderTextureFormat kFormat = RenderTextureFormat.ARGB32; + const RenderTextureReadWrite kRWMode = RenderTextureReadWrite.Linear; + const FilterMode kFilter = FilterMode.Bilinear; + + // AO buffer + var rtMask = Uniforms._OcclusionTexture1; + cb.GetTemporaryRT(rtMask, tw / ts, th / ts, 0, kFilter, kFormat, kRWMode); + + // AO estimation + cb.Blit((Texture)null, rtMask, material, (int)occlusionSource); + + // Blur buffer + var rtBlur = Uniforms._OcclusionTexture2; + + // Separable blur (horizontal pass) + cb.GetTemporaryRT(rtBlur, tw, th, 0, kFilter, kFormat, kRWMode); + cb.SetGlobalTexture(Uniforms._MainTex, rtMask); + cb.Blit(rtMask, rtBlur, material, occlusionSource == OcclusionSource.GBuffer ? 4 : 3); + cb.ReleaseTemporaryRT(rtMask); + + // Separable blur (vertical pass) + rtMask = Uniforms._OcclusionTexture; + cb.GetTemporaryRT(rtMask, tw, th, 0, kFilter, kFormat, kRWMode); + cb.SetGlobalTexture(Uniforms._MainTex, rtBlur); + cb.Blit(rtBlur, rtMask, material, 5); + cb.ReleaseTemporaryRT(rtBlur); + + if (context.profile.debugViews.IsModeActive(DebugMode.AmbientOcclusion)) + { + cb.SetGlobalTexture(Uniforms._MainTex, rtMask); + cb.Blit(rtMask, BuiltinRenderTextureType.CameraTarget, material, 8); + context.Interrupt(); + } + else if (ambientOnlySupported) + { + cb.SetRenderTarget(m_MRT, BuiltinRenderTextureType.CameraTarget); + cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, 7); + } + else + { + var fbFormat = context.isHdr ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; + + int tempRT = Uniforms._TempRT; + cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear, fbFormat); + cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0); + cb.SetGlobalTexture(Uniforms._MainTex, tempRT); + cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget, material, 6); + cb.ReleaseTemporaryRT(tempRT); + } + + cb.ReleaseTemporaryRT(rtMask); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs.meta new file mode 100644 index 0000000..4433821 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c6e33ce72d3776b408121f946283403d +timeCreated: 1467275948 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/BloomComponent.cs b/Assets/PostProcessing/Runtime/Components/BloomComponent.cs new file mode 100644 index 0000000..53ac6fc --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/BloomComponent.cs @@ -0,0 +1,143 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class BloomComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure"); + internal static readonly int _Threshold = Shader.PropertyToID("_Threshold"); + internal static readonly int _Curve = Shader.PropertyToID("_Curve"); + internal static readonly int _PrefilterOffs = Shader.PropertyToID("_PrefilterOffs"); + internal static readonly int _SampleScale = Shader.PropertyToID("_SampleScale"); + internal static readonly int _BaseTex = Shader.PropertyToID("_BaseTex"); + internal static readonly int _BloomTex = Shader.PropertyToID("_BloomTex"); + internal static readonly int _Bloom_Settings = Shader.PropertyToID("_Bloom_Settings"); + internal static readonly int _Bloom_DirtTex = Shader.PropertyToID("_Bloom_DirtTex"); + internal static readonly int _Bloom_DirtIntensity = Shader.PropertyToID("_Bloom_DirtIntensity"); + } + + const int k_MaxPyramidBlurLevel = 16; + readonly RenderTexture[] m_BlurBuffer1 = new RenderTexture[k_MaxPyramidBlurLevel]; + readonly RenderTexture[] m_BlurBuffer2 = new RenderTexture[k_MaxPyramidBlurLevel]; + + public override bool active + { + get + { + return model.enabled + && model.settings.bloom.intensity > 0f + && !context.interrupted; + } + } + + public void Prepare(RenderTexture source, Material uberMaterial, Texture autoExposure) + { + var bloom = model.settings.bloom; + var lensDirt = model.settings.lensDirt; + var material = context.materialFactory.Get("Hidden/Post FX/Bloom"); + material.shaderKeywords = null; + + // Apply auto exposure before the prefiltering pass + material.SetTexture(Uniforms._AutoExposure, autoExposure); + + // Do bloom on a half-res buffer, full-res doesn't bring much and kills performances on + // fillrate limited platforms + var tw = context.width / 2; + var th = context.height / 2; + + // Blur buffer format + // TODO: Extend the use of RGBM to the whole chain for mobile platforms + var useRGBM = Application.isMobilePlatform; + var rtFormat = useRGBM + ? RenderTextureFormat.Default + : RenderTextureFormat.DefaultHDR; + + // Determine the iteration count + float logh = Mathf.Log(th, 2f) + bloom.radius - 8f; + int logh_i = (int)logh; + int iterations = Mathf.Clamp(logh_i, 1, k_MaxPyramidBlurLevel); + + // Uupdate the shader properties + float lthresh = bloom.thresholdLinear; + material.SetFloat(Uniforms._Threshold, lthresh); + + float knee = lthresh * bloom.softKnee + 1e-5f; + var curve = new Vector3(lthresh - knee, knee * 2f, 0.25f / knee); + material.SetVector(Uniforms._Curve, curve); + + material.SetFloat(Uniforms._PrefilterOffs, bloom.antiFlicker ? -0.5f : 0f); + + float sampleScale = 0.5f + logh - logh_i; + material.SetFloat(Uniforms._SampleScale, sampleScale); + + // TODO: Probably can disable antiFlicker if TAA is enabled - need to do some testing + if (bloom.antiFlicker) + material.EnableKeyword("ANTI_FLICKER"); + + // Prefilter pass + var prefiltered = context.renderTextureFactory.Get(tw, th, 0, rtFormat); + Graphics.Blit(source, prefiltered, material, 0); + + // Construct a mip pyramid + var last = prefiltered; + + for (int level = 0; level < iterations; level++) + { + m_BlurBuffer1[level] = context.renderTextureFactory.Get( + last.width / 2, last.height / 2, 0, rtFormat + ); + + int pass = (level == 0) ? 1 : 2; + Graphics.Blit(last, m_BlurBuffer1[level], material, pass); + + last = m_BlurBuffer1[level]; + } + + // Upsample and combine loop + for (int level = iterations - 2; level >= 0; level--) + { + var baseTex = m_BlurBuffer1[level]; + material.SetTexture(Uniforms._BaseTex, baseTex); + + m_BlurBuffer2[level] = context.renderTextureFactory.Get( + baseTex.width, baseTex.height, 0, rtFormat + ); + + Graphics.Blit(last, m_BlurBuffer2[level], material, 3); + last = m_BlurBuffer2[level]; + } + + var bloomTex = last; + + // Release the temporary buffers + for (int i = 0; i < k_MaxPyramidBlurLevel; i++) + { + if (m_BlurBuffer1[i] != null) + context.renderTextureFactory.Release(m_BlurBuffer1[i]); + + if (m_BlurBuffer2[i] != null && m_BlurBuffer2[i] != bloomTex) + context.renderTextureFactory.Release(m_BlurBuffer2[i]); + + m_BlurBuffer1[i] = null; + m_BlurBuffer2[i] = null; + } + + context.renderTextureFactory.Release(prefiltered); + + // Push everything to the uber material + uberMaterial.SetTexture(Uniforms._BloomTex, bloomTex); + uberMaterial.SetVector(Uniforms._Bloom_Settings, new Vector2(sampleScale, bloom.intensity)); + + if (lensDirt.intensity > 0f && lensDirt.texture != null) + { + uberMaterial.SetTexture(Uniforms._Bloom_DirtTex, lensDirt.texture); + uberMaterial.SetFloat(Uniforms._Bloom_DirtIntensity, lensDirt.intensity); + uberMaterial.EnableKeyword("BLOOM_LENS_DIRT"); + } + else + { + uberMaterial.EnableKeyword("BLOOM"); + } + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/BloomComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/BloomComponent.cs.meta new file mode 100644 index 0000000..a67b103 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/BloomComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: acd4204a794b09048b928b1e987500c5 +timeCreated: 1473089954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs b/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs new file mode 100644 index 0000000..269aeee --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs @@ -0,0 +1,258 @@ +using System.Collections.Generic; +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using Mode = BuiltinDebugViewsModel.Mode; + + public sealed class BuiltinDebugViewsComponent : PostProcessingComponentCommandBuffer + { + static class Uniforms + { + internal static readonly int _DepthScale = Shader.PropertyToID("_DepthScale"); + internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); + internal static readonly int _Opacity = Shader.PropertyToID("_Opacity"); + internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); + internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2"); + internal static readonly int _Amplitude = Shader.PropertyToID("_Amplitude"); + internal static readonly int _Scale = Shader.PropertyToID("_Scale"); + } + + const string k_ShaderString = "Hidden/Post FX/Builtin Debug Views"; + + enum Pass + { + Depth, + Normals, + MovecOpacity, + MovecImaging, + MovecArrows + } + + ArrowArray m_Arrows; + + class ArrowArray + { + public Mesh mesh { get; private set; } + + public int columnCount { get; private set; } + public int rowCount { get; private set; } + + public void BuildMesh(int columns, int rows) + { + // Base shape + var arrow = new Vector3[6] + { + new Vector3(0f, 0f, 0f), + new Vector3(0f, 1f, 0f), + new Vector3(0f, 1f, 0f), + new Vector3(-1f, 1f, 0f), + new Vector3(0f, 1f, 0f), + new Vector3(1f, 1f, 0f) + }; + + // make the vertex array + int vcount = 6 * columns * rows; + var vertices = new List(vcount); + var uvs = new List(vcount); + + for (int iy = 0; iy < rows; iy++) + { + for (int ix = 0; ix < columns; ix++) + { + var uv = new Vector2( + (0.5f + ix) / columns, + (0.5f + iy) / rows + ); + + for (int i = 0; i < 6; i++) + { + vertices.Add(arrow[i]); + uvs.Add(uv); + } + } + } + + // make the index array + var indices = new int[vcount]; + + for (int i = 0; i < vcount; i++) + indices[i] = i; + + // initialize the mesh object + mesh = new Mesh { hideFlags = HideFlags.DontSave }; + mesh.SetVertices(vertices); + mesh.SetUVs(0, uvs); + mesh.SetIndices(indices, MeshTopology.Lines, 0); + mesh.UploadMeshData(true); + + // update the properties + columnCount = columns; + rowCount = rows; + } + + public void Release() + { + GraphicsUtils.Destroy(mesh); + mesh = null; + } + } + + public override bool active + { + get + { + return model.IsModeActive(Mode.Depth) + || model.IsModeActive(Mode.Normals) + || model.IsModeActive(Mode.MotionVectors); + } + } + + public override DepthTextureMode GetCameraFlags() + { + var mode = model.settings.mode; + var flags = DepthTextureMode.None; + + switch (mode) + { + case Mode.Normals: + flags |= DepthTextureMode.DepthNormals; + break; + case Mode.MotionVectors: + flags |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth; + break; + case Mode.Depth: + flags |= DepthTextureMode.Depth; + break; + } + + return flags; + } + + public override CameraEvent GetCameraEvent() + { + return model.settings.mode == Mode.MotionVectors + ? CameraEvent.BeforeImageEffects + : CameraEvent.BeforeImageEffectsOpaque; + } + + public override string GetName() + { + return "Builtin Debug Views"; + } + + public override void PopulateCommandBuffer(CommandBuffer cb) + { + var settings = model.settings; + var material = context.materialFactory.Get(k_ShaderString); + material.shaderKeywords = null; + + if (context.isGBufferAvailable) + material.EnableKeyword("SOURCE_GBUFFER"); + + switch (settings.mode) + { + case Mode.Depth: + DepthPass(cb); + break; + case Mode.Normals: + DepthNormalsPass(cb); + break; + case Mode.MotionVectors: + MotionVectorsPass(cb); + break; + } + + context.Interrupt(); + } + + void DepthPass(CommandBuffer cb) + { + var material = context.materialFactory.Get(k_ShaderString); + var settings = model.settings.depth; + + cb.SetGlobalFloat(Uniforms._DepthScale, 1f / settings.scale); + cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Depth); + } + + void DepthNormalsPass(CommandBuffer cb) + { + var material = context.materialFactory.Get(k_ShaderString); + cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Normals); + } + + void MotionVectorsPass(CommandBuffer cb) + { +#if UNITY_EDITOR + // Don't render motion vectors preview when the editor is not playing as it can in some + // cases results in ugly artifacts (i.e. when resizing the game view). + if (!Application.isPlaying) + return; +#endif + + var material = context.materialFactory.Get(k_ShaderString); + var settings = model.settings.motionVectors; + + // Blit the original source image + int tempRT = Uniforms._TempRT; + cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear); + cb.SetGlobalFloat(Uniforms._Opacity, settings.sourceOpacity); + cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); + cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, material, (int)Pass.MovecOpacity); + + // Motion vectors (imaging) + if (settings.motionImageOpacity > 0f && settings.motionImageAmplitude > 0f) + { + int tempRT2 = Uniforms._TempRT2; + cb.GetTemporaryRT(tempRT2, context.width, context.height, 0, FilterMode.Bilinear); + cb.SetGlobalFloat(Uniforms._Opacity, settings.motionImageOpacity); + cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionImageAmplitude); + cb.SetGlobalTexture(Uniforms._MainTex, tempRT); + cb.Blit(tempRT, tempRT2, material, (int)Pass.MovecImaging); + cb.ReleaseTemporaryRT(tempRT); + tempRT = tempRT2; + } + + // Motion vectors (arrows) + if (settings.motionVectorsOpacity > 0f && settings.motionVectorsAmplitude > 0f) + { + PrepareArrows(); + + float sy = 1f / settings.motionVectorsResolution; + float sx = sy * context.height / context.width; + + cb.SetGlobalVector(Uniforms._Scale, new Vector2(sx, sy)); + cb.SetGlobalFloat(Uniforms._Opacity, settings.motionVectorsOpacity); + cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionVectorsAmplitude); + cb.DrawMesh(m_Arrows.mesh, Matrix4x4.identity, material, 0, (int)Pass.MovecArrows); + } + + cb.SetGlobalTexture(Uniforms._MainTex, tempRT); + cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget); + cb.ReleaseTemporaryRT(tempRT); + } + + void PrepareArrows() + { + int row = model.settings.motionVectors.motionVectorsResolution; + int col = row * Screen.width / Screen.height; + + if (m_Arrows == null) + m_Arrows = new ArrowArray(); + + if (m_Arrows.columnCount != col || m_Arrows.rowCount != row) + { + m_Arrows.Release(); + m_Arrows.BuildMesh(col, row); + } + } + + public override void OnDisable() + { + if (m_Arrows != null) + m_Arrows.Release(); + + m_Arrows = null; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs.meta new file mode 100644 index 0000000..e8625d3 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/BuiltinDebugViewsComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fd834b6165e82e64f9da2d4ed9f4e236 +timeCreated: 1473163679 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs b/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs new file mode 100644 index 0000000..821a29f --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs @@ -0,0 +1,63 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class ChromaticAberrationComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _ChromaticAberration_Amount = Shader.PropertyToID("_ChromaticAberration_Amount"); + internal static readonly int _ChromaticAberration_Spectrum = Shader.PropertyToID("_ChromaticAberration_Spectrum"); + } + + Texture2D m_SpectrumLut; + + public override bool active + { + get + { + return model.enabled + && model.settings.intensity > 0f + && !context.interrupted; + } + } + + public override void OnDisable() + { + GraphicsUtils.Destroy(m_SpectrumLut); + m_SpectrumLut = null; + } + + public override void Prepare(Material uberMaterial) + { + var settings = model.settings; + var spectralLut = settings.spectralTexture; + + if (spectralLut == null) + { + if (m_SpectrumLut == null) + { + m_SpectrumLut = new Texture2D(3, 1, TextureFormat.RGB24, false) + { + name = "Chromatic Aberration Spectrum Lookup", + filterMode = FilterMode.Bilinear, + wrapMode = TextureWrapMode.Clamp, + anisoLevel = 0, + hideFlags = HideFlags.DontSave + }; + + var pixels = new Color[3]; + pixels[0] = new Color(1f, 0f, 0f); + pixels[1] = new Color(0f, 1f, 0f); + pixels[2] = new Color(0f, 0f, 1f); + m_SpectrumLut.SetPixels(pixels); + m_SpectrumLut.Apply(); + } + + spectralLut = m_SpectrumLut; + } + + uberMaterial.EnableKeyword("CHROMATIC_ABERRATION"); + uberMaterial.SetFloat(Uniforms._ChromaticAberration_Amount, settings.intensity * 0.03f); + uberMaterial.SetTexture(Uniforms._ChromaticAberration_Spectrum, spectralLut); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs.meta new file mode 100644 index 0000000..c059230 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ChromaticAberrationComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b9c65642df654a84d84ded1b07448a4c +timeCreated: 1473085971 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs b/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs new file mode 100644 index 0000000..3948e7b --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs @@ -0,0 +1,436 @@ +namespace UnityEngine.PostProcessing +{ + using DebugMode = BuiltinDebugViewsModel.Mode; + + public sealed class ColorGradingComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _LutParams = Shader.PropertyToID("_LutParams"); + internal static readonly int _NeutralTonemapperParams1 = Shader.PropertyToID("_NeutralTonemapperParams1"); + internal static readonly int _NeutralTonemapperParams2 = Shader.PropertyToID("_NeutralTonemapperParams2"); + internal static readonly int _HueShift = Shader.PropertyToID("_HueShift"); + internal static readonly int _Saturation = Shader.PropertyToID("_Saturation"); + internal static readonly int _Contrast = Shader.PropertyToID("_Contrast"); + internal static readonly int _Balance = Shader.PropertyToID("_Balance"); + internal static readonly int _Lift = Shader.PropertyToID("_Lift"); + internal static readonly int _InvGamma = Shader.PropertyToID("_InvGamma"); + internal static readonly int _Gain = Shader.PropertyToID("_Gain"); + internal static readonly int _Slope = Shader.PropertyToID("_Slope"); + internal static readonly int _Power = Shader.PropertyToID("_Power"); + internal static readonly int _Offset = Shader.PropertyToID("_Offset"); + internal static readonly int _ChannelMixerRed = Shader.PropertyToID("_ChannelMixerRed"); + internal static readonly int _ChannelMixerGreen = Shader.PropertyToID("_ChannelMixerGreen"); + internal static readonly int _ChannelMixerBlue = Shader.PropertyToID("_ChannelMixerBlue"); + internal static readonly int _Curves = Shader.PropertyToID("_Curves"); + internal static readonly int _LogLut = Shader.PropertyToID("_LogLut"); + internal static readonly int _LogLut_Params = Shader.PropertyToID("_LogLut_Params"); + internal static readonly int _ExposureEV = Shader.PropertyToID("_ExposureEV"); + } + + const int k_InternalLogLutSize = 32; + const int k_CurvePrecision = 128; + const float k_CurveStep = 1f / k_CurvePrecision; + + Texture2D m_GradingCurves; + Color[] m_pixels = new Color[k_CurvePrecision * 2]; + + public override bool active + { + get + { + return model.enabled + && !context.interrupted; + } + } + + // An analytical model of chromaticity of the standard illuminant, by Judd et al. + // http://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D + // Slightly modifed to adjust it with the D65 white point (x=0.31271, y=0.32902). + float StandardIlluminantY(float x) + { + return 2.87f * x - 3f * x * x - 0.27509507f; + } + + // CIE xy chromaticity to CAT02 LMS. + // http://en.wikipedia.org/wiki/LMS_color_space#CAT02 + Vector3 CIExyToLMS(float x, float y) + { + float Y = 1f; + float X = Y * x / y; + float Z = Y * (1f - x - y) / y; + + float L = 0.7328f * X + 0.4296f * Y - 0.1624f * Z; + float M = -0.7036f * X + 1.6975f * Y + 0.0061f * Z; + float S = 0.0030f * X + 0.0136f * Y + 0.9834f * Z; + + return new Vector3(L, M, S); + } + + Vector3 CalculateColorBalance(float temperature, float tint) + { + // Range ~[-1.8;1.8] ; using higher ranges is unsafe + float t1 = temperature / 55f; + float t2 = tint / 55f; + + // Get the CIE xy chromaticity of the reference white point. + // Note: 0.31271 = x value on the D65 white point + float x = 0.31271f - t1 * (t1 < 0f ? 0.1f : 0.05f); + float y = StandardIlluminantY(x) + t2 * 0.05f; + + // Calculate the coefficients in the LMS space. + var w1 = new Vector3(0.949237f, 1.03542f, 1.08728f); // D65 white point + var w2 = CIExyToLMS(x, y); + return new Vector3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z); + } + + static Color NormalizeColor(Color c) + { + float sum = (c.r + c.g + c.b) / 3f; + + if (Mathf.Approximately(sum, 0f)) + return new Color(1f, 1f, 1f, c.a); + + return new Color + { + r = c.r / sum, + g = c.g / sum, + b = c.b / sum, + a = c.a + }; + } + + static Vector3 ClampVector(Vector3 v, float min, float max) + { + return new Vector3( + Mathf.Clamp(v.x, min, max), + Mathf.Clamp(v.y, min, max), + Mathf.Clamp(v.z, min, max) + ); + } + + public static Vector3 GetLiftValue(Color lift) + { + const float kLiftScale = 0.1f; + + var nLift = NormalizeColor(lift); + float avgLift = (nLift.r + nLift.g + nLift.b) / 3f; + + // Getting some artifacts when going into the negatives using a very low offset (lift.a) with non ACES-tonemapping + float liftR = (nLift.r - avgLift) * kLiftScale + lift.a; + float liftG = (nLift.g - avgLift) * kLiftScale + lift.a; + float liftB = (nLift.b - avgLift) * kLiftScale + lift.a; + + return ClampVector(new Vector3(liftR, liftG, liftB), -1f, 1f); + } + + public static Vector3 GetGammaValue(Color gamma) + { + const float kGammaScale = 0.5f; + const float kMinGamma = 0.01f; + + var nGamma = NormalizeColor(gamma); + float avgGamma = (nGamma.r + nGamma.g + nGamma.b) / 3f; + + gamma.a *= gamma.a < 0f ? 0.8f : 5f; + float gammaR = Mathf.Pow(2f, (nGamma.r - avgGamma) * kGammaScale) + gamma.a; + float gammaG = Mathf.Pow(2f, (nGamma.g - avgGamma) * kGammaScale) + gamma.a; + float gammaB = Mathf.Pow(2f, (nGamma.b - avgGamma) * kGammaScale) + gamma.a; + + float invGammaR = 1f / Mathf.Max(kMinGamma, gammaR); + float invGammaG = 1f / Mathf.Max(kMinGamma, gammaG); + float invGammaB = 1f / Mathf.Max(kMinGamma, gammaB); + + return ClampVector(new Vector3(invGammaR, invGammaG, invGammaB), 0f, 5f); + } + + public static Vector3 GetGainValue(Color gain) + { + const float kGainScale = 0.5f; + + var nGain = NormalizeColor(gain); + float avgGain = (nGain.r + nGain.g + nGain.b) / 3f; + + gain.a *= gain.a > 0f ? 3f : 1f; + float gainR = Mathf.Pow(2f, (nGain.r - avgGain) * kGainScale) + gain.a; + float gainG = Mathf.Pow(2f, (nGain.g - avgGain) * kGainScale) + gain.a; + float gainB = Mathf.Pow(2f, (nGain.b - avgGain) * kGainScale) + gain.a; + + return ClampVector(new Vector3(gainR, gainG, gainB), 0f, 4f); + } + + public static void CalculateLiftGammaGain(Color lift, Color gamma, Color gain, out Vector3 outLift, out Vector3 outGamma, out Vector3 outGain) + { + outLift = GetLiftValue(lift); + outGamma = GetGammaValue(gamma); + outGain = GetGainValue(gain); + } + + public static Vector3 GetSlopeValue(Color slope) + { + const float kSlopeScale = 0.1f; + + var nSlope = NormalizeColor(slope); + float avgSlope = (nSlope.r + nSlope.g + nSlope.b) / 3f; + + slope.a *= 0.5f; + float slopeR = (nSlope.r - avgSlope) * kSlopeScale + slope.a + 1f; + float slopeG = (nSlope.g - avgSlope) * kSlopeScale + slope.a + 1f; + float slopeB = (nSlope.b - avgSlope) * kSlopeScale + slope.a + 1f; + + return ClampVector(new Vector3(slopeR, slopeG, slopeB), 0f, 2f); + } + + public static Vector3 GetPowerValue(Color power) + { + const float kPowerScale = 0.1f; + const float minPower = 0.01f; + + var nPower = NormalizeColor(power); + float avgPower = (nPower.r + nPower.g + nPower.b) / 3f; + + power.a *= 0.5f; + float powerR = (nPower.r - avgPower) * kPowerScale + power.a + 1f; + float powerG = (nPower.g - avgPower) * kPowerScale + power.a + 1f; + float powerB = (nPower.b - avgPower) * kPowerScale + power.a + 1f; + + float invPowerR = 1f / Mathf.Max(minPower, powerR); + float invPowerG = 1f / Mathf.Max(minPower, powerG); + float invPowerB = 1f / Mathf.Max(minPower, powerB); + + return ClampVector(new Vector3(invPowerR, invPowerG, invPowerB), 0.5f, 2.5f); + } + + public static Vector3 GetOffsetValue(Color offset) + { + const float kOffsetScale = 0.05f; + + var nOffset = NormalizeColor(offset); + float avgOffset = (nOffset.r + nOffset.g + nOffset.b) / 3f; + + offset.a *= 0.5f; + float offsetR = (nOffset.r - avgOffset) * kOffsetScale + offset.a; + float offsetG = (nOffset.g - avgOffset) * kOffsetScale + offset.a; + float offsetB = (nOffset.b - avgOffset) * kOffsetScale + offset.a; + + return ClampVector(new Vector3(offsetR, offsetG, offsetB), -0.8f, 0.8f); + } + + public static void CalculateSlopePowerOffset(Color slope, Color power, Color offset, out Vector3 outSlope, out Vector3 outPower, out Vector3 outOffset) + { + outSlope = GetSlopeValue(slope); + outPower = GetPowerValue(power); + outOffset = GetOffsetValue(offset); + } + + TextureFormat GetCurveFormat() + { + if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf)) + return TextureFormat.RGBAHalf; + + return TextureFormat.RGBA32; + } + + Texture2D GetCurveTexture() + { + if (m_GradingCurves == null) + { + m_GradingCurves = new Texture2D(k_CurvePrecision, 2, GetCurveFormat(), false, true) + { + name = "Internal Curves Texture", + hideFlags = HideFlags.DontSave, + anisoLevel = 0, + wrapMode = TextureWrapMode.Clamp, + filterMode = FilterMode.Bilinear + }; + } + + var curves = model.settings.curves; + curves.hueVShue.Cache(); + curves.hueVSsat.Cache(); + + for (int i = 0; i < k_CurvePrecision; i++) + { + float t = i * k_CurveStep; + + // HSL + float x = curves.hueVShue.Evaluate(t); + float y = curves.hueVSsat.Evaluate(t); + float z = curves.satVSsat.Evaluate(t); + float w = curves.lumVSsat.Evaluate(t); + m_pixels[i] = new Color(x, y, z, w); + + // YRGB + float m = curves.master.Evaluate(t); + float r = curves.red.Evaluate(t); + float g = curves.green.Evaluate(t); + float b = curves.blue.Evaluate(t); + m_pixels[i + k_CurvePrecision] = new Color(r, g, b, m); + } + + m_GradingCurves.SetPixels(m_pixels); + m_GradingCurves.Apply(false, false); + + return m_GradingCurves; + } + + bool IsLogLutValid(RenderTexture lut) + { + return lut != null && lut.IsCreated() && lut.height == k_InternalLogLutSize; + } + + RenderTextureFormat GetLutFormat() + { + if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)) + return RenderTextureFormat.ARGBHalf; + + return RenderTextureFormat.ARGB32; + } + + void GenerateLut() + { + var settings = model.settings; + + if (!IsLogLutValid(model.bakedLut)) + { + GraphicsUtils.Destroy(model.bakedLut); + + model.bakedLut = new RenderTexture(k_InternalLogLutSize * k_InternalLogLutSize, k_InternalLogLutSize, 0, GetLutFormat()) + { + name = "Color Grading Log LUT", + hideFlags = HideFlags.DontSave, + filterMode = FilterMode.Bilinear, + wrapMode = TextureWrapMode.Clamp, + anisoLevel = 0 + }; + } + + var lutMaterial = context.materialFactory.Get("Hidden/Post FX/Lut Generator"); + lutMaterial.SetVector(Uniforms._LutParams, new Vector4( + k_InternalLogLutSize, + 0.5f / (k_InternalLogLutSize * k_InternalLogLutSize), + 0.5f / k_InternalLogLutSize, + k_InternalLogLutSize / (k_InternalLogLutSize - 1f)) + ); + + // Tonemapping + lutMaterial.shaderKeywords = null; + + var tonemapping = settings.tonemapping; + switch (tonemapping.tonemapper) + { + case ColorGradingModel.Tonemapper.Neutral: + { + lutMaterial.EnableKeyword("TONEMAPPING_NEUTRAL"); + + const float scaleFactor = 20f; + const float scaleFactorHalf = scaleFactor * 0.5f; + + float inBlack = tonemapping.neutralBlackIn * scaleFactor + 1f; + float outBlack = tonemapping.neutralBlackOut * scaleFactorHalf + 1f; + float inWhite = tonemapping.neutralWhiteIn / scaleFactor; + float outWhite = 1f - tonemapping.neutralWhiteOut / scaleFactor; + float blackRatio = inBlack / outBlack; + float whiteRatio = inWhite / outWhite; + + const float a = 0.2f; + float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio)); + float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio); + float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio)); + const float e = 0.02f; + const float f = 0.30f; + + lutMaterial.SetVector(Uniforms._NeutralTonemapperParams1, new Vector4(a, b, c, d)); + lutMaterial.SetVector(Uniforms._NeutralTonemapperParams2, new Vector4(e, f, tonemapping.neutralWhiteLevel, tonemapping.neutralWhiteClip / scaleFactorHalf)); + break; + } + + case ColorGradingModel.Tonemapper.ACES: + { + lutMaterial.EnableKeyword("TONEMAPPING_FILMIC"); + break; + } + } + + // Color balance & basic grading settings + lutMaterial.SetFloat(Uniforms._HueShift, settings.basic.hueShift / 360f); + lutMaterial.SetFloat(Uniforms._Saturation, settings.basic.saturation); + lutMaterial.SetFloat(Uniforms._Contrast, settings.basic.contrast); + lutMaterial.SetVector(Uniforms._Balance, CalculateColorBalance(settings.basic.temperature, settings.basic.tint)); + + // Lift / Gamma / Gain + Vector3 lift, gamma, gain; + CalculateLiftGammaGain( + settings.colorWheels.linear.lift, + settings.colorWheels.linear.gamma, + settings.colorWheels.linear.gain, + out lift, out gamma, out gain + ); + + lutMaterial.SetVector(Uniforms._Lift, lift); + lutMaterial.SetVector(Uniforms._InvGamma, gamma); + lutMaterial.SetVector(Uniforms._Gain, gain); + + // Slope / Power / Offset + Vector3 slope, power, offset; + CalculateSlopePowerOffset( + settings.colorWheels.log.slope, + settings.colorWheels.log.power, + settings.colorWheels.log.offset, + out slope, out power, out offset + ); + + lutMaterial.SetVector(Uniforms._Slope, slope); + lutMaterial.SetVector(Uniforms._Power, power); + lutMaterial.SetVector(Uniforms._Offset, offset); + + // Channel mixer + lutMaterial.SetVector(Uniforms._ChannelMixerRed, settings.channelMixer.red); + lutMaterial.SetVector(Uniforms._ChannelMixerGreen, settings.channelMixer.green); + lutMaterial.SetVector(Uniforms._ChannelMixerBlue, settings.channelMixer.blue); + + // Selective grading & YRGB curves + lutMaterial.SetTexture(Uniforms._Curves, GetCurveTexture()); + + // Generate the lut + Graphics.Blit(null, model.bakedLut, lutMaterial, 0); + } + + public override void Prepare(Material uberMaterial) + { + if (model.isDirty || !IsLogLutValid(model.bakedLut)) + { + GenerateLut(); + model.isDirty = false; + } + + uberMaterial.EnableKeyword( + context.profile.debugViews.IsModeActive(DebugMode.PreGradingLog) + ? "COLOR_GRADING_LOG_VIEW" + : "COLOR_GRADING" + ); + + var bakedLut = model.bakedLut; + uberMaterial.SetTexture(Uniforms._LogLut, bakedLut); + uberMaterial.SetVector(Uniforms._LogLut_Params, new Vector3(1f / bakedLut.width, 1f / bakedLut.height, bakedLut.height - 1f)); + + float ev = Mathf.Exp(model.settings.basic.postExposure * 0.69314718055994530941723212145818f); + uberMaterial.SetFloat(Uniforms._ExposureEV, ev); + } + + public void OnGUI() + { + var bakedLut = model.bakedLut; + var rect = new Rect(context.viewport.x * Screen.width + 8f, 8f, bakedLut.width, bakedLut.height); + GUI.DrawTexture(rect, bakedLut); + } + + public override void OnDisable() + { + GraphicsUtils.Destroy(m_GradingCurves); + GraphicsUtils.Destroy(model.bakedLut); + m_GradingCurves = null; + model.bakedLut = null; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs.meta new file mode 100644 index 0000000..59e7758 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ColorGradingComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9baf73db7c9fc1b478f4a0a1000c86f5 +timeCreated: 1473086520 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs b/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs new file mode 100644 index 0000000..c79a333 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs @@ -0,0 +1,165 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using DebugMode = BuiltinDebugViewsModel.Mode; + + public sealed class DepthOfFieldComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _DepthOfFieldTex = Shader.PropertyToID("_DepthOfFieldTex"); + internal static readonly int _DepthOfFieldCoCTex = Shader.PropertyToID("_DepthOfFieldCoCTex"); + internal static readonly int _Distance = Shader.PropertyToID("_Distance"); + internal static readonly int _LensCoeff = Shader.PropertyToID("_LensCoeff"); + internal static readonly int _MaxCoC = Shader.PropertyToID("_MaxCoC"); + internal static readonly int _RcpMaxCoC = Shader.PropertyToID("_RcpMaxCoC"); + internal static readonly int _RcpAspect = Shader.PropertyToID("_RcpAspect"); + internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); + internal static readonly int _CoCTex = Shader.PropertyToID("_CoCTex"); + internal static readonly int _TaaParams = Shader.PropertyToID("_TaaParams"); + internal static readonly int _DepthOfFieldParams = Shader.PropertyToID("_DepthOfFieldParams"); + } + + const string k_ShaderString = "Hidden/Post FX/Depth Of Field"; + + public override bool active + { + get + { + return model.enabled + && !context.interrupted; + } + } + + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth; + } + + RenderTexture m_CoCHistory; + + // Height of the 35mm full-frame format (36mm x 24mm) + const float k_FilmHeight = 0.024f; + + float CalculateFocalLength() + { + var settings = model.settings; + + if (!settings.useCameraFov) + return settings.focalLength / 1000f; + + float fov = context.camera.fieldOfView * Mathf.Deg2Rad; + return 0.5f * k_FilmHeight / Mathf.Tan(0.5f * fov); + } + + float CalculateMaxCoCRadius(int screenHeight) + { + // Estimate the allowable maximum radius of CoC from the kernel + // size (the equation below was empirically derived). + float radiusInPixels = (float)model.settings.kernelSize * 4f + 6f; + + // Applying a 5% limit to the CoC radius to keep the size of + // TileMax/NeighborMax small enough. + return Mathf.Min(0.05f, radiusInPixels / screenHeight); + } + + bool CheckHistory(int width, int height) + { + return m_CoCHistory != null && m_CoCHistory.IsCreated() && + m_CoCHistory.width == width && m_CoCHistory.height == height; + } + + RenderTextureFormat SelectFormat(RenderTextureFormat primary, RenderTextureFormat secondary) + { + if (SystemInfo.SupportsRenderTextureFormat(primary)) return primary; + if (SystemInfo.SupportsRenderTextureFormat(secondary)) return secondary; + return RenderTextureFormat.Default; + } + + public void Prepare(RenderTexture source, Material uberMaterial, bool antialiasCoC, Vector2 taaJitter, float taaBlending) + { + var settings = model.settings; + var colorFormat = RenderTextureFormat.DefaultHDR; + var cocFormat = SelectFormat(RenderTextureFormat.R8, RenderTextureFormat.RHalf); + + // Avoid using R8 on OSX with Metal. #896121, https://goo.gl/MgKqu6 + #if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) && !UNITY_2017_1_OR_NEWER + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) + cocFormat = SelectFormat(RenderTextureFormat.RHalf, RenderTextureFormat.Default); + #endif + + // Material setup + var f = CalculateFocalLength(); + var s1 = Mathf.Max(settings.focusDistance, f); + var aspect = (float)source.width / source.height; + var coeff = f * f / (settings.aperture * (s1 - f) * k_FilmHeight * 2); + var maxCoC = CalculateMaxCoCRadius(source.height); + + var material = context.materialFactory.Get(k_ShaderString); + material.SetFloat(Uniforms._Distance, s1); + material.SetFloat(Uniforms._LensCoeff, coeff); + material.SetFloat(Uniforms._MaxCoC, maxCoC); + material.SetFloat(Uniforms._RcpMaxCoC, 1f / maxCoC); + material.SetFloat(Uniforms._RcpAspect, 1f / aspect); + + // CoC calculation pass + var rtCoC = context.renderTextureFactory.Get(context.width, context.height, 0, cocFormat, RenderTextureReadWrite.Linear); + Graphics.Blit(null, rtCoC, material, 0); + + if (antialiasCoC) + { + // CoC temporal filter pass + material.SetTexture(Uniforms._CoCTex, rtCoC); + + var blend = CheckHistory(context.width, context.height) ? taaBlending : 0f; + material.SetVector(Uniforms._TaaParams, new Vector3(taaJitter.x, taaJitter.y, blend)); + + var rtFiltered = RenderTexture.GetTemporary(context.width, context.height, 0, cocFormat); + Graphics.Blit(m_CoCHistory, rtFiltered, material, 1); + + context.renderTextureFactory.Release(rtCoC); + if (m_CoCHistory != null) RenderTexture.ReleaseTemporary(m_CoCHistory); + + m_CoCHistory = rtCoC = rtFiltered; + } + + // Downsampling and prefiltering pass + var rt1 = context.renderTextureFactory.Get(context.width / 2, context.height / 2, 0, colorFormat); + material.SetTexture(Uniforms._CoCTex, rtCoC); + Graphics.Blit(source, rt1, material, 2); + + // Bokeh simulation pass + var rt2 = context.renderTextureFactory.Get(context.width / 2, context.height / 2, 0, colorFormat); + Graphics.Blit(rt1, rt2, material, 3 + (int)settings.kernelSize); + + // Postfilter pass + Graphics.Blit(rt2, rt1, material, 7); + + // Give the results to the uber shader. + uberMaterial.SetVector(Uniforms._DepthOfFieldParams, new Vector3(s1, coeff, maxCoC)); + + if (context.profile.debugViews.IsModeActive(DebugMode.FocusPlane)) + { + uberMaterial.EnableKeyword("DEPTH_OF_FIELD_COC_VIEW"); + context.Interrupt(); + } + else + { + uberMaterial.SetTexture(Uniforms._DepthOfFieldTex, rt1); + uberMaterial.SetTexture(Uniforms._DepthOfFieldCoCTex, rtCoC); + uberMaterial.EnableKeyword("DEPTH_OF_FIELD"); + } + + context.renderTextureFactory.Release(rt2); + } + + public override void OnDisable() + { + if (m_CoCHistory != null) + RenderTexture.ReleaseTemporary(m_CoCHistory); + + m_CoCHistory = null; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs.meta new file mode 100644 index 0000000..f4191ba --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/DepthOfFieldComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d862c8701bf34c342b95cf9058d0b70c +timeCreated: 1468410915 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs b/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs new file mode 100644 index 0000000..a0b594b --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs @@ -0,0 +1,71 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class DitheringComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _DitheringTex = Shader.PropertyToID("_DitheringTex"); + internal static readonly int _DitheringCoords = Shader.PropertyToID("_DitheringCoords"); + } + + public override bool active + { + get + { + return model.enabled + && !context.interrupted; + } + } + + // Holds 64 64x64 Alpha8 textures (256kb total) + Texture2D[] noiseTextures; + int textureIndex = 0; + + const int k_TextureCount = 64; + + public override void OnDisable() + { + noiseTextures = null; + } + + void LoadNoiseTextures() + { + noiseTextures = new Texture2D[k_TextureCount]; + + for (int i = 0; i < k_TextureCount; i++) + noiseTextures[i] = Resources.Load("Bluenoise64/LDR_LLL1_" + i); + } + + public override void Prepare(Material uberMaterial) + { + float rndOffsetX; + float rndOffsetY; + +#if POSTFX_DEBUG_STATIC_DITHERING + textureIndex = 0; + rndOffsetX = 0f; + rndOffsetY = 0f; +#else + if (++textureIndex >= k_TextureCount) + textureIndex = 0; + + rndOffsetX = Random.value; + rndOffsetY = Random.value; +#endif + + if (noiseTextures == null) + LoadNoiseTextures(); + + var noiseTex = noiseTextures[textureIndex]; + + uberMaterial.EnableKeyword("DITHERING"); + uberMaterial.SetTexture(Uniforms._DitheringTex, noiseTex); + uberMaterial.SetVector(Uniforms._DitheringCoords, new Vector4( + (float)context.width / (float)noiseTex.width, + (float)context.height / (float)noiseTex.height, + rndOffsetX, + rndOffsetY + )); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs.meta new file mode 100644 index 0000000..7c6dd3b --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/DitheringComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 35ceb4b3cfab56d43a3f0efeb9d68c43 +timeCreated: 1485179235 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs b/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs new file mode 100644 index 0000000..2d07ba6 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs @@ -0,0 +1,185 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class EyeAdaptationComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _Params = Shader.PropertyToID("_Params"); + internal static readonly int _Speed = Shader.PropertyToID("_Speed"); + internal static readonly int _ScaleOffsetRes = Shader.PropertyToID("_ScaleOffsetRes"); + internal static readonly int _ExposureCompensation = Shader.PropertyToID("_ExposureCompensation"); + internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure"); + internal static readonly int _DebugWidth = Shader.PropertyToID("_DebugWidth"); + } + + ComputeShader m_EyeCompute; + ComputeBuffer m_HistogramBuffer; + + readonly RenderTexture[] m_AutoExposurePool = new RenderTexture[2]; + int m_AutoExposurePingPing; + RenderTexture m_CurrentAutoExposure; + + RenderTexture m_DebugHistogram; + + static uint[] s_EmptyHistogramBuffer; + + bool m_FirstFrame = true; + + // Don't forget to update 'EyeAdaptation.cginc' if you change these values ! + const int k_HistogramBins = 64; + const int k_HistogramThreadX = 16; + const int k_HistogramThreadY = 16; + + public override bool active + { + get + { + return model.enabled + && SystemInfo.supportsComputeShaders + && !context.interrupted; + } + } + + public void ResetHistory() + { + m_FirstFrame = true; + } + + public override void OnEnable() + { + m_FirstFrame = true; + } + + public override void OnDisable() + { + foreach (var rt in m_AutoExposurePool) + GraphicsUtils.Destroy(rt); + + if (m_HistogramBuffer != null) + m_HistogramBuffer.Release(); + + m_HistogramBuffer = null; + + if (m_DebugHistogram != null) + m_DebugHistogram.Release(); + + m_DebugHistogram = null; + } + + Vector4 GetHistogramScaleOffsetRes() + { + var settings = model.settings; + float diff = settings.logMax - settings.logMin; + float scale = 1f / diff; + float offset = -settings.logMin * scale; + return new Vector4(scale, offset, Mathf.Floor(context.width / 2f), Mathf.Floor(context.height / 2f)); + } + + public Texture Prepare(RenderTexture source, Material uberMaterial) + { + var settings = model.settings; + + // Setup compute + if (m_EyeCompute == null) + m_EyeCompute = Resources.Load("Shaders/EyeHistogram"); + + var material = context.materialFactory.Get("Hidden/Post FX/Eye Adaptation"); + material.shaderKeywords = null; + + if (m_HistogramBuffer == null) + m_HistogramBuffer = new ComputeBuffer(k_HistogramBins, sizeof(uint)); + + if (s_EmptyHistogramBuffer == null) + s_EmptyHistogramBuffer = new uint[k_HistogramBins]; + + // Downscale the framebuffer, we don't need an absolute precision for auto exposure and it + // helps making it more stable + var scaleOffsetRes = GetHistogramScaleOffsetRes(); + + var rt = context.renderTextureFactory.Get((int)scaleOffsetRes.z, (int)scaleOffsetRes.w, 0, source.format); + Graphics.Blit(source, rt); + + if (m_AutoExposurePool[0] == null || !m_AutoExposurePool[0].IsCreated()) + m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat); + + if (m_AutoExposurePool[1] == null || !m_AutoExposurePool[1].IsCreated()) + m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat); + + // Clears the buffer on every frame as we use it to accumulate luminance values on each frame + m_HistogramBuffer.SetData(s_EmptyHistogramBuffer); + + // Gets a log histogram + int kernel = m_EyeCompute.FindKernel("KEyeHistogram"); + m_EyeCompute.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); + m_EyeCompute.SetTexture(kernel, "_Source", rt); + m_EyeCompute.SetVector("_ScaleOffsetRes", scaleOffsetRes); + m_EyeCompute.Dispatch(kernel, Mathf.CeilToInt(rt.width / (float)k_HistogramThreadX), Mathf.CeilToInt(rt.height / (float)k_HistogramThreadY), 1); + + // Cleanup + context.renderTextureFactory.Release(rt); + + // Make sure filtering values are correct to avoid apocalyptic consequences + const float minDelta = 1e-2f; + settings.highPercent = Mathf.Clamp(settings.highPercent, 1f + minDelta, 99f); + settings.lowPercent = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - minDelta); + + // Compute auto exposure + material.SetBuffer("_Histogram", m_HistogramBuffer); // No (int, buffer) overload for SetBuffer ? + material.SetVector(Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.69314718055994530941723212145818f), Mathf.Exp(settings.maxLuminance * 0.69314718055994530941723212145818f))); + material.SetVector(Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp)); + material.SetVector(Uniforms._ScaleOffsetRes, scaleOffsetRes); + material.SetFloat(Uniforms._ExposureCompensation, settings.keyValue); + + if (settings.dynamicKeyValue) + material.EnableKeyword("AUTO_KEY_VALUE"); + + if (m_FirstFrame || !Application.isPlaying) + { + // We don't want eye adaptation when not in play mode because the GameView isn't + // animated, thus making it harder to tweak. Just use the final audo exposure value. + m_CurrentAutoExposure = m_AutoExposurePool[0]; + Graphics.Blit(null, m_CurrentAutoExposure, material, (int)EyeAdaptationModel.EyeAdaptationType.Fixed); + + // Copy current exposure to the other pingpong target to avoid adapting from black + Graphics.Blit(m_AutoExposurePool[0], m_AutoExposurePool[1]); + } + else + { + int pp = m_AutoExposurePingPing; + var src = m_AutoExposurePool[++pp % 2]; + var dst = m_AutoExposurePool[++pp % 2]; + Graphics.Blit(src, dst, material, (int)settings.adaptationType); + m_AutoExposurePingPing = ++pp % 2; + m_CurrentAutoExposure = dst; + } + + // Generate debug histogram + if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation)) + { + if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated()) + { + m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32) + { + filterMode = FilterMode.Point, + wrapMode = TextureWrapMode.Clamp + }; + } + + material.SetFloat(Uniforms._DebugWidth, m_DebugHistogram.width); + Graphics.Blit(null, m_DebugHistogram, material, 2); + } + + m_FirstFrame = false; + return m_CurrentAutoExposure; + } + + public void OnGUI() + { + if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated()) + return; + + var rect = new Rect(context.viewport.x * Screen.width + 8f, 8f, m_DebugHistogram.width, m_DebugHistogram.height); + GUI.DrawTexture(rect, m_DebugHistogram); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs.meta new file mode 100644 index 0000000..aef3d46 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/EyeAdaptationComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c227d71a4040d304c943c26e0914bdeb +timeCreated: 1473088756 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/FogComponent.cs b/Assets/PostProcessing/Runtime/Components/FogComponent.cs new file mode 100644 index 0000000..f04691e --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/FogComponent.cs @@ -0,0 +1,79 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + public sealed class FogComponent : PostProcessingComponentCommandBuffer + { + static class Uniforms + { + internal static readonly int _FogColor = Shader.PropertyToID("_FogColor"); + internal static readonly int _Density = Shader.PropertyToID("_Density"); + internal static readonly int _Start = Shader.PropertyToID("_Start"); + internal static readonly int _End = Shader.PropertyToID("_End"); + internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); + } + + const string k_ShaderString = "Hidden/Post FX/Fog"; + + public override bool active + { + get + { + return model.enabled + && context.isGBufferAvailable // In forward fog is already done at shader level + && RenderSettings.fog + && !context.interrupted; + } + } + + public override string GetName() + { + return "Fog"; + } + + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth; + } + + public override CameraEvent GetCameraEvent() + { + return CameraEvent.AfterImageEffectsOpaque; + } + + public override void PopulateCommandBuffer(CommandBuffer cb) + { + var settings = model.settings; + + var material = context.materialFactory.Get(k_ShaderString); + material.shaderKeywords = null; + var fogColor = GraphicsUtils.isLinearColorSpace ? RenderSettings.fogColor.linear : RenderSettings.fogColor; + material.SetColor(Uniforms._FogColor, fogColor); + material.SetFloat(Uniforms._Density, RenderSettings.fogDensity); + material.SetFloat(Uniforms._Start, RenderSettings.fogStartDistance); + material.SetFloat(Uniforms._End, RenderSettings.fogEndDistance); + + switch (RenderSettings.fogMode) + { + case FogMode.Linear: + material.EnableKeyword("FOG_LINEAR"); + break; + case FogMode.Exponential: + material.EnableKeyword("FOG_EXP"); + break; + case FogMode.ExponentialSquared: + material.EnableKeyword("FOG_EXP2"); + break; + } + + var fbFormat = context.isHdr + ? RenderTextureFormat.DefaultHDR + : RenderTextureFormat.Default; + + cb.GetTemporaryRT(Uniforms._TempRT, context.width, context.height, 24, FilterMode.Bilinear, fbFormat); + cb.Blit(BuiltinRenderTextureType.CameraTarget, Uniforms._TempRT); + cb.Blit(Uniforms._TempRT, BuiltinRenderTextureType.CameraTarget, material, settings.excludeSkybox ? 1 : 0); + cb.ReleaseTemporaryRT(Uniforms._TempRT); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/FogComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/FogComponent.cs.meta new file mode 100644 index 0000000..3044a43 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/FogComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d0363c1cc7de62b4989190994103f5e2 +timeCreated: 1487334918 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs b/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs new file mode 100644 index 0000000..d3b03dd --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs @@ -0,0 +1,48 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class FxaaComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _QualitySettings = Shader.PropertyToID("_QualitySettings"); + internal static readonly int _ConsoleSettings = Shader.PropertyToID("_ConsoleSettings"); + } + + public override bool active + { + get + { + return model.enabled + && model.settings.method == AntialiasingModel.Method.Fxaa + && !context.interrupted; + } + } + + public void Render(RenderTexture source, RenderTexture destination) + { + var settings = model.settings.fxaaSettings; + var material = context.materialFactory.Get("Hidden/Post FX/FXAA"); + var qualitySettings = AntialiasingModel.FxaaQualitySettings.presets[(int)settings.preset]; + var consoleSettings = AntialiasingModel.FxaaConsoleSettings.presets[(int)settings.preset]; + + material.SetVector(Uniforms._QualitySettings, + new Vector3( + qualitySettings.subpixelAliasingRemovalAmount, + qualitySettings.edgeDetectionThreshold, + qualitySettings.minimumRequiredLuminance + ) + ); + + material.SetVector(Uniforms._ConsoleSettings, + new Vector4( + consoleSettings.subpixelSpreadAmount, + consoleSettings.edgeSharpnessAmount, + consoleSettings.edgeDetectionThreshold, + consoleSettings.minimumRequiredLuminance + ) + ); + + Graphics.Blit(source, destination, material, 0); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs.meta new file mode 100644 index 0000000..43737d7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/FxaaComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d4e1109c5030ca04e9a28243a35155ff +timeCreated: 1473088423 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/GrainComponent.cs b/Assets/PostProcessing/Runtime/Components/GrainComponent.cs new file mode 100644 index 0000000..10c2a47 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/GrainComponent.cs @@ -0,0 +1,79 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class GrainComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _Grain_Params1 = Shader.PropertyToID("_Grain_Params1"); + internal static readonly int _Grain_Params2 = Shader.PropertyToID("_Grain_Params2"); + internal static readonly int _GrainTex = Shader.PropertyToID("_GrainTex"); + internal static readonly int _Phase = Shader.PropertyToID("_Phase"); + } + + public override bool active + { + get + { + return model.enabled + && model.settings.intensity > 0f + && SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) + && !context.interrupted; + } + } + + RenderTexture m_GrainLookupRT; + + public override void OnDisable() + { + GraphicsUtils.Destroy(m_GrainLookupRT); + m_GrainLookupRT = null; + } + + public override void Prepare(Material uberMaterial) + { + var settings = model.settings; + + uberMaterial.EnableKeyword("GRAIN"); + + float rndOffsetX; + float rndOffsetY; + +#if POSTFX_DEBUG_STATIC_GRAIN + // Chosen by a fair dice roll + float time = 4f; + rndOffsetX = 0f; + rndOffsetY = 0f; +#else + float time = Time.realtimeSinceStartup; + rndOffsetX = Random.value; + rndOffsetY = Random.value; +#endif + + // Generate the grain lut for the current frame first + if (m_GrainLookupRT == null || !m_GrainLookupRT.IsCreated()) + { + GraphicsUtils.Destroy(m_GrainLookupRT); + + m_GrainLookupRT = new RenderTexture(192, 192, 0, RenderTextureFormat.ARGBHalf) + { + filterMode = FilterMode.Bilinear, + wrapMode = TextureWrapMode.Repeat, + anisoLevel = 0, + name = "Grain Lookup Texture" + }; + + m_GrainLookupRT.Create(); + } + + var grainMaterial = context.materialFactory.Get("Hidden/Post FX/Grain Generator"); + grainMaterial.SetFloat(Uniforms._Phase, time / 20f); + + Graphics.Blit((Texture)null, m_GrainLookupRT, grainMaterial, settings.colored ? 1 : 0); + + // Send everything to the uber shader + uberMaterial.SetTexture(Uniforms._GrainTex, m_GrainLookupRT); + uberMaterial.SetVector(Uniforms._Grain_Params1, new Vector2(settings.luminanceContribution, settings.intensity * 20f)); + uberMaterial.SetVector(Uniforms._Grain_Params2, new Vector4((float)context.width / (float)m_GrainLookupRT.width / settings.size, (float)context.height / (float)m_GrainLookupRT.height / settings.size, rndOffsetX, rndOffsetY)); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/GrainComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/GrainComponent.cs.meta new file mode 100644 index 0000000..494b43f --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/GrainComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6ff793ec42153c34799eed059982bac3 +timeCreated: 1473084716 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs b/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs new file mode 100644 index 0000000..4f79381 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs @@ -0,0 +1,444 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using Settings = MotionBlurModel.Settings; + + public sealed class MotionBlurComponent : PostProcessingComponentCommandBuffer + { + static class Uniforms + { + internal static readonly int _VelocityScale = Shader.PropertyToID("_VelocityScale"); + internal static readonly int _MaxBlurRadius = Shader.PropertyToID("_MaxBlurRadius"); + internal static readonly int _RcpMaxBlurRadius = Shader.PropertyToID("_RcpMaxBlurRadius"); + internal static readonly int _VelocityTex = Shader.PropertyToID("_VelocityTex"); + internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); + internal static readonly int _Tile2RT = Shader.PropertyToID("_Tile2RT"); + internal static readonly int _Tile4RT = Shader.PropertyToID("_Tile4RT"); + internal static readonly int _Tile8RT = Shader.PropertyToID("_Tile8RT"); + internal static readonly int _TileMaxOffs = Shader.PropertyToID("_TileMaxOffs"); + internal static readonly int _TileMaxLoop = Shader.PropertyToID("_TileMaxLoop"); + internal static readonly int _TileVRT = Shader.PropertyToID("_TileVRT"); + internal static readonly int _NeighborMaxTex = Shader.PropertyToID("_NeighborMaxTex"); + internal static readonly int _LoopCount = Shader.PropertyToID("_LoopCount"); + internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); + + internal static readonly int _History1LumaTex = Shader.PropertyToID("_History1LumaTex"); + internal static readonly int _History2LumaTex = Shader.PropertyToID("_History2LumaTex"); + internal static readonly int _History3LumaTex = Shader.PropertyToID("_History3LumaTex"); + internal static readonly int _History4LumaTex = Shader.PropertyToID("_History4LumaTex"); + + internal static readonly int _History1ChromaTex = Shader.PropertyToID("_History1ChromaTex"); + internal static readonly int _History2ChromaTex = Shader.PropertyToID("_History2ChromaTex"); + internal static readonly int _History3ChromaTex = Shader.PropertyToID("_History3ChromaTex"); + internal static readonly int _History4ChromaTex = Shader.PropertyToID("_History4ChromaTex"); + + internal static readonly int _History1Weight = Shader.PropertyToID("_History1Weight"); + internal static readonly int _History2Weight = Shader.PropertyToID("_History2Weight"); + internal static readonly int _History3Weight = Shader.PropertyToID("_History3Weight"); + internal static readonly int _History4Weight = Shader.PropertyToID("_History4Weight"); + } + + enum Pass + { + VelocitySetup, + TileMax1, + TileMax2, + TileMaxV, + NeighborMax, + Reconstruction, + FrameCompression, + FrameBlendingChroma, + FrameBlendingRaw + } + + public class ReconstructionFilter + { + // Texture format for storing 2D vectors. + RenderTextureFormat m_VectorRTFormat = RenderTextureFormat.RGHalf; + + // Texture format for storing packed velocity/depth. + RenderTextureFormat m_PackedRTFormat = RenderTextureFormat.ARGB2101010; + + public ReconstructionFilter() + { + CheckTextureFormatSupport(); + } + + void CheckTextureFormatSupport() + { + // If 2:10:10:10 isn't supported, use ARGB32 instead. + if (!SystemInfo.SupportsRenderTextureFormat(m_PackedRTFormat)) + m_PackedRTFormat = RenderTextureFormat.ARGB32; + } + + public bool IsSupported() + { + return SystemInfo.supportsMotionVectors; + } + + public void ProcessImage(PostProcessingContext context, CommandBuffer cb, ref Settings settings, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material) + { + const float kMaxBlurRadius = 5f; + + // Calculate the maximum blur radius in pixels. + int maxBlurPixels = (int)(kMaxBlurRadius * context.height / 100); + + // Calculate the TileMax size. + // It should be a multiple of 8 and larger than maxBlur. + int tileSize = ((maxBlurPixels - 1) / 8 + 1) * 8; + + // Pass 1 - Velocity/depth packing + var velocityScale = settings.shutterAngle / 360f; + cb.SetGlobalFloat(Uniforms._VelocityScale, velocityScale); + cb.SetGlobalFloat(Uniforms._MaxBlurRadius, maxBlurPixels); + cb.SetGlobalFloat(Uniforms._RcpMaxBlurRadius, 1f / maxBlurPixels); + + int vbuffer = Uniforms._VelocityTex; + cb.GetTemporaryRT(vbuffer, context.width, context.height, 0, FilterMode.Point, m_PackedRTFormat, RenderTextureReadWrite.Linear); + cb.Blit((Texture)null, vbuffer, material, (int)Pass.VelocitySetup); + + // Pass 2 - First TileMax filter (1/2 downsize) + int tile2 = Uniforms._Tile2RT; + cb.GetTemporaryRT(tile2, context.width / 2, context.height / 2, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear); + cb.SetGlobalTexture(Uniforms._MainTex, vbuffer); + cb.Blit(vbuffer, tile2, material, (int)Pass.TileMax1); + + // Pass 3 - Second TileMax filter (1/2 downsize) + int tile4 = Uniforms._Tile4RT; + cb.GetTemporaryRT(tile4, context.width / 4, context.height / 4, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear); + cb.SetGlobalTexture(Uniforms._MainTex, tile2); + cb.Blit(tile2, tile4, material, (int)Pass.TileMax2); + cb.ReleaseTemporaryRT(tile2); + + // Pass 4 - Third TileMax filter (1/2 downsize) + int tile8 = Uniforms._Tile8RT; + cb.GetTemporaryRT(tile8, context.width / 8, context.height / 8, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear); + cb.SetGlobalTexture(Uniforms._MainTex, tile4); + cb.Blit(tile4, tile8, material, (int)Pass.TileMax2); + cb.ReleaseTemporaryRT(tile4); + + // Pass 5 - Fourth TileMax filter (reduce to tileSize) + var tileMaxOffs = Vector2.one * (tileSize / 8f - 1f) * -0.5f; + cb.SetGlobalVector(Uniforms._TileMaxOffs, tileMaxOffs); + cb.SetGlobalFloat(Uniforms._TileMaxLoop, (int)(tileSize / 8f)); + + int tile = Uniforms._TileVRT; + cb.GetTemporaryRT(tile, context.width / tileSize, context.height / tileSize, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear); + cb.SetGlobalTexture(Uniforms._MainTex, tile8); + cb.Blit(tile8, tile, material, (int)Pass.TileMaxV); + cb.ReleaseTemporaryRT(tile8); + + // Pass 6 - NeighborMax filter + int neighborMax = Uniforms._NeighborMaxTex; + int neighborMaxWidth = context.width / tileSize; + int neighborMaxHeight = context.height / tileSize; + cb.GetTemporaryRT(neighborMax, neighborMaxWidth, neighborMaxHeight, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear); + cb.SetGlobalTexture(Uniforms._MainTex, tile); + cb.Blit(tile, neighborMax, material, (int)Pass.NeighborMax); + cb.ReleaseTemporaryRT(tile); + + // Pass 7 - Reconstruction pass + cb.SetGlobalFloat(Uniforms._LoopCount, Mathf.Clamp(settings.sampleCount / 2, 1, 64)); + cb.SetGlobalTexture(Uniforms._MainTex, source); + + cb.Blit(source, destination, material, (int)Pass.Reconstruction); + + cb.ReleaseTemporaryRT(vbuffer); + cb.ReleaseTemporaryRT(neighborMax); + } + } + + public class FrameBlendingFilter + { + struct Frame + { + public RenderTexture lumaTexture; + public RenderTexture chromaTexture; + + float m_Time; + RenderTargetIdentifier[] m_MRT; + + public float CalculateWeight(float strength, float currentTime) + { + if (Mathf.Approximately(m_Time, 0f)) + return 0f; + + var coeff = Mathf.Lerp(80f, 16f, strength); + return Mathf.Exp((m_Time - currentTime) * coeff); + } + + public void Release() + { + if (lumaTexture != null) + RenderTexture.ReleaseTemporary(lumaTexture); + + if (chromaTexture != null) + RenderTexture.ReleaseTemporary(chromaTexture); + + lumaTexture = null; + chromaTexture = null; + } + + public void MakeRecord(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material) + { + Release(); + + lumaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); + chromaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); + + lumaTexture.filterMode = FilterMode.Point; + chromaTexture.filterMode = FilterMode.Point; + + if (m_MRT == null) + m_MRT = new RenderTargetIdentifier[2]; + + m_MRT[0] = lumaTexture; + m_MRT[1] = chromaTexture; + + cb.SetGlobalTexture(Uniforms._MainTex, source); + cb.SetRenderTarget(m_MRT, lumaTexture); + cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, (int)Pass.FrameCompression); + + m_Time = Time.time; + } + + public void MakeRecordRaw(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, RenderTextureFormat format) + { + Release(); + + lumaTexture = RenderTexture.GetTemporary(width, height, 0, format); + lumaTexture.filterMode = FilterMode.Point; + + cb.SetGlobalTexture(Uniforms._MainTex, source); + cb.Blit(source, lumaTexture); + + m_Time = Time.time; + } + } + + bool m_UseCompression; + RenderTextureFormat m_RawTextureFormat; + + Frame[] m_FrameList; + int m_LastFrameCount; + + public FrameBlendingFilter() + { + m_UseCompression = CheckSupportCompression(); + m_RawTextureFormat = GetPreferredRenderTextureFormat(); + m_FrameList = new Frame[4]; + } + + public void Dispose() + { + foreach (var frame in m_FrameList) + frame.Release(); + } + + public void PushFrame(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material) + { + // Push only when actual update (do nothing while pausing) + var frameCount = Time.frameCount; + if (frameCount == m_LastFrameCount) return; + + // Update the frame record. + var index = frameCount % m_FrameList.Length; + + if (m_UseCompression) + m_FrameList[index].MakeRecord(cb, source, width, height, material); + else + m_FrameList[index].MakeRecordRaw(cb, source, width, height, m_RawTextureFormat); + + m_LastFrameCount = frameCount; + } + + public void BlendFrames(CommandBuffer cb, float strength, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material) + { + var t = Time.time; + + var f1 = GetFrameRelative(-1); + var f2 = GetFrameRelative(-2); + var f3 = GetFrameRelative(-3); + var f4 = GetFrameRelative(-4); + + cb.SetGlobalTexture(Uniforms._History1LumaTex, f1.lumaTexture); + cb.SetGlobalTexture(Uniforms._History2LumaTex, f2.lumaTexture); + cb.SetGlobalTexture(Uniforms._History3LumaTex, f3.lumaTexture); + cb.SetGlobalTexture(Uniforms._History4LumaTex, f4.lumaTexture); + + cb.SetGlobalTexture(Uniforms._History1ChromaTex, f1.chromaTexture); + cb.SetGlobalTexture(Uniforms._History2ChromaTex, f2.chromaTexture); + cb.SetGlobalTexture(Uniforms._History3ChromaTex, f3.chromaTexture); + cb.SetGlobalTexture(Uniforms._History4ChromaTex, f4.chromaTexture); + + cb.SetGlobalFloat(Uniforms._History1Weight, f1.CalculateWeight(strength, t)); + cb.SetGlobalFloat(Uniforms._History2Weight, f2.CalculateWeight(strength, t)); + cb.SetGlobalFloat(Uniforms._History3Weight, f3.CalculateWeight(strength, t)); + cb.SetGlobalFloat(Uniforms._History4Weight, f4.CalculateWeight(strength, t)); + + cb.SetGlobalTexture(Uniforms._MainTex, source); + cb.Blit(source, destination, material, m_UseCompression ? (int)Pass.FrameBlendingChroma : (int)Pass.FrameBlendingRaw); + } + + // Check if the platform has the capability of compression. + static bool CheckSupportCompression() + { + return + SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8) && + SystemInfo.supportedRenderTargetCount > 1; + } + + // Determine which 16-bit render texture format is available. + static RenderTextureFormat GetPreferredRenderTextureFormat() + { + RenderTextureFormat[] formats = + { + RenderTextureFormat.RGB565, + RenderTextureFormat.ARGB1555, + RenderTextureFormat.ARGB4444 + }; + + foreach (var f in formats) + if (SystemInfo.SupportsRenderTextureFormat(f)) return f; + + return RenderTextureFormat.Default; + } + + // Retrieve a frame record with relative indexing. + // Use a negative index to refer to previous frames. + Frame GetFrameRelative(int offset) + { + var index = (Time.frameCount + m_FrameList.Length + offset) % m_FrameList.Length; + return m_FrameList[index]; + } + } + + ReconstructionFilter m_ReconstructionFilter; + public ReconstructionFilter reconstructionFilter + { + get + { + if (m_ReconstructionFilter == null) + m_ReconstructionFilter = new ReconstructionFilter(); + + return m_ReconstructionFilter; + } + } + + FrameBlendingFilter m_FrameBlendingFilter; + public FrameBlendingFilter frameBlendingFilter + { + get + { + if (m_FrameBlendingFilter == null) + m_FrameBlendingFilter = new FrameBlendingFilter(); + + return m_FrameBlendingFilter; + } + } + + bool m_FirstFrame = true; + + public override bool active + { + get + { + var settings = model.settings; + return model.enabled + && ((settings.shutterAngle > 0f && reconstructionFilter.IsSupported()) || settings.frameBlending > 0f) + && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2 // No movecs on GLES2 platforms + && !context.interrupted; + } + } + + public override string GetName() + { + return "Motion Blur"; + } + + public void ResetHistory() + { + if (m_FrameBlendingFilter != null) + m_FrameBlendingFilter.Dispose(); + + m_FrameBlendingFilter = null; + } + + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth | DepthTextureMode.MotionVectors; + } + + public override CameraEvent GetCameraEvent() + { + return CameraEvent.BeforeImageEffects; + } + + public override void OnEnable() + { + m_FirstFrame = true; + } + + public override void PopulateCommandBuffer(CommandBuffer cb) + { +#if UNITY_EDITOR + // Don't render motion blur preview when the editor is not playing as it can in some + // cases results in ugly artifacts (i.e. when resizing the game view). + if (!Application.isPlaying) + return; +#endif + + // Skip rendering in the first frame as motion vectors won't be abvailable until the + // next one + if (m_FirstFrame) + { + m_FirstFrame = false; + return; + } + + var material = context.materialFactory.Get("Hidden/Post FX/Motion Blur"); + var blitMaterial = context.materialFactory.Get("Hidden/Post FX/Blit"); + var settings = model.settings; + + var fbFormat = context.isHdr + ? RenderTextureFormat.DefaultHDR + : RenderTextureFormat.Default; + + int tempRT = Uniforms._TempRT; + cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Point, fbFormat); + + if (settings.shutterAngle > 0f && settings.frameBlending > 0f) + { + // Motion blur + frame blending + reconstructionFilter.ProcessImage(context, cb, ref settings, BuiltinRenderTextureType.CameraTarget, tempRT, material); + frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material); + frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material); + } + else if (settings.shutterAngle > 0f) + { + // No frame blending + cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); + cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0); + reconstructionFilter.ProcessImage(context, cb, ref settings, tempRT, BuiltinRenderTextureType.CameraTarget, material); + } + else if (settings.frameBlending > 0f) + { + // Frame blending only + cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); + cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0); + frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material); + frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material); + } + + // Cleaning up + cb.ReleaseTemporaryRT(tempRT); + } + + public override void OnDisable() + { + if (m_FrameBlendingFilter != null) + m_FrameBlendingFilter.Dispose(); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs.meta new file mode 100644 index 0000000..2d1818d --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/MotionBlurComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9a9ae59cbb7c53e40851df7f32805098 +timeCreated: 1468325905 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs b/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs new file mode 100644 index 0000000..7411f85 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs @@ -0,0 +1,239 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using SSRResolution = ScreenSpaceReflectionModel.SSRResolution; + using SSRReflectionBlendType = ScreenSpaceReflectionModel.SSRReflectionBlendType; + + public sealed class ScreenSpaceReflectionComponent : PostProcessingComponentCommandBuffer + { + static class Uniforms + { + internal static readonly int _RayStepSize = Shader.PropertyToID("_RayStepSize"); + internal static readonly int _AdditiveReflection = Shader.PropertyToID("_AdditiveReflection"); + internal static readonly int _BilateralUpsampling = Shader.PropertyToID("_BilateralUpsampling"); + internal static readonly int _TreatBackfaceHitAsMiss = Shader.PropertyToID("_TreatBackfaceHitAsMiss"); + internal static readonly int _AllowBackwardsRays = Shader.PropertyToID("_AllowBackwardsRays"); + internal static readonly int _TraceBehindObjects = Shader.PropertyToID("_TraceBehindObjects"); + internal static readonly int _MaxSteps = Shader.PropertyToID("_MaxSteps"); + internal static readonly int _FullResolutionFiltering = Shader.PropertyToID("_FullResolutionFiltering"); + internal static readonly int _HalfResolution = Shader.PropertyToID("_HalfResolution"); + internal static readonly int _HighlightSuppression = Shader.PropertyToID("_HighlightSuppression"); + internal static readonly int _PixelsPerMeterAtOneMeter = Shader.PropertyToID("_PixelsPerMeterAtOneMeter"); + internal static readonly int _ScreenEdgeFading = Shader.PropertyToID("_ScreenEdgeFading"); + internal static readonly int _ReflectionBlur = Shader.PropertyToID("_ReflectionBlur"); + internal static readonly int _MaxRayTraceDistance = Shader.PropertyToID("_MaxRayTraceDistance"); + internal static readonly int _FadeDistance = Shader.PropertyToID("_FadeDistance"); + internal static readonly int _LayerThickness = Shader.PropertyToID("_LayerThickness"); + internal static readonly int _SSRMultiplier = Shader.PropertyToID("_SSRMultiplier"); + internal static readonly int _FresnelFade = Shader.PropertyToID("_FresnelFade"); + internal static readonly int _FresnelFadePower = Shader.PropertyToID("_FresnelFadePower"); + internal static readonly int _ReflectionBufferSize = Shader.PropertyToID("_ReflectionBufferSize"); + internal static readonly int _ScreenSize = Shader.PropertyToID("_ScreenSize"); + internal static readonly int _InvScreenSize = Shader.PropertyToID("_InvScreenSize"); + internal static readonly int _ProjInfo = Shader.PropertyToID("_ProjInfo"); + internal static readonly int _CameraClipInfo = Shader.PropertyToID("_CameraClipInfo"); + internal static readonly int _ProjectToPixelMatrix = Shader.PropertyToID("_ProjectToPixelMatrix"); + internal static readonly int _WorldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix"); + internal static readonly int _CameraToWorldMatrix = Shader.PropertyToID("_CameraToWorldMatrix"); + internal static readonly int _Axis = Shader.PropertyToID("_Axis"); + internal static readonly int _CurrentMipLevel = Shader.PropertyToID("_CurrentMipLevel"); + internal static readonly int _NormalAndRoughnessTexture = Shader.PropertyToID("_NormalAndRoughnessTexture"); + internal static readonly int _HitPointTexture = Shader.PropertyToID("_HitPointTexture"); + internal static readonly int _BlurTexture = Shader.PropertyToID("_BlurTexture"); + internal static readonly int _FilteredReflections = Shader.PropertyToID("_FilteredReflections"); + internal static readonly int _FinalReflectionTexture = Shader.PropertyToID("_FinalReflectionTexture"); + internal static readonly int _TempTexture = Shader.PropertyToID("_TempTexture"); + } + + // Unexposed variables + bool k_HighlightSuppression = false; + bool k_TraceBehindObjects = true; + bool k_TreatBackfaceHitAsMiss = false; + bool k_BilateralUpsample = true; + + enum PassIndex + { + RayTraceStep = 0, + CompositeFinal = 1, + Blur = 2, + CompositeSSR = 3, + MinMipGeneration = 4, + HitPointToReflections = 5, + BilateralKeyPack = 6, + BlitDepthAsCSZ = 7, + PoissonBlur = 8, + } + + readonly int[] m_ReflectionTextures = new int[5]; + + // Not really needed as SSR only works in deferred right now + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth; + } + + public override bool active + { + get + { + return model.enabled + && context.isGBufferAvailable + && !context.interrupted; + } + } + + public override void OnEnable() + { + m_ReflectionTextures[0] = Shader.PropertyToID("_ReflectionTexture0"); + m_ReflectionTextures[1] = Shader.PropertyToID("_ReflectionTexture1"); + m_ReflectionTextures[2] = Shader.PropertyToID("_ReflectionTexture2"); + m_ReflectionTextures[3] = Shader.PropertyToID("_ReflectionTexture3"); + m_ReflectionTextures[4] = Shader.PropertyToID("_ReflectionTexture4"); + } + + public override string GetName() + { + return "Screen Space Reflection"; + } + + public override CameraEvent GetCameraEvent() + { + return CameraEvent.AfterFinalPass; + } + + public override void PopulateCommandBuffer(CommandBuffer cb) + { + var settings = model.settings; + var camera = context.camera; + + // Material setup + int downsampleAmount = (settings.reflection.reflectionQuality == SSRResolution.High) ? 1 : 2; + + var rtW = context.width / downsampleAmount; + var rtH = context.height / downsampleAmount; + + float sWidth = context.width; + float sHeight = context.height; + + float sx = sWidth / 2f; + float sy = sHeight / 2f; + + var material = context.materialFactory.Get("Hidden/Post FX/Screen Space Reflection"); + + material.SetInt(Uniforms._RayStepSize, settings.reflection.stepSize); + material.SetInt(Uniforms._AdditiveReflection, settings.reflection.blendType == SSRReflectionBlendType.Additive ? 1 : 0); + material.SetInt(Uniforms._BilateralUpsampling, k_BilateralUpsample ? 1 : 0); + material.SetInt(Uniforms._TreatBackfaceHitAsMiss, k_TreatBackfaceHitAsMiss ? 1 : 0); + material.SetInt(Uniforms._AllowBackwardsRays, settings.reflection.reflectBackfaces ? 1 : 0); + material.SetInt(Uniforms._TraceBehindObjects, k_TraceBehindObjects ? 1 : 0); + material.SetInt(Uniforms._MaxSteps, settings.reflection.iterationCount); + material.SetInt(Uniforms._FullResolutionFiltering, 0); + material.SetInt(Uniforms._HalfResolution, (settings.reflection.reflectionQuality != SSRResolution.High) ? 1 : 0); + material.SetInt(Uniforms._HighlightSuppression, k_HighlightSuppression ? 1 : 0); + + // The height in pixels of a 1m object if viewed from 1m away. + float pixelsPerMeterAtOneMeter = sWidth / (-2f * Mathf.Tan(camera.fieldOfView / 180f * Mathf.PI * 0.5f)); + + material.SetFloat(Uniforms._PixelsPerMeterAtOneMeter, pixelsPerMeterAtOneMeter); + material.SetFloat(Uniforms._ScreenEdgeFading, settings.screenEdgeMask.intensity); + material.SetFloat(Uniforms._ReflectionBlur, settings.reflection.reflectionBlur); + material.SetFloat(Uniforms._MaxRayTraceDistance, settings.reflection.maxDistance); + material.SetFloat(Uniforms._FadeDistance, settings.intensity.fadeDistance); + material.SetFloat(Uniforms._LayerThickness, settings.reflection.widthModifier); + material.SetFloat(Uniforms._SSRMultiplier, settings.intensity.reflectionMultiplier); + material.SetFloat(Uniforms._FresnelFade, settings.intensity.fresnelFade); + material.SetFloat(Uniforms._FresnelFadePower, settings.intensity.fresnelFadePower); + + var P = camera.projectionMatrix; + var projInfo = new Vector4( + -2f / (sWidth * P[0]), + -2f / (sHeight * P[5]), + (1f - P[2]) / P[0], + (1f + P[6]) / P[5] + ); + + var cameraClipInfo = float.IsPositiveInfinity(camera.farClipPlane) ? + new Vector3(camera.nearClipPlane, -1f, 1f) : + new Vector3(camera.nearClipPlane * camera.farClipPlane, camera.nearClipPlane - camera.farClipPlane, camera.farClipPlane); + + material.SetVector(Uniforms._ReflectionBufferSize, new Vector2(rtW, rtH)); + material.SetVector(Uniforms._ScreenSize, new Vector2(sWidth, sHeight)); + material.SetVector(Uniforms._InvScreenSize, new Vector2(1f / sWidth, 1f / sHeight)); + material.SetVector(Uniforms._ProjInfo, projInfo); // used for unprojection + + material.SetVector(Uniforms._CameraClipInfo, cameraClipInfo); + + var warpToScreenSpaceMatrix = new Matrix4x4(); + warpToScreenSpaceMatrix.SetRow(0, new Vector4(sx, 0f, 0f, sx)); + warpToScreenSpaceMatrix.SetRow(1, new Vector4(0f, sy, 0f, sy)); + warpToScreenSpaceMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f)); + warpToScreenSpaceMatrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f)); + + var projectToPixelMatrix = warpToScreenSpaceMatrix * P; + + material.SetMatrix(Uniforms._ProjectToPixelMatrix, projectToPixelMatrix); + material.SetMatrix(Uniforms._WorldToCameraMatrix, camera.worldToCameraMatrix); + material.SetMatrix(Uniforms._CameraToWorldMatrix, camera.worldToCameraMatrix.inverse); + + // Command buffer setup + var intermediateFormat = context.isHdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32; + const int maxMip = 5; + + var kNormalAndRoughnessTexture = Uniforms._NormalAndRoughnessTexture; + var kHitPointTexture = Uniforms._HitPointTexture; + var kBlurTexture = Uniforms._BlurTexture; + var kFilteredReflections = Uniforms._FilteredReflections; + var kFinalReflectionTexture = Uniforms._FinalReflectionTexture; + var kTempTexture = Uniforms._TempTexture; + + // RGB: Normals, A: Roughness. + // Has the nice benefit of allowing us to control the filtering mode as well. + cb.GetTemporaryRT(kNormalAndRoughnessTexture, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); + + cb.GetTemporaryRT(kHitPointTexture, rtW, rtH, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear); + + for (int i = 0; i < maxMip; ++i) + { + // We explicitly interpolate during bilateral upsampling. + cb.GetTemporaryRT(m_ReflectionTextures[i], rtW >> i, rtH >> i, 0, FilterMode.Bilinear, intermediateFormat); + } + + cb.GetTemporaryRT(kFilteredReflections, rtW, rtH, 0, k_BilateralUpsample ? FilterMode.Point : FilterMode.Bilinear, intermediateFormat); + cb.GetTemporaryRT(kFinalReflectionTexture, rtW, rtH, 0, FilterMode.Point, intermediateFormat); + + cb.Blit(BuiltinRenderTextureType.CameraTarget, kNormalAndRoughnessTexture, material, (int)PassIndex.BilateralKeyPack); + cb.Blit(BuiltinRenderTextureType.CameraTarget, kHitPointTexture, material, (int)PassIndex.RayTraceStep); + cb.Blit(BuiltinRenderTextureType.CameraTarget, kFilteredReflections, material, (int)PassIndex.HitPointToReflections); + cb.Blit(kFilteredReflections, m_ReflectionTextures[0], material, (int)PassIndex.PoissonBlur); + + for (int i = 1; i < maxMip; ++i) + { + int inputTex = m_ReflectionTextures[i - 1]; + + int lowMip = i; + + cb.GetTemporaryRT(kBlurTexture, rtW >> lowMip, rtH >> lowMip, 0, FilterMode.Bilinear, intermediateFormat); + cb.SetGlobalVector(Uniforms._Axis, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + cb.SetGlobalFloat(Uniforms._CurrentMipLevel, i - 1.0f); + + cb.Blit(inputTex, kBlurTexture, material, (int)PassIndex.Blur); + + cb.SetGlobalVector(Uniforms._Axis, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + + inputTex = m_ReflectionTextures[i]; + cb.Blit(kBlurTexture, inputTex, material, (int)PassIndex.Blur); + cb.ReleaseTemporaryRT(kBlurTexture); + } + + cb.Blit(m_ReflectionTextures[0], kFinalReflectionTexture, material, (int)PassIndex.CompositeSSR); + + cb.GetTemporaryRT(kTempTexture, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Bilinear, intermediateFormat); + + cb.Blit(BuiltinRenderTextureType.CameraTarget, kTempTexture, material, (int)PassIndex.CompositeFinal); + cb.Blit(kTempTexture, BuiltinRenderTextureType.CameraTarget); + + cb.ReleaseTemporaryRT(kTempTexture); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs.meta new file mode 100644 index 0000000..2c4ad1c --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/ScreenSpaceReflectionComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dd75f795d6a798f44a7801082f6a703f +timeCreated: 1467626205 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/TaaComponent.cs b/Assets/PostProcessing/Runtime/Components/TaaComponent.cs new file mode 100644 index 0000000..afd9d49 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/TaaComponent.cs @@ -0,0 +1,216 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + public sealed class TaaComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static int _Jitter = Shader.PropertyToID("_Jitter"); + internal static int _SharpenParameters = Shader.PropertyToID("_SharpenParameters"); + internal static int _FinalBlendParameters = Shader.PropertyToID("_FinalBlendParameters"); + internal static int _HistoryTex = Shader.PropertyToID("_HistoryTex"); + internal static int _MainTex = Shader.PropertyToID("_MainTex"); + } + + const string k_ShaderString = "Hidden/Post FX/Temporal Anti-aliasing"; + const int k_SampleCount = 8; + + readonly RenderBuffer[] m_MRT = new RenderBuffer[2]; + + int m_SampleIndex = 0; + bool m_ResetHistory = true; + + RenderTexture m_HistoryTexture; + + public override bool active + { + get + { + return model.enabled + && model.settings.method == AntialiasingModel.Method.Taa + && SystemInfo.supportsMotionVectors + && SystemInfo.supportedRenderTargetCount >= 2 + && !context.interrupted; + } + } + + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth | DepthTextureMode.MotionVectors; + } + + public Vector2 jitterVector { get; private set; } + + public void ResetHistory() + { + m_ResetHistory = true; + } + + public void SetProjectionMatrix(Func jitteredFunc) + { + var settings = model.settings.taaSettings; + + var jitter = GenerateRandomOffset(); + jitter *= settings.jitterSpread; + + context.camera.nonJitteredProjectionMatrix = context.camera.projectionMatrix; + + if (jitteredFunc != null) + { + context.camera.projectionMatrix = jitteredFunc(jitter); + } + else + { + context.camera.projectionMatrix = context.camera.orthographic + ? GetOrthographicProjectionMatrix(jitter) + : GetPerspectiveProjectionMatrix(jitter); + } + +#if UNITY_5_5_OR_NEWER + context.camera.useJitteredProjectionMatrixForTransparentRendering = false; +#endif + + jitter.x /= context.width; + jitter.y /= context.height; + + var material = context.materialFactory.Get(k_ShaderString); + material.SetVector(Uniforms._Jitter, jitter); + + jitterVector = jitter; + } + + public void Render(RenderTexture source, RenderTexture destination) + { + var material = context.materialFactory.Get(k_ShaderString); + material.shaderKeywords = null; + + var settings = model.settings.taaSettings; + + if (m_ResetHistory || m_HistoryTexture == null || m_HistoryTexture.width != source.width || m_HistoryTexture.height != source.height) + { + if (m_HistoryTexture) + RenderTexture.ReleaseTemporary(m_HistoryTexture); + + m_HistoryTexture = RenderTexture.GetTemporary(source.width, source.height, 0, source.format); + m_HistoryTexture.name = "TAA History"; + + Graphics.Blit(source, m_HistoryTexture, material, 2); + } + + const float kMotionAmplification = 100f * 60f; + material.SetVector(Uniforms._SharpenParameters, new Vector4(settings.sharpen, 0f, 0f, 0f)); + material.SetVector(Uniforms._FinalBlendParameters, new Vector4(settings.stationaryBlending, settings.motionBlending, kMotionAmplification, 0f)); + material.SetTexture(Uniforms._MainTex, source); + material.SetTexture(Uniforms._HistoryTex, m_HistoryTexture); + + var tempHistory = RenderTexture.GetTemporary(source.width, source.height, 0, source.format); + tempHistory.name = "TAA History"; + + m_MRT[0] = destination.colorBuffer; + m_MRT[1] = tempHistory.colorBuffer; + + Graphics.SetRenderTarget(m_MRT, source.depthBuffer); + GraphicsUtils.Blit(material, context.camera.orthographic ? 1 : 0); + + RenderTexture.ReleaseTemporary(m_HistoryTexture); + m_HistoryTexture = tempHistory; + + m_ResetHistory = false; + } + + float GetHaltonValue(int index, int radix) + { + float result = 0f; + float fraction = 1f / (float)radix; + + while (index > 0) + { + result += (float)(index % radix) * fraction; + + index /= radix; + fraction /= (float)radix; + } + + return result; + } + + Vector2 GenerateRandomOffset() + { + var offset = new Vector2( + GetHaltonValue(m_SampleIndex & 1023, 2), + GetHaltonValue(m_SampleIndex & 1023, 3)); + + if (++m_SampleIndex >= k_SampleCount) + m_SampleIndex = 0; + + return offset; + } + + // Adapted heavily from PlayDead's TAA code + // https://github.com/playdeadgames/temporal/blob/master/Assets/Scripts/Extensions.cs + Matrix4x4 GetPerspectiveProjectionMatrix(Vector2 offset) + { + float vertical = Mathf.Tan(0.5f * Mathf.Deg2Rad * context.camera.fieldOfView); + float horizontal = vertical * context.camera.aspect; + + offset.x *= horizontal / (0.5f * context.width); + offset.y *= vertical / (0.5f * context.height); + + float left = (offset.x - horizontal) * context.camera.nearClipPlane; + float right = (offset.x + horizontal) * context.camera.nearClipPlane; + float top = (offset.y + vertical) * context.camera.nearClipPlane; + float bottom = (offset.y - vertical) * context.camera.nearClipPlane; + + var matrix = new Matrix4x4(); + + matrix[0, 0] = (2f * context.camera.nearClipPlane) / (right - left); + matrix[0, 1] = 0f; + matrix[0, 2] = (right + left) / (right - left); + matrix[0, 3] = 0f; + + matrix[1, 0] = 0f; + matrix[1, 1] = (2f * context.camera.nearClipPlane) / (top - bottom); + matrix[1, 2] = (top + bottom) / (top - bottom); + matrix[1, 3] = 0f; + + matrix[2, 0] = 0f; + matrix[2, 1] = 0f; + matrix[2, 2] = -(context.camera.farClipPlane + context.camera.nearClipPlane) / (context.camera.farClipPlane - context.camera.nearClipPlane); + matrix[2, 3] = -(2f * context.camera.farClipPlane * context.camera.nearClipPlane) / (context.camera.farClipPlane - context.camera.nearClipPlane); + + matrix[3, 0] = 0f; + matrix[3, 1] = 0f; + matrix[3, 2] = -1f; + matrix[3, 3] = 0f; + + return matrix; + } + + Matrix4x4 GetOrthographicProjectionMatrix(Vector2 offset) + { + float vertical = context.camera.orthographicSize; + float horizontal = vertical * context.camera.aspect; + + offset.x *= horizontal / (0.5f * context.width); + offset.y *= vertical / (0.5f * context.height); + + float left = offset.x - horizontal; + float right = offset.x + horizontal; + float top = offset.y + vertical; + float bottom = offset.y - vertical; + + return Matrix4x4.Ortho(left, right, bottom, top, context.camera.nearClipPlane, context.camera.farClipPlane); + } + + public override void OnDisable() + { + if (m_HistoryTexture != null) + RenderTexture.ReleaseTemporary(m_HistoryTexture); + + m_HistoryTexture = null; + m_SampleIndex = 0; + ResetHistory(); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/TaaComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/TaaComponent.cs.meta new file mode 100644 index 0000000..e0553ba --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/TaaComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f28703283e17be54180fd04a7c70e1d5 +timeCreated: 1472806965 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs b/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs new file mode 100644 index 0000000..0dd05de --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs @@ -0,0 +1,39 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class UserLutComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _UserLut = Shader.PropertyToID("_UserLut"); + internal static readonly int _UserLut_Params = Shader.PropertyToID("_UserLut_Params"); + } + + public override bool active + { + get + { + var settings = model.settings; + return model.enabled + && settings.lut != null + && settings.contribution > 0f + && settings.lut.height == (int)Mathf.Sqrt(settings.lut.width) + && !context.interrupted; + } + } + + public override void Prepare(Material uberMaterial) + { + var settings = model.settings; + uberMaterial.EnableKeyword("USER_LUT"); + uberMaterial.SetTexture(Uniforms._UserLut, settings.lut); + uberMaterial.SetVector(Uniforms._UserLut_Params, new Vector4(1f / settings.lut.width, 1f / settings.lut.height, settings.lut.height - 1f, settings.contribution)); + } + + public void OnGUI() + { + var settings = model.settings; + var rect = new Rect(context.viewport.x * Screen.width + 8f, 8f, settings.lut.width, settings.lut.height); + GUI.DrawTexture(rect, settings.lut); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs.meta new file mode 100644 index 0000000..58e6f50 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/UserLutComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 63cb071fb8442a14f85c02e6ddba9b72 +timeCreated: 1473086193 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs b/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs new file mode 100644 index 0000000..58148dd --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs @@ -0,0 +1,46 @@ +namespace UnityEngine.PostProcessing +{ + public sealed class VignetteComponent : PostProcessingComponentRenderTexture + { + static class Uniforms + { + internal static readonly int _Vignette_Color = Shader.PropertyToID("_Vignette_Color"); + internal static readonly int _Vignette_Center = Shader.PropertyToID("_Vignette_Center"); + internal static readonly int _Vignette_Settings = Shader.PropertyToID("_Vignette_Settings"); + internal static readonly int _Vignette_Mask = Shader.PropertyToID("_Vignette_Mask"); + internal static readonly int _Vignette_Opacity = Shader.PropertyToID("_Vignette_Opacity"); + } + + public override bool active + { + get + { + return model.enabled + && !context.interrupted; + } + } + + public override void Prepare(Material uberMaterial) + { + var settings = model.settings; + uberMaterial.SetColor(Uniforms._Vignette_Color, settings.color); + + if (settings.mode == VignetteModel.Mode.Classic) + { + uberMaterial.SetVector(Uniforms._Vignette_Center, settings.center); + uberMaterial.EnableKeyword("VIGNETTE_CLASSIC"); + float roundness = (1f - settings.roundness) * 6f + settings.roundness; + uberMaterial.SetVector(Uniforms._Vignette_Settings, new Vector4(settings.intensity * 3f, settings.smoothness * 5f, roundness, settings.rounded ? 1f : 0f)); + } + else if (settings.mode == VignetteModel.Mode.Masked) + { + if (settings.mask != null && settings.opacity > 0f) + { + uberMaterial.EnableKeyword("VIGNETTE_MASKED"); + uberMaterial.SetTexture(Uniforms._Vignette_Mask, settings.mask); + uberMaterial.SetFloat(Uniforms._Vignette_Opacity, settings.opacity); + } + } + } + } +} diff --git a/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs.meta b/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs.meta new file mode 100644 index 0000000..33806e2 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Components/VignetteComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 39074aa97f4be23438147346f081c7f3 +timeCreated: 1473083872 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models.meta b/Assets/PostProcessing/Runtime/Models.meta new file mode 100644 index 0000000..0133f91 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8d5a699332eb8a9499077fa4bcd4e0a0 +folderAsset: yes +timeCreated: 1459757852 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs b/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs new file mode 100644 index 0000000..189d447 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs @@ -0,0 +1,71 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class AmbientOcclusionModel : PostProcessingModel + { + public enum SampleCount + { + Lowest = 3, + Low = 6, + Medium = 10, + High = 16 + } + + [Serializable] + public struct Settings + { + [Range(0, 4), Tooltip("Degree of darkness produced by the effect.")] + public float intensity; + + [Min(1e-4f), Tooltip("Radius of sample points, which affects extent of darkened areas.")] + public float radius; + + [Tooltip("Number of sample points, which affects quality and performance.")] + public SampleCount sampleCount; + + [Tooltip("Halves the resolution of the effect to increase performance at the cost of visual quality.")] + public bool downsampling; + + [Tooltip("Forces compatibility with Forward rendered objects when working with the Deferred rendering path.")] + public bool forceForwardCompatibility; + + [Tooltip("Enables the ambient-only mode in that the effect only affects ambient lighting. This mode is only available with the Deferred rendering path and HDR rendering.")] + public bool ambientOnly; + + [Tooltip("Toggles the use of a higher precision depth texture with the forward rendering path (may impact performances). Has no effect with the deferred rendering path.")] + public bool highPrecision; + + public static Settings defaultSettings + { + get + { + return new Settings + { + intensity = 1f, + radius = 0.3f, + sampleCount = SampleCount.Medium, + downsampling = true, + forceForwardCompatibility = false, + ambientOnly = false, + highPrecision = false + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs.meta b/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs.meta new file mode 100644 index 0000000..fadb8b3 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/AmbientOcclusionModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 564228afc5cbd5f49beb80038b4b7af2 +timeCreated: 1462280796 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs b/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs new file mode 100644 index 0000000..05e73a7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs @@ -0,0 +1,242 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class AntialiasingModel : PostProcessingModel + { + public enum Method + { + Fxaa, + Taa + } + + // Most settings aren't exposed to the user anymore, presets are enough. Still, I'm leaving + // the tooltip attributes in case an user wants to customize each preset. + + #region FXAA Settings + public enum FxaaPreset + { + ExtremePerformance, + Performance, + Default, + Quality, + ExtremeQuality + } + + [Serializable] + public struct FxaaQualitySettings + { + [Tooltip("The amount of desired sub-pixel aliasing removal. Effects the sharpeness of the output.")] + [Range(0f, 1f)] + public float subpixelAliasingRemovalAmount; + + [Tooltip("The minimum amount of local contrast required to qualify a region as containing an edge.")] + [Range(0.063f, 0.333f)] + public float edgeDetectionThreshold; + + [Tooltip("Local contrast adaptation value to disallow the algorithm from executing on the darker regions.")] + [Range(0f, 0.0833f)] + public float minimumRequiredLuminance; + + public static FxaaQualitySettings[] presets = + { + // ExtremePerformance + new FxaaQualitySettings + { + subpixelAliasingRemovalAmount = 0f, + edgeDetectionThreshold = 0.333f, + minimumRequiredLuminance = 0.0833f + }, + + // Performance + new FxaaQualitySettings + { + subpixelAliasingRemovalAmount = 0.25f, + edgeDetectionThreshold = 0.25f, + minimumRequiredLuminance = 0.0833f + }, + + // Default + new FxaaQualitySettings + { + subpixelAliasingRemovalAmount = 0.75f, + edgeDetectionThreshold = 0.166f, + minimumRequiredLuminance = 0.0833f + }, + + // Quality + new FxaaQualitySettings + { + subpixelAliasingRemovalAmount = 1f, + edgeDetectionThreshold = 0.125f, + minimumRequiredLuminance = 0.0625f + }, + + // ExtremeQuality + new FxaaQualitySettings + { + subpixelAliasingRemovalAmount = 1f, + edgeDetectionThreshold = 0.063f, + minimumRequiredLuminance = 0.0312f + } + }; + } + + [Serializable] + public struct FxaaConsoleSettings + { + [Tooltip("The amount of spread applied to the sampling coordinates while sampling for subpixel information.")] + [Range(0.33f, 0.5f)] + public float subpixelSpreadAmount; + + [Tooltip("This value dictates how sharp the edges in the image are kept; a higher value implies sharper edges.")] + [Range(2f, 8f)] + public float edgeSharpnessAmount; + + [Tooltip("The minimum amount of local contrast required to qualify a region as containing an edge.")] + [Range(0.125f, 0.25f)] + public float edgeDetectionThreshold; + + [Tooltip("Local contrast adaptation value to disallow the algorithm from executing on the darker regions.")] + [Range(0.04f, 0.06f)] + public float minimumRequiredLuminance; + + public static FxaaConsoleSettings[] presets = + { + // ExtremePerformance + new FxaaConsoleSettings + { + subpixelSpreadAmount = 0.33f, + edgeSharpnessAmount = 8f, + edgeDetectionThreshold = 0.25f, + minimumRequiredLuminance = 0.06f + }, + + // Performance + new FxaaConsoleSettings + { + subpixelSpreadAmount = 0.33f, + edgeSharpnessAmount = 8f, + edgeDetectionThreshold = 0.125f, + minimumRequiredLuminance = 0.06f + }, + + // Default + new FxaaConsoleSettings + { + subpixelSpreadAmount = 0.5f, + edgeSharpnessAmount = 8f, + edgeDetectionThreshold = 0.125f, + minimumRequiredLuminance = 0.05f + }, + + // Quality + new FxaaConsoleSettings + { + subpixelSpreadAmount = 0.5f, + edgeSharpnessAmount = 4f, + edgeDetectionThreshold = 0.125f, + minimumRequiredLuminance = 0.04f + }, + + // ExtremeQuality + new FxaaConsoleSettings + { + subpixelSpreadAmount = 0.5f, + edgeSharpnessAmount = 2f, + edgeDetectionThreshold = 0.125f, + minimumRequiredLuminance = 0.04f + } + }; + } + + [Serializable] + public struct FxaaSettings + { + public FxaaPreset preset; + + public static FxaaSettings defaultSettings + { + get + { + return new FxaaSettings + { + preset = FxaaPreset.Default + }; + } + } + } + #endregion + + #region TAA Settings + [Serializable] + public struct TaaSettings + { + [Tooltip("The diameter (in texels) inside which jitter samples are spread. Smaller values result in crisper but more aliased output, while larger values result in more stable but blurrier output.")] + [Range(0.1f, 1f)] + public float jitterSpread; + + [Tooltip("Controls the amount of sharpening applied to the color buffer.")] + [Range(0f, 3f)] + public float sharpen; + + [Tooltip("The blend coefficient for a stationary fragment. Controls the percentage of history sample blended into the final color.")] + [Range(0f, 0.99f)] + public float stationaryBlending; + + [Tooltip("The blend coefficient for a fragment with significant motion. Controls the percentage of history sample blended into the final color.")] + [Range(0f, 0.99f)] + public float motionBlending; + + public static TaaSettings defaultSettings + { + get + { + return new TaaSettings + { + jitterSpread = 0.75f, + sharpen = 0.3f, + stationaryBlending = 0.95f, + motionBlending = 0.85f + }; + } + } + } + #endregion + + [Serializable] + public struct Settings + { + public Method method; + public FxaaSettings fxaaSettings; + public TaaSettings taaSettings; + + public static Settings defaultSettings + { + get + { + return new Settings + { + method = Method.Fxaa, + fxaaSettings = FxaaSettings.defaultSettings, + taaSettings = TaaSettings.defaultSettings + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs.meta b/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs.meta new file mode 100644 index 0000000..85ccaec --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/AntialiasingModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cb9a239ec5f20ca4cb5d0391441588de +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/BloomModel.cs b/Assets/PostProcessing/Runtime/Models/BloomModel.cs new file mode 100644 index 0000000..bddae5e --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/BloomModel.cs @@ -0,0 +1,102 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class BloomModel : PostProcessingModel + { + [Serializable] + public struct BloomSettings + { + [Min(0f), Tooltip("Strength of the bloom filter.")] + public float intensity; + + [Min(0f), Tooltip("Filters out pixels under this level of brightness.")] + public float threshold; + + public float thresholdLinear + { + set { threshold = Mathf.LinearToGammaSpace(value); } + get { return Mathf.GammaToLinearSpace(threshold); } + } + + [Range(0f, 1f), Tooltip("Makes transition between under/over-threshold gradual (0 = hard threshold, 1 = soft threshold).")] + public float softKnee; + + [Range(1f, 7f), Tooltip("Changes extent of veiling effects in a screen resolution-independent fashion.")] + public float radius; + + [Tooltip("Reduces flashing noise with an additional filter.")] + public bool antiFlicker; + + public static BloomSettings defaultSettings + { + get + { + return new BloomSettings + { + intensity = 0.5f, + threshold = 1.1f, + softKnee = 0.5f, + radius = 4f, + antiFlicker = false, + }; + } + } + } + + [Serializable] + public struct LensDirtSettings + { + [Tooltip("Dirtiness texture to add smudges or dust to the lens.")] + public Texture texture; + + [Min(0f), Tooltip("Amount of lens dirtiness.")] + public float intensity; + + public static LensDirtSettings defaultSettings + { + get + { + return new LensDirtSettings + { + texture = null, + intensity = 3f + }; + } + } + } + + [Serializable] + public struct Settings + { + public BloomSettings bloom; + public LensDirtSettings lensDirt; + + public static Settings defaultSettings + { + get + { + return new Settings + { + bloom = BloomSettings.defaultSettings, + lensDirt = LensDirtSettings.defaultSettings + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/BloomModel.cs.meta b/Assets/PostProcessing/Runtime/Models/BloomModel.cs.meta new file mode 100644 index 0000000..4f60ccd --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/BloomModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e215a6ec29d100f489c186f289526f06 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs b/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs new file mode 100644 index 0000000..473fdb8 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs @@ -0,0 +1,133 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class BuiltinDebugViewsModel : PostProcessingModel + { + [Serializable] + public struct DepthSettings + { + [Range(0f, 1f), Tooltip("Scales the camera far plane before displaying the depth map.")] + public float scale; + + public static DepthSettings defaultSettings + { + get + { + return new DepthSettings + { + scale = 1f + }; + } + } + } + + [Serializable] + public struct MotionVectorsSettings + { + [Range(0f, 1f), Tooltip("Opacity of the source render.")] + public float sourceOpacity; + + [Range(0f, 1f), Tooltip("Opacity of the per-pixel motion vector colors.")] + public float motionImageOpacity; + + [Min(0f), Tooltip("Because motion vectors are mainly very small vectors, you can use this setting to make them more visible.")] + public float motionImageAmplitude; + + [Range(0f, 1f), Tooltip("Opacity for the motion vector arrows.")] + public float motionVectorsOpacity; + + [Range(8, 64), Tooltip("The arrow density on screen.")] + public int motionVectorsResolution; + + [Min(0f), Tooltip("Tweaks the arrows length.")] + public float motionVectorsAmplitude; + + public static MotionVectorsSettings defaultSettings + { + get + { + return new MotionVectorsSettings + { + sourceOpacity = 1f, + + motionImageOpacity = 0f, + motionImageAmplitude = 16f, + + motionVectorsOpacity = 1f, + motionVectorsResolution = 24, + motionVectorsAmplitude = 64f + }; + } + } + } + + public enum Mode + { + None, + + Depth, + Normals, + MotionVectors, + + AmbientOcclusion, + EyeAdaptation, + FocusPlane, + PreGradingLog, + LogLut, + UserLut + } + + [Serializable] + public struct Settings + { + public Mode mode; + public DepthSettings depth; + public MotionVectorsSettings motionVectors; + + public static Settings defaultSettings + { + get + { + return new Settings + { + mode = Mode.None, + depth = DepthSettings.defaultSettings, + motionVectors = MotionVectorsSettings.defaultSettings + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public bool willInterrupt + { + get + { + return !IsModeActive(Mode.None) + && !IsModeActive(Mode.EyeAdaptation) + && !IsModeActive(Mode.PreGradingLog) + && !IsModeActive(Mode.LogLut) + && !IsModeActive(Mode.UserLut); + } + } + + public override void Reset() + { + settings = Settings.defaultSettings; + } + + public bool IsModeActive(Mode mode) + { + return m_Settings.mode == mode; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs.meta b/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs.meta new file mode 100644 index 0000000..986298f --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/BuiltinDebugViewsModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 33d6d1a4b7b3dec40819019a25605191 +timeCreated: 1467970684 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs b/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs new file mode 100644 index 0000000..2788167 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs @@ -0,0 +1,43 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class ChromaticAberrationModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + [Tooltip("Shift the hue of chromatic aberrations.")] + public Texture2D spectralTexture; + + [Range(0f, 1f), Tooltip("Amount of tangential distortion.")] + public float intensity; + + public static Settings defaultSettings + { + get + { + return new Settings + { + spectralTexture = null, + intensity = 0.1f + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs.meta b/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs.meta new file mode 100644 index 0000000..55c7401 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ChromaticAberrationModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8da01668697617e43879715e835a2367 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs b/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs new file mode 100644 index 0000000..7933f9f --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs @@ -0,0 +1,311 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class ColorGradingModel : PostProcessingModel + { + public enum Tonemapper + { + None, + + /// + /// ACES Filmic reference tonemapper. + /// + ACES, + + /// + /// Neutral tonemapper (based off John Hable's & Jim Hejl's work). + /// + Neutral + } + + [Serializable] + public struct TonemappingSettings + { + [Tooltip("Tonemapping algorithm to use at the end of the color grading process. Use \"Neutral\" if you need a customizable tonemapper or \"Filmic\" to give a standard filmic look to your scenes.")] + public Tonemapper tonemapper; + + // Neutral settings + [Range(-0.1f, 0.1f)] + public float neutralBlackIn; + + [Range(1f, 20f)] + public float neutralWhiteIn; + + [Range(-0.09f, 0.1f)] + public float neutralBlackOut; + + [Range(1f, 19f)] + public float neutralWhiteOut; + + [Range(0.1f, 20f)] + public float neutralWhiteLevel; + + [Range(1f, 10f)] + public float neutralWhiteClip; + + public static TonemappingSettings defaultSettings + { + get + { + return new TonemappingSettings + { + tonemapper = Tonemapper.Neutral, + + neutralBlackIn = 0.02f, + neutralWhiteIn = 10f, + neutralBlackOut = 0f, + neutralWhiteOut = 10f, + neutralWhiteLevel = 5.3f, + neutralWhiteClip = 10f + }; + } + } + } + + [Serializable] + public struct BasicSettings + { + [Tooltip("Adjusts the overall exposure of the scene in EV units. This is applied after HDR effect and right before tonemapping so it won't affect previous effects in the chain.")] + public float postExposure; + + [Range(-100f, 100f), Tooltip("Sets the white balance to a custom color temperature.")] + public float temperature; + + [Range(-100f, 100f), Tooltip("Sets the white balance to compensate for a green or magenta tint.")] + public float tint; + + [Range(-180f, 180f), Tooltip("Shift the hue of all colors.")] + public float hueShift; + + [Range(0f, 2f), Tooltip("Pushes the intensity of all colors.")] + public float saturation; + + [Range(0f, 2f), Tooltip("Expands or shrinks the overall range of tonal values.")] + public float contrast; + + public static BasicSettings defaultSettings + { + get + { + return new BasicSettings + { + postExposure = 0f, + + temperature = 0f, + tint = 0f, + + hueShift = 0f, + saturation = 1f, + contrast = 1f, + }; + } + } + } + + [Serializable] + public struct ChannelMixerSettings + { + public Vector3 red; + public Vector3 green; + public Vector3 blue; + + [HideInInspector] + public int currentEditingChannel; // Used only in the editor + + public static ChannelMixerSettings defaultSettings + { + get + { + return new ChannelMixerSettings + { + red = new Vector3(1f, 0f, 0f), + green = new Vector3(0f, 1f, 0f), + blue = new Vector3(0f, 0f, 1f), + currentEditingChannel = 0 + }; + } + } + } + + [Serializable] + public struct LogWheelsSettings + { + [Trackball("GetSlopeValue")] + public Color slope; + + [Trackball("GetPowerValue")] + public Color power; + + [Trackball("GetOffsetValue")] + public Color offset; + + public static LogWheelsSettings defaultSettings + { + get + { + return new LogWheelsSettings + { + slope = Color.clear, + power = Color.clear, + offset = Color.clear + }; + } + } + } + + [Serializable] + public struct LinearWheelsSettings + { + [Trackball("GetLiftValue")] + public Color lift; + + [Trackball("GetGammaValue")] + public Color gamma; + + [Trackball("GetGainValue")] + public Color gain; + + public static LinearWheelsSettings defaultSettings + { + get + { + return new LinearWheelsSettings + { + lift = Color.clear, + gamma = Color.clear, + gain = Color.clear + }; + } + } + } + + public enum ColorWheelMode + { + Linear, + Log + } + + [Serializable] + public struct ColorWheelsSettings + { + public ColorWheelMode mode; + + [TrackballGroup] + public LogWheelsSettings log; + + [TrackballGroup] + public LinearWheelsSettings linear; + + public static ColorWheelsSettings defaultSettings + { + get + { + return new ColorWheelsSettings + { + mode = ColorWheelMode.Log, + log = LogWheelsSettings.defaultSettings, + linear = LinearWheelsSettings.defaultSettings + }; + } + } + } + + [Serializable] + public struct CurvesSettings + { + public ColorGradingCurve master; + public ColorGradingCurve red; + public ColorGradingCurve green; + public ColorGradingCurve blue; + public ColorGradingCurve hueVShue; + public ColorGradingCurve hueVSsat; + public ColorGradingCurve satVSsat; + public ColorGradingCurve lumVSsat; + + // Used only in the editor + [HideInInspector] public int e_CurrentEditingCurve; + [HideInInspector] public bool e_CurveY; + [HideInInspector] public bool e_CurveR; + [HideInInspector] public bool e_CurveG; + [HideInInspector] public bool e_CurveB; + + public static CurvesSettings defaultSettings + { + get + { + return new CurvesSettings + { + master = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, false, new Vector2(0f, 1f)), + red = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, false, new Vector2(0f, 1f)), + green = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, false, new Vector2(0f, 1f)), + blue = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, false, new Vector2(0f, 1f)), + + hueVShue = new ColorGradingCurve(new AnimationCurve(), 0.5f, true, new Vector2(0f, 1f)), + hueVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, true, new Vector2(0f, 1f)), + satVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, false, new Vector2(0f, 1f)), + lumVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, false, new Vector2(0f, 1f)), + + e_CurrentEditingCurve = 0, + e_CurveY = true, + e_CurveR = false, + e_CurveG = false, + e_CurveB = false + }; + } + } + } + + [Serializable] + public struct Settings + { + public TonemappingSettings tonemapping; + public BasicSettings basic; + public ChannelMixerSettings channelMixer; + public ColorWheelsSettings colorWheels; + public CurvesSettings curves; + + public static Settings defaultSettings + { + get + { + return new Settings + { + tonemapping = TonemappingSettings.defaultSettings, + basic = BasicSettings.defaultSettings, + channelMixer = ChannelMixerSettings.defaultSettings, + colorWheels = ColorWheelsSettings.defaultSettings, + curves = CurvesSettings.defaultSettings + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set + { + m_Settings = value; + OnValidate(); + } + } + + public bool isDirty { get; internal set; } + public RenderTexture bakedLut { get; internal set; } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + OnValidate(); + } + + public override void OnValidate() + { + isDirty = true; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs.meta b/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs.meta new file mode 100644 index 0000000..dffabd0 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ColorGradingModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fe146bcdc1fb8ae4ab7dd803982d3489 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs b/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs new file mode 100644 index 0000000..bde86cb --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs @@ -0,0 +1,63 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class DepthOfFieldModel : PostProcessingModel + { + public enum KernelSize + { + Small, + Medium, + Large, + VeryLarge + } + + [Serializable] + public struct Settings + { + [Min(0.1f), Tooltip("Distance to the point of focus.")] + public float focusDistance; + + [Range(0.05f, 32f), Tooltip("Ratio of aperture (known as f-stop or f-number). The smaller the value is, the shallower the depth of field is.")] + public float aperture; + + [Range(1f, 300f), Tooltip("Distance between the lens and the film. The larger the value is, the shallower the depth of field is.")] + public float focalLength; + + [Tooltip("Calculate the focal length automatically from the field-of-view value set on the camera. Using this setting isn't recommended.")] + public bool useCameraFov; + + [Tooltip("Convolution kernel size of the bokeh filter, which determines the maximum radius of bokeh. It also affects the performance (the larger the kernel is, the longer the GPU time is required).")] + public KernelSize kernelSize; + + public static Settings defaultSettings + { + get + { + return new Settings + { + focusDistance = 10f, + aperture = 5.6f, + focalLength = 50f, + useCameraFov = false, + kernelSize = KernelSize.Medium + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs.meta b/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs.meta new file mode 100644 index 0000000..77a8911 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/DepthOfFieldModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2626b17c595c71e43811d654eb28d30d +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/DitheringModel.cs b/Assets/PostProcessing/Runtime/Models/DitheringModel.cs new file mode 100644 index 0000000..7fd6afb --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/DitheringModel.cs @@ -0,0 +1,30 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class DitheringModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + public static Settings defaultSettings + { + get { return new Settings(); } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/DitheringModel.cs.meta b/Assets/PostProcessing/Runtime/Models/DitheringModel.cs.meta new file mode 100644 index 0000000..a89cb14 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/DitheringModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 41209882cdbcf31429d2a457a2164801 +timeCreated: 1485179235 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs b/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs new file mode 100644 index 0000000..aa2020b --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs @@ -0,0 +1,88 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class EyeAdaptationModel : PostProcessingModel + { + public enum EyeAdaptationType + { + Progressive, + Fixed + } + + [Serializable] + public struct Settings + { + [Range(1f, 99f), Tooltip("Filters the dark part of the histogram when computing the average luminance to avoid very dark pixels from contributing to the auto exposure. Unit is in percent.")] + public float lowPercent; + + [Range(1f, 99f), Tooltip("Filters the bright part of the histogram when computing the average luminance to avoid very dark pixels from contributing to the auto exposure. Unit is in percent.")] + public float highPercent; + + [Tooltip("Minimum average luminance to consider for auto exposure (in EV).")] + public float minLuminance; + + [Tooltip("Maximum average luminance to consider for auto exposure (in EV).")] + public float maxLuminance; + + [Min(0f), Tooltip("Exposure bias. Use this to offset the global exposure of the scene.")] + public float keyValue; + + [Tooltip("Set this to true to let Unity handle the key value automatically based on average luminance.")] + public bool dynamicKeyValue; + + [Tooltip("Use \"Progressive\" if you want the auto exposure to be animated. Use \"Fixed\" otherwise.")] + public EyeAdaptationType adaptationType; + + [Min(0f), Tooltip("Adaptation speed from a dark to a light environment.")] + public float speedUp; + + [Min(0f), Tooltip("Adaptation speed from a light to a dark environment.")] + public float speedDown; + + [Range(-16, -1), Tooltip("Lower bound for the brightness range of the generated histogram (in EV). The bigger the spread between min & max, the lower the precision will be.")] + public int logMin; + + [Range(1, 16), Tooltip("Upper bound for the brightness range of the generated histogram (in EV). The bigger the spread between min & max, the lower the precision will be.")] + public int logMax; + + public static Settings defaultSettings + { + get + { + return new Settings + { + lowPercent = 45f, + highPercent = 95f, + + minLuminance = -5f, + maxLuminance = 1f, + keyValue = 0.25f, + dynamicKeyValue = true, + + adaptationType = EyeAdaptationType.Progressive, + speedUp = 2f, + speedDown = 1f, + + logMin = -8, + logMax = 4 + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs.meta b/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs.meta new file mode 100644 index 0000000..54680eb --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/EyeAdaptationModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: edf6d216ca4b60942a0c533c14f26d53 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/FogModel.cs b/Assets/PostProcessing/Runtime/Models/FogModel.cs new file mode 100644 index 0000000..81effcb --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/FogModel.cs @@ -0,0 +1,39 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class FogModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + [Tooltip("Should the fog affect the skybox?")] + public bool excludeSkybox; + + public static Settings defaultSettings + { + get + { + return new Settings + { + excludeSkybox = true + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/FogModel.cs.meta b/Assets/PostProcessing/Runtime/Models/FogModel.cs.meta new file mode 100644 index 0000000..6e73dd0 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/FogModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1e20e66aa2deb7943993c444137d9acd +timeCreated: 1487328709 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/GrainModel.cs b/Assets/PostProcessing/Runtime/Models/GrainModel.cs new file mode 100644 index 0000000..f2d1b56 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/GrainModel.cs @@ -0,0 +1,51 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class GrainModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + [Tooltip("Enable the use of colored grain.")] + public bool colored; + + [Range(0f, 1f), Tooltip("Grain strength. Higher means more visible grain.")] + public float intensity; + + [Range(0.3f, 3f), Tooltip("Grain particle size.")] + public float size; + + [Range(0f, 1f), Tooltip("Controls the noisiness response curve based on scene luminance. Lower values mean less noise in dark areas.")] + public float luminanceContribution; + + public static Settings defaultSettings + { + get + { + return new Settings + { + colored = true, + intensity = 0.5f, + size = 1f, + luminanceContribution = 0.8f + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/GrainModel.cs.meta b/Assets/PostProcessing/Runtime/Models/GrainModel.cs.meta new file mode 100644 index 0000000..0e63ba0 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/GrainModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f4fbcdb7f7a3c76489f32ffea74e6bb3 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs b/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs new file mode 100644 index 0000000..4fd3171 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs @@ -0,0 +1,47 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class MotionBlurModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + [Range(0f, 360f), Tooltip("The angle of rotary shutter. Larger values give longer exposure.")] + public float shutterAngle; + + [Range(4, 32), Tooltip("The amount of sample points, which affects quality and performances.")] + public int sampleCount; + + [Range(0f, 1f), Tooltip("The strength of multiple frame blending. The opacity of preceding frames are determined from this coefficient and time differences.")] + public float frameBlending; + + public static Settings defaultSettings + { + get + { + return new Settings + { + shutterAngle = 270f, + sampleCount = 10, + frameBlending = 0f + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs.meta b/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs.meta new file mode 100644 index 0000000..6f497f9 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/MotionBlurModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bb4df227c906dd342bd34767914d292c +timeCreated: 1468325392 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs b/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs new file mode 100644 index 0000000..b697cd2 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs @@ -0,0 +1,140 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class ScreenSpaceReflectionModel : PostProcessingModel + { + public enum SSRResolution + { + High = 0, + Low = 2 + } + + public enum SSRReflectionBlendType + { + PhysicallyBased, + Additive + } + + [Serializable] + public struct IntensitySettings + { + [Tooltip("Nonphysical multiplier for the SSR reflections. 1.0 is physically based.")] + [Range(0.0f, 2.0f)] + public float reflectionMultiplier; + + [Tooltip("How far away from the maxDistance to begin fading SSR.")] + [Range(0.0f, 1000.0f)] + public float fadeDistance; + + [Tooltip("Amplify Fresnel fade out. Increase if floor reflections look good close to the surface and bad farther 'under' the floor.")] + [Range(0.0f, 1.0f)] + public float fresnelFade; + + [Tooltip("Higher values correspond to a faster Fresnel fade as the reflection changes from the grazing angle.")] + [Range(0.1f, 10.0f)] + public float fresnelFadePower; + } + + [Serializable] + public struct ReflectionSettings + { + // When enabled, we just add our reflections on top of the existing ones. This is physically incorrect, but several + // popular demos and games have taken this approach, and it does hide some artifacts. + [Tooltip("How the reflections are blended into the render.")] + public SSRReflectionBlendType blendType; + + [Tooltip("Half resolution SSRR is much faster, but less accurate.")] + public SSRResolution reflectionQuality; + + [Tooltip("Maximum reflection distance in world units.")] + [Range(0.1f, 300.0f)] + public float maxDistance; + + /// REFLECTIONS + [Tooltip("Max raytracing length.")] + [Range(16, 1024)] + public int iterationCount; + + [Tooltip("Log base 2 of ray tracing coarse step size. Higher traces farther, lower gives better quality silhouettes.")] + [Range(1, 16)] + public int stepSize; + + [Tooltip("Typical thickness of columns, walls, furniture, and other objects that reflection rays might pass behind.")] + [Range(0.01f, 10.0f)] + public float widthModifier; + + [Tooltip("Blurriness of reflections.")] + [Range(0.1f, 8.0f)] + public float reflectionBlur; + + [Tooltip("Disable for a performance gain in scenes where most glossy objects are horizontal, like floors, water, and tables. Leave on for scenes with glossy vertical objects.")] + public bool reflectBackfaces; + } + + [Serializable] + public struct ScreenEdgeMask + { + [Tooltip("Higher = fade out SSRR near the edge of the screen so that reflections don't pop under camera motion.")] + [Range(0.0f, 1.0f)] + public float intensity; + } + + [Serializable] + public struct Settings + { + public ReflectionSettings reflection; + public IntensitySettings intensity; + public ScreenEdgeMask screenEdgeMask; + + public static Settings defaultSettings + { + get + { + return new Settings + { + reflection = new ReflectionSettings + { + blendType = SSRReflectionBlendType.PhysicallyBased, + reflectionQuality = SSRResolution.Low, + maxDistance = 100f, + iterationCount = 256, + stepSize = 3, + widthModifier = 0.5f, + reflectionBlur = 1f, + reflectBackfaces = false + }, + + intensity = new IntensitySettings + { + reflectionMultiplier = 1f, + fadeDistance = 100f, + + fresnelFade = 1f, + fresnelFadePower = 1f, + }, + + screenEdgeMask = new ScreenEdgeMask + { + intensity = 0.03f + } + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs.meta b/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs.meta new file mode 100644 index 0000000..b761a85 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/ScreenSpaceReflectionModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e841012229e57cd408a146561435e90d +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/UserLutModel.cs b/Assets/PostProcessing/Runtime/Models/UserLutModel.cs new file mode 100644 index 0000000..d0efc2d --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/UserLutModel.cs @@ -0,0 +1,43 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class UserLutModel : PostProcessingModel + { + [Serializable] + public struct Settings + { + [Tooltip("Custom lookup texture (strip format, e.g. 256x16).")] + public Texture2D lut; + + [Range(0f, 1f), Tooltip("Blending factor.")] + public float contribution; + + public static Settings defaultSettings + { + get + { + return new Settings + { + lut = null, + contribution = 1f + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/UserLutModel.cs.meta b/Assets/PostProcessing/Runtime/Models/UserLutModel.cs.meta new file mode 100644 index 0000000..a40ad00 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/UserLutModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3a7afd753a89c4140b80c855e15f69d6 +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Models/VignetteModel.cs b/Assets/PostProcessing/Runtime/Models/VignetteModel.cs new file mode 100644 index 0000000..33b082e --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/VignetteModel.cs @@ -0,0 +1,78 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public class VignetteModel : PostProcessingModel + { + public enum Mode + { + Classic, + Masked + } + + [Serializable] + public struct Settings + { + [Tooltip("Use the \"Classic\" mode for parametric controls. Use the \"Masked\" mode to use your own texture mask.")] + public Mode mode; + + [ColorUsage(false)] + [Tooltip("Vignette color. Use the alpha channel for transparency.")] + public Color color; + + [Tooltip("Sets the vignette center point (screen center is [0.5,0.5]).")] + public Vector2 center; + + [Range(0f, 1f), Tooltip("Amount of vignetting on screen.")] + public float intensity; + + [Range(0.01f, 1f), Tooltip("Smoothness of the vignette borders.")] + public float smoothness; + + [Range(0f, 1f), Tooltip("Lower values will make a square-ish vignette.")] + public float roundness; + + [Tooltip("A black and white mask to use as a vignette.")] + public Texture mask; + + [Range(0f, 1f), Tooltip("Mask opacity.")] + public float opacity; + + [Tooltip("Should the vignette be perfectly round or be dependent on the current aspect ratio?")] + public bool rounded; + + public static Settings defaultSettings + { + get + { + return new Settings + { + mode = Mode.Classic, + color = new Color(0f, 0f, 0f, 1f), + center = new Vector2(0.5f, 0.5f), + intensity = 0.45f, + smoothness = 0.2f, + roundness = 1f, + mask = null, + opacity = 1f, + rounded = false + }; + } + } + } + + [SerializeField] + Settings m_Settings = Settings.defaultSettings; + public Settings settings + { + get { return m_Settings; } + set { m_Settings = value; } + } + + public override void Reset() + { + m_Settings = Settings.defaultSettings; + } + } +} diff --git a/Assets/PostProcessing/Runtime/Models/VignetteModel.cs.meta b/Assets/PostProcessing/Runtime/Models/VignetteModel.cs.meta new file mode 100644 index 0000000..638aaa7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Models/VignetteModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d7aa967ba692363448f1b25d0728b9bd +timeCreated: 1467126855 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs b/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs new file mode 100644 index 0000000..6f292d2 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs @@ -0,0 +1,470 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + using DebugMode = BuiltinDebugViewsModel.Mode; + +#if UNITY_5_4_OR_NEWER + [ImageEffectAllowedInSceneView] +#endif + [RequireComponent(typeof(Camera)), DisallowMultipleComponent, ExecuteInEditMode] + [AddComponentMenu("Effects/Post-Processing Behaviour", -1)] + public class PostProcessingBehaviour : MonoBehaviour + { + // Inspector fields + public PostProcessingProfile profile; + + public Func jitteredMatrixFunc; + + // Internal helpers + Dictionary> m_CommandBuffers; + List m_Components; + Dictionary m_ComponentStates; + + MaterialFactory m_MaterialFactory; + RenderTextureFactory m_RenderTextureFactory; + PostProcessingContext m_Context; + Camera m_Camera; + PostProcessingProfile m_PreviousProfile; + + bool m_RenderingInSceneView = false; + + // Effect components + BuiltinDebugViewsComponent m_DebugViews; + AmbientOcclusionComponent m_AmbientOcclusion; + ScreenSpaceReflectionComponent m_ScreenSpaceReflection; + FogComponent m_FogComponent; + MotionBlurComponent m_MotionBlur; + TaaComponent m_Taa; + EyeAdaptationComponent m_EyeAdaptation; + DepthOfFieldComponent m_DepthOfField; + BloomComponent m_Bloom; + ChromaticAberrationComponent m_ChromaticAberration; + ColorGradingComponent m_ColorGrading; + UserLutComponent m_UserLut; + GrainComponent m_Grain; + VignetteComponent m_Vignette; + DitheringComponent m_Dithering; + FxaaComponent m_Fxaa; + + void OnEnable() + { + m_CommandBuffers = new Dictionary>(); + m_MaterialFactory = new MaterialFactory(); + m_RenderTextureFactory = new RenderTextureFactory(); + m_Context = new PostProcessingContext(); + + // Keep a list of all post-fx for automation purposes + m_Components = new List(); + + // Component list + m_DebugViews = AddComponent(new BuiltinDebugViewsComponent()); + m_AmbientOcclusion = AddComponent(new AmbientOcclusionComponent()); + m_ScreenSpaceReflection = AddComponent(new ScreenSpaceReflectionComponent()); + m_FogComponent = AddComponent(new FogComponent()); + m_MotionBlur = AddComponent(new MotionBlurComponent()); + m_Taa = AddComponent(new TaaComponent()); + m_EyeAdaptation = AddComponent(new EyeAdaptationComponent()); + m_DepthOfField = AddComponent(new DepthOfFieldComponent()); + m_Bloom = AddComponent(new BloomComponent()); + m_ChromaticAberration = AddComponent(new ChromaticAberrationComponent()); + m_ColorGrading = AddComponent(new ColorGradingComponent()); + m_UserLut = AddComponent(new UserLutComponent()); + m_Grain = AddComponent(new GrainComponent()); + m_Vignette = AddComponent(new VignetteComponent()); + m_Dithering = AddComponent(new DitheringComponent()); + m_Fxaa = AddComponent(new FxaaComponent()); + + // Prepare state observers + m_ComponentStates = new Dictionary(); + + foreach (var component in m_Components) + m_ComponentStates.Add(component, false); + + useGUILayout = false; + } + + void OnPreCull() + { + // All the per-frame initialization logic has to be done in OnPreCull instead of Update + // because [ImageEffectAllowedInSceneView] doesn't trigger Update events... + + m_Camera = GetComponent(); + + if (profile == null || m_Camera == null) + return; + +#if UNITY_EDITOR + // Track the scene view camera to disable some effects we don't want to see in the + // scene view + // Currently disabled effects : + // - Temporal Antialiasing + // - Depth of Field + // - Motion blur + m_RenderingInSceneView = UnityEditor.SceneView.currentDrawingSceneView != null + && UnityEditor.SceneView.currentDrawingSceneView.camera == m_Camera; +#endif + + // Prepare context + var context = m_Context.Reset(); + context.profile = profile; + context.renderTextureFactory = m_RenderTextureFactory; + context.materialFactory = m_MaterialFactory; + context.camera = m_Camera; + + // Prepare components + m_DebugViews.Init(context, profile.debugViews); + m_AmbientOcclusion.Init(context, profile.ambientOcclusion); + m_ScreenSpaceReflection.Init(context, profile.screenSpaceReflection); + m_FogComponent.Init(context, profile.fog); + m_MotionBlur.Init(context, profile.motionBlur); + m_Taa.Init(context, profile.antialiasing); + m_EyeAdaptation.Init(context, profile.eyeAdaptation); + m_DepthOfField.Init(context, profile.depthOfField); + m_Bloom.Init(context, profile.bloom); + m_ChromaticAberration.Init(context, profile.chromaticAberration); + m_ColorGrading.Init(context, profile.colorGrading); + m_UserLut.Init(context, profile.userLut); + m_Grain.Init(context, profile.grain); + m_Vignette.Init(context, profile.vignette); + m_Dithering.Init(context, profile.dithering); + m_Fxaa.Init(context, profile.antialiasing); + + // Handles profile change and 'enable' state observers + if (m_PreviousProfile != profile) + { + DisableComponents(); + m_PreviousProfile = profile; + } + + CheckObservers(); + + // Find out which camera flags are needed before rendering begins + // Note that motion vectors will only be available one frame after being enabled + var flags = context.camera.depthTextureMode; + foreach (var component in m_Components) + { + if (component.active) + flags |= component.GetCameraFlags(); + } + + context.camera.depthTextureMode = flags; + + // Temporal antialiasing jittering, needs to happen before culling + if (!m_RenderingInSceneView && m_Taa.active && !profile.debugViews.willInterrupt) + m_Taa.SetProjectionMatrix(jitteredMatrixFunc); + } + + void OnPreRender() + { + if (profile == null) + return; + + // Command buffer-based effects should be set-up here + TryExecuteCommandBuffer(m_DebugViews); + TryExecuteCommandBuffer(m_AmbientOcclusion); + TryExecuteCommandBuffer(m_ScreenSpaceReflection); + TryExecuteCommandBuffer(m_FogComponent); + + if (!m_RenderingInSceneView) + TryExecuteCommandBuffer(m_MotionBlur); + } + + void OnPostRender() + { + if (profile == null || m_Camera == null) + return; + + if (!m_RenderingInSceneView && m_Taa.active && !profile.debugViews.willInterrupt) + m_Context.camera.ResetProjectionMatrix(); + } + + // Classic render target pipeline for RT-based effects + void OnRenderImage(RenderTexture source, RenderTexture destination) + { + if (profile == null || m_Camera == null) + { + Graphics.Blit(source, destination); + return; + } + + // Uber shader setup + bool uberActive = false; + bool fxaaActive = m_Fxaa.active; + bool taaActive = m_Taa.active && !m_RenderingInSceneView; + bool dofActive = m_DepthOfField.active && !m_RenderingInSceneView; + + var uberMaterial = m_MaterialFactory.Get("Hidden/Post FX/Uber Shader"); + uberMaterial.shaderKeywords = null; + + var src = source; + var dst = destination; + + if (taaActive) + { + var tempRT = m_RenderTextureFactory.Get(src); + m_Taa.Render(src, tempRT); + src = tempRT; + } + +#if UNITY_EDITOR + // Render to a dedicated target when monitors are enabled so they can show information + // about the final render. + // At runtime the output will always be the backbuffer or whatever render target is + // currently set on the camera. + if (profile.monitors.onFrameEndEditorOnly != null) + dst = m_RenderTextureFactory.Get(src); +#endif + + Texture autoExposure = GraphicsUtils.whiteTexture; + if (m_EyeAdaptation.active) + { + uberActive = true; + autoExposure = m_EyeAdaptation.Prepare(src, uberMaterial); + } + + uberMaterial.SetTexture("_AutoExposure", autoExposure); + + if (dofActive) + { + uberActive = true; + m_DepthOfField.Prepare(src, uberMaterial, taaActive, m_Taa.jitterVector, m_Taa.model.settings.taaSettings.motionBlending); + } + + if (m_Bloom.active) + { + uberActive = true; + m_Bloom.Prepare(src, uberMaterial, autoExposure); + } + + uberActive |= TryPrepareUberImageEffect(m_ChromaticAberration, uberMaterial); + uberActive |= TryPrepareUberImageEffect(m_ColorGrading, uberMaterial); + uberActive |= TryPrepareUberImageEffect(m_Vignette, uberMaterial); + uberActive |= TryPrepareUberImageEffect(m_UserLut, uberMaterial); + + var fxaaMaterial = fxaaActive + ? m_MaterialFactory.Get("Hidden/Post FX/FXAA") + : null; + + if (fxaaActive) + { + fxaaMaterial.shaderKeywords = null; + TryPrepareUberImageEffect(m_Grain, fxaaMaterial); + TryPrepareUberImageEffect(m_Dithering, fxaaMaterial); + + if (uberActive) + { + var output = m_RenderTextureFactory.Get(src); + Graphics.Blit(src, output, uberMaterial, 0); + src = output; + } + + m_Fxaa.Render(src, dst); + } + else + { + uberActive |= TryPrepareUberImageEffect(m_Grain, uberMaterial); + uberActive |= TryPrepareUberImageEffect(m_Dithering, uberMaterial); + + if (uberActive) + { + if (!GraphicsUtils.isLinearColorSpace) + uberMaterial.EnableKeyword("UNITY_COLORSPACE_GAMMA"); + + Graphics.Blit(src, dst, uberMaterial, 0); + } + } + + if (!uberActive && !fxaaActive) + Graphics.Blit(src, dst); + +#if UNITY_EDITOR + if (profile.monitors.onFrameEndEditorOnly != null) + { + Graphics.Blit(dst, destination); + + var oldRt = RenderTexture.active; + profile.monitors.onFrameEndEditorOnly(dst); + RenderTexture.active = oldRt; + } +#endif + + m_RenderTextureFactory.ReleaseAll(); + } + + void OnGUI() + { + if (Event.current.type != EventType.Repaint) + return; + + if (profile == null || m_Camera == null) + return; + + if (m_EyeAdaptation.active && profile.debugViews.IsModeActive(DebugMode.EyeAdaptation)) + m_EyeAdaptation.OnGUI(); + else if (m_ColorGrading.active && profile.debugViews.IsModeActive(DebugMode.LogLut)) + m_ColorGrading.OnGUI(); + else if (m_UserLut.active && profile.debugViews.IsModeActive(DebugMode.UserLut)) + m_UserLut.OnGUI(); + } + + void OnDisable() + { + // Clear command buffers + foreach (var cb in m_CommandBuffers.Values) + { + m_Camera.RemoveCommandBuffer(cb.Key, cb.Value); + cb.Value.Dispose(); + } + + m_CommandBuffers.Clear(); + + // Clear components + if (profile != null) + DisableComponents(); + + m_Components.Clear(); + + // Factories + m_MaterialFactory.Dispose(); + m_RenderTextureFactory.Dispose(); + GraphicsUtils.Dispose(); + } + + public void ResetTemporalEffects() + { + m_Taa.ResetHistory(); + m_MotionBlur.ResetHistory(); + m_EyeAdaptation.ResetHistory(); + } + + #region State management + + List m_ComponentsToEnable = new List(); + List m_ComponentsToDisable = new List(); + + void CheckObservers() + { + foreach (var cs in m_ComponentStates) + { + var component = cs.Key; + var state = component.GetModel().enabled; + + if (state != cs.Value) + { + if (state) m_ComponentsToEnable.Add(component); + else m_ComponentsToDisable.Add(component); + } + } + + for (int i = 0; i < m_ComponentsToDisable.Count; i++) + { + var c = m_ComponentsToDisable[i]; + m_ComponentStates[c] = false; + c.OnDisable(); + } + + for (int i = 0; i < m_ComponentsToEnable.Count; i++) + { + var c = m_ComponentsToEnable[i]; + m_ComponentStates[c] = true; + c.OnEnable(); + } + + m_ComponentsToDisable.Clear(); + m_ComponentsToEnable.Clear(); + } + + void DisableComponents() + { + foreach (var component in m_Components) + { + var model = component.GetModel(); + if (model != null && model.enabled) + component.OnDisable(); + } + } + + #endregion + + #region Command buffer handling & rendering helpers + // Placeholders before the upcoming Scriptable Render Loop as command buffers will be + // executed on the go so we won't need of all that stuff + CommandBuffer AddCommandBuffer(CameraEvent evt, string name) + where T : PostProcessingModel + { + var cb = new CommandBuffer { name = name }; + var kvp = new KeyValuePair(evt, cb); + m_CommandBuffers.Add(typeof(T), kvp); + m_Camera.AddCommandBuffer(evt, kvp.Value); + return kvp.Value; + } + + void RemoveCommandBuffer() + where T : PostProcessingModel + { + KeyValuePair kvp; + var type = typeof(T); + + if (!m_CommandBuffers.TryGetValue(type, out kvp)) + return; + + m_Camera.RemoveCommandBuffer(kvp.Key, kvp.Value); + m_CommandBuffers.Remove(type); + kvp.Value.Dispose(); + } + + CommandBuffer GetCommandBuffer(CameraEvent evt, string name) + where T : PostProcessingModel + { + CommandBuffer cb; + KeyValuePair kvp; + + if (!m_CommandBuffers.TryGetValue(typeof(T), out kvp)) + { + cb = AddCommandBuffer(evt, name); + } + else if (kvp.Key != evt) + { + RemoveCommandBuffer(); + cb = AddCommandBuffer(evt, name); + } + else cb = kvp.Value; + + return cb; + } + + void TryExecuteCommandBuffer(PostProcessingComponentCommandBuffer component) + where T : PostProcessingModel + { + if (component.active) + { + var cb = GetCommandBuffer(component.GetCameraEvent(), component.GetName()); + cb.Clear(); + component.PopulateCommandBuffer(cb); + } + else RemoveCommandBuffer(); + } + + bool TryPrepareUberImageEffect(PostProcessingComponentRenderTexture component, Material material) + where T : PostProcessingModel + { + if (!component.active) + return false; + + component.Prepare(material); + return true; + } + + T AddComponent(T component) + where T : PostProcessingComponentBase + { + m_Components.Add(component); + return component; + } + + #endregion + } +} diff --git a/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs.meta b/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs.meta new file mode 100644 index 0000000..d564375 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ff26db721962cdf4a8edcdfa9a767d2a +timeCreated: 1459757354 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/PostProcessingComponent.cs b/Assets/PostProcessing/Runtime/PostProcessingComponent.cs new file mode 100644 index 0000000..c3c0d7d --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingComponent.cs @@ -0,0 +1,58 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.PostProcessing +{ + public abstract class PostProcessingComponentBase + { + public PostProcessingContext context; + + public virtual DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.None; + } + + public abstract bool active { get; } + + public virtual void OnEnable() + {} + + public virtual void OnDisable() + {} + + public abstract PostProcessingModel GetModel(); + } + + public abstract class PostProcessingComponent : PostProcessingComponentBase + where T : PostProcessingModel + { + public T model { get; internal set; } + + public virtual void Init(PostProcessingContext pcontext, T pmodel) + { + context = pcontext; + model = pmodel; + } + + public override PostProcessingModel GetModel() + { + return model; + } + } + + public abstract class PostProcessingComponentCommandBuffer : PostProcessingComponent + where T : PostProcessingModel + { + public abstract CameraEvent GetCameraEvent(); + + public abstract string GetName(); + + public abstract void PopulateCommandBuffer(CommandBuffer cb); + } + + public abstract class PostProcessingComponentRenderTexture : PostProcessingComponent + where T : PostProcessingModel + { + public virtual void Prepare(Material material) + {} + } +} diff --git a/Assets/PostProcessing/Runtime/PostProcessingComponent.cs.meta b/Assets/PostProcessing/Runtime/PostProcessingComponent.cs.meta new file mode 100644 index 0000000..fafa500 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ef3277e9c14f78546a1ecaab0d293b77 +timeCreated: 1473009349 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/PostProcessingContext.cs b/Assets/PostProcessing/Runtime/PostProcessingContext.cs new file mode 100644 index 0000000..dba51ed --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingContext.cs @@ -0,0 +1,60 @@ +namespace UnityEngine.PostProcessing +{ + public class PostProcessingContext + { + public PostProcessingProfile profile; + public Camera camera; + + public MaterialFactory materialFactory; + public RenderTextureFactory renderTextureFactory; + + public bool interrupted { get; private set; } + + public void Interrupt() + { + interrupted = true; + } + + public PostProcessingContext Reset() + { + profile = null; + camera = null; + materialFactory = null; + renderTextureFactory = null; + interrupted = false; + return this; + } + + #region Helpers + public bool isGBufferAvailable + { + get { return camera.actualRenderingPath == RenderingPath.DeferredShading; } + } + + public bool isHdr + { + // No UNITY_5_6_OR_NEWER defined in early betas of 5.6 +#if UNITY_5_6 || UNITY_5_6_OR_NEWER + get { return camera.allowHDR; } +#else + get { return camera.hdr; } +#endif + } + + public int width + { + get { return camera.pixelWidth; } + } + + public int height + { + get { return camera.pixelHeight; } + } + + public Rect viewport + { + get { return camera.rect; } // Normalized coordinates + } + #endregion + } +} diff --git a/Assets/PostProcessing/Runtime/PostProcessingContext.cs.meta b/Assets/PostProcessing/Runtime/PostProcessingContext.cs.meta new file mode 100644 index 0000000..8feba14 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingContext.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 63da4b6536f11834fa026e327087bd7b +timeCreated: 1467630780 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/PostProcessingModel.cs b/Assets/PostProcessing/Runtime/PostProcessingModel.cs new file mode 100644 index 0000000..69f5095 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingModel.cs @@ -0,0 +1,27 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + [Serializable] + public abstract class PostProcessingModel + { + [SerializeField, GetSet("enabled")] + bool m_Enabled; + public bool enabled + { + get { return m_Enabled; } + set + { + m_Enabled = value; + + if (value) + OnValidate(); + } + } + + public abstract void Reset(); + + public virtual void OnValidate() + {} + } +} diff --git a/Assets/PostProcessing/Runtime/PostProcessingModel.cs.meta b/Assets/PostProcessing/Runtime/PostProcessingModel.cs.meta new file mode 100644 index 0000000..6dd4507 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 28413153a26e53342baf1a7b2c3711c3 +timeCreated: 1466586474 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/PostProcessingProfile.cs b/Assets/PostProcessing/Runtime/PostProcessingProfile.cs new file mode 100644 index 0000000..2628a58 --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingProfile.cs @@ -0,0 +1,68 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + public class PostProcessingProfile : ScriptableObject + { + #pragma warning disable 0169 // "field x is never used" + + public BuiltinDebugViewsModel debugViews = new BuiltinDebugViewsModel(); + public FogModel fog = new FogModel(); + public AntialiasingModel antialiasing = new AntialiasingModel(); + public AmbientOcclusionModel ambientOcclusion = new AmbientOcclusionModel(); + public ScreenSpaceReflectionModel screenSpaceReflection = new ScreenSpaceReflectionModel(); + public DepthOfFieldModel depthOfField = new DepthOfFieldModel(); + public MotionBlurModel motionBlur = new MotionBlurModel(); + public EyeAdaptationModel eyeAdaptation = new EyeAdaptationModel(); + public BloomModel bloom = new BloomModel(); + public ColorGradingModel colorGrading = new ColorGradingModel(); + public UserLutModel userLut = new UserLutModel(); + public ChromaticAberrationModel chromaticAberration = new ChromaticAberrationModel(); + public GrainModel grain = new GrainModel(); + public VignetteModel vignette = new VignetteModel(); + public DitheringModel dithering = new DitheringModel(); + +#if UNITY_EDITOR + // Monitor settings + [Serializable] + public class MonitorSettings + { + // Callback used in the editor to grab the rendered frame and sent it to monitors + public Action onFrameEndEditorOnly; + + // Global + public int currentMonitorID = 0; + public bool refreshOnPlay = false; + + // Histogram + public enum HistogramMode + { + Red = 0, + Green = 1, + Blue = 2, + Luminance = 3, + RGBMerged, + RGBSplit + } + + public HistogramMode histogramMode = HistogramMode.Luminance; + + // Waveform + public float waveformExposure = 0.12f; + public bool waveformY = false; + public bool waveformR = true; + public bool waveformG = true; + public bool waveformB = true; + + // Parade + public float paradeExposure = 0.12f; + + // Vectorscope + public float vectorscopeExposure = 0.12f; + public bool vectorscopeShowBackground = true; + } + + public MonitorSettings monitors = new MonitorSettings(); +#endif + } +} diff --git a/Assets/PostProcessing/Runtime/PostProcessingProfile.cs.meta b/Assets/PostProcessing/Runtime/PostProcessingProfile.cs.meta new file mode 100644 index 0000000..277d7cf --- /dev/null +++ b/Assets/PostProcessing/Runtime/PostProcessingProfile.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8a3bdb2cd68f901469e7cc149151eb49 +timeCreated: 1459756301 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Utils.meta b/Assets/PostProcessing/Runtime/Utils.meta new file mode 100644 index 0000000..5b617b7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 18fb6a6b698945843a16c2d0111a7af2 +folderAsset: yes +timeCreated: 1459945070 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs b/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs new file mode 100644 index 0000000..da75978 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs @@ -0,0 +1,64 @@ +using System; + +namespace UnityEngine.PostProcessing +{ + // Small wrapper on top of AnimationCurve to handle zero-key curves and keyframe looping + + [Serializable] + public sealed class ColorGradingCurve + { + public AnimationCurve curve; + + [SerializeField] + bool m_Loop; + + [SerializeField] + float m_ZeroValue; + + [SerializeField] + float m_Range; + + AnimationCurve m_InternalLoopingCurve; + + public ColorGradingCurve(AnimationCurve curve, float zeroValue, bool loop, Vector2 bounds) + { + this.curve = curve; + m_ZeroValue = zeroValue; + m_Loop = loop; + m_Range = bounds.magnitude; + } + + public void Cache() + { + if (!m_Loop) + return; + + var length = curve.length; + + if (length < 2) + return; + + if (m_InternalLoopingCurve == null) + m_InternalLoopingCurve = new AnimationCurve(); + + var prev = curve[length - 1]; + prev.time -= m_Range; + var next = curve[0]; + next.time += m_Range; + m_InternalLoopingCurve.keys = curve.keys; + m_InternalLoopingCurve.AddKey(prev); + m_InternalLoopingCurve.AddKey(next); + } + + public float Evaluate(float t) + { + if (curve.length == 0) + return m_ZeroValue; + + if (!m_Loop || curve.length == 1) + return curve.Evaluate(t); + + return m_InternalLoopingCurve.Evaluate(t); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs.meta b/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs.meta new file mode 100644 index 0000000..1420d70 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/ColorGradingCurve.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1bb6f2275f7eff940b6f0d72681e7877 +timeCreated: 1473847739 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs b/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs new file mode 100644 index 0000000..5e428c0 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs @@ -0,0 +1,144 @@ +namespace UnityEngine.PostProcessing +{ + using UnityObject = Object; + + public static class GraphicsUtils + { + public static bool isLinearColorSpace + { + get { return QualitySettings.activeColorSpace == ColorSpace.Linear; } + } + + public static bool supportsDX11 + { +#if UNITY_WEBGL + get { return false; } +#else + get { return SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders; } +#endif + } + + static Texture2D s_WhiteTexture; + public static Texture2D whiteTexture + { + get + { + if (s_WhiteTexture != null) + return s_WhiteTexture; + + s_WhiteTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false); + s_WhiteTexture.SetPixel(0, 0, new Color(1f, 1f, 1f, 1f)); + s_WhiteTexture.Apply(); + + return s_WhiteTexture; + } + } + + static Mesh s_Quad; + public static Mesh quad + { + get + { + if (s_Quad != null) + return s_Quad; + + var vertices = new[] + { + new Vector3(-1f, -1f, 0f), + new Vector3( 1f, 1f, 0f), + new Vector3( 1f, -1f, 0f), + new Vector3(-1f, 1f, 0f) + }; + + var uvs = new[] + { + new Vector2(0f, 0f), + new Vector2(1f, 1f), + new Vector2(1f, 0f), + new Vector2(0f, 1f) + }; + + var indices = new[] { 0, 1, 2, 1, 0, 3 }; + + s_Quad = new Mesh + { + vertices = vertices, + uv = uvs, + triangles = indices + }; + s_Quad.RecalculateNormals(); + s_Quad.RecalculateBounds(); + + return s_Quad; + } + } + + // Useful when rendering to MRT + public static void Blit(Material material, int pass) + { + GL.PushMatrix(); + { + GL.LoadOrtho(); + + material.SetPass(pass); + + GL.Begin(GL.TRIANGLE_STRIP); + { + GL.TexCoord2(0f, 0f); GL.Vertex3(0f, 0f, 0.1f); + GL.TexCoord2(1f, 0f); GL.Vertex3(1f, 0f, 0.1f); + GL.TexCoord2(0f, 1f); GL.Vertex3(0f, 1f, 0.1f); + GL.TexCoord2(1f, 1f); GL.Vertex3(1f, 1f, 0.1f); + } + GL.End(); + } + GL.PopMatrix(); + } + + public static void ClearAndBlit(Texture source, RenderTexture destination, Material material, int pass, bool clearColor = true, bool clearDepth = false) + { + var oldRT = RenderTexture.active; + RenderTexture.active = destination; + + GL.Clear(false, clearColor, Color.clear); + GL.PushMatrix(); + { + GL.LoadOrtho(); + + material.SetTexture("_MainTex", source); + material.SetPass(pass); + + GL.Begin(GL.TRIANGLE_STRIP); + { + GL.TexCoord2(0f, 0f); GL.Vertex3(0f, 0f, 0.1f); + GL.TexCoord2(1f, 0f); GL.Vertex3(1f, 0f, 0.1f); + GL.TexCoord2(0f, 1f); GL.Vertex3(0f, 1f, 0.1f); + GL.TexCoord2(1f, 1f); GL.Vertex3(1f, 1f, 0.1f); + } + GL.End(); + } + GL.PopMatrix(); + + RenderTexture.active = oldRT; + } + + public static void Destroy(UnityObject obj) + { + if (obj != null) + { +#if UNITY_EDITOR + if (Application.isPlaying) + UnityObject.Destroy(obj); + else + UnityObject.DestroyImmediate(obj); +#else + UnityObject.Destroy(obj); +#endif + } + } + + public static void Dispose() + { + Destroy(s_Quad); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs.meta b/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs.meta new file mode 100644 index 0000000..74042f5 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/GraphicsUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f40f0a1acf6ce2f419f2b71c667e8973 +timeCreated: 1467635425 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs b/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs new file mode 100644 index 0000000..fa5eee7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.PostProcessing +{ + using UnityObject = Object; + + public sealed class MaterialFactory : IDisposable + { + Dictionary m_Materials; + + public MaterialFactory() + { + m_Materials = new Dictionary(); + } + + public Material Get(string shaderName) + { + Material material; + + if (!m_Materials.TryGetValue(shaderName, out material)) + { + var shader = Shader.Find(shaderName); + + if (shader == null) + throw new ArgumentException(string.Format("Shader not found ({0})", shaderName)); + + material = new Material(shader) + { + name = string.Format("PostFX - {0}", shaderName.Substring(shaderName.LastIndexOf("/") + 1)), + hideFlags = HideFlags.DontSave + }; + + m_Materials.Add(shaderName, material); + } + + return material; + } + + public void Dispose() + { + var enumerator = m_Materials.GetEnumerator(); + while (enumerator.MoveNext()) + { + var material = enumerator.Current.Value; + GraphicsUtils.Destroy(material); + } + + m_Materials.Clear(); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs.meta b/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs.meta new file mode 100644 index 0000000..27b6c20 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/MaterialFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 594fad000c373f746864717c588e1815 +timeCreated: 1466586851 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs b/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs new file mode 100644 index 0000000..a386473 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.PostProcessing +{ + public sealed class RenderTextureFactory : IDisposable + { + HashSet m_TemporaryRTs; + + public RenderTextureFactory() + { + m_TemporaryRTs = new HashSet(); + } + + public RenderTexture Get(RenderTexture baseRenderTexture) + { + return Get( + baseRenderTexture.width, + baseRenderTexture.height, + baseRenderTexture.depth, + baseRenderTexture.format, + baseRenderTexture.sRGB ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear, + baseRenderTexture.filterMode, + baseRenderTexture.wrapMode + ); + } + + public RenderTexture Get(int width, int height, int depthBuffer = 0, RenderTextureFormat format = RenderTextureFormat.ARGBHalf, RenderTextureReadWrite rw = RenderTextureReadWrite.Default, FilterMode filterMode = FilterMode.Bilinear, TextureWrapMode wrapMode = TextureWrapMode.Clamp, string name = "FactoryTempTexture") + { + var rt = RenderTexture.GetTemporary(width, height, depthBuffer, format, rw); // add forgotten param rw + rt.filterMode = filterMode; + rt.wrapMode = wrapMode; + rt.name = name; + m_TemporaryRTs.Add(rt); + return rt; + } + + public void Release(RenderTexture rt) + { + if (rt == null) + return; + + if (!m_TemporaryRTs.Contains(rt)) + throw new ArgumentException(string.Format("Attempting to remove a RenderTexture that was not allocated: {0}", rt)); + + m_TemporaryRTs.Remove(rt); + RenderTexture.ReleaseTemporary(rt); + } + + public void ReleaseAll() + { + var enumerator = m_TemporaryRTs.GetEnumerator(); + while (enumerator.MoveNext()) + RenderTexture.ReleaseTemporary(enumerator.Current); + + m_TemporaryRTs.Clear(); + } + + public void Dispose() + { + ReleaseAll(); + } + } +} diff --git a/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs.meta b/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs.meta new file mode 100644 index 0000000..adf43f7 --- /dev/null +++ b/Assets/PostProcessing/Runtime/Utils/RenderTextureFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aec5694806c4d75449e231cfae69c329 +timeCreated: 1467361102 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures.meta b/Assets/PostProcessing/Textures.meta new file mode 100644 index 0000000..499c8a7 --- /dev/null +++ b/Assets/PostProcessing/Textures.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e15c29a7abfa52743a8cb7714389c3c7 +folderAsset: yes +timeCreated: 1466585230 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/LUTs.meta b/Assets/PostProcessing/Textures/LUTs.meta new file mode 100644 index 0000000..e0a1add --- /dev/null +++ b/Assets/PostProcessing/Textures/LUTs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 499867e2df2e54e4aad0b9333221f875 +folderAsset: yes +timeCreated: 1473255405 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png new file mode 100644 index 0000000..0e4bda4 Binary files /dev/null and b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png differ diff --git a/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png.meta b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png.meta new file mode 100644 index 0000000..179f953 --- /dev/null +++ b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_16.png.meta @@ -0,0 +1,57 @@ +fileFormatVersion: 2 +guid: e45483e270a314c4bbc6e317771d56ab +timeCreated: 1463066524 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png new file mode 100644 index 0000000..b8724d4 Binary files /dev/null and b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png differ diff --git a/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png.meta b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png.meta new file mode 100644 index 0000000..aab5d02 --- /dev/null +++ b/Assets/PostProcessing/Textures/LUTs/NeutralLUT_32.png.meta @@ -0,0 +1,57 @@ +fileFormatVersion: 2 +guid: 4f98e9c96c8a48541b5eb704e92d99b8 +timeCreated: 1463066534 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Lens Dirt.meta b/Assets/PostProcessing/Textures/Lens Dirt.meta new file mode 100644 index 0000000..0fd5403 --- /dev/null +++ b/Assets/PostProcessing/Textures/Lens Dirt.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 705e7922061713741885ae52a3e0bea4 +folderAsset: yes +timeCreated: 1472737148 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png new file mode 100644 index 0000000..d90b8c0 Binary files /dev/null and b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png differ diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png.meta b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png.meta new file mode 100644 index 0000000..83cf623 --- /dev/null +++ b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt00.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 69e847bbff1cf5449a4ee0bbd045dbc9 +timeCreated: 1472572785 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 4096 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png new file mode 100644 index 0000000..eb9efb6 Binary files /dev/null and b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png differ diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png.meta b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png.meta new file mode 100644 index 0000000..a9514eb --- /dev/null +++ b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt01.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 3884f7a2d04ffe8409ad9200b275896f +timeCreated: 1472551546 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 4096 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png new file mode 100644 index 0000000..bc52c2a Binary files /dev/null and b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png differ diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png.meta b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png.meta new file mode 100644 index 0000000..572a9ef --- /dev/null +++ b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt02.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: a2960ffde020f27409e070d92fb2e00b +timeCreated: 1472632371 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 4096 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png new file mode 100644 index 0000000..7ccd8af Binary files /dev/null and b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png differ diff --git a/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png.meta b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png.meta new file mode 100644 index 0000000..177c1d5 --- /dev/null +++ b/Assets/PostProcessing/Textures/Lens Dirt/LensDirt03.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 7a051dbda2d7bc447bee412427cd311e +timeCreated: 1472641925 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 4096 + textureSettings: + filterMode: -1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 1024 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Spectral LUTs.meta b/Assets/PostProcessing/Textures/Spectral LUTs.meta new file mode 100644 index 0000000..53dbfa1 --- /dev/null +++ b/Assets/PostProcessing/Textures/Spectral LUTs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 67d9249960fda4c41b0a23a65573a8a2 +folderAsset: yes +timeCreated: 1473255405 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga new file mode 100644 index 0000000..81828f5 Binary files /dev/null and b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga differ diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga.meta b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga.meta new file mode 100644 index 0000000..f8f5402 --- /dev/null +++ b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_BlueRed.tga.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 318cbcd94840f1d48aca4d86234dc2e7 +timeCreated: 1473255656 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga new file mode 100644 index 0000000..4dd4db7 Binary files /dev/null and b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga differ diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga.meta b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga.meta new file mode 100644 index 0000000..6946708 --- /dev/null +++ b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_GreenPurple.tga.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 4a8f054acfbd08043a931cd22760758d +timeCreated: 1473255985 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga new file mode 100644 index 0000000..d67304c Binary files /dev/null and b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga differ diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga.meta b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga.meta new file mode 100644 index 0000000..d86e3f7 --- /dev/null +++ b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_PurpleGreen.tga.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 42183971d24cfe443a346e7ec6e83bbb +timeCreated: 1473256088 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga new file mode 100644 index 0000000..43cd826 Binary files /dev/null and b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga differ diff --git a/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga.meta b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga.meta new file mode 100644 index 0000000..590ad5b --- /dev/null +++ b/Assets/PostProcessing/Textures/Spectral LUTs/SpectralLut_RedBlue.tga.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: ff5f3317371838d4fa16ac6c2acf2040 +timeCreated: 1473255656 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 32 + textureSettings: + filterMode: 1 + aniso: 0 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities.meta b/Assets/PostProcessing/Utilities.meta new file mode 100644 index 0000000..2162062 --- /dev/null +++ b/Assets/PostProcessing/Utilities.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 478d405e757b044f2bd9c4b777026b7e +folderAsset: yes +timeCreated: 1487339997 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture.meta new file mode 100644 index 0000000..1a389df --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5b271143f6e834d6bb7a4309f2c781f2 +folderAsset: yes +timeCreated: 1487339997 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset b/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset new file mode 100644 index 0000000..c450ee5 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset @@ -0,0 +1,344 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a3bdb2cd68f901469e7cc149151eb49, type: 3} + m_Name: CustomMotionVectorDebugProfile + m_EditorClassIdentifier: + debugViews: + m_Enabled: 1 + m_Settings: + mode: 3 + depth: + scale: 1 + motionVectors: + sourceOpacity: 1 + motionImageOpacity: 0 + motionImageAmplitude: 16 + motionVectorsOpacity: 1 + motionVectorsResolution: 48 + motionVectorsAmplitude: 64 + fog: + m_Enabled: 0 + m_Settings: + excludeSkybox: 1 + antialiasing: + m_Enabled: 0 + m_Settings: + method: 0 + fxaaSettings: + preset: 2 + taaSettings: + jitterSpread: 0.75 + sharpen: 0.3 + stationaryBlending: 0.95 + motionBlending: 0.85 + ambientOcclusion: + m_Enabled: 0 + m_Settings: + intensity: 1 + radius: 0.3 + sampleCount: 10 + downsampling: 1 + forceForwardCompatibility: 0 + ambientOnly: 0 + highPrecision: 0 + screenSpaceReflection: + m_Enabled: 0 + m_Settings: + reflection: + blendType: 0 + reflectionQuality: 2 + maxDistance: 100 + iterationCount: 256 + stepSize: 3 + widthModifier: 0.5 + reflectionBlur: 1 + reflectBackfaces: 0 + intensity: + reflectionMultiplier: 1 + fadeDistance: 100 + fresnelFade: 1 + fresnelFadePower: 1 + screenEdgeMask: + intensity: 0.03 + depthOfField: + m_Enabled: 0 + m_Settings: + focusDistance: 10 + aperture: 5.6 + focalLength: 50 + useCameraFov: 0 + kernelSize: 1 + motionBlur: + m_Enabled: 1 + m_Settings: + shutterAngle: 270 + sampleCount: 10 + frameBlending: 0 + eyeAdaptation: + m_Enabled: 0 + m_Settings: + lowPercent: 65 + highPercent: 95 + minLuminance: 0.03 + maxLuminance: 2 + keyValue: 0.25 + dynamicKeyValue: 1 + adaptationType: 0 + speedUp: 2 + speedDown: 1 + logMin: -8 + logMax: 4 + bloom: + m_Enabled: 0 + m_Settings: + bloom: + intensity: 0.5 + threshold: 1.1 + softKnee: 0.5 + radius: 4 + antiFlicker: 0 + lensDirt: + texture: {fileID: 0} + intensity: 3 + colorGrading: + m_Enabled: 0 + m_Settings: + tonemapping: + tonemapper: 2 + neutralBlackIn: 0.02 + neutralWhiteIn: 10 + neutralBlackOut: 0 + neutralWhiteOut: 10 + neutralWhiteLevel: 5.3 + neutralWhiteClip: 10 + basic: + postExposure: 0 + temperature: 0 + tint: 0 + hueShift: 0 + saturation: 1 + contrast: 1 + channelMixer: + red: {x: 1, y: 0, z: 0} + green: {x: 0, y: 1, z: 0} + blue: {x: 0, y: 0, z: 1} + currentEditingChannel: 0 + colorWheels: + mode: 1 + log: + slope: {r: 0, g: 0, b: 0, a: 0} + power: {r: 0, g: 0, b: 0, a: 0} + offset: {r: 0, g: 0, b: 0, a: 0} + linear: + lift: {r: 0, g: 0, b: 0, a: 0} + gamma: {r: 0, g: 0, b: 0, a: 0} + gain: {r: 0, g: 0, b: 0, a: 0} + curves: + master: + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0 + m_Range: 1 + red: + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0 + m_Range: 1 + green: + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0 + m_Range: 1 + blue: + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 1 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0 + m_Range: 1 + hueVShue: + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 1 + m_ZeroValue: 0.5 + m_Range: 1 + hueVSsat: + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 1 + m_ZeroValue: 0.5 + m_Range: 1 + satVSsat: + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0.5 + m_Range: 1 + lumVSsat: + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_Loop: 0 + m_ZeroValue: 0.5 + m_Range: 1 + e_CurrentEditingCurve: 0 + e_CurveY: 1 + e_CurveR: 0 + e_CurveG: 0 + e_CurveB: 0 + userLut: + m_Enabled: 0 + m_Settings: + lut: {fileID: 0} + contribution: 1 + chromaticAberration: + m_Enabled: 0 + m_Settings: + spectralTexture: {fileID: 0} + intensity: 0.1 + grain: + m_Enabled: 0 + m_Settings: + colored: 1 + intensity: 0.5 + size: 1 + luminanceContribution: 0.8 + vignette: + m_Enabled: 0 + m_Settings: + mode: 0 + color: {r: 0, g: 0, b: 0, a: 1} + center: {x: 0.5, y: 0.5} + intensity: 0.45 + smoothness: 0.2 + roundness: 1 + mask: {fileID: 0} + opacity: 1 + rounded: 0 + dithering: + m_Enabled: 0 + monitors: + currentMonitorID: 0 + refreshOnPlay: 0 + histogramMode: 3 + waveformExposure: 0.12 + waveformY: 0 + waveformR: 1 + waveformG: 1 + waveformB: 1 + paradeExposure: 0.12 + vectorscopeExposure: 0.12 + vectorscopeShowBackground: 1 diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset.meta new file mode 100644 index 0000000..5ece9be --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/CustomMotionVectorDebugProfile.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d982e879ff67b4d3fb6522d08c3cd5af +timeCreated: 1487341088 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity new file mode 100644 index 0000000..9243cc8 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity @@ -0,0 +1,1277 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 0 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &159053895 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 100000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 159053896} + m_Layer: 0 + m_Name: CustomMotionVectorTexture + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &159053896 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 400000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 159053895} + m_LocalRotation: {x: -0, y: 0.17364816, z: -0, w: 0.9848078} + m_LocalPosition: {x: 0, y: -0.211, z: -0.65} + m_LocalScale: {x: 40, y: 40, z: 40} + m_Children: + - {fileID: 1356308505} + - {fileID: 860688641} + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &483713897 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 483713898} + - component: {fileID: 483713900} + - component: {fileID: 483713899} + m_Layer: 5 + m_Name: Text (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &483713898 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 483713897} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1670569530} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -115} + m_SizeDelta: {x: 160, y: 70.5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &483713899 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 483713897} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 'Controls: + + + UpArrow - Forward + + DownArrow - Reverse' +--- !u!222 &483713900 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 483713897} + m_CullTransparentMesh: 0 +--- !u!1 &687590844 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 100000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 687590849} + - component: {fileID: 687590848} + - component: {fileID: 687590847} + - component: {fileID: 687590846} + - component: {fileID: 687590845} + m_Layer: 0 + m_Name: Wheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!54 &687590845 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 687590844} + serializedVersion: 2 + m_Mass: 0.1 + m_Drag: 0 + m_AngularDrag: 0.05 + m_UseGravity: 0 + m_IsKinematic: 0 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!114 &687590846 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 687590844} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 840c928746809454cb5b9309b640dbd7, type: 3} + m_Name: + m_EditorClassIdentifier: + acceleration: 10 + motionVectorRenderer: {fileID: 0} +--- !u!23 &687590847 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 2300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 687590844} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 944463113244f4bf8b05c1757cd838a4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &687590848 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 3300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 687590844} + m_Mesh: {fileID: 4300000, guid: c4abfbff3b9d442f4b435849d2d2124c, type: 3} +--- !u!4 &687590849 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 400000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 687590844} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 732169372} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: -20, z: 0} +--- !u!1 &732169371 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 100000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 732169372} + m_Layer: 0 + m_Name: RegularMotionVectors + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &732169372 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 400000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 732169371} + m_LocalRotation: {x: 0, y: -0.17364825, z: 0, w: 0.9848078} + m_LocalPosition: {x: -0, y: -0.211, z: 0.65} + m_LocalScale: {x: 40, y: 40, z: 40} + m_Children: + - {fileID: 687590849} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: -20, z: 0} +--- !u!1 &860688640 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 100000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 860688641} + - component: {fileID: 860688644} + - component: {fileID: 860688643} + m_Layer: 0 + m_Name: MotionVectorRenderer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &860688641 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 400000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860688640} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.01, y: 1.01, z: 1.01} + m_Children: [] + m_Father: {fileID: 159053896} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &860688643 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 2300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860688640} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 055f7217f136349d9b68e82b9e987dae, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &860688644 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 3300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860688640} + m_Mesh: {fileID: 4300000, guid: c4abfbff3b9d442f4b435849d2d2124c, type: 3} +--- !u!1 &902023479 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 902023480} + - component: {fileID: 902023482} + - component: {fileID: 902023481} + m_Layer: 5 + m_Name: Text (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &902023480 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 902023479} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1670569530} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 146} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &902023481 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 902023479} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Debug Texture +--- !u!222 &902023482 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 902023479} + m_CullTransparentMesh: 0 +--- !u!1 &1216344938 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1216344942} + - component: {fileID: 1216344941} + - component: {fileID: 1216344940} + - component: {fileID: 1216344939} + m_Layer: 0 + m_Name: MotionVectorRenderer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &1216344939 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1216344938} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: d7daeefbca4f14360bac0e1df1bdacd4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!64 &1216344940 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1216344938} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Convex: 0 + m_CookingOptions: 14 + m_SkinWidth: 0.01 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &1216344941 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1216344938} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1216344942 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1216344938} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1695974773} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: -90.382, z: 0} +--- !u!1 &1356308501 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 100000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1356308505} + - component: {fileID: 1356308504} + - component: {fileID: 1356308503} + - component: {fileID: 1356308506} + - component: {fileID: 1356308502} + m_Layer: 0 + m_Name: Wheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!54 &1356308502 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1356308501} + serializedVersion: 2 + m_Mass: 0.1 + m_Drag: 0 + m_AngularDrag: 0.05 + m_UseGravity: 0 + m_IsKinematic: 0 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!23 &1356308503 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 2300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1356308501} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 944463113244f4bf8b05c1757cd838a4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &1356308504 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 3300000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1356308501} + m_Mesh: {fileID: 4300000, guid: c4abfbff3b9d442f4b435849d2d2124c, type: 3} +--- !u!4 &1356308505 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 400000, guid: c4abfbff3b9d442f4b435849d2d2124c, + type: 3} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1356308501} + m_LocalRotation: {x: -0, y: -0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 159053896} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 20, z: 0} +--- !u!114 &1356308506 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1356308501} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 840c928746809454cb5b9309b640dbd7, type: 3} + m_Name: + m_EditorClassIdentifier: + acceleration: 10 + motionVectorRenderer: {fileID: 860688643} +--- !u!1 &1427819714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1427819715} + - component: {fileID: 1427819717} + - component: {fileID: 1427819716} + m_Layer: 5 + m_Name: Text (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1427819715 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1427819714} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1670569530} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 160, y: 68} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1427819716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1427819714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Regular Motion Vectors +--- !u!222 &1427819717 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1427819714} + m_CullTransparentMesh: 0 +--- !u!1 &1489478929 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1489478934} + - component: {fileID: 1489478933} + - component: {fileID: 1489478932} + - component: {fileID: 1489478931} + - component: {fileID: 1489478930} + - component: {fileID: 1489478935} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1489478930 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_Enabled: 1 +--- !u!124 &1489478931 +Behaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_Enabled: 1 +--- !u!92 &1489478932 +Behaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_Enabled: 1 +--- !u!20 &1489478933 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.23529412, g: 0.23529412, b: 0.23529412, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: 3 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1489478934 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_LocalRotation: {x: 0.111127794, y: -0.69831985, z: 0.111127794, w: 0.69831985} + m_LocalPosition: {x: 1.02, y: 0.3286136, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 18.084002, y: -90, z: 0} +--- !u!114 &1489478935 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1489478929} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ff26db721962cdf4a8edcdfa9a767d2a, type: 3} + m_Name: + m_EditorClassIdentifier: + profile: {fileID: 11400000, guid: d982e879ff67b4d3fb6522d08c3cd5af, type: 2} +--- !u!1 &1563286491 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1563286492} + - component: {fileID: 1563286494} + - component: {fileID: 1563286493} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1563286492 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1563286491} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1670569530} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -160, y: 68} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1563286493 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1563286491} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Custom Motion Vectors +--- !u!222 &1563286494 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1563286491} + m_CullTransparentMesh: 0 +--- !u!1 &1670569526 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1670569530} + - component: {fileID: 1670569529} + - component: {fileID: 1670569528} + - component: {fileID: 1670569527} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1670569527 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1670569526} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1670569528 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1670569526} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &1670569529 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1670569526} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 25 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1670569530 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1670569526} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1563286492} + - {fileID: 1427819715} + - {fileID: 483713898} + - {fileID: 902023480} + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1695974769 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1695974773} + - component: {fileID: 1695974772} + - component: {fileID: 1695974771} + - component: {fileID: 1695974770} + m_Layer: 0 + m_Name: DebugQuad + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &1695974770 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1695974769} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 2100000, guid: 3c40c8fdc50a841579d7cb15882ac9d9, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!64 &1695974771 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1695974769} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Convex: 0 + m_CookingOptions: 14 + m_SkinWidth: 0.01 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &1695974772 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1695974769} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1695974773 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1695974769} + m_LocalRotation: {x: -0, y: -0.7094573, z: -0, w: 0.7047485} + m_LocalPosition: {x: 0, y: 0.284, z: 0} + m_LocalScale: {x: 0.25, y: 0.25, z: 0.25} + m_Children: + - {fileID: 1216344942} + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: -90.382, z: 0} +--- !u!1 &1940873752 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1940873755} + - component: {fileID: 1940873754} + - component: {fileID: 1940873753} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1940873753 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1940873752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1940873754 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1940873752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 5 +--- !u!4 &1940873755 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1940873752} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2138017022 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2138017024} + - component: {fileID: 2138017023} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &2138017023 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2138017022} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &2138017024 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2138017022} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity.meta new file mode 100644 index 0000000..94ac193 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ed3a9f41209f84f6db99e07013da9628 +timeCreated: 1487347827 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs new file mode 100644 index 0000000..a8bf34a --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +public class ExampleWheelController : MonoBehaviour +{ + public float acceleration; + public Renderer motionVectorRenderer; // Reference to the custom motion vector renderer + + Rigidbody m_Rigidbody; + + static class Uniforms + { + internal static readonly int _MotionAmount = Shader.PropertyToID("_MotionAmount"); + } + + void Start() + { + m_Rigidbody = GetComponent(); // Get reference to rigidbody + m_Rigidbody.maxAngularVelocity = 100; // Set max velocity for rigidbody + } + + void Update() + { + if (Input.GetKey (KeyCode.UpArrow)) // Rotate forward + m_Rigidbody.AddRelativeTorque(new Vector3(-1 * acceleration, 0, 0), ForceMode.Acceleration); // Add forward torque to mesh + else if (Input.GetKey (KeyCode.DownArrow)) // Rotate backward + m_Rigidbody.AddRelativeTorque(new Vector3(1 * acceleration, 0, 0), ForceMode.Acceleration); // Add backward torque to mesh + + float m = -m_Rigidbody.angularVelocity.x / 100; // Calculate multiplier for motion vector texture + + if (motionVectorRenderer) // If the custom motion vector texture renderer exists + motionVectorRenderer.material.SetFloat(Uniforms._MotionAmount, Mathf.Clamp(m, -0.25f, 0.25f)); // Set the multiplier on the renderer's material + } +} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs.meta new file mode 100644 index 0000000..3640cf0 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/ExampleWheelController.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 840c928746809454cb5b9309b640dbd7 +timeCreated: 1479836093 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials.meta new file mode 100644 index 0000000..89cab6e --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c4b2008f2662a41e587c4351609053c4 +folderAsset: yes +timeCreated: 1487340121 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat new file mode 100644 index 0000000..cdbbc2d --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: DebugMotionVectors + m_Shader: {fileID: 4800000, guid: 9189229324e2342b8b69f7c1904dceba, type: 3} + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 3aac3087967ea4fae858ec0494fd24d9, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MotionTex: + m_Texture: {fileID: 2800000, guid: 3aac3087967ea4fae858ec0494fd24d9, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _MotionAmount: 0.1 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat.meta new file mode 100644 index 0000000..66e3c8e --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugMotionVectors.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7daeefbca4f14360bac0e1df1bdacd4 +timeCreated: 1479896287 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat new file mode 100644 index 0000000..1799d6e --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: DebugQuad + m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 3aac3087967ea4fae858ec0494fd24d9, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MotionTex: + m_Texture: {fileID: 2800000, guid: 3aac3087967ea4fae858ec0494fd24d9, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _MotionAmount: 0.26 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat.meta new file mode 100644 index 0000000..a08b218 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/DebugQuad.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3c40c8fdc50a841579d7cb15882ac9d9 +timeCreated: 1479896287 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat new file mode 100644 index 0000000..4f27925 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: UVChecker + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: a08960dd6e8274e7f8fca616e09c48ed, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat.meta new file mode 100644 index 0000000..ac49b57 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/UVChecker.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 944463113244f4bf8b05c1757cd838a4 +timeCreated: 1487340121 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat new file mode 100644 index 0000000..adeaa8f --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: WheelMotionVectors + m_Shader: {fileID: 4800000, guid: 9189229324e2342b8b69f7c1904dceba, type: 3} + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MotionTex: + m_Texture: {fileID: 2800000, guid: d1cc06458fe724df8837423c0a2f8f93, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _MotionAmount: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat.meta new file mode 100644 index 0000000..f711c1d --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Materials/WheelMotionVectors.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 055f7217f136349d9b68e82b9e987dae +timeCreated: 1479896287 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Models.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models.meta new file mode 100644 index 0000000..c6d9a8c --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ef5ce588de3614b39b5ba7b0613cbe43 +folderAsset: yes +timeCreated: 1487348152 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX new file mode 100644 index 0000000..d8f6b35 Binary files /dev/null and b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX differ diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX.meta new file mode 100644 index 0000000..4f14161 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Models/WheelMovecs.FBX.meta @@ -0,0 +1,81 @@ +fileFormatVersion: 2 +guid: c4abfbff3b9d442f4b435849d2d2124c +timeCreated: 1479895866 +licenseType: Store +ModelImporter: + serializedVersion: 19 + fileIDToRecycleName: + 100000: //RootNode + 400000: //RootNode + 2300000: //RootNode + 3300000: //RootNode + 4300000: Object + 9500000: //RootNode + materials: + importMaterials: 0 + materialName: 0 + materialSearch: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + motionNodeName: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 0 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 0 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + optimizeMeshForGPU: 1 + keepQuads: 0 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + serializedVersion: 2 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + rootMotionBoneName: + rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1} + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 2 + humanoidOversampling: 1 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders.meta new file mode 100644 index 0000000..3baecf4 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8e565c240745c49628f96f0573adfa76 +folderAsset: yes +timeCreated: 1487348368 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader new file mode 100644 index 0000000..b966815 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader @@ -0,0 +1,70 @@ +Shader "Post Processing/Custom Motion Vector Texture" +{ + Properties + { + _MotionTex ("Motion Vector Texture", 2D) = "black" {} + _MotionAmount ("Motion Vector Multiplier", range (-0.25, 0.25)) = 0 + } + SubShader + { + Pass + { + Name "Motion Vectors" + Tags { "LightMode" = "MotionVectors" } + + ZTest LEqual Cull Back ZWrite On + + CGPROGRAM + + #pragma vertex vert + #pragma fragment FragMotionVectors + #include "UnityCG.cginc" + + float4 _MotionValue; + sampler2D _MotionTex; + float4 _MotionTex_ST; + float _MotionAmount; + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float3 normal : NORMAL; + float4 tangent : TANGENT; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + float3 normal : NORMAL; + float4 tangent : TANGENT; + float4 transposedTangent : TEXCOORD1; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.uv, _MotionTex); + o.normal = UnityObjectToClipPos(v.normal); + o.normal = o.normal * 0.5 + 0.5; + o.tangent = mul(UNITY_MATRIX_MV, v.tangent); + o.transposedTangent = (mul(UNITY_MATRIX_IT_MV, v.tangent)) * 0.5 + 0.5; + return o; + } + + float4 FragMotionVectors(v2f i) : SV_Target + { + half4 c = tex2D(_MotionTex, i.uv); + c.rg = (c.rg * 2.0 - 1.0) * _MotionAmount; // Using color texture so need to make 0.5 neutral + half4 t1 = i.tangent * 0.005; // Sides of tire + half4 t2 = c * float4(i.transposedTangent.r * 2.0, i.transposedTangent.g * 2.0, 0.0, 1.0); // Front of tire + half4 t3 = lerp(t2, t1, c.b); // Lerp between front and side of tire + return t3 * _MotionAmount; + } + + ENDCG + } + } +} diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader.meta new file mode 100644 index 0000000..07d7945 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Shaders/CustomMotionVectorTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9189229324e2342b8b69f7c1904dceba +timeCreated: 1479826273 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures.meta new file mode 100644 index 0000000..238d285 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 92c42dce939f844cea2248583e06bd55 +folderAsset: yes +timeCreated: 1487348131 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png new file mode 100644 index 0000000..4c32bd5 Binary files /dev/null and b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png differ diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png.meta new file mode 100644 index 0000000..f0580fc --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/DebugMotionVectors.png.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: 3aac3087967ea4fae858ec0494fd24d9 +timeCreated: 1479828550 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png new file mode 100644 index 0000000..39442e6 Binary files /dev/null and b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png differ diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png.meta new file mode 100644 index 0000000..1114b26 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/UVChecker.png.meta @@ -0,0 +1,68 @@ +fileFormatVersion: 2 +guid: a08960dd6e8274e7f8fca616e09c48ed +timeCreated: 1487340672 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png new file mode 100644 index 0000000..175836d Binary files /dev/null and b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png differ diff --git a/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png.meta b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png.meta new file mode 100644 index 0000000..c141bb9 --- /dev/null +++ b/Assets/PostProcessing/Utilities/CustomMotionTexture/Textures/WheelMotionVectors.png.meta @@ -0,0 +1,68 @@ +fileFormatVersion: 2 +guid: d1cc06458fe724df8837423c0a2f8f93 +timeCreated: 1487348028 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/README.MD b/Assets/README.MD index 1aad31e..7df21d8 100644 --- a/Assets/README.MD +++ b/Assets/README.MD @@ -52,3 +52,10 @@ approximate gaps fences vegetation +stencil +luminance +saturation +brightness +contrast +gradient +accumulation diff --git a/Assets/Scenes/Chapter14/Scene_14_1.unity b/Assets/Scenes/Chapter14/Scene_14_1.unity new file mode 100644 index 0000000..2165f40 --- /dev/null +++ b/Assets/Scenes/Chapter14/Scene_14_1.unity @@ -0,0 +1,308 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657844, g: 0.49641222, b: 0.57481694, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &84908524 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 84908527} + - component: {fileID: 84908526} + - component: {fileID: 84908525} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &84908525 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 84908524} + m_Enabled: 1 +--- !u!20 &84908526 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 84908524} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &84908527 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 84908524} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &599021862 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 599021864} + - component: {fileID: 599021863} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &599021863 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 599021862} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &599021864 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 599021862} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1001 &742679154 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalPosition.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalPosition.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalPosition.z + value: -7 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalRotation.y + value: 0.98232 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalRotation.w + value: 0.18720998 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 400002, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 158.42 + objectReference: {fileID: 0} + - target: {fileID: 2300000, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + propertyPath: m_Materials.Array.data[0] + value: + objectReference: {fileID: 2100000, guid: 4c2d1637ec0ee6b4799a5e53092c18f9, type: 2} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 44e861aa1c32b40b98ea93eb35f1c5eb, type: 3} + m_IsPrefabAsset: 0 diff --git a/Assets/Scenes/Chapter14/Scene_14_1.unity.meta b/Assets/Scenes/Chapter14/Scene_14_1.unity.meta new file mode 100644 index 0000000..13cdf57 --- /dev/null +++ b/Assets/Scenes/Chapter14/Scene_14_1.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 834a0945803eb9840b796fdb384f1926 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/Chapter14/Hatching.shader b/Assets/Shaders/Chapter14/Hatching.shader new file mode 100644 index 0000000..7166f85 --- /dev/null +++ b/Assets/Shaders/Chapter14/Hatching.shader @@ -0,0 +1,121 @@ +Shader "Unity Shaders Book/Chapter 14/Hatching" { + Properties { + _Color ("Color Tint", Color) = (1, 1, 1, 1) + _TileFactor ("Tile Factor", Float) = 1 + _Outline ("Outline", Range(0, 1)) = 0.1 + _Hatch0("Hatch 0", 2D) = "white" {} + _Hatch1("Hatch 1", 2D) = "white" {} + _Hatch2("Hatch 2", 2D) = "white" {} + _Hatch3("Hatch 3", 2D) = "white" {} + _Hatch4("Hatch 4", 2D) = "white" {} + _Hatch5("Hatch 5", 2D) = "white" {} + } + + Subshader { + Tags { "Queue"="Geometry" "RenderType"="Opaque" } + + UsePass "Unity Shader Book/Chapter 14/Toon Shading/OUTLINE" + + Pass { + Tags { "LightMode"="ForwardBase" } + + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + + #pragma multi_compile_fwdbase + + #include "UnityCG.cginc" + #include "Lighting.cginc" + #include "AutoLight.cginc" + #include "UnityShaderVariables.cginc" + + fixed4 _Color; + float _TileFactor; + sampler2D _Hatch0; + sampler2D _Hatch1; + sampler2D _Hatch2; + sampler2D _Hatch3; + sampler2D _Hatch4; + sampler2D _Hatch5; + + struct a2v { + float4 vertex : POSITION; + float3 normal : NORMAL; + float4 tangent : TANGENT; + float2 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + fixed3 hatchWeights0 : TEXCOORD1; + fixed3 hatchWeights1 : TEXCOORD2; + float3 worldPos : TEXCOORD3; + SHADOW_COORDS(4) + }; + + v2f vert(a2v v) { + v2f o; + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord.xy * _TileFactor; + + fixed3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex)); + fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); + fixed diff = max(0, dot(worldLightDir, worldNormal)); + + o.hatchWeights0 = fixed3(0, 0, 0); + o.hatchWeights1 = fixed3(0, 0, 0); + + float hatchFactor = diff * 7.0; + if (hatchFactor > 6.0) { + // Pure white, do nothing + } else if (hatchFactor > 5.0) { + o.hatchWeights0.x = hatchFactor - 5.0; + } else if (hatchFactor > 4.0) { + o.hatchWeights0.x = hatchFactor - 4.0; + o.hatchWeights0.y = 1.0 - o.hatchWeights0.x; + } else if (hatchFactor > 3.0) { + o.hatchWeights0.y = hatchFactor - 3.0; + o.hatchWeights0.z = 1.0 - o.hatchWeights0.y; + } else if (hatchFactor > 2.0) { + o.hatchWeights0.z = hatchFactor - 2.0; + o.hatchWeights1.x = 1.0 - o.hatchWeights0.z; + } else if (hatchFactor > 1.0) { + o.hatchWeights1.x = hatchFactor - 1.0; + o.hatchWeights1.y = 1.0 - o.hatchWeights1.x; + } else { + o.hatchWeights1.y = hatchFactor; + o.hatchWeights1.z = 1.0 - o.hatchWeights1.y; + } + + o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; + + TRANSFER_SHADOW(o); + + return o; + } + + fixed4 frag(v2f i) : SV_Target { + fixed4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x; + fixed4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y; + fixed4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z; + fixed4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x; + fixed4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y; + fixed4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z; + fixed4 whiteColor = fixed4(1, 1, 1, 1) * (1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z); + fixed4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor; + + UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); + + return fixed4(hatchColor.rgb * _Color.rgb * atten, 1.0); + } + } + } + + Fallback "Diffuse" + + // CustomEditor "Hatching Editor Script Name" +} diff --git a/Assets/Shaders/Chapter14/Hatching.shader.meta b/Assets/Shaders/Chapter14/Hatching.shader.meta new file mode 100644 index 0000000..f4488fb --- /dev/null +++ b/Assets/Shaders/Chapter14/Hatching.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 186fdaa7cbfb083449a479a536f1cf8d +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/Chapter14/ToonShading.shader b/Assets/Shaders/Chapter14/ToonShading.shader new file mode 100644 index 0000000..45c29cf --- /dev/null +++ b/Assets/Shaders/Chapter14/ToonShading.shader @@ -0,0 +1,141 @@ +Shader "Unity Shaders Book/Chapter 14/Toon Shading" { + Properties { + _MainTex ("Main Tex", 2D) = "white" {} + _Color ("Color Tini", Color) = (1, 1, 1, 1) + _Ramp ("Ramp Texture", 2D) = "white" {} + _Outline ("Outline", Range(0, 1)) = 0.1 + _OutlineColor ("Outline Color", Color) = (0, 0, 0, 1) + _Specular ("Specular", Color) = (1, 1, 1, 1) + _SpecularScale ("Specular Scale", Range(0, 0.1)) = 0.01 + } + + SubShader { + Tags { "Queue"="Geometry" "RenderType"="Opaque" } + + Pass { + NAME "OUTLINE" + + Cull Front + + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + float _Outline; + fixed4 _OutlineColor; + + struct a2v { + float4 vertex : POSITION; + float3 normal : NORMAL; + }; + + struct v2f { + float4 pos : SV_POSITION; + }; + + v2f vert(a2v v) { + v2f o; + + //float4 pos = mul(UNITY_MATRIX_MV, v.vertex); + float4 pos = float4(UnityObjectToViewPos(v.vertex).xyz, 1.0); + float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal); + normal.z = -0.5; + pos = pos + float4(normalize(normal), 0) * _Outline; + o.pos = mul(UNITY_MATRIX_P, pos); + + return o; + } + + float4 frag (v2f i) : SV_Target { + return float4(_OutlineColor.rgb, 1.0); + } + + ENDCG + } + + Pass { + Tags { "LightMode"="ForwardBase" } + + Cull Back + + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + + #pragma multi_compile_fwdbase + + #include "UnityCG.cginc" + #include "Lighting.cginc" + #include "AutoLight.cginc" + #include "UnityShaderVariables.cginc" + + fixed4 _Color; + sampler2D _MainTex; + float4 _MainTex_ST; + sampler2D _Ramp; + fixed4 _Specular; + fixed _SpecularScale; + + struct a2v { + float4 vertex : POSITION; + float3 normal : NORMAL; + float4 tangent : TANGENT; + float4 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float3 worldNormal : TEXCOORD1; + float3 worldPos : TEXCOORD2; + SHADOW_COORDS(3) + }; + + v2f vert(a2v v) { + v2f o; + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + o.worldNormal = UnityObjectToWorldNormal(v.normal); + o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; + + TRANSFER_SHADOW(o); + + return o; + } + + float4 frag(v2f i) : SV_Target { + fixed3 worldNormal = normalize(i.worldNormal); + fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); + fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); + fixed3 worldHalfDir = normalize(worldLightDir + worldViewDir); + + fixed3 color = tex2D(_MainTex, i.uv); + fixed3 albedo = color.rgb * _Color.rgb; + fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; + + UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); + + fixed diff = dot(worldNormal, worldLightDir); + diff = (diff * 0.5 + 0.5) * atten; + + fixed3 diffuse = _LightColor0.rgb * albedo * tex2D(_Ramp, float2(diff, diff)).rgb; + fixed spec = dot(worldNormal, worldHalfDir); + fixed w = fwidth(spec) * 2.0; + fixed3 specular = _Specular.rgb * lerp(0, 1, smoothstep(-w, w, spec + _SpecularScale -1)) * step(0.0001, _SpecularScale); + + return fixed4 (ambient + diffuse + specular, 1.0); + } + + ENDCG + } + } + + Fallback "Diffuse" + + // CustomEditor "Toon Shading Editor Script Name" +} diff --git a/Assets/Shaders/Chapter14/ToonShading.shader.meta b/Assets/Shaders/Chapter14/ToonShading.shader.meta new file mode 100644 index 0000000..ebe7f84 --- /dev/null +++ b/Assets/Shaders/Chapter14/ToonShading.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c7003a2e6a2f78542a4f7afbb06ffd7c +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: