|
|
- #ifndef FOG_VOLUME_COMMON_INCLUDED
- #define FOG_VOLUME_COMMON_INCLUDED
- float3 VolumeSpaceCoords = 0;
- half VerticalGrad;
- half2 heightGradient;
- half HeightAtten;
- float3 VolumeSpaceCoordsWorldSpace;
-
- //#ifdef VOLUMETRIC_SHADOWS
- half3 VolumeShadow = 1;
- #define _GeneralShadowOffset 0.001f
- #define bias 0
- //Shadow params
- uniform float4 _ShadowCameraPosition;
- uniform float4x4 _ShadowCameraProjection;
- uniform float _ShadowCameraSize;
- uniform sampler2D _ShadowTexture;
- //#define _VolumetricShadowsEnabled 0
- uniform int _VolumetricShadowsEnabled = 0;
- float4 when_eq(float4 x, float4 y) {
- return 1.0 - abs(sign(x - y));
- }
- float3 when_eq(float3 x, float3 y) {
- return 1.0 - abs(sign(x - y));
- }
- float when_eq(float x, float y) {
- return 1.0 - abs(sign(x - y));
- }
- float FrameShadow(in float2 shadowUVs, in float3 worldPos) {
-
- float FinalShadow = 1;
- float2 ShadowMap = tex2Dlod(_ShadowTexture, float4(shadowUVs, 0, 0)).rg;
- float d = ShadowMap.x;
-
- //if (d < .0001)FinalShadow = 1.0;
- //else
- //{
- float theLength = distance(worldPos, _ShadowCameraPosition);
- FinalShadow = theLength < d + bias ? 1.0f : 0.0f;
-
- //}
-
- //fade before reaching the end
- half edges = ShadowMap.y;
- return lerp(1,FinalShadow, edges);
- }
- //#endif
-
- float sdSphere(float3 p, float s)
- {
- return (length(p) - s);
- }
-
- float sdBox(float3 p, float3 b)
- {
- float3 d = abs(p) - b;
- d = (min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0)));
-
- return d;
- }
-
- float udBox(float3 p, float3 b)
- {
- return length(max(abs(p) - b, 0.0));
- }
-
- float PrimitiveShape(fixed ShapeType, float3 p, float3 s)
- {
- if (ShapeType <= 1.0f)//Box
- return sdBox(p, s);
- else
-
- if (ShapeType <= 2.0f)//Sphere
- return sdSphere(p, s);
-
- else return .0f;
- }
-
-
- float nrand(float2 ScreenUVs)
- {
- return frac(sin(ScreenUVs.x * 12.9898 + ScreenUVs.y * 78.233) * 43758.5453);
- }
-
- float remap_tri(float v)
- {
- float orig = v * 2.0 - 1.0;
- v = max(-1.0, orig / sqrt(abs(orig)));
-
- return v - sign(orig) + 0.5;
- }
-
- bool IntersectBox(float3 startpoint, float3 direction, float3 boxmin, float3 boxmax, out float tnear, out float tfar)
- {
- // compute intersection of ray with all six bbox planes
- float3 invR = 1.0 / direction;
- float3 tbot = invR * (boxmin.xyz - startpoint);
- float3 ttop = invR * (boxmax.xyz - startpoint);
- // re-order intersections to find smallest and largest on each axis
- float3 tmin = min(ttop, tbot);
- float3 tmax = max(ttop, tbot);
- // find the largest tmin and the smallest tmax
- float2 t0 = max(tmin.xx, tmin.yz);
- tnear = max(t0.x, t0.y);
- t0 = min(tmax.xx, tmax.yz);
- tfar = min(t0.x, t0.y);
- // check for hit
- bool hit;
- if ((tnear > tfar))
- hit = false;
- else
- hit = true;
- return hit;
- }
- half3 ToneMap(half3 x, half exposure)
- {
- //Photographic
- return 1 - exp2(-x * exposure);
- }
- #define PI 3.1416
- //http://zurich.disneyresearch.com/~wjarosz/publications/dissertation/chapter4.pdf
- float Henyey(float3 E, float3 L, float mieDirectionalG)
- {
- float theta = saturate(dot(E, L));
- return (1.0 / (4.0 * PI)) * ((1.0 - mieDirectionalG * mieDirectionalG) / pow(1.0 - 2.0 * mieDirectionalG * theta + mieDirectionalG * mieDirectionalG, 1.5));
- }
-
- half3 ContrastF(half3 pixelColor, fixed contrast)
- {
- return saturate(((pixelColor.rgb - 0.5f) * max(contrast, 0)) + 0.5f);
- }
-
- float3 rotate(float3 p, float rot)
- {
- float3 r = 0;
- #ifdef Twirl_X
- float3x3 rx = float3x3(1.0, 0.0, 0.0, 0.0, cos(rot), sin(rot), 0.0, -sin(rot), cos(rot));
- r = mul(p, rx);
- #endif
-
- #ifdef Twirl_Y
- float3x3 ry = float3x3(cos(rot), 0.0, -sin(rot), 0.0, 1.0, 0.0, sin(rot), 0.0, cos(rot));
- r = mul(p, ry);
- #endif
-
- #ifdef Twirl_Z
- float3x3 rz = float3x3(cos(rot), -sin(rot), 0.0, sin(rot), cos(rot), 0.0, 0.0, 0.0, 1.0);
- r = mul(p, rz);
- #endif
- return r;
- }
-
- half HeightGradient(float H, half H0, half Hmax)
- {
- return saturate((H - H0) / (Hmax - H0));
- }
-
- half Threshold(float a, float Gain, float Contrast)
- {
- float input = a * Gain;
- //float thresh = input - Contrast;
- float thresh = ContrastF(input, Contrast);
- return saturate(lerp(0.0f, input, thresh));
- }
- half PrimitiveAccum = 1;
- #ifdef _FOG_VOLUME_NOISE
-
- float NoiseSamplerLoop(float3 p)
- {
- float n = 0, iter = 1;
-
- for (int i = 0; i < Octaves; i++)
- {
- p /= 1 + i*.06;
- p += Speed.rgb *_BaseRelativeSpeed * (i*.15 + 1);
-
- #ifdef EARTH_CLOUD_STYLE
- n += tex3Dlod(_NoiseVolume, float4(p * float3(.5, 1, .5), 0));
- n += tex3Dlod(_NoiseVolume, float4(p*.3, 0))*2+ (heightGradient.x);
-
- n = (n-1); //n *= n*.57;
-
- #else
-
- n += tex3Dlod(_NoiseVolume, float4(p, 0));
- #endif
- }
-
- n = n / Octaves;
-
- /*if (Octaves > 1)
- {
- n++;
- n *= tex3Dlod(_NoiseVolume, float4(p *.75, 0));
- }*/
- return n;
- }
-
- float noise(in float3 p, half DistanceFade)
- {
- float Volume = 0;
- float lowFreqScale = BaseTiling;
-
-
- half NoiseBaseLayers = 0;
-
- if (Coverage > 0.01)
- NoiseBaseLayers = NoiseSamplerLoop(p * lowFreqScale);
-
- #ifdef DF
- NoiseBaseLayers = Threshold(NoiseBaseLayers, Coverage * NoiseAtten*PrimitiveAccum, threshold);
- #else
- NoiseBaseLayers = Threshold(NoiseBaseLayers, Coverage * NoiseAtten, threshold);
- #endif
- half NoiseDetail = 0;
- half BaseMask = saturate((1 - NoiseBaseLayers * _DetailMaskingThreshold));
-
- if (DistanceFade > 0 && NoiseBaseLayers>0 && BaseMask>0)//no me samplees donde ya es opaco del t�
- {
- NoiseDetail += BaseMask*DistanceFade*(tex3Dlod(_NoiseVolume, float4(p*DetailTiling + Speed * _DetailRelativeSpeed, 0)).r);
-
- if (Octaves > 1 )
- NoiseDetail += DistanceFade*(tex3Dlod(_NoiseVolume,
- //size and offset
- float4(p * .5 * DetailTiling + .5
- //distortion
- + NoiseDetail * _Curl * BaseMask * 2.0 - 1.0
- //animation
- + Speed * _DetailRelativeSpeed, 0)).r) * 1.5 * BaseMask;
-
- NoiseDetail = Threshold(NoiseDetail, 1, 0);
- }
-
- //base layer (coverage)
- Volume += NoiseBaseLayers;
-
- //add detail layer
-
- Volume -= NoiseDetail * _NoiseDetailRange;
- Volume *= 1 + _NoiseDetailRange;
- Volume *= NoiseDensity;
-
- return saturate(Volume);
- }
-
- //http://flafla2.github.io/2016/10/01/raymarching.html
- float3 calcNormal(in float3 pos, half DistanceFade)
- {
- // epsilon - used to approximate dx when taking the derivative
- const float2 eps = float2(NormalDistance, 0.0);
-
- // The idea here is to find the "gradient" of the distance field at pos
- // Remember, the distance field is not boolean - even if you are inside an object
- // the number is negative, so this calculation still works.
- // Essentially you are approximating the derivative of the distance field at this point.
- float3 nor = float3(
- noise(pos + eps.xyy, DistanceFade).x - noise(pos - eps.xyy, DistanceFade).x,
- noise(pos + eps.yxy, DistanceFade).x - noise(pos - eps.yxy, DistanceFade).x,
- noise(pos + eps.yyx, DistanceFade).x - noise(pos - eps.yyx, DistanceFade).x);
- return normalize(nor);
- }
- #endif
-
-
- #if _FOG_VOLUME_NOISE && _SHADE
-
- half ShadowGrad(half ShadowThreshold, half SampleDiff)
- {
- return saturate(ShadowThreshold / (ShadowThreshold - SampleDiff));
- }
- half ShadowShift = .05;
- //#define _SelfShadowSteps 20
- float Shadow(float3 ShadowCoords, v2f i, half detailDist, half3 LightVector, half NoiseAtten)
- {
-
- float ShadowThreshold = noise(ShadowCoords, detailDist);
- float3 LightStep = /*_LightLocalDirection*/LightVector / (float)_SelfShadowSteps;
-
- float accum = 0;
- float3 ShadowCoordsStep = ShadowCoords;
- for (int k = 0; k <= _SelfShadowSteps && NoiseAtten>0; k++, ShadowCoordsStep += LightStep)
- {
- float NoiseSample = 0;
- float SampleDiff = 0;
- if (ShadowThreshold > 0 && accum < 1)
- {
- NoiseSample = noise(ShadowCoordsStep, detailDist);
- SampleDiff = ShadowThreshold - NoiseSample;
-
-
- if (SampleDiff <= 0)
- {
- if (ShadowThreshold > 0)
- {
- accum += 1 - ShadowGrad(ShadowThreshold, SampleDiff);
- }
- else
- {
- accum += 1;
- }
- }
- else
- if (ShadowThreshold <= 0)
- {
- accum += ShadowGrad(ShadowThreshold, SampleDiff);
- }
- }
- }
- //return accum;
- return saturate(1 - accum);
-
- }
- #endif
-
-
- float4 PointLight(float3 LightPosition, float3 VolumePosition,
- half size, half3 color, half LightAttenuation, v2f i)
- {
- //#define ATTEN_METHOD_2
- half d = distance(LightPosition, VolumePosition) / size;
- float Attenuation = 0;
- half UnityScaleMatch = 5;
- //https://en.wikipedia.org/wiki/Optical_depth
- #ifdef ATTEN_METHOD_1
- Attenuation = exp(-d)*UnityScaleMatch;
- #endif
-
- #ifdef ATTEN_METHOD_2
- Attenuation = UnityScaleMatch / (4 * PI*d*d);
- #endif
-
- //Linear
- #ifdef ATTEN_METHOD_3
- Attenuation = saturate(1 - d / UnityScaleMatch);
-
-
- #endif
- return float4(Attenuation * LightAttenuation * color, Attenuation* LightAttenuation);
- }
-
- float4 SpotLight(float3 LightPosition, float3 VolumePosition,
- half size, half3 color, half LightAttenuation, float4 Direction, half Angle, half fallof, v2f i)
- {
- float3 spotDir = normalize(Direction.xyz);
- Angle *= .5;//Unity match
- float coneAngle = Angle;//inner angle
- float coneDelta = Angle + fallof;//outer angle
-
- float3 lray = normalize(LightPosition - VolumePosition);
- float SpotCone = (dot(lray, -spotDir) - cos(radians(coneDelta))) / (cos(radians(coneAngle)) - cos(radians(coneDelta)));
- SpotCone = max(0, SpotCone);
- float4 _PointLight = PointLight(LightPosition, VolumePosition,
- size, color, LightAttenuation, i);
-
- return SpotCone * _PointLight;
- // half d = distance(LightPosition, VolumePosition) / size;
- // float Attenuation = 0;
- // half UnityScaleMatch = 5;
- // //https://en.wikipedia.org/wiki/Optical_depth
- //#ifdef ATTEN_METHOD_1
- // Attenuation = exp(-d)*UnityScaleMatch;
- //#endif
- //
- //#ifdef ATTEN_METHOD_2
- // Attenuation = UnityScaleMatch / (4 * PI*d*d);
- //#endif
- //
- // //Linear
- //#ifdef ATTEN_METHOD_3
- // Attenuation = saturate(1 - d / UnityScaleMatch);
- //
- //
- //#endif
- // return float4(Attenuation * SpotCone * LightAttenuation * color, Attenuation* LightAttenuation);
- }
-
-
- #if UNITY_LIGHT_PROBE_PROXY_VOLUME
-
- // normal should be normalized, w=1.0
- half3 FVSHEvalLinearL0L1_SampleProbeVolume(half4 normal, float3 worldPos)
- {
- const float transformToLocal = unity_ProbeVolumeParams.y;
- const float texelSizeX = unity_ProbeVolumeParams.z;
-
- //The SH coefficients textures and probe occlusion are packed into 1 atlas.
- //-------------------------
- //| ShR | ShG | ShB | Occ |
- //-------------------------
-
- float3 position = (transformToLocal == 1.0f) ? mul(unity_ProbeVolumeWorldToObject, float4(worldPos, 1.0)).xyz : worldPos;
- float3 texCoord = (position - unity_ProbeVolumeMin.xyz) * unity_ProbeVolumeSizeInv.xyz;
- texCoord.x = texCoord.x * 0.25f;
-
- // We need to compute proper X coordinate to sample.
- // Clamp the coordinate otherwize we'll have leaking between RGB coefficients
- float texCoordX = clamp(texCoord.x, 0.5f * texelSizeX, 0.25f - 0.5f * texelSizeX);
-
- // sampler state comes from SHr (all SH textures share the same sampler)
- texCoord.x = texCoordX;
- half4 SHAr = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
-
- texCoord.x = texCoordX + 0.25f;
- half4 SHAg = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
-
- texCoord.x = texCoordX + 0.5f;
- half4 SHAb = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
-
- // Linear + constant polynomial terms
- half3 x1;
- x1.r = dot(SHAr, normal);
- x1.g = dot(SHAg, normal);
- x1.b = dot(SHAb, normal);
-
- return x1;
- }
- #endif
-
- half3 ShadeSHPerPixel(half3 normal, half3 ambient, float3 worldPos)
- {
- half3 ambient_contrib = 0.0;
-
- // L2 per-vertex, L0..L1 & gamma-correction per-pixel
- // Ambient in this case is expected to be always Linear, see ShadeSHPerVertex()
- #if UNITY_LIGHT_PROBE_PROXY_VOLUME
- if (unity_ProbeVolumeParams.x == 1.0)
- ambient_contrib = FVSHEvalLinearL0L1_SampleProbeVolume(half4(normal, 1.0), worldPos);
- else
- ambient_contrib = SHEvalLinearL0L1(half4(normal, 1.0));
- #else
- ambient_contrib = 1;// SHEvalLinearL0L1(half4(normal, 1.0));
- #endif
-
- ambient = max(half3(0, 0, 0), ambient + ambient_contrib); // include L2 contribution in vertex shader before clamp.
- #ifdef UNITY_COLORSPACE_GAMMA
- ambient = LinearToGammaSpace(ambient);
- #endif
-
-
- return ambient;
- }
- #endif
|