You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
12 KiB

5 years ago
  1. #ifndef FOG_VOLUME_COMMON_INCLUDED
  2. #define FOG_VOLUME_COMMON_INCLUDED
  3. float3 VolumeSpaceCoords = 0;
  4. half VerticalGrad;
  5. half2 heightGradient;
  6. half HeightAtten;
  7. float3 VolumeSpaceCoordsWorldSpace;
  8. //#ifdef VOLUMETRIC_SHADOWS
  9. half3 VolumeShadow = 1;
  10. #define _GeneralShadowOffset 0.001f
  11. #define bias 0
  12. //Shadow params
  13. uniform float4 _ShadowCameraPosition;
  14. uniform float4x4 _ShadowCameraProjection;
  15. uniform float _ShadowCameraSize;
  16. uniform sampler2D _ShadowTexture;
  17. //#define _VolumetricShadowsEnabled 0
  18. uniform int _VolumetricShadowsEnabled = 0;
  19. float4 when_eq(float4 x, float4 y) {
  20. return 1.0 - abs(sign(x - y));
  21. }
  22. float3 when_eq(float3 x, float3 y) {
  23. return 1.0 - abs(sign(x - y));
  24. }
  25. float when_eq(float x, float y) {
  26. return 1.0 - abs(sign(x - y));
  27. }
  28. float FrameShadow(in float2 shadowUVs, in float3 worldPos) {
  29. float FinalShadow = 1;
  30. float2 ShadowMap = tex2Dlod(_ShadowTexture, float4(shadowUVs, 0, 0)).rg;
  31. float d = ShadowMap.x;
  32. //if (d < .0001)FinalShadow = 1.0;
  33. //else
  34. //{
  35. float theLength = distance(worldPos, _ShadowCameraPosition);
  36. FinalShadow = theLength < d + bias ? 1.0f : 0.0f;
  37. //}
  38. //fade before reaching the end
  39. half edges = ShadowMap.y;
  40. return lerp(1,FinalShadow, edges);
  41. }
  42. //#endif
  43. float sdSphere(float3 p, float s)
  44. {
  45. return (length(p) - s);
  46. }
  47. float sdBox(float3 p, float3 b)
  48. {
  49. float3 d = abs(p) - b;
  50. d = (min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0)));
  51. return d;
  52. }
  53. float udBox(float3 p, float3 b)
  54. {
  55. return length(max(abs(p) - b, 0.0));
  56. }
  57. float PrimitiveShape(fixed ShapeType, float3 p, float3 s)
  58. {
  59. if (ShapeType <= 1.0f)//Box
  60. return sdBox(p, s);
  61. else
  62. if (ShapeType <= 2.0f)//Sphere
  63. return sdSphere(p, s);
  64. else return .0f;
  65. }
  66. float nrand(float2 ScreenUVs)
  67. {
  68. return frac(sin(ScreenUVs.x * 12.9898 + ScreenUVs.y * 78.233) * 43758.5453);
  69. }
  70. float remap_tri(float v)
  71. {
  72. float orig = v * 2.0 - 1.0;
  73. v = max(-1.0, orig / sqrt(abs(orig)));
  74. return v - sign(orig) + 0.5;
  75. }
  76. bool IntersectBox(float3 startpoint, float3 direction, float3 boxmin, float3 boxmax, out float tnear, out float tfar)
  77. {
  78. // compute intersection of ray with all six bbox planes
  79. float3 invR = 1.0 / direction;
  80. float3 tbot = invR * (boxmin.xyz - startpoint);
  81. float3 ttop = invR * (boxmax.xyz - startpoint);
  82. // re-order intersections to find smallest and largest on each axis
  83. float3 tmin = min(ttop, tbot);
  84. float3 tmax = max(ttop, tbot);
  85. // find the largest tmin and the smallest tmax
  86. float2 t0 = max(tmin.xx, tmin.yz);
  87. tnear = max(t0.x, t0.y);
  88. t0 = min(tmax.xx, tmax.yz);
  89. tfar = min(t0.x, t0.y);
  90. // check for hit
  91. bool hit;
  92. if ((tnear > tfar))
  93. hit = false;
  94. else
  95. hit = true;
  96. return hit;
  97. }
  98. half3 ToneMap(half3 x, half exposure)
  99. {
  100. //Photographic
  101. return 1 - exp2(-x * exposure);
  102. }
  103. #define PI 3.1416
  104. //http://zurich.disneyresearch.com/~wjarosz/publications/dissertation/chapter4.pdf
  105. float Henyey(float3 E, float3 L, float mieDirectionalG)
  106. {
  107. float theta = saturate(dot(E, L));
  108. return (1.0 / (4.0 * PI)) * ((1.0 - mieDirectionalG * mieDirectionalG) / pow(1.0 - 2.0 * mieDirectionalG * theta + mieDirectionalG * mieDirectionalG, 1.5));
  109. }
  110. half3 ContrastF(half3 pixelColor, fixed contrast)
  111. {
  112. return saturate(((pixelColor.rgb - 0.5f) * max(contrast, 0)) + 0.5f);
  113. }
  114. float3 rotate(float3 p, float rot)
  115. {
  116. float3 r = 0;
  117. #ifdef Twirl_X
  118. float3x3 rx = float3x3(1.0, 0.0, 0.0, 0.0, cos(rot), sin(rot), 0.0, -sin(rot), cos(rot));
  119. r = mul(p, rx);
  120. #endif
  121. #ifdef Twirl_Y
  122. float3x3 ry = float3x3(cos(rot), 0.0, -sin(rot), 0.0, 1.0, 0.0, sin(rot), 0.0, cos(rot));
  123. r = mul(p, ry);
  124. #endif
  125. #ifdef Twirl_Z
  126. float3x3 rz = float3x3(cos(rot), -sin(rot), 0.0, sin(rot), cos(rot), 0.0, 0.0, 0.0, 1.0);
  127. r = mul(p, rz);
  128. #endif
  129. return r;
  130. }
  131. half HeightGradient(float H, half H0, half Hmax)
  132. {
  133. return saturate((H - H0) / (Hmax - H0));
  134. }
  135. half Threshold(float a, float Gain, float Contrast)
  136. {
  137. float input = a * Gain;
  138. //float thresh = input - Contrast;
  139. float thresh = ContrastF(input, Contrast);
  140. return saturate(lerp(0.0f, input, thresh));
  141. }
  142. half PrimitiveAccum = 1;
  143. #ifdef _FOG_VOLUME_NOISE
  144. float NoiseSamplerLoop(float3 p)
  145. {
  146. float n = 0, iter = 1;
  147. for (int i = 0; i < Octaves; i++)
  148. {
  149. p /= 1 + i*.06;
  150. p += Speed.rgb *_BaseRelativeSpeed * (i*.15 + 1);
  151. #ifdef EARTH_CLOUD_STYLE
  152. n += tex3Dlod(_NoiseVolume, float4(p * float3(.5, 1, .5), 0));
  153. n += tex3Dlod(_NoiseVolume, float4(p*.3, 0))*2+ (heightGradient.x);
  154. n = (n-1); //n *= n*.57;
  155. #else
  156. n += tex3Dlod(_NoiseVolume, float4(p, 0));
  157. #endif
  158. }
  159. n = n / Octaves;
  160. /*if (Octaves > 1)
  161. {
  162. n++;
  163. n *= tex3Dlod(_NoiseVolume, float4(p *.75, 0));
  164. }*/
  165. return n;
  166. }
  167. float noise(in float3 p, half DistanceFade)
  168. {
  169. float Volume = 0;
  170. float lowFreqScale = BaseTiling;
  171. half NoiseBaseLayers = 0;
  172. if (Coverage > 0.01)
  173. NoiseBaseLayers = NoiseSamplerLoop(p * lowFreqScale);
  174. #ifdef DF
  175. NoiseBaseLayers = Threshold(NoiseBaseLayers, Coverage * NoiseAtten*PrimitiveAccum, threshold);
  176. #else
  177. NoiseBaseLayers = Threshold(NoiseBaseLayers, Coverage * NoiseAtten, threshold);
  178. #endif
  179. half NoiseDetail = 0;
  180. half BaseMask = saturate((1 - NoiseBaseLayers * _DetailMaskingThreshold));
  181. if (DistanceFade > 0 && NoiseBaseLayers>0 && BaseMask>0)//no me samplees donde ya es opaco del t�
  182. {
  183. NoiseDetail += BaseMask*DistanceFade*(tex3Dlod(_NoiseVolume, float4(p*DetailTiling + Speed * _DetailRelativeSpeed, 0)).r);
  184. if (Octaves > 1 )
  185. NoiseDetail += DistanceFade*(tex3Dlod(_NoiseVolume,
  186. //size and offset
  187. float4(p * .5 * DetailTiling + .5
  188. //distortion
  189. + NoiseDetail * _Curl * BaseMask * 2.0 - 1.0
  190. //animation
  191. + Speed * _DetailRelativeSpeed, 0)).r) * 1.5 * BaseMask;
  192. NoiseDetail = Threshold(NoiseDetail, 1, 0);
  193. }
  194. //base layer (coverage)
  195. Volume += NoiseBaseLayers;
  196. //add detail layer
  197. Volume -= NoiseDetail * _NoiseDetailRange;
  198. Volume *= 1 + _NoiseDetailRange;
  199. Volume *= NoiseDensity;
  200. return saturate(Volume);
  201. }
  202. //http://flafla2.github.io/2016/10/01/raymarching.html
  203. float3 calcNormal(in float3 pos, half DistanceFade)
  204. {
  205. // epsilon - used to approximate dx when taking the derivative
  206. const float2 eps = float2(NormalDistance, 0.0);
  207. // The idea here is to find the "gradient" of the distance field at pos
  208. // Remember, the distance field is not boolean - even if you are inside an object
  209. // the number is negative, so this calculation still works.
  210. // Essentially you are approximating the derivative of the distance field at this point.
  211. float3 nor = float3(
  212. noise(pos + eps.xyy, DistanceFade).x - noise(pos - eps.xyy, DistanceFade).x,
  213. noise(pos + eps.yxy, DistanceFade).x - noise(pos - eps.yxy, DistanceFade).x,
  214. noise(pos + eps.yyx, DistanceFade).x - noise(pos - eps.yyx, DistanceFade).x);
  215. return normalize(nor);
  216. }
  217. #endif
  218. #if _FOG_VOLUME_NOISE && _SHADE
  219. half ShadowGrad(half ShadowThreshold, half SampleDiff)
  220. {
  221. return saturate(ShadowThreshold / (ShadowThreshold - SampleDiff));
  222. }
  223. half ShadowShift = .05;
  224. //#define _SelfShadowSteps 20
  225. float Shadow(float3 ShadowCoords, v2f i, half detailDist, half3 LightVector, half NoiseAtten)
  226. {
  227. float ShadowThreshold = noise(ShadowCoords, detailDist);
  228. float3 LightStep = /*_LightLocalDirection*/LightVector / (float)_SelfShadowSteps;
  229. float accum = 0;
  230. float3 ShadowCoordsStep = ShadowCoords;
  231. for (int k = 0; k <= _SelfShadowSteps && NoiseAtten>0; k++, ShadowCoordsStep += LightStep)
  232. {
  233. float NoiseSample = 0;
  234. float SampleDiff = 0;
  235. if (ShadowThreshold > 0 && accum < 1)
  236. {
  237. NoiseSample = noise(ShadowCoordsStep, detailDist);
  238. SampleDiff = ShadowThreshold - NoiseSample;
  239. if (SampleDiff <= 0)
  240. {
  241. if (ShadowThreshold > 0)
  242. {
  243. accum += 1 - ShadowGrad(ShadowThreshold, SampleDiff);
  244. }
  245. else
  246. {
  247. accum += 1;
  248. }
  249. }
  250. else
  251. if (ShadowThreshold <= 0)
  252. {
  253. accum += ShadowGrad(ShadowThreshold, SampleDiff);
  254. }
  255. }
  256. }
  257. //return accum;
  258. return saturate(1 - accum);
  259. }
  260. #endif
  261. float4 PointLight(float3 LightPosition, float3 VolumePosition,
  262. half size, half3 color, half LightAttenuation, v2f i)
  263. {
  264. //#define ATTEN_METHOD_2
  265. half d = distance(LightPosition, VolumePosition) / size;
  266. float Attenuation = 0;
  267. half UnityScaleMatch = 5;
  268. //https://en.wikipedia.org/wiki/Optical_depth
  269. #ifdef ATTEN_METHOD_1
  270. Attenuation = exp(-d)*UnityScaleMatch;
  271. #endif
  272. #ifdef ATTEN_METHOD_2
  273. Attenuation = UnityScaleMatch / (4 * PI*d*d);
  274. #endif
  275. //Linear
  276. #ifdef ATTEN_METHOD_3
  277. Attenuation = saturate(1 - d / UnityScaleMatch);
  278. #endif
  279. return float4(Attenuation * LightAttenuation * color, Attenuation* LightAttenuation);
  280. }
  281. float4 SpotLight(float3 LightPosition, float3 VolumePosition,
  282. half size, half3 color, half LightAttenuation, float4 Direction, half Angle, half fallof, v2f i)
  283. {
  284. float3 spotDir = normalize(Direction.xyz);
  285. Angle *= .5;//Unity match
  286. float coneAngle = Angle;//inner angle
  287. float coneDelta = Angle + fallof;//outer angle
  288. float3 lray = normalize(LightPosition - VolumePosition);
  289. float SpotCone = (dot(lray, -spotDir) - cos(radians(coneDelta))) / (cos(radians(coneAngle)) - cos(radians(coneDelta)));
  290. SpotCone = max(0, SpotCone);
  291. float4 _PointLight = PointLight(LightPosition, VolumePosition,
  292. size, color, LightAttenuation, i);
  293. return SpotCone * _PointLight;
  294. // half d = distance(LightPosition, VolumePosition) / size;
  295. // float Attenuation = 0;
  296. // half UnityScaleMatch = 5;
  297. // //https://en.wikipedia.org/wiki/Optical_depth
  298. //#ifdef ATTEN_METHOD_1
  299. // Attenuation = exp(-d)*UnityScaleMatch;
  300. //#endif
  301. //
  302. //#ifdef ATTEN_METHOD_2
  303. // Attenuation = UnityScaleMatch / (4 * PI*d*d);
  304. //#endif
  305. //
  306. // //Linear
  307. //#ifdef ATTEN_METHOD_3
  308. // Attenuation = saturate(1 - d / UnityScaleMatch);
  309. //
  310. //
  311. //#endif
  312. // return float4(Attenuation * SpotCone * LightAttenuation * color, Attenuation* LightAttenuation);
  313. }
  314. #if UNITY_LIGHT_PROBE_PROXY_VOLUME
  315. // normal should be normalized, w=1.0
  316. half3 FVSHEvalLinearL0L1_SampleProbeVolume(half4 normal, float3 worldPos)
  317. {
  318. const float transformToLocal = unity_ProbeVolumeParams.y;
  319. const float texelSizeX = unity_ProbeVolumeParams.z;
  320. //The SH coefficients textures and probe occlusion are packed into 1 atlas.
  321. //-------------------------
  322. //| ShR | ShG | ShB | Occ |
  323. //-------------------------
  324. float3 position = (transformToLocal == 1.0f) ? mul(unity_ProbeVolumeWorldToObject, float4(worldPos, 1.0)).xyz : worldPos;
  325. float3 texCoord = (position - unity_ProbeVolumeMin.xyz) * unity_ProbeVolumeSizeInv.xyz;
  326. texCoord.x = texCoord.x * 0.25f;
  327. // We need to compute proper X coordinate to sample.
  328. // Clamp the coordinate otherwize we'll have leaking between RGB coefficients
  329. float texCoordX = clamp(texCoord.x, 0.5f * texelSizeX, 0.25f - 0.5f * texelSizeX);
  330. // sampler state comes from SHr (all SH textures share the same sampler)
  331. texCoord.x = texCoordX;
  332. half4 SHAr = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
  333. texCoord.x = texCoordX + 0.25f;
  334. half4 SHAg = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
  335. texCoord.x = texCoordX + 0.5f;
  336. half4 SHAb = UNITY_SAMPLE_TEX3D_SAMPLER_LOD(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord, 0);
  337. // Linear + constant polynomial terms
  338. half3 x1;
  339. x1.r = dot(SHAr, normal);
  340. x1.g = dot(SHAg, normal);
  341. x1.b = dot(SHAb, normal);
  342. return x1;
  343. }
  344. #endif
  345. half3 ShadeSHPerPixel(half3 normal, half3 ambient, float3 worldPos)
  346. {
  347. half3 ambient_contrib = 0.0;
  348. // L2 per-vertex, L0..L1 & gamma-correction per-pixel
  349. // Ambient in this case is expected to be always Linear, see ShadeSHPerVertex()
  350. #if UNITY_LIGHT_PROBE_PROXY_VOLUME
  351. if (unity_ProbeVolumeParams.x == 1.0)
  352. ambient_contrib = FVSHEvalLinearL0L1_SampleProbeVolume(half4(normal, 1.0), worldPos);
  353. else
  354. ambient_contrib = SHEvalLinearL0L1(half4(normal, 1.0));
  355. #else
  356. ambient_contrib = 1;// SHEvalLinearL0L1(half4(normal, 1.0));
  357. #endif
  358. ambient = max(half3(0, 0, 0), ambient + ambient_contrib); // include L2 contribution in vertex shader before clamp.
  359. #ifdef UNITY_COLORSPACE_GAMMA
  360. ambient = LinearToGammaSpace(ambient);
  361. #endif
  362. return ambient;
  363. }
  364. #endif