2016-01-28 00:58:00 +01:00
|
|
|
#version 450
|
|
|
|
|
2015-12-17 14:25:42 +01:00
|
|
|
#ifdef GL_ES
|
|
|
|
precision mediump float;
|
|
|
|
#endif
|
|
|
|
|
2016-07-12 00:09:02 +02:00
|
|
|
#include "../compiled.glsl"
|
2016-10-17 17:39:40 +02:00
|
|
|
#ifdef _EnvTex
|
|
|
|
#include "../std/math.glsl"
|
|
|
|
#endif
|
2015-12-17 14:25:42 +01:00
|
|
|
|
2016-07-10 00:51:39 +02:00
|
|
|
#ifdef _EnvCol
|
|
|
|
uniform vec3 backgroundCol;
|
|
|
|
#endif
|
2016-06-30 13:22:05 +02:00
|
|
|
#ifdef _EnvSky
|
|
|
|
uniform vec3 A;
|
|
|
|
uniform vec3 B;
|
|
|
|
uniform vec3 C;
|
|
|
|
uniform vec3 D;
|
|
|
|
uniform vec3 E;
|
|
|
|
uniform vec3 F;
|
|
|
|
uniform vec3 G;
|
|
|
|
uniform vec3 H;
|
|
|
|
uniform vec3 I;
|
|
|
|
uniform vec3 Z;
|
|
|
|
uniform vec3 sunDirection;
|
|
|
|
#endif
|
2016-07-12 00:09:02 +02:00
|
|
|
#ifdef _EnvClouds
|
|
|
|
uniform sampler2D snoise;
|
|
|
|
uniform float time;
|
2016-07-21 13:05:40 +02:00
|
|
|
// uniform vec3 eye;
|
2016-07-12 00:09:02 +02:00
|
|
|
const float difference = cloudsUpper - cloudsLower;
|
2016-07-17 20:29:53 +02:00
|
|
|
const float steps = 45.0;
|
2016-07-12 00:09:02 +02:00
|
|
|
#endif
|
2016-06-30 13:22:05 +02:00
|
|
|
#ifdef _EnvTex
|
|
|
|
uniform sampler2D envmap;
|
2016-06-03 17:18:38 +02:00
|
|
|
#endif
|
2016-11-03 19:07:16 +01:00
|
|
|
#ifdef _EnvImg // Static background
|
|
|
|
uniform vec2 screenSize;
|
|
|
|
uniform sampler2D envmap;
|
|
|
|
#endif
|
2016-07-12 00:09:02 +02:00
|
|
|
|
2016-07-20 01:14:28 +02:00
|
|
|
// uniform sampler2D gbufferD;
|
2016-09-08 14:08:31 +02:00
|
|
|
uniform float envmapStrength; // From world material
|
2015-12-17 14:25:42 +01:00
|
|
|
|
2016-07-20 01:14:28 +02:00
|
|
|
// in vec2 texCoord;
|
2016-02-08 12:03:20 +01:00
|
|
|
in vec3 normal;
|
2016-10-12 17:52:27 +02:00
|
|
|
out vec4 fragColor;
|
2015-12-17 14:25:42 +01:00
|
|
|
|
2016-06-30 13:22:05 +02:00
|
|
|
#ifdef _EnvSky
|
2016-06-03 17:18:38 +02:00
|
|
|
vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) {
|
|
|
|
vec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5));
|
2016-10-17 17:39:40 +02:00
|
|
|
return (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta));
|
2016-06-03 17:18:38 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-07-12 00:09:02 +02:00
|
|
|
#ifdef _EnvClouds
|
2016-07-17 20:29:53 +02:00
|
|
|
// float hash(vec3 p) {
|
|
|
|
// p = fract(p * vec3(0.16532, 0.17369, 0.15787));
|
2016-10-17 17:39:40 +02:00
|
|
|
// p += dot(p.xyz, p.zyx + 19.19);
|
|
|
|
// return fract(p.x * p.y * p.z);
|
2016-07-17 20:29:53 +02:00
|
|
|
// }
|
2016-07-12 00:09:02 +02:00
|
|
|
float noise(vec3 x) {
|
2016-07-17 20:29:53 +02:00
|
|
|
vec3 p = floor(x);
|
|
|
|
vec3 f = fract(x);
|
2016-07-12 00:09:02 +02:00
|
|
|
f = f * f * (3.0 - 2.0 * f);
|
|
|
|
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
|
|
|
|
vec2 rg = texture(snoise, (uv + 0.5) / 256.0).yx;
|
|
|
|
return mix(rg.x, rg.y, f.z);
|
|
|
|
}
|
|
|
|
float fbm(vec3 p) {
|
|
|
|
p *= 0.0005 * cloudsSize;
|
|
|
|
float f = 0.5 * noise(p); p = p * 3.0; p.y += time * cloudsWind.x;
|
|
|
|
f += 0.25 * noise(p); p = p * 2.0; p.y += time * cloudsWind.y;
|
|
|
|
f += 0.125 * noise(p); p = p * 3.0;
|
|
|
|
f += 0.0625 * noise(p); p = p * 3.0;
|
|
|
|
f += 0.03125 * noise(p); p = p * 3.0;
|
|
|
|
f += 0.015625 * noise(p);
|
2016-10-17 17:39:40 +02:00
|
|
|
return f;
|
2016-07-12 00:09:02 +02:00
|
|
|
}
|
|
|
|
float map(vec3 p) {
|
|
|
|
return fbm(p) - cloudsDensity * 0.6;
|
|
|
|
}
|
|
|
|
// Weather by David Hoskins, https://www.shadertoy.com/view/4dsXWn
|
|
|
|
// Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
|
|
|
vec3 traceP;
|
|
|
|
vec2 doCloudTrace(vec3 add, vec2 shadeSum) {
|
|
|
|
float h = map(traceP);
|
|
|
|
vec2 shade = vec2(traceP.z / difference, max(-h, 0.0));
|
|
|
|
traceP += add;
|
|
|
|
return shadeSum + shade * (1.0 - shadeSum.y);
|
|
|
|
}
|
|
|
|
vec2 traceCloud(vec3 pos, vec3 dir) {
|
|
|
|
float beg = ((cloudsLower - pos.z) / dir.z);
|
|
|
|
float end = ((cloudsUpper - pos.z) / dir.z);
|
|
|
|
traceP = vec3(pos.x + dir.x * beg, pos.y + dir.y * beg, 0.0);
|
2016-10-17 17:39:40 +02:00
|
|
|
// beg += hash(traceP) * 150.0; // Noisy
|
2016-07-12 00:09:02 +02:00
|
|
|
vec3 add = dir * ((end - beg) / steps);
|
|
|
|
|
|
|
|
vec2 shadeSum = vec2(0.0);
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
2016-08-07 01:43:21 +02:00
|
|
|
|
2016-07-17 20:29:53 +02:00
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
|
|
|
// shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum;
|
2016-07-12 00:09:02 +02:00
|
|
|
return shadeSum;
|
|
|
|
}
|
|
|
|
// GPU PRO 7 - Real-time Volumetric Cloudscapes
|
2016-08-07 01:43:21 +02:00
|
|
|
// https://www.guerrilla-games.com/read/the-real-time-volumetric-cloudscapes-of-horizon-zero-dawn
|
2016-07-12 00:09:02 +02:00
|
|
|
vec3 cloudsColor(vec3 R, vec3 pos, vec3 dir) {
|
|
|
|
vec2 traced = traceCloud(pos, dir);
|
|
|
|
float d = traced.x / 200.0 * traced.y + traced.x / 1500.0 * cloudsSecondary;
|
|
|
|
const float g = cloudsEccentricity;
|
2016-07-17 20:29:53 +02:00
|
|
|
#ifdef _EnvSky
|
2016-07-12 00:09:02 +02:00
|
|
|
float cosAngle = dot(sunDirection, dir);
|
2016-07-17 20:29:53 +02:00
|
|
|
#else // Predefined sun direction
|
|
|
|
float cosAngle = dot(vec3(0.0, -1.0, 0.0), dir);
|
|
|
|
#endif
|
2016-07-12 00:09:02 +02:00
|
|
|
float E = 2.0 * exp(-d * cloudsPrecipitation) * (1.0 - exp(-2.0 * d)) * (0.25 * PI) * ((1.0 - g * g) / pow(1.0 + g * g - 2.0 * g * cosAngle, 3.0 / 2.0));
|
|
|
|
return mix(vec3(R), vec3(E * 24.0), d * 12.0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-01-24 22:32:51 +01:00
|
|
|
void main() {
|
2016-07-20 01:14:28 +02:00
|
|
|
// if (texture(gbufferD, texCoord).r/* * 2.0 - 1.0*/ != 1.0) {
|
|
|
|
// discard;
|
|
|
|
// }
|
2016-07-10 00:51:39 +02:00
|
|
|
|
|
|
|
#ifdef _EnvCol
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = backgroundCol;
|
2016-07-17 20:29:53 +02:00
|
|
|
#ifdef _EnvClouds
|
2016-02-08 12:03:20 +01:00
|
|
|
vec3 n = normalize(normal);
|
2016-07-10 00:51:39 +02:00
|
|
|
#endif
|
2016-07-17 20:29:53 +02:00
|
|
|
#endif
|
2016-07-10 00:51:39 +02:00
|
|
|
|
2016-09-05 17:03:20 +02:00
|
|
|
#ifndef _EnvSky // Prevent case when sky radiance is enabled
|
2016-06-30 13:22:05 +02:00
|
|
|
#ifdef _EnvTex
|
2016-07-17 20:29:53 +02:00
|
|
|
vec3 n = normalize(normal);
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = texture(envmap, envMapEquirect(n)).rgb * envmapStrength;
|
2017-01-08 11:25:30 +01:00
|
|
|
#ifdef _EnvLDR
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = pow(fragColor.rgb, vec3(2.2));
|
2017-01-08 11:25:30 +01:00
|
|
|
#endif
|
2016-06-30 13:22:05 +02:00
|
|
|
#endif
|
2016-09-05 17:03:20 +02:00
|
|
|
#endif
|
2016-06-03 17:18:38 +02:00
|
|
|
|
2016-11-03 19:07:16 +01:00
|
|
|
#ifdef _EnvImg // Static background
|
|
|
|
// Will have to get rid of gl_FragCoord, pass tc from VS
|
|
|
|
vec2 texco = gl_FragCoord.xy / screenSize;
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = texture(envmap, vec2(texco.x, 1.0 - texco.y)).rgb * envmapStrength;
|
2016-11-03 19:07:16 +01:00
|
|
|
#endif
|
|
|
|
|
2016-06-30 13:22:05 +02:00
|
|
|
#ifdef _EnvSky
|
2016-07-17 20:29:53 +02:00
|
|
|
vec3 n = normalize(normal);
|
2016-10-17 17:39:40 +02:00
|
|
|
vec3 sunDir = vec3(sunDirection.x, -sunDirection.y, sunDirection.z);
|
2016-06-03 17:18:38 +02:00
|
|
|
float phi = acos(n.z);
|
|
|
|
float theta = atan(-n.y, n.x) + PI;
|
2016-05-10 12:11:31 +02:00
|
|
|
|
2016-08-11 22:24:45 +02:00
|
|
|
float cos_theta = clamp(n.z, 0.0, 1.0);
|
2016-06-03 17:18:38 +02:00
|
|
|
float cos_gamma = dot(n, sunDir);
|
|
|
|
float gamma_val = acos(cos_gamma);
|
|
|
|
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = Z * hosekWilkie(cos_theta, gamma_val, cos_gamma) * envmapStrength;
|
2016-07-17 20:29:53 +02:00
|
|
|
#endif
|
2016-07-12 00:09:02 +02:00
|
|
|
|
|
|
|
#ifdef _EnvClouds
|
2017-03-12 17:29:22 +01:00
|
|
|
// cloudsColor(fragColor.rgb, eye, n)
|
|
|
|
vec3 clouds = cloudsColor(fragColor.rgb, vec3(0.0), n);
|
|
|
|
if (n.z > 0.0) fragColor.rgb = mix(fragColor.rgb, clouds, n.z * 5.0 * envmapStrength);
|
2016-07-12 00:09:02 +02:00
|
|
|
#endif
|
2016-08-07 01:43:21 +02:00
|
|
|
|
|
|
|
#ifdef _LDR
|
2017-03-12 17:29:22 +01:00
|
|
|
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
|
2016-08-07 01:43:21 +02:00
|
|
|
#endif
|
2015-12-17 14:25:42 +01:00
|
|
|
}
|