// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
|
|
|
// Copyright(c) 2016, Michal Skalsky
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
|
// may be used to endorse or promote products derived from this software without
|
|
// specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT
|
|
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//Modified by Carlos Macarrón & David Miranda
|
|
|
|
Shader "Hidden/Upsample"
|
|
{
|
|
Properties
|
|
{
|
|
|
|
|
|
_UpsampleDepthThreshold("Upsample Depth Threshold", Range(0, 2)) = .05
|
|
[HideInInspector] _LowResColor("", 2D) = "white"{}
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
// No culling or depth
|
|
Cull Off ZWrite Off ZTest Always
|
|
|
|
CGINCLUDE
|
|
|
|
// #define UPSAMPLE_DEPTH_THRESHOLD 0.05f
|
|
uniform half _UpsampleDepthThreshold = .05;
|
|
int RightSide;
|
|
#define PI 3.1415927f
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
float4 _TexelSize = 1;
|
|
sampler2D _HiResDepthBufferR;
|
|
sampler2D _HiResDepthBuffer;
|
|
sampler2D _LowResDepthBuffer;
|
|
sampler2D _LowResDepthBufferR;
|
|
sampler2D _LowResColor;
|
|
sampler2D _LowResColorR;
|
|
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
};
|
|
|
|
struct v2fDownsample
|
|
{
|
|
float4 vertex : SV_POSITION0;
|
|
float2 uv : TEXCOORD0;
|
|
float2 uv00 : TEXCOORD1;
|
|
float2 uv01 : TEXCOORD2;
|
|
float2 uv10 : TEXCOORD3;
|
|
float2 uv11 : TEXCOORD4;
|
|
};
|
|
|
|
struct v2fUpsample
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float2 uv00 : TEXCOORD1;
|
|
float2 uv01 : TEXCOORD2;
|
|
float2 uv10 : TEXCOORD3;
|
|
float2 uv11 : TEXCOORD4;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
// vertDownsampleDepth
|
|
//-----------------------------------------------------------------------------------------
|
|
v2fDownsample vertDownsampleDepth(appdata v, float2 texelSize)
|
|
{
|
|
v2fDownsample o;
|
|
UNITY_INITIALIZE_OUTPUT(v2fDownsample, o);
|
|
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
#if UNITY_SINGLE_PASS_STEREO
|
|
o.uv = UnityStereoTransformScreenSpaceTex(v.uv);
|
|
#else
|
|
o.uv = v.uv;
|
|
#endif
|
|
|
|
o.uv00 = v.uv - 0.5 * texelSize.xy;
|
|
o.uv10 = o.uv00 + float2(texelSize.x, 0);
|
|
o.uv01 = o.uv00 + float2(0, texelSize.y);
|
|
o.uv11 = o.uv00 + texelSize.xy;
|
|
return o;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
// vertUpsample
|
|
//-----------------------------------------------------------------------------------------
|
|
v2fUpsample vertUpsample(appdata v, float2 texelSize)
|
|
{
|
|
v2fUpsample o;
|
|
UNITY_INITIALIZE_OUTPUT(v2fUpsample, o);
|
|
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
#if UNITY_SINGLE_PASS_STEREO
|
|
o.uv = UnityStereoTransformScreenSpaceTex(v.uv);
|
|
#else
|
|
o.uv = v.uv;
|
|
#endif
|
|
o.uv00 = v.uv - 0.5 * texelSize.xy;
|
|
o.uv10 = o.uv00 + float2(texelSize.x, 0);
|
|
o.uv01 = o.uv00 + float2(0, texelSize.y);
|
|
o.uv11 = o.uv00 + texelSize.xy;
|
|
return o;
|
|
}
|
|
|
|
#undef SAMPLE_DEPTH_TEXTURE
|
|
#define SAMPLE_DEPTH_TEXTURE(sampler, uv) ( tex2D(sampler, uv).r )
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
// BilateralUpsample
|
|
//-----------------------------------------------------------------------------------------
|
|
float4 BilateralUpsample(v2fUpsample input, sampler2D hiDepth, sampler2D loDepth, sampler2D loColor)
|
|
{
|
|
float4 highResDepth = (SAMPLE_DEPTH_TEXTURE(hiDepth, input.uv)).xxxx;
|
|
|
|
float4 lowResDepth=0;
|
|
#if UNITY_SINGLE_PASS_STEREO
|
|
float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
|
|
input.uv00 = (input.uv00 - scaleOffset.zw) / scaleOffset.xy;
|
|
input.uv10 = (input.uv10 - scaleOffset.zw) / scaleOffset.xy;
|
|
input.uv01 = (input.uv01 - scaleOffset.zw) / scaleOffset.xy;
|
|
input.uv11 = (input.uv11 - scaleOffset.zw) / scaleOffset.xy;
|
|
#endif
|
|
|
|
lowResDepth[0] = (SAMPLE_DEPTH_TEXTURE(loDepth, input.uv00));
|
|
lowResDepth[1] = (SAMPLE_DEPTH_TEXTURE(loDepth, input.uv10));
|
|
lowResDepth[2] = (SAMPLE_DEPTH_TEXTURE(loDepth, input.uv01));
|
|
lowResDepth[3] = (SAMPLE_DEPTH_TEXTURE(loDepth, input.uv11));
|
|
|
|
float4 depthDiff = abs(lowResDepth - highResDepth);
|
|
float accumDiff = dot(depthDiff, .1);//3.2.1 changed 1 to .1
|
|
//UNITY_BRANCH
|
|
if (accumDiff < _UpsampleDepthThreshold) // small error, not an edge -> use bilinear filter
|
|
{
|
|
// should be bilinear sampler, dont know how to use two different samplers for one texture in Unity
|
|
//return float4(1, 0, 0, 1);
|
|
return tex2D(loColor, input.uv);
|
|
}
|
|
|
|
#if VISUALIZE_EDGE
|
|
return float4(1, .2, 0, 1);
|
|
#endif
|
|
|
|
// find nearest sample
|
|
float minDepthDiff = depthDiff[0];
|
|
float2 nearestUv = input.uv00;
|
|
|
|
if (depthDiff[1] < minDepthDiff)
|
|
{
|
|
nearestUv = input.uv10;
|
|
minDepthDiff = depthDiff[1];
|
|
}
|
|
|
|
if (depthDiff[2] < minDepthDiff)
|
|
{
|
|
nearestUv = input.uv01;
|
|
minDepthDiff = depthDiff[2];
|
|
}
|
|
|
|
if (depthDiff[3] < minDepthDiff)
|
|
{
|
|
nearestUv = input.uv11;
|
|
minDepthDiff = depthDiff[3];
|
|
}
|
|
|
|
return tex2D(loColor, nearestUv);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
// DownsampleDepth
|
|
//-----------------------------------------------------------------------------------------
|
|
float4 DownsampleDepth(v2fDownsample input, sampler2D depthTexture)
|
|
{
|
|
float final;
|
|
// Normal
|
|
final = tex2D(depthTexture, input.uv).x;
|
|
|
|
#if DOWNSAMPLE_DEPTH_MODE_MIN // min depth
|
|
float depth = tex2D(depthTexture, input.uv00) ;
|
|
depth = min(depth, tex2D(depthTexture, input.uv01) );
|
|
depth = min(depth, tex2D(depthTexture, input.uv10) );
|
|
depth = min(depth, tex2D(depthTexture, input.uv11) );
|
|
final = (depth);
|
|
#elif DOWNSAMPLE_DEPTH_MODE_MAX // max depth
|
|
float depth = tex2D(depthTexture, input.uv00) ;
|
|
depth = max(depth, tex2D(depthTexture, input.uv01) );
|
|
depth = max(depth, tex2D(depthTexture, input.uv10) );
|
|
depth = max(depth, tex2D(depthTexture, input.uv11) );
|
|
final = (depth);
|
|
#else // DOWNSAMPLE_DEPTH_MODE_CHESSBOARD
|
|
float4 depth;
|
|
depth.x = tex2D(depthTexture, input.uv00) ;
|
|
depth.y = tex2D(depthTexture, input.uv01) ;
|
|
depth.z = tex2D(depthTexture, input.uv10) ;
|
|
depth.w = tex2D(depthTexture, input.uv11) ;
|
|
|
|
float minDepth = min(min(depth.x, depth.y), min(depth.z, depth.w));
|
|
float maxDepth = max(max(depth.x, depth.y), max(depth.z, depth.w));
|
|
|
|
// chessboard pattern
|
|
int2 position = input.vertex.xy % 2;
|
|
int index = position.x + position.y;
|
|
final = (index == 1 ? minDepth : maxDepth);
|
|
#endif
|
|
return final;
|
|
}
|
|
|
|
ENDCG
|
|
|
|
// pass 0 - downsample depth
|
|
Pass
|
|
{
|
|
// Name "downsample depth"
|
|
CGPROGRAM
|
|
#pragma vertex vertDepth
|
|
#pragma fragment frag
|
|
#pragma exclude_renderers d3d9
|
|
#pragma target 3.0
|
|
#pragma multi_compile DOWNSAMPLE_DEPTH_MODE_MIN DOWNSAMPLE_DEPTH_MODE_MAX DOWNSAMPLE_DEPTH_MODE_CHESSBOARD
|
|
#pragma multi_compile _ FOG_VOLUME_STEREO_ON
|
|
v2fDownsample vertDepth(appdata v)
|
|
{
|
|
return vertDownsampleDepth(v, _TexelSize);
|
|
}
|
|
|
|
float4 frag(v2fDownsample input) : SV_Target
|
|
{
|
|
#ifdef FOG_VOLUME_STEREO_ON
|
|
if (RightSide == 1)
|
|
return DownsampleDepth(input, _HiResDepthBufferR);
|
|
else
|
|
return DownsampleDepth(input, _HiResDepthBuffer);
|
|
#else
|
|
return DownsampleDepth(input, _HiResDepthBuffer);
|
|
#endif
|
|
}
|
|
|
|
ENDCG
|
|
}
|
|
|
|
// pass 1 - bilateral upsample
|
|
Pass
|
|
{
|
|
// Name "bilateral upsample"
|
|
Blend One Zero
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vertUpsampleToFull
|
|
#pragma fragment frag
|
|
#pragma exclude_renderers d3d9
|
|
#pragma target 3.0
|
|
#pragma shader_feature VISUALIZE_EDGE
|
|
#pragma multi_compile _ FOG_VOLUME_STEREO_ON
|
|
|
|
v2fUpsample vertUpsampleToFull(appdata v)
|
|
{
|
|
return vertUpsample(v, _TexelSize);
|
|
}
|
|
float4 frag(v2fUpsample input) : SV_Target
|
|
{
|
|
float4 c = 0;
|
|
//#ifdef FOG_VOLUME_STEREO_ON
|
|
if (RightSide==0)
|
|
c = BilateralUpsample(input, _HiResDepthBuffer, _LowResDepthBuffer, _LowResColor);
|
|
//c = float4(1, 0, 0, 1);
|
|
else
|
|
c = BilateralUpsample(input, _HiResDepthBufferR, _LowResDepthBufferR, _LowResColorR);
|
|
//c = float4(0, 1, 0, 1);
|
|
//#else
|
|
//c = BilateralUpsample(input, _HiResDepthBuffer, _LowResDepthBuffer, _LowResColor);
|
|
//#endif
|
|
return c;
|
|
}
|
|
|
|
ENDCG
|
|
}
|
|
}
|
|
}
|