forked from LeenkxTeam/LNXSDK
Compare commits
127 Commits
Author | SHA1 | Date | |
---|---|---|---|
2434ad07f2 | |||
00493bed9c | |||
7b17633c28 | |||
1ef805eb0b | |||
cb7b041fea | |||
a0e8e1a1a6 | |||
846c3b2c11 | |||
b5af208766 | |||
63565052e3 | |||
38eb66a0b5 | |||
908efdd554 | |||
e014484d27 | |||
872433cafb | |||
74bbb6ca87 | |||
cbbd6fe495 | |||
45a48acf8a | |||
c769b3ca26 | |||
c4378be891 | |||
6ad615a961 | |||
1e4510ba56 | |||
a2714bf101 | |||
5639234eb9 | |||
1591ccdae5 | |||
9cb5232187 | |||
6b25d8c8ad | |||
13ca31f480 | |||
d102e59040 | |||
df0e24c307 | |||
2df86850f8 | |||
02ff259860 | |||
2e6de515ef | |||
41b840212c | |||
429e6d6768 | |||
2d8bfbf181 | |||
1ad7e0eaf4 | |||
ae72401657 | |||
58b9000305 | |||
0cc86c41b8 | |||
25f8c5f64c | |||
109544cea9 | |||
4c92c4bcc9 | |||
3433afb1c3 | |||
e22b522059 | |||
200af34740 | |||
6d7b0078b4 | |||
fa501cb09b | |||
62a4bbb714 | |||
eab3e3b30c | |||
3be7528a6c | |||
c9dd46c5e3 | |||
99806b8069 | |||
e98bfb125d | |||
c4c0e2beaa | |||
36cbc934ba | |||
210d5ea532 | |||
dab9a38424 | |||
b7bbe40348 | |||
8b084156ff | |||
538c364f33 | |||
09eee93ac9 | |||
8b5a77c001 | |||
436b7fac02 | |||
9ef9f5a637 | |||
b8ca4be56a | |||
29e4993f06 | |||
4134352688 | |||
25cf758a33 | |||
23af038a16 | |||
7f7878aaa6 | |||
d7e076fb56 | |||
dab915b60d | |||
74389ba76a | |||
bd5afc797d | |||
27b4ec42a8 | |||
ab7edaa9e3 | |||
27540ac7e9 | |||
a5b512f20b | |||
f8d0e67f33 | |||
915118617d | |||
ea69511e67 | |||
3926a7f83e | |||
0eafd14ae2 | |||
08614512d7 | |||
08261a9335 | |||
ce3c1cea6a | |||
392d12a816 | |||
6b423038d4 | |||
76628fc010 | |||
99f687b10c | |||
316441b954 | |||
9bf83bc49f | |||
d88e1f0f42 | |||
96f4e29778 | |||
1d705d2ca2 | |||
0979cd976f | |||
db6d786ee4 | |||
106e36e30d | |||
2bb296028f | |||
25d7ba3e72 | |||
bf7b4416ec | |||
a2d03cfe6e | |||
95f0ecfc54 | |||
07f59224fc | |||
02259985be | |||
6b8585c81a | |||
5d78eabf94 | |||
41c1459c4e | |||
304a497565 | |||
9fa399371a | |||
4625fdb6b2 | |||
79553927aa | |||
86661c1012 | |||
03967c7a2b | |||
61fd48a12f | |||
519039b8b6 | |||
5244b1b3e8 | |||
7ae3bbe496 | |||
001be2f8da | |||
6a25b3c5d7 | |||
8d4ac7251a | |||
ae63b252c6 | |||
ee73823206 | |||
af2850e20c | |||
bc4a31d415 | |||
5303ad3ac6 | |||
5153cff790 | |||
abe17870ce |
@ -29,10 +29,11 @@ uniform sampler2D gbuffer1;
|
||||
#ifdef _VoxelGI
|
||||
uniform sampler2D voxels_diffuse;
|
||||
uniform sampler2D voxels_specular;
|
||||
#endif
|
||||
#else
|
||||
#ifdef _VoxelAOvar
|
||||
uniform sampler2D voxels_ao;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler3D voxelsSDF;
|
||||
@ -56,6 +57,10 @@ uniform vec3 backgroundCol;
|
||||
|
||||
#ifdef _SSAO
|
||||
uniform sampler2D ssaotex;
|
||||
#else
|
||||
#ifdef _SSGI
|
||||
uniform sampler2D ssaotex;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _SSS
|
||||
@ -113,11 +118,15 @@ uniform vec2 cameraPlane;
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
//!uniform sampler2DShadow shadowMapSpot[1];
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform sampler2D shadowMapSpotTransparent[1];
|
||||
#endif
|
||||
//!uniform mat4 LWVPSpot[1];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[1];
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform samplerCube shadowMapPointTransparent[1];
|
||||
#endif
|
||||
//!uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
@ -125,30 +134,40 @@ uniform vec2 cameraPlane;
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifdef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlas;
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapAtlasTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform sampler2D shadowMapAtlasPointTransparent;
|
||||
#endif
|
||||
//!uniform vec4 pointLightDataArray[4];
|
||||
#endif
|
||||
//!uniform vec4 pointLightDataArray[maxLightsCluster * 6];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[4];
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform samplerCube shadowMapPointTransparent[4];
|
||||
#endif
|
||||
#endif
|
||||
//!uniform vec2 lightProj;
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
//!uniform sampler2DShadow shadowMapSpot[4];
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform sampler2D shadowMapSpotTransparent[4];
|
||||
#endif
|
||||
#endif
|
||||
//!uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
@ -161,12 +180,16 @@ uniform vec3 sunCol;
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSun;
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapAtlasSunTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMap;
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapTransparent;
|
||||
#endif
|
||||
#endif
|
||||
uniform float shadowsBias;
|
||||
#ifdef _CSM
|
||||
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
|
||||
@ -227,17 +250,22 @@ void main() {
|
||||
vec4 g2 = textureLod(gbuffer2, texCoord, 0.0);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
|
||||
#endif
|
||||
|
||||
#ifdef _Brdf
|
||||
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
|
||||
vec3 F = f0 * envBRDF.x + envBRDF.y;
|
||||
#else
|
||||
vec3 F = f0;
|
||||
#endif
|
||||
|
||||
#ifndef _VoxelAOvar
|
||||
#ifndef _VoxelGI
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
|
||||
vec3 envl = shIrradiance(n, shirr);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
@ -271,33 +299,33 @@ void main() {
|
||||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Brdf
|
||||
envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y); //LV: We should take refracted light into account
|
||||
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
|
||||
#endif
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y); //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
|
||||
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * (f0 * envBRDF.x + envBRDF.y); //LV: Eh, what's the point of weighting it only by F0?
|
||||
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= envmapStrength * occspec.x;
|
||||
|
||||
#ifdef _VoxelGI
|
||||
vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
|
||||
fragColor.rgb = (indirect_diffuse.rgb * albedo + envl.rgb * (1.0 - indirect_diffuse.a)) * voxelgiDiff;
|
||||
if(roughness < 1.0 && occspec.y > 0.0)
|
||||
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelAOvar
|
||||
envl.rgb *= textureLod(voxels_ao, texCoord, 0.0).r;
|
||||
#endif
|
||||
|
||||
#ifndef _VoxelGI
|
||||
fragColor.rgb = envl;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
fragColor.rgb = textureLod(voxels_diffuse, texCoord, 0.0).rgb * voxelgiDiff;
|
||||
if(roughness < 1.0 && occspec.y > 0.0)
|
||||
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * F * voxelgiRefl;
|
||||
#else
|
||||
#ifdef _VoxelAOvar
|
||||
fragColor.rgb = textureLod(voxels_ao, texCoord, 0.0).rgb * voxelgiOcc;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Show voxels
|
||||
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
|
||||
// vec3 direction = vec3(0.0, 0.0, -1.0);
|
||||
@ -317,6 +345,10 @@ void main() {
|
||||
// #else
|
||||
fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r;
|
||||
// #endif
|
||||
#else
|
||||
#ifdef _SSGI
|
||||
fragColor.rgb += textureLod(ssaotex, texCoord, 0.0).rgb;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _EmissionShadeless
|
||||
@ -349,40 +381,70 @@ void main() {
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _CSM
|
||||
svisibility = shadowTestCascade(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias, false
|
||||
);
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMap, shadowMapTransparent
|
||||
#else
|
||||
shadowMap
|
||||
#endif
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, false
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
|
||||
if (lPos.w > 0.0) {
|
||||
svisibility = shadowTest(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias, false
|
||||
);
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMap, shadowMapTransparent
|
||||
#else
|
||||
shadowMap
|
||||
#endif
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, false
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelShadow
|
||||
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
|
||||
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, -g2.rg).r) * voxelgiShad;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _SSRS
|
||||
// vec2 coords = getProjectedCoord(hitCoord);
|
||||
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
@ -439,13 +501,16 @@ void main() {
|
||||
fragColor.rgb += sampleLight(
|
||||
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias, true, false
|
||||
, 0, pointBias, true
|
||||
#ifdef _ShadowMapTransparent
|
||||
, false
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, voxels, voxelsSDF, clipmaps
|
||||
, voxels, voxelsSDF, clipmaps, -g2.rg
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, occspec.x
|
||||
@ -492,7 +557,10 @@ void main() {
|
||||
f0
|
||||
#ifdef _ShadowMap
|
||||
// light index, shadow bias, cast_shadows
|
||||
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false
|
||||
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0
|
||||
#ifdef _ShadowMapTransparent
|
||||
, false
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, lightsArray[li * 3 + 2].y != 0.0
|
||||
@ -503,7 +571,7 @@ void main() {
|
||||
, lightsArraySpot[li * 2 + 1].xyz // right
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, voxels, voxelsSDF, clipmaps
|
||||
, voxels, voxelsSDF, clipmaps, -g2.rg
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, occspec.x
|
||||
@ -514,14 +582,5 @@ void main() {
|
||||
);
|
||||
}
|
||||
#endif // _Clusters
|
||||
|
||||
/*
|
||||
#ifdef _VoxelRefract
|
||||
if(opac < 1.0) {
|
||||
vec3 refraction = traceRefraction(p, n, voxels, v, ior, roughness, eye) * voxelgiRefr;
|
||||
fragColor.rgb = mix(refraction, fragColor.rgb, opac);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
fragColor.a = 1.0; // Mark as opaque
|
||||
}
|
||||
|
@ -1,107 +1,506 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/math.glsl"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _Clusters
|
||||
#include "std/clusters.glsl"
|
||||
#endif
|
||||
#ifdef _ShadowMap
|
||||
#include "std/shadows.glsl"
|
||||
#endif
|
||||
#ifdef _LTC
|
||||
#include "std/ltc.glsl"
|
||||
#endif
|
||||
#ifdef _LightIES
|
||||
#include "std/ies.glsl"
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#include "std/light_common.glsl"
|
||||
#endif
|
||||
#include "std/constants.glsl"
|
||||
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0; // Normal
|
||||
// #ifdef _RTGI
|
||||
// uniform sampler2D gbuffer1; // Basecol
|
||||
// #endif
|
||||
uniform mat4 P;
|
||||
uniform mat3 V3;
|
||||
|
||||
#ifdef _EmissionShaded
|
||||
uniform sampler2D gbufferEmission;
|
||||
#endif
|
||||
uniform sampler2D sveloc;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 screenSize;
|
||||
uniform mat4 invVP;
|
||||
|
||||
const float angleMix = 0.5f;
|
||||
#ifdef _SSGICone9
|
||||
const float strength = 2.0 * (1.0 / ssgiStrength);
|
||||
#else
|
||||
const float strength = 2.0 * (1.0 / ssgiStrength) * 1.8;
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec3 fragColor;
|
||||
|
||||
float metallic;
|
||||
uint matid;
|
||||
|
||||
#ifdef _SMSizeUniform
|
||||
//!uniform vec2 smSizeUniform;
|
||||
#endif
|
||||
|
||||
in vec3 viewRay;
|
||||
in vec2 texCoord;
|
||||
out float fragColor;
|
||||
|
||||
vec3 hitCoord;
|
||||
vec2 coord;
|
||||
float depth;
|
||||
// #ifdef _RTGI
|
||||
// vec3 col = vec3(0.0);
|
||||
// #endif
|
||||
vec3 vpos;
|
||||
|
||||
vec2 getProjectedCoord(vec3 hitCoord) {
|
||||
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
#ifdef _InvY
|
||||
projectedCoord.y = 1.0 - projectedCoord.y;
|
||||
#ifdef _Clusters
|
||||
uniform vec4 lightsArray[maxLights * 3];
|
||||
#ifdef _Spot
|
||||
uniform vec4 lightsArraySpot[maxLights * 2];
|
||||
#endif
|
||||
return projectedCoord.xy;
|
||||
}
|
||||
uniform sampler2D clustersData;
|
||||
uniform vec2 cameraPlane;
|
||||
#endif
|
||||
|
||||
float getDeltaDepth(vec3 hitCoord) {
|
||||
coord = getProjectedCoord(hitCoord);
|
||||
depth = textureLod(gbufferD, coord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 p = getPosView(viewRay, depth, cameraProj);
|
||||
return p.z - hitCoord.z;
|
||||
}
|
||||
#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 vec3 spotRight;
|
||||
uniform vec4 spotData;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void rayCast(vec3 dir) {
|
||||
hitCoord = vpos;
|
||||
dir *= ssgiRayStep * 2;
|
||||
float dist = 0.15;
|
||||
for (int i = 0; i < ssgiMaxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
float delta = getDeltaDepth(hitCoord);
|
||||
if (delta > 0.0 && delta < 0.2) {
|
||||
dist = distance(vpos, hitCoord);
|
||||
break;
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 PPComp12;
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
#ifndef _LTC
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
uniform mat4 LWVPSpot[1];
|
||||
#endif
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[1];
|
||||
uniform samplerCube shadowMapPointTransparent[1];
|
||||
uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlas;
|
||||
uniform sampler2D shadowMapAtlasTransparent;
|
||||
#endif
|
||||
uniform vec2 lightProj;
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
uniform sampler2D shadowMapAtlasPointTransparent;
|
||||
//!uniform vec4 pointLightDataArray[maxLightsCluster * 6];
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[4];
|
||||
uniform samplerCube shadowMapPointTransparent[4];
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMapSpot[4];
|
||||
uniform sampler2D shadowMapSpotTransparent[4];
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
uniform vec3 lightArea0;
|
||||
uniform vec3 lightArea1;
|
||||
uniform vec3 lightArea2;
|
||||
uniform vec3 lightArea3;
|
||||
uniform sampler2D sltcMat;
|
||||
uniform sampler2D sltcMag;
|
||||
#ifdef _ShadowMap
|
||||
#ifndef _Spot
|
||||
#ifdef _SinglePoint
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
uniform mat4 LWVPSpot[1];
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _Sun
|
||||
uniform vec3 sunDir;
|
||||
uniform vec3 sunCol;
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSun;
|
||||
uniform sampler2D shadowMapAtlasSunTransparent;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform sampler2D shadowMapTransparent;
|
||||
#endif
|
||||
uniform float shadowsBias;
|
||||
#ifdef _CSM
|
||||
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
|
||||
#else
|
||||
uniform mat4 LWVP;
|
||||
#endif
|
||||
#endif // _ShadowMap
|
||||
#endif
|
||||
|
||||
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 lp, const vec3 lightCol
|
||||
#ifdef _ShadowMap
|
||||
, int index, float bias, bool receiveShadow, bool transparent
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
||||
#endif
|
||||
) {
|
||||
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
|
||||
vec3 visibility = lightCol;
|
||||
visibility *= attenuate(distance(p, lp));
|
||||
|
||||
#ifdef _LTC
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
||||
visibility *= shadowTest(shadowMapSpot[0],
|
||||
shadowMapSpotTransparent[0],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
if (index == 0) visibility *= shadowTest(shadowMapSpot[0],
|
||||
shadowMapSpotTransparent[0],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 1) visibility *= shadowTest(shadowMapSpot[1],
|
||||
shadowMapSpotTransparent[1],
|
||||
, lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 2) visibility *= shadowTest(shadowMapSpot[2],
|
||||
shadowMapSpotTransparent[2],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 3) visibility *= shadowTest(shadowMapSpot[3],
|
||||
shadowMapSpotTransparent[3],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return visibility;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
visibility *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
||||
visibility *= shadowTest(shadowMapSpot[0],
|
||||
shadowMapSpotTransparent[0],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
#ifdef _ShadowMapAtlas
|
||||
visibility *= shadowTest(
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, bias, transparent
|
||||
);
|
||||
#else
|
||||
if (index == 0) visibility *= shadowTest(shadowMapSpot[0],
|
||||
shadowMapSpotTransparent[0],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 1) visibility *= shadowTest(shadowMapSpot[1],
|
||||
shadowMapSpotTransparent[1],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 2) visibility *= shadowTest(shadowMapSpot[2],
|
||||
shadowMapSpotTransparent[2],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 3) visibility *= shadowTest(shadowMapSpot[3],
|
||||
shadowMapSpotTransparent[3],
|
||||
lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return visibility;
|
||||
}
|
||||
fragColor += dist;
|
||||
// #ifdef _RTGI
|
||||
// col += textureLod(gbuffer1, coord, 0.0).rgb * ((ssgiRayStep * ssgiMaxSteps) - dist);
|
||||
// #endif
|
||||
#endif
|
||||
|
||||
#ifdef _LightIES
|
||||
visibility *= iesAttenuation(-l);
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
#ifndef _Spot
|
||||
visibility *= PCFCube(shadowMapPoint[0],
|
||||
shadowMapPointTransparent[0],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
visibility *= PCFFakeCube(
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
, ld, -l, bias, lightProj, n, index, transparent
|
||||
);
|
||||
#else
|
||||
if (index == 0) visibility *= PCFCube(shadowMapPoint[0],
|
||||
shadowMapPointTransparent[0],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 1) visibility *= PCFCube(shadowMapPoint[1],
|
||||
shadowMapPointTransparent[1],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 2) visibility *= PCFCube(shadowMapPoint[2],
|
||||
shadowMapPointTransparent[2],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 3) visibility *= PCFCube(shadowMapPoint[3],
|
||||
shadowMapPointTransparent[3],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
vec3 tangent(const vec3 n) {
|
||||
vec3 t1 = cross(n, vec3(0, 0, 1));
|
||||
vec3 t2 = cross(n, vec3(0, 1, 0));
|
||||
if (length(t1) > length(t2)) return normalize(t1);
|
||||
else return normalize(t2);
|
||||
vec3 getVisibility(vec3 p, vec3 n, float depth, vec2 uv) {
|
||||
vec3 visibility = vec3(0.0);
|
||||
#ifdef _Sun
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _CSM
|
||||
visibility = shadowTestCascade(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias, false
|
||||
);
|
||||
#else
|
||||
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
|
||||
if (lPos.w > 0.0) {
|
||||
visibility = shadowTest(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias, false
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _SinglePoint
|
||||
visibility += sampleLight(
|
||||
p, n, pointPos, pointCol
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias, true, false
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef _Clusters
|
||||
float viewz = linearize(depth, cameraProj);
|
||||
int clusterI = getClusterI(uv, viewz, cameraPlane);
|
||||
int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);
|
||||
|
||||
#ifdef HLSL
|
||||
viewz += textureLod(clustersData, vec2(0.0), 0.0).r * 1e-9; // TODO: krafix bug, needs to generate sampler
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
int numSpots = int(texelFetch(clustersData, ivec2(clusterI, 1 + maxLightsCluster), 0).r * 255);
|
||||
int numPoints = numLights - numSpots;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < min(numLights, maxLightsCluster); i++) {
|
||||
int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);
|
||||
visibility += sampleLight(
|
||||
p,
|
||||
n,
|
||||
lightsArray[li * 3].xyz, // lp
|
||||
lightsArray[li * 3 + 1].xyz // lightCol
|
||||
#ifdef _ShadowMap
|
||||
// light index, shadow bias, cast_shadows
|
||||
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, lightsArray[li * 3 + 2].y != 0.0
|
||||
, lightsArray[li * 3 + 2].y // spot size (cutoff)
|
||||
, lightsArraySpot[li * 2].w // spot blend (exponent)
|
||||
, lightsArraySpot[li * 2].xyz // spotDir
|
||||
, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w) // scale
|
||||
, lightsArraySpot[li * 2 + 1].xyz // right
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif // _Clusters
|
||||
return visibility;
|
||||
}
|
||||
|
||||
vec3 getWorldPos(vec2 uv, float depth) {
|
||||
vec4 pos = invVP * vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
return pos.xyz / pos.w;
|
||||
}
|
||||
|
||||
vec3 getNormal(vec2 uv) {
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
vec2 enc = g0.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
vec3 calculateIndirectLight(vec2 uv, vec3 pos, vec3 normal, float depth) {
|
||||
// Simplified visibility - replace with your full visibility function if needed
|
||||
vec3 sampleColor = textureLod(gbuffer1, uv, 0.0).rgb * getVisibility(pos, normal, depth, uv);
|
||||
|
||||
#ifdef _EmissionShadeless
|
||||
if (matid == 1) { // pure emissive material, color stored in basecol
|
||||
sampleColor += textureLod(gbuffer1, uv, 0.0).rgb;
|
||||
}
|
||||
#endif
|
||||
#ifdef _EmissionShaded
|
||||
#ifdef _EmissionShadeless
|
||||
else {
|
||||
#endif
|
||||
vec3 sampleEmission = textureLod(gbufferEmission, uv, 0.0).rgb;
|
||||
sampleColor += sampleEmission; // Emission should be added directly
|
||||
#ifdef _EmissionShadeless
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return sampleColor;
|
||||
}
|
||||
|
||||
// Improved sampling parameters
|
||||
const float GOLDEN_ANGLE = 2.39996323;
|
||||
const float MAX_DEPTH_DIFFERENCE = 0.9; // More conservative depth threshold
|
||||
const float SAMPLE_BIAS = 0.01; // Small offset to avoid self-occlusion
|
||||
|
||||
void main() {
|
||||
fragColor = 0;
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0);
|
||||
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r;
|
||||
if (depth >= 1.0) {
|
||||
fragColor = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
|
||||
vec2 enc = g0.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(V3 * n);
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vpos = getPosView(viewRay, d, cameraProj);
|
||||
vec3 pos = getWorldPos(texCoord, depth);
|
||||
vec3 normal = getNormal(texCoord);
|
||||
vec3 centerColor = textureLod(gbuffer1, texCoord, 0.0).rgb;
|
||||
|
||||
rayCast(n);
|
||||
vec3 o1 = normalize(tangent(n));
|
||||
vec3 o2 = (cross(o1, n));
|
||||
vec3 c1 = 0.5f * (o1 + o2);
|
||||
vec3 c2 = 0.5f * (o1 - o2);
|
||||
rayCast(mix(n, o1, angleMix));
|
||||
rayCast(mix(n, o2, angleMix));
|
||||
rayCast(mix(n, -c1, angleMix));
|
||||
rayCast(mix(n, -c2, angleMix));
|
||||
float radius = ssaoRadius;
|
||||
|
||||
#ifdef _SSGICone9
|
||||
rayCast(mix(n, -o1, angleMix));
|
||||
rayCast(mix(n, -o2, angleMix));
|
||||
rayCast(mix(n, c1, angleMix));
|
||||
rayCast(mix(n, c2, angleMix));
|
||||
vec3 gi = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float angle = fract(sin(dot(texCoord, vec2(12.9898, 78.233))) * 100.0);
|
||||
|
||||
for (int i = 0; i < ssgiSamples; i++) {
|
||||
// Use quasi-random sequence for better coverage
|
||||
float r = sqrt((float(i) + 0.5) / float(ssgiSamples)) * radius;
|
||||
float a = (float(i) * GOLDEN_ANGLE) + angle;
|
||||
|
||||
vec2 offset = vec2(cos(a), sin(a)) * r * radius;
|
||||
vec2 sampleUV = clamp(texCoord + offset * (BayerMatrix8[int(gl_FragCoord.x + velocity.x) % 8][int(gl_FragCoord.y + velocity.y) % 8] - 0.5) / screenSize, vec2(0.001), vec2(0.999));
|
||||
|
||||
float sampleDepth = textureLod(gbufferD, sampleUV, 0.0).r;
|
||||
if (sampleDepth >= 1.0) continue;
|
||||
|
||||
vec3 samplePos = getWorldPos(sampleUV, sampleDepth);
|
||||
vec3 sampleNormal = getNormal(sampleUV);
|
||||
|
||||
// Apply small bias to sample position to avoid self-occlusion
|
||||
samplePos += sampleNormal * SAMPLE_BIAS;
|
||||
|
||||
vec3 dir = pos - samplePos;
|
||||
float dist = length(dir);
|
||||
|
||||
if (abs(pos.z - samplePos.z) > MAX_DEPTH_DIFFERENCE) continue;;
|
||||
|
||||
vec3 sampleColor = calculateIndirectLight(sampleUV, samplePos, sampleNormal, sampleDepth);
|
||||
float weight = 1.0 / (1.0 + dist * dist * 2.0) * max(dot(sampleNormal, n), 0.0);
|
||||
|
||||
gi += sampleColor * weight;
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
// Normalize and apply intensity
|
||||
if (totalWeight > 0.0) {
|
||||
gi /= totalWeight;
|
||||
#ifdef _CPostprocess
|
||||
gi *= PPComp12.x;
|
||||
#else
|
||||
gi *= ssaoStrength;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _EmissionShadeless
|
||||
if (matid == 1) { // pure emissive material, color stored in basecol
|
||||
gi += textureLod(gbuffer1, texCoord, 0.0).rgb;
|
||||
}
|
||||
#endif
|
||||
#ifdef _EmissionShaded
|
||||
#ifdef _EmissionShadeless
|
||||
else {
|
||||
#endif
|
||||
gi += textureLod(gbufferEmission, texCoord, 0.0).rgb;
|
||||
#ifdef _EmissionShadeless
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
fragColor = gi / (gi + vec3(1.0)); // Reinhard tone mapping
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "P",
|
||||
"link": "_projectionMatrix"
|
||||
@ -15,16 +19,180 @@
|
||||
"link": "_viewMatrix3"
|
||||
},
|
||||
{
|
||||
"name": "invP",
|
||||
"link": "_inverseProjectionMatrix"
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
},
|
||||
{
|
||||
"name": "PPComp12",
|
||||
"link": "_PPComp12",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArraySpot",
|
||||
"link": "_lightsArraySpot",
|
||||
"ifdef": ["_Clusters", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArray",
|
||||
"link": "_lightsArray",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"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": "_sunShadowsBias",
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVP",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSun",
|
||||
"ifndef": ["_CSM"],
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "casData",
|
||||
"link": "_cascadeData",
|
||||
"ifdef": ["_Sun", "_ShadowMap", "_CSM"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea0",
|
||||
"link": "_lightArea0",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea1",
|
||||
"link": "_lightArea1",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea2",
|
||||
"link": "_lightArea2",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea3",
|
||||
"link": "_lightArea3",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "sltcMat",
|
||||
"link": "_ltcMat",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "sltcMag",
|
||||
"link": "_ltcMag",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "smSizeUniform",
|
||||
"link": "_shadowMapSize",
|
||||
"ifdef": ["_SMSizeUniform"]
|
||||
},
|
||||
{
|
||||
"name": "lightProj",
|
||||
"link": "_lightPlaneProj",
|
||||
"ifdef": ["_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"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": "spotRight",
|
||||
"link": "_spotRight",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpotArray",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "pointLightDataArray",
|
||||
"link": "_pointLightsAtlasArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[0]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot0",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[1]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot1",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[2]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot2",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[3]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot3",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass_viewray2.vert.glsl",
|
||||
"vertex_shader": "../include/pass_viewray.vert.glsl",
|
||||
"fragment_shader": "ssgi_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
|
@ -64,7 +64,7 @@ vec4 rayCast(vec3 dir) {
|
||||
ddepth = getDeltaDepth(hitCoord);
|
||||
if (ddepth > 0.0) return binarySearch(dir);
|
||||
}
|
||||
return vec4(texCoord, 0.0, 1.0);
|
||||
return vec4(getProjectedCoord(hitCoord), 0.0, 1.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
@ -86,7 +86,7 @@ void main() {
|
||||
|
||||
vec3 viewNormal = V3 * n;
|
||||
vec3 viewPos = getPosView(viewRay, d, cameraProj);
|
||||
vec3 refracted = refract(normalize(viewPos), viewNormal, 1.0 / ior);
|
||||
vec3 refracted = refract(viewPos, viewNormal, 1.0 / ior);
|
||||
hitCoord = viewPos;
|
||||
|
||||
vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0;
|
||||
|
18
leenkx/Shaders/std/aabb.glsl
Normal file
18
leenkx/Shaders/std/aabb.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _AABB_GLSL
|
||||
#define _AABB_GLSL
|
||||
|
||||
bool IntersectAABB(vec3[2] a, vec3[2] b) {
|
||||
const float EPSILON = 0.001; // Small tolerance to prevent false negatives
|
||||
if (abs(a[0].x - b[0].x) > (a[1].x + b[1].x + EPSILON)) return false;
|
||||
if (abs(a[0].y - b[0].y) > (a[1].y + b[1].y + EPSILON)) return false;
|
||||
if (abs(a[0].z - b[0].z) > (a[1].z + b[1].z + EPSILON)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AABBfromMinMax(inout vec3[2] aabb, vec3 _min, vec3 _max)
|
||||
{
|
||||
aabb[0] = (_min + _max) * 0.5f;
|
||||
aabb[1] = abs(_max - aabb[0]);
|
||||
}
|
||||
|
||||
#endif
|
@ -22,7 +22,7 @@ THE SOFTWARE.
|
||||
#ifndef _CONETRACE_GLSL_
|
||||
#define _CONETRACE_GLSL_
|
||||
|
||||
#include "std/voxels_constants.glsl"
|
||||
#include "std/constants.glsl"
|
||||
|
||||
// References
|
||||
// https://github.com/Friduric/voxel-cone-tracing
|
||||
@ -92,7 +92,7 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
|
||||
float dist = voxelSize0;
|
||||
float step_dist = dist;
|
||||
vec3 samplePos;
|
||||
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
|
||||
vec3 start_pos = origin + n * voxelSize0;
|
||||
int clipmap_index0 = 0;
|
||||
|
||||
vec3 aniso_direction = -dir;
|
||||
@ -125,7 +125,7 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
|
||||
|
||||
if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) {
|
||||
vec4 mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight);
|
||||
mipSample = mix(mipSample, mipSampleNext, smoothstep(0.0, 1.0, clipmap_blend));
|
||||
mipSample = mix(mipSample, mipSampleNext, clipmap_blend);
|
||||
}
|
||||
|
||||
sampleCol += (1.0 - sampleCol.a) * mipSample;
|
||||
@ -148,8 +148,9 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
|
||||
vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) {
|
||||
float sum = 0.0;
|
||||
vec4 amount = vec4(0.0);
|
||||
mat3 TBN = makeTangentBasis(normal);
|
||||
for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) {
|
||||
vec3 coneDir = DIFFUSE_CONE_DIRECTIONS[i];
|
||||
vec3 coneDir = TBN * DIFFUSE_CONE_DIRECTIONS[i];
|
||||
const float cosTheta = dot(normal, coneDir);
|
||||
if (cosTheta <= 0)
|
||||
continue;
|
||||
@ -166,7 +167,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels,
|
||||
}
|
||||
|
||||
vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
|
||||
vec3 specularDir = reflect(-viewDir, normal);
|
||||
vec3 specularDir = reflect(normalize(-viewDir), normal);
|
||||
vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep;
|
||||
vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
|
||||
|
||||
@ -176,9 +177,9 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels,
|
||||
return amount * voxelgiOcc;
|
||||
}
|
||||
|
||||
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
|
||||
const float transmittance = 1.0;
|
||||
vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior);
|
||||
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity, const float opacity) {
|
||||
const float transmittance = 1.0 - opacity;
|
||||
vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior);
|
||||
vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
|
||||
vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
|
||||
|
||||
@ -196,7 +197,7 @@ float traceConeAO(const sampler3D voxels, const vec3 origin, const vec3 n, const
|
||||
float dist = voxelSize0;
|
||||
float step_dist = dist;
|
||||
vec3 samplePos;
|
||||
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
|
||||
vec3 start_pos = origin + n * voxelSize0;
|
||||
int clipmap_index0 = 0;
|
||||
|
||||
vec3 aniso_direction = -dir;
|
||||
@ -259,7 +260,6 @@ float traceAO(const vec3 origin, const vec3 normal, const sampler3D voxels, cons
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _VoxelShadow
|
||||
float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 origin, const vec3 n, const vec3 dir, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) {
|
||||
float sampleCol = 0.0;
|
||||
@ -267,7 +267,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
|
||||
float dist = voxelSize0;
|
||||
float step_dist = dist;
|
||||
vec3 samplePos;
|
||||
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
|
||||
vec3 start_pos = origin + n * voxelSize0;
|
||||
int clipmap_index0 = 0;
|
||||
|
||||
vec3 aniso_direction = -dir;
|
||||
@ -287,7 +287,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
|
||||
float clipmap_blend = fract(lod);
|
||||
vec3 p0 = start_pos + dir * dist;
|
||||
|
||||
samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution.x);
|
||||
samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution);
|
||||
samplePos = samplePos * 0.5 + 0.5;
|
||||
|
||||
if ((any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0))))) {
|
||||
@ -328,9 +328,9 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
|
||||
}
|
||||
|
||||
|
||||
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel) {
|
||||
vec3 P = origin + dir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep;
|
||||
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
|
||||
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
|
||||
vec3 P = origin + dir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
|
||||
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, SHADOW_CONE_APERTURE, voxelgiStep, clipmaps);
|
||||
amount = clamp(amount, 0.0, 1.0);
|
||||
return amount * voxelgiOcc;
|
||||
}
|
||||
|
@ -21,29 +21,42 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
const int DIFFUSE_CONE_COUNT = 16;
|
||||
const float DIFFUSE_CONE_APERTURE = radians(45.0);
|
||||
|
||||
const vec3 DIFFUSE_CONE_DIRECTIONS[16] = {
|
||||
vec3(0.0000, 0.0000, 1.0000), // Central direction
|
||||
vec3(0.3827, 0.0000, 0.9239), // Ring 1
|
||||
vec3(-0.3827, 0.0000, 0.9239),
|
||||
vec3(0.0000, 0.3827, 0.9239),
|
||||
vec3(0.0000, -0.3827, 0.9239),
|
||||
vec3(0.2706, 0.2706, 0.9239), // Ring 2
|
||||
vec3(-0.2706, 0.2706, 0.9239),
|
||||
vec3(0.2706, -0.2706, 0.9239),
|
||||
vec3(-0.2706, -0.2706, 0.9239),
|
||||
vec3(0.1802, 0.3604, 0.9239), // Ring 3
|
||||
vec3(-0.1802, 0.3604, 0.9239),
|
||||
vec3(0.1802, -0.3604, 0.9239),
|
||||
vec3(-0.1802, -0.3604, 0.9239),
|
||||
vec3(0.3604, 0.1802, 0.9239),
|
||||
vec3(-0.3604, 0.1802, 0.9239),
|
||||
vec3(0.3604, -0.1802, 0.9239)
|
||||
};
|
||||
const float SHADOW_CONE_APERTURE = radians(15.0);
|
||||
|
||||
const float DIFFUSE_CONE_APERTURE = radians(50.0);
|
||||
|
||||
const float BayerMatrix8[8][8] =
|
||||
const vec3 DIFFUSE_CONE_DIRECTIONS[DIFFUSE_CONE_COUNT] = vec3[](
|
||||
vec3(0.0, 0.0, 1.0), // center
|
||||
|
||||
vec3(0.0, 0.5, 0.866),
|
||||
vec3(0.5, 0.0, 0.866),
|
||||
vec3(0.0, -0.5, 0.866),
|
||||
vec3(-0.5, 0.0, 0.866),
|
||||
|
||||
vec3(0.353, 0.353, 0.866),
|
||||
vec3(0.353, -0.353, 0.866),
|
||||
vec3(-0.353, -0.353, 0.866),
|
||||
vec3(-0.353, 0.353, 0.866),
|
||||
|
||||
vec3(0.707, 0.0, 0.707),
|
||||
vec3(0.0, 0.707, 0.707),
|
||||
vec3(-0.707, 0.0, 0.707),
|
||||
vec3(0.0, -0.707, 0.707),
|
||||
|
||||
vec3(0.5, 0.5, 0.707),
|
||||
vec3(-0.5, 0.5, 0.707),
|
||||
vec3(-0.5, -0.5, 0.707)
|
||||
);
|
||||
|
||||
mat3 makeTangentBasis(vec3 normal) {
|
||||
vec3 tangent = normalize(abs(normal.y) < 0.999 ? cross(normal, vec3(0, 1, 0)) : cross(normal, vec3(1, 0, 0)));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
return mat3(tangent, bitangent, normal);
|
||||
}
|
||||
|
||||
// TO DO - Disabled momentarily instead of changing formulas
|
||||
const float off_BayerMatrix8[8][8] =
|
||||
{
|
||||
{ 1.0 / 65.0, 49.0 / 65.0, 13.0 / 65.0, 61.0 / 65.0, 4.0 / 65.0, 52.0 / 65.0, 16.0 / 65.0, 64.0 / 65.0 },
|
||||
{ 33.0 / 65.0, 17.0 / 65.0, 45.0 / 65.0, 29.0 / 65.0, 36.0 / 65.0, 20.0 / 65.0, 48.0 / 65.0, 32.0 / 65.0 },
|
||||
@ -54,3 +67,15 @@ const float BayerMatrix8[8][8] =
|
||||
{ 11.0 / 65.0, 59.0 / 65.0, 7.0 / 65.0, 55.0 / 65.0, 10.0 / 65.0, 58.0 / 65.0, 6.0 / 65.0, 54.0 / 65.0 },
|
||||
{ 43.0 / 65.0, 27.0 / 65.0, 39.0 / 65.0, 23.0 / 65.0, 42.0 / 65.0, 26.0 / 65.0, 38.0 / 65.0, 22.0 / 65.0 }
|
||||
};
|
||||
const float BayerMatrix8[8][8] =
|
||||
{
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
|
||||
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 }
|
||||
};
|
||||
|
@ -1,239 +1,679 @@
|
||||
#ifndef _LIGHT_GLSL_
|
||||
#define _LIGHT_GLSL_
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _ShadowMap
|
||||
#include "std/shadows.glsl"
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
#include "std/conetrace.glsl"
|
||||
//!uniform sampler2D voxels_shadows;
|
||||
#endif
|
||||
#ifdef _LTC
|
||||
#include "std/ltc.glsl"
|
||||
#endif
|
||||
#ifdef _LightIES
|
||||
#include "std/ies.glsl"
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
#include "std/ssrs.glsl"
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#include "std/light_common.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
#ifndef _LTC
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
uniform mat4 LWVPSpot[1];
|
||||
#endif
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[1];
|
||||
uniform samplerCube shadowMapPointTransparent[1];
|
||||
uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlas;
|
||||
//!uniform sampler2D shadowMapAtlasTransparent;
|
||||
#endif
|
||||
uniform vec2 lightProj;
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
uniform sampler2D shadowMapAtlasPointTransparent;
|
||||
#endif
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[4];
|
||||
uniform samplerCube shadowMapPointTransparent[4];
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMapSpot[4];
|
||||
uniform sampler2D shadowMapSpotTransparent[4];
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
uniform vec3 lightArea0;
|
||||
uniform vec3 lightArea1;
|
||||
uniform vec3 lightArea2;
|
||||
uniform vec3 lightArea3;
|
||||
uniform sampler2D sltcMat;
|
||||
uniform sampler2D sltcMag;
|
||||
#ifdef _ShadowMap
|
||||
#ifndef _Spot
|
||||
#ifdef _SinglePoint
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
uniform mat4 LWVPSpot[1];
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
|
||||
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
||||
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
||||
#ifdef _ShadowMap
|
||||
, int index, float bias, bool receiveShadow, bool transparent
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, float occ
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
, sampler2D gbufferD, mat4 invVP, vec3 eye
|
||||
#endif
|
||||
) {
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
vec3 h = normalize(v + l);
|
||||
float dotNH = max(0.0, dot(n, h));
|
||||
float dotVH = max(0.0, dot(v, h));
|
||||
float dotNL = max(0.0, dot(n, l));
|
||||
|
||||
#ifdef _LTC
|
||||
float theta = acos(dotNV);
|
||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||
vec4 t = textureLod(sltcMat, tuv, 0.0);
|
||||
mat3 invM = mat3(
|
||||
vec3(1.0, 0.0, t.y),
|
||||
vec3(0.0, t.z, 0.0),
|
||||
vec3(t.w, 0.0, t.x));
|
||||
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
|
||||
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
|
||||
#else
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
|
||||
direct *= attenuate(distance(p, lp));
|
||||
direct *= lightCol;
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef _SSRS
|
||||
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelShadow
|
||||
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= shadowTest(
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, bias, transparent
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _LightIES
|
||||
direct *= iesAttenuation(-l);
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
#ifndef _Spot
|
||||
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= PCFFakeCube(
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
, ld, -l, bias, lightProj, n, index, transparent
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return direct;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef _LIGHT_GLSL_
|
||||
#define _LIGHT_GLSL_
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _ShadowMap
|
||||
#include "std/shadows.glsl"
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
#include "std/conetrace.glsl"
|
||||
#endif
|
||||
#ifdef _LTC
|
||||
#include "std/ltc.glsl"
|
||||
#endif
|
||||
#ifdef _LightIES
|
||||
#include "std/ies.glsl"
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
#include "std/ssrs.glsl"
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#include "std/light_common.glsl"
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
#include "std/conetrace.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
#ifndef _LTC
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[1];
|
||||
#endif
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[1];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform samplerCube shadowMapPointTransparent[1];
|
||||
#endif
|
||||
uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlas;
|
||||
#ifdef _ShadowMapTransparent
|
||||
//!uniform sampler2D shadowMapAtlasTransparent;
|
||||
#endif
|
||||
#endif
|
||||
uniform vec2 lightProj;
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapAtlasPointTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
uniform samplerCubeShadow shadowMapPoint[4];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform samplerCube shadowMapPointTransparent[4];
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMapSpot[4];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapSpotTransparent[4];
|
||||
#endif
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
uniform vec3 lightArea0;
|
||||
uniform vec3 lightArea1;
|
||||
uniform vec3 lightArea2;
|
||||
uniform vec3 lightArea3;
|
||||
uniform sampler2D sltcMat;
|
||||
uniform sampler2D sltcMag;
|
||||
#ifdef _ShadowMap
|
||||
#ifndef _Spot
|
||||
#ifdef _SinglePoint
|
||||
uniform sampler2DShadow shadowMapSpot[1];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapSpotTransparent[1];
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[1];
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
|
||||
#ifdef _ShadowMapTransparent
|
||||
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
|
||||
#endif
|
||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
||||
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
||||
#ifdef _ShadowMap
|
||||
, int index, float bias, bool receiveShadow
|
||||
#ifdef _ShadowMapTransparent
|
||||
, bool transparent
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount], vec2 velocity
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, float occ
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
, sampler2D gbufferD, mat4 invVP, vec3 eye
|
||||
#endif
|
||||
) {
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
vec3 h = normalize(v + l);
|
||||
float dotNH = max(0.0, dot(n, h));
|
||||
float dotVH = max(0.0, dot(v, h));
|
||||
float dotNL = max(0.0, dot(n, l));
|
||||
|
||||
#ifdef _LTC
|
||||
float theta = acos(dotNV);
|
||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||
vec4 t = textureLod(sltcMat, tuv, 0.0);
|
||||
mat3 invM = mat3(
|
||||
vec3(1.0, 0.0, t.y),
|
||||
vec3(0.0, t.z, 0.0),
|
||||
vec3(t.w, 0.0, t.x));
|
||||
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
|
||||
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
|
||||
#else
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
|
||||
direct *= attenuate(distance(p, lp));
|
||||
direct *= lightCol;
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef _SSRS
|
||||
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelShadow
|
||||
vec3 lightDir = l;
|
||||
#ifdef _Spot
|
||||
if (isSpot)
|
||||
lightDir = spotDir;
|
||||
#endif
|
||||
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, lightDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0);
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[1],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[2],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[3],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= shadowTest(
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[1],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[2],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[3],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _LightIES
|
||||
direct *= iesAttenuation(-l);
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
#ifndef _Spot
|
||||
direct *= PCFCube(shadowMapPoint[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[0],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= PCFFakeCube(
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
, ld, -l, bias, lightProj, n, index
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= PCFCube(shadowMapPoint[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[0],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= PCFCube(shadowMapPoint[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[1],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= PCFCube(shadowMapPoint[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[2],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= PCFCube(shadowMapPoint[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[3],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return direct;
|
||||
}
|
||||
|
||||
#ifdef _VoxelGI
|
||||
vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
||||
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
||||
#ifdef _ShadowMap
|
||||
, int index, float bias, bool receiveShadow
|
||||
#ifdef _ShadowMapTransparent
|
||||
, bool transparent
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
||||
#endif
|
||||
) {
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
vec3 h = normalize(v + l);
|
||||
float dotNH = max(0.0, dot(n, h));
|
||||
float dotVH = max(0.0, dot(v, h));
|
||||
float dotNL = max(0.0, dot(n, l));
|
||||
|
||||
#ifdef _LTC
|
||||
float theta = acos(dotNV);
|
||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||
vec4 t = textureLod(sltcMat, tuv, 0.0);
|
||||
mat3 invM = mat3(
|
||||
vec3(1.0, 0.0, t.y),
|
||||
vec3(0.0, t.z, 0.0),
|
||||
vec3(t.w, 0.0, t.x));
|
||||
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
|
||||
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
|
||||
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
|
||||
#else
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
|
||||
direct *= attenuate(distance(p, lp));
|
||||
direct *= lightCol;
|
||||
|
||||
#ifdef _LTC
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0);
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[1],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[2],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[3],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= shadowTest(
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSpot
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[0],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[1],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[2],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapSpotTransparent[3],
|
||||
#endif
|
||||
lPos.xyz / lPos.w, bias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _LightIES
|
||||
direct *= iesAttenuation(-l);
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
#ifndef _Spot
|
||||
direct *= PCFCube(shadowMapPoint[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[0],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
direct *= PCFFakeCube(
|
||||
#ifdef _ShadowMapTransparent
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#endif
|
||||
, ld, -l, bias, lightProj, n, index
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
if (index == 0) direct *= PCFCube(shadowMapPoint[0],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[0],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 1) direct *= PCFCube(shadowMapPoint[1],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[1],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 2) direct *= PCFCube(shadowMapPoint[2],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[2],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
else if (index == 3) direct *= PCFCube(shadowMapPoint[3],
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapPointTransparent[3],
|
||||
#endif
|
||||
ld, -l, bias, lightProj, n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return direct;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -58,7 +58,15 @@ vec2 sampleCube(vec3 dir, out int faceIndex) {
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 uv, const float compare, const vec2 smSize, const bool transparent) {
|
||||
vec3 PCF(sampler2DShadow shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
sampler2D shadowMapTransparent,
|
||||
#endif
|
||||
const vec2 uv, const float compare, const vec2 smSize
|
||||
#ifdef _ShadowMapTransparent
|
||||
, const bool transparent
|
||||
#endif
|
||||
) {
|
||||
vec3 result = vec3(0.0);
|
||||
result.x = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare));
|
||||
result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
|
||||
@ -71,11 +79,13 @@ vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 u
|
||||
result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare));
|
||||
result = result.xxx / 9.0;
|
||||
|
||||
#ifdef _ShadowMapTransparent
|
||||
if (transparent == false) {
|
||||
vec4 shadowmap_transparent = texture(shadowMapTransparent, uv);
|
||||
if (shadowmap_transparent.a < compare)
|
||||
result *= shadowmap_transparent.rgb;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -87,41 +97,15 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
|
||||
return zcomp * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
#ifndef _ShadowMapAtlas
|
||||
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, vec3 lp, vec3 ml, float bias, vec2 lightProj, vec3 n, const bool transparent) {
|
||||
const float s = shadowmapCubePcfSize;
|
||||
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
||||
ml = ml + n * bias * 20;
|
||||
#ifdef _InvY
|
||||
ml.y = -ml.y;
|
||||
#endif
|
||||
|
||||
float shadowFactor = 0.0;
|
||||
shadowFactor = texture(shadowMapCube, vec4(ml, compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, -s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, -s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, -s), compare));
|
||||
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
|
||||
shadowFactor /= 9.0;
|
||||
|
||||
vec3 result = vec3(shadowFactor);
|
||||
|
||||
if (transparent == false) {
|
||||
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
|
||||
if (shadowmap_transparent.a < compare)
|
||||
result *= shadowmap_transparent.rgb;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMapAtlas
|
||||
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const bool transparent) {
|
||||
vec3 PCFCube(samplerCubeShadow shadowMapCube,
|
||||
#ifdef _ShadowMapTransparent
|
||||
samplerCube shadowMapCubeTransparent,
|
||||
#endif
|
||||
const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n
|
||||
#ifdef _ShadowMapTransparent
|
||||
, const bool transparent
|
||||
#endif
|
||||
) {
|
||||
const float s = shadowmapCubePcfSize; // TODO: incorrect...
|
||||
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
||||
ml = ml + n * bias * 20;
|
||||
@ -140,16 +124,18 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTranspare
|
||||
result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
|
||||
result = result.xxx / 9.0;
|
||||
|
||||
#ifdef _ShadowMapTransparent
|
||||
if (transparent == false) {
|
||||
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
|
||||
if (shadowmap_transparent.a < compare)
|
||||
result *= shadowmap_transparent.rgb;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _ShadowMapAtlas
|
||||
// transform "out-of-bounds" coordinates to the correct face/coordinate system
|
||||
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
|
||||
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
|
||||
@ -243,89 +229,50 @@ vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec3 PCFFakeCube(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index, const bool transparent) {
|
||||
vec3 PCFFakeCube(sampler2DShadow shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
sampler2D shadowMapTransparent,
|
||||
#endif
|
||||
const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index
|
||||
#ifdef _ShadowMapTransparent
|
||||
, const bool transparent
|
||||
#endif
|
||||
) {
|
||||
const vec2 smSize = smSizeUniform; // TODO: incorrect...
|
||||
const float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
||||
ml = ml + n * bias * 20;
|
||||
|
||||
int faceIndex = 0;
|
||||
const int lightIndex = index * 6;
|
||||
const vec2 uv = sampleCube(ml, faceIndex);
|
||||
|
||||
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
|
||||
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
|
||||
if (any(lessThan(uvtiled, vec2(0.0))) || any(greaterThan(uvtiled, vec2(1.0)))) {
|
||||
return vec3(1.0); // Or handle edge cases differently
|
||||
}
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
// soft shadowing
|
||||
int newFaceIndex = 0;
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 0.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, -1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, 1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, -1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 0.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
|
||||
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 1.0) / smSize)));
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
// In PCFFakeCube(), modify the sampling pattern to be more robust:
|
||||
const vec2 offsets[9] = vec2[](
|
||||
vec2(0, 0),
|
||||
vec2(1, 0), vec2(-1, 0), vec2(0, 1), vec2(0, -1),
|
||||
vec2(1, 1), vec2(-1, 1), vec2(1, -1), vec2(-1, -1)
|
||||
);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
vec2 sampleUV = uv + offsets[i] / smSize;
|
||||
int newFaceIndex;
|
||||
vec2 transformedUV = transformOffsetedUV(faceIndex, newFaceIndex, sampleUV);
|
||||
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
|
||||
uvtiled = pointLightTile.z * transformedUV + pointLightTile.xy;
|
||||
#ifdef _FlipY
|
||||
uvtiled.y = 1.0 - uvtiled.y;
|
||||
#endif
|
||||
result.x += texture(shadowMap, vec3(uvtiled, compare));
|
||||
}
|
||||
result = result.xxx / 9.0;
|
||||
|
||||
pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
|
||||
@ -334,30 +281,47 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, cons
|
||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMapTransparent
|
||||
if (transparent == false) {
|
||||
vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled);
|
||||
if (shadowmap_transparent.a < compare)
|
||||
result *= shadowmap_transparent.rgb;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 shadowTest(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lPos, const float shadowsBias, const bool transparent) {
|
||||
vec3 shadowTest(sampler2DShadow shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
sampler2D shadowMapTransparent,
|
||||
#endif
|
||||
const vec3 lPos, const float shadowsBias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, const bool transparent
|
||||
#endif
|
||||
) {
|
||||
#ifdef _SMSizeUniform
|
||||
vec2 smSize = smSizeUniform;
|
||||
#else
|
||||
const vec2 smSize = shadowmapSize;
|
||||
#endif
|
||||
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0);
|
||||
return PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent);
|
||||
return PCF(shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapTransparent,
|
||||
#endif
|
||||
lPos.xy, lPos.z - shadowsBias, smSize
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef _CSM
|
||||
mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
|
||||
const int c = shadowmapCascades;
|
||||
|
||||
// Get cascade index
|
||||
// TODO: use bounding box slice selection instead of sphere
|
||||
const vec4 ci = vec4(float(c > 0), float(c > 1), float(c > 2), float(c > 3));
|
||||
@ -373,21 +337,26 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
|
||||
float(d > casData[c * 4].z),
|
||||
float(d > casData[c * 4].w));
|
||||
casi = int(min(dot(ci, comp), c));
|
||||
|
||||
// Get cascade mat
|
||||
casIndex = casi * 4;
|
||||
|
||||
return mat4(
|
||||
casData[casIndex ],
|
||||
casData[casIndex + 1],
|
||||
casData[casIndex + 2],
|
||||
casData[casIndex + 3]);
|
||||
|
||||
// if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]);
|
||||
// ..
|
||||
}
|
||||
|
||||
vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 eye, const vec3 p, const float shadowsBias, const bool transparent) {
|
||||
vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
sampler2D shadowMapTransparent,
|
||||
#endif
|
||||
const vec3 eye, const vec3 p, const float shadowsBias
|
||||
#ifdef _ShadowMapTransparent
|
||||
, const bool transparent
|
||||
#endif
|
||||
) {
|
||||
#ifdef _SMSizeUniform
|
||||
vec2 smSize = smSizeUniform;
|
||||
#else
|
||||
@ -395,16 +364,22 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
|
||||
#endif
|
||||
const int c = shadowmapCascades;
|
||||
float d = distance(eye, p);
|
||||
|
||||
int casi;
|
||||
int casIndex;
|
||||
mat4 LWVP = getCascadeMat(d, casi, casIndex);
|
||||
|
||||
vec4 lPos = LWVP * vec4(p, 1.0);
|
||||
lPos.xyz /= lPos.w;
|
||||
|
||||
vec3 visibility = vec3(1.0);
|
||||
if (lPos.w > 0.0) visibility = PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent);
|
||||
if (lPos.w > 0.0) visibility = PCF(shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapTransparent,
|
||||
#endif
|
||||
lPos.xy, lPos.z - shadowsBias, smSize
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
|
||||
// Blend cascade
|
||||
// https://github.com/TheRealMJP/Shadows
|
||||
@ -423,13 +398,20 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
|
||||
vec4 lPos2 = LWVP2 * vec4(p, 1.0);
|
||||
lPos2.xyz /= lPos2.w;
|
||||
vec3 visibility2 = vec3(1.0);
|
||||
if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, shadowMapTransparent, lPos2.xy, lPos2.z - shadowsBias, smSize, transparent);
|
||||
if (lPos2.w > 0.0) visibility2 = PCF(shadowMap,
|
||||
#ifdef _ShadowMapTransparent
|
||||
shadowMapTransparent,
|
||||
#endif
|
||||
lPos.xy, lPos.z - shadowsBias, smSize
|
||||
#ifdef _ShadowMapTransparent
|
||||
, transparent
|
||||
#endif
|
||||
);
|
||||
|
||||
float lerpAmt = smoothstep(0.0, blendThres, splitDist);
|
||||
return mix(visibility2, visibility, lerpAmt);
|
||||
}
|
||||
return visibility;
|
||||
|
||||
// Visualize cascades
|
||||
// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0);
|
||||
// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0);
|
||||
@ -437,4 +419,4 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
|
||||
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
@ -33,6 +33,7 @@ uniform layout(r32ui) uimage3D voxelsLight;
|
||||
|
||||
#ifdef _ShadowMap
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform sampler2D shadowMapTransparent;
|
||||
uniform sampler2DShadow shadowMapSpot;
|
||||
#ifdef _ShadowMapAtlas
|
||||
uniform sampler2DShadow shadowMapPoint;
|
||||
@ -86,30 +87,28 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
|
||||
|
||||
void main() {
|
||||
int res = voxelgiResolution.x;
|
||||
|
||||
ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
|
||||
dst.y += clipmapLevel * res;
|
||||
|
||||
vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
|
||||
P = P * 2.0 - 1.0;
|
||||
P *= clipmaps[int(clipmapLevel * 10)];
|
||||
P *= voxelgiResolution;
|
||||
P += vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)]);
|
||||
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
|
||||
wposition = wposition * 2.0 - 1.0;
|
||||
wposition *= float(clipmaps[int(clipmapLevel * 10)]);
|
||||
wposition *= voxelgiResolution.x;
|
||||
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
|
||||
|
||||
vec3 visibility;
|
||||
vec3 lp = lightPos - P;
|
||||
float visibility;
|
||||
vec3 lp = lightPos -wposition;
|
||||
vec3 l;
|
||||
if (lightType == 0) { l = lightDir; visibility = vec3(1.0); }
|
||||
else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); }
|
||||
if (lightType == 0) { l = lightDir; visibility = 1.0; }
|
||||
else { l = normalize(lp); visibility = attenuate(distance(wposition, lightPos)); }
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (lightShadow == 1) {
|
||||
vec4 lightPosition = LVP * vec4(P, 1.0);
|
||||
vec4 lightPosition = LVP * vec4(wposition, 1.0);
|
||||
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
||||
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr;
|
||||
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
|
||||
}
|
||||
else if (lightShadow == 2) {
|
||||
vec4 lightPosition = LVP * vec4(P, 1.0);
|
||||
vec4 lightPosition = LVP * vec4(wposition, 1.0);
|
||||
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
||||
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
|
||||
}
|
||||
@ -130,9 +129,7 @@ void main() {
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 light = visibility * lightColor;
|
||||
|
||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, 0), uint(light.r * 255));
|
||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(light.g * 255));
|
||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(light.b * 255));
|
||||
imageAtomicAdd(voxelsLight, dst, uint(visibility * lightColor.r * 255));
|
||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(visibility * lightColor.g * 255));
|
||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 255));
|
||||
}
|
||||
|
@ -27,14 +27,14 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
#include "std/math.glsl"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/voxels_constants.glsl"
|
||||
#include "std/constants.glsl"
|
||||
|
||||
#ifdef _VoxelGI
|
||||
uniform layout(rgba8) image3D voxelsB;
|
||||
uniform layout(rgba8) image3D voxelsOut;
|
||||
#else
|
||||
uniform layout(r16) image3D voxelsB;
|
||||
uniform layout(r16) image3D voxelsOut;
|
||||
uniform layout(r8) image3D voxelsB;
|
||||
uniform layout(r8) image3D voxelsOut;
|
||||
#endif
|
||||
|
||||
uniform int clipmapLevel;
|
||||
|
@ -29,19 +29,38 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/conetrace.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/shirr.glsl"
|
||||
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform layout(r8) image2D voxels_ao;
|
||||
uniform layout(rgba8) image2D voxels_ao;
|
||||
|
||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||
uniform mat4 InvVP;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 postprocess_resolution;
|
||||
|
||||
uniform sampler2D gbuffer1;
|
||||
#ifdef _gbuffer2
|
||||
uniform sampler2D gbuffer2;
|
||||
#endif
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
uniform float shirr[7 * 4];
|
||||
#endif
|
||||
#ifdef _Brdf
|
||||
uniform sampler2D senvmapBrdf;
|
||||
#endif
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
#ifdef _EnvCol
|
||||
uniform vec3 backgroundCol;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
const vec2 pixel = gl_GlobalInvocationID.xy;
|
||||
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
||||
@ -54,12 +73,11 @@ void main() {
|
||||
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = uv.y * 2 - 1;
|
||||
vec4 v = vec4(x, y, 1.0, 1.0);
|
||||
v = vec4(InvVP * v);
|
||||
v.xyz /= v.w;
|
||||
vec3 viewRay = v.xyz - eye;
|
||||
vec4 clipPos = vec4(x, y, depth, 1.0);
|
||||
vec4 worldPos = InvVP * clipPos;
|
||||
vec3 P = worldPos.xyz / worldPos.w;
|
||||
|
||||
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
vec3 v = normalize(eye - P);
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
vec3 n;
|
||||
@ -67,7 +85,89 @@ void main() {
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float occ = 1.0 - traceAO(P, n, voxels, clipmaps);
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
imageStore(voxels_ao, ivec2(pixel), vec4(occ));
|
||||
vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ
|
||||
vec2 occspec = unpackFloat2(g1.a);
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metallic);
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
vec4 g2 = textureLod(gbuffer2, uv, 0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
|
||||
#endif
|
||||
|
||||
#ifdef _Brdf
|
||||
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
|
||||
vec3 F = f0 * envBRDF.x + envBRDF.y;
|
||||
#endif
|
||||
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
vec4 shPacked[7];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int base = i * 4;
|
||||
shPacked[i] = vec4(
|
||||
shirr[base],
|
||||
shirr[base + 1],
|
||||
shirr[base + 2],
|
||||
shirr[base + 3]
|
||||
);
|
||||
}
|
||||
vec3 envl = shIrradiance(n, shPacked);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
if (g2.b < 0.5) {
|
||||
envl = envl;
|
||||
} else {
|
||||
envl = vec3(0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EnvTex
|
||||
envl /= PI;
|
||||
#endif
|
||||
#else
|
||||
vec3 envl = vec3(0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#endif
|
||||
|
||||
#ifdef _EnvLDR
|
||||
envl.rgb = pow(envl.rgb, vec3(2.2));
|
||||
#ifdef _Rad
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Brdf
|
||||
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
|
||||
#endif
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= envmapStrength * occspec.x;
|
||||
|
||||
vec3 occ = envl * (1.0 - traceAO(P, n, voxels, clipmaps));
|
||||
|
||||
imageStore(voxels_ao, ivec2(pixel), vec4(occ, 1.0));
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/conetrace.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/shirr.glsl"
|
||||
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler2D gbufferD;
|
||||
@ -37,29 +39,44 @@ uniform layout(rgba8) image2D voxels_diffuse;
|
||||
|
||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||
uniform mat4 InvVP;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 postprocess_resolution;
|
||||
|
||||
uniform sampler2D gbuffer1;
|
||||
#ifdef _gbuffer2
|
||||
uniform sampler2D gbuffer2;
|
||||
#endif
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
uniform float shirr[7 * 4];
|
||||
#endif
|
||||
#ifdef _Brdf
|
||||
uniform sampler2D senvmapBrdf;
|
||||
#endif
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
#ifdef _EnvCol
|
||||
uniform vec3 backgroundCol;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
const vec2 pixel = gl_GlobalInvocationID.xy;
|
||||
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
||||
#ifdef _InvY
|
||||
uv.y = 1.0 - uv.y
|
||||
uv.y = 1.0 - uv.y;
|
||||
#endif
|
||||
|
||||
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
|
||||
if (depth == 0) return;
|
||||
if (depth == 0.0) return;
|
||||
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = uv.y * 2 - 1;
|
||||
vec4 v = vec4(x, y, 1.0, 1.0);
|
||||
v = vec4(InvVP * v);
|
||||
v.xyz /= v.w;
|
||||
vec3 viewRay = v.xyz - eye;
|
||||
|
||||
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
vec4 clipPos = vec4(x, y, depth, 1.0);
|
||||
vec4 worldPos = InvVP * clipPos;
|
||||
vec3 P = worldPos.xyz / worldPos.w;
|
||||
vec3 v = normalize(eye - P);
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
vec3 n;
|
||||
@ -67,7 +84,91 @@ void main() {
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec4 color = traceDiffuse(P, n, voxels, clipmaps);
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
imageStore(voxels_diffuse, ivec2(pixel), color);
|
||||
vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ
|
||||
vec2 occspec = unpackFloat2(g1.a);
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metallic);
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
vec4 g2 = textureLod(gbuffer2, uv, 0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
|
||||
#endif
|
||||
|
||||
#ifdef _Brdf
|
||||
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
|
||||
vec3 F = f0 * envBRDF.x + envBRDF.y;
|
||||
#endif
|
||||
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
vec4 shPacked[7];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int base = i * 4;
|
||||
shPacked[i] = vec4(
|
||||
shirr[base],
|
||||
shirr[base + 1],
|
||||
shirr[base + 2],
|
||||
shirr[base + 3]
|
||||
);
|
||||
}
|
||||
vec3 envl = shIrradiance(n, shPacked);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
if (g2.b < 0.5) {
|
||||
envl = envl;
|
||||
} else {
|
||||
envl = vec3(0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EnvTex
|
||||
envl /= PI;
|
||||
#endif
|
||||
#else
|
||||
vec3 envl = vec3(0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#endif
|
||||
|
||||
#ifdef _EnvLDR
|
||||
envl.rgb = pow(envl.rgb, vec3(2.2));
|
||||
#ifdef _Rad
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Brdf
|
||||
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
|
||||
#endif
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= envmapStrength * occspec.x;
|
||||
|
||||
vec4 trace = traceDiffuse(P, n, voxels, clipmaps);
|
||||
vec3 color = trace.rgb * albedo * (1.0 - F);
|
||||
color += envl * (1.0 - trace.a);
|
||||
|
||||
imageStore(voxels_diffuse, ivec2(pixel), vec4(color, 1.0));
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2024 Turánszki János
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#version 450
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/math.glsl"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/conetrace.glsl"
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler3D voxelsSDF;
|
||||
uniform sampler2D gbuffer_refraction;
|
||||
uniform layout(rgba8) image2D voxels_refraction;
|
||||
|
||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||
uniform mat4 InvVP;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 postprocess_resolution;
|
||||
|
||||
void main() {
|
||||
const vec2 pixel = gl_GlobalInvocationID.xy;
|
||||
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
||||
#ifdef _InvY
|
||||
uv.y = 1.0 - uv.y
|
||||
#endif
|
||||
|
||||
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
|
||||
if (depth == 0) return;
|
||||
|
||||
vec2 ior_opac = textureLod(gbuffer_refraction, uv, 0.0).xy;
|
||||
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = uv.y * 2 - 1;
|
||||
vec4 v = vec4(x, y, 1.0, 1.0);
|
||||
v = vec4(InvVP * v);
|
||||
v.xyz /= v.w;
|
||||
vec3 viewRay = v.xyz - eye;
|
||||
|
||||
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
if(ior_opac.y < 1.0)
|
||||
color = traceRefraction(P, n, voxels, voxelsSDF, normalize(eye - P), ior_opac.x, g0.b, clipmaps, pixel).rgb;
|
||||
|
||||
imageStore(voxels_refraction, ivec2(pixel), vec4(color, 1.0));
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2024 Turánszki János
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#version 450
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/math.glsl"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/conetrace.glsl"
|
||||
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler3D voxelsSDF;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform layout(r16) image2D voxels_shadows;
|
||||
|
||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||
uniform mat4 InvVP;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 postprocess_resolution;
|
||||
uniform vec3 lPos;
|
||||
|
||||
void main() {
|
||||
const vec2 pixel = gl_GlobalInvocationID.xy;
|
||||
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
||||
#ifdef _InvY
|
||||
uv.y = 1.0 - uv.y;
|
||||
#endif
|
||||
|
||||
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
|
||||
if (depth == 0) return;
|
||||
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = uv.y * 2 - 1;
|
||||
vec4 v = vec4(x, y, 1.0, 1.0);
|
||||
v = vec4(InvVP * v);
|
||||
v.xyz /= v.w;
|
||||
vec3 viewRay = v.xyz - eye;
|
||||
|
||||
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float occ = 1.0 - traceShadow(P, n, voxels, voxelsSDF, normalize(lPos - P), clipmaps, pixel);
|
||||
|
||||
imageStore(voxels_shadows, ivec2(pixel), vec4(occ));
|
||||
}
|
@ -29,6 +29,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/imageatomic.glsl"
|
||||
#include "std/conetrace.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
@ -38,9 +39,7 @@ uniform layout(rgba8) image2D voxels_specular;
|
||||
|
||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||
uniform mat4 InvVP;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 postprocess_resolution;
|
||||
uniform sampler2D sveloc;
|
||||
|
||||
@ -56,12 +55,10 @@ void main() {
|
||||
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = uv.y * 2 - 1;
|
||||
vec4 v = vec4(x, y, 1.0, 1.0);
|
||||
v = vec4(InvVP * v);
|
||||
v.xyz /= v.w;
|
||||
vec4 clipPos = vec4(x, y, depth, 1.0);
|
||||
vec4 worldPos = InvVP * clipPos;
|
||||
vec3 P = worldPos.xyz / worldPos.w;
|
||||
|
||||
vec3 viewRay = v.xyz - eye;
|
||||
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
|
||||
|
||||
vec3 n;
|
||||
@ -71,7 +68,7 @@ void main() {
|
||||
|
||||
vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
|
||||
|
||||
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z, clipmaps, pixel, velocity).rgb;
|
||||
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z * g0.z, clipmaps, pixel, velocity).rgb;
|
||||
|
||||
imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ THE SOFTWARE.
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform layout(r16) image3D input_sdf;
|
||||
uniform layout(r16) image3D output_sdf;
|
||||
uniform layout(r8) image3D input_sdf;
|
||||
uniform layout(r8) image3D output_sdf;
|
||||
|
||||
uniform float jump_size;
|
||||
uniform int clipmapLevel;
|
||||
|
@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
|
||||
uniform layout(r32ui) uimage3D voxelsLight;
|
||||
uniform layout(rgba8) image3D voxelsB;
|
||||
uniform layout(rgba8) image3D voxelsOut;
|
||||
uniform layout(r16) image3D SDF;
|
||||
uniform layout(r8) image3D SDF;
|
||||
#else
|
||||
#ifdef _VoxelAOvar
|
||||
#ifdef _VoxelShadow
|
||||
uniform layout(r16) image3D SDF;
|
||||
uniform layout(r8) image3D SDF;
|
||||
#endif
|
||||
uniform layout(r32ui) uimage3D voxels;
|
||||
uniform layout(r16) image3D voxelsB;
|
||||
uniform layout(r16) image3D voxelsOut;
|
||||
uniform layout(r8) image3D voxelsB;
|
||||
uniform layout(r8) image3D voxelsOut;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -74,14 +74,8 @@ void main() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ivec3 src = ivec3(gl_GlobalInvocationID.xyz);
|
||||
#ifdef _VoxelGI
|
||||
vec3 light = vec3(0.0);
|
||||
light.r = float(imageLoad(voxelsLight, src)) / 255;
|
||||
light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
|
||||
light.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
|
||||
light /= 3;
|
||||
#endif
|
||||
mat3 TBN = mat3(1.0);
|
||||
vec3 avgNormal = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
|
||||
{
|
||||
@ -91,7 +85,7 @@ void main() {
|
||||
float aniso_colors[6];
|
||||
#endif
|
||||
|
||||
src = ivec3(gl_GlobalInvocationID.xyz);
|
||||
ivec3 src = ivec3(gl_GlobalInvocationID.xyz);
|
||||
src.x += i * res;
|
||||
ivec3 dst = src;
|
||||
dst.y += clipmapLevel * res;
|
||||
@ -104,44 +98,59 @@ void main() {
|
||||
|
||||
if (i < 6) {
|
||||
#ifdef _VoxelGI
|
||||
vec4 basecol = vec4(0.0);
|
||||
basecol.r = float(imageLoad(voxels, src)) / 255;
|
||||
basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
|
||||
basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
|
||||
basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255;
|
||||
basecol /= 4;
|
||||
vec3 emission = vec3(0.0);
|
||||
emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255;
|
||||
emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255;
|
||||
emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255;
|
||||
emission /= 3;
|
||||
vec3 N = vec3(0.0);
|
||||
N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255;
|
||||
N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255;
|
||||
N /= 2;
|
||||
vec3 wnormal = decode_oct(N.rg * 2 - 1);
|
||||
vec3 envl = vec3(0.0);
|
||||
envl.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 9))) / 255;
|
||||
envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
|
||||
envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
|
||||
envl /= 3;
|
||||
envl *= 100;
|
||||
int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 15)));
|
||||
if (count > 0) {
|
||||
vec4 basecol = vec4(0.0);
|
||||
basecol.r = float(imageLoad(voxels, src)) / 255;
|
||||
basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
|
||||
basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
|
||||
basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255;
|
||||
basecol /= count;
|
||||
vec3 emission = vec3(0.0);
|
||||
emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255;
|
||||
emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255;
|
||||
emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255;
|
||||
emission /= count;
|
||||
vec3 N = vec3(0.0);
|
||||
N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255;
|
||||
N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255;
|
||||
N /= count;
|
||||
N = decode_oct(N.rg * 2.0 - 1.0);
|
||||
avgNormal += N;
|
||||
|
||||
//clipmap to world
|
||||
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
|
||||
wposition = wposition * 2.0 - 1.0;
|
||||
wposition *= float(clipmaps[int(clipmapLevel * 10)]);
|
||||
wposition *= voxelgiResolution.x;
|
||||
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
|
||||
if (i == 5)
|
||||
TBN = makeTangentBasis(normalize(avgNormal));
|
||||
|
||||
radiance = basecol;
|
||||
vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
|
||||
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
|
||||
radiance.rgb *= light + indirect;
|
||||
radiance.rgb += emission.rgb;
|
||||
vec3 envl = vec3(0.0);
|
||||
envl.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 9))) / 255;
|
||||
envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
|
||||
envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
|
||||
envl /= count;
|
||||
vec3 light = vec3(0.0);
|
||||
light.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 12))) / 255;
|
||||
light.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 13))) / 255;
|
||||
light.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 14))) / 255;
|
||||
light /= count;
|
||||
|
||||
//clipmap to world
|
||||
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
|
||||
wposition = wposition * 2.0 - 1.0;
|
||||
wposition *= float(clipmaps[int(clipmapLevel * 10)]);
|
||||
wposition *= voxelgiResolution.x;
|
||||
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
|
||||
|
||||
radiance = basecol;
|
||||
vec4 trace = traceDiffuse(wposition, N, voxelsSampler, clipmaps);
|
||||
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
|
||||
radiance.rgb *= light + indirect;
|
||||
radiance.rgb += emission.rgb;
|
||||
}
|
||||
#else
|
||||
opac = float(imageLoad(voxels, src)) / 255;
|
||||
int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x)));
|
||||
if (count > 0) {
|
||||
opac = float(imageLoad(voxels, src)) / 255;
|
||||
opac /= count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
@ -195,7 +204,7 @@ void main() {
|
||||
}
|
||||
else {
|
||||
// precompute cone sampling:
|
||||
vec3 coneDirection = DIFFUSE_CONE_DIRECTIONS[i - 6];
|
||||
vec3 coneDirection = TBN * DIFFUSE_CONE_DIRECTIONS[i - 6];
|
||||
vec3 aniso_direction = -coneDirection;
|
||||
uvec3 face_offsets = uvec3(
|
||||
aniso_direction.x > 0 ? 0 : 1,
|
||||
|
@ -75,16 +75,17 @@ vec4 binarySearch(vec3 dir) {
|
||||
}
|
||||
|
||||
vec4 rayCast(vec3 dir) {
|
||||
#ifdef _CPostprocess
|
||||
dir *= PPComp9.x;
|
||||
#else
|
||||
dir *= ssrRayStep;
|
||||
#endif
|
||||
for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
}
|
||||
return vec4(0.0);
|
||||
float ddepth;
|
||||
dir *= ss_refractionRayStep;
|
||||
for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
ddepth = getDeltaDepth(hitCoord);
|
||||
if (ddepth > 0.0)
|
||||
return binarySearch(dir);
|
||||
}
|
||||
// No hit — fallback to projecting the ray to UV space
|
||||
vec2 fallbackUV = getProjectedCoord(hitCoord);
|
||||
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
|
||||
}
|
||||
#endif //SSR
|
||||
|
||||
|
@ -181,11 +181,15 @@ class Uniforms {
|
||||
// Multiple voxel volumes, always set params
|
||||
g.setImageTexture(context.textureUnits[j], rt.image); // image2D/3D
|
||||
if (rt.raw.name.startsWith("voxels_")) {
|
||||
g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter);
|
||||
g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.LinearMipFilter);
|
||||
}
|
||||
else if (rt.raw.name.startsWith("voxelsSDF"))
|
||||
{
|
||||
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.PointFilter, TextureFilter.PointFilter, MipMapFilter.NoMipFilter);
|
||||
}
|
||||
else if (rt.raw.name.startsWith("voxels"))
|
||||
{
|
||||
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter);
|
||||
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.PointMipFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -34,10 +34,10 @@ class Inc {
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
static var voxel_td1:kha.compute.TextureUnit;
|
||||
static var voxel_te1:kha.compute.TextureUnit;
|
||||
static var voxel_tf1:kha.compute.TextureUnit;
|
||||
static var voxel_cc1:kha.compute.ConstantLocation;
|
||||
#else
|
||||
#if lnx_voxelgi_shadows
|
||||
static var voxel_tf1:kha.compute.TextureUnit;
|
||||
static var voxel_te1:kha.compute.TextureUnit;
|
||||
#end
|
||||
#end
|
||||
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
|
||||
@ -53,12 +53,28 @@ class Inc {
|
||||
static var voxel_tb3:kha.compute.TextureUnit;
|
||||
static var voxel_tc3:kha.compute.TextureUnit;
|
||||
static var voxel_td3:kha.compute.TextureUnit;
|
||||
static var voxel_te3:kha.compute.TextureUnit;
|
||||
static var voxel_tf3:kha.compute.TextureUnit;
|
||||
#if lnx_brdf
|
||||
static var voxel_tg3:kha.compute.TextureUnit;
|
||||
#end
|
||||
#if lnx_radiance
|
||||
static var voxel_th3:kha.compute.TextureUnit;
|
||||
#end
|
||||
static var voxel_ca3:kha.compute.ConstantLocation;
|
||||
static var voxel_cb3:kha.compute.ConstantLocation;
|
||||
static var voxel_cc3:kha.compute.ConstantLocation;
|
||||
static var voxel_cd3:kha.compute.ConstantLocation;
|
||||
static var voxel_ce3:kha.compute.ConstantLocation;
|
||||
#if lnx_irradiance
|
||||
static var voxel_cf3:kha.compute.ConstantLocation;
|
||||
#end
|
||||
#if lnx_radiance
|
||||
static var voxel_cg3:kha.compute.ConstantLocation;
|
||||
#end
|
||||
#if lnx_envcol
|
||||
static var voxel_ch3:kha.compute.ConstantLocation;
|
||||
#end
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
static var voxel_sh4:kha.compute.Shader = null;
|
||||
static var voxel_ta4:kha.compute.TextureUnit;
|
||||
@ -71,33 +87,6 @@ class Inc {
|
||||
static var voxel_cb4:kha.compute.ConstantLocation;
|
||||
static var voxel_cc4:kha.compute.ConstantLocation;
|
||||
static var voxel_cd4:kha.compute.ConstantLocation;
|
||||
static var voxel_ce4:kha.compute.ConstantLocation;
|
||||
static var voxel_cf4:kha.compute.ConstantLocation;
|
||||
#end
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
static var voxel_sh5:kha.compute.Shader = null;
|
||||
static var voxel_ta5:kha.compute.TextureUnit;
|
||||
static var voxel_ca5:kha.compute.ConstantLocation;
|
||||
static var voxel_cb5:kha.compute.ConstantLocation;
|
||||
static var voxel_cc5:kha.compute.ConstantLocation;
|
||||
static var voxel_cd5:kha.compute.ConstantLocation;
|
||||
static var voxel_ce5:kha.compute.ConstantLocation;
|
||||
static var voxel_cf5:kha.compute.ConstantLocation;
|
||||
static var voxel_cg5:kha.compute.ConstantLocation;
|
||||
#if rp_shadowmap
|
||||
static var voxel_tb5:kha.compute.TextureUnit;
|
||||
static var voxel_tc5:kha.compute.TextureUnit;
|
||||
static var voxel_td5:kha.compute.TextureUnit;
|
||||
static var voxel_ch5:kha.compute.ConstantLocation;
|
||||
static var voxel_ci5:kha.compute.ConstantLocation;
|
||||
static var voxel_cj5:kha.compute.ConstantLocation;
|
||||
static var voxel_ck5:kha.compute.ConstantLocation;
|
||||
static var voxel_cl5:kha.compute.ConstantLocation;
|
||||
static var voxel_cm5:kha.compute.ConstantLocation;
|
||||
#if lnx_shadowmap_atlas
|
||||
static var m2 = iron.math.Mat4.identity();
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end //rp_voxels
|
||||
|
||||
@ -163,9 +152,11 @@ class Inc {
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlases) {
|
||||
path.bindTarget(atlas.target, atlas.target);
|
||||
}
|
||||
#if rp_shadowmap_transparent
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
|
||||
path.bindTarget(atlas.target, atlas.target);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
static function getShadowMapAtlas(atlas:ShadowMapAtlas, transparent: Bool):String {
|
||||
@ -206,24 +197,30 @@ class Inc {
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlases) {
|
||||
atlas.rejectedLights = [];
|
||||
}
|
||||
#if rp_shadowmap_transparent
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
|
||||
atlas.rejectedLights = [];
|
||||
}
|
||||
#end
|
||||
#end
|
||||
|
||||
for (light in iron.Scene.active.lights) {
|
||||
if (!light.lightInAtlas && !light.culledLight && light.visible && light.shadowMapScale > 0.0
|
||||
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
|
||||
ShadowMapAtlas.addLight(light, false);
|
||||
}
|
||||
#if rp_shadowmap_transparent
|
||||
if (!light.lightInAtlasTransparent && !light.culledLight && light.visible && light.shadowMapScale > 0.0
|
||||
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
|
||||
ShadowMapAtlas.addLight(light, true);
|
||||
}
|
||||
#end
|
||||
}
|
||||
// update point light data before rendering
|
||||
updatePointLightAtlasData(true);
|
||||
updatePointLightAtlasData(false);
|
||||
#if rp_shadowmap_transparent
|
||||
updatePointLightAtlasData(true);
|
||||
#end
|
||||
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlases) {
|
||||
var tilesToRemove = [];
|
||||
@ -301,6 +298,7 @@ class Inc {
|
||||
path.endStream();
|
||||
}
|
||||
|
||||
#if rp_shadowmap_transparent
|
||||
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
|
||||
var tilesToRemove = [];
|
||||
#if lnx_shadowmap_atlas_lod
|
||||
@ -395,10 +393,8 @@ class Inc {
|
||||
tile.freeTile();
|
||||
}
|
||||
}
|
||||
#if lnx_debug
|
||||
endShadowsLogicProfile();
|
||||
#end
|
||||
#end // rp_shadowmap
|
||||
#end
|
||||
}
|
||||
#else
|
||||
public static function bindShadowMap() {
|
||||
@ -501,6 +497,7 @@ class Inc {
|
||||
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
|
||||
}
|
||||
|
||||
#if rp_shadowmap_transparent
|
||||
pointIndex = 0;
|
||||
spotIndex = 0;
|
||||
for (l in iron.Scene.active.lights) {
|
||||
@ -522,6 +519,7 @@ class Inc {
|
||||
if (l.data.raw.type == "point") pointIndex++;
|
||||
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
|
||||
}
|
||||
#end
|
||||
#end // rp_shadowmap
|
||||
}
|
||||
#end
|
||||
@ -589,7 +587,7 @@ class Inc {
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = getDisplayp();
|
||||
t.format = "R32";
|
||||
t.format = "R16";
|
||||
t.scale = getSuperSampling();
|
||||
t.depth_buffer = "main";
|
||||
path.createRenderTarget(t);
|
||||
@ -615,10 +613,14 @@ class Inc {
|
||||
#end
|
||||
|
||||
#if (rp_voxels != "Off")
|
||||
{
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
}
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
#end
|
||||
#end
|
||||
|
||||
#if rp_ssrs
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
#end
|
||||
|
||||
path.drawMeshes("translucent");
|
||||
@ -679,12 +681,11 @@ class Inc {
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = getDisplayp();
|
||||
//t.scale = Inc.getSuperSampling();
|
||||
t.format = t.name == "voxels_ao" ? "R8" : "RGBA32";
|
||||
t.format = "RGBA32";
|
||||
}
|
||||
else {
|
||||
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
|
||||
t.format = "R16";
|
||||
t.format = "R8";
|
||||
t.width = res;
|
||||
t.height = res * Main.voxelgiClipmapCount;
|
||||
t.depth = res;
|
||||
@ -693,16 +694,16 @@ class Inc {
|
||||
#if (rp_voxels == "Voxel AO")
|
||||
{
|
||||
if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
|
||||
t.format = "R16";
|
||||
t.format = "R8";
|
||||
t.width = res * (6 + 16);
|
||||
t.height = res * Main.voxelgiClipmapCount;
|
||||
t.depth = res;
|
||||
}
|
||||
else {
|
||||
t.format = "R32";
|
||||
t.format = "R32UI";
|
||||
t.width = res * 6;
|
||||
t.height = res;
|
||||
t.depth = res;
|
||||
t.depth = res * 2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -713,17 +714,11 @@ class Inc {
|
||||
t.height = res * Main.voxelgiClipmapCount;
|
||||
t.depth = res;
|
||||
}
|
||||
else if (t.name == "voxelsLight") {
|
||||
t.format = "R32";
|
||||
t.width = res;
|
||||
t.height = res;
|
||||
t.depth = res * 3;
|
||||
}
|
||||
else {
|
||||
t.format = "R32";
|
||||
t.format = "R32UI";
|
||||
t.width = res * 6;
|
||||
t.height = res;
|
||||
t.depth = res * 12;
|
||||
t.depth = res * 16;
|
||||
}
|
||||
}
|
||||
#end
|
||||
@ -835,14 +830,15 @@ class Inc {
|
||||
|
||||
voxel_ca1 = voxel_sh1.getConstantLocation("clipmaps");
|
||||
voxel_cb1 = voxel_sh1.getConstantLocation("clipmapLevel");
|
||||
voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength");
|
||||
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
voxel_td1 = voxel_sh1.getTextureUnit("voxelsSampler");
|
||||
voxel_te1 = voxel_sh1.getTextureUnit("voxelsLight");
|
||||
voxel_tf1 = voxel_sh1.getTextureUnit("SDF");
|
||||
voxel_te1 = voxel_sh1.getTextureUnit("SDF");
|
||||
voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength");
|
||||
#else
|
||||
#if lnx_voxelgi_shadows
|
||||
voxel_tf1 = voxel_sh1.getTextureUnit("SDF");
|
||||
voxel_te1 = voxel_sh1.getTextureUnit("SDF");
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@ -873,12 +869,28 @@ class Inc {
|
||||
#else
|
||||
voxel_td3 = voxel_sh3.getTextureUnit("voxels_diffuse");
|
||||
#end
|
||||
voxel_ca3 = voxel_sh3.getConstantLocation("clipmaps");
|
||||
voxel_te3 = voxel_sh3.getTextureUnit("gbuffer1");
|
||||
voxel_tf3 = voxel_sh3.getTextureUnit("gbuffer2");
|
||||
#if lnx_brdf
|
||||
voxel_tg3 = voxel_sh3.getTextureUnit("senvmapBrdf");
|
||||
#end
|
||||
#if lnx_radiance
|
||||
voxel_th3 = voxel_sh3.getTextureUnit("senvmapRadiance");
|
||||
#end
|
||||
voxel_ca3 = voxel_sh3.getConstantLocation("clipmaps");
|
||||
voxel_cb3 = voxel_sh3.getConstantLocation("InvVP");
|
||||
voxel_cc3 = voxel_sh3.getConstantLocation("cameraProj");
|
||||
voxel_cd3 = voxel_sh3.getConstantLocation("eye");
|
||||
voxel_ce3 = voxel_sh3.getConstantLocation("eyeLook");
|
||||
voxel_cf3 = voxel_sh3.getConstantLocation("postprocess_resolution");
|
||||
voxel_cc3 = voxel_sh3.getConstantLocation("eye");
|
||||
voxel_cd3 = voxel_sh3.getConstantLocation("postprocess_resolution");
|
||||
voxel_ce3 = voxel_sh3.getConstantLocation("envmapStrength");
|
||||
#if lnx_irradiance
|
||||
voxel_cf3 = voxel_sh3.getConstantLocation("shirr");
|
||||
#end
|
||||
#if lnx_radiance
|
||||
voxel_cg3 = voxel_sh3.getConstantLocation("envmapNumMipmaps");
|
||||
#end
|
||||
#if lnx_envcol
|
||||
voxel_ch3 = voxel_sh3.getConstantLocation("backgroundCol");
|
||||
#end
|
||||
}
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
if (voxel_sh4 == null)
|
||||
@ -892,40 +904,8 @@ class Inc {
|
||||
voxel_tf4 = voxel_sh4.getTextureUnit("sveloc");
|
||||
voxel_ca4 = voxel_sh4.getConstantLocation("clipmaps");
|
||||
voxel_cb4 = voxel_sh4.getConstantLocation("InvVP");
|
||||
voxel_cc4 = voxel_sh4.getConstantLocation("cameraProj");
|
||||
voxel_cd4 = voxel_sh4.getConstantLocation("eye");
|
||||
voxel_ce4 = voxel_sh4.getConstantLocation("eyeLook");
|
||||
voxel_cf4 = voxel_sh4.getConstantLocation("postprocess_resolution");
|
||||
}
|
||||
#end
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
if (voxel_sh5 == null)
|
||||
{
|
||||
voxel_sh5 = path.getComputeShader("voxel_light");
|
||||
voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
|
||||
|
||||
voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps");
|
||||
voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
|
||||
|
||||
voxel_cc5 = voxel_sh5.getConstantLocation("lightPos");
|
||||
voxel_cd5 = voxel_sh5.getConstantLocation("lightColor");
|
||||
voxel_ce5 = voxel_sh5.getConstantLocation("lightType");
|
||||
voxel_cf5 = voxel_sh5.getConstantLocation("lightDir");
|
||||
voxel_cg5 = voxel_sh5.getConstantLocation("spotData");
|
||||
#if rp_shadowmap
|
||||
voxel_tb5 = voxel_sh5.getTextureUnit("shadowMap");
|
||||
voxel_tc5 = voxel_sh5.getTextureUnit("shadowMapSpot");
|
||||
voxel_td5 = voxel_sh5.getTextureUnit("shadowMapPoint");
|
||||
|
||||
voxel_ch5 = voxel_sh5.getConstantLocation("lightShadow");
|
||||
voxel_ci5 = voxel_sh5.getConstantLocation("lightProj");
|
||||
voxel_cj5 = voxel_sh5.getConstantLocation("LVP");
|
||||
voxel_ck5 = voxel_sh5.getConstantLocation("shadowsBias");
|
||||
#if lnx_shadowmap_atlas
|
||||
voxel_cl5 = voxel_sh5.getConstantLocation("index");
|
||||
voxel_cm5 = voxel_sh5.getConstantLocation("pointLightDataArray");
|
||||
#end
|
||||
#end
|
||||
voxel_cc4 = voxel_sh4.getConstantLocation("eye");
|
||||
voxel_cd4 = voxel_sh4.getConstantLocation("postprocess_resolution");
|
||||
}
|
||||
#end
|
||||
}
|
||||
@ -976,11 +956,11 @@ class Inc {
|
||||
kha.compute.Compute.setTexture(voxel_tc1, rts.get("voxelsOut").image, kha.compute.Access.Write);
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
kha.compute.Compute.setSampledTexture(voxel_td1, rts.get("voxelsOutB").image);
|
||||
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsLight").image, kha.compute.Access.Read);
|
||||
kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
|
||||
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
|
||||
kha.compute.Compute.setFloat(voxel_cc1, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
|
||||
#else
|
||||
#if lnx_voxelgi_shadows
|
||||
kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
|
||||
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
|
||||
#end
|
||||
#end
|
||||
|
||||
@ -1002,6 +982,8 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setInt(voxel_cb1, iron.RenderPath.clipmapLevel);
|
||||
|
||||
kha.compute.Compute.setFloat(voxel_cc1, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
|
||||
|
||||
kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8));
|
||||
}
|
||||
|
||||
@ -1054,6 +1036,7 @@ class Inc {
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_voxels == "Voxel AO")
|
||||
public static function resolveAO() {
|
||||
var rts = path.renderTargets;
|
||||
@ -1066,13 +1049,20 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
|
||||
#if lnx_deferred
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("lbuffer1").image);
|
||||
#end
|
||||
kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_ao").image, kha.compute.Access.Write);
|
||||
|
||||
kha.compute.Compute.setSampledTexture(voxel_te3, rts.get("gbuffer1").image);
|
||||
#if rp_gbuffer2
|
||||
kha.compute.Compute.setSampledTexture(voxel_tf3, rts.get("gbuffer2").image);
|
||||
#end
|
||||
#if lnx_brdf
|
||||
kha.compute.Compute.setSampledTexture(voxel_tg3, iron.Scene.active.embedded.get("brdf.png"));
|
||||
#end
|
||||
#if lnx_radiance
|
||||
kha.compute.Compute.setSampledTexture(voxel_th3, iron.Scene.active.world.probe.radiance);
|
||||
#end
|
||||
|
||||
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||
for (i in 0...Main.voxelgiClipmapCount) {
|
||||
fa[i * 10] = clipmaps[i].voxelSize;
|
||||
@ -1099,18 +1089,7 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setMatrix(voxel_cb3, m.self);
|
||||
|
||||
var near = camera.data.raw.near_plane;
|
||||
var far = camera.data.raw.far_plane;
|
||||
var v = new iron.math.Vec2();
|
||||
v.x = far / (far - near);
|
||||
v.y = (-far * near) / (far - near);
|
||||
|
||||
kha.compute.Compute.setFloat2(voxel_cc3, v.x, v.y);
|
||||
|
||||
|
||||
kha.compute.Compute.setFloat3(voxel_cd3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
var eyeLook = camera.lookWorld().normalize();
|
||||
kha.compute.Compute.setFloat3(voxel_ce3, eyeLook.x, eyeLook.y, eyeLook.z);
|
||||
kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
|
||||
var width = iron.App.w();
|
||||
var height = iron.App.h();
|
||||
@ -1125,7 +1104,32 @@ class Inc {
|
||||
width = Std.int(dp * Inc.getSuperSampling());
|
||||
}
|
||||
}
|
||||
kha.compute.Compute.setFloat2(voxel_cf3, width, height);
|
||||
kha.compute.Compute.setFloat2(voxel_cd3, width, height);
|
||||
|
||||
kha.compute.Compute.setFloat(voxel_ce3, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
|
||||
#if lnx_irradiance
|
||||
var irradiance = iron.Scene.active.world == null ?
|
||||
iron.data.WorldData.getEmptyIrradiance() :
|
||||
iron.Scene.active.world.probe.irradiance;
|
||||
kha.compute.Compute.setFloats(voxel_cf3, irradiance);
|
||||
#end
|
||||
#if lnx_radiance
|
||||
kha.compute.Compute.setFloat(voxel_cg3, iron.Scene.active.world != null ? iron.Scene.active.world.probe.raw.radiance_mipmaps + 1 - 2 : 1);
|
||||
#end
|
||||
|
||||
#if lnx_envcol
|
||||
var x: kha.FastFloat = 0.0;
|
||||
var y: kha.FastFloat = 0.0;
|
||||
var z: kha.FastFloat = 0.0;
|
||||
|
||||
if (camera.data.raw.clear_color != null) {
|
||||
x = camera.data.raw.clear_color[0];
|
||||
y = camera.data.raw.clear_color[1];
|
||||
z = camera.data.raw.clear_color[2];
|
||||
}
|
||||
|
||||
kha.compute.Compute.setFloat3(voxel_ch3, x, y, z);
|
||||
#end
|
||||
|
||||
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
|
||||
}
|
||||
@ -1141,12 +1145,18 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
|
||||
#if lnx_deferred
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("lbuffer1").image);
|
||||
#end
|
||||
kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_diffuse").image, kha.compute.Access.Write);
|
||||
kha.compute.Compute.setSampledTexture(voxel_te3, rts.get("gbuffer1").image);
|
||||
#if rp_gbuffer2
|
||||
kha.compute.Compute.setSampledTexture(voxel_tf3, rts.get("gbuffer2").image);
|
||||
#end
|
||||
#if lnx_brdf
|
||||
kha.compute.Compute.setSampledTexture(voxel_tg3, iron.Scene.active.embedded.get("brdf.png"));
|
||||
#end
|
||||
#if lnx_radiance
|
||||
kha.compute.Compute.setSampledTexture(voxel_th3, iron.Scene.active.world.probe.radiance);
|
||||
#end
|
||||
|
||||
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||
for (i in 0...Main.voxelgiClipmapCount) {
|
||||
@ -1174,18 +1184,7 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setMatrix(voxel_cb3, m.self);
|
||||
|
||||
var near = camera.data.raw.near_plane;
|
||||
var far = camera.data.raw.far_plane;
|
||||
var v = new iron.math.Vec2();
|
||||
v.x = far / (far - near);
|
||||
v.y = (-far * near) / (far - near);
|
||||
|
||||
kha.compute.Compute.setFloat2(voxel_cc3, v.x, v.y);
|
||||
|
||||
|
||||
kha.compute.Compute.setFloat3(voxel_cd3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
var eyeLook = camera.lookWorld().normalize();
|
||||
kha.compute.Compute.setFloat3(voxel_ce3, eyeLook.x, eyeLook.y, eyeLook.z);
|
||||
kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
|
||||
var width = iron.App.w();
|
||||
var height = iron.App.h();
|
||||
@ -1200,7 +1199,32 @@ class Inc {
|
||||
width = Std.int(dp * Inc.getSuperSampling());
|
||||
}
|
||||
}
|
||||
kha.compute.Compute.setFloat2(voxel_cf3, width, height);
|
||||
kha.compute.Compute.setFloat2(voxel_cd3, width, height);
|
||||
|
||||
kha.compute.Compute.setFloat(voxel_ce3, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
|
||||
#if lnx_irradiance
|
||||
var irradiance = iron.Scene.active.world == null ?
|
||||
iron.data.WorldData.getEmptyIrradiance() :
|
||||
iron.Scene.active.world.probe.irradiance;
|
||||
kha.compute.Compute.setFloats(voxel_cf3, irradiance);
|
||||
#end
|
||||
#if lnx_radiance
|
||||
kha.compute.Compute.setFloat(voxel_cg3, iron.Scene.active.world != null ? iron.Scene.active.world.probe.raw.radiance_mipmaps + 1 - 2 : 1);
|
||||
#end
|
||||
|
||||
#if lnx_envcol
|
||||
var x: kha.FastFloat = 0.0;
|
||||
var y: kha.FastFloat = 0.0;
|
||||
var z: kha.FastFloat = 0.0;
|
||||
|
||||
if (camera.data.raw.clear_color != null) {
|
||||
x = camera.data.raw.clear_color[0];
|
||||
y = camera.data.raw.clear_color[1];
|
||||
z = camera.data.raw.clear_color[2];
|
||||
}
|
||||
|
||||
kha.compute.Compute.setFloat3(voxel_ch3, x, y, z);
|
||||
#end
|
||||
|
||||
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
|
||||
}
|
||||
@ -1216,15 +1240,12 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setSampledTexture(voxel_ta4, rts.get("voxelsOut").image);
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb4, rts.get("half").image);
|
||||
#if lnx_deferred
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("gbuffer0").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("lbuffer1").image);
|
||||
#end
|
||||
kha.compute.Compute.setSampledTexture(voxel_td4, rts.get("voxelsSDF").image);
|
||||
kha.compute.Compute.setTexture(voxel_te4, rts.get("voxels_specular").image, kha.compute.Access.Write);
|
||||
|
||||
//kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
|
||||
#if rp_gbuffer2
|
||||
kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
|
||||
#end
|
||||
|
||||
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||
for (i in 0...Main.voxelgiClipmapCount) {
|
||||
@ -1252,18 +1273,7 @@ class Inc {
|
||||
|
||||
kha.compute.Compute.setMatrix(voxel_cb4, m.self);
|
||||
|
||||
var near = camera.data.raw.near_plane;
|
||||
var far = camera.data.raw.far_plane;
|
||||
var v = new iron.math.Vec2();
|
||||
v.x = far / (far - near);
|
||||
v.y = (-far * near) / (far - near);
|
||||
|
||||
kha.compute.Compute.setFloat2(voxel_cc4, v.x, v.y);
|
||||
|
||||
|
||||
kha.compute.Compute.setFloat3(voxel_cd4, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
var eyeLook = camera.lookWorld().normalize();
|
||||
kha.compute.Compute.setFloat3(voxel_ce4, eyeLook.x, eyeLook.y, eyeLook.z);
|
||||
kha.compute.Compute.setFloat3(voxel_cc4, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
|
||||
|
||||
var width = iron.App.w();
|
||||
var height = iron.App.h();
|
||||
@ -1278,146 +1288,10 @@ class Inc {
|
||||
width = Std.int(dp * Inc.getSuperSampling());
|
||||
}
|
||||
}
|
||||
kha.compute.Compute.setFloat2(voxel_cf4, width, height);
|
||||
kha.compute.Compute.setFloat2(voxel_cd4, width, height);
|
||||
|
||||
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
|
||||
}
|
||||
public static function computeVoxelsLight() {
|
||||
var rts = path.renderTargets;
|
||||
var res = iron.RenderPath.getVoxelRes();
|
||||
var camera = iron.Scene.active.camera;
|
||||
var clipmaps = iron.RenderPath.clipmaps;
|
||||
var clipmap = clipmaps[iron.RenderPath.clipmapLevel];
|
||||
var lights = iron.Scene.active.lights;
|
||||
|
||||
pointIndex = spotIndex = 0;
|
||||
for (i in 0...lights.length) {
|
||||
var l = lights[i];
|
||||
if (!l.visible) continue;
|
||||
path.light = l;
|
||||
|
||||
kha.compute.Compute.setShader(voxel_sh5);
|
||||
|
||||
kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write);
|
||||
|
||||
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||
for (i in 0...Main.voxelgiClipmapCount) {
|
||||
fa[i * 10] = clipmaps[i].voxelSize;
|
||||
fa[i * 10 + 1] = clipmaps[i].extents.x;
|
||||
fa[i * 10 + 2] = clipmaps[i].extents.y;
|
||||
fa[i * 10 + 3] = clipmaps[i].extents.z;
|
||||
fa[i * 10 + 4] = clipmaps[i].center.x;
|
||||
fa[i * 10 + 5] = clipmaps[i].center.y;
|
||||
fa[i * 10 + 6] = clipmaps[i].center.z;
|
||||
fa[i * 10 + 7] = clipmaps[i].offset_prev.x;
|
||||
fa[i * 10 + 8] = clipmaps[i].offset_prev.y;
|
||||
fa[i * 10 + 9] = clipmaps[i].offset_prev.z;
|
||||
}
|
||||
|
||||
kha.compute.Compute.setFloats(voxel_ca5, fa);
|
||||
|
||||
kha.compute.Compute.setInt(voxel_cb5, iron.RenderPath.clipmapLevel);
|
||||
|
||||
#if rp_shadowmap
|
||||
if (l.data.raw.type == "sun") {
|
||||
#if lnx_shadowmap_atlas
|
||||
#if lnx_shadowmap_atlas_single_map
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMapAtlas").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMapAtlasSun").image);
|
||||
#end
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMap").image);
|
||||
#end
|
||||
kha.compute.Compute.setInt(voxel_ch5, 1); // lightShadow
|
||||
}
|
||||
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") {
|
||||
#if lnx_shadowmap_atlas
|
||||
#if lnx_shadowmap_atlas_single_map
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapAtlas").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapAtlasSpot").image);
|
||||
#end
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapSpot[" + spotIndex + "]").image);
|
||||
spotIndex++;
|
||||
#end
|
||||
kha.compute.Compute.setInt(voxel_ch5, 2);
|
||||
}
|
||||
else {
|
||||
#if lnx_shadowmap_atlas
|
||||
#if lnx_shadowmap_atlas_single_map
|
||||
kha.compute.Compute.setSampledTexture(voxel_td5, rts.get("shadowMapAtlas").image);
|
||||
#else
|
||||
kha.compute.Compute.setSampledTexture(voxel_td5, rts.get("shadowMapAtlasPoint").image);
|
||||
kha.compute.Compute.setInt(voxel_cl5, i);
|
||||
kha.compute.Compute.setFloats(voxel_cm5, iron.object.LightObject.pointLightsData);
|
||||
#end
|
||||
#else
|
||||
kha.compute.Compute.setSampledCubeMap(voxel_td5, rts.get("shadowMapPoint[" + pointIndex + "]").cubeMap);
|
||||
pointIndex++;
|
||||
#end
|
||||
kha.compute.Compute.setInt(voxel_ch5, 3);
|
||||
}
|
||||
|
||||
// lightProj
|
||||
var near = l.data.raw.near_plane;
|
||||
var far = l.data.raw.far_plane;
|
||||
var a:kha.FastFloat = far + near;
|
||||
var b:kha.FastFloat = far - near;
|
||||
var f2:kha.FastFloat = 2.0;
|
||||
var c:kha.FastFloat = f2 * far * near;
|
||||
var vx:kha.FastFloat = a / b;
|
||||
var vy:kha.FastFloat = c / b;
|
||||
kha.compute.Compute.setFloat2(voxel_ci5, vx, vy);
|
||||
// LVP
|
||||
m.setFrom(l.VP);
|
||||
m.multmat(iron.object.Uniforms.biasMat);
|
||||
#if lnx_shadowmap_atlas
|
||||
if (l.data.raw.type == "sun")
|
||||
{
|
||||
// tile matrix
|
||||
m.setIdentity();
|
||||
// scale [0-1] coords to [0-tilescale]
|
||||
m2._00 = l.tileScale[0];
|
||||
m2._11 = l.tileScale[0];
|
||||
// offset coordinate start from [0, 0] to [tile-start-x, tile-start-y]
|
||||
m2._30 = l.tileOffsetX[0];
|
||||
m2._31 = l.tileOffsetY[0];
|
||||
m.multmat(m2);
|
||||
#if (!kha_opengl)
|
||||
m2.setIdentity();
|
||||
m2._11 = -1.0;
|
||||
m2._31 = 1.0;
|
||||
m.multmat(m2);
|
||||
#end
|
||||
}
|
||||
#end
|
||||
kha.compute.Compute.setMatrix(voxel_cj5, m.self);
|
||||
// shadowsBias
|
||||
kha.compute.Compute.setFloat(voxel_ck5, l.data.raw.shadows_bias);
|
||||
#end // rp_shadowmap
|
||||
|
||||
// lightPos
|
||||
kha.compute.Compute.setFloat3(voxel_cc5, l.transform.worldx(), l.transform.worldy(), l.transform.worldz());
|
||||
// lightCol
|
||||
var f = l.data.raw.strength;
|
||||
kha.compute.Compute.setFloat3(voxel_cd5, l.data.raw.color[0] * f, l.data.raw.color[1] * f, l.data.raw.color[2] * f);
|
||||
// lightType
|
||||
kha.compute.Compute.setInt(voxel_ce5, iron.data.LightData.typeToInt(l.data.raw.type));
|
||||
// lightDir
|
||||
var v = l.look();
|
||||
kha.compute.Compute.setFloat3(voxel_cf5, v.x, v.y, v.z);
|
||||
// spotData
|
||||
if (l.data.raw.type == "spot") {
|
||||
var vx = l.data.raw.spot_size;
|
||||
var vy = vx - l.data.raw.spot_blend;
|
||||
kha.compute.Compute.setFloat2(voxel_cg5, vx, vy);
|
||||
}
|
||||
|
||||
kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8));
|
||||
}
|
||||
}
|
||||
#end // GI
|
||||
#end // Voxels
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ class RenderPathDeferred {
|
||||
static var bloomUpsampler: Upsampler;
|
||||
#end
|
||||
|
||||
#if (rp_ssgi == "SSGI")
|
||||
static var ssgitex = "singleb";
|
||||
static var ssgitexb = "singleb";
|
||||
#end
|
||||
|
||||
public static inline function setTargetMeshes() {
|
||||
//Always keep the order of render targets the same as defined in compiled.inc
|
||||
path.setTarget("gbuffer0", [
|
||||
@ -57,12 +62,11 @@ class RenderPathDeferred {
|
||||
Inc.initGI("voxels");
|
||||
Inc.initGI("voxelsOut");
|
||||
Inc.initGI("voxelsOutB");
|
||||
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
Inc.initGI("voxelsSDF");
|
||||
Inc.initGI("voxelsSDFtmp");
|
||||
#end
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
Inc.initGI("voxelsLight");
|
||||
Inc.initGI("voxels_diffuse");
|
||||
Inc.initGI("voxels_specular");
|
||||
#else
|
||||
@ -195,24 +199,94 @@ class RenderPathDeferred {
|
||||
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
|
||||
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
|
||||
}
|
||||
#elseif (rp_ssgi == "SSGI")
|
||||
{
|
||||
path.loadShader("shader_datas/ssgi_pass/ssgi_pass");
|
||||
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
|
||||
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
|
||||
}
|
||||
#end
|
||||
|
||||
#if ((rp_ssgi != "Off") || rp_volumetriclight)
|
||||
#if (rp_ssgi != "Off")
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "singlea";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
#if (rp_ssgi == "SSGI")
|
||||
t.format = "RGBA32";
|
||||
#else
|
||||
t.format = "R8";
|
||||
#end
|
||||
t.scale = Inc.getSuperSampling();
|
||||
#if rp_ssgi_half
|
||||
t.scale *= 0.5;
|
||||
#end
|
||||
path.createRenderTarget(t);
|
||||
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "singleb";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
#if (rp_ssgi == "SSGI")
|
||||
t.format = "RGBA32";
|
||||
#else
|
||||
t.format = "R8";
|
||||
#end
|
||||
t.scale = Inc.getSuperSampling();
|
||||
#if rp_ssgi_half
|
||||
t.scale *= 0.5;
|
||||
#end
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_volumetriclight
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "volumetrica";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
t.format = "R8";
|
||||
t.scale = Inc.getSuperSampling();
|
||||
#if rp_ssgi_half // Do we keep this ?
|
||||
t.scale *= 0.5;
|
||||
#end
|
||||
path.createRenderTarget(t);
|
||||
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "volumetricb";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
t.format = "R8";
|
||||
t.scale = Inc.getSuperSampling();
|
||||
#if rp_ssgi_half
|
||||
t.scale *= 0.5;
|
||||
#end
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_volumetriclight
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "volumetrica";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
t.format = "R8";
|
||||
t.scale = Inc.getSuperSampling();
|
||||
#if rp_ssgi_half // Do we keep this ?
|
||||
t.scale *= 0.5;
|
||||
#end
|
||||
path.createRenderTarget(t);
|
||||
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "singleb";
|
||||
t.name = "volumetricb";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
@ -368,7 +442,7 @@ class RenderPathDeferred {
|
||||
t.scale = Inc.getSuperSampling();
|
||||
path.createRenderTarget(t);
|
||||
|
||||
// holds background depth
|
||||
// holds background color
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "refr";
|
||||
t.width = 0;
|
||||
@ -461,7 +535,7 @@ class RenderPathDeferred {
|
||||
|
||||
#if (rp_ssrefr || lnx_voxelgi_refract)
|
||||
{
|
||||
path.setTarget("gbuffer_refraction"); // Only clear gbuffer0
|
||||
path.setTarget("gbuffer_refraction");
|
||||
path.clearTarget(0xffffff00);
|
||||
}
|
||||
#end
|
||||
@ -517,30 +591,16 @@ class RenderPathDeferred {
|
||||
path.drawShader("shader_datas/downsample_depth/downsample_depth");
|
||||
#end
|
||||
|
||||
#if ((rp_ssgi == "RTGI") || (rp_ssgi == "RTAO"))
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssgi != false) {
|
||||
path.setTarget("singlea");
|
||||
#if rp_ssgi_half
|
||||
path.bindTarget("half", "gbufferD");
|
||||
#else
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
#end
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/ssgi_pass/ssgi_pass");
|
||||
#if (rp_shadowmap)
|
||||
// atlasing is exclusive for now
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.drawShadowMapAtlas();
|
||||
#else
|
||||
Inc.drawShadowMap();
|
||||
#end
|
||||
#end
|
||||
|
||||
path.setTarget("singleb");
|
||||
path.bindTarget("singlea", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
|
||||
|
||||
path.setTarget("singlea");
|
||||
path.bindTarget("singleb", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
|
||||
}
|
||||
}
|
||||
#elseif (rp_ssgi == "SSAO")
|
||||
#if (rp_ssgi == "SSAO")
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssgi != false) {
|
||||
path.setTarget("singlea");
|
||||
@ -559,15 +619,43 @@ class RenderPathDeferred {
|
||||
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
|
||||
}
|
||||
}
|
||||
#end
|
||||
#elseif (rp_ssgi == "SSGI")
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssgi != false) {
|
||||
path.setTarget("singlea");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("gbuffer1", "gbuffer1");
|
||||
#if rp_gbuffer_emission
|
||||
{
|
||||
path.bindTarget("gbuffer_emission", "gbufferEmission");
|
||||
}
|
||||
#end
|
||||
#if rp_gbuffer2
|
||||
path.bindTarget("gbuffer2", "sveloc");
|
||||
#end
|
||||
#if rp_shadowmap
|
||||
{
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
#else
|
||||
Inc.bindShadowMap();
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_shadowmap)
|
||||
// atlasing is exclusive for now
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.drawShadowMapAtlas();
|
||||
#else
|
||||
Inc.drawShadowMap();
|
||||
#end
|
||||
path.drawShader("shader_datas/ssgi_pass/ssgi_pass");
|
||||
path.setTarget("singleb");
|
||||
path.bindTarget("singlea", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
|
||||
|
||||
path.setTarget("singlea");
|
||||
path.bindTarget("singleb", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
// Voxels
|
||||
@ -580,9 +668,6 @@ class RenderPathDeferred {
|
||||
|
||||
if (iron.RenderPath.pre_clear == true)
|
||||
{
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
path.clearImage("voxelsLight", 0x00000000);
|
||||
#end
|
||||
path.clearImage("voxels", 0x00000000);
|
||||
path.clearImage("voxelsOut", 0x00000000);
|
||||
path.clearImage("voxelsOutB", 0x00000000);
|
||||
@ -594,26 +679,30 @@ class RenderPathDeferred {
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
path.clearImage("voxelsLight", 0x00000000);
|
||||
#end
|
||||
path.clearImage("voxels", 0x00000000);
|
||||
Inc.computeVoxelsOffsetPrev();
|
||||
}
|
||||
|
||||
path.setTarget("");
|
||||
path.bindTarget("voxels", "voxels");
|
||||
#if rp_shadowmap
|
||||
{
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
#else
|
||||
Inc.bindShadowMap();
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
var res = iron.RenderPath.getVoxelRes();
|
||||
path.setViewport(res, res);
|
||||
|
||||
path.bindTarget("voxels", "voxels");
|
||||
path.drawMeshes("voxel");
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
Inc.computeVoxelsLight();
|
||||
#end
|
||||
|
||||
Inc.computeVoxelsTemporal();
|
||||
|
||||
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
Inc.computeVoxelsSDF();
|
||||
#end
|
||||
|
||||
@ -628,7 +717,6 @@ class RenderPathDeferred {
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
// ---
|
||||
// Deferred light
|
||||
// ---
|
||||
@ -760,15 +848,9 @@ class RenderPathDeferred {
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_translucency && !rp_ssrefr)
|
||||
{
|
||||
Inc.drawTranslucency("tex");
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_volumetriclight
|
||||
{
|
||||
path.setTarget("singlea");
|
||||
path.setTarget("volumetrica");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
@ -777,85 +859,16 @@ class RenderPathDeferred {
|
||||
#end
|
||||
path.drawShader("shader_datas/volumetric_light/volumetric_light");
|
||||
|
||||
path.setTarget("singleb");
|
||||
path.bindTarget("singlea", "tex");
|
||||
path.setTarget("volumetricb");
|
||||
path.bindTarget("volumetrica", "tex");
|
||||
path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
|
||||
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("singleb", "tex");
|
||||
path.bindTarget("volumetricb", "tex");
|
||||
path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_bloom
|
||||
{
|
||||
inline Inc.drawBloom("tex", bloomDownsampler, bloomUpsampler);
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_sss
|
||||
{
|
||||
#if (!kha_opengl)
|
||||
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
|
||||
#end
|
||||
|
||||
path.setTarget("buf");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/sss_pass/sss_pass_x");
|
||||
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("buf", "tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/sss_pass/sss_pass_y");
|
||||
|
||||
#if (!kha_opengl)
|
||||
path.setDepthFrom("tex", "gbuffer0");
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_ssrefr
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssrefr != false)
|
||||
{
|
||||
//save depth
|
||||
path.setTarget("gbufferD1");
|
||||
path.bindTarget("_main", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
//save background color
|
||||
path.setTarget("refr");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
path.setTarget("gbuffer0", ["tex", "gbuffer_refraction"]);
|
||||
|
||||
#if (rp_voxels != "Off")
|
||||
{
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
path.bindTarget("gbuffer2", "sveloc");
|
||||
}
|
||||
#end
|
||||
|
||||
path.drawMeshes("refraction");
|
||||
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.bindTarget("refr", "tex1");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbufferD1", "gbufferD1");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
|
||||
|
||||
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_ssr
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssr != false) {
|
||||
@ -900,6 +913,88 @@ class RenderPathDeferred {
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_sss
|
||||
{
|
||||
#if (!kha_opengl)
|
||||
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
|
||||
#end
|
||||
|
||||
path.setTarget("buf");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/sss_pass/sss_pass_x");
|
||||
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("buf", "tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("shader_datas/sss_pass/sss_pass_y");
|
||||
|
||||
#if (!kha_opengl)
|
||||
path.setDepthFrom("tex", "gbuffer0");
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_translucency && !rp_ssrefr)
|
||||
{
|
||||
Inc.drawTranslucency("tex");
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_ssrefr
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssrefr != false)
|
||||
{
|
||||
//save depth
|
||||
path.setTarget("gbufferD1");
|
||||
path.bindTarget("_main", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
//save background color
|
||||
path.setTarget("refr");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
path.setTarget("gbuffer0", ["tex", "gbuffer_refraction"]);
|
||||
|
||||
#if rp_shadowmap
|
||||
{
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
#else
|
||||
Inc.bindShadowMap();
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_voxels != "Off")
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
#end
|
||||
#end
|
||||
|
||||
#if rp_ssrs
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
#end
|
||||
|
||||
path.drawMeshes("refraction");
|
||||
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("tex", "tex");
|
||||
path.bindTarget("refr", "tex1");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbufferD1", "gbufferD1");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
|
||||
|
||||
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if ((rp_motionblur == "Camera") || (rp_motionblur == "Object"))
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_motionblur != false) {
|
||||
@ -964,6 +1059,12 @@ class RenderPathDeferred {
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_bloom
|
||||
{
|
||||
inline Inc.drawBloom("tex", bloomDownsampler, bloomUpsampler);
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_supersampling == 4)
|
||||
var framebuffer = "buf";
|
||||
#else
|
||||
|
@ -142,16 +142,17 @@ class RenderPathForward {
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
t.format = "R32";
|
||||
t.format = "DEPTH24";
|
||||
t.scale = Inc.getSuperSampling();
|
||||
path.createRenderTarget(t);
|
||||
|
||||
//holds colors before refractive meshes are drawn
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "refr";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
t.format = "RGBA64";
|
||||
t.format = Inc.getHdrFormat();
|
||||
t.scale = Inc.getSuperSampling();
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
@ -200,17 +201,10 @@ class RenderPathForward {
|
||||
Inc.initGI("voxels");
|
||||
Inc.initGI("voxelsOut");
|
||||
Inc.initGI("voxelsOutB");
|
||||
#if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI"))
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
Inc.initGI("voxelsSDF");
|
||||
Inc.initGI("voxelsSDFtmp");
|
||||
#end
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
Inc.initGI("voxelsLight");
|
||||
Inc.initGI("voxels_diffuse");
|
||||
Inc.initGI("voxels_specular");
|
||||
#else
|
||||
Inc.initGI("voxels_ao");
|
||||
#end
|
||||
iron.RenderPath.clipmaps = new Array<Clipmap>();
|
||||
for (i in 0...Main.voxelgiClipmapCount) {
|
||||
var clipmap = new iron.object.Clipmap();
|
||||
@ -257,18 +251,25 @@ class RenderPathForward {
|
||||
#end
|
||||
#end
|
||||
|
||||
#if rp_volumetriclight
|
||||
#if (rp_volumetriclight || rp_ssgi != "Off")
|
||||
{
|
||||
#if (rp_volumetriclight)
|
||||
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");
|
||||
#end
|
||||
|
||||
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "singlea";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
#if (rp_ssgi == "SSGI")
|
||||
t.format = "RGBA32";
|
||||
#else
|
||||
t.format = "R8";
|
||||
#end
|
||||
t.scale = Inc.getSuperSampling();
|
||||
path.createRenderTarget(t);
|
||||
|
||||
@ -277,7 +278,11 @@ class RenderPathForward {
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.displayp = Inc.getDisplayp();
|
||||
#if (rp_ssgi == "SSGI")
|
||||
t.format = "RGBA32";
|
||||
#else
|
||||
t.format = "R8";
|
||||
#end
|
||||
t.scale = Inc.getSuperSampling();
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
@ -374,9 +379,6 @@ class RenderPathForward {
|
||||
|
||||
if (iron.RenderPath.pre_clear == true)
|
||||
{
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
path.clearImage("voxelsLight", 0x00000000);
|
||||
#end
|
||||
path.clearImage("voxels", 0x00000000);
|
||||
path.clearImage("voxelsOut", 0x00000000);
|
||||
path.clearImage("voxelsOutB", 0x00000000);
|
||||
@ -388,9 +390,6 @@ class RenderPathForward {
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
path.clearImage("voxelsLight", 0x00000000);
|
||||
#end
|
||||
path.clearImage("voxels", 0x00000000);
|
||||
Inc.computeVoxelsOffsetPrev();
|
||||
}
|
||||
@ -400,27 +399,12 @@ class RenderPathForward {
|
||||
path.setViewport(res, res);
|
||||
|
||||
path.bindTarget("voxels", "voxels");
|
||||
path.drawMeshes("voxel");
|
||||
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
Inc.computeVoxelsLight();
|
||||
#end
|
||||
Inc.computeVoxelsTemporal();
|
||||
|
||||
#if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI"))
|
||||
Inc.computeVoxelsSDF();
|
||||
#end
|
||||
|
||||
if (iron.RenderPath.res_pre_clear == true)
|
||||
{
|
||||
iron.RenderPath.res_pre_clear = false;
|
||||
#if (rp_voxels == "Voxel GI")
|
||||
path.clearImage("voxels_diffuse", 0x00000000);
|
||||
path.clearImage("voxels_specular", 0x00000000);
|
||||
#else
|
||||
path.clearImage("voxels_ao", 0x00000000);
|
||||
#end
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
@ -439,7 +423,7 @@ class RenderPathForward {
|
||||
#if (rp_ssrefr || lnx_voxelgi_refract)
|
||||
{
|
||||
path.setTarget("gbuffer_refraction"); // Only clear gbuffer0
|
||||
path.clearTarget(0xff000000);
|
||||
path.clearTarget(0xffffff00);
|
||||
}
|
||||
#end
|
||||
|
||||
@ -449,13 +433,6 @@ class RenderPathForward {
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_ssrefr
|
||||
{
|
||||
path.setTarget("gbuffer_refraction");
|
||||
path.clearTarget(0xffffff00);
|
||||
}
|
||||
#end
|
||||
|
||||
RenderPathCreator.setTargetMeshes();
|
||||
|
||||
#if rp_shadowmap
|
||||
@ -472,19 +449,12 @@ class RenderPathForward {
|
||||
#if (rp_voxels != "Off")
|
||||
if (leenkx.data.Config.raw.rp_gi != false)
|
||||
{
|
||||
#if (rp_voxels == "Voxel AO")
|
||||
Inc.resolveAO();
|
||||
path.bindTarget("voxels_ao", "voxels_ao");
|
||||
#else
|
||||
Inc.resolveDiffuse();
|
||||
Inc.resolveSpecular();
|
||||
path.bindTarget("voxels_diffuse", "voxels_diffuse");
|
||||
path.bindTarget("voxels_specular", "voxels_specular");
|
||||
#end
|
||||
#if lnx_voxelgi_shadows
|
||||
#if (rp_voxels != "Off")
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
@ -522,14 +492,31 @@ class RenderPathForward {
|
||||
|
||||
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
|
||||
|
||||
#if rp_shadowmap
|
||||
{
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
#else
|
||||
Inc.bindShadowMap();
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_voxels != "Off")
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
#end
|
||||
#end
|
||||
|
||||
#if rp_ssrs
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
#end
|
||||
|
||||
path.drawMeshes("refraction");
|
||||
|
||||
path.setTarget("lbuffer0");
|
||||
|
||||
path.bindTarget("lbuffer0", "tex");
|
||||
path.bindTarget("refr", "tex1");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
@ -577,6 +564,50 @@ class RenderPathForward {
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_ssrefr
|
||||
{
|
||||
if (leenkx.data.Config.raw.rp_ssrefr != false)
|
||||
{
|
||||
path.setTarget("gbufferD1");
|
||||
path.bindTarget("_main", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
path.setTarget("refr");
|
||||
path.bindTarget("lbuffer0", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
|
||||
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
|
||||
|
||||
#if rp_shadowmap
|
||||
{
|
||||
#if lnx_shadowmap_atlas
|
||||
Inc.bindShadowMapAtlas();
|
||||
#else
|
||||
Inc.bindShadowMap();
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if (rp_voxels != "Off")
|
||||
path.bindTarget("voxelsOut", "voxels");
|
||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||
#end
|
||||
|
||||
path.drawMeshes("refraction");
|
||||
|
||||
path.setTarget("lbuffer0");
|
||||
path.bindTarget("lbuffer0", "tex");
|
||||
path.bindTarget("refr", "tex1");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbufferD1", "gbufferD1");
|
||||
path.bindTarget("lbuffer1", "gbuffer0");
|
||||
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
|
||||
|
||||
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_bloom
|
||||
{
|
||||
inline Inc.drawBloom("lbuffer0", bloomDownsampler, bloomUpsampler);
|
||||
|
@ -41,7 +41,11 @@ class Starter {
|
||||
try {
|
||||
#end
|
||||
|
||||
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) {
|
||||
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {
|
||||
#if lnx_render_viewport
|
||||
visible: false,
|
||||
#end
|
||||
mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
|
||||
|
||||
iron.App.init(function() {
|
||||
#if lnx_loadscreen
|
||||
|
@ -58,6 +58,9 @@ def add_world_defs():
|
||||
if rpdat.rp_shadowmap_cascades != '1':
|
||||
wrd.world_defs += '_CSM'
|
||||
assets.add_khafile_def('lnx_csm')
|
||||
if rpdat.rp_shadowmap_transparent:
|
||||
wrd.world_defs += '_ShadowMapTransparent'
|
||||
assets.add_khafile_def('rp_shadowmap_transparent')
|
||||
if rpdat.rp_shadowmap_atlas:
|
||||
assets.add_khafile_def('lnx_shadowmap_atlas')
|
||||
wrd.world_defs += '_ShadowMapAtlas'
|
||||
@ -118,17 +121,15 @@ def add_world_defs():
|
||||
if rpdat.lnx_voxelgi_shadows and (point_lights > 0 or '_Sun' in wrd.world_defs):
|
||||
wrd.world_defs += '_VoxelShadow'
|
||||
assets.add_khafile_def('lnx_voxelgi_shadows')
|
||||
#assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_shadows/voxel_resolve_shadows.comp.glsl')
|
||||
|
||||
if voxelgi:
|
||||
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_light/voxel_light.comp.glsl')
|
||||
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl')
|
||||
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl')
|
||||
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_light/voxel_light.comp.glsl')
|
||||
wrd.world_defs += '_VoxelGI'
|
||||
if rpdat.lnx_voxelgi_refract:
|
||||
wrd.world_defs += '_VoxelRefract'
|
||||
assets.add_khafile_def('lnx_voxelgi_refract')
|
||||
#assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_refraction/voxel_resolve_refraction.comp.glsl')
|
||||
|
||||
elif voxelao:
|
||||
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl')
|
||||
@ -306,10 +307,14 @@ def build():
|
||||
|
||||
assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi))
|
||||
if rpdat.rp_ssgi != 'Off':
|
||||
wrd.world_defs += '_SSAO'
|
||||
if rpdat.rp_ssgi == 'SSAO':
|
||||
wrd.world_defs += '_SSAO'
|
||||
assets.add_shader_pass('ssao_pass')
|
||||
assets.add_shader_pass('blur_edge_pass')
|
||||
elif rpdat.rp_ssgi == 'SSGI':
|
||||
wrd.world_defs += '_SSGI'
|
||||
assets.add_shader_pass('ssgi_pass')
|
||||
assets.add_shader_pass('blur_edge_pass')
|
||||
else:
|
||||
assets.add_shader_pass('ssgi_pass')
|
||||
assets.add_shader_pass('blur_edge_pass')
|
||||
@ -456,7 +461,8 @@ def build():
|
||||
if ignoreIrr:
|
||||
wrd.world_defs += '_IgnoreIrr'
|
||||
|
||||
gbuffer2 = '_Veloc' in wrd.world_defs or '_IgnoreIrr' in wrd.world_defs
|
||||
gbuffer2 = '_Veloc' in wrd.world_defs or '_IgnoreIrr' in wrd.world_defs or '_VoxelGI' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs or '_SSGI' in wrd.world_defs
|
||||
|
||||
if gbuffer2:
|
||||
assets.add_khafile_def('rp_gbuffer2')
|
||||
wrd.world_defs += '_gbuffer2'
|
||||
|
@ -199,6 +199,7 @@ def build_node_tree(world: bpy.types.World, frag: Shader, vert: Shader, con: Sha
|
||||
world.lnx_envtex_color = [col[0], col[1], col[2], 1.0]
|
||||
world.lnx_envtex_strength = 1.0
|
||||
world.world_defs += '_EnvCol'
|
||||
assets.add_khafile_def("lnx_envcol")
|
||||
|
||||
# Clouds enabled
|
||||
if rpdat.lnx_clouds and world.lnx_use_clouds:
|
||||
@ -280,6 +281,7 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
|
||||
# Append irradiance define
|
||||
if rpdat.lnx_irradiance and not solid_mat:
|
||||
wrd.world_defs += '_Irr'
|
||||
assets.add_khafile_def("lnx_irradiance")
|
||||
|
||||
# Extract environment strength
|
||||
# Todo: follow/parse strength input
|
||||
@ -293,6 +295,7 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
|
||||
solid_mat = rpdat.lnx_material_model == 'Solid'
|
||||
if rpdat.lnx_irradiance and not solid_mat:
|
||||
world.world_defs += '_Irr'
|
||||
assets.add_khafile_def("lnx_irradiance")
|
||||
world.lnx_envtex_color = node_surface.inputs[0].default_value
|
||||
world.lnx_envtex_strength = 1.0
|
||||
|
||||
|
@ -342,9 +342,6 @@ def parse_sky_hosekwilkie(node: bpy.types.ShaderNodeTexSky, state: ParserState)
|
||||
world = state.world
|
||||
curshader = state.curshader
|
||||
|
||||
# Match to cycles
|
||||
world.lnx_envtex_strength *= 0.1
|
||||
|
||||
assets.add_khafile_def('lnx_hosek')
|
||||
curshader.add_uniform('vec3 A', link="_hosekA")
|
||||
curshader.add_uniform('vec3 B', link="_hosekB")
|
||||
|
@ -19,6 +19,7 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
parse_opacity = blend or mat_utils.is_transluc(mat_state.material)
|
||||
is_mobile = rpdat.lnx_material_model == 'Mobile'
|
||||
is_shadows = '_ShadowMap' in wrd.world_defs
|
||||
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
|
||||
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
|
||||
is_single_atlas = '_SingleAtlas' in wrd.world_defs
|
||||
|
||||
@ -33,14 +34,17 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
if is_shadows_atlas:
|
||||
if not is_single_atlas:
|
||||
frag.add_uniform('sampler2DShadow shadowMapAtlasPoint', included=True)
|
||||
frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True)
|
||||
else:
|
||||
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
|
||||
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
|
||||
frag.add_uniform('vec4 pointLightDataArray[maxLightsCluster]', link='_pointLightsAtlasArray', included=True)
|
||||
else:
|
||||
frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True)
|
||||
frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True)
|
||||
|
||||
if not '_VoxelAOvar' in wrd.world_defs and not '_VoxelGI' in wrd.world_defs or ((parse_opacity or '_VoxelShadow' in wrd.world_defs) and ('_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs)):
|
||||
vert.add_out('vec4 wvpposition')
|
||||
@ -62,13 +66,16 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
if is_shadows_atlas:
|
||||
if not is_single_atlas:
|
||||
frag.add_uniform('sampler2DShadow shadowMapAtlasSpot', included=True)
|
||||
frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True)
|
||||
else:
|
||||
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
|
||||
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
|
||||
else:
|
||||
frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True)
|
||||
frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True)
|
||||
frag.add_uniform('mat4 LWVPSpotArray[maxLightsCluster]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True)
|
||||
|
||||
frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {')
|
||||
@ -84,12 +91,10 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
frag.write(' roughness,')
|
||||
frag.write(' specular,')
|
||||
frag.write(' f0')
|
||||
|
||||
if is_shadows:
|
||||
if parse_opacity:
|
||||
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, opacity != 1.0') # bias
|
||||
else:
|
||||
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false') # bias
|
||||
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0') # bias
|
||||
if is_transparent_shadows:
|
||||
frag.write('\t, opacity != 1.0')
|
||||
if '_Spot' in wrd.world_defs:
|
||||
frag.write('\t, lightsArray[li * 3 + 2].y != 0.0')
|
||||
frag.write('\t, lightsArray[li * 3 + 2].y') # spot size (cutoff)
|
||||
@ -98,13 +103,13 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
frag.write('\t, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w)') # scale
|
||||
frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right
|
||||
if '_VoxelShadow' in wrd.world_defs:
|
||||
frag.write(', voxels, voxelsSDF, clipmaps')
|
||||
frag.write(', voxels, voxelsSDF, clipmaps, velocity')
|
||||
if '_MicroShadowing' in wrd.world_defs and not is_mobile:
|
||||
frag.write('\t, occlusion')
|
||||
if '_SSRS' in wrd.world_defs:
|
||||
frag.add_uniform('sampler2D gbufferD')
|
||||
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
frag.add_uniform('sampler2D gbufferD', link='_gbufferD', top=True)
|
||||
frag.write(', gbufferD, invVP, eye')
|
||||
frag.write(');')
|
||||
|
||||
|
@ -1,155 +1,161 @@
|
||||
import bpy
|
||||
|
||||
import lnx
|
||||
import lnx.material.mat_state as mat_state
|
||||
import lnx.material.make_tess as make_tess
|
||||
from lnx.material.shader import ShaderContext
|
||||
|
||||
if lnx.is_reload(__name__):
|
||||
mat_state = lnx.reload_module(mat_state)
|
||||
make_tess = lnx.reload_module(make_tess)
|
||||
lnx.material.shader = lnx.reload_module(lnx.material.shader)
|
||||
from lnx.material.shader import ShaderContext
|
||||
else:
|
||||
lnx.enable_reload(__name__)
|
||||
|
||||
|
||||
def make(con_mesh: ShaderContext):
|
||||
vert = con_mesh.vert
|
||||
frag = con_mesh.frag
|
||||
geom = con_mesh.geom
|
||||
tesc = con_mesh.tesc
|
||||
tese = con_mesh.tese
|
||||
|
||||
# Additional values referenced in cycles
|
||||
# TODO: enable from cycles.py
|
||||
if frag.contains('dotNV') and not frag.contains('float dotNV'):
|
||||
frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')
|
||||
|
||||
# n is not always defined yet (in some shadowmap shaders e.g.)
|
||||
if not frag.contains('vec3 n'):
|
||||
vert.add_out('vec3 wnormal')
|
||||
billboard = mat_state.material.lnx_billboard
|
||||
if billboard == 'spherical':
|
||||
vert.add_uniform('mat3 N', '_normalMatrixSphere')
|
||||
elif billboard == 'cylindrical':
|
||||
vert.add_uniform('mat3 N', '_normalMatrixCylinder')
|
||||
else:
|
||||
vert.add_uniform('mat3 N', '_normalMatrix')
|
||||
vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
|
||||
frag.write_attrib('vec3 n = normalize(wnormal);')
|
||||
|
||||
# If not yet added, add nor vertex data
|
||||
vertex_elems = con_mesh.data['vertex_elements']
|
||||
has_normals = False
|
||||
for elem in vertex_elems:
|
||||
if elem['name'] == 'nor':
|
||||
has_normals = True
|
||||
break
|
||||
if not has_normals:
|
||||
vertex_elems.append({'name': 'nor', 'data': 'short2norm'})
|
||||
|
||||
write_wpos = False
|
||||
if frag.contains('vVec') and not frag.contains('vec3 vVec'):
|
||||
if tese is not None:
|
||||
tese.add_out('vec3 eyeDir')
|
||||
tese.add_uniform('vec3 eye', '_cameraPosition')
|
||||
tese.write('eyeDir = eye - wposition;')
|
||||
|
||||
else:
|
||||
if not vert.contains('wposition'):
|
||||
write_wpos = True
|
||||
vert.add_out('vec3 eyeDir')
|
||||
vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
vert.write('eyeDir = eye - wposition;')
|
||||
frag.write_attrib('vec3 vVec = normalize(eyeDir);')
|
||||
|
||||
export_wpos = False
|
||||
if frag.contains('wposition') and not frag.contains('vec3 wposition'):
|
||||
export_wpos = True
|
||||
if tese is not None:
|
||||
export_wpos = True
|
||||
if vert.contains('wposition'):
|
||||
write_wpos = True
|
||||
|
||||
if export_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_out('vec3 wposition')
|
||||
vert.write('wposition = vec4(W * spos).xyz;')
|
||||
elif write_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')
|
||||
|
||||
frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition')
|
||||
if frag_mpos:
|
||||
vert.add_out('vec3 mposition')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('mposition = spos.xyz * posUnpack;')
|
||||
|
||||
if tese is not None:
|
||||
if frag_mpos:
|
||||
make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
|
||||
elif tese.contains('mposition') and not tese.contains('vec3 mposition'):
|
||||
vert.add_out('vec3 mposition')
|
||||
vert.write_pre = True
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write('mposition = spos.xyz * posUnpack;')
|
||||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
|
||||
|
||||
frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition')
|
||||
if frag_bpos:
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
|
||||
vert.write_attrib('if (dim.z == 0) bposition.z = 0;')
|
||||
vert.write_attrib('if (dim.y == 0) bposition.y = 0;')
|
||||
vert.write_attrib('if (dim.x == 0) bposition.x = 0;')
|
||||
|
||||
if tese is not None:
|
||||
if frag_bpos:
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
|
||||
elif tese.contains('bposition') and not tese.contains('vec3 bposition'):
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=False)
|
||||
|
||||
frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
|
||||
if frag_wtan:
|
||||
# Indicate we want tang attrib in finalizer to prevent TBN generation
|
||||
con_mesh.add_elem('tex', 'short2norm')
|
||||
con_mesh.add_elem('tang', 'short4norm')
|
||||
vert.add_out('vec3 wtangent')
|
||||
vert.write_pre = True
|
||||
vert.write('wtangent = normalize(N * tang.xyz);')
|
||||
vert.write_pre = False
|
||||
|
||||
if tese is not None:
|
||||
if frag_wtan:
|
||||
make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
|
||||
elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
|
||||
vert.add_out('vec3 wtangent')
|
||||
vert.write_pre = True
|
||||
vert.write('wtangent = normalize(N * tang.xyz);')
|
||||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)
|
||||
|
||||
if frag.contains('vVecCam'):
|
||||
vert.add_out('vec3 eyeDirCam')
|
||||
vert.add_uniform('mat4 WV', '_worldViewMatrix')
|
||||
vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
|
||||
frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
|
||||
|
||||
if frag.contains('nAttr'):
|
||||
vert.add_out('vec3 nAttr')
|
||||
vert.write_attrib('nAttr = vec3(nor.xy, pos.w);')
|
||||
|
||||
wrd = bpy.data.worlds['Lnx']
|
||||
if '_Legacy' in wrd.world_defs:
|
||||
frag.replace('sampler2DShadow', 'sampler2D')
|
||||
frag.replace('samplerCubeShadow', 'samplerCube')
|
||||
import bpy
|
||||
|
||||
import lnx
|
||||
import lnx.material.mat_state as mat_state
|
||||
import lnx.material.make_tess as make_tess
|
||||
from lnx.material.shader import ShaderContext
|
||||
|
||||
if lnx.is_reload(__name__):
|
||||
mat_state = lnx.reload_module(mat_state)
|
||||
make_tess = lnx.reload_module(make_tess)
|
||||
lnx.material.shader = lnx.reload_module(lnx.material.shader)
|
||||
from lnx.material.shader import ShaderContext
|
||||
else:
|
||||
lnx.enable_reload(__name__)
|
||||
|
||||
|
||||
def make(con_mesh: ShaderContext):
|
||||
vert = con_mesh.vert
|
||||
frag = con_mesh.frag
|
||||
geom = con_mesh.geom
|
||||
tesc = con_mesh.tesc
|
||||
tese = con_mesh.tese
|
||||
|
||||
# Additional values referenced in cycles
|
||||
# TODO: enable from cycles.py
|
||||
if frag.contains('dotNV') and not frag.contains('float dotNV'):
|
||||
frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')
|
||||
|
||||
# n is not always defined yet (in some shadowmap shaders e.g.)
|
||||
if not frag.contains('vec3 n'):
|
||||
vert.add_out('vec3 wnormal')
|
||||
billboard = mat_state.material.lnx_billboard
|
||||
if billboard == 'spherical':
|
||||
vert.add_uniform('mat3 N', '_normalMatrixSphere')
|
||||
elif billboard == 'cylindrical':
|
||||
vert.add_uniform('mat3 N', '_normalMatrixCylinder')
|
||||
else:
|
||||
vert.add_uniform('mat3 N', '_normalMatrix')
|
||||
vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
|
||||
frag.write_attrib('vec3 n = normalize(wnormal);')
|
||||
|
||||
# If not yet added, add nor vertex data
|
||||
vertex_elems = con_mesh.data['vertex_elements']
|
||||
has_normals = False
|
||||
for elem in vertex_elems:
|
||||
if elem['name'] == 'nor':
|
||||
has_normals = True
|
||||
break
|
||||
if not has_normals:
|
||||
vertex_elems.append({'name': 'nor', 'data': 'short2norm'})
|
||||
|
||||
write_wpos = False
|
||||
export_wpos = False
|
||||
if frag.contains('wposition') and not frag.contains('vec3 wposition'):
|
||||
export_wpos = True
|
||||
if tese is not None:
|
||||
export_wpos = True
|
||||
if vert.contains('wposition'):
|
||||
write_wpos = True
|
||||
|
||||
|
||||
|
||||
|
||||
if frag.contains('vVec') and not frag.contains('vec3 vVec'):
|
||||
if tese is not None:
|
||||
tese.add_out('vec3 eyeDir')
|
||||
tese.add_uniform('vec3 eye', '_cameraPosition')
|
||||
tese.write('eyeDir = eye - wposition;')
|
||||
|
||||
else:
|
||||
if not vert.contains('wposition'):
|
||||
write_wpos = True
|
||||
vert.add_out('vec3 eyeDir')
|
||||
vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
vert.write('eyeDir = eye - wposition;')
|
||||
frag.write_attrib('vec3 vVec = normalize(eyeDir);')
|
||||
|
||||
if export_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_out('vec3 wposition')
|
||||
vert.write_attrib('wposition = vec4(W * spos).xyz;')
|
||||
elif write_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')
|
||||
|
||||
if frag.contains('dotNV') and not frag.contains('float dotNV'):
|
||||
frag.write_attrib('float dotNV = max(dot(n, vVec), 0.0);')
|
||||
|
||||
frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition')
|
||||
if frag_mpos:
|
||||
vert.add_out('vec3 mposition')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('mposition = spos.xyz * posUnpack;')
|
||||
|
||||
if tese is not None:
|
||||
if frag_mpos:
|
||||
make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
|
||||
elif tese.contains('mposition') and not tese.contains('vec3 mposition'):
|
||||
vert.add_out('vec3 mposition')
|
||||
vert.write_pre = True
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write('mposition = spos.xyz * posUnpack;')
|
||||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
|
||||
|
||||
frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition')
|
||||
if frag_bpos:
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
|
||||
vert.write_attrib('if (dim.z == 0) bposition.z = 0;')
|
||||
vert.write_attrib('if (dim.y == 0) bposition.y = 0;')
|
||||
vert.write_attrib('if (dim.x == 0) bposition.x = 0;')
|
||||
|
||||
if tese is not None:
|
||||
if frag_bpos:
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
|
||||
elif tese.contains('bposition') and not tese.contains('vec3 bposition'):
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.add_uniform('float posUnpack', link='_posUnpack')
|
||||
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=False)
|
||||
|
||||
frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
|
||||
if frag_wtan:
|
||||
# Indicate we want tang attrib in finalizer to prevent TBN generation
|
||||
con_mesh.add_elem('tex', 'short2norm')
|
||||
con_mesh.add_elem('tang', 'short4norm')
|
||||
vert.add_out('vec3 wtangent')
|
||||
vert.write_pre = True
|
||||
vert.write('wtangent = normalize(N * tang.xyz);')
|
||||
vert.write_pre = False
|
||||
|
||||
if tese is not None:
|
||||
if frag_wtan:
|
||||
make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
|
||||
elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
|
||||
vert.add_out('vec3 wtangent')
|
||||
vert.write_pre = True
|
||||
vert.write('wtangent = normalize(N * tang.xyz);')
|
||||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)
|
||||
|
||||
if frag.contains('vVecCam'):
|
||||
vert.add_out('vec3 eyeDirCam')
|
||||
vert.add_uniform('mat4 WV', '_worldViewMatrix')
|
||||
vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
|
||||
frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
|
||||
|
||||
if frag.contains('nAttr'):
|
||||
vert.add_out('vec3 nAttr')
|
||||
vert.write_attrib('nAttr = vec3(nor.xy, pos.w);')
|
||||
|
||||
wrd = bpy.data.worlds['Lnx']
|
||||
if '_Legacy' in wrd.world_defs:
|
||||
frag.replace('sampler2DShadow', 'sampler2D')
|
||||
frag.replace('samplerCubeShadow', 'samplerCube')
|
||||
|
@ -557,7 +557,7 @@ def make_forward(con_mesh):
|
||||
frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));')
|
||||
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
|
||||
if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract:
|
||||
frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 1.0);')
|
||||
frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 0.0);')
|
||||
|
||||
else:
|
||||
frag.add_out('vec4 fragColor[1]')
|
||||
@ -611,10 +611,42 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
sh = tese if tese is not None else vert
|
||||
sh.add_out('vec3 eyeDir')
|
||||
sh.add_uniform('vec3 eye', '_cameraPosition')
|
||||
sh.write('eyeDir = eye - spos.xyz;')
|
||||
sh.write('eyeDir = eye - wposition;')
|
||||
if '_VoxelGI' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs:
|
||||
if '_gbuffer2' in wrd.world_defs:
|
||||
if '_Veloc' in wrd.world_defs:
|
||||
if tese is None:
|
||||
vert.add_uniform('mat4 prevWVP', link='_prevWorldViewProjectionMatrix')
|
||||
vert.add_out('vec4 wvpposition')
|
||||
vert.add_out('vec4 prevwvpposition')
|
||||
vert.write('wvpposition = gl_Position;')
|
||||
if is_displacement:
|
||||
vert.add_uniform('mat4 invW', link='_inverseWorldMatrix')
|
||||
vert.write('prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));')
|
||||
else:
|
||||
vert.write('prevwvpposition = prevWVP * spos;')
|
||||
else:
|
||||
tese.add_out('vec4 wvpposition')
|
||||
tese.add_out('vec4 prevwvpposition')
|
||||
tese.write('wvpposition = gl_Position;')
|
||||
if is_displacement:
|
||||
tese.add_uniform('mat4 invW', link='_inverseWorldMatrix')
|
||||
tese.add_uniform('mat4 prevWVP', '_prevWorldViewProjectionMatrix')
|
||||
tese.write('prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));')
|
||||
else:
|
||||
vert.add_uniform('mat4 prevW', link='_prevWorldMatrix')
|
||||
vert.add_out('vec3 prevwposition')
|
||||
vert.write('prevwposition = vec4(prevW * spos).xyz;')
|
||||
tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix')
|
||||
make_tess.interpolate(tese, 'prevwposition', 3)
|
||||
tese.write('prevwvpposition = prevVP * vec4(prevwposition, 1.0);')
|
||||
frag.write('vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
|
||||
frag.write('vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;')
|
||||
frag.write('vec2 velocity = -vec2(posa - posb);')
|
||||
|
||||
frag.add_include('std/light.glsl')
|
||||
is_shadows = '_ShadowMap' in wrd.world_defs
|
||||
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
|
||||
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
|
||||
is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs
|
||||
shadowmap_sun = 'shadowMap'
|
||||
@ -630,7 +662,10 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
if '_Brdf' in wrd.world_defs:
|
||||
frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png')
|
||||
frag.write('vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;')
|
||||
|
||||
frag.write('vec3 F = f0 * envBRDF.x + envBRDF.y;')
|
||||
else:
|
||||
frag.write('vec3 F = f0;')
|
||||
|
||||
if '_Irr' in wrd.world_defs:
|
||||
frag.add_include('std/shirr.glsl')
|
||||
frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance')
|
||||
@ -655,51 +690,36 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.write('envl *= albedo;')
|
||||
|
||||
if '_Brdf' in wrd.world_defs:
|
||||
frag.write('envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y);')
|
||||
frag.write('envl.rgb *= 1.0 - F;')
|
||||
if '_Rad' in wrd.world_defs:
|
||||
frag.write('envl += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);')
|
||||
frag.write('envl += prefilteredColor * F;')
|
||||
elif '_EnvCol' in wrd.world_defs:
|
||||
frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
|
||||
frag.write('envl += backgroundCol * (f0 * envBRDF.x + envBRDF.y);')
|
||||
frag.write('envl += backgroundCol * F;')
|
||||
|
||||
frag.add_uniform('float envmapStrength', link='_envmapStrength')
|
||||
frag.write('envl *= envmapStrength * occlusion;')
|
||||
|
||||
if '_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs:
|
||||
if parse_opacity or '_VoxelShadow' in wrd.world_defs:
|
||||
frag.add_include('std/conetrace.glsl')
|
||||
frag.add_uniform('sampler3D voxels')
|
||||
frag.add_uniform('sampler3D voxelsSDF')
|
||||
frag.add_uniform('vec3 eye', "_cameraPosition")
|
||||
frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps')
|
||||
vert.add_out('vec4 wvpposition')
|
||||
vert.write('wvpposition = gl_Position;')
|
||||
frag.write('vec2 texCoord = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
|
||||
frag.add_include('std/conetrace.glsl')
|
||||
frag.add_uniform('sampler3D voxels')
|
||||
frag.add_uniform('sampler3D voxelsSDF')
|
||||
frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps')
|
||||
|
||||
if '_VoxelAOvar' in wrd.world_defs and not parse_opacity:
|
||||
frag.add_uniform("sampler2D voxels_ao");
|
||||
frag.write('envl *= textureLod(voxels_ao, texCoord, 0.0).rrr;')
|
||||
if '_VoxelAOvar' in wrd.world_defs:
|
||||
frag.write('envl *= (1.0 - traceAO(wposition, n, voxels, clipmaps));')
|
||||
|
||||
if '_VoxelGI' in wrd.world_defs:
|
||||
frag.write('vec3 indirect = vec3(0.0);')
|
||||
else:
|
||||
frag.write('vec3 indirect = envl;')
|
||||
|
||||
if '_VoxelGI' in wrd.world_defs:
|
||||
if parse_opacity:
|
||||
frag.write('vec4 trace = traceDiffuse(wposition, wnormal, voxels, clipmaps);')
|
||||
frag.write('indirect = ((trace.rgb * albedo + envl * (1.0 - trace.a)) * voxelgiDiff);')
|
||||
frag.write('if (roughness < 1.0 && specular > 0.0){')
|
||||
frag.add_uniform('sampler2D sveloc')
|
||||
frag.write(' vec2 velocity = -textureLod(sveloc, gl_FragCoord.xy, 0.0).rg;')
|
||||
frag.write(' indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness, clipmaps, gl_FragCoord.xy, velocity).rgb * specular * voxelgiRefl;}')
|
||||
else:
|
||||
frag.add_uniform("sampler2D voxels_diffuse")
|
||||
frag.add_uniform("sampler2D voxels_specular")
|
||||
frag.write("indirect = textureLod(voxels_diffuse, texCoord, 0.0).rgb * albedo * voxelgiDiff;")
|
||||
frag.write("if (roughness < 1.0 && specular > 0.0)")
|
||||
frag.write(" indirect += textureLod(voxels_specular, texCoord, 0.0).rgb * specular * voxelgiRefl;")
|
||||
|
||||
if '_VoxelGI' in wrd.world_defs:
|
||||
frag.write('vec4 diffuse_indirect = traceDiffuse(wposition, n, voxels, clipmaps);')
|
||||
frag.write('indirect = (diffuse_indirect.rgb * albedo * (1.0 - F) + envl * (1.0 - diffuse_indirect.a)) * voxelgiDiff;')
|
||||
frag.write('if (roughness < 1.0 && specular > 0.0) {')
|
||||
frag.write(' indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity).rgb * F * voxelgiRefl;')
|
||||
frag.write('}')
|
||||
frag.write('vec3 direct = vec3(0.0);')
|
||||
|
||||
if '_Sun' in wrd.world_defs:
|
||||
@ -713,18 +733,21 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
if is_shadows:
|
||||
frag.add_uniform('bool receiveShadow')
|
||||
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True)
|
||||
frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True)
|
||||
frag.add_uniform('float shadowsBias', '_sunShadowsBias')
|
||||
frag.write('if (receiveShadow) {')
|
||||
if '_CSM' in wrd.world_defs:
|
||||
frag.add_include('std/shadows.glsl')
|
||||
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
if parse_opacity:
|
||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, true);')
|
||||
else:
|
||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, false);')
|
||||
|
||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
||||
if is_transparent_shadows:
|
||||
frag.write(f'{shadowmap_sun_tr},')
|
||||
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
|
||||
if is_transparent_shadows:
|
||||
frag.write(', false')
|
||||
frag.write(');')
|
||||
else:
|
||||
if tese is not None:
|
||||
tese.add_out('vec4 lightPosition')
|
||||
@ -738,15 +761,18 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
else:
|
||||
vert.add_out('vec4 lightPosition')
|
||||
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
|
||||
vert.write('lightPosition = LWVP * lightPosition;')
|
||||
vert.write('lightPosition = LWVP * pos;')
|
||||
frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
|
||||
frag.write('const vec2 smSize = shadowmapSize;')
|
||||
if parse_opacity:
|
||||
frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, true);')
|
||||
else:
|
||||
frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, false);')
|
||||
frag.write(f'svisibility = PCF({shadowmap_sun},')
|
||||
if is_transparent_shadows:
|
||||
frag.write(f'{shadowmap_sun_tr},')
|
||||
frag.write('lPos.xy, lPos.z - shadowsBias, smSize')
|
||||
if is_transparent_shadows:
|
||||
frag.write(', false')
|
||||
frag.write(');')
|
||||
if '_VoxelShadow' in wrd.world_defs:
|
||||
frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;')
|
||||
frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;')
|
||||
frag.write('}') # receiveShadow
|
||||
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
|
||||
# sun
|
||||
@ -765,7 +791,8 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
# Skip world matrix, already in world-space
|
||||
frag.add_uniform('mat4 LWVPSpot[1]', link='_biasLightViewProjectionMatrixSpotArray', included=True)
|
||||
frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True)
|
||||
frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True)
|
||||
if is_transparent_shadows:
|
||||
frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True)
|
||||
else:
|
||||
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
|
||||
frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True)
|
||||
@ -773,18 +800,19 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.write('direct += sampleLight(')
|
||||
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
|
||||
if is_shadows:
|
||||
if parse_opacity:
|
||||
frag.write(', 0, pointBias, receiveShadow, opacity != 1.0')
|
||||
else:
|
||||
frag.write(', 0, pointBias, receiveShadow, false')
|
||||
frag.write(', 0, pointBias, receiveShadow')
|
||||
if is_transparent_shadows:
|
||||
frag.write(', opacity != 1.0')
|
||||
if '_Spot' in wrd.world_defs:
|
||||
frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight')
|
||||
if '_VoxelShadow' in wrd.world_defs:
|
||||
frag.write(', voxels, voxelsSDF, clipmaps')
|
||||
if '_Veloc' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs:
|
||||
frag.write(', velocity')
|
||||
if '_MicroShadowing' in wrd.world_defs:
|
||||
frag.write(', occlusion')
|
||||
if '_SSRS' in wrd.world_defs:
|
||||
frag.add_uniform('sampler2D gbufferD', top=True)
|
||||
frag.add_uniform('sampler2D gbufferD')
|
||||
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
frag.write(', gbufferD, invVP, eye')
|
||||
@ -800,10 +828,9 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
|
||||
if '_VoxelRefract' in wrd.world_defs and parse_opacity:
|
||||
frag.write('if (opacity < 1.0) {')
|
||||
frag.write(' vec2 velocity = -textureLod(sveloc, gl_FragCoord.xy, 0.0).rg;')
|
||||
frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness, clipmaps, gl_FragCoord.xy,velocity).rgb;')
|
||||
frag.write(' indirect = mix(refraction, indirect, opacity) * voxelgiRefr;')
|
||||
frag.write(' direct = mix(refraction, direct, opacity) * voxelgiRefr;')
|
||||
frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity, opacity).rgb * (1.0 - F) * voxelgiRefr;')
|
||||
frag.write(' indirect = mix(refraction, indirect, opacity);')
|
||||
frag.write(' direct = mix(refraction, direct, opacity);')
|
||||
frag.write('}')
|
||||
|
||||
def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
|
||||
@ -817,4 +844,4 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
|
||||
frag.write('vec3 emissionCol;')
|
||||
if parse_opacity:
|
||||
frag.write('float opacity;')
|
||||
frag.write('float ior;')
|
||||
frag.write('float ior = 1.45;')
|
||||
|
@ -1,49 +0,0 @@
|
||||
import bpy
|
||||
|
||||
import lnx
|
||||
import lnx.material.cycles as cycles
|
||||
import lnx.material.mat_state as mat_state
|
||||
import lnx.material.mat_utils as mat_utils
|
||||
import lnx.material.make_mesh as make_mesh
|
||||
import lnx.material.make_finalize as make_finalize
|
||||
import lnx.assets as assets
|
||||
|
||||
if lnx.is_reload(__name__):
|
||||
cycles = lnx.reload_module(cycles)
|
||||
mat_state = lnx.reload_module(mat_state)
|
||||
make_mesh = lnx.reload_module(make_mesh)
|
||||
make_finalize = lnx.reload_module(make_finalize)
|
||||
assets = lnx.reload_module(assets)
|
||||
else:
|
||||
lnx.enable_reload(__name__)
|
||||
|
||||
|
||||
def make(context_id):
|
||||
con_refraction_buffer = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
|
||||
|
||||
lnx_discard = mat_state.material.lnx_discard
|
||||
blend = mat_state.material.lnx_blending
|
||||
parse_opacity = blend or mat_utils.is_transluc(mat_state.material) or lnx_discard
|
||||
|
||||
make_mesh.make_base(con_refraction_buffer, parse_opacity)
|
||||
|
||||
vert = con_refraction_buffer.vert
|
||||
frag = con_refraction_buffer.frag
|
||||
|
||||
frag.add_out('vec4 fragColor')
|
||||
|
||||
# Remove fragColor = ...;
|
||||
frag.main = frag.main[:frag.main.rfind('fragColor')]
|
||||
frag.write('\n')
|
||||
|
||||
if parse_opacity:
|
||||
frag.write('fragColor = vec4(ior, opacity, 0.0, 1.0);')
|
||||
else:
|
||||
frag.write('fragColor = vec4(1.0, 1.0, 0.0, 1.0);')
|
||||
|
||||
make_finalize.make(con_refraction_buffer)
|
||||
|
||||
# assets.vs_equal(con_refract, assets.shader_cons['transluc_vert']) # shader_cons has no transluc yet
|
||||
# assets.fs_equal(con_refract, assets.shader_cons['transluc_frag'])
|
||||
|
||||
return con_refraction_buffer
|
File diff suppressed because it is too large
Load Diff
@ -295,6 +295,7 @@ def init_properties():
|
||||
name="Assertion Level", description="Ignore all assertions below this level (assertions are turned off completely for published builds)", default='Warning', update=assets.invalidate_compiler_cache)
|
||||
bpy.types.World.lnx_assert_quit = BoolProperty(name="Quit On Assertion Fail", description="Whether to close the game when an 'Error' level assertion fails", default=False, update=assets.invalidate_compiler_cache)
|
||||
bpy.types.World.lnx_live_patch = BoolProperty(name="Live Patch", description="Live patching for Krom", default=False)
|
||||
bpy.types.World.lnx_render_viewport = BoolProperty(name="Viewport Render", description="Viewport rendering", default=False)
|
||||
bpy.types.World.lnx_clear_on_compile = BoolProperty(name="Clear Console", description="Clears the system console on compile", default=False)
|
||||
bpy.types.World.lnx_play_camera = EnumProperty(
|
||||
items=[('Scene', 'Scene', 'Scene'),
|
||||
|
@ -65,8 +65,8 @@ def update_preset(self, context):
|
||||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_voxelgi_resolution = '32'
|
||||
rpdat.lnx_voxelgi_size = 0.25
|
||||
rpdat.rp_voxels = 'Voxel AO'
|
||||
rpdat.lnx_voxelgi_size = 0.125
|
||||
rpdat.rp_voxels = 'Voxel GI'
|
||||
rpdat.rp_render_to_texture = True
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'SMAA'
|
||||
@ -142,8 +142,8 @@ def update_preset(self, context):
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_voxels = 'Voxel GI'
|
||||
rpdat.rp_voxelgi_resolution = '64'
|
||||
rpdat.lnx_voxelgi_size = 0.25
|
||||
rpdat.lnx_voxelgi_step = 0.25
|
||||
rpdat.lnx_voxelgi_size = 0.125
|
||||
rpdat.lnx_voxelgi_step = 0.01
|
||||
rpdat.lnx_voxelgi_revoxelize = False
|
||||
rpdat.lnx_voxelgi_camera = False
|
||||
rpdat.rp_voxelgi_emission = False
|
||||
@ -152,7 +152,7 @@ def update_preset(self, context):
|
||||
rpdat.rp_antialiasing = 'TAA'
|
||||
rpdat.rp_compositornodes = True
|
||||
rpdat.rp_volumetriclight = False
|
||||
rpdat.rp_ssgi = 'RTAO'
|
||||
rpdat.rp_ssgi = 'SSGI'
|
||||
rpdat.lnx_ssrs = False
|
||||
rpdat.lnx_micro_shadowing = True
|
||||
rpdat.rp_ssr = True
|
||||
@ -330,6 +330,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
||||
rp_shadowmap_atlas: BoolProperty(name="Shadow Map Atlasing", description="Group shadow maps of lights of the same type in the same texture", default=False, update=update_renderpath)
|
||||
rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=False, update=update_renderpath)
|
||||
rp_shadowmap_atlas_lod: BoolProperty(name="Shadow Map Atlas LOD (Experimental)", description="When enabled, the size of the shadow map will be determined on runtime based on the distance of the light to the camera", default=False, update=update_renderpath)
|
||||
rp_shadowmap_transparent: BoolProperty(name="Transparency", description="Enable transparent shadowmaps", default=False, update=update_renderpath)
|
||||
rp_shadowmap_atlas_lod_subdivisions: EnumProperty(
|
||||
items=[('2', '2', '2'),
|
||||
('3', '3', '3'),
|
||||
@ -391,7 +392,8 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
||||
rp_ssgi: EnumProperty(
|
||||
items=[('Off', 'No AO', 'Off'),
|
||||
('SSAO', 'SSAO', 'Screen space ambient occlusion'),
|
||||
('RTAO', 'RTAO', 'Ray-traced ambient occlusion')
|
||||
('SSGI', 'SSGI', 'Screen space global illumination')
|
||||
#('RTAO', 'RTAO', 'Ray-traced ambient occlusion')
|
||||
# ('RTGI', 'RTGI', 'Ray-traced global illumination')
|
||||
],
|
||||
name="SSGI", description="Screen space global illumination", default='SSAO', update=update_renderpath)
|
||||
@ -508,7 +510,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
||||
('1', '1', '1'),
|
||||
('2', '2', '2')],
|
||||
name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath)
|
||||
lnx_voxelgi_clipmap_count: IntProperty(name="Clipmap count", description="Number of clipmaps", default=3, update=assets.invalidate_compiled_data)
|
||||
lnx_voxelgi_clipmap_count: IntProperty(name="Clipmap count", description="Number of clipmaps", default=5, update=assets.invalidate_compiled_data)
|
||||
lnx_voxelgi_temporal: BoolProperty(name="Temporal Filter", description="Use temporal filtering to stabilize voxels", default=False, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
|
||||
lnx_samples_per_pixel: EnumProperty(
|
||||
@ -530,9 +532,10 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
||||
lnx_voxelgi_spec: FloatProperty(name="Reflection", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_refr: FloatProperty(name="Refraction", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_shad: FloatProperty(name="Shadows", description="Contrast for voxels shadows", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_env: FloatProperty(name="Environment", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_occ: FloatProperty(name="Occlusion", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_size: FloatProperty(name="Size", description="Voxel size", default=0.25, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_step: FloatProperty(name="Step", description="Step size", default=0.25, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_step: FloatProperty(name="Step", description="Step size", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_range: FloatProperty(name="Range", description="Maximum range", default=100.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_offset: FloatProperty(name="Offset", description="Multiplicative Offset for dealing with self occlusion", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_voxelgi_aperture: FloatProperty(name="Aperture", description="Cone aperture for shadow trace", default=0.0, update=assets.invalidate_shader_cache)
|
||||
@ -545,15 +548,17 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
||||
lnx_water_density: FloatProperty(name="Density", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_water_refract: FloatProperty(name="Refract", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_water_reflect: FloatProperty(name="Reflect", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_strength: FloatProperty(name="Strength", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_strength: FloatProperty(name="Strength", default=8.0, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_radius: FloatProperty(name="Radius", default=1.0, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_step: FloatProperty(name="Step", default=2.0, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_max_steps: IntProperty(name="Max Steps", default=8, update=assets.invalidate_shader_cache)
|
||||
lnx_ssgi_samples: IntProperty(name="Samples", default=32, update=assets.invalidate_shader_cache)
|
||||
"""
|
||||
lnx_ssgi_rays: EnumProperty(
|
||||
items=[('9', '9', '9'),
|
||||
('5', '5', '5'),
|
||||
],
|
||||
name="Rays", description="Number of rays to trace for RTAO", default='5', update=assets.invalidate_shader_cache)
|
||||
"""
|
||||
lnx_ssgi_half_res: BoolProperty(name="Half Res", description="Trace in half resolution", default=False, update=assets.invalidate_shader_cache)
|
||||
lnx_bloom_threshold: FloatProperty(name="Threshold", description="Brightness above which a pixel is contributing to the bloom effect", min=0, default=0.8, update=assets.invalidate_shader_cache)
|
||||
lnx_bloom_knee: FloatProperty(name="Knee", description="Smoothen transition around the threshold (higher values = smoother transition)", min=0, max=1, default=0.5, update=assets.invalidate_shader_cache)
|
||||
|
@ -1629,6 +1629,7 @@ class LNX_PT_RenderPathShadowsPanel(bpy.types.Panel):
|
||||
col.prop(rpdat, 'rp_shadowmap_cube')
|
||||
layout.prop(rpdat, 'rp_shadowmap_cascade')
|
||||
layout.prop(rpdat, 'rp_shadowmap_cascades')
|
||||
layout.prop(rpdat, 'rp_shadowmap_transparent')
|
||||
col = layout.column()
|
||||
col2 = col.column()
|
||||
col2.enabled = rpdat.rp_shadowmap_cascades != '1'
|
||||
@ -1760,7 +1761,7 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
|
||||
col3.enabled = rpdat.rp_voxels == 'Voxel AO'
|
||||
col.prop(rpdat, 'lnx_voxelgi_shadows', text='Shadows')
|
||||
col2.prop(rpdat, 'lnx_voxelgi_refract', text='Refraction')
|
||||
col.prop(rpdat, 'lnx_voxelgi_clipmap_count')
|
||||
#col.prop(rpdat, 'lnx_voxelgi_clipmap_count')
|
||||
#col.prop(rpdat, 'lnx_voxelgi_cones')
|
||||
col.prop(rpdat, 'rp_voxelgi_resolution')
|
||||
col.prop(rpdat, 'lnx_voxelgi_size')
|
||||
@ -1774,9 +1775,10 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
|
||||
col2.prop(rpdat, 'lnx_voxelgi_spec')
|
||||
col2.prop(rpdat, 'lnx_voxelgi_refr')
|
||||
col.prop(rpdat, 'lnx_voxelgi_shad')
|
||||
col.prop(rpdat, 'lnx_voxelgi_env')
|
||||
col.prop(rpdat, 'lnx_voxelgi_occ')
|
||||
col.label(text="Ray")
|
||||
col.prop(rpdat, 'lnx_voxelgi_offset')
|
||||
#col.prop(rpdat, 'lnx_voxelgi_offset')
|
||||
col.prop(rpdat, 'lnx_voxelgi_step')
|
||||
col.prop(rpdat, 'lnx_voxelgi_range')
|
||||
#col.prop(rpdat, 'lnx_voxelgi_aperture')
|
||||
@ -1867,10 +1869,10 @@ class LNX_PT_RenderPathPostProcessPanel(bpy.types.Panel):
|
||||
sub = col.column()
|
||||
sub.enabled = rpdat.rp_ssgi != 'Off'
|
||||
sub.prop(rpdat, 'lnx_ssgi_half_res')
|
||||
sub.prop(rpdat, 'lnx_ssgi_rays')
|
||||
#sub.prop(rpdat, 'lnx_ssgi_rays')
|
||||
sub.prop(rpdat, 'lnx_ssgi_radius')
|
||||
sub.prop(rpdat, 'lnx_ssgi_strength')
|
||||
sub.prop(rpdat, 'lnx_ssgi_max_steps')
|
||||
sub.prop(rpdat, 'lnx_ssgi_samples')
|
||||
layout.separator()
|
||||
|
||||
row = layout.row()
|
||||
|
@ -207,6 +207,8 @@ project.addSources('Sources');
|
||||
# get instantiated
|
||||
khafile.write("""project.addParameter("--macro include('leenkx.logicnode')");\n""")
|
||||
|
||||
if wrd.lnx_render_viewport:
|
||||
assets.add_khafile_def('lnx_render_viewport')
|
||||
import_traits = list(set(import_traits))
|
||||
for i in range(0, len(import_traits)):
|
||||
khafile.write("project.addParameter('" + import_traits[i] + "');\n")
|
||||
@ -625,32 +627,18 @@ def write_compiledglsl(defs, make_variants):
|
||||
|
||||
idx_emission = 2
|
||||
idx_refraction = 2
|
||||
|
||||
if '_gbuffer2' in wrd.world_defs:
|
||||
f.write('#define GBUF_IDX_2 2\n')
|
||||
idx_emission += 1
|
||||
idx_refraction += 1
|
||||
|
||||
# Special case for WebGL with both TAA and SSRefraction
|
||||
webgl_with_taa_refr = ('_kha_webgl' in wrd.world_defs and
|
||||
('_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs) and
|
||||
('_TAA' in wrd.world_defs or '_SMAA' in wrd.world_defs))
|
||||
|
||||
if webgl_with_taa_refr:
|
||||
# WebGL needs refraction to come before emission for correct rendering
|
||||
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_REFRACTION {idx_emission}\n')
|
||||
idx_emission += 1
|
||||
|
||||
if '_EmissionShaded' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
|
||||
else:
|
||||
# Standard order for all other platforms
|
||||
if '_EmissionShaded' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
|
||||
idx_refraction += 1
|
||||
|
||||
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\n')
|
||||
if '_EmissionShaded' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
|
||||
idx_refraction += 1
|
||||
|
||||
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\n')
|
||||
|
||||
f.write("""#if defined(HLSL) || defined(METAL)
|
||||
#define _InvY
|
||||
@ -684,16 +672,16 @@ const float waterReflect = """ + str(round(rpdat.lnx_water_reflect * 100) / 100)
|
||||
f'const float ditherStrengthValue = {rpdat.lnx_dithering_strength};\n'
|
||||
)
|
||||
|
||||
if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight:
|
||||
if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'SSGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight:
|
||||
f.write(
|
||||
"""const float ssaoRadius = """ + str(round(rpdat.lnx_ssgi_radius * 100) / 100) + """;
|
||||
const float ssaoStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """;
|
||||
const float ssaoScale = """ + ("2.0" if rpdat.lnx_ssgi_half_res else "20.0") + """;
|
||||
""")
|
||||
|
||||
if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO':
|
||||
if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_ssgi == 'SSGI' :
|
||||
f.write(
|
||||
"""const int ssgiMaxSteps = """ + str(rpdat.lnx_ssgi_max_steps) + """;
|
||||
"""const int ssgiSamples = """ + str(rpdat.lnx_ssgi_samples) + """;
|
||||
const float ssgiRayStep = 0.005 * """ + str(round(rpdat.lnx_ssgi_step * 100) / 100) + """;
|
||||
const float ssgiStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """;
|
||||
""")
|
||||
@ -840,6 +828,7 @@ const float voxelgiRange = """ + str(round(rpdat.lnx_voxelgi_range * 100) / 100)
|
||||
const float voxelgiOffset = """ + str(round(rpdat.lnx_voxelgi_offset * 1000) / 1000) + """;
|
||||
const float voxelgiAperture = """ + str(round(rpdat.lnx_voxelgi_aperture * 100) / 100) + """;
|
||||
const float voxelgiShad = """ + str(round(rpdat.lnx_voxelgi_shad * 100) / 100) + """;
|
||||
const float voxelgiEnv = """ + str(round(rpdat.lnx_voxelgi_env * 100) / 100) + """;
|
||||
""")
|
||||
if rpdat.rp_voxels == 'Voxel GI':
|
||||
f.write("""
|
||||
|
Reference in New Issue
Block a user