armory/Shaders/volumetric_light/volumetric_light.frag.glsl

99 lines
2.9 KiB
Text
Raw Normal View History

2016-08-31 00:46:10 +02:00
// http://sebastien.hillaire.free.fr/index.php?option=com_content&view=article&id=72&Itemid=106
#version 450
2017-12-13 14:21:42 +01:00
#include "compiled.glsl"
#include "std/gbuffer.glsl"
#include "std/shadows.glsl"
2016-09-08 14:08:31 +02:00
2016-08-31 00:46:10 +02:00
uniform sampler2D gbufferD;
#ifndef _NoShadows
2018-01-29 23:52:42 +01:00
uniform sampler2D shadowMap;
uniform samplerCube shadowMapCube;
2016-08-31 00:46:10 +02:00
#endif
uniform sampler2D snoise;
uniform vec2 screenSize;
uniform mat4 invVP;
uniform mat4 LWVP;
2017-07-08 14:12:18 +02:00
uniform vec3 eye;
2016-08-31 00:46:10 +02:00
uniform vec3 lightPos;
uniform float lightRadius;
uniform float shadowsBias;
2017-05-22 15:55:34 +02:00
uniform int lightShadow;
2018-01-28 14:57:49 +01:00
uniform vec2 lightProj;
2016-08-31 00:46:10 +02:00
in vec4 wvpposition;
2018-01-28 13:53:06 +01:00
out float fragColor;
2016-08-31 00:46:10 +02:00
2018-01-07 20:01:43 +01:00
const float tScat = 0.08;
2016-08-31 00:46:10 +02:00
const float tAbs = 0.0;
2018-01-06 00:33:33 +01:00
const float tExt = tScat + tAbs;
2018-01-07 20:01:43 +01:00
const float stepLen = 1.0 / volumSteps;
2018-01-06 00:33:33 +01:00
const float lighting = 0.4;
// float lighting(vec3 p) {
// vec3 L = lightPos.xyz - p.xyz;
// float Ldist = length(lightPos.xyz - p.xyz);
// vec3 Lnorm = L / Ldist;
// float linearAtenuation = min(1.0, max(0.0, (lightRadius - Ldist) / lightRadius));
// return linearAtenuation; //* min(1.0, 1.0 / (Ldist * Ldist));
// }
2016-08-31 00:46:10 +02:00
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
curPos += stepLenWorld * viewVecNorm;
2018-01-06 00:33:33 +01:00
const float density = 1.0;
2016-08-31 00:46:10 +02:00
2018-01-06 00:33:33 +01:00
// float l1 = lighting(curPos) * stepLenWorld * tScat * density;
float l1 = lighting * stepLenWorld * tScat * density;
2016-08-31 00:46:10 +02:00
curOpticalDepth *= exp(-tExt * stepLenWorld * density);
float visibility = 1.0;
2018-01-28 14:57:49 +01:00
if (lightShadow == 1) {
vec4 lampPos = LWVP * vec4(curPos, 1.0);
if (lampPos.w > 0.0) {
lampPos.xyz /= lampPos.w;
visibility = float(texture(shadowMap, lampPos.xy).r > lampPos.z - shadowsBias);
}
}
else { // Cubemap
vec3 lp = lightPos - curPos;
vec3 l = normalize(lp);
visibility = float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightProj));
2016-08-31 00:46:10 +02:00
}
scatteredLightAmount += curOpticalDepth * l1 * visibility;
}
void main() {
vec2 screenPosition = wvpposition.xy / wvpposition.w;
vec2 texCoord = screenPosition * 0.5 + 0.5;
2018-01-28 13:53:06 +01:00
float pixelRayMarchNoise = texture(snoise, texCoord * 100).r * 2.0 - 1.0;
2016-08-31 00:46:10 +02:00
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
2016-10-17 17:39:40 +02:00
vec3 worldPos = getPos2(invVP, depth, texCoord);
2016-08-31 00:46:10 +02:00
2017-07-08 14:12:18 +02:00
vec3 viewVec = worldPos - eye;
2016-10-17 17:39:40 +02:00
float worldPosDist = length(viewVec);
vec3 viewVecNorm = viewVec / worldPosDist;
float startDepth = 0.1;
startDepth = min(worldPosDist, startDepth);
float endDepth = 20.0;
endDepth = min(worldPosDist, endDepth);
2017-07-08 14:12:18 +02:00
vec3 curPos = eye + viewVecNorm * startDepth;
2016-10-17 17:39:40 +02:00
float stepLenWorld = stepLen * (endDepth - startDepth);
float curOpticalDepth = exp(-tExt * stepLenWorld);
float scatteredLightAmount = 0.0;
2018-01-07 20:01:43 +01:00
curPos += stepLenWorld * viewVecNorm * pixelRayMarchNoise;
2016-10-17 17:39:40 +02:00
2018-01-06 00:33:33 +01:00
for (float l = stepLen; l < 0.99999; l += stepLen) { // Do not do the first and last steps
2016-10-17 17:39:40 +02:00
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
2018-01-06 00:33:33 +01:00
}
2016-10-17 17:39:40 +02:00
2018-01-28 13:53:06 +01:00
fragColor = scatteredLightAmount * volumAirTurbidity;
2016-08-31 00:46:10 +02:00
}