Update volumetric

This commit is contained in:
luboslenco 2019-01-28 11:28:21 +01:00
parent 4172e0a2c6
commit 7b7260d647
11 changed files with 243 additions and 339 deletions

View file

@ -319,14 +319,12 @@ void main() {
// #endif
#ifdef _ShadowMap
// if (lightShadow == 1) {
#ifdef _CSM
svisibility = shadowTestCascade(shadowMap, eye, p + n * shadowsBias * 10, shadowsBias);
#else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) svisibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias);
#endif
// }
#endif
#ifdef _VoxelAOvar

View file

@ -72,9 +72,9 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#endif
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
#endif
, sampler3D voxels, vec3 voxpos
#endif
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);

View file

@ -4,25 +4,80 @@
#include "compiled.inc"
#include "std/gbuffer.glsl"
#include "std/shadows.glsl"
#ifdef _Clusters
#include "std/clusters.glsl"
#endif
uniform sampler2D gbufferD;
#ifndef _NoShadows
uniform sampler2D shadowMap;
uniform samplerCube shadowMapCube;
#endif
uniform sampler2D snoise;
uniform vec2 screenSize;
uniform mat4 invVP;
uniform mat4 LWVP;
uniform vec3 eye;
uniform vec3 lightPos;
uniform float lightRadius;
uniform float shadowsBias;
uniform int lightShadow;
uniform vec2 lightProj;
#ifdef _Clusters
uniform vec4 lightsArray[maxLights * 2];
#ifdef _Spot
uniform vec4 lightsArraySpot[maxLights];
#endif
uniform sampler2D clustersData;
uniform vec2 cameraPlane;
#endif
in vec4 wvpposition;
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
#ifdef _Sun
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
uniform sampler2DShadow shadowMap;
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
#else
uniform mat4 LWVP;
#endif
// #ifdef _SoftShadows
// uniform sampler2D svisibility;
// #else
#endif // _ShadowMap
#endif
#ifdef _SinglePoint // Fast path for single light
uniform vec3 pointPos;
uniform vec3 pointCol;
#ifdef _ShadowMap
uniform float pointBias;
#endif
#ifdef _Spot
uniform vec3 spotDir;
uniform vec2 spotData;
#endif
#endif
uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
in vec2 texCoord;
in vec3 viewRay;
out float fragColor;
const float tScat = 0.08;
@ -30,51 +85,50 @@ const float tAbs = 0.0;
const float tExt = tScat + tAbs;
const float stepLen = 1.0 / volumSteps;
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));
// }
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
curPos += stepLenWorld * viewVecNorm;
const float density = 1.0;
// float l1 = lighting(curPos) * stepLenWorld * tScat * density;
float l1 = lighting * stepLenWorld * tScat * density;
curOpticalDepth *= exp(-tExt * stepLenWorld * density);
float visibility = 1.0;
#ifdef _Sun
#ifdef _CSM
mat4 LWVP = mat4(casData[4 + 0], casData[4 + 1], casData[4 + 2], casData[4 + 3]);
#endif
vec4 lPos = LWVP * vec4(curPos, 1.0);
lPos.xyz /= lPos.w;
float visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias));
#endif
if (lightShadow == 1) {
vec4 lightPosition = LWVP * vec4(curPos, 1.0);
if (lightPosition.w > 0.0) {
lightPosition.xyz /= lightPosition.w;
visibility = float(texture(shadowMap, lightPosition.xy).r > lightPosition.z - shadowsBias);
}
}
else { // Cubemap
vec3 lp = lightPos - curPos;
vec3 l = normalize(lp);
visibility = float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightProj));
#ifdef _SinglePoint
#ifdef _Spot
vec4 lPos = LWVPSpot0 * vec4(curPos, 1.0);
float visibility = shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, pointBias);
float spotEffect = dot(spotDir, normalize(pointPos - curPos)); // lightDir
if (spotEffect < spotData.x) { // x - cutoff, y - cutoff - exponent
visibility *= smoothstep(spotData.y, spotData.x, spotEffect);
}
#else
vec3 ld = pointPos - curPos;
float visibility = PCFCube(shadowMapPoint[0], ld, -normalize(ld), pointBias, lightProj, vec3(0.0));
#endif
#endif
#ifdef _Clusters
#endif
scatteredLightAmount += curOpticalDepth * l1 * visibility;
}
void main() {
vec2 screenPosition = wvpposition.xy / wvpposition.w;
vec2 texCoord = screenPosition * 0.5 + 0.5;
float pixelRayMarchNoise = textureLod(snoise, texCoord * 100, 0.0).r * 2.0 - 1.0;
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
vec3 worldPos = getPos2(invVP, depth, texCoord);
vec3 p = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec3 viewVec = worldPos - eye;
vec3 viewVec = p - eye;
float worldPosDist = length(viewVec);
vec3 viewVecNorm = viewVec / worldPosDist;

View file

@ -3,56 +3,129 @@
{
"name": "volumetric_light",
"depth_write": false,
"compare_mode": "greater",
"cull_mode": "counter_clockwise",
"compare_mode": "always",
"cull_mode": "none",
"links": [
{
"name": "VWVP",
"link": "_lightVolumeWorldViewProjectionMatrix"
"name": "eye",
"link": "_cameraPosition"
},
{
"name": "eyeLook",
"link": "_cameraLook"
},
{
"name": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrix"
"name": "cameraProj",
"link": "_cameraPlaneProj"
},
{
"name": "lightsArray",
"link": "_lightsArray",
"ifdef": ["_Clusters"]
},
{
"name": "lightsArraySpot",
"link": "_lightsArraySpot",
"ifdef": ["_Clusters", "_Spot"]
},
{
"name": "clustersData",
"link": "_clustersData",
"ifdef": ["_Clusters"]
},
{
"name": "cameraPlane",
"link": "_cameraPlane",
"ifdef": ["_Clusters"]
},
{
"name": "sunDir",
"link": "_sunDirection",
"ifdef": ["_Sun"]
},
{
"name": "sunCol",
"link": "_sunColor",
"ifdef": ["_Sun"]
},
{
"name": "shadowsBias",
"link": "_lightShadowsBias"
"link": "_sunShadowsBias",
"ifdef": ["_Sun", "_ShadowMap"]
},
{
"name": "screenSize",
"link": "_screenSize"
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrix",
"ifndef": ["_CSM"],
"ifdef": ["_Sun", "_ShadowMap"]
},
{
"name": "eye",
"link": "_cameraPosition"
"name": "casData",
"link": "_cascadeData",
"ifdef": ["_Sun", "_ShadowMap", "_CSM"]
},
{
"name": "lightPos",
"link": "_lightPosition"
},
{
"name": "lightRadius",
"link": "_lightRadius"
},
{
"name": "snoise",
"link": "_blueNoise64"
"name": "smSizeUniform",
"link": "_shadowMapSize",
"ifdef": ["_SMSizeUniform"]
},
{
"name": "lightProj",
"link": "_lightPlaneProj"
"link": "_lightPlaneProj",
"ifdef": ["_ShadowMap"]
},
{
"name": "lightShadow",
"link": "_lightCastShadow"
"name": "pointPos",
"link": "_pointPosition",
"ifdef": ["_SinglePoint"]
},
{
"name": "pointCol",
"link": "_pointColor",
"ifdef": ["_SinglePoint"]
},
{
"name": "pointBias",
"link": "_pointShadowsBias",
"ifdef": ["_SinglePoint", "_ShadowMap"]
},
{
"name": "spotDir",
"link": "_spotDirection",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "spotData",
"link": "_spotData",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifdef": ["_Spot", "_ShadowMap"]
}
],
"texture_params": [],
"vertex_shader": "../include/pass_volume.vert.glsl",
"vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "volumetric_light.frag.glsl"
}
]

View file

@ -1,80 +0,0 @@
// http://sebastien.hillaire.free.fr/index.php?option=com_content&view=article&id=72&Itemid=106
#version 450
#include "compiled.inc"
#include "std/gbuffer.glsl"
uniform sampler2D gbufferD;
uniform sampler2DShadow shadowMap;
uniform sampler2D snoise;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
#else
uniform mat4 LWVP;
#endif
uniform float shadowsBias;
uniform vec3 lightColor;
uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 cameraProj;
in vec2 texCoord;
in vec3 viewRay;
out float fragColor;
const float tScat = 0.08;
const float tAbs = 0.0;
const float tExt = tScat + tAbs;
const float stepLen = 1.0 / volumSteps;
const float lighting = 0.4;
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
curPos += stepLenWorld * viewVecNorm;
const float density = 1.0;
float l1 = lighting * stepLenWorld * tScat * density;
curOpticalDepth *= exp(-tExt * stepLenWorld * density);
float visibility = 1.0;
#ifdef _CSM
mat4 LWVP = mat4(casData[4 + 0], casData[4 + 1], casData[4 + 2], casData[4 + 3]);
#endif
vec4 lightPosition = LWVP * vec4(curPos, 1.0);
if (lightPosition.w > 0.0) {
lightPosition.xyz /= lightPosition.w;
visibility = texture(shadowMap, vec3(lightPosition.xy, lightPosition.z - shadowsBias));
}
scatteredLightAmount += curOpticalDepth * l1 * visibility;
}
void main() {
float pixelRayMarchNoise = textureLod(snoise, texCoord * 100, 0.0).r * 2.0 - 1.0;
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
vec3 worldPos = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec3 viewVec = worldPos - eye;
float worldPosDist = length(viewVec);
vec3 viewVecNorm = viewVec / worldPosDist;
float startDepth = 0.1;
startDepth = min(worldPosDist, startDepth);
float endDepth = 20.0;
endDepth = min(worldPosDist, endDepth);
vec3 curPos = eye + viewVecNorm * startDepth;
float stepLenWorld = stepLen * (endDepth - startDepth);
float curOpticalDepth = exp(-tExt * stepLenWorld);
float scatteredLightAmount = 0.0;
curPos += stepLenWorld * viewVecNorm * pixelRayMarchNoise;
for (float l = stepLen; l < 0.99999; l += stepLen) { // Do not do the first and last steps
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
}
fragColor = scatteredLightAmount * volumAirTurbidity;
}

View file

@ -1,99 +0,0 @@
{
"contexts": [
{
"name": "volumetric_light_quad",
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"links": [
{
"name": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrix",
"ifndef": ["_CSM"]
},
{
"name": "shadowsBias",
"link": "_lightShadowsBias"
},
{
"name": "snoise",
"link": "_blueNoise64"
},
{
"name": "eye",
"link": "_cameraPosition"
},
{
"name": "eyeLook",
"link": "_cameraLook"
},
{
"name": "cameraProj",
"link": "_cameraPlaneProj"
},
{
"name": "casData",
"link": "_cascadeData",
"ifdef": ["_CSM"]
}
],
"texture_params": [],
"vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "volumetric_light_quad.frag.glsl"
},
{
"name": "volumetric_light_quad_blend",
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"blend_source": "blend_one",
"blend_destination": "blend_one",
"blend_operation": "add",
"alpha_blend_source": "blend_one",
"alpha_blend_destination": "blend_one",
"alpha_blend_operation": "add",
"links": [
{
"name": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrix"
},
{
"name": "shadowsBias",
"link": "_lightShadowsBias"
},
{
"name": "lightColor",
"link": "_lightColor"
},
{
"name": "eye",
"link": "_cameraPosition"
},
{
"name": "eyeLook",
"link": "_cameraLook"
},
{
"name": "cameraProj",
"link": "_cameraPlaneProj"
},
{
"name": "casData",
"link": "_cascadeData",
"ifdef": ["_CSM"]
}
],
"texture_params": [],
"vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "volumetric_light_quad.frag.glsl"
}
]
}

View file

@ -171,7 +171,7 @@ class RenderPathDeferred {
}
#end
#if (rp_ssgi != "Off")
#if ((rp_ssgi != "Off") || rp_volumetriclight)
{
var t = new RenderTargetRaw();
t.name = "singlea";
@ -257,32 +257,9 @@ class RenderPathDeferred {
#if rp_volumetriclight
{
path.loadShader("shader_datas/volumetric_light_quad/volumetric_light_quad");
path.loadShader("shader_datas/volumetric_light/volumetric_light");
path.loadShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
{
var t = new RenderTargetRaw();
t.name = "bufvola";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8";
t.scale = Inc.getSuperSampling();
// t.scale = Inc.getSuperSampling() * 0.5;
path.createRenderTarget(t);
}
{
var t = new RenderTargetRaw();
t.name = "bufvolb";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8";
t.scale = Inc.getSuperSampling();
// t.scale = Inc.getSuperSampling() * 0.5;
path.createRenderTarget(t);
}
}
#end
@ -642,13 +619,11 @@ class RenderPathDeferred {
#if rp_shadowmap
{
// if (path.lightCastShadow()) {
#if rp_soft_shadows
path.bindTarget("visa", "svisibility");
#else
Inc.bindShadowMap();
#end
// }
#if rp_soft_shadows
path.bindTarget("visa", "svisibility");
#else
Inc.bindShadowMap();
#end
}
#end
@ -692,30 +667,25 @@ class RenderPathDeferred {
}
#end
#if rp_volumetriclight
{
path.setTarget("singlea");
path.bindTarget("_main", "gbufferD");
Inc.bindShadowMap();
path.drawShader("shader_datas/volumetric_light/volumetric_light");
path.setTarget("singleb");
path.bindTarget("singlea", "tex");
path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.setTarget("tex");
path.bindTarget("singleb", "tex");
path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
}
#end
path.setDepthFrom("tex", "gbuffer0"); // Re-bind depth
// #if rp_volumetriclight
// {
// path.setTarget("bufvola");
// path.bindTarget("_main", "gbufferD");
// Inc.bindShadowMap();
// if (path.lightIsSun()) {
// path.drawShader("shader_datas/volumetric_light_quad/volumetric_light_quad");
// }
// else {
// path.drawLightVolume("shader_datas/volumetric_light/volumetric_light");
// }
// path.setTarget("bufvolb");
// path.bindTarget("bufvola", "tex");
// path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
// path.setTarget("tex");
// path.bindTarget("bufvolb", "tex");
// path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
// }
// #end
#if (rp_background == "World")
{
path.setTarget("tex"); // Re-binds depth

View file

@ -176,13 +176,12 @@ class RenderPathForward {
#if rp_volumetriclight
{
path.loadShader("shader_datas/volumetric_light_quad/volumetric_light_quad");
path.loadShader("shader_datas/volumetric_light/volumetric_light");
path.loadShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
{
var t = new RenderTargetRaw();
t.name = "bufvola";
t.name = "singlea";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
@ -192,7 +191,7 @@ class RenderPathForward {
}
{
var t = new RenderTargetRaw();
t.name = "bufvolb";
t.name = "singleb";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
@ -399,28 +398,6 @@ class RenderPathForward {
#if rp_render_to_texture
{
// #if rp_volumetriclight
// {
// path.setTarget("bufvola");
// path.bindTarget("_main", "gbufferD");
// Inc.bindShadowMap();
// if (path.lightIsSun()) {
// path.drawShader("shader_datas/volumetric_light_quad/volumetric_light_quad");
// }
// else {
// path.drawLightVolume("shader_datas/volumetric_light/volumetric_light");
// }
// path.setTarget("bufvolb");
// path.bindTarget("bufvola", "tex");
// path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
// path.setTarget("lbuffer0");
// path.bindTarget("bufvolb", "tex");
// path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
// }
// #end
#if (rp_ssr_half || rp_ssgi_half)
path.setTarget("half");
path.bindTarget("_main", "texdepth");
@ -504,6 +481,23 @@ class RenderPathForward {
}
#end
#if rp_volumetriclight
{
path.setTarget("singlea");
path.bindTarget("_main", "gbufferD");
Inc.bindShadowMap();
path.drawShader("shader_datas/volumetric_light/volumetric_light");
path.setTarget("singleb");
path.bindTarget("singlea", "tex");
path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.setTarget("lbuffer0");
path.bindTarget("singleb", "tex");
path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
}
#end
#if (rp_supersampling == 4)
var framebuffer = "buf";
#else

View file

@ -36,11 +36,6 @@ class Starter {
if (c.window_minimizable) windowFeatures |= FeatureMinimizable;
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window:kha.Window) {
#if kha_webgl
if (!kha.SystemImpl.gl2) trace("WebGL 2 is not supported on this browser");
#end
iron.App.init(function() {
#if arm_loadscreen
function load(g:kha.graphics2.Graphics) {

View file

@ -1360,7 +1360,7 @@ class ArmoryExporter:
# Mesh users have different modifier stack
for i in range(1, len(table)):
if not self.mod_equal_stack(bobject, table[i]):
log.warn('{0} users {1} and {2} differ in modifier stack - use Make Single User(U) - Object & Data for now'.format(oid, bobject.name, table[i].name))
log.warn('{0} users {1} and {2} differ in modifier stack - use Make Single User - Object & Data for now'.format(oid, bobject.name, table[i].name))
break
print('Exporting mesh ' + arm.utils.asset_name(bobject.data))

View file

@ -296,14 +296,13 @@ def build():
assets.add_shader_pass('probe_cubemap')
assets.add_shader_pass('copy_pass')
# if rpdat.rp_volumetriclight:
# assets.add_khafile_def('rp_volumetriclight')
# assets.add_shader_pass('volumetric_light_quad')
# assets.add_shader_pass('volumetric_light')
# assets.add_shader_pass('blur_bilat_pass')
# assets.add_shader_pass('blur_bilat_blend_pass')
# assets.add(assets_path + 'blue_noise64.png')
# assets.add_embedded_data('blue_noise64.png')
if rpdat.rp_volumetriclight:
assets.add_khafile_def('rp_volumetriclight')
assets.add_shader_pass('volumetric_light')
assets.add_shader_pass('blur_bilat_pass')
assets.add_shader_pass('blur_bilat_blend_pass')
assets.add(assets_path + 'blue_noise64.png')
assets.add_embedded_data('blue_noise64.png')
if rpdat.rp_decals:
assets.add_khafile_def('rp_decals')