add weather and time
This commit is contained in:
@@ -0,0 +1,812 @@
|
||||
// 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.
|
||||
|
||||
|
||||
|
||||
Shader "Hidden/EnviroBlur"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
//_MainTex("Texture", any) = "" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
CGINCLUDE
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Downsample, bilateral blur and upsample config
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// method used to downsample depth buffer: 0 = min; 1 = max; 2 = min/max in chessboard pattern
|
||||
#define DOWNSAMPLE_DEPTH_MODE 2
|
||||
#define UPSAMPLE_DEPTH_THRESHOLD 1.5f
|
||||
#define BLUR_DEPTH_FACTOR 0.5
|
||||
#define GAUSS_BLUR_DEVIATION 1.5
|
||||
#define FULL_RES_BLUR_KERNEL_SIZE 7
|
||||
#define HALF_RES_BLUR_KERNEL_SIZE 5
|
||||
#define QUARTER_RES_BLUR_KERNEL_SIZE 6
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
#define PI 3.1415927f
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
|
||||
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
UNITY_DECLARE_TEX2DARRAY(_CameraDepthTexture);
|
||||
UNITY_DECLARE_TEX2DARRAY(_HalfResDepthBuffer);
|
||||
UNITY_DECLARE_TEX2DARRAY(_QuarterResDepthBuffer);
|
||||
UNITY_DECLARE_TEX2DARRAY(_HalfResColor);
|
||||
UNITY_DECLARE_TEX2DARRAY(_QuarterResColor);
|
||||
UNITY_DECLARE_TEX2DARRAY(_MainTex);
|
||||
#else
|
||||
UNITY_DECLARE_TEX2D(_CameraDepthTexture);
|
||||
UNITY_DECLARE_TEX2D(_HalfResDepthBuffer);
|
||||
UNITY_DECLARE_TEX2D(_QuarterResDepthBuffer);
|
||||
UNITY_DECLARE_TEX2D(_HalfResColor);
|
||||
UNITY_DECLARE_TEX2D(_QuarterResColor);
|
||||
UNITY_DECLARE_TEX2D(_MainTex);
|
||||
#endif
|
||||
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
float4 _CameraDepthTexture_TexelSize;
|
||||
float4 _HalfResDepthBuffer_TexelSize;
|
||||
float4 _QuarterResDepthBuffer_TexelSize;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
struct v2fDownsample
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float2 uv : TEXCOORD0;
|
||||
#else
|
||||
float2 uv00 : TEXCOORD0;
|
||||
float2 uv01 : TEXCOORD1;
|
||||
float2 uv10 : TEXCOORD2;
|
||||
float2 uv11 : TEXCOORD3;
|
||||
#endif
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
struct v2fUpsample
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv00 : TEXCOORD1;
|
||||
float2 uv01 : TEXCOORD2;
|
||||
float2 uv10 : TEXCOORD3;
|
||||
float2 uv11 : TEXCOORD4;
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(ENVIROURP)
|
||||
o.vertex = float4(v.vertex.xyz,1.0);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.vertex.y *= -1;
|
||||
#endif
|
||||
#else
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
#endif
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// vertDownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
v2fDownsample vertDownsampleDepth(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fDownsample o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2fDownsample, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(ENVIROURP)
|
||||
o.vertex = float4(v.vertex.xyz,1.0);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.vertex.y *= -1;
|
||||
#endif
|
||||
#else
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
#endif
|
||||
#if SHADER_TARGET > 40
|
||||
o.uv = v.uv;
|
||||
#else
|
||||
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;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// vertUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
v2fUpsample vertUpsample(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fUpsample o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2fUpsample, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(ENVIROURP)
|
||||
o.vertex = float4(v.vertex.xyz,1.0);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.vertex.y *= -1;
|
||||
#endif
|
||||
#else
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
#endif
|
||||
o.uv = v.uv;
|
||||
|
||||
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;
|
||||
}
|
||||
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
|
||||
float4 SampleTexture(Texture2DArray tex, SamplerState samplerState, float2 uv)
|
||||
{
|
||||
//return UNITY_SAMPLE_TEX2DARRAY(tex, float3((uv).xy, (float)unity_StereoEyeIndex));
|
||||
|
||||
|
||||
//return UNITY_SAMPLE_TEX2DARRAY_SAMPLER(tex,samplerState,uv);
|
||||
return tex.Sample(samplerState, float3((uv).xy, (float)unity_StereoEyeIndex));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralUpsample(v2fUpsample input, Texture2DArray hiDepth, Texture2DArray loDepth, Texture2DArray loColor, SamplerState linearSampler, SamplerState pointSampler)
|
||||
{
|
||||
const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
|
||||
// float4 highResDepth = LinearEyeDepth(hiDepth.Sample(pointSampler, input.uv)).xxxx;
|
||||
float4 highResDepth = LinearEyeDepth(SampleTexture(hiDepth, pointSampler, input.uv)).xxxx;
|
||||
|
||||
float4 lowResDepth;
|
||||
|
||||
lowResDepth[0] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv00));
|
||||
lowResDepth[1] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv10));
|
||||
lowResDepth[2] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv01));
|
||||
lowResDepth[3] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv11));
|
||||
|
||||
float4 depthDiff = abs(lowResDepth - highResDepth);
|
||||
|
||||
float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
|
||||
|
||||
[branch]
|
||||
if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
|
||||
{
|
||||
return SampleTexture(loColor,linearSampler,input.uv);
|
||||
}
|
||||
|
||||
// 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 SampleTexture(loColor,pointSampler,nearestUv);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// DownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float DownsampleDepth(v2fDownsample input, Texture2DArray depthTexture, SamplerState depthSampler)
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float4 depth = depthTexture.Gather(depthSampler, input.uv);
|
||||
#else
|
||||
float4 depth;
|
||||
depth.x = SampleTexture(depthTexture,depthSampler,input.uv00).x;
|
||||
depth.y = SampleTexture(depthTexture,depthSampler,input.uv01).x;
|
||||
depth.z = SampleTexture(depthTexture,depthSampler,input.uv10).x;
|
||||
depth.w = SampleTexture(depthTexture,depthSampler,input.uv11).x;
|
||||
|
||||
#endif
|
||||
|
||||
#if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
|
||||
return min(min(depth.x, depth.y), min(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
|
||||
return max(max(depth.x, depth.y), max(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
|
||||
|
||||
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;
|
||||
return index == 1 ? minDepth : maxDepth;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GaussianWeight
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GaussianWeight(float offset, float deviation)
|
||||
{
|
||||
float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
|
||||
weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
|
||||
return weight;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralBlur
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralBlur(v2f input, int2 direction, Texture2DArray depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
|
||||
{
|
||||
//const float deviation = kernelRadius / 2.5;
|
||||
const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
|
||||
|
||||
float2 uv = input.uv;
|
||||
float4 centerColor = SampleTexture(_MainTex,sampler_MainTex,uv);
|
||||
|
||||
float3 color = centerColor.xyz;
|
||||
//return float4(color, 1);
|
||||
|
||||
float centerDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,uv));
|
||||
|
||||
float weightSum = 0;
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
float weight = GaussianWeight(0, deviation);
|
||||
color *= weight;
|
||||
weightSum += weight;
|
||||
|
||||
[unroll] for (int i = -kernelRadius; i < 0; i += 1)
|
||||
{
|
||||
float2 offset = (direction * i);
|
||||
|
||||
float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy).rgb;
|
||||
float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy));
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(i, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
[unroll] for (int k = 1; k <= kernelRadius; k += 1)
|
||||
{
|
||||
float2 offset = (direction * k);
|
||||
|
||||
float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy).rgb;
|
||||
float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy));
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(k, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
color /= weightSum;
|
||||
return float4(color, centerColor.w);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
float4 SampleTexture(Texture2D tex, SamplerState samplerState, float2 uv)
|
||||
{
|
||||
return tex.Sample(samplerState,uv);
|
||||
}
|
||||
|
||||
float4 SampleTexture(Texture2D tex, SamplerState samplerState, float2 uv, float2 offset)
|
||||
{
|
||||
return tex.Sample(samplerState,uv,offset);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralUpsample(v2fUpsample input, Texture2D hiDepth, Texture2D loDepth, Texture2D loColor, SamplerState linearSampler, SamplerState pointSampler)
|
||||
{
|
||||
float4 result = float4(0,0,0,0);
|
||||
const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
|
||||
// float4 highResDepth = LinearEyeDepth(hiDepth.Sample(pointSampler, input.uv)).xxxx;
|
||||
float4 highResDepth = LinearEyeDepth(SampleTexture(hiDepth, pointSampler, input.uv)).xxxx;
|
||||
|
||||
float4 lowResDepth;
|
||||
|
||||
lowResDepth[0] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv00));
|
||||
lowResDepth[1] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv10));
|
||||
lowResDepth[2] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv01));
|
||||
lowResDepth[3] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv11));
|
||||
|
||||
float4 depthDiff = abs(lowResDepth - highResDepth);
|
||||
|
||||
float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
|
||||
|
||||
[branch]
|
||||
if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
|
||||
{
|
||||
result = SampleTexture(loColor,linearSampler,input.uv);
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
result = SampleTexture(loColor,pointSampler,nearestUv);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// DownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float DownsampleDepth(v2fDownsample input, Texture2D depthTexture, SamplerState depthSampler)
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float4 depth = depthTexture.Gather(depthSampler, input.uv);
|
||||
#else
|
||||
float4 depth;
|
||||
depth.x = SampleTexture(depthTexture,depthSampler,input.uv00).x;
|
||||
depth.y = SampleTexture(depthTexture,depthSampler,input.uv01).x;
|
||||
depth.z = SampleTexture(depthTexture,depthSampler,input.uv10).x;
|
||||
depth.w = SampleTexture(depthTexture,depthSampler,input.uv11).x;
|
||||
|
||||
#endif
|
||||
|
||||
#if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
|
||||
return min(min(depth.x, depth.y), min(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
|
||||
return max(max(depth.x, depth.y), max(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
|
||||
|
||||
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;
|
||||
return index == 1 ? minDepth : maxDepth;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GaussianWeight
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GaussianWeight(float offset, float deviation)
|
||||
{
|
||||
float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
|
||||
weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
|
||||
return weight;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralBlur
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralBlur(v2f input, int2 direction, Texture2D depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
|
||||
{
|
||||
//const float deviation = kernelRadius / 2.5;
|
||||
const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
|
||||
|
||||
float2 uv = input.uv;
|
||||
float4 centerColor = SampleTexture(_MainTex,sampler_MainTex,uv);
|
||||
|
||||
float4 color = centerColor;
|
||||
//return float4(color, 1);
|
||||
|
||||
float centerDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,uv));
|
||||
|
||||
float weightSum = 0;
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
float weight = GaussianWeight(0, deviation);
|
||||
color *= weight;
|
||||
weightSum += weight;
|
||||
|
||||
[unroll] for (int i = -kernelRadius; i < 0; i += 1)
|
||||
{
|
||||
float2 offset = (direction * i);
|
||||
|
||||
float4 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv,offset);
|
||||
float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv, offset).x);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(i, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
[unroll] for (int k = 1; k <= kernelRadius; k += 1)
|
||||
{
|
||||
float2 offset = (direction * k);
|
||||
|
||||
float4 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv,offset);
|
||||
float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,input.uv,offset).x);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(k, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
color /= weightSum;
|
||||
return float4(color);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ENDCG
|
||||
|
||||
// pass 0 - horizontal blur (hires)
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize.xy);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 1 - vertical blur (hires)
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
return BilateralBlur(input, int2(0, 1), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 2 - horizontal blur (lores)
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 3 - vertical blur (lores)
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(0, 1), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 4 - downsample depth to half
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertHalfDepth
|
||||
#pragma fragment frag
|
||||
// #pragma target gl4.1
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fDownsample vertHalfDepth(appdata v)
|
||||
{
|
||||
return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
|
||||
return float4(depth,depth,depth,depth);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 5 - bilateral upsample
|
||||
Pass
|
||||
{
|
||||
|
||||
Blend One Zero
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertUpsampleToFull
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fUpsample vertUpsampleToFull(appdata v)
|
||||
{
|
||||
return vertUpsample(v, _HalfResDepthBuffer_TexelSize);
|
||||
}
|
||||
float4 frag(v2fUpsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralUpsample(input, _CameraDepthTexture, _HalfResDepthBuffer, _HalfResColor, sampler_HalfResColor, sampler_HalfResDepthBuffer);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 6 - downsample depth to quarter
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertQuarterDepth
|
||||
#pragma fragment frag
|
||||
//#pragma target gl4.1
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fDownsample vertQuarterDepth(appdata v)
|
||||
{
|
||||
return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
|
||||
return float4(depth,depth,depth,depth);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 7 - bilateral upsample quarter to full
|
||||
Pass
|
||||
{
|
||||
Blend One Zero
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertUpsampleToFull
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fUpsample vertUpsampleToFull(appdata v)
|
||||
{
|
||||
return vertUpsample(v, _QuarterResDepthBuffer_TexelSize);
|
||||
}
|
||||
float4 frag(v2fUpsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralUpsample(input, _CameraDepthTexture, _QuarterResDepthBuffer, _QuarterResColor, sampler_QuarterResColor, sampler_QuarterResDepthBuffer);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 8 - horizontal blur (quarter res)
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 9 - vertical blur (quarter res)
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
fixed4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(0, 1), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 10 - downsample depth to half (fallback for DX10)
|
||||
Pass
|
||||
{
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertHalfDepth
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fDownsample vertHalfDepth(appdata v)
|
||||
{
|
||||
return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
|
||||
|
||||
return float4(depth,depth,depth,depth);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 11 - downsample depth to quarter (fallback for DX10)
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vertQuarterDepth
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
v2fDownsample vertQuarterDepth(appdata v)
|
||||
{
|
||||
return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
|
||||
|
||||
return float4(depth,depth,depth,depth);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1575a50566010d44dab58feb9714c69a
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.1.2
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroBilateralBlur.shader
|
||||
uploadId: 660896
|
||||
@@ -0,0 +1,917 @@
|
||||
// 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.
|
||||
|
||||
|
||||
|
||||
Shader "Hidden/EnviroBlurURP"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex("Texture", any) = "" {}
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
HLSLINCLUDE
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Downsample, bilateral blur and upsample config
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// method used to downsample depth buffer: 0 = min; 1 = max; 2 = min/max in chessboard pattern
|
||||
#define DOWNSAMPLE_DEPTH_MODE 2
|
||||
#define UPSAMPLE_DEPTH_THRESHOLD 1.5f
|
||||
#define BLUR_DEPTH_FACTOR 0.5
|
||||
#define GAUSS_BLUR_DEVIATION 1.5
|
||||
#define FULL_RES_BLUR_KERNEL_SIZE 7
|
||||
#define HALF_RES_BLUR_KERNEL_SIZE 5
|
||||
#define QUARTER_RES_BLUR_KERNEL_SIZE 6
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
//#define PI 3.1415927f
|
||||
|
||||
#if ENVIROURP17
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
|
||||
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
|
||||
SAMPLER(sampler_CameraDepthTexture);
|
||||
TEXTURE2D_X_FLOAT(_HalfResDepthBuffer);
|
||||
SAMPLER(sampler_HalfResDepthBuffer);
|
||||
TEXTURE2D_X_FLOAT(_QuarterResDepthBuffer);
|
||||
SAMPLER(sampler_QuarterResDepthBuffer);
|
||||
TEXTURE2D_X(_HalfResColor);
|
||||
SAMPLER(sampler_HalfResColor);
|
||||
TEXTURE2D_X(_QuarterResColor);
|
||||
SAMPLER(sampler_QuarterResColor);
|
||||
TEXTURE2D_X(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
float4 _CameraDepthTexture_TexelSize;
|
||||
float4 _HalfResDepthBuffer_TexelSize;
|
||||
float4 _QuarterResDepthBuffer_TexelSize;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
uint vertex : SV_VertexID;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
struct v2fDownsample
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float2 uv : TEXCOORD0;
|
||||
#else
|
||||
float2 uv00 : TEXCOORD0;
|
||||
float2 uv01 : TEXCOORD1;
|
||||
float2 uv10 : TEXCOORD2;
|
||||
float2 uv11 : TEXCOORD3;
|
||||
#endif
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
struct v2fUpsample
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv00 : TEXCOORD1;
|
||||
float2 uv01 : TEXCOORD2;
|
||||
float2 uv10 : TEXCOORD3;
|
||||
float2 uv11 : TEXCOORD4;
|
||||
float4 vertex : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(v.vertex);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(v.vertex);
|
||||
|
||||
o.vertex = pos;
|
||||
o.uv = DYNAMIC_SCALING_APPLY_SCALEBIAS(uv);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// vertDownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
v2fDownsample vertDownsampleDepth(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fDownsample o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(v.vertex);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(v.vertex);
|
||||
|
||||
o.vertex = pos;
|
||||
|
||||
#if SHADER_TARGET > 40
|
||||
o.uv = DYNAMIC_SCALING_APPLY_SCALEBIAS(uv);
|
||||
#else
|
||||
o.uv00 = DYNAMIC_SCALING_APPLY_SCALEBIAS(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;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// vertUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
v2fUpsample vertUpsample(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fUpsample o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(v.vertex);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(v.vertex);
|
||||
|
||||
o.vertex = pos;
|
||||
o.uv = DYNAMIC_SCALING_APPLY_SCALEBIAS(uv);
|
||||
|
||||
o.uv00 = DYNAMIC_SCALING_APPLY_SCALEBIAS(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;
|
||||
}
|
||||
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralUpsample(v2fUpsample input, Texture2DArray hiDepth, Texture2DArray loDepth, Texture2DArray loColor, SamplerState linearSampler, SamplerState pointSampler)
|
||||
{
|
||||
float4 result = float4(0,0,0,0);
|
||||
const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
|
||||
float4 highResDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(hiDepth, pointSampler, input.uv), _ZBufferParams).xxxx;
|
||||
|
||||
float4 lowResDepth;
|
||||
|
||||
lowResDepth[0] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv00), _ZBufferParams);
|
||||
lowResDepth[1] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv10), _ZBufferParams);
|
||||
lowResDepth[2] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv01), _ZBufferParams);
|
||||
lowResDepth[3] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv11), _ZBufferParams);
|
||||
|
||||
float4 depthDiff = abs(lowResDepth - highResDepth);
|
||||
|
||||
float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
|
||||
|
||||
[branch]
|
||||
if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
|
||||
{
|
||||
result = SAMPLE_TEXTURE2D_X(loColor,linearSampler,input.uv);
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
result = SAMPLE_TEXTURE2D_X(loColor,pointSampler,nearestUv);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// DownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float DownsampleDepth(v2fDownsample input, Texture2DArray depthTexture, SamplerState depthSampler)
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float4 depth = depthTexture.Gather(depthSampler, input.uv);
|
||||
#else
|
||||
float4 depth;
|
||||
depth.x = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv00).x;
|
||||
depth.y = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv01).x;
|
||||
depth.z = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv10).x;
|
||||
depth.w = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv11).x;
|
||||
|
||||
#endif
|
||||
|
||||
#if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
|
||||
return min(min(depth.x, depth.y), min(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
|
||||
return max(max(depth.x, depth.y), max(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
|
||||
|
||||
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;
|
||||
return index == 1 ? minDepth : maxDepth;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GaussianWeight
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GaussianWeight(float offset, float deviation)
|
||||
{
|
||||
float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
|
||||
weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
|
||||
return weight;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralBlur
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralBlur(v2f input, int2 direction, Texture2DArray depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
|
||||
{
|
||||
//const float deviation = kernelRadius / 2.5;
|
||||
const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
|
||||
|
||||
float2 uv = input.uv;
|
||||
float4 centerColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,uv );
|
||||
|
||||
float4 color = centerColor;
|
||||
//return float4(color, 1);
|
||||
|
||||
float centerDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler,uv), _ZBufferParams);
|
||||
|
||||
float weightSum = 0;
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
float weight = GaussianWeight(0, deviation);
|
||||
color *= weight;
|
||||
weightSum += weight;
|
||||
|
||||
[unroll] for (int i = -kernelRadius; i < 0; i += 1)
|
||||
{
|
||||
float2 offset = (direction * i);
|
||||
|
||||
float4 sampleColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy);
|
||||
float sampleDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy).x, _ZBufferParams);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(i, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
[unroll] for (int k = 1; k <= kernelRadius; k += 1)
|
||||
{
|
||||
float2 offset = (direction * k);
|
||||
|
||||
float4 sampleColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy );
|
||||
float sampleDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler,input.uv + offset * _MainTex_TexelSize.xy ).x , _ZBufferParams);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(k, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
color /= weightSum;
|
||||
return float4(color);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralUpsample
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralUpsample(v2fUpsample input, Texture2D hiDepth, Texture2D loDepth, Texture2D loColor, SamplerState linearSampler, SamplerState pointSampler)
|
||||
{
|
||||
const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
|
||||
float4 highResDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(hiDepth, pointSampler, input.uv), _ZBufferParams).xxxx;
|
||||
|
||||
float4 lowResDepth;
|
||||
|
||||
lowResDepth[0] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv00), _ZBufferParams);
|
||||
lowResDepth[1] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv10), _ZBufferParams);
|
||||
lowResDepth[2] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv01), _ZBufferParams);
|
||||
lowResDepth[3] = LinearEyeDepth(SAMPLE_TEXTURE2D_X(loDepth, pointSampler, input.uv11), _ZBufferParams);
|
||||
|
||||
float4 depthDiff = abs(lowResDepth - highResDepth);
|
||||
|
||||
float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
|
||||
|
||||
[branch]
|
||||
if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
|
||||
{
|
||||
return SAMPLE_TEXTURE2D_X(loColor,linearSampler,input.uv);
|
||||
}
|
||||
|
||||
// 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 SAMPLE_TEXTURE2D_X(loColor,pointSampler,nearestUv);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// DownsampleDepth
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float DownsampleDepth(v2fDownsample input, Texture2D depthTexture, SamplerState depthSampler)
|
||||
{
|
||||
#if SHADER_TARGET > 40
|
||||
float4 depth = depthTexture.Gather(depthSampler, input.uv);
|
||||
#else
|
||||
float4 depth;
|
||||
depth.x = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv00).x;
|
||||
depth.y = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv01).x;
|
||||
depth.z = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv10).x;
|
||||
depth.w = SAMPLE_TEXTURE2D_X(depthTexture,depthSampler,input.uv11).x;
|
||||
|
||||
#endif
|
||||
|
||||
#if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
|
||||
return min(min(depth.x, depth.y), min(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
|
||||
return max(max(depth.x, depth.y), max(depth.z, depth.w));
|
||||
#elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
|
||||
|
||||
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;
|
||||
return index == 1 ? minDepth : maxDepth;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GaussianWeight
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GaussianWeight(float offset, float deviation)
|
||||
{
|
||||
float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
|
||||
weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
|
||||
return weight;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// BilateralBlur
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float4 BilateralBlur(v2f input, int2 direction, Texture2D depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
|
||||
{
|
||||
//const float deviation = kernelRadius / 2.5;
|
||||
const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
|
||||
|
||||
float2 uv = input.uv;
|
||||
float4 centerColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,uv );
|
||||
|
||||
float4 color = centerColor;
|
||||
//return float4(color, 1);
|
||||
|
||||
float centerDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler,uv), _ZBufferParams);
|
||||
|
||||
float weightSum = 0;
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
float weight = GaussianWeight(0, deviation);
|
||||
color *= weight;
|
||||
weightSum += weight;
|
||||
|
||||
[unroll] for (int i = -kernelRadius; i < 0; i += 1)
|
||||
{
|
||||
float2 offset = (direction * i);
|
||||
|
||||
float4 sampleColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy);
|
||||
float sampleDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy).x, _ZBufferParams);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(i, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
[unroll] for (int k = 1; k <= kernelRadius; k += 1)
|
||||
{
|
||||
float2 offset = (direction * k);
|
||||
|
||||
float4 sampleColor = SAMPLE_TEXTURE2D_X(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy );
|
||||
float sampleDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_X(depth,depthSampler,input.uv + offset * _MainTex_TexelSize.xy ).x , _ZBufferParams);
|
||||
|
||||
float depthDiff = abs(centerDepth - sampleDepth);
|
||||
float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
|
||||
float w = exp(-(dFactor * dFactor));
|
||||
|
||||
// gaussian weight is computed from constants only -> will be computed in compile time
|
||||
weight = GaussianWeight(k, deviation) * w;
|
||||
|
||||
color += weight * sampleColor;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
color /= weightSum;
|
||||
return float4(color);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
struct v2fDownsample
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
struct v2fUpsample
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
v2fUpsample vertUpsample(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fUpsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
v2fDownsample vertDownsampleDepth(appdata v, float2 texelSize)
|
||||
{
|
||||
v2fDownsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ENDHLSL
|
||||
|
||||
// pass 0 - horizontal blur (hires)
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize.xy);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 1 - vertical blur (hires)
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(0, 1), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 2 - horizontal blur (lores)
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 3 - vertical blur (lores)
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(0, 1), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 4 - downsample depth to half
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertHalfDepth
|
||||
#pragma fragment frag
|
||||
// #pragma target gl4.1
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fDownsample vertHalfDepth(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
|
||||
#else
|
||||
v2fDownsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
|
||||
return float4(depth,depth,depth,depth);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 5 - bilateral upsample
|
||||
Pass
|
||||
{
|
||||
|
||||
Blend One Zero
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertUpsampleToFull
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fUpsample vertUpsampleToFull(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertUpsample(v, _HalfResDepthBuffer_TexelSize);
|
||||
#else
|
||||
v2fUpsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
float4 frag(v2fUpsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralUpsample(input, _CameraDepthTexture, _HalfResDepthBuffer, _HalfResColor, sampler_HalfResColor, sampler_HalfResDepthBuffer);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 6 - downsample depth to quarter
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertQuarterDepth
|
||||
#pragma fragment frag
|
||||
//#pragma target gl4.1
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fDownsample vertQuarterDepth(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
|
||||
#else
|
||||
v2fDownsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
|
||||
return float4(depth,depth,depth,depth);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 7 - bilateral upsample quarter to full
|
||||
Pass
|
||||
{
|
||||
Blend One Zero
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertUpsampleToFull
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fUpsample vertUpsampleToFull(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertUpsample(v, _QuarterResDepthBuffer_TexelSize);
|
||||
#else
|
||||
v2fUpsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
float4 frag(v2fUpsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralUpsample(input, _CameraDepthTexture, _QuarterResDepthBuffer, _QuarterResColor, sampler_QuarterResColor, sampler_QuarterResDepthBuffer);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 8 - horizontal blur (quarter res)
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment horizontalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 horizontalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(1, 0), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 9 - vertical blur (quarter res)
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment verticalFrag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
float4 verticalFrag(v2f input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
return BilateralBlur(input, int2(0, 1), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 10 - downsample depth to half (fallback for DX10)
|
||||
Pass
|
||||
{
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertHalfDepth
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fDownsample vertHalfDepth(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
|
||||
#else
|
||||
v2fDownsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
|
||||
return float4(depth,depth,depth,depth);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// pass 11 - downsample depth to quarter (fallback for DX10)
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertQuarterDepth
|
||||
#pragma fragment frag
|
||||
#pragma target 3.5
|
||||
#pragma exclude_renderers gles
|
||||
#pragma multi_compile __ ENVIROURP17
|
||||
|
||||
v2fDownsample vertQuarterDepth(appdata v)
|
||||
{
|
||||
#if ENVIROURP17
|
||||
return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
|
||||
#else
|
||||
v2fDownsample o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
#endif
|
||||
}
|
||||
|
||||
float4 frag(v2fDownsample input) : SV_Target
|
||||
{
|
||||
#if ENVIROURP17
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
|
||||
return float4(depth,depth,depth,depth);
|
||||
#else
|
||||
return float4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32fd70cd087662643831919acaa533c2
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures:
|
||||
- _MainTex: {instanceID: 0}
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.1.4
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroBilateralBlurURP.shader
|
||||
uploadId: 673787
|
||||
@@ -0,0 +1,111 @@
|
||||
Shader "Hidden/EnviroHeightFog"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
//_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
#pragma multi_compile __ UNITY_COLORSPACE_GAMMA
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include_with_pragmas "../Includes/FogInclude.cginc"
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
float3 ray : TEXCOORD1;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(ENVIROURP)
|
||||
o.position = float4(v.vertex.xyz,1.0);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.position.y *= -1;
|
||||
#endif
|
||||
#else
|
||||
o.position = UnityObjectToClipPos(v.vertex);
|
||||
#endif
|
||||
|
||||
o.uv = v.texcoord;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
|
||||
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
|
||||
|
||||
void InverseProjectDepth (float depth, float2 texcoord, out float3 worldPos)
|
||||
{
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
#if !UNITY_UV_STARTS_AT_TOP
|
||||
//texcoord.y = 1 - texcoord.y;
|
||||
#endif
|
||||
|
||||
float2 uvClip = texcoord * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
worldPos = mul(eyeToWorld, viewPos).xyz;
|
||||
}
|
||||
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
|
||||
float linearDepth = Linear01Depth(depth);
|
||||
|
||||
float3 worldPos;
|
||||
InverseProjectDepth(depth, i.uv.xy, worldPos);
|
||||
|
||||
float4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv);
|
||||
float4 fog = GetExponentialHeightFog(worldPos,linearDepth);
|
||||
//this is not correct but LinearToGamma does produce even worse results..
|
||||
#if defined(UNITY_COLORSPACE_GAMMA)
|
||||
fog.rgb *= 1.5;
|
||||
#endif
|
||||
|
||||
float3 final = ApplyVolumetricLights(fog,col.rgb, i.uv);
|
||||
|
||||
return float4(final.rgb,col.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f1a7a03afe5374439810ec3993fb6ac
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.1.2
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroHeightFog.shader
|
||||
uploadId: 660896
|
||||
@@ -0,0 +1,163 @@
|
||||
Shader "Hidden/EnviroHeightFogHDRP"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
//_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 4.5
|
||||
#pragma multi_compile __ ENVIROHDRP
|
||||
|
||||
#if defined (ENVIROHDRP)
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUtils.hlsl"
|
||||
#include_with_pragmas "../Includes/FogIncludeHLSL.hlsl"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
uint vertexID : SV_VertexID;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
float3 ray : TEXCOORD1;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
o.position = GetFullScreenTriangleVertexPosition(v.vertexID);
|
||||
o.uv = GetFullScreenTriangleTexCoord(v.vertexID);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
float3 color, opacity;
|
||||
|
||||
float _EnviroSkyIntensity;
|
||||
|
||||
TEXTURE2D_X(_MainTex);
|
||||
|
||||
void InverseProjectDepth (float depth, float2 texcoord, out float3 worldPos)
|
||||
{
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
#if !UNITY_UV_STARTS_AT_TOP
|
||||
texcoord.y = 1 - texcoord.y;
|
||||
#endif
|
||||
|
||||
float2 uvClip = texcoord * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
worldPos = mul(eyeToWorld, viewPos).xyz;
|
||||
//viewDir = worldPos - _CameraPosition.xyz;
|
||||
//dist = length(viewDir);
|
||||
//viewDir /= dist;
|
||||
}
|
||||
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
float depth = LOAD_TEXTURE2D_X_LOD(_CameraDepthTexture, i.uv * _ScreenSize.xy * (1/_RTHandleScale.xy), 0).r;
|
||||
float linearDepth = Linear01Depth(depth, _ZBufferParams);
|
||||
|
||||
float3 worldPos;
|
||||
InverseProjectDepth(depth, i.uv.xy * (1/_RTHandleScale.xy), worldPos);
|
||||
|
||||
float4 fog = GetExponentialHeightFog(worldPos,linearDepth);
|
||||
fog.rgb *= _EnviroSkyIntensity * GetCurrentExposureMultiplier();
|
||||
|
||||
//HDRP Fog
|
||||
//float3 V = GetSkyViewDirWS(i.uv.xy * _ScreenSize.xy * (1/_RTHandleScale.xy));
|
||||
//PositionInputs posInput = GetPositionInput(i.position.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
|
||||
//posInput.positionWS = GetCurrentViewPosition() - V * _MaxFogDistance;
|
||||
//EvaluateAtmosphericScattering(posInput, V, color, opacity);
|
||||
//fog.rgb = color + (1 - opacity) * fog.rgb;
|
||||
|
||||
|
||||
float4 col = SAMPLE_TEXTURE2D_X_LOD(_MainTex,s_trilinear_clamp_sampler, i.uv, 0);
|
||||
|
||||
//float4 volumetrics = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_EnviroVolumetricFogTex, i.uv);
|
||||
//col.rgb = col.rgb * fog.a + fog.rgb * max(volumetrics.rgb,0.75);
|
||||
|
||||
col.rgb = col.rgb * fog.a + fog.rgb;
|
||||
return col;
|
||||
}
|
||||
#else
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv);
|
||||
// just invert the colors
|
||||
col.rgb = 1 - col.rgb;
|
||||
return col;
|
||||
}
|
||||
#endif
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05a94bc890a932e4c96dc05c6427e9d9
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.1.2
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroHeightFogHDRP.shader
|
||||
uploadId: 660896
|
||||
@@ -0,0 +1,148 @@
|
||||
Shader "Hidden/EnviroHeightFogURP"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile __ UNITY_COLORSPACE_GAMMA
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
|
||||
#if defined (ENVIROURP)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
#include_with_pragmas "../Includes/FogIncludeHLSL.hlsl"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
uint vertex : SV_VertexID;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(v.vertex);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(v.vertex);
|
||||
|
||||
o.position = pos;
|
||||
o.uv = DYNAMIC_SCALING_APPLY_SCALEBIAS(uv);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
TEXTURE2D_X(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
|
||||
SAMPLER (sampler_CameraDepthTexture);
|
||||
|
||||
void InverseProjectDepth (float depth, float2 texcoord, out float3 worldPos)
|
||||
{
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
#if !UNITY_UV_STARTS_AT_TOP
|
||||
//texcoord.y = 1 - texcoord.y;
|
||||
#endif
|
||||
|
||||
float2 uvClip = texcoord * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
worldPos = mul(eyeToWorld, viewPos).xyz;
|
||||
}
|
||||
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture,sampler_CameraDepthTexture, i.uv);
|
||||
float linearDepth = Linear01Depth(depth, _ZBufferParams);
|
||||
|
||||
float3 worldPos;
|
||||
InverseProjectDepth(depth, i.uv.xy, worldPos);
|
||||
|
||||
float4 col = SAMPLE_TEXTURE2D_X(_MainTex, sampler_MainTex, i.uv);
|
||||
float4 fog = GetExponentialHeightFog(worldPos,linearDepth);
|
||||
//this is not correct but LinearToGamma does produce even worse results..
|
||||
#if defined(UNITY_COLORSPACE_GAMMA)
|
||||
fog.rgb *= 1.5;
|
||||
#endif
|
||||
|
||||
float3 final = ApplyVolumetricLights(fog,col.rgb, i.uv);
|
||||
|
||||
return float4(final.rgb,col.a);
|
||||
}
|
||||
|
||||
#else
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv);
|
||||
// just invert the colors
|
||||
col.rgb = 1 - col.rgb;
|
||||
return col;
|
||||
}
|
||||
#endif
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29134b07a9b3ff847890a42914b2a6f4
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,395 @@
|
||||
Shader "Hidden/Volumetrics"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
sampler2D _DitherTexture;
|
||||
|
||||
UNITY_DECLARE_SHADOWMAP(_CascadeShadowMapTexture);
|
||||
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
|
||||
|
||||
/* #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
UNITY_DECLARE_TEX2DARRAY(_EnviroCloudsTex);
|
||||
#else
|
||||
sampler2D _EnviroCloudsTex;
|
||||
#endif*/
|
||||
|
||||
uniform sampler3D _NoiseTexture;
|
||||
|
||||
uniform int _Steps;
|
||||
uniform float3 _CameraPosition;
|
||||
uniform float4 _VolumetricLight;
|
||||
uniform float4 _HeightFog;
|
||||
uniform float4 _HeightParams;
|
||||
uniform float4 _NoiseData;
|
||||
uniform float3 _WindDirection;
|
||||
uniform float4 _MieG;
|
||||
uniform float _MaxRayLength;
|
||||
uniform float _MaxRayLengthLights;
|
||||
|
||||
uniform float4 _AmbientColor;
|
||||
|
||||
uniform float3 _DirLightDir;
|
||||
//uniform float4 _DirLightColor;
|
||||
|
||||
uniform float4 _Randomness;
|
||||
#if !SHADER_API_GLES3
|
||||
struct PointLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float padding;
|
||||
};
|
||||
StructuredBuffer<PointLight> _PointLights;
|
||||
float _PointLightsCount;
|
||||
|
||||
struct SpotLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float3 lightDirection;
|
||||
float lightCosHalfAngle;
|
||||
//float2 angularFalloffParameters;
|
||||
//float2 distanceFalloffParameters;
|
||||
float padding;
|
||||
};
|
||||
|
||||
StructuredBuffer<SpotLight> _SpotLights;
|
||||
float _SpotLightsCount;
|
||||
#endif
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
o.position = UnityObjectToClipPos(v.vertex);
|
||||
//o.position = v.vertex * float4(2,2,1,1) + float4(-1,-1,0,0);
|
||||
o.uv = v.texcoord;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 GetCascadeWeights_SplitSpheres(float3 wpos)
|
||||
{
|
||||
float3 fromCenter0 = wpos - unity_ShadowSplitSpheres[0].xyz;
|
||||
float3 fromCenter1 = wpos - unity_ShadowSplitSpheres[1].xyz;
|
||||
float3 fromCenter2 = wpos - unity_ShadowSplitSpheres[2].xyz;
|
||||
float3 fromCenter3 = wpos - unity_ShadowSplitSpheres[3].xyz;
|
||||
float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3));
|
||||
float4 weights = float4(distances2 >= unity_ShadowSplitSqRadii);
|
||||
return weights;
|
||||
}
|
||||
|
||||
float4 GetCascadeShadowCoord(float4 pos, float4 cascadeWeights)
|
||||
{
|
||||
return mul(unity_WorldToShadow[(int)dot(cascadeWeights, float4(1,1,1,1))], pos);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
float GetCascadeWeights_SplitSpheres(float3 positionWS)
|
||||
{
|
||||
float3 fromCenter0 = positionWS - unity_ShadowSplitSpheres[0].xyz;
|
||||
float3 fromCenter1 = positionWS - unity_ShadowSplitSpheres[1].xyz;
|
||||
float3 fromCenter2 = positionWS - unity_ShadowSplitSpheres[2].xyz;
|
||||
float3 fromCenter3 = positionWS - unity_ShadowSplitSpheres[3].xyz;
|
||||
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
|
||||
|
||||
float4 weights = float4(distances2 >= unity_ShadowSplitSqRadii);
|
||||
weights.yzw = saturate(weights.yzw - weights.xyz);
|
||||
|
||||
return float(4.0) - dot(weights, float4(4, 3, 2, 1));
|
||||
}
|
||||
|
||||
float4 GetCascadeShadowCoord(float3 positionWS, half cascadeIndex)
|
||||
{
|
||||
float4 shadowCoord = mul(unity_WorldToShadow[cascadeIndex], float4(positionWS, 1.0));
|
||||
|
||||
return float4(shadowCoord.xyz, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
float anisotropy(float costheta)
|
||||
{
|
||||
float g = _MieG.x;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float anisotropyPointSpot(float costheta)
|
||||
{
|
||||
float g = 0.8;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float Attenuation(float distNorm)
|
||||
{
|
||||
return 1.0 / (1.0 + 25.0 * distNorm);
|
||||
}
|
||||
|
||||
float DirectionalLight(float3 wpos)
|
||||
{
|
||||
float atten = 1.0f;
|
||||
|
||||
float4 cascadeWeights = GetCascadeWeights_SplitSpheres(wpos);
|
||||
bool inside = dot(cascadeWeights, float4(1, 1, 1, 1)) < 4;
|
||||
|
||||
float4 samplePos = GetCascadeShadowCoord(float4(wpos, 1), cascadeWeights);
|
||||
|
||||
float shadows = UNITY_SAMPLE_SHADOW(_CascadeShadowMapTexture, samplePos.xyz).r;
|
||||
|
||||
atten = inside ? shadows : 1.0f;
|
||||
|
||||
if(shadows > 0.0f)
|
||||
atten = 1.0f;
|
||||
|
||||
return atten;
|
||||
}
|
||||
#if !SHADER_API_GLES3
|
||||
float3 PointLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
|
||||
for (int i = 0; i < _PointLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _PointLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _PointLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
//#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _WorldSpaceCameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
//#endif
|
||||
|
||||
color += _PointLights[i].color * att;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 SpotLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
for (int i = 0; i < _SpotLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _SpotLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _SpotLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
half3 lightVector = normalize(pos - _SpotLights[i].pos);
|
||||
half cosAngle = dot(_SpotLights[i].lightDirection.xyz, lightVector);
|
||||
|
||||
half angleAttenuation = 1;
|
||||
angleAttenuation = smoothstep(_SpotLights[i].lightCosHalfAngle, lerp(1, _SpotLights[i].lightCosHalfAngle, 0.8f), cosAngle);
|
||||
angleAttenuation = pow(angleAttenuation, 2.0f);
|
||||
att *= angleAttenuation;
|
||||
|
||||
#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _CameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
#endif
|
||||
color += _SpotLights[i].color * att;
|
||||
|
||||
}
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GetDensity
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GetDensity(float3 wpos, inout float density, float depth, float3 rayDir)
|
||||
{
|
||||
density = 1.0f;
|
||||
|
||||
// #ifdef NOISE
|
||||
// float4 noise = tex3D(_NoiseTexture, frac(wpos * _NoiseData.x + float3(_Time.y * _WindDirection.x, 0, _Time.y * _WindDirection.y)));
|
||||
// float noiseFbm = (noise.g * 0.625) + (noise.b * 0.25) + (noise.a * 0.125);
|
||||
// noiseFbm = saturate(noiseFbm - _NoiseData.y);
|
||||
// density *= saturate(noiseFbm);
|
||||
// #endif
|
||||
return density;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float2 squareUV(float2 uv)
|
||||
{
|
||||
float width = _ScreenParams.x;
|
||||
float height = _ScreenParams.y;
|
||||
float scale = 1000;
|
||||
float x = uv.x * width;
|
||||
float y = uv.y * height;
|
||||
return float2 (x/scale, y/scale);
|
||||
}
|
||||
float2 WorldToScreenUV(float3 worldPos)
|
||||
{
|
||||
// Project world position into clip space
|
||||
float4 clipPos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
|
||||
|
||||
// Perspective divide
|
||||
clipPos.xyz /= clipPos.w;
|
||||
|
||||
// Convert from clip space (-1..1) to UV space (0..1)
|
||||
float2 uv = clipPos.xy * 0.5 + 0.5;
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
float4 RayMarch(float2 uv,float2 screenPos, float3 rayStart, float3 rayDir, float rayLength, float rayLengthLights, float linearDepth)
|
||||
{
|
||||
if (rayLength <= 0.01 || !all(isfinite(rayDir)))
|
||||
return float4(0, 0, 0, 0);
|
||||
|
||||
float2 interleavedPos = fmod(floor(saturate(screenPos.xy)), 8.0);
|
||||
interleavedPos = clamp(interleavedPos, 0.0, 7.999);
|
||||
|
||||
#if UNITY_SINGLE_PASS_STEREO
|
||||
float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
|
||||
interleavedPos = (interleavedPos - scaleOffset.zw) / scaleOffset.xy;
|
||||
#endif
|
||||
|
||||
float4 ditherUV = saturate(float4(interleavedPos / 8.0 + float2(0.5 / 8.0, 0.5 / 8.0),0,0));
|
||||
float offset = tex2Dlod(_DitherTexture, ditherUV).w; //+ _Randomness.xy
|
||||
|
||||
int stepCount = _Steps;
|
||||
|
||||
float stepSize = rayLength / stepCount;
|
||||
float3 step = rayDir * stepSize;
|
||||
|
||||
float stepSizeLights = rayLengthLights / stepCount;
|
||||
float3 stepLights = rayDir * stepSizeLights;
|
||||
|
||||
float3 currentPositionDithered = rayStart + step * offset;
|
||||
float3 currentPositionLightsDithered = rayStart + stepLights * offset;
|
||||
float3 currentPosition = rayStart + step;
|
||||
|
||||
float4 color = float4(0.0,0.0,0.0,0);
|
||||
float cosAngle;
|
||||
|
||||
float extinction = 0;
|
||||
float transmitance = 0;
|
||||
float ambient = 0;
|
||||
cosAngle = dot(_DirLightDir.xyz, -rayDir);
|
||||
|
||||
float ani = anisotropy(cosAngle);
|
||||
float4 lightsColor = float4(0,0,0,0);
|
||||
|
||||
[loop]
|
||||
for (int i = 0; i < stepCount; i++)
|
||||
{
|
||||
float density = GetDensity(currentPosition, density, linearDepth, rayDir);
|
||||
float2 shadowUV = WorldToScreenUV(currentPositionDithered);
|
||||
//float cloudsShadows = pow(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_EnviroCloudsTex, shadowUV).b,0.25);
|
||||
|
||||
float atten = DirectionalLight(currentPositionDithered) * 0.1 ;//* (1-cloudsShadows);
|
||||
|
||||
float scattering = _VolumetricLight.x * density;
|
||||
extinction += _VolumetricLight.y * density;
|
||||
|
||||
transmitance += atten * scattering * exp(-extinction);
|
||||
#if !SHADER_API_GLES3
|
||||
lightsColor.rgb += PointLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
lightsColor.rgb += SpotLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
#endif
|
||||
currentPosition += step;
|
||||
currentPositionDithered += step;
|
||||
currentPositionLightsDithered += stepLights;
|
||||
}
|
||||
|
||||
//color.rgb = _DirLightColor.rgb * transmitance * ani;
|
||||
color.a = transmitance * ani;
|
||||
color.rgb += lightsColor.rgb * 0.1;
|
||||
|
||||
color = max(0, color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
float2 uv = i.uv.xy;
|
||||
|
||||
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
|
||||
float linearDepth = Linear01Depth(depth);
|
||||
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
//bit of matrix math to take the screen space coord (u,v,depth) and transform to world space
|
||||
float2 uvClip = i.uv * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
float3 wpos = mul(eyeToWorld, viewPos).xyz;
|
||||
|
||||
float3 rayStart = _WorldSpaceCameraPos;
|
||||
float3 rayDir = wpos - _WorldSpaceCameraPos;
|
||||
//rayDir *= linearDepth;
|
||||
|
||||
float rayLength = length(rayDir);
|
||||
rayDir /= rayLength;
|
||||
|
||||
float rayLengthLights = min(rayLength, _MaxRayLengthLights);
|
||||
rayLength = min(rayLength, _MaxRayLength);
|
||||
|
||||
float4 color = RayMarch(uv, i.position.xy, rayStart, rayDir, rayLength, rayLengthLights, linearDepth);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1104191b0e8adc746b7bb747e1ea1a87
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.2.2
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroVolumetrics.shader
|
||||
uploadId: 766468
|
||||
@@ -0,0 +1,406 @@
|
||||
Shader "Hidden/VolumetricsURP"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
//_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma multi_compile __ ENVIROURP
|
||||
#pragma shader_feature_local __ ENVIROURP17
|
||||
|
||||
#if defined (ENVIROURP)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
#if defined (ENVIROURP17)
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
#endif
|
||||
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
sampler2D _DitherTexture;
|
||||
|
||||
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
|
||||
SAMPLER(sampler_CameraDepthTexture);
|
||||
|
||||
uniform sampler3D _NoiseTexture;
|
||||
|
||||
uniform int _Steps;
|
||||
uniform float3 _CameraPosition;
|
||||
uniform float4 _VolumetricLight;
|
||||
uniform float4 _HeightFog;
|
||||
uniform float4 _HeightParams;
|
||||
uniform float4 _NoiseData;
|
||||
uniform float3 _WindDirection;
|
||||
uniform float4 _MieG;
|
||||
uniform float _MaxRayLength;
|
||||
uniform float _MaxRayLengthLights;
|
||||
uniform float4 _AmbientColor;
|
||||
|
||||
uniform float3 _DirLightDir;
|
||||
|
||||
uniform float4 _Randomness;
|
||||
#if !SHADER_API_GLES3
|
||||
struct PointLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float padding;
|
||||
};
|
||||
StructuredBuffer<PointLight> _PointLights;
|
||||
float _PointLightsCount;
|
||||
|
||||
struct SpotLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float3 lightDirection;
|
||||
float lightCosHalfAngle;
|
||||
float padding;
|
||||
};
|
||||
|
||||
StructuredBuffer<SpotLight> _SpotLights;
|
||||
float _SpotLightsCount;
|
||||
#endif
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
struct appdata
|
||||
{
|
||||
#if defined (ENVIROURP17)
|
||||
uint vertex : SV_VertexID;
|
||||
#else
|
||||
float4 vertex : POSITION;
|
||||
#endif
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o = (v2f)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
#if defined (ENVIROURP17)
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(v.vertex);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(v.vertex);
|
||||
|
||||
o.position = pos;
|
||||
o.uv = DYNAMIC_SCALING_APPLY_SCALEBIAS(uv);
|
||||
#else
|
||||
|
||||
o.position = float4(v.vertex.xyz,1);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.position.y *= -1;
|
||||
#endif
|
||||
o.uv = v.texcoord;
|
||||
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
float anisotropy(float costheta)
|
||||
{
|
||||
float g = _MieG.x;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float anisotropyPointSpot(float costheta)
|
||||
{
|
||||
float g = 0.8;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float Attenuation(float distNorm)
|
||||
{
|
||||
return 1.0 / (1.0 + 25.0 * distNorm);
|
||||
}
|
||||
|
||||
float DirectionalLight(float3 wpos)
|
||||
{
|
||||
float atten = 1.0f;
|
||||
|
||||
half cascadeIndex = ComputeCascadeIndex(wpos);
|
||||
bool inside = dot(cascadeIndex, 1) < 4;
|
||||
float4 coords = mul(_MainLightWorldToShadow[cascadeIndex], float4(wpos, 1.0));
|
||||
|
||||
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
|
||||
half4 shadowParams = GetMainLightShadowParams();
|
||||
|
||||
#if UNITY_VERSION >= 202220
|
||||
float shadows = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), coords, shadowSamplingData, shadowParams, false).r;
|
||||
|
||||
#else
|
||||
float shadows = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), coords, shadowSamplingData, shadowParams, false).r;
|
||||
#endif
|
||||
|
||||
atten = inside ? shadows : 1.0f;
|
||||
|
||||
// if(shadows > 0.0f)
|
||||
// atten = 1.0f;
|
||||
|
||||
return atten;
|
||||
}
|
||||
#if !SHADER_API_GLES3
|
||||
float3 PointLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
|
||||
for (int i = 0; i < _PointLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _PointLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _PointLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
//#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _WorldSpaceCameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
//#endif
|
||||
|
||||
color += _PointLights[i].color * att;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 SpotLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
for (int i = 0; i < _SpotLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _SpotLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _SpotLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
half3 lightVector = normalize(pos - _SpotLights[i].pos);
|
||||
half cosAngle = dot(_SpotLights[i].lightDirection.xyz, lightVector);
|
||||
|
||||
half angleAttenuation = 1;
|
||||
angleAttenuation = smoothstep(_SpotLights[i].lightCosHalfAngle, lerp(1, _SpotLights[i].lightCosHalfAngle, 0.8f), cosAngle);
|
||||
angleAttenuation = pow(angleAttenuation, 2.0f);
|
||||
att *= angleAttenuation;
|
||||
|
||||
#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _CameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
#endif
|
||||
color += _SpotLights[i].color * att;
|
||||
|
||||
}
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GetDensity
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GetDensity(float3 wpos, inout float density, float depth, float3 rayDir)
|
||||
{
|
||||
density = 1.0f;
|
||||
|
||||
// #ifdef NOISE
|
||||
// float4 noise = tex3D(_NoiseTexture, frac(wpos * _NoiseData.x + float3(_Time.y * _WindDirection.x, 0, _Time.y * _WindDirection.y)));
|
||||
// float noiseFbm = (noise.g * 0.625) + (noise.b * 0.25) + (noise.a * 0.125);
|
||||
// noiseFbm = saturate(noiseFbm - _NoiseData.y);
|
||||
// density *= saturate(noiseFbm);
|
||||
// #endif
|
||||
return density;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float2 squareUV(float2 uv)
|
||||
{
|
||||
float width = _ScreenParams.x;
|
||||
float height =_ScreenParams.y;
|
||||
float scale = 1000;
|
||||
float x = uv.x * width;
|
||||
float y = uv.y * height;
|
||||
return float2 (x/scale, y/scale);
|
||||
}
|
||||
|
||||
float4 RayMarch(float2 uv,float2 screenPos, float3 rayStart, float3 rayDir, float rayLength, float rayLengthLights, float linearDepth)
|
||||
{
|
||||
|
||||
if (rayLength <= 0.01 || !all(isfinite(rayDir)))
|
||||
return float4(0, 0, 0, 0);
|
||||
|
||||
float2 interleavedPos = fmod(floor(saturate(screenPos.xy)), 8.0);
|
||||
interleavedPos = clamp(interleavedPos, 0.0, 7.999);
|
||||
|
||||
#if UNITY_SINGLE_PASS_STEREO
|
||||
float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
|
||||
interleavedPos = (interleavedPos - scaleOffset.zw) / scaleOffset.xy;
|
||||
#endif
|
||||
|
||||
float4 ditherUV = saturate(float4(interleavedPos / 8.0 + float2(0.5 / 8.0, 0.5 / 8.0),0,0));
|
||||
float offset = tex2Dlod(_DitherTexture, ditherUV).w; //+ _Randomness.xy
|
||||
|
||||
int stepCount = _Steps;
|
||||
|
||||
float stepSize = rayLength / stepCount;
|
||||
float3 step = rayDir * stepSize;
|
||||
|
||||
float stepSizeLights = rayLengthLights / stepCount;
|
||||
float3 stepLights = rayDir * stepSizeLights;
|
||||
|
||||
float3 currentPositionDithered = rayStart + step * offset;
|
||||
float3 currentPositionLightsDithered = rayStart + stepLights * offset;
|
||||
float3 currentPosition = rayStart + step;
|
||||
|
||||
float4 color = float4(0.0,0.0,0.0,0);
|
||||
float cosAngle;
|
||||
|
||||
float extinction = 0;
|
||||
float transmitance = 0;
|
||||
float ambient = 0;
|
||||
cosAngle = dot(_DirLightDir.xyz, -rayDir);
|
||||
|
||||
float ani = anisotropy(cosAngle);
|
||||
float4 lightsColor = float4(0,0,0,0);
|
||||
|
||||
[loop]
|
||||
for (int i = 0; i < stepCount; i++)
|
||||
{
|
||||
float density = GetDensity(currentPosition, density, linearDepth, rayDir);
|
||||
float atten = DirectionalLight(currentPositionDithered) * 0.1;
|
||||
|
||||
//Cloud Shadows
|
||||
//float cloudShadows = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CloudsTex,uv).b;
|
||||
//atten *= (1-cloudShadows);
|
||||
|
||||
float scattering = _VolumetricLight.x * density;
|
||||
extinction += _VolumetricLight.y * density;
|
||||
|
||||
transmitance += atten * scattering * exp(-extinction);
|
||||
#if !SHADER_API_GLES3
|
||||
lightsColor.rgb += PointLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
lightsColor.rgb += SpotLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
#endif
|
||||
currentPosition += step;
|
||||
currentPositionDithered += step;
|
||||
currentPositionLightsDithered += stepLights;
|
||||
}
|
||||
|
||||
//color.rgb = _DirLightColor.rgb * transmitance * ani;
|
||||
color.a = transmitance * ani;
|
||||
color.rgb += lightsColor.rgb * 0.1;
|
||||
|
||||
color = max(0, color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
float2 uv = i.uv.xy;
|
||||
|
||||
float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(uv)).r;
|
||||
|
||||
float linearDepth = Linear01Depth(depth,_ZBufferParams);
|
||||
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
//bit of matrix math to take the screen space coord (u,v,depth) and transform to world space
|
||||
float2 uvClip = i.uv * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
float3 wpos = mul(eyeToWorld, viewPos).xyz;
|
||||
|
||||
float3 rayStart = _WorldSpaceCameraPos;
|
||||
float3 rayDir = wpos - _WorldSpaceCameraPos;
|
||||
//rayDir *= linearDepth;
|
||||
|
||||
float rayLength = length(rayDir);
|
||||
rayDir /= rayLength;
|
||||
|
||||
float rayLengthLights = min(rayLength, _MaxRayLengthLights);
|
||||
rayLength = min(rayLength, _MaxRayLength);
|
||||
|
||||
float4 color = RayMarch(uv, i.position.xy, rayStart, rayDir, rayLength, rayLengthLights, linearDepth);
|
||||
|
||||
return color;
|
||||
}
|
||||
#else
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = v.vertex;
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv);
|
||||
// just invert the colors
|
||||
col.rgb = 1 - col.rgb;
|
||||
return col;
|
||||
}
|
||||
#endif
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48155ce484c07e140a82661968a2c303
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 236601
|
||||
packageName: Enviro 3 - Sky and Weather
|
||||
packageVersion: 3.2.2
|
||||
assetPath: Assets/Enviro 3 - Sky and Weather/Resources/Shader/Fog/EnviroVolumetricsURP.shader
|
||||
uploadId: 766468
|
||||
Reference in New Issue
Block a user