3 Commits

42 changed files with 2094 additions and 3597 deletions

View File

@ -2,10 +2,12 @@
-cp ../Kha/Backends/Krom -cp ../Kha/Backends/Krom
-cp ../leenkx/Sources -cp ../leenkx/Sources
-cp ../iron/Sources -cp ../iron/Sources
-cp ../lib/aura/Sources
-cp ../lib/haxebullet/Sources -cp ../lib/haxebullet/Sources
-cp ../lib/haxerecast/Sources -cp ../lib/haxerecast/Sources
-cp ../lib/zui/Sources -cp ../lib/zui/Sources
--macro include('iron', true, null, ['../iron/Sources']) --macro include('iron', true, null, ['../iron/Sources'])
--macro include('aura', true, null, ['../lib/aura/Sources'])
--macro include('haxebullet', true, null, ['../lib/haxebullet/Sources']) --macro include('haxebullet', true, null, ['../lib/haxebullet/Sources'])
--macro include('haxerecast', true, null, ['../lib/haxerecast/Sources']) --macro include('haxerecast', true, null, ['../lib/haxerecast/Sources'])
--macro include('leenkx', true, ['leenkx.network'], ['../leenkx/Sources','../iron/Sources']) --macro include('leenkx', true, ['leenkx.network'], ['../leenkx/Sources','../iron/Sources'])

View File

@ -29,11 +29,10 @@ uniform sampler2D gbuffer1;
#ifdef _VoxelGI #ifdef _VoxelGI
uniform sampler2D voxels_diffuse; uniform sampler2D voxels_diffuse;
uniform sampler2D voxels_specular; uniform sampler2D voxels_specular;
#else #endif
#ifdef _VoxelAOvar #ifdef _VoxelAOvar
uniform sampler2D voxels_ao; uniform sampler2D voxels_ao;
#endif #endif
#endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler3D voxelsSDF; uniform sampler3D voxelsSDF;
@ -57,10 +56,6 @@ uniform vec3 backgroundCol;
#ifdef _SSAO #ifdef _SSAO
uniform sampler2D ssaotex; uniform sampler2D ssaotex;
#else
#ifdef _SSGI
uniform sampler2D ssaotex;
#endif
#endif #endif
#ifdef _SSS #ifdef _SSS
@ -118,15 +113,11 @@ uniform vec2 cameraPlane;
#ifdef _SinglePoint #ifdef _SinglePoint
#ifdef _Spot #ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[1]; //!uniform sampler2DShadow shadowMapSpot[1];
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapSpotTransparent[1]; //!uniform sampler2D shadowMapSpotTransparent[1];
#endif
//!uniform mat4 LWVPSpot[1]; //!uniform mat4 LWVPSpot[1];
#else #else
//!uniform samplerCubeShadow shadowMapPoint[1]; //!uniform samplerCubeShadow shadowMapPoint[1];
#ifdef _ShadowMapTransparent
//!uniform samplerCube shadowMapPointTransparent[1]; //!uniform samplerCube shadowMapPointTransparent[1];
#endif
//!uniform vec2 lightProj; //!uniform vec2 lightProj;
#endif #endif
#endif #endif
@ -134,40 +125,30 @@ uniform vec2 cameraPlane;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifdef _SingleAtlas #ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlas; uniform sampler2DShadow shadowMapAtlas;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasTransparent; uniform sampler2D shadowMapAtlasTransparent;
#endif #endif
#endif
#endif #endif
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasPoint; //!uniform sampler2DShadow shadowMapAtlasPoint;
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapAtlasPointTransparent; //!uniform sampler2D shadowMapAtlasPointTransparent;
#endif #endif
#endif //!uniform vec4 pointLightDataArray[4];
//!uniform vec4 pointLightDataArray[maxLightsCluster * 6];
#else #else
//!uniform samplerCubeShadow shadowMapPoint[4]; //!uniform samplerCubeShadow shadowMapPoint[4];
#ifdef _ShadowMapTransparent
//!uniform samplerCube shadowMapPointTransparent[4]; //!uniform samplerCube shadowMapPointTransparent[4];
#endif
#endif #endif
//!uniform vec2 lightProj; //!uniform vec2 lightProj;
#ifdef _Spot #ifdef _Spot
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasSpot; //!uniform sampler2DShadow shadowMapAtlasSpot;
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapAtlasSpotTransparent; //!uniform sampler2D shadowMapAtlasSpotTransparent;
#endif #endif
#endif
#else #else
//!uniform sampler2DShadow shadowMapSpot[4]; //!uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapSpotTransparent[4]; //!uniform sampler2D shadowMapSpotTransparent[4];
#endif #endif
#endif
//!uniform mat4 LWVPSpotArray[maxLightsCluster]; //!uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif #endif
#endif #endif
@ -180,16 +161,12 @@ uniform vec3 sunCol;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun; uniform sampler2DShadow shadowMapAtlasSun;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasSunTransparent; uniform sampler2D shadowMapAtlasSunTransparent;
#endif #endif
#endif
#else #else
uniform sampler2DShadow shadowMap; uniform sampler2DShadow shadowMap;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapTransparent; uniform sampler2D shadowMapTransparent;
#endif #endif
#endif
uniform float shadowsBias; uniform float shadowsBias;
#ifdef _CSM #ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4]; //!uniform vec4 casData[shadowmapCascades * 4 + 4];
@ -250,22 +227,17 @@ void main() {
vec4 g2 = textureLod(gbuffer2, texCoord, 0.0); vec4 g2 = textureLod(gbuffer2, texCoord, 0.0);
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
#endif #endif
#ifdef _Brdf #ifdef _Brdf
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy; 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 #endif
#ifndef _VoxelAOvar
#ifndef _VoxelGI
// Envmap // Envmap
#ifdef _Irr #ifdef _Irr
vec3 envl = shIrradiance(n, shirr); vec3 envl = shIrradiance(n, shirr);
#ifdef _gbuffer2 #ifdef _gbuffer2
@ -299,33 +271,33 @@ void main() {
envl.rgb *= albedo; envl.rgb *= albedo;
#ifdef _Brdf #ifdef _Brdf
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y); //LV: We should take refracted light into account
#endif #endif
#ifdef _Rad // Indirect specular #ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y); //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
#else #else
#ifdef _EnvCol #ifdef _EnvCol
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0? envl.rgb += backgroundCol * (f0 * envBRDF.x + envBRDF.y); //LV: Eh, what's the point of weighting it only by F0?
#endif #endif
#endif #endif
envl.rgb *= envmapStrength * occspec.x; envl.rgb *= envmapStrength * occspec.x;
fragColor.rgb = envl;
#endif
#endif
#ifdef _VoxelGI #ifdef _VoxelGI
fragColor.rgb = textureLod(voxels_diffuse, texCoord, 0.0).rgb * voxelgiDiff; 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) if(roughness < 1.0 && occspec.y > 0.0)
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl; fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
#else
#ifdef _VoxelAOvar
fragColor.rgb = textureLod(voxels_ao, texCoord, 0.0).rgb * voxelgiOcc;
#endif
#endif #endif
#ifdef _VoxelAOvar
envl.rgb *= textureLod(voxels_ao, texCoord, 0.0).r;
#endif
#ifndef _VoxelGI
fragColor.rgb = envl;
#endif
// Show voxels // Show voxels
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99); // vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
// vec3 direction = vec3(0.0, 0.0, -1.0); // vec3 direction = vec3(0.0, 0.0, -1.0);
@ -345,10 +317,6 @@ void main() {
// #else // #else
fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r; fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r;
// #endif // #endif
#else
#ifdef _SSGI
fragColor.rgb += textureLod(ssaotex, texCoord, 0.0).rgb;
#endif
#endif #endif
#ifdef _EmissionShadeless #ifdef _EmissionShadeless
@ -381,70 +349,40 @@ void main() {
#ifdef _ShadowMap #ifdef _ShadowMap
#ifdef _CSM #ifdef _CSM
svisibility = shadowTestCascade( svisibility = shadowTestCascade(
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifdef _ShadowMapTransparent #ifndef _SingleAtlas
#ifndef _SingleAtlas shadowMapAtlasSun, shadowMapAtlasSunTransparent
shadowMapAtlasSun, shadowMapAtlasSunTransparent #else
#else shadowMapAtlas, shadowMapAtlasTransparent
shadowMapAtlas, shadowMapAtlasTransparent #endif
#endif #else
#else shadowMap, shadowMapTransparent
#ifndef _SingleAtlas #endif
shadowMapAtlasSun , eye, p + n * shadowsBias * 10, shadowsBias, false
#else );
shadowMapAtlas
#endif
#endif
#else
#ifdef _ShadowMapTransparent
shadowMap, shadowMapTransparent
#else
shadowMap
#endif
#endif
, eye, p + n * shadowsBias * 10, shadowsBias
#ifdef _ShadowMapTransparent
, false
#endif
);
#else #else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0); vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) { if (lPos.w > 0.0) {
svisibility = shadowTest( svisibility = shadowTest(
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifdef _ShadowMapTransparent #ifndef _SingleAtlas
#ifndef _SingleAtlas shadowMapAtlasSun, shadowMapAtlasSunTransparent
shadowMapAtlasSun, shadowMapAtlasSunTransparent #else
#else shadowMapAtlas, shadowMapAtlasTransparent
shadowMapAtlas, shadowMapAtlasTransparent #endif
#endif #else
#else shadowMap, shadowMapTransparent
#ifndef _SingleAtlas #endif
shadowMapAtlasSun , lPos.xyz / lPos.w, shadowsBias, false
#else );
shadowMapAtlas
#endif
#endif
#else
#ifdef _ShadowMapTransparent
shadowMap, shadowMapTransparent
#else
shadowMap
#endif
#endif
, lPos.xyz / lPos.w, shadowsBias
#ifdef _ShadowMapTransparent
, false
#endif
);
} }
#endif #endif
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, -g2.rg).r) * voxelgiShad; svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
#endif #endif
#ifdef _SSRS #ifdef _SSRS
// vec2 coords = getProjectedCoord(hitCoord); // vec2 coords = getProjectedCoord(hitCoord);
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy); // vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
@ -501,16 +439,13 @@ void main() {
fragColor.rgb += sampleLight( fragColor.rgb += sampleLight(
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0 p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
#ifdef _ShadowMap #ifdef _ShadowMap
, 0, pointBias, true , 0, pointBias, true, false
#ifdef _ShadowMapTransparent
, false
#endif
#endif #endif
#ifdef _Spot #ifdef _Spot
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight , true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
, voxels, voxelsSDF, clipmaps, -g2.rg , voxels, voxelsSDF, clipmaps
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
, occspec.x , occspec.x
@ -557,10 +492,7 @@ void main() {
f0 f0
#ifdef _ShadowMap #ifdef _ShadowMap
// light index, shadow bias, cast_shadows // light index, shadow bias, cast_shadows
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0 , li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false
#ifdef _ShadowMapTransparent
, false
#endif
#endif #endif
#ifdef _Spot #ifdef _Spot
, lightsArray[li * 3 + 2].y != 0.0 , lightsArray[li * 3 + 2].y != 0.0
@ -571,7 +503,7 @@ void main() {
, lightsArraySpot[li * 2 + 1].xyz // right , lightsArraySpot[li * 2 + 1].xyz // right
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
, voxels, voxelsSDF, clipmaps, -g2.rg , voxels, voxelsSDF, clipmaps
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
, occspec.x , occspec.x
@ -582,5 +514,14 @@ void main() {
); );
} }
#endif // _Clusters #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 fragColor.a = 1.0; // Mark as opaque
} }

View File

@ -1,506 +1,107 @@
#version 450 #version 450
#include "compiled.inc" #include "compiled.inc"
#include "std/gbuffer.glsl"
#include "std/brdf.glsl"
#include "std/math.glsl" #include "std/math.glsl"
#ifdef _Clusters #include "std/gbuffer.glsl"
#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 gbufferD;
#ifdef _EmissionShaded uniform sampler2D gbuffer0; // Normal
uniform sampler2D gbufferEmission; // #ifdef _RTGI
#endif // uniform sampler2D gbuffer1; // Basecol
uniform sampler2D sveloc; // #endif
uniform mat4 P;
uniform mat3 V3;
uniform vec2 cameraProj; uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 screenSize;
uniform mat4 invVP;
in vec2 texCoord; 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;
#endif
in vec3 viewRay; in vec3 viewRay;
out vec3 fragColor; in vec2 texCoord;
out float fragColor;
float metallic; vec3 hitCoord;
uint matid; vec2 coord;
float depth;
// #ifdef _RTGI
// vec3 col = vec3(0.0);
// #endif
vec3 vpos;
#ifdef _SMSizeUniform vec2 getProjectedCoord(vec3 hitCoord) {
//!uniform vec2 smSizeUniform; vec4 projectedCoord = P * vec4(hitCoord, 1.0);
#endif projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
#ifdef _InvY
projectedCoord.y = 1.0 - projectedCoord.y;
#endif
return projectedCoord.xy;
}
#ifdef _Clusters float getDeltaDepth(vec3 hitCoord) {
uniform vec4 lightsArray[maxLights * 3]; coord = getProjectedCoord(hitCoord);
#ifdef _Spot depth = textureLod(gbufferD, coord, 0.0).r * 2.0 - 1.0;
uniform vec4 lightsArraySpot[maxLights * 2]; vec3 p = getPosView(viewRay, depth, cameraProj);
#endif return p.z - hitCoord.z;
uniform sampler2D clustersData; }
uniform vec2 cameraPlane;
#endif
#ifdef _SinglePoint // Fast path for single light void rayCast(vec3 dir) {
uniform vec3 pointPos; hitCoord = vpos;
uniform vec3 pointCol; dir *= ssgiRayStep * 2;
#ifdef _ShadowMap float dist = 0.15;
uniform float pointBias; for (int i = 0; i < ssgiMaxSteps; i++) {
#endif hitCoord += dir;
#ifdef _Spot float delta = getDeltaDepth(hitCoord);
uniform vec3 spotDir; if (delta > 0.0 && delta < 0.2) {
uniform vec3 spotRight; dist = distance(vpos, hitCoord);
uniform vec4 spotData; break;
#endif
#endif
#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;
} }
#endif fragColor += dist;
// #ifdef _RTGI
#ifdef _LightIES // col += textureLod(gbuffer1, coord, 0.0).rgb * ((ssgiRayStep * ssgiMaxSteps) - dist);
visibility *= iesAttenuation(-l); // #endif
#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 getVisibility(vec3 p, vec3 n, float depth, vec2 uv) { vec3 tangent(const vec3 n) {
vec3 visibility = vec3(0.0); vec3 t1 = cross(n, vec3(0, 0, 1));
#ifdef _Sun vec3 t2 = cross(n, vec3(0, 1, 0));
#ifdef _ShadowMap if (length(t1) > length(t2)) return normalize(t1);
#ifdef _CSM else return normalize(t2);
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() { void main() {
float depth = textureLod(gbufferD, texCoord, 0.0).r; fragColor = 0;
if (depth >= 1.0) { vec4 g0 = textureLod(gbuffer0, texCoord, 0.0);
fragColor = vec3(0.0); float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.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; vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y); n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy); n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n); n = normalize(V3 * n);
vec3 pos = getWorldPos(texCoord, depth); vpos = getPosView(viewRay, d, cameraProj);
vec3 normal = getNormal(texCoord);
vec3 centerColor = textureLod(gbuffer1, texCoord, 0.0).rgb;
float radius = ssaoRadius; 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));
vec3 gi = vec3(0.0); #ifdef _SSGICone9
float totalWeight = 0.0; rayCast(mix(n, -o1, angleMix));
float angle = fract(sin(dot(texCoord, vec2(12.9898, 78.233))) * 100.0); rayCast(mix(n, -o2, angleMix));
rayCast(mix(n, c1, angleMix));
for (int i = 0; i < ssgiSamples; i++) { rayCast(mix(n, c2, angleMix));
// 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 #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
} }

View File

@ -6,10 +6,6 @@
"compare_mode": "always", "compare_mode": "always",
"cull_mode": "none", "cull_mode": "none",
"links": [ "links": [
{
"name": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{ {
"name": "P", "name": "P",
"link": "_projectionMatrix" "link": "_projectionMatrix"
@ -19,180 +15,16 @@
"link": "_viewMatrix3" "link": "_viewMatrix3"
}, },
{ {
"name": "eye", "name": "invP",
"link": "_cameraPosition" "link": "_inverseProjectionMatrix"
},
{
"name": "eyeLook",
"link": "_cameraLook"
}, },
{ {
"name": "cameraProj", "name": "cameraProj",
"link": "_cameraPlaneProj" "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": [], "texture_params": [],
"vertex_shader": "../include/pass_viewray.vert.glsl", "vertex_shader": "../include/pass_viewray2.vert.glsl",
"fragment_shader": "ssgi_pass.frag.glsl" "fragment_shader": "ssgi_pass.frag.glsl"
} }
] ]

View File

@ -72,11 +72,10 @@ void main() {
float roughness = g0.z; float roughness = g0.z;
vec4 gr = textureLod(gbuffer_refraction, texCoord, 0.0); vec4 gr = textureLod(gbuffer_refraction, texCoord, 0.0);
float ior = gr.x; float ior = gr.x;
float opac = 1.0 - gr.y; float opac = gr.y;
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0; float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (d == 0.0 || d == 1.0 || opac == 1.0 || ior == 1.0) { if (d == 0.0 || d == 1.0 || opac == 1.0 || ior == 1.0) {
fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb; fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
fragColor.a = opac;
return; return;
} }
vec2 enc = g0.rg; vec2 enc = g0.rg;
@ -99,12 +98,9 @@ void main() {
clamp(-refracted.z, 0.0, 1.0) * clamp((length(viewPos - hitCoord)), 0.0, 1.0) * coords.w; clamp(-refracted.z, 0.0, 1.0) * clamp((length(viewPos - hitCoord)), 0.0, 1.0) * coords.w;
intensity = clamp(intensity, 0.0, 1.0); intensity = clamp(intensity, 0.0, 1.0);
vec4 refractionCol = textureLod(tex1, coords.xy, 0.0).rgba; vec3 refractionCol = textureLod(tex1, coords.xy, 0.0).rgb;
refractionCol.a = opac; refractionCol *= intensity;
//refractionCol *= intensity; vec3 color = textureLod(tex, texCoord.xy, 0.0).rgb;
vec4 color = textureLod(tex, texCoord.xy, 0.0).rgba;
color.a = opac;
fragColor.rgba = mix(refractionCol, color, opac); fragColor.rgb = mix(refractionCol, color, opac);
fragColor.a = opac;
} }

View File

@ -5,12 +5,6 @@
"depth_write": false, "depth_write": false,
"compare_mode": "always", "compare_mode": "always",
"cull_mode": "none", "cull_mode": "none",
"blend_source": "source_alpha",
"blend_destination": "inverse_source_alpha",
"blend_operation": "add",
"alpha_blend_source": "blend_one",
"alpha_blend_destination": "blend_one",
"alpha_blend_operation": "add",
"links": [ "links": [
{ {
"name": "P", "name": "P",

View File

@ -1,7 +1,6 @@
// //
// Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com) // Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com)
// Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es) // Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es)
// Copyright (C) 2025 Onek8 (info@leenkx.com)
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -34,14 +33,6 @@
// policies, either expressed or implied, of the copyright holders. // policies, either expressed or implied, of the copyright holders.
// //
// TODO:
// Add real sss radius
// Add real sss scale
// Move temp hash, reorganize shader utility functions
// Add compiler flag for quality presets or with samples parameter
// Clean up + Document comment
#version 450 #version 450
#include "compiled.inc" #include "compiled.inc"
@ -58,93 +49,67 @@ out vec4 fragColor;
const float SSSS_FOVY = 108.0; const float SSSS_FOVY = 108.0;
// Temp hash func - // Separable SSS Reflectance
float hash13(vec3 p3) { // const float sssWidth = 0.005;
p3 = fract(p3 * vec3(0.1031, 0.1030, 0.0973));
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
}
vec4 SSSSBlur() { vec4 SSSSBlur() {
const int SSSS_N_SAMPLES = 15; // Quality = 0
vec4 kernel[SSSS_N_SAMPLES]; const int SSSS_N_SAMPLES = 11;
vec4 kernel[SSSS_N_SAMPLES];
// color neutral kernel weights to prevent color shifting kernel[0] = vec4(0.560479, 0.669086, 0.784728, 0);
kernel[0] = vec4(0.2, 0.2, 0.2, 0.0); kernel[1] = vec4(0.00471691, 0.000184771, 5.07566e-005, -2);
kernel[1] = vec4(0.12, 0.12, 0.12, 0.2); kernel[2] = vec4(0.0192831, 0.00282018, 0.00084214, -1.28);
kernel[2] = vec4(0.09, 0.09, 0.09, 0.4); kernel[3] = vec4(0.03639, 0.0130999, 0.00643685, -0.72);
kernel[3] = vec4(0.06, 0.06, 0.06, 0.8); kernel[4] = vec4(0.0821904, 0.0358608, 0.0209261, -0.32);
kernel[4] = vec4(0.04, 0.04, 0.04, 1.2); kernel[5] = vec4(0.0771802, 0.113491, 0.0793803, -0.08);
kernel[5] = vec4(0.025, 0.025, 0.025, 1.6); kernel[6] = vec4(0.0771802, 0.113491, 0.0793803, 0.08);
kernel[6] = vec4(0.015, 0.015, 0.015, 2.0); kernel[7] = vec4(0.0821904, 0.0358608, 0.0209261, 0.32);
kernel[7] = vec4(0.005, 0.005, 0.005, 2.5); kernel[8] = vec4(0.03639, 0.0130999, 0.00643685, 0.72);
kernel[8] = vec4(0.12, 0.12, 0.12, -0.2); kernel[9] = vec4(0.0192831, 0.00282018, 0.00084214, 1.28);
kernel[9] = vec4(0.09, 0.09, 0.09, -0.4); kernel[10] = vec4(0.00471691, 0.000184771, 5.07565e-005, 2);
kernel[10] = vec4(0.06, 0.06, 0.06, -0.8);
kernel[11] = vec4(0.04, 0.04, 0.04, -1.2);
kernel[12] = vec4(0.025, 0.025, 0.025, -1.6);
kernel[13] = vec4(0.015, 0.015, 0.015, -2.0);
kernel[14] = vec4(0.005, 0.005, 0.005, -2.5);
vec4 colorM = textureLod(tex, texCoord, 0.0); vec4 colorM = textureLod(tex, texCoord, 0.0);
// Fetch linear depth of current pixel
float depth = textureLod(gbufferD, texCoord, 0.0).r; float depth = textureLod(gbufferD, texCoord, 0.0).r;
float depthM = cameraProj.y / (depth - cameraProj.x); float depthM = cameraProj.y / (depth - cameraProj.x);
// Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window)
float distanceToProjectionWindow = 1.0 / tan(0.5 * radians(SSSS_FOVY)); float distanceToProjectionWindow = 1.0 / tan(0.5 * radians(SSSS_FOVY));
float scale = distanceToProjectionWindow / depthM; float scale = distanceToProjectionWindow / depthM;
// Calculate the final step to fetch the surrounding pixels
vec2 finalStep = sssWidth * scale * dir; vec2 finalStep = sssWidth * scale * dir;
finalStep *= 1.0;//SSSS_STREGTH_SOURCE; // Modulate it using the alpha channel.
finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
finalStep *= 0.05; //
vec3 jitterSeed = vec3(texCoord.xy * 1000.0, fract(cameraProj.x * 0.0001)); // Accumulate the center sample:
float jitterOffset = (hash13(jitterSeed) * 2.0 - 1.0) * 0.15; // 15% jitteR vec4 colorBlurred = colorM;
colorBlurred.rgb *= kernel[0].rgb;
finalStep *= (1.0 + jitterOffset);
finalStep *= 0.05; // Accumulate the other samples
vec3 colorBlurred = vec3(0.0);
vec3 weightSum = vec3(0.0);
colorBlurred += colorM.rgb * kernel[0].rgb;
weightSum += kernel[0].rgb;
// Accumulate the other samples with per-pixel jittering to reduce banding
for (int i = 1; i < SSSS_N_SAMPLES; i++) { for (int i = 1; i < SSSS_N_SAMPLES; i++) {
float sampleJitter = hash13(vec3(texCoord.xy * 720.0, float(i) * 37.45)) * 0.1 - 0.05; // Fetch color and depth for current sample
vec2 offset = texCoord + kernel[i].a * finalStep;
vec2 offset = texCoord + (kernel[i].a + sampleJitter) * finalStep;
vec4 color = textureLod(tex, offset, 0.0); vec4 color = textureLod(tex, offset, 0.0);
//#if SSSS_FOLLOW_SURFACE == 1
// ADJUST FOR SURFACE FOLLOWING // If the difference in depth is huge, we lerp color back to "colorM":
// 0.0 = disabled (maximum SSS but with bleeding), 1.0 = fully enabled (prevents bleeding but might reduce SSS effect) //float depth = textureLod(tex, offset, 0.0).r;
const float SURFACE_FOLLOWING_STRENGTH = 0.15; // Reduced to preserve more SSS effect //float s = clamp(300.0f * distanceToProjectionWindow * sssWidth * abs(depthM - depth),0.0,1.0);
//color.rgb = mix(color.rgb, colorM.rgb, s);
if (SURFACE_FOLLOWING_STRENGTH > 0.0) { //#endif
float sampleDepth = textureLod(gbufferD, offset, 0.0).r; // Accumulate
float depthScale = 5.0; colorBlurred.rgb += kernel[i].rgb * color.rgb;
float depthDiff = abs(depth - sampleDepth) * depthScale;
if (depthDiff > 0.3) {
float blendFactor = clamp(depthDiff - 0.3, 0.0, 1.0) * SURFACE_FOLLOWING_STRENGTH;
color.rgb = mix(color.rgb, colorM.rgb, blendFactor);
}
}
colorBlurred += color.rgb * kernel[i].rgb;
weightSum += kernel[i].rgb;
} }
vec3 normalizedColor = colorBlurred / max(weightSum, vec3(0.00001));
float dither = hash13(vec3(texCoord * 1333.0, 0.0)) * 0.003 - 0.0015; return colorBlurred;
return vec4(normalizedColor + vec3(dither), colorM.a);
} }
void main() { void main() {
if (textureLod(gbuffer0, texCoord, 0.0).a == 8192.0) { if (textureLod(gbuffer0, texCoord, 0.0).a == 8192.0) {
vec4 originalColor = textureLod(tex, texCoord, 0.0); fragColor = clamp(SSSSBlur(), 0.0, 1.0);
vec4 blurredColor = SSSSBlur(); }
vec4 finalColor = mix(blurredColor, originalColor, 0.15); else {
fragColor = clamp(finalColor, 0.0, 1.0);
} else {
fragColor = textureLod(tex, texCoord, 0.0); fragColor = textureLod(tex, texCoord, 0.0);
} }
} }

View File

@ -1,18 +0,0 @@
#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

View File

@ -22,7 +22,7 @@ THE SOFTWARE.
#ifndef _CONETRACE_GLSL_ #ifndef _CONETRACE_GLSL_
#define _CONETRACE_GLSL_ #define _CONETRACE_GLSL_
#include "std/constants.glsl" #include "std/voxels_constants.glsl"
// References // References
// https://github.com/Friduric/voxel-cone-tracing // 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 dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0; vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; 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) { 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); vec4 mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight);
mipSample = mix(mipSample, mipSampleNext, clipmap_blend); mipSample = mix(mipSample, mipSampleNext, smoothstep(0.0, 1.0, clipmap_blend));
} }
sampleCol += (1.0 - sampleCol.a) * mipSample; sampleCol += (1.0 - sampleCol.a) * mipSample;
@ -148,9 +148,8 @@ 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]) { vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) {
float sum = 0.0; float sum = 0.0;
vec4 amount = vec4(0.0); vec4 amount = vec4(0.0);
mat3 TBN = makeTangentBasis(normal);
for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) { for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) {
vec3 coneDir = TBN * DIFFUSE_CONE_DIRECTIONS[i]; vec3 coneDir = DIFFUSE_CONE_DIRECTIONS[i];
const float cosTheta = dot(normal, coneDir); const float cosTheta = dot(normal, coneDir);
if (cosTheta <= 0) if (cosTheta <= 0)
continue; continue;
@ -167,7 +166,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) { 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(normalize(-viewDir), normal); vec3 specularDir = reflect(-viewDir, normal);
vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep; 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); vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -177,9 +176,9 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels,
return amount * voxelgiOcc; 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 opacity) { 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 - opacity; const float transmittance = 1.0;
vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior); vec3 refractionDir = refract(-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; 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); vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -197,7 +196,7 @@ float traceConeAO(const sampler3D voxels, const vec3 origin, const vec3 n, const
float dist = voxelSize0; float dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0; vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; vec3 aniso_direction = -dir;
@ -260,6 +259,7 @@ float traceAO(const vec3 origin, const vec3 normal, const sampler3D voxels, cons
} }
#endif #endif
#ifdef _VoxelShadow #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 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; float sampleCol = 0.0;
@ -267,7 +267,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
float dist = voxelSize0; float dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0; vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; vec3 aniso_direction = -dir;
@ -287,7 +287,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
float clipmap_blend = fract(lod); float clipmap_blend = fract(lod);
vec3 p0 = start_pos + dir * dist; 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); 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 = samplePos * 0.5 + 0.5; samplePos = samplePos * 0.5 + 0.5;
if ((any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0))))) { 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, const vec2 velocity) { 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 + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep; vec3 P = origin + dir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep;
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, SHADOW_CONE_APERTURE, voxelgiStep, clipmaps); float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
amount = clamp(amount, 0.0, 1.0); amount = clamp(amount, 0.0, 1.0);
return amount * voxelgiOcc; return amount * voxelgiOcc;
} }

View File

@ -1,679 +1,239 @@
#ifndef _LIGHT_GLSL_ #ifndef _LIGHT_GLSL_
#define _LIGHT_GLSL_ #define _LIGHT_GLSL_
#include "compiled.inc" #include "compiled.inc"
#include "std/brdf.glsl" #include "std/brdf.glsl"
#include "std/math.glsl" #include "std/math.glsl"
#ifdef _ShadowMap #ifdef _ShadowMap
#include "std/shadows.glsl" #include "std/shadows.glsl"
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#endif //!uniform sampler2D voxels_shadows;
#ifdef _LTC #endif
#include "std/ltc.glsl" #ifdef _LTC
#endif #include "std/ltc.glsl"
#ifdef _LightIES #endif
#include "std/ies.glsl" #ifdef _LightIES
#endif #include "std/ies.glsl"
#ifdef _SSRS #endif
#include "std/ssrs.glsl" #ifdef _SSRS
#endif #include "std/ssrs.glsl"
#ifdef _Spot #endif
#include "std/light_common.glsl" #ifdef _Spot
#endif #include "std/light_common.glsl"
#ifdef _VoxelShadow #endif
#include "std/conetrace.glsl"
#endif #ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _ShadowMap #ifdef _Spot
#ifdef _SinglePoint #ifndef _LTC
#ifdef _Spot uniform sampler2DShadow shadowMapSpot[1];
#ifndef _LTC uniform sampler2D shadowMapSpotTransparent[1];
uniform sampler2DShadow shadowMapSpot[1]; uniform mat4 LWVPSpot[1];
#ifdef _ShadowMapTransparent #endif
uniform sampler2D shadowMapSpotTransparent[1]; #else
#endif uniform samplerCubeShadow shadowMapPoint[1];
uniform mat4 LWVPSpotArray[1]; uniform samplerCube shadowMapPointTransparent[1];
#endif uniform vec2 lightProj;
#else #endif
uniform samplerCubeShadow shadowMapPoint[1]; #endif
#ifdef _ShadowMapTransparent #ifdef _Clusters
uniform samplerCube shadowMapPointTransparent[1]; #ifdef _SingleAtlas
#endif //!uniform sampler2DShadow shadowMapAtlas;
uniform vec2 lightProj; //!uniform sampler2D shadowMapAtlasTransparent;
#endif #endif
#endif uniform vec2 lightProj;
#ifdef _Clusters #ifdef _ShadowMapAtlas
#ifdef _SingleAtlas #ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas; uniform sampler2DShadow shadowMapAtlasPoint;
#ifdef _ShadowMapTransparent uniform sampler2D shadowMapAtlasPointTransparent;
//!uniform sampler2D shadowMapAtlasTransparent; #endif
#endif #else
#endif uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj; uniform samplerCube shadowMapPointTransparent[4];
#ifdef _ShadowMapAtlas #endif
#ifndef _SingleAtlas #ifdef _Spot
uniform sampler2DShadow shadowMapAtlasPoint; #ifdef _ShadowMapAtlas
#ifdef _ShadowMapTransparent #ifndef _SingleAtlas
uniform sampler2D shadowMapAtlasPointTransparent; uniform sampler2DShadow shadowMapAtlasSpot;
#endif uniform sampler2D shadowMapAtlasSpotTransparent;
#endif #endif
#else #else
uniform samplerCubeShadow shadowMapPoint[4]; uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMapTransparent uniform sampler2D shadowMapSpotTransparent[4];
uniform samplerCube shadowMapPointTransparent[4]; #endif
#endif uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif #endif
#ifdef _Spot #endif
#ifdef _ShadowMapAtlas #endif
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot; #ifdef _LTC
#ifdef _ShadowMapTransparent uniform vec3 lightArea0;
uniform sampler2D shadowMapAtlasSpotTransparent; uniform vec3 lightArea1;
#endif uniform vec3 lightArea2;
#endif uniform vec3 lightArea3;
#else uniform sampler2D sltcMat;
uniform sampler2DShadow shadowMapSpot[4]; uniform sampler2D sltcMag;
#ifdef _ShadowMapTransparent #ifdef _ShadowMap
uniform sampler2D shadowMapSpotTransparent[4]; #ifndef _Spot
#endif #ifdef _SinglePoint
#endif uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpotArray[maxLightsCluster]; uniform sampler2D shadowMapSpotTransparent[1];
#endif uniform mat4 LWVPSpot[1];
#endif #endif
#endif #ifdef _Clusters
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
#ifdef _LTC uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
uniform vec3 lightArea0; uniform mat4 LWVPSpotArray[maxLightsCluster];
uniform vec3 lightArea1; #endif
uniform vec3 lightArea2; #endif
uniform vec3 lightArea3; #endif
uniform sampler2D sltcMat; #endif
uniform sampler2D sltcMag;
#ifdef _ShadowMap vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
#ifndef _Spot const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _SinglePoint #ifdef _ShadowMap
uniform sampler2DShadow shadowMapSpot[1]; , int index, float bias, bool receiveShadow, bool transparent
#ifdef _ShadowMapTransparent #endif
uniform sampler2D shadowMapSpotTransparent[1]; #ifdef _Spot
#endif , const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
uniform mat4 LWVPSpotArray[1]; #endif
#endif #ifdef _VoxelShadow
#ifdef _Clusters , sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
uniform sampler2DShadow shadowMapSpot[maxLightsCluster]; #endif
#ifdef _ShadowMapTransparent #ifdef _MicroShadowing
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster]; , float occ
#endif #endif
uniform mat4 LWVPSpotArray[maxLightsCluster]; #ifdef _SSRS
#endif , sampler2D gbufferD, mat4 invVP, vec3 eye
#endif #endif
#endif ) {
#endif vec3 ld = lp - p;
vec3 l = normalize(ld);
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol, vec3 h = normalize(v + l);
const vec3 albedo, const float rough, const float spec, const vec3 f0 float dotNH = max(0.0, dot(n, h));
#ifdef _ShadowMap float dotVH = max(0.0, dot(v, h));
, int index, float bias, bool receiveShadow float dotNL = max(0.0, dot(n, l));
#ifdef _ShadowMapTransparent
, bool transparent #ifdef _LTC
#endif float theta = acos(dotNV);
#endif vec2 tuv = vec2(rough, theta / (0.5 * PI));
#ifdef _Spot tuv = tuv * LUT_SCALE + LUT_BIAS;
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right vec4 t = textureLod(sltcMat, tuv, 0.0);
#endif mat3 invM = mat3(
#ifdef _VoxelShadow vec3(1.0, 0.0, t.y),
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount], vec2 velocity vec3(0.0, t.z, 0.0),
#endif vec3(t.w, 0.0, t.x));
#ifdef _MicroShadowing float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
, float occ ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
#endif float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
#ifdef _SSRS vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
, sampler2D gbufferD, mat4 invVP, vec3 eye #else
#endif vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
) { specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
vec3 ld = lp - p; #endif
vec3 l = normalize(ld);
vec3 h = normalize(v + l); direct *= attenuate(distance(p, lp));
float dotNH = max(0.0, dot(n, h)); direct *= lightCol;
float dotVH = max(0.0, dot(v, h));
float dotNL = max(0.0, dot(n, l)); #ifdef _MicroShadowing
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
#ifdef _LTC #endif
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI)); #ifdef _SSRS
tuv = tuv * LUT_SCALE + LUT_BIAS; direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
vec4 t = textureLod(sltcMat, tuv, 0.0); #endif
mat3 invM = mat3(
vec3(1.0, 0.0, t.y), #ifdef _VoxelShadow
vec3(0.0, t.z, 0.0), direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
vec3(t.w, 0.0, t.x)); #endif
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a; #ifdef _LTC
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3); #ifdef _ShadowMap
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05; if (receiveShadow) {
#else #ifdef _SinglePoint
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec; direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif #endif
#ifdef _Clusters
direct *= attenuate(distance(p, lp)); vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
direct *= lightCol; 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);
#ifdef _MicroShadowing else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0); else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
#endif #endif
}
#ifdef _SSRS #endif
direct *= traceShadowSS(l, p, gbufferD, invVP, eye); return direct;
#endif #endif
#ifdef _VoxelShadow #ifdef _Spot
vec3 lightDir = l; if (isSpot) {
#ifdef _Spot direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
if (isSpot)
lightDir = spotDir; #ifdef _ShadowMap
#endif if (receiveShadow) {
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, lightDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad; #ifdef _SinglePoint
#endif vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#ifdef _LTC #endif
#ifdef _ShadowMap #ifdef _Clusters
if (receiveShadow) { vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _SinglePoint #ifdef _ShadowMapAtlas
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0); direct *= shadowTest(
direct *= shadowTest(shadowMapSpot[0], #ifndef _SingleAtlas
#ifdef _ShadowMapTransparent shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
shadowMapSpotTransparent[0], #else
#endif shadowMapAtlas, shadowMapAtlasTransparent
lPos.xyz / lPos.w, bias #endif
#ifdef _ShadowMapTransparent , lPos.xyz / lPos.w, bias, transparent
, transparent );
#endif #else
); if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
#ifdef _Clusters else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0); else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
if (index == 0) direct *= shadowTest(shadowMapSpot[0], #endif
#ifdef _ShadowMapTransparent #endif
shadowMapSpotTransparent[0], }
#endif #endif
lPos.xyz / lPos.w, bias return direct;
#ifdef _ShadowMapTransparent }
, transparent #endif
#endif
); #ifdef _LightIES
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], direct *= iesAttenuation(-l);
#ifdef _ShadowMapTransparent #endif
shadowMapSpotTransparent[1],
#endif #ifdef _ShadowMap
lPos.xyz / lPos.w, bias if (receiveShadow) {
#ifdef _ShadowMapTransparent #ifdef _SinglePoint
, transparent #ifndef _Spot
#endif direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
); #endif
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], #endif
#ifdef _ShadowMapTransparent #ifdef _Clusters
shadowMapSpotTransparent[2], #ifdef _ShadowMapAtlas
#endif direct *= PCFFakeCube(
lPos.xyz / lPos.w, bias #ifndef _SingleAtlas
#ifdef _ShadowMapTransparent shadowMapAtlasPoint, shadowMapAtlasPointTransparent
, transparent #else
#endif shadowMapAtlas, shadowMapAtlasTransparent
); #endif
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], , ld, -l, bias, lightProj, n, index, transparent
#ifdef _ShadowMapTransparent );
shadowMapSpotTransparent[3], #else
#endif if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
lPos.xyz / lPos.w, bias else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
#ifdef _ShadowMapTransparent else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
, transparent else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
#endif #endif
); #endif
#endif }
} #endif
#endif
return direct; return direct;
#endif }
#ifdef _Spot #endif
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

View File

@ -58,15 +58,7 @@ vec2 sampleCube(vec3 dir, out int faceIndex) {
} }
#endif #endif
vec3 PCF(sampler2DShadow shadowMap, vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 uv, const float compare, const vec2 smSize, const bool transparent) {
#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); 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, -1.0) / smSize), compare));
result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare)); result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
@ -79,13 +71,11 @@ vec3 PCF(sampler2DShadow shadowMap,
result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare)); result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare));
result = result.xxx / 9.0; result = result.xxx / 9.0;
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapTransparent, uv); vec4 shadowmap_transparent = texture(shadowMapTransparent, uv);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
@ -97,15 +87,41 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
return zcomp * 0.5 + 0.5; return zcomp * 0.5 + 0.5;
} }
vec3 PCFCube(samplerCubeShadow shadowMapCube, #ifndef _ShadowMapAtlas
#ifdef _ShadowMapTransparent vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, vec3 lp, vec3 ml, float bias, vec2 lightProj, vec3 n, const bool transparent) {
samplerCube shadowMapCubeTransparent, const float s = shadowmapCubePcfSize;
#endif float compare = lpToDepth(lp, lightProj) - bias * 1.5;
const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n ml = ml + n * bias * 20;
#ifdef _ShadowMapTransparent #ifdef _InvY
, const bool transparent ml.y = -ml.y;
#endif #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) {
const float s = shadowmapCubePcfSize; // TODO: incorrect... const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp, lightProj) - bias * 1.5; float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
@ -124,18 +140,16 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube,
result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare)); result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
result = result.xxx / 9.0; result = result.xxx / 9.0;
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml); vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
#ifdef _ShadowMapAtlas
// transform "out-of-bounds" coordinates to the correct face/coordinate system // transform "out-of-bounds" coordinates to the correct face/coordinate system
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png // https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) { vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
@ -229,31 +243,21 @@ vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
return uv; return uv;
} }
vec3 PCFFakeCube(sampler2DShadow shadowMap, 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) {
#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 vec2 smSize = smSizeUniform; // TODO: incorrect...
const float compare = lpToDepth(lp, lightProj) - bias * 1.5; const float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
int faceIndex = 0; int faceIndex = 0;
const int lightIndex = index * 6; const int lightIndex = index * 6;
const vec2 uv = sampleCube(ml, faceIndex); 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 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; vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _FlipY #ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif #endif
if (any(lessThan(uvtiled, vec2(0.0))) || any(greaterThan(uvtiled, vec2(1.0)))) {
return vec3(1.0); // Handle edge cases by returning full light
}
vec3 result = vec3(0.0); vec3 result = vec3(0.0);
result.x += texture(shadowMap, vec3(uvtiled, compare)); result.x += texture(shadowMap, vec3(uvtiled, compare));
// soft shadowing // soft shadowing
@ -266,6 +270,14 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
#endif #endif
result.x += texture(shadowMap, vec3(uvtiled, compare)); 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))); uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex]; pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy; uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
@ -322,47 +334,30 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif #endif
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled); vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
#endif #endif
vec3 shadowTest(sampler2DShadow shadowMap, vec3 shadowTest(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lPos, const float shadowsBias, const bool transparent) {
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec3 lPos, const float shadowsBias
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
#ifdef _SMSizeUniform #ifdef _SMSizeUniform
vec2 smSize = smSizeUniform; vec2 smSize = smSizeUniform;
#else #else
const vec2 smSize = shadowmapSize; const vec2 smSize = shadowmapSize;
#endif #endif
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0); if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0);
return PCF(shadowMap, return PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent);
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
} }
#ifdef _CSM #ifdef _CSM
mat4 getCascadeMat(const float d, out int casi, out int casIndex) { mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
const int c = shadowmapCascades; const int c = shadowmapCascades;
// Get cascade index // Get cascade index
// TODO: use bounding box slice selection instead of sphere // 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)); const vec4 ci = vec4(float(c > 0), float(c > 1), float(c > 2), float(c > 3));
@ -378,26 +373,21 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
float(d > casData[c * 4].z), float(d > casData[c * 4].z),
float(d > casData[c * 4].w)); float(d > casData[c * 4].w));
casi = int(min(dot(ci, comp), c)); casi = int(min(dot(ci, comp), c));
// Get cascade mat // Get cascade mat
casIndex = casi * 4; casIndex = casi * 4;
return mat4( return mat4(
casData[casIndex ], casData[casIndex ],
casData[casIndex + 1], casData[casIndex + 1],
casData[casIndex + 2], casData[casIndex + 2],
casData[casIndex + 3]); casData[casIndex + 3]);
// if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]); // if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]);
// .. // ..
} }
vec3 shadowTestCascade(sampler2DShadow shadowMap, vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 eye, const vec3 p, const float shadowsBias, const bool transparent) {
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec3 eye, const vec3 p, const float shadowsBias
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
#ifdef _SMSizeUniform #ifdef _SMSizeUniform
vec2 smSize = smSizeUniform; vec2 smSize = smSizeUniform;
#else #else
@ -405,22 +395,16 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
#endif #endif
const int c = shadowmapCascades; const int c = shadowmapCascades;
float d = distance(eye, p); float d = distance(eye, p);
int casi; int casi;
int casIndex; int casIndex;
mat4 LWVP = getCascadeMat(d, casi, casIndex); mat4 LWVP = getCascadeMat(d, casi, casIndex);
vec4 lPos = LWVP * vec4(p, 1.0); vec4 lPos = LWVP * vec4(p, 1.0);
lPos.xyz /= lPos.w; lPos.xyz /= lPos.w;
vec3 visibility = vec3(1.0); vec3 visibility = vec3(1.0);
if (lPos.w > 0.0) visibility = PCF(shadowMap, if (lPos.w > 0.0) visibility = PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent);
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
// Blend cascade // Blend cascade
// https://github.com/TheRealMJP/Shadows // https://github.com/TheRealMJP/Shadows
@ -439,20 +423,13 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
vec4 lPos2 = LWVP2 * vec4(p, 1.0); vec4 lPos2 = LWVP2 * vec4(p, 1.0);
lPos2.xyz /= lPos2.w; lPos2.xyz /= lPos2.w;
vec3 visibility2 = vec3(1.0); vec3 visibility2 = vec3(1.0);
if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, shadowMapTransparent, lPos2.xy, lPos2.z - shadowsBias, smSize, transparent);
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
float lerpAmt = smoothstep(0.0, blendThres, splitDist); float lerpAmt = smoothstep(0.0, blendThres, splitDist);
return mix(visibility2, visibility, lerpAmt); return mix(visibility2, visibility, lerpAmt);
} }
return visibility; return visibility;
// Visualize cascades // Visualize cascades
// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0); // if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0);
// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0); // if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0);
@ -460,4 +437,4 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0); // if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
} }
#endif #endif
#endif #endif

View File

@ -21,49 +21,29 @@ THE SOFTWARE.
*/ */
const int DIFFUSE_CONE_COUNT = 16; const int DIFFUSE_CONE_COUNT = 16;
const float DIFFUSE_CONE_APERTURE = radians(45.0);
const float SHADOW_CONE_APERTURE = radians(15.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 DIFFUSE_CONE_APERTURE = 0.872665; // 50 degrees in radians
mat3 makeTangentBasis(const vec3 normal) { const float BayerMatrix8[8][8] =
// Create a tangent basis from normal vector
vec3 tangent;
vec3 bitangent;
// Compute tangent (Frisvad's method)
if (abs(normal.z) < 0.999) {
tangent = normalize(cross(vec3(0, 1, 0), normal));
} else {
tangent = normalize(cross(normal, vec3(1, 0, 0)));
}
bitangent = cross(normal, tangent);
return mat3(tangent, bitangent, normal);
}
// 16 optimized cone directions for hemisphere sampling (Z-up, normalized)
const vec3 DIFFUSE_CONE_DIRECTIONS[16] = vec3[](
vec3(0.707107, 0.000000, 0.707107), // Front
vec3(-0.707107, 0.000000, 0.707107), // Back
vec3(0.000000, 0.707107, 0.707107), // Right
vec3(0.000000, -0.707107, 0.707107), // Left
vec3(0.500000, 0.500000, 0.707107), // Front-right
vec3(-0.500000, 0.500000, 0.707107), // Back-right
vec3(0.500000, -0.500000, 0.707107), // Front-left
vec3(-0.500000, -0.500000, 0.707107),// Back-left
vec3(0.353553, 0.000000, 0.935414), // Narrow front
vec3(-0.353553, 0.000000, 0.935414), // Narrow back
vec3(0.000000, 0.353553, 0.935414), // Narrow right
vec3(0.000000, -0.353553, 0.935414), // Narrow left
vec3(0.270598, 0.270598, 0.923880), // Narrow front-right
vec3(-0.270598, 0.270598, 0.923880), // Narrow back-right
vec3(0.270598, -0.270598, 0.923880), // Narrow front-left
vec3(-0.270598, -0.270598, 0.923880) // Narrow back-left
);
// 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 }, { 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 }, { 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 },
@ -74,15 +54,3 @@ const float off_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 }, { 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 } { 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 }
};

View File

@ -33,7 +33,6 @@ uniform layout(r32ui) uimage3D voxelsLight;
#ifdef _ShadowMap #ifdef _ShadowMap
uniform sampler2DShadow shadowMap; uniform sampler2DShadow shadowMap;
uniform sampler2D shadowMapTransparent;
uniform sampler2DShadow shadowMapSpot; uniform sampler2DShadow shadowMapSpot;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
uniform sampler2DShadow shadowMapPoint; uniform sampler2DShadow shadowMapPoint;
@ -87,28 +86,30 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
void main() { void main() {
int res = voxelgiResolution.x; int res = voxelgiResolution.x;
ivec3 dst = ivec3(gl_GlobalInvocationID.xyz); ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
dst.y += clipmapLevel * res;
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x; vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
wposition = wposition * 2.0 - 1.0; P = P * 2.0 - 1.0;
wposition *= float(clipmaps[int(clipmapLevel * 10)]); P *= clipmaps[int(clipmapLevel * 10)];
wposition *= voxelgiResolution.x; P *= voxelgiResolution;
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]); P += vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)]);
float visibility; vec3 visibility;
vec3 lp = lightPos -wposition; vec3 lp = lightPos - P;
vec3 l; vec3 l;
if (lightType == 0) { l = lightDir; visibility = 1.0; } if (lightType == 0) { l = lightDir; visibility = vec3(1.0); }
else { l = normalize(lp); visibility = attenuate(distance(wposition, lightPos)); } else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); }
#ifdef _ShadowMap #ifdef _ShadowMap
if (lightShadow == 1) { if (lightShadow == 1) {
vec4 lightPosition = LVP * vec4(wposition, 1.0); vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w; vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r; visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr;
} }
else if (lightShadow == 2) { else if (lightShadow == 2) {
vec4 lightPosition = LVP * vec4(wposition, 1.0); vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w; vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r; visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
} }
@ -129,7 +130,9 @@ void main() {
} }
#endif #endif
imageAtomicAdd(voxelsLight, dst, uint(visibility * lightColor.r * 255)); vec3 light = visibility * lightColor;
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)); 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));
} }

View File

@ -27,14 +27,14 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
#include "std/math.glsl" #include "std/math.glsl"
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/constants.glsl" #include "std/voxels_constants.glsl"
#ifdef _VoxelGI #ifdef _VoxelGI
uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsB;
uniform layout(rgba8) image3D voxelsOut; uniform layout(rgba8) image3D voxelsOut;
#else #else
uniform layout(r8) image3D voxelsB; uniform layout(r16) image3D voxelsB;
uniform layout(r8) image3D voxelsOut; uniform layout(r16) image3D voxelsOut;
#endif #endif
uniform int clipmapLevel; uniform int clipmapLevel;

View File

@ -29,38 +29,19 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
#include "std/shirr.glsl"
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D gbuffer0; uniform sampler2D gbuffer0;
uniform layout(rgba8) image2D voxels_ao; uniform layout(r8) image2D voxels_ao;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; 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() { void main() {
const vec2 pixel = gl_GlobalInvocationID.xy; const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution; vec2 uv = (pixel + 0.5) / postprocess_resolution;
@ -73,11 +54,12 @@ void main() {
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 clipPos = vec4(x, y, depth, 1.0); vec4 v = vec4(x, y, 1.0, 1.0);
vec4 worldPos = InvVP * clipPos; v = vec4(InvVP * v);
vec3 P = worldPos.xyz / worldPos.w; v.xyz /= v.w;
vec3 viewRay = v.xyz - eye;
vec3 v = normalize(eye - P); vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -85,89 +67,7 @@ void main() {
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy); n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n); n = normalize(n);
float roughness = g0.b; float occ = 1.0 - traceAO(P, n, voxels, clipmaps);
float metallic;
uint matid;
unpackFloatInt16(g0.a, metallic, matid);
vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ imageStore(voxels_ao, ivec2(pixel), vec4(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));
} }

View File

@ -29,8 +29,6 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
#include "std/shirr.glsl"
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
@ -39,44 +37,29 @@ uniform layout(rgba8) image2D voxels_diffuse;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; 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() { void main() {
const vec2 pixel = gl_GlobalInvocationID.xy; const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution; vec2 uv = (pixel + 0.5) / postprocess_resolution;
#ifdef _InvY #ifdef _InvY
uv.y = 1.0 - uv.y; uv.y = 1.0 - uv.y
#endif #endif
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0; float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
if (depth == 0.0) return; if (depth == 0) return;
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 clipPos = vec4(x, y, depth, 1.0); vec4 v = vec4(x, y, 1.0, 1.0);
vec4 worldPos = InvVP * clipPos; v = vec4(InvVP * v);
vec3 P = worldPos.xyz / worldPos.w; v.xyz /= v.w;
vec3 v = normalize(eye - P); vec3 viewRay = v.xyz - eye;
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -84,94 +67,7 @@ void main() {
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy); n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n); n = normalize(n);
float roughness = g0.b; vec4 color = traceDiffuse(P, n, voxels, clipmaps);
float metallic;
uint matid;
unpackFloatInt16(g0.a, metallic, matid);
vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ imageStore(voxels_diffuse, ivec2(pixel), color);
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;
#else
vec3 F = f0;
#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));
} }

View File

@ -0,0 +1,79 @@
/*
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));
}

View File

@ -0,0 +1,75 @@
/*
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));
}

View File

@ -29,7 +29,6 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D gbuffer0; uniform sampler2D gbuffer0;
@ -39,7 +38,9 @@ uniform layout(rgba8) image2D voxels_specular;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; uniform vec2 postprocess_resolution;
uniform sampler2D sveloc; uniform sampler2D sveloc;
@ -55,10 +56,12 @@ void main() {
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 clipPos = vec4(x, y, depth, 1.0); vec4 v = vec4(x, y, 1.0, 1.0);
vec4 worldPos = InvVP * clipPos; v = vec4(InvVP * v);
vec3 P = worldPos.xyz / worldPos.w; 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); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -68,7 +71,7 @@ void main() {
vec2 velocity = -textureLod(sveloc, uv, 0.0).rg; vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z * g0.z, clipmaps, pixel, velocity).rgb; vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z, clipmaps, pixel, velocity).rgb;
imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0)); imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
} }

View File

@ -23,8 +23,8 @@ THE SOFTWARE.
#include "compiled.inc" #include "compiled.inc"
uniform layout(r8) image3D input_sdf; uniform layout(r16) image3D input_sdf;
uniform layout(r8) image3D output_sdf; uniform layout(r16) image3D output_sdf;
uniform float jump_size; uniform float jump_size;
uniform int clipmapLevel; uniform int clipmapLevel;

View File

@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
uniform layout(r32ui) uimage3D voxelsLight; uniform layout(r32ui) uimage3D voxelsLight;
uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsB;
uniform layout(rgba8) image3D voxelsOut; uniform layout(rgba8) image3D voxelsOut;
uniform layout(r8) image3D SDF; uniform layout(r16) image3D SDF;
#else #else
#ifdef _VoxelAOvar #ifdef _VoxelAOvar
#ifdef _VoxelShadow #ifdef _VoxelShadow
uniform layout(r8) image3D SDF; uniform layout(r16) image3D SDF;
#endif #endif
uniform layout(r32ui) uimage3D voxels; uniform layout(r32ui) uimage3D voxels;
uniform layout(r8) image3D voxelsB; uniform layout(r16) image3D voxelsB;
uniform layout(r8) image3D voxelsOut; uniform layout(r16) image3D voxelsOut;
#endif #endif
#endif #endif
@ -74,9 +74,14 @@ void main() {
#endif #endif
#endif #endif
int nor_count = 0; ivec3 src = ivec3(gl_GlobalInvocationID.xyz);
vec3 avgNormal = vec3(0.0); #ifdef _VoxelGI
mat3 TBN = mat3(0.0); 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
for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++) for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
{ {
@ -86,7 +91,7 @@ void main() {
float aniso_colors[6]; float aniso_colors[6];
#endif #endif
ivec3 src = ivec3(gl_GlobalInvocationID.xyz); src = ivec3(gl_GlobalInvocationID.xyz);
src.x += i * res; src.x += i * res;
ivec3 dst = src; ivec3 dst = src;
dst.y += clipmapLevel * res; dst.y += clipmapLevel * res;
@ -99,67 +104,44 @@ void main() {
if (i < 6) { if (i < 6) {
#ifdef _VoxelGI #ifdef _VoxelGI
int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 15))); vec4 basecol = vec4(0.0);
if (count > 0) { basecol.r = float(imageLoad(voxels, src)) / 255;
vec4 basecol = vec4(0.0); basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
basecol.r = float(imageLoad(voxels, src)) / 255; basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255; basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255;
basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255; basecol /= 4;
basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255; vec3 emission = vec3(0.0);
basecol /= count; emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255;
vec3 emission = vec3(0.0); emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255;
emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255; emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255;
emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255; emission /= 3;
emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255; vec3 N = vec3(0.0);
emission /= count; N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255;
vec3 N = vec3(0.0); N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255;
N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255; N /= 2;
N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255; vec3 wnormal = decode_oct(N.rg * 2 - 1);
N /= count; vec3 envl = vec3(0.0);
N = decode_oct(N.rg * 2.0 - 1.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;
if (abs(N.x) > 0) //clipmap to world
avgNormal.x += N.x; vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
if (abs(N.y) > 0) wposition = wposition * 2.0 - 1.0;
avgNormal.y += N.y; wposition *= float(clipmaps[int(clipmapLevel * 10)]);
if (abs(N.z) > 0) wposition *= voxelgiResolution.x;
avgNormal.z += N.z; wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
if (i == 5)
{
avgNormal = normalize(avgNormal);
TBN = makeTangentBasis(avgNormal);
}
vec3 envl = vec3(0.0); radiance = basecol;
envl.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 9))) / 255; vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255; vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255; radiance.rgb *= light + indirect;
envl /= count; radiance.rgb += emission.rgb;
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 #else
int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))); opac = float(imageLoad(voxels, src)) / 255;
if (count > 0) {
opac = float(imageLoad(voxels, src)) / 255;
opac /= count;
}
#endif #endif
#ifdef _VoxelGI #ifdef _VoxelGI
@ -213,7 +195,7 @@ void main() {
} }
else { else {
// precompute cone sampling: // precompute cone sampling:
vec3 coneDirection = TBN * DIFFUSE_CONE_DIRECTIONS[i - 6]; vec3 coneDirection = DIFFUSE_CONE_DIRECTIONS[i - 6];
vec3 aniso_direction = -coneDirection; vec3 aniso_direction = -coneDirection;
uvec3 face_offsets = uvec3( uvec3 face_offsets = uvec3(
aniso_direction.x > 0 ? 0 : 1, aniso_direction.x > 0 ? 0 : 1,
@ -254,4 +236,4 @@ void main() {
imageStore(SDF, dst_sdf, vec4(sdf)); imageStore(SDF, dst_sdf, vec4(sdf));
#endif #endif
#endif #endif
} }

View File

@ -75,17 +75,16 @@ vec4 binarySearch(vec3 dir) {
} }
vec4 rayCast(vec3 dir) { vec4 rayCast(vec3 dir) {
float ddepth; #ifdef _CPostprocess
dir *= ss_refractionRayStep; dir *= PPComp9.x;
for (int i = 0; i < maxSteps; i++) { #else
hitCoord += dir; dir *= ssrRayStep;
ddepth = getDeltaDepth(hitCoord); #endif
if (ddepth > 0.0) for (int i = 0; i < maxSteps; i++) {
return binarySearch(dir); hitCoord += dir;
} if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
// No hit — fallback to projecting the ray to UV space }
vec2 fallbackUV = getProjectedCoord(hitCoord); return vec4(0.0);
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
} }
#endif //SSR #endif //SSR

View File

@ -181,15 +181,11 @@ class Uniforms {
// Multiple voxel volumes, always set params // Multiple voxel volumes, always set params
g.setImageTexture(context.textureUnits[j], rt.image); // image2D/3D g.setImageTexture(context.textureUnits[j], rt.image); // image2D/3D
if (rt.raw.name.startsWith("voxels_")) { if (rt.raw.name.startsWith("voxels_")) {
g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.LinearMipFilter); g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter);
}
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")) else if (rt.raw.name.startsWith("voxels"))
{ {
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.PointMipFilter); g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter);
} }
else else
{ {

View File

@ -34,10 +34,10 @@ class Inc {
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
static var voxel_td1:kha.compute.TextureUnit; static var voxel_td1:kha.compute.TextureUnit;
static var voxel_te1:kha.compute.TextureUnit; static var voxel_te1:kha.compute.TextureUnit;
static var voxel_cc1:kha.compute.ConstantLocation; static var voxel_tf1:kha.compute.TextureUnit;
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
static var voxel_te1:kha.compute.TextureUnit; static var voxel_tf1:kha.compute.TextureUnit;
#end #end
#end #end
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI") #if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
@ -53,28 +53,12 @@ class Inc {
static var voxel_tb3:kha.compute.TextureUnit; static var voxel_tb3:kha.compute.TextureUnit;
static var voxel_tc3:kha.compute.TextureUnit; static var voxel_tc3:kha.compute.TextureUnit;
static var voxel_td3: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_ca3:kha.compute.ConstantLocation;
static var voxel_cb3:kha.compute.ConstantLocation; static var voxel_cb3:kha.compute.ConstantLocation;
static var voxel_cc3:kha.compute.ConstantLocation; static var voxel_cc3:kha.compute.ConstantLocation;
static var voxel_cd3:kha.compute.ConstantLocation; static var voxel_cd3:kha.compute.ConstantLocation;
static var voxel_ce3:kha.compute.ConstantLocation; static var voxel_ce3:kha.compute.ConstantLocation;
#if lnx_irradiance
static var voxel_cf3:kha.compute.ConstantLocation; 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") #if (rp_voxels == "Voxel GI")
static var voxel_sh4:kha.compute.Shader = null; static var voxel_sh4:kha.compute.Shader = null;
static var voxel_ta4:kha.compute.TextureUnit; static var voxel_ta4:kha.compute.TextureUnit;
@ -87,6 +71,33 @@ class Inc {
static var voxel_cb4:kha.compute.ConstantLocation; static var voxel_cb4:kha.compute.ConstantLocation;
static var voxel_cc4:kha.compute.ConstantLocation; static var voxel_cc4:kha.compute.ConstantLocation;
static var voxel_cd4: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
#end //rp_voxels #end //rp_voxels
@ -152,11 +163,9 @@ class Inc {
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
path.bindTarget(atlas.target, atlas.target); path.bindTarget(atlas.target, atlas.target);
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
path.bindTarget(atlas.target, atlas.target); path.bindTarget(atlas.target, atlas.target);
} }
#end
} }
static function getShadowMapAtlas(atlas:ShadowMapAtlas, transparent: Bool):String { static function getShadowMapAtlas(atlas:ShadowMapAtlas, transparent: Bool):String {
@ -197,30 +206,24 @@ class Inc {
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
atlas.rejectedLights = []; atlas.rejectedLights = [];
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
atlas.rejectedLights = []; atlas.rejectedLights = [];
} }
#end #end
#end
for (light in iron.Scene.active.lights) { for (light in iron.Scene.active.lights) {
if (!light.lightInAtlas && !light.culledLight && light.visible && light.shadowMapScale > 0.0 if (!light.lightInAtlas && !light.culledLight && light.visible && light.shadowMapScale > 0.0
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) { && light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
ShadowMapAtlas.addLight(light, false); ShadowMapAtlas.addLight(light, false);
} }
#if rp_shadowmap_transparent
if (!light.lightInAtlasTransparent && !light.culledLight && light.visible && light.shadowMapScale > 0.0 if (!light.lightInAtlasTransparent && !light.culledLight && light.visible && light.shadowMapScale > 0.0
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) { && light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
ShadowMapAtlas.addLight(light, true); ShadowMapAtlas.addLight(light, true);
} }
#end
} }
// update point light data before rendering // update point light data before rendering
updatePointLightAtlasData(false);
#if rp_shadowmap_transparent
updatePointLightAtlasData(true); updatePointLightAtlasData(true);
#end updatePointLightAtlasData(false);
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
var tilesToRemove = []; var tilesToRemove = [];
@ -298,7 +301,6 @@ class Inc {
path.endStream(); path.endStream();
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
var tilesToRemove = []; var tilesToRemove = [];
#if lnx_shadowmap_atlas_lod #if lnx_shadowmap_atlas_lod
@ -393,8 +395,10 @@ class Inc {
tile.freeTile(); tile.freeTile();
} }
} }
#if lnx_debug
endShadowsLogicProfile();
#end #end
#end #end // rp_shadowmap
} }
#else #else
public static function bindShadowMap() { public static function bindShadowMap() {
@ -497,7 +501,6 @@ class Inc {
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++; else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
} }
#if rp_shadowmap_transparent
pointIndex = 0; pointIndex = 0;
spotIndex = 0; spotIndex = 0;
for (l in iron.Scene.active.lights) { for (l in iron.Scene.active.lights) {
@ -519,7 +522,6 @@ class Inc {
if (l.data.raw.type == "point") pointIndex++; if (l.data.raw.type == "point") pointIndex++;
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++; else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
} }
#end
#end // rp_shadowmap #end // rp_shadowmap
} }
#end #end
@ -587,7 +589,7 @@ class Inc {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = getDisplayp(); t.displayp = getDisplayp();
t.format = "R16"; t.format = "R32";
t.scale = getSuperSampling(); t.scale = getSuperSampling();
t.depth_buffer = "main"; t.depth_buffer = "main";
path.createRenderTarget(t); path.createRenderTarget(t);
@ -613,14 +615,10 @@ class Inc {
#end #end
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels"); {
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows) path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF"); path.bindTarget("voxelsSDF", "voxelsSDF");
#end }
#end
#if rp_ssrs
path.bindTarget("_main", "gbufferD");
#end #end
path.drawMeshes("translucent"); path.drawMeshes("translucent");
@ -681,11 +679,12 @@ class Inc {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = getDisplayp(); t.displayp = getDisplayp();
t.format = "RGBA32"; //t.scale = Inc.getSuperSampling();
t.format = t.name == "voxels_ao" ? "R8" : "RGBA32";
} }
else { else {
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") { if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
t.format = "R8"; t.format = "R16";
t.width = res; t.width = res;
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
@ -694,16 +693,16 @@ class Inc {
#if (rp_voxels == "Voxel AO") #if (rp_voxels == "Voxel AO")
{ {
if (t.name == "voxelsOut" || t.name == "voxelsOutB") { if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
t.format = "R8"; t.format = "R16";
t.width = res * (6 + 16); t.width = res * (6 + 16);
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
} }
else { else {
t.format = "R32UI"; t.format = "R32";
t.width = res * 6; t.width = res * 6;
t.height = res; t.height = res;
t.depth = res * 2; t.depth = res;
} }
} }
#else #else
@ -714,11 +713,17 @@ class Inc {
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
} }
else if (t.name == "voxelsLight") {
t.format = "R32";
t.width = res;
t.height = res;
t.depth = res * 3;
}
else { else {
t.format = "R32UI"; t.format = "R32";
t.width = res * 6; t.width = res * 6;
t.height = res; t.height = res;
t.depth = res * 16; t.depth = res * 12;
} }
} }
#end #end
@ -830,15 +835,14 @@ class Inc {
voxel_ca1 = voxel_sh1.getConstantLocation("clipmaps"); voxel_ca1 = voxel_sh1.getConstantLocation("clipmaps");
voxel_cb1 = voxel_sh1.getConstantLocation("clipmapLevel"); voxel_cb1 = voxel_sh1.getConstantLocation("clipmapLevel");
voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength");
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
voxel_td1 = voxel_sh1.getTextureUnit("voxelsSampler"); voxel_td1 = voxel_sh1.getTextureUnit("voxelsSampler");
voxel_te1 = voxel_sh1.getTextureUnit("SDF"); voxel_te1 = voxel_sh1.getTextureUnit("voxelsLight");
voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength"); voxel_tf1 = voxel_sh1.getTextureUnit("SDF");
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
voxel_te1 = voxel_sh1.getTextureUnit("SDF"); voxel_tf1 = voxel_sh1.getTextureUnit("SDF");
#end #end
#end #end
} }
@ -869,28 +873,12 @@ class Inc {
#else #else
voxel_td3 = voxel_sh3.getTextureUnit("voxels_diffuse"); voxel_td3 = voxel_sh3.getTextureUnit("voxels_diffuse");
#end #end
voxel_te3 = voxel_sh3.getTextureUnit("gbuffer1"); voxel_ca3 = voxel_sh3.getConstantLocation("clipmaps");
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_cb3 = voxel_sh3.getConstantLocation("InvVP");
voxel_cc3 = voxel_sh3.getConstantLocation("eye"); voxel_cc3 = voxel_sh3.getConstantLocation("cameraProj");
voxel_cd3 = voxel_sh3.getConstantLocation("postprocess_resolution"); voxel_cd3 = voxel_sh3.getConstantLocation("eye");
voxel_ce3 = voxel_sh3.getConstantLocation("envmapStrength"); voxel_ce3 = voxel_sh3.getConstantLocation("eyeLook");
#if lnx_irradiance voxel_cf3 = voxel_sh3.getConstantLocation("postprocess_resolution");
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 (rp_voxels == "Voxel GI")
if (voxel_sh4 == null) if (voxel_sh4 == null)
@ -904,8 +892,40 @@ class Inc {
voxel_tf4 = voxel_sh4.getTextureUnit("sveloc"); voxel_tf4 = voxel_sh4.getTextureUnit("sveloc");
voxel_ca4 = voxel_sh4.getConstantLocation("clipmaps"); voxel_ca4 = voxel_sh4.getConstantLocation("clipmaps");
voxel_cb4 = voxel_sh4.getConstantLocation("InvVP"); voxel_cb4 = voxel_sh4.getConstantLocation("InvVP");
voxel_cc4 = voxel_sh4.getConstantLocation("eye"); voxel_cc4 = voxel_sh4.getConstantLocation("cameraProj");
voxel_cd4 = voxel_sh4.getConstantLocation("postprocess_resolution"); 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
} }
#end #end
} }
@ -956,11 +976,11 @@ class Inc {
kha.compute.Compute.setTexture(voxel_tc1, rts.get("voxelsOut").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_tc1, rts.get("voxelsOut").image, kha.compute.Access.Write);
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
kha.compute.Compute.setSampledTexture(voxel_td1, rts.get("voxelsOutB").image); kha.compute.Compute.setSampledTexture(voxel_td1, rts.get("voxelsOutB").image);
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsLight").image, kha.compute.Access.Read);
kha.compute.Compute.setFloat(voxel_cc1, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength); kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
#end #end
#end #end
@ -982,8 +1002,6 @@ class Inc {
kha.compute.Compute.setInt(voxel_cb1, iron.RenderPath.clipmapLevel); 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)); kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8));
} }
@ -1036,7 +1054,6 @@ class Inc {
} }
} }
#end #end
#if (rp_voxels == "Voxel AO") #if (rp_voxels == "Voxel AO")
public static function resolveAO() { public static function resolveAO() {
var rts = path.renderTargets; var rts = path.renderTargets;
@ -1049,20 +1066,13 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image); 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.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); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
fa[i * 10] = clipmaps[i].voxelSize; fa[i * 10] = clipmaps[i].voxelSize;
@ -1089,7 +1099,18 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb3, m.self); kha.compute.Compute.setMatrix(voxel_cb3, m.self);
kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz()); 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);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1104,32 +1125,7 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cd3, width, height); kha.compute.Compute.setFloat2(voxel_cf3, 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); kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
} }
@ -1145,18 +1141,12 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image); 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.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); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
@ -1184,7 +1174,18 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb3, m.self); kha.compute.Compute.setMatrix(voxel_cb3, m.self);
kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz()); 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);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1199,32 +1200,7 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cd3, width, height); kha.compute.Compute.setFloat2(voxel_cf3, 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); kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
} }
@ -1240,12 +1216,15 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta4, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta4, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb4, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb4, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("gbuffer0").image); 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.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.setTexture(voxel_te4, rts.get("voxels_specular").image, kha.compute.Access.Write);
#if rp_gbuffer2
kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image); //kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
#end
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
@ -1273,7 +1252,18 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb4, m.self); kha.compute.Compute.setMatrix(voxel_cb4, m.self);
kha.compute.Compute.setFloat3(voxel_cc4, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz()); 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);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1288,10 +1278,146 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cd4, width, height); kha.compute.Compute.setFloat2(voxel_cf4, width, height);
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1); 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 // GI
#end // Voxels #end // Voxels
} }

View File

@ -15,11 +15,6 @@ class RenderPathDeferred {
static var bloomUpsampler: Upsampler; static var bloomUpsampler: Upsampler;
#end #end
#if (rp_ssgi == "SSGI")
static var ssgitex = "singleb";
static var ssgitexb = "singleb";
#end
public static inline function setTargetMeshes() { public static inline function setTargetMeshes() {
//Always keep the order of render targets the same as defined in compiled.inc //Always keep the order of render targets the same as defined in compiled.inc
path.setTarget("gbuffer0", [ path.setTarget("gbuffer0", [
@ -62,11 +57,12 @@ class RenderPathDeferred {
Inc.initGI("voxels"); Inc.initGI("voxels");
Inc.initGI("voxelsOut"); Inc.initGI("voxelsOut");
Inc.initGI("voxelsOutB"); Inc.initGI("voxelsOutB");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows) #if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
Inc.initGI("voxelsSDF"); Inc.initGI("voxelsSDF");
Inc.initGI("voxelsSDFtmp"); Inc.initGI("voxelsSDFtmp");
#end #end
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
Inc.initGI("voxelsLight");
Inc.initGI("voxels_diffuse"); Inc.initGI("voxels_diffuse");
Inc.initGI("voxels_specular"); Inc.initGI("voxels_specular");
#else #else
@ -199,26 +195,16 @@ class RenderPathDeferred {
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x"); path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y"); 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 #end
#if (rp_ssgi != "Off") #if ((rp_ssgi != "Off") || rp_volumetriclight)
{ {
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "singlea"; t.name = "singlea";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8"; t.format = "R8";
#end
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
#if rp_ssgi_half #if rp_ssgi_half
t.scale *= 0.5; t.scale *= 0.5;
@ -230,66 +216,6 @@ class RenderPathDeferred {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); 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 = "volumetricb";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8"; t.format = "R8";
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
#if rp_ssgi_half #if rp_ssgi_half
@ -442,7 +368,7 @@ class RenderPathDeferred {
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
// holds background color // holds background depth
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "refr"; t.name = "refr";
t.width = 0; t.width = 0;
@ -535,7 +461,7 @@ class RenderPathDeferred {
#if (rp_ssrefr || lnx_voxelgi_refract) #if (rp_ssrefr || lnx_voxelgi_refract)
{ {
path.setTarget("gbuffer_refraction"); path.setTarget("gbuffer_refraction"); // Only clear gbuffer0
path.clearTarget(0xffffff00); path.clearTarget(0xffffff00);
} }
#end #end
@ -591,16 +517,30 @@ class RenderPathDeferred {
path.drawShader("shader_datas/downsample_depth/downsample_depth"); path.drawShader("shader_datas/downsample_depth/downsample_depth");
#end #end
#if (rp_shadowmap) #if ((rp_ssgi == "RTGI") || (rp_ssgi == "RTAO"))
// atlasing is exclusive for now {
#if lnx_shadowmap_atlas if (leenkx.data.Config.raw.rp_ssgi != false) {
Inc.drawShadowMapAtlas(); path.setTarget("singlea");
#else #if rp_ssgi_half
Inc.drawShadowMap(); path.bindTarget("half", "gbufferD");
#end #else
#end path.bindTarget("_main", "gbufferD");
#end
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/ssgi_pass/ssgi_pass");
#if (rp_ssgi == "SSAO") 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 (leenkx.data.Config.raw.rp_ssgi != false) { if (leenkx.data.Config.raw.rp_ssgi != false) {
path.setTarget("singlea"); path.setTarget("singlea");
@ -619,43 +559,15 @@ class RenderPathDeferred {
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y"); path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
} }
} }
#elseif (rp_ssgi == "SSGI") #end
{
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
path.drawShader("shader_datas/ssgi_pass/ssgi_pass"); #if (rp_shadowmap)
path.setTarget("singleb"); // atlasing is exclusive for now
path.bindTarget("singlea", "tex"); #if lnx_shadowmap_atlas
path.bindTarget("gbuffer0", "gbuffer0"); Inc.drawShadowMapAtlas();
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_x"); #else
Inc.drawShadowMap();
path.setTarget("singlea"); #end
path.bindTarget("singleb", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
}
}
#end #end
// Voxels // Voxels
@ -668,6 +580,9 @@ class RenderPathDeferred {
if (iron.RenderPath.pre_clear == true) if (iron.RenderPath.pre_clear == true)
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
path.clearImage("voxelsOut", 0x00000000); path.clearImage("voxelsOut", 0x00000000);
path.clearImage("voxelsOutB", 0x00000000); path.clearImage("voxelsOutB", 0x00000000);
@ -679,30 +594,26 @@ class RenderPathDeferred {
} }
else else
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
Inc.computeVoxelsOffsetPrev(); Inc.computeVoxelsOffsetPrev();
} }
path.setTarget(""); 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(); var res = iron.RenderPath.getVoxelRes();
path.setViewport(res, res); path.setViewport(res, res);
path.bindTarget("voxels", "voxels");
path.drawMeshes("voxel"); path.drawMeshes("voxel");
#if (rp_voxels == "Voxel GI")
Inc.computeVoxelsLight();
#end
Inc.computeVoxelsTemporal(); Inc.computeVoxelsTemporal();
#if (rp_voxels == "Voxel GI") #if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
Inc.computeVoxelsSDF(); Inc.computeVoxelsSDF();
#end #end
@ -717,6 +628,7 @@ class RenderPathDeferred {
} }
} }
#end #end
// --- // ---
// Deferred light // Deferred light
// --- // ---
@ -848,9 +760,15 @@ class RenderPathDeferred {
} }
#end #end
#if (rp_translucency && !rp_ssrefr)
{
Inc.drawTranslucency("tex");
}
#end
#if rp_volumetriclight #if rp_volumetriclight
{ {
path.setTarget("volumetrica"); path.setTarget("singlea");
path.bindTarget("_main", "gbufferD"); path.bindTarget("_main", "gbufferD");
#if lnx_shadowmap_atlas #if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas(); Inc.bindShadowMapAtlas();
@ -859,16 +777,85 @@ class RenderPathDeferred {
#end #end
path.drawShader("shader_datas/volumetric_light/volumetric_light"); path.drawShader("shader_datas/volumetric_light/volumetric_light");
path.setTarget("volumetricb"); path.setTarget("singleb");
path.bindTarget("volumetrica", "tex"); path.bindTarget("singlea", "tex");
path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x"); path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.setTarget("tex"); path.setTarget("tex");
path.bindTarget("volumetricb", "tex"); path.bindTarget("singleb", "tex");
path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y"); path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
} }
#end #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 rp_ssr
{ {
if (leenkx.data.Config.raw.rp_ssr != false) { if (leenkx.data.Config.raw.rp_ssr != false) {
@ -913,88 +900,6 @@ class RenderPathDeferred {
} }
#end #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 ((rp_motionblur == "Camera") || (rp_motionblur == "Object"))
{ {
if (leenkx.data.Config.raw.rp_motionblur != false) { if (leenkx.data.Config.raw.rp_motionblur != false) {
@ -1059,12 +964,6 @@ class RenderPathDeferred {
} }
#end #end
#if rp_bloom
{
inline Inc.drawBloom("tex", bloomDownsampler, bloomUpsampler);
}
#end
#if (rp_supersampling == 4) #if (rp_supersampling == 4)
var framebuffer = "buf"; var framebuffer = "buf";
#else #else

View File

@ -142,17 +142,16 @@ class RenderPathForward {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
t.format = "DEPTH24"; t.format = "R32";
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
//holds colors before refractive meshes are drawn
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "refr"; t.name = "refr";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
t.format = Inc.getHdrFormat(); t.format = "RGBA64";
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
} }
@ -201,10 +200,17 @@ class RenderPathForward {
Inc.initGI("voxels"); Inc.initGI("voxels");
Inc.initGI("voxelsOut"); Inc.initGI("voxelsOut");
Inc.initGI("voxelsOutB"); Inc.initGI("voxelsOutB");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows) #if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI"))
Inc.initGI("voxelsSDF"); Inc.initGI("voxelsSDF");
Inc.initGI("voxelsSDFtmp"); Inc.initGI("voxelsSDFtmp");
#end #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>(); iron.RenderPath.clipmaps = new Array<Clipmap>();
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
var clipmap = new iron.object.Clipmap(); var clipmap = new iron.object.Clipmap();
@ -251,25 +257,18 @@ class RenderPathForward {
#end #end
#end #end
#if (rp_volumetriclight || rp_ssgi != "Off") #if rp_volumetriclight
{ {
#if (rp_volumetriclight)
path.loadShader("shader_datas/volumetric_light/volumetric_light"); 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_pass/blur_bilat_pass_x");
path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y"); path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
#end
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "singlea"; t.name = "singlea";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8"; t.format = "R8";
#end
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
@ -278,11 +277,7 @@ class RenderPathForward {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8"; t.format = "R8";
#end
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
} }
@ -379,6 +374,9 @@ class RenderPathForward {
if (iron.RenderPath.pre_clear == true) if (iron.RenderPath.pre_clear == true)
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
path.clearImage("voxelsOut", 0x00000000); path.clearImage("voxelsOut", 0x00000000);
path.clearImage("voxelsOutB", 0x00000000); path.clearImage("voxelsOutB", 0x00000000);
@ -390,6 +388,9 @@ class RenderPathForward {
} }
else else
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
Inc.computeVoxelsOffsetPrev(); Inc.computeVoxelsOffsetPrev();
} }
@ -399,12 +400,27 @@ class RenderPathForward {
path.setViewport(res, res); path.setViewport(res, res);
path.bindTarget("voxels", "voxels"); path.bindTarget("voxels", "voxels");
path.drawMeshes("voxel");
#if (rp_voxels == "Voxel GI")
Inc.computeVoxelsLight();
#end
Inc.computeVoxelsTemporal(); Inc.computeVoxelsTemporal();
#if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI")) #if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI"))
Inc.computeVoxelsSDF(); Inc.computeVoxelsSDF();
#end #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 #end
@ -423,7 +439,7 @@ class RenderPathForward {
#if (rp_ssrefr || lnx_voxelgi_refract) #if (rp_ssrefr || lnx_voxelgi_refract)
{ {
path.setTarget("gbuffer_refraction"); // Only clear gbuffer0 path.setTarget("gbuffer_refraction"); // Only clear gbuffer0
path.clearTarget(0xffffff00); path.clearTarget(0xff000000);
} }
#end #end
@ -433,6 +449,13 @@ class RenderPathForward {
} }
#end #end
#if rp_ssrefr
{
path.setTarget("gbuffer_refraction");
path.clearTarget(0xffffff00);
}
#end
RenderPathCreator.setTargetMeshes(); RenderPathCreator.setTargetMeshes();
#if rp_shadowmap #if rp_shadowmap
@ -449,11 +472,18 @@ class RenderPathForward {
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
if (leenkx.data.Config.raw.rp_gi != false) if (leenkx.data.Config.raw.rp_gi != false)
{ {
#if (rp_voxels != "Off") #if (rp_voxels == "Voxel AO")
path.bindTarget("voxelsOut", "voxels"); Inc.resolveAO();
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows) path.bindTarget("voxels_ao", "voxels_ao");
path.bindTarget("voxelsSDF", "voxelsSDF"); #else
Inc.resolveDiffuse();
Inc.resolveSpecular();
path.bindTarget("voxels_diffuse", "voxels_diffuse");
path.bindTarget("voxels_specular", "voxels_specular");
#end #end
#if lnx_voxelgi_shadows
path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF");
#end #end
} }
#end #end
@ -492,31 +522,14 @@ class RenderPathForward {
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]); path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels"); path.bindTarget("voxelsOut", "voxels");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
path.bindTarget("voxelsSDF", "voxelsSDF"); path.bindTarget("voxelsSDF", "voxelsSDF");
#end #end
#end
#if rp_ssrs
path.bindTarget("_main", "gbufferD");
#end
path.drawMeshes("refraction"); path.drawMeshes("refraction");
path.setTarget("lbuffer0"); path.setTarget("lbuffer0");
path.bindTarget("lbuffer0", "tex"); path.bindTarget("lbuffer0", "tex");
path.bindTarget("refr", "tex1"); path.bindTarget("refr", "tex1");
path.bindTarget("_main", "gbufferD"); path.bindTarget("_main", "gbufferD");
@ -564,50 +577,6 @@ class RenderPathForward {
} }
#end #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 #if rp_bloom
{ {
inline Inc.drawBloom("lbuffer0", bloomDownsampler, bloomUpsampler); inline Inc.drawBloom("lbuffer0", bloomDownsampler, bloomUpsampler);

View File

@ -41,11 +41,7 @@ class Starter {
try { try {
#end #end
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: { kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
#if 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() { iron.App.init(function() {
#if lnx_loadscreen #if lnx_loadscreen

View File

@ -73,7 +73,17 @@ class PhysicsBreak extends Trait {
collisionMargin: 0.04, collisionMargin: 0.04,
linearDeactivationThreshold: 0.0, linearDeactivationThreshold: 0.0,
angularDeactivationThrshold: 0.0, angularDeactivationThrshold: 0.0,
deactivationTime: 0.0 deactivationTime: 0.0,
linearVelocityMin: 0.0,
linearVelocityMax: 0.0,
angularVelocityMin: 0.0,
angularVelocityMax: 0.0,
lockTranslationX: false,
lockTranslationY: false,
lockTranslationZ: false,
lockRotationX: false,
lockRotationY: false,
lockRotationZ: false
}; };
o.addTrait(new RigidBody(Shape.ConvexHull, ud.mass, ud.friction, 0, 1, params)); o.addTrait(new RigidBody(Shape.ConvexHull, ud.mass, ud.friction, 0, 1, params));
if (cast(o, MeshObject).data.geom.positions.values.length < 600) { if (cast(o, MeshObject).data.geom.positions.values.length < 600) {

View File

@ -58,9 +58,6 @@ def add_world_defs():
if rpdat.rp_shadowmap_cascades != '1': if rpdat.rp_shadowmap_cascades != '1':
wrd.world_defs += '_CSM' wrd.world_defs += '_CSM'
assets.add_khafile_def('lnx_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: if rpdat.rp_shadowmap_atlas:
assets.add_khafile_def('lnx_shadowmap_atlas') assets.add_khafile_def('lnx_shadowmap_atlas')
wrd.world_defs += '_ShadowMapAtlas' wrd.world_defs += '_ShadowMapAtlas'
@ -121,15 +118,17 @@ def add_world_defs():
if rpdat.lnx_voxelgi_shadows and (point_lights > 0 or '_Sun' in wrd.world_defs): if rpdat.lnx_voxelgi_shadows and (point_lights > 0 or '_Sun' in wrd.world_defs):
wrd.world_defs += '_VoxelShadow' wrd.world_defs += '_VoxelShadow'
assets.add_khafile_def('lnx_voxelgi_shadows') 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: 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_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_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' wrd.world_defs += '_VoxelGI'
if rpdat.lnx_voxelgi_refract: if rpdat.lnx_voxelgi_refract:
wrd.world_defs += '_VoxelRefract' wrd.world_defs += '_VoxelRefract'
assets.add_khafile_def('lnx_voxelgi_refract') 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: elif voxelao:
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl') assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl')
@ -307,14 +306,10 @@ def build():
assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi)) assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi))
if rpdat.rp_ssgi != 'Off': if rpdat.rp_ssgi != 'Off':
wrd.world_defs += '_SSAO'
if rpdat.rp_ssgi == 'SSAO': if rpdat.rp_ssgi == 'SSAO':
wrd.world_defs += '_SSAO'
assets.add_shader_pass('ssao_pass') assets.add_shader_pass('ssao_pass')
assets.add_shader_pass('blur_edge_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: else:
assets.add_shader_pass('ssgi_pass') assets.add_shader_pass('ssgi_pass')
assets.add_shader_pass('blur_edge_pass') assets.add_shader_pass('blur_edge_pass')
@ -461,8 +456,7 @@ def build():
if ignoreIrr: if ignoreIrr:
wrd.world_defs += '_IgnoreIrr' wrd.world_defs += '_IgnoreIrr'
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 gbuffer2 = '_Veloc' in wrd.world_defs or '_IgnoreIrr' in wrd.world_defs
if gbuffer2: if gbuffer2:
assets.add_khafile_def('rp_gbuffer2') assets.add_khafile_def('rp_gbuffer2')
wrd.world_defs += '_gbuffer2' wrd.world_defs += '_gbuffer2'

View File

@ -199,7 +199,6 @@ 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_color = [col[0], col[1], col[2], 1.0]
world.lnx_envtex_strength = 1.0 world.lnx_envtex_strength = 1.0
world.world_defs += '_EnvCol' world.world_defs += '_EnvCol'
assets.add_khafile_def("lnx_envcol")
# Clouds enabled # Clouds enabled
if rpdat.lnx_clouds and world.lnx_use_clouds: if rpdat.lnx_clouds and world.lnx_use_clouds:
@ -281,7 +280,6 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
# Append irradiance define # Append irradiance define
if rpdat.lnx_irradiance and not solid_mat: if rpdat.lnx_irradiance and not solid_mat:
wrd.world_defs += '_Irr' wrd.world_defs += '_Irr'
assets.add_khafile_def("lnx_irradiance")
# Extract environment strength # Extract environment strength
# Todo: follow/parse strength input # Todo: follow/parse strength input
@ -295,7 +293,6 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
solid_mat = rpdat.lnx_material_model == 'Solid' solid_mat = rpdat.lnx_material_model == 'Solid'
if rpdat.lnx_irradiance and not solid_mat: if rpdat.lnx_irradiance and not solid_mat:
world.world_defs += '_Irr' world.world_defs += '_Irr'
assets.add_khafile_def("lnx_irradiance")
world.lnx_envtex_color = node_surface.inputs[0].default_value world.lnx_envtex_color = node_surface.inputs[0].default_value
world.lnx_envtex_strength = 1.0 world.lnx_envtex_strength = 1.0

View File

@ -250,7 +250,7 @@ def parse_bsdfglass(node: bpy.types.ShaderNodeBsdfGlass, out_socket: NodeSocket,
c.write_normal(node.inputs[3]) c.write_normal(node.inputs[3])
state.out_roughness = c.parse_value_input(node.inputs[1]) state.out_roughness = c.parse_value_input(node.inputs[1])
if state.parse_opacity: if state.parse_opacity:
state.out_opacity = '1.0' state.out_opacity = '0.1'
state.out_ior = c.parse_value_input(node.inputs[2]) state.out_ior = c.parse_value_input(node.inputs[2])
@ -270,7 +270,7 @@ def parse_bsdfrefraction(node: bpy.types.ShaderNodeBsdfRefraction, out_socket: N
c.write_normal(node.inputs[3]) c.write_normal(node.inputs[3])
state.out_roughness = c.parse_value_input(node.inputs[1]) state.out_roughness = c.parse_value_input(node.inputs[1])
if state.parse_opacity: if state.parse_opacity:
state.out_opacity = '1.0' state.out_opacity = '0.0'
state.out_ior = c.parse_value_input(node.inputs[2]) state.out_ior = c.parse_value_input(node.inputs[2])
def parse_subsurfacescattering(node: bpy.types.ShaderNodeSubsurfaceScattering, out_socket: NodeSocket, state: ParserState) -> None: def parse_subsurfacescattering(node: bpy.types.ShaderNodeSubsurfaceScattering, out_socket: NodeSocket, state: ParserState) -> None:

View File

@ -342,6 +342,9 @@ def parse_sky_hosekwilkie(node: bpy.types.ShaderNodeTexSky, state: ParserState)
world = state.world world = state.world
curshader = state.curshader curshader = state.curshader
# Match to cycles
world.lnx_envtex_strength *= 0.1
assets.add_khafile_def('lnx_hosek') assets.add_khafile_def('lnx_hosek')
curshader.add_uniform('vec3 A', link="_hosekA") curshader.add_uniform('vec3 A', link="_hosekA")
curshader.add_uniform('vec3 B', link="_hosekB") curshader.add_uniform('vec3 B', link="_hosekB")

View File

@ -19,7 +19,6 @@ def write(vert: shader.Shader, frag: shader.Shader):
parse_opacity = blend or mat_utils.is_transluc(mat_state.material) parse_opacity = blend or mat_utils.is_transluc(mat_state.material)
is_mobile = rpdat.lnx_material_model == 'Mobile' is_mobile = rpdat.lnx_material_model == 'Mobile'
is_shadows = '_ShadowMap' in wrd.world_defs is_shadows = '_ShadowMap' in wrd.world_defs
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
is_single_atlas = '_SingleAtlas' in wrd.world_defs is_single_atlas = '_SingleAtlas' in wrd.world_defs
@ -34,17 +33,14 @@ def write(vert: shader.Shader, frag: shader.Shader):
if is_shadows_atlas: if is_shadows_atlas:
if not is_single_atlas: if not is_single_atlas:
frag.add_uniform('sampler2DShadow shadowMapAtlasPoint', included=True) frag.add_uniform('sampler2DShadow shadowMapAtlasPoint', included=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True)
frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True) frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
frag.add_uniform('vec4 pointLightDataArray[maxLightsCluster]', link='_pointLightsAtlasArray', included=True) frag.add_uniform('vec4 pointLightDataArray[maxLightsCluster]', link='_pointLightsAtlasArray', included=True)
else: else:
frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True) frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True)
if is_transparent_shadows: frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True)
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)): 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') vert.add_out('vec4 wvpposition')
@ -66,16 +62,13 @@ def write(vert: shader.Shader, frag: shader.Shader):
if is_shadows_atlas: if is_shadows_atlas:
if not is_single_atlas: if not is_single_atlas:
frag.add_uniform('sampler2DShadow shadowMapAtlasSpot', included=True) frag.add_uniform('sampler2DShadow shadowMapAtlasSpot', included=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True)
frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True) frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True)
frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True)
frag.add_uniform('mat4 LWVPSpotArray[maxLightsCluster]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True) frag.add_uniform('mat4 LWVPSpotArray[maxLightsCluster]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True)
frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {') frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {')
@ -91,10 +84,12 @@ def write(vert: shader.Shader, frag: shader.Shader):
frag.write(' roughness,') frag.write(' roughness,')
frag.write(' specular,') frag.write(' specular,')
frag.write(' f0') frag.write(' f0')
if is_shadows: if is_shadows:
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0') # bias if parse_opacity:
if is_transparent_shadows: frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, opacity != 1.0') # bias
frag.write('\t, opacity != 1.0') else:
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false') # bias
if '_Spot' in wrd.world_defs: if '_Spot' in wrd.world_defs:
frag.write('\t, lightsArray[li * 3 + 2].y != 0.0') frag.write('\t, lightsArray[li * 3 + 2].y != 0.0')
frag.write('\t, lightsArray[li * 3 + 2].y') # spot size (cutoff) frag.write('\t, lightsArray[li * 3 + 2].y') # spot size (cutoff)
@ -103,13 +98,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, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w)') # scale
frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write(', voxels, voxelsSDF, clipmaps, velocity') frag.write(', voxels, voxelsSDF, clipmaps')
if '_MicroShadowing' in wrd.world_defs and not is_mobile: if '_MicroShadowing' in wrd.world_defs and not is_mobile:
frag.write('\t, occlusion') frag.write('\t, occlusion')
if '_SSRS' in wrd.world_defs: if '_SSRS' in wrd.world_defs:
frag.add_uniform('sampler2D gbufferD')
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix') frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
frag.add_uniform('sampler2D gbufferD', link='_gbufferD', top=True)
frag.write(', gbufferD, invVP, eye') frag.write(', gbufferD, invVP, eye')
frag.write(');') frag.write(');')

View File

@ -1,161 +1,155 @@
import bpy import bpy
import lnx import lnx
import lnx.material.mat_state as mat_state import lnx.material.mat_state as mat_state
import lnx.material.make_tess as make_tess import lnx.material.make_tess as make_tess
from lnx.material.shader import ShaderContext from lnx.material.shader import ShaderContext
if lnx.is_reload(__name__): if lnx.is_reload(__name__):
mat_state = lnx.reload_module(mat_state) mat_state = lnx.reload_module(mat_state)
make_tess = lnx.reload_module(make_tess) make_tess = lnx.reload_module(make_tess)
lnx.material.shader = lnx.reload_module(lnx.material.shader) lnx.material.shader = lnx.reload_module(lnx.material.shader)
from lnx.material.shader import ShaderContext from lnx.material.shader import ShaderContext
else: else:
lnx.enable_reload(__name__) lnx.enable_reload(__name__)
def make(con_mesh: ShaderContext): def make(con_mesh: ShaderContext):
vert = con_mesh.vert vert = con_mesh.vert
frag = con_mesh.frag frag = con_mesh.frag
geom = con_mesh.geom geom = con_mesh.geom
tesc = con_mesh.tesc tesc = con_mesh.tesc
tese = con_mesh.tese tese = con_mesh.tese
# Additional values referenced in cycles # Additional values referenced in cycles
# TODO: enable from cycles.py # TODO: enable from cycles.py
if frag.contains('dotNV') and not frag.contains('float dotNV'): if frag.contains('dotNV') and not frag.contains('float dotNV'):
frag.write_init('float dotNV = max(dot(n, vVec), 0.0);') frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')
# n is not always defined yet (in some shadowmap shaders e.g.) # n is not always defined yet (in some shadowmap shaders e.g.)
if not frag.contains('vec3 n'): if not frag.contains('vec3 n'):
vert.add_out('vec3 wnormal') vert.add_out('vec3 wnormal')
billboard = mat_state.material.lnx_billboard billboard = mat_state.material.lnx_billboard
if billboard == 'spherical': if billboard == 'spherical':
vert.add_uniform('mat3 N', '_normalMatrixSphere') vert.add_uniform('mat3 N', '_normalMatrixSphere')
elif billboard == 'cylindrical': elif billboard == 'cylindrical':
vert.add_uniform('mat3 N', '_normalMatrixCylinder') vert.add_uniform('mat3 N', '_normalMatrixCylinder')
else: else:
vert.add_uniform('mat3 N', '_normalMatrix') vert.add_uniform('mat3 N', '_normalMatrix')
vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));') vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
frag.write_attrib('vec3 n = normalize(wnormal);') frag.write_attrib('vec3 n = normalize(wnormal);')
# If not yet added, add nor vertex data # If not yet added, add nor vertex data
vertex_elems = con_mesh.data['vertex_elements'] vertex_elems = con_mesh.data['vertex_elements']
has_normals = False has_normals = False
for elem in vertex_elems: for elem in vertex_elems:
if elem['name'] == 'nor': if elem['name'] == 'nor':
has_normals = True has_normals = True
break break
if not has_normals: if not has_normals:
vertex_elems.append({'name': 'nor', 'data': 'short2norm'}) vertex_elems.append({'name': 'nor', 'data': 'short2norm'})
write_wpos = False write_wpos = False
export_wpos = False if frag.contains('vVec') and not frag.contains('vec3 vVec'):
if frag.contains('wposition') and not frag.contains('vec3 wposition'): if tese is not None:
export_wpos = True tese.add_out('vec3 eyeDir')
if tese is not None: tese.add_uniform('vec3 eye', '_cameraPosition')
export_wpos = True tese.write('eyeDir = eye - wposition;')
if vert.contains('wposition'):
write_wpos = True else:
if not vert.contains('wposition'):
write_wpos = True
vert.add_out('vec3 eyeDir')
vert.add_uniform('vec3 eye', '_cameraPosition')
if frag.contains('vVec') and not frag.contains('vec3 vVec'): vert.write('eyeDir = eye - wposition;')
if tese is not None: frag.write_attrib('vec3 vVec = normalize(eyeDir);')
tese.add_out('vec3 eyeDir')
tese.add_uniform('vec3 eye', '_cameraPosition') export_wpos = False
tese.write('eyeDir = eye - wposition;') if frag.contains('wposition') and not frag.contains('vec3 wposition'):
export_wpos = True
else: if tese is not None:
if not vert.contains('wposition'): export_wpos = True
write_wpos = True if vert.contains('wposition'):
vert.add_out('vec3 eyeDir') write_wpos = True
vert.add_uniform('vec3 eye', '_cameraPosition')
vert.write('eyeDir = eye - wposition;') if export_wpos:
frag.write_attrib('vec3 vVec = normalize(eyeDir);') vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_out('vec3 wposition')
if export_wpos: vert.write('wposition = vec4(W * spos).xyz;')
vert.add_uniform('mat4 W', '_worldMatrix') elif write_wpos:
vert.add_out('vec3 wposition') vert.add_uniform('mat4 W', '_worldMatrix')
vert.write_attrib('wposition = vec4(W * spos).xyz;') vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')
elif write_wpos:
vert.add_uniform('mat4 W', '_worldMatrix') frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition')
vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;') if frag_mpos:
vert.add_out('vec3 mposition')
if frag.contains('dotNV') and not frag.contains('float dotNV'): vert.add_uniform('float posUnpack', link='_posUnpack')
frag.write_attrib('float dotNV = max(dot(n, vVec), 0.0);') vert.write_attrib('mposition = spos.xyz * posUnpack;')
frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition') if tese is not None:
if frag_mpos: if frag_mpos:
vert.add_out('vec3 mposition') make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
vert.add_uniform('float posUnpack', link='_posUnpack') elif tese.contains('mposition') and not tese.contains('vec3 mposition'):
vert.write_attrib('mposition = spos.xyz * posUnpack;') vert.add_out('vec3 mposition')
vert.write_pre = True
if tese is not None: vert.add_uniform('float posUnpack', link='_posUnpack')
if frag_mpos: vert.write('mposition = spos.xyz * posUnpack;')
make_tess.interpolate(tese, 'mposition', 3, declare_out=True) vert.write_pre = False
elif tese.contains('mposition') and not tese.contains('vec3 mposition'): make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
vert.add_out('vec3 mposition')
vert.write_pre = True frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition')
vert.add_uniform('float posUnpack', link='_posUnpack') if frag_bpos:
vert.write('mposition = spos.xyz * posUnpack;') vert.add_out('vec3 bposition')
vert.write_pre = False vert.add_uniform('vec3 dim', link='_dim')
make_tess.interpolate(tese, 'mposition', 3, declare_out=False) vert.add_uniform('vec3 hdim', link='_halfDim')
vert.add_uniform('float posUnpack', link='_posUnpack')
frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition') vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
if frag_bpos: vert.write_attrib('if (dim.z == 0) bposition.z = 0;')
vert.add_out('vec3 bposition') vert.write_attrib('if (dim.y == 0) bposition.y = 0;')
vert.add_uniform('vec3 dim', link='_dim') vert.write_attrib('if (dim.x == 0) bposition.x = 0;')
vert.add_uniform('vec3 hdim', link='_halfDim')
vert.add_uniform('float posUnpack', link='_posUnpack') if tese is not None:
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;') if frag_bpos:
vert.write_attrib('if (dim.z == 0) bposition.z = 0;') make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
vert.write_attrib('if (dim.y == 0) bposition.y = 0;') elif tese.contains('bposition') and not tese.contains('vec3 bposition'):
vert.write_attrib('if (dim.x == 0) bposition.x = 0;') vert.add_out('vec3 bposition')
vert.add_uniform('vec3 dim', link='_dim')
if tese is not None: vert.add_uniform('vec3 hdim', link='_halfDim')
if frag_bpos: vert.add_uniform('float posUnpack', link='_posUnpack')
make_tess.interpolate(tese, 'bposition', 3, declare_out=True) vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
elif tese.contains('bposition') and not tese.contains('vec3 bposition'): make_tess.interpolate(tese, 'bposition', 3, declare_out=False)
vert.add_out('vec3 bposition')
vert.add_uniform('vec3 dim', link='_dim') frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
vert.add_uniform('vec3 hdim', link='_halfDim') if frag_wtan:
vert.add_uniform('float posUnpack', link='_posUnpack') # Indicate we want tang attrib in finalizer to prevent TBN generation
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;') con_mesh.add_elem('tex', 'short2norm')
make_tess.interpolate(tese, 'bposition', 3, declare_out=False) con_mesh.add_elem('tang', 'short4norm')
vert.add_out('vec3 wtangent')
frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent') vert.write_pre = True
if frag_wtan: vert.write('wtangent = normalize(N * tang.xyz);')
# Indicate we want tang attrib in finalizer to prevent TBN generation vert.write_pre = False
con_mesh.add_elem('tex', 'short2norm')
con_mesh.add_elem('tang', 'short4norm') if tese is not None:
vert.add_out('vec3 wtangent') if frag_wtan:
vert.write_pre = True make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
vert.write('wtangent = normalize(N * tang.xyz);') elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
vert.write_pre = False vert.add_out('vec3 wtangent')
vert.write_pre = True
if tese is not None: vert.write('wtangent = normalize(N * tang.xyz);')
if frag_wtan: vert.write_pre = False
make_tess.interpolate(tese, 'wtangent', 3, declare_out=True) make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)
elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
vert.add_out('vec3 wtangent') if frag.contains('vVecCam'):
vert.write_pre = True vert.add_out('vec3 eyeDirCam')
vert.write('wtangent = normalize(N * tang.xyz);') vert.add_uniform('mat4 WV', '_worldViewMatrix')
vert.write_pre = False vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
make_tess.interpolate(tese, 'wtangent', 3, declare_out=False) frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
if frag.contains('vVecCam'): if frag.contains('nAttr'):
vert.add_out('vec3 eyeDirCam') vert.add_out('vec3 nAttr')
vert.add_uniform('mat4 WV', '_worldViewMatrix') vert.write_attrib('nAttr = vec3(nor.xy, pos.w);')
vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);') wrd = bpy.data.worlds['Lnx']
if '_Legacy' in wrd.world_defs:
if frag.contains('nAttr'): frag.replace('sampler2DShadow', 'sampler2D')
vert.add_out('vec3 nAttr') frag.replace('samplerCubeShadow', 'samplerCube')
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')

View File

@ -557,7 +557,7 @@ def make_forward(con_mesh):
frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));') frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));')
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);') frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract: if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract:
frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 0.0);') frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 1.0);')
else: else:
frag.add_out('vec4 fragColor[1]') frag.add_out('vec4 fragColor[1]')
@ -611,42 +611,10 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
sh = tese if tese is not None else vert sh = tese if tese is not None else vert
sh.add_out('vec3 eyeDir') sh.add_out('vec3 eyeDir')
sh.add_uniform('vec3 eye', '_cameraPosition') sh.add_uniform('vec3 eye', '_cameraPosition')
sh.write('eyeDir = eye - wposition;') sh.write('eyeDir = eye - spos.xyz;')
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') frag.add_include('std/light.glsl')
is_shadows = '_ShadowMap' in wrd.world_defs is_shadows = '_ShadowMap' in wrd.world_defs
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs
shadowmap_sun = 'shadowMap' shadowmap_sun = 'shadowMap'
@ -662,10 +630,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if '_Brdf' in wrd.world_defs: if '_Brdf' in wrd.world_defs:
frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png') 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('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: if '_Irr' in wrd.world_defs:
frag.add_include('std/shirr.glsl') frag.add_include('std/shirr.glsl')
frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance') frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance')
@ -690,36 +655,51 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('envl *= albedo;') frag.write('envl *= albedo;')
if '_Brdf' in wrd.world_defs: if '_Brdf' in wrd.world_defs:
frag.write('envl.rgb *= 1.0 - F;') frag.write('envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y);')
if '_Rad' in wrd.world_defs: if '_Rad' in wrd.world_defs:
frag.write('envl += prefilteredColor * F;') frag.write('envl += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);')
elif '_EnvCol' in wrd.world_defs: elif '_EnvCol' in wrd.world_defs:
frag.add_uniform('vec3 backgroundCol', link='_backgroundCol') frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
frag.write('envl += backgroundCol * F;') frag.write('envl += backgroundCol * (f0 * envBRDF.x + envBRDF.y);')
frag.add_uniform('float envmapStrength', link='_envmapStrength') frag.add_uniform('float envmapStrength', link='_envmapStrength')
frag.write('envl *= envmapStrength * occlusion;') frag.write('envl *= envmapStrength * occlusion;')
if '_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs: if '_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs:
frag.add_include('std/conetrace.glsl') if parse_opacity or '_VoxelShadow' in wrd.world_defs:
frag.add_uniform('sampler3D voxels') frag.add_include('std/conetrace.glsl')
frag.add_uniform('sampler3D voxelsSDF') frag.add_uniform('sampler3D voxels')
frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps') 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;')
if '_VoxelAOvar' in wrd.world_defs: if '_VoxelAOvar' in wrd.world_defs and not parse_opacity:
frag.write('envl *= (1.0 - traceAO(wposition, n, voxels, clipmaps));') frag.add_uniform("sampler2D voxels_ao");
frag.write('envl *= textureLod(voxels_ao, texCoord, 0.0).rrr;')
if '_VoxelGI' in wrd.world_defs: if '_VoxelGI' in wrd.world_defs:
frag.write('vec3 indirect = vec3(0.0);') frag.write('vec3 indirect = vec3(0.0);')
else: else:
frag.write('vec3 indirect = envl;') frag.write('vec3 indirect = envl;')
if '_VoxelGI' in wrd.world_defs: if '_VoxelGI' in wrd.world_defs:
frag.write('vec4 diffuse_indirect = traceDiffuse(wposition, n, voxels, clipmaps);') if parse_opacity:
frag.write('indirect = (diffuse_indirect.rgb * albedo * (1.0 - F) + envl * (1.0 - diffuse_indirect.a)) * voxelgiDiff;') frag.write('vec4 trace = traceDiffuse(wposition, wnormal, voxels, clipmaps);')
frag.write('if (roughness < 1.0 && specular > 0.0) {') frag.write('indirect = ((trace.rgb * albedo + envl * (1.0 - trace.a)) * voxelgiDiff);')
frag.write(' indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity).rgb * F * voxelgiRefl;') frag.write('if (roughness < 1.0 && specular > 0.0){')
frag.write('}') 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;")
frag.write('vec3 direct = vec3(0.0);') frag.write('vec3 direct = vec3(0.0);')
if '_Sun' in wrd.world_defs: if '_Sun' in wrd.world_defs:
@ -733,21 +713,18 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if is_shadows: if is_shadows:
frag.add_uniform('bool receiveShadow') frag.add_uniform('bool receiveShadow')
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True) frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True)
if is_transparent_shadows: frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True)
frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True)
frag.add_uniform('float shadowsBias', '_sunShadowsBias') frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {') frag.write('if (receiveShadow) {')
if '_CSM' in wrd.world_defs: if '_CSM' in wrd.world_defs:
frag.add_include('std/shadows.glsl') frag.add_include('std/shadows.glsl')
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True) frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},') if parse_opacity:
if is_transparent_shadows: frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, true);')
frag.write(f'{shadowmap_sun_tr},') else:
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias') frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, false);')
if is_transparent_shadows:
frag.write(', false')
frag.write(');')
else: else:
if tese is not None: if tese is not None:
tese.add_out('vec4 lightPosition') tese.add_out('vec4 lightPosition')
@ -761,18 +738,15 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
else: else:
vert.add_out('vec4 lightPosition') vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
vert.write('lightPosition = LWVP * pos;') vert.write('lightPosition = LWVP * lightPosition;')
frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;') frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
frag.write('const vec2 smSize = shadowmapSize;') frag.write('const vec2 smSize = shadowmapSize;')
frag.write(f'svisibility = PCF({shadowmap_sun},') if parse_opacity:
if is_transparent_shadows: frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, true);')
frag.write(f'{shadowmap_sun_tr},') else:
frag.write('lPos.xy, lPos.z - shadowsBias, smSize') frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, false);')
if is_transparent_shadows:
frag.write(', false')
frag.write(');')
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;') frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;')
frag.write('}') # receiveShadow frag.write('}') # receiveShadow
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;') frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
# sun # sun
@ -791,8 +765,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
# Skip world matrix, already in world-space # Skip world matrix, already in world-space
frag.add_uniform('mat4 LWVPSpot[1]', link='_biasLightViewProjectionMatrixSpotArray', included=True) frag.add_uniform('mat4 LWVPSpot[1]', link='_biasLightViewProjectionMatrixSpotArray', included=True)
frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True)
if is_transparent_shadows: frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True)
frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True)
else: else:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True) frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True) frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True)
@ -800,19 +773,18 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('direct += sampleLight(') frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0') frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows: if is_shadows:
frag.write(', 0, pointBias, receiveShadow') if parse_opacity:
if is_transparent_shadows: frag.write(', 0, pointBias, receiveShadow, opacity != 1.0')
frag.write(', opacity != 1.0') else:
frag.write(', 0, pointBias, receiveShadow, false')
if '_Spot' in wrd.world_defs: if '_Spot' in wrd.world_defs:
frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight') frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight')
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write(', voxels, voxelsSDF, clipmaps') 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: if '_MicroShadowing' in wrd.world_defs:
frag.write(', occlusion') frag.write(', occlusion')
if '_SSRS' in wrd.world_defs: if '_SSRS' in wrd.world_defs:
frag.add_uniform('sampler2D gbufferD') frag.add_uniform('sampler2D gbufferD', top=True)
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix') frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write(', gbufferD, invVP, eye') frag.write(', gbufferD, invVP, eye')
@ -828,9 +800,10 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if '_VoxelRefract' in wrd.world_defs and parse_opacity: if '_VoxelRefract' in wrd.world_defs and parse_opacity:
frag.write('if (opacity < 1.0) {') frag.write('if (opacity < 1.0) {')
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(' vec2 velocity = -textureLod(sveloc, gl_FragCoord.xy, 0.0).rg;')
frag.write(' indirect = mix(refraction, indirect, opacity);') frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness, clipmaps, gl_FragCoord.xy,velocity).rgb;')
frag.write(' direct = mix(refraction, direct, opacity);') frag.write(' indirect = mix(refraction, indirect, opacity) * voxelgiRefr;')
frag.write(' direct = mix(refraction, direct, opacity) * voxelgiRefr;')
frag.write('}') frag.write('}')
def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool): def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
@ -844,4 +817,4 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
frag.write('vec3 emissionCol;') frag.write('vec3 emissionCol;')
if parse_opacity: if parse_opacity:
frag.write('float opacity;') frag.write('float opacity;')
frag.write('float ior = 1.45;') frag.write('float ior;')

View File

@ -58,7 +58,6 @@ def make(context_id):
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);') frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
frag.write('fragColor[2] = vec4(ior, opacity, 0.0, 1.0);') frag.write('fragColor[2] = vec4(ior, opacity, 0.0, 1.0);')
# frag.write('fragColor[2] = vec4(ior, opacity, packFloat2(basecol.r, basecol.g), basecol.b);')
make_finalize.make(con_refract) make_finalize.make(con_refract)

View File

@ -0,0 +1,49 @@
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

View File

@ -295,7 +295,6 @@ 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) 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_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_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_clear_on_compile = BoolProperty(name="Clear Console", description="Clears the system console on compile", default=False)
bpy.types.World.lnx_play_camera = EnumProperty( bpy.types.World.lnx_play_camera = EnumProperty(
items=[('Scene', 'Scene', 'Scene'), items=[('Scene', 'Scene', 'Scene'),

View File

@ -65,8 +65,8 @@ def update_preset(self, context):
rpdat.rp_background = 'World' rpdat.rp_background = 'World'
rpdat.rp_stereo = False rpdat.rp_stereo = False
rpdat.rp_voxelgi_resolution = '32' rpdat.rp_voxelgi_resolution = '32'
rpdat.lnx_voxelgi_size = 0.125 rpdat.lnx_voxelgi_size = 0.25
rpdat.rp_voxels = 'Voxel GI' rpdat.rp_voxels = 'Voxel AO'
rpdat.rp_render_to_texture = True rpdat.rp_render_to_texture = True
rpdat.rp_supersampling = '1' rpdat.rp_supersampling = '1'
rpdat.rp_antialiasing = 'SMAA' rpdat.rp_antialiasing = 'SMAA'
@ -142,8 +142,8 @@ def update_preset(self, context):
rpdat.rp_stereo = False rpdat.rp_stereo = False
rpdat.rp_voxels = 'Voxel GI' rpdat.rp_voxels = 'Voxel GI'
rpdat.rp_voxelgi_resolution = '64' rpdat.rp_voxelgi_resolution = '64'
rpdat.lnx_voxelgi_size = 0.125 rpdat.lnx_voxelgi_size = 0.25
rpdat.lnx_voxelgi_step = 0.01 rpdat.lnx_voxelgi_step = 0.25
rpdat.lnx_voxelgi_revoxelize = False rpdat.lnx_voxelgi_revoxelize = False
rpdat.lnx_voxelgi_camera = False rpdat.lnx_voxelgi_camera = False
rpdat.rp_voxelgi_emission = False rpdat.rp_voxelgi_emission = False
@ -152,7 +152,7 @@ def update_preset(self, context):
rpdat.rp_antialiasing = 'TAA' rpdat.rp_antialiasing = 'TAA'
rpdat.rp_compositornodes = True rpdat.rp_compositornodes = True
rpdat.rp_volumetriclight = False rpdat.rp_volumetriclight = False
rpdat.rp_ssgi = 'SSGI' rpdat.rp_ssgi = 'RTAO'
rpdat.lnx_ssrs = False rpdat.lnx_ssrs = False
rpdat.lnx_micro_shadowing = True rpdat.lnx_micro_shadowing = True
rpdat.rp_ssr = True rpdat.rp_ssr = True
@ -330,7 +330,6 @@ 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: 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_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_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 shadows for transparent objects", default=False, update=update_renderpath)
rp_shadowmap_atlas_lod_subdivisions: EnumProperty( rp_shadowmap_atlas_lod_subdivisions: EnumProperty(
items=[('2', '2', '2'), items=[('2', '2', '2'),
('3', '3', '3'), ('3', '3', '3'),
@ -392,8 +391,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
rp_ssgi: EnumProperty( rp_ssgi: EnumProperty(
items=[('Off', 'No AO', 'Off'), items=[('Off', 'No AO', 'Off'),
('SSAO', 'SSAO', 'Screen space ambient occlusion'), ('SSAO', 'SSAO', 'Screen space ambient occlusion'),
('SSGI', 'SSGI', 'Screen space global illumination') ('RTAO', 'RTAO', 'Ray-traced ambient occlusion')
#('RTAO', 'RTAO', 'Ray-traced ambient occlusion')
# ('RTGI', 'RTGI', 'Ray-traced global illumination') # ('RTGI', 'RTGI', 'Ray-traced global illumination')
], ],
name="SSGI", description="Screen space global illumination", default='SSAO', update=update_renderpath) name="SSGI", description="Screen space global illumination", default='SSAO', update=update_renderpath)
@ -510,7 +508,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
('1', '1', '1'), ('1', '1', '1'),
('2', '2', '2')], ('2', '2', '2')],
name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath) 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=5, update=assets.invalidate_compiled_data) lnx_voxelgi_clipmap_count: IntProperty(name="Clipmap count", description="Number of clipmaps", default=3, 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_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_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
lnx_samples_per_pixel: EnumProperty( lnx_samples_per_pixel: EnumProperty(
@ -532,10 +530,9 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_voxelgi_spec: FloatProperty(name="Reflection", description="", default=1.0, update=assets.invalidate_shader_cache) 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_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_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_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_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=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_step: FloatProperty(name="Step", description="Step size", default=0.25, update=assets.invalidate_shader_cache)
lnx_voxelgi_range: FloatProperty(name="Range", description="Maximum range", default=100.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_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) lnx_voxelgi_aperture: FloatProperty(name="Aperture", description="Cone aperture for shadow trace", default=0.0, update=assets.invalidate_shader_cache)
@ -548,17 +545,15 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_water_density: FloatProperty(name="Density", default=1.0, update=assets.invalidate_shader_cache) 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_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_water_reflect: FloatProperty(name="Reflect", default=1.0, update=assets.invalidate_shader_cache)
lnx_ssgi_strength: FloatProperty(name="Strength", default=1.250, update=assets.invalidate_shader_cache) lnx_ssgi_strength: FloatProperty(name="Strength", default=1.0, update=assets.invalidate_shader_cache)
lnx_ssgi_radius: FloatProperty(name="Radius", default=0.750, 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_step: FloatProperty(name="Step", default=2.0, update=assets.invalidate_shader_cache)
lnx_ssgi_samples: IntProperty(name="Samples", default=32, update=assets.invalidate_shader_cache) lnx_ssgi_max_steps: IntProperty(name="Max Steps", default=8, update=assets.invalidate_shader_cache)
"""
lnx_ssgi_rays: EnumProperty( lnx_ssgi_rays: EnumProperty(
items=[('9', '9', '9'), items=[('9', '9', '9'),
('5', '5', '5'), ('5', '5', '5'),
], ],
name="Rays", description="Number of rays to trace for RTAO", default='5', update=assets.invalidate_shader_cache) 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_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_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) 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)

View File

@ -1659,7 +1659,6 @@ class LNX_PT_RenderPathShadowsPanel(bpy.types.Panel):
col.prop(rpdat, 'rp_shadowmap_cube') col.prop(rpdat, 'rp_shadowmap_cube')
layout.prop(rpdat, 'rp_shadowmap_cascade') layout.prop(rpdat, 'rp_shadowmap_cascade')
layout.prop(rpdat, 'rp_shadowmap_cascades') layout.prop(rpdat, 'rp_shadowmap_cascades')
layout.prop(rpdat, 'rp_shadowmap_transparent')
col = layout.column() col = layout.column()
col2 = col.column() col2 = col.column()
col2.enabled = rpdat.rp_shadowmap_cascades != '1' col2.enabled = rpdat.rp_shadowmap_cascades != '1'
@ -1791,7 +1790,7 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
col3.enabled = rpdat.rp_voxels == 'Voxel AO' col3.enabled = rpdat.rp_voxels == 'Voxel AO'
col.prop(rpdat, 'lnx_voxelgi_shadows', text='Shadows') col.prop(rpdat, 'lnx_voxelgi_shadows', text='Shadows')
col2.prop(rpdat, 'lnx_voxelgi_refract', text='Refraction') 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, 'lnx_voxelgi_cones')
col.prop(rpdat, 'rp_voxelgi_resolution') col.prop(rpdat, 'rp_voxelgi_resolution')
col.prop(rpdat, 'lnx_voxelgi_size') col.prop(rpdat, 'lnx_voxelgi_size')
@ -1805,10 +1804,9 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
col2.prop(rpdat, 'lnx_voxelgi_spec') col2.prop(rpdat, 'lnx_voxelgi_spec')
col2.prop(rpdat, 'lnx_voxelgi_refr') col2.prop(rpdat, 'lnx_voxelgi_refr')
col.prop(rpdat, 'lnx_voxelgi_shad') col.prop(rpdat, 'lnx_voxelgi_shad')
col.prop(rpdat, 'lnx_voxelgi_env')
col.prop(rpdat, 'lnx_voxelgi_occ') col.prop(rpdat, 'lnx_voxelgi_occ')
col.label(text="Ray") 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_step')
col.prop(rpdat, 'lnx_voxelgi_range') col.prop(rpdat, 'lnx_voxelgi_range')
#col.prop(rpdat, 'lnx_voxelgi_aperture') #col.prop(rpdat, 'lnx_voxelgi_aperture')
@ -1899,10 +1897,10 @@ class LNX_PT_RenderPathPostProcessPanel(bpy.types.Panel):
sub = col.column() sub = col.column()
sub.enabled = rpdat.rp_ssgi != 'Off' sub.enabled = rpdat.rp_ssgi != 'Off'
sub.prop(rpdat, 'lnx_ssgi_half_res') 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_radius')
sub.prop(rpdat, 'lnx_ssgi_strength') sub.prop(rpdat, 'lnx_ssgi_strength')
sub.prop(rpdat, 'lnx_ssgi_samples') sub.prop(rpdat, 'lnx_ssgi_max_steps')
layout.separator() layout.separator()
row = layout.row() row = layout.row()

View File

@ -207,8 +207,6 @@ project.addSources('Sources');
# get instantiated # get instantiated
khafile.write("""project.addParameter("--macro include('leenkx.logicnode')");\n""") 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)) import_traits = list(set(import_traits))
for i in range(0, len(import_traits)): for i in range(0, len(import_traits)):
khafile.write("project.addParameter('" + import_traits[i] + "');\n") khafile.write("project.addParameter('" + import_traits[i] + "');\n")
@ -627,18 +625,32 @@ def write_compiledglsl(defs, make_variants):
idx_emission = 2 idx_emission = 2
idx_refraction = 2 idx_refraction = 2
if '_gbuffer2' in wrd.world_defs: if '_gbuffer2' in wrd.world_defs:
f.write('#define GBUF_IDX_2 2\n') f.write('#define GBUF_IDX_2 2\n')
idx_emission += 1 idx_emission += 1
idx_refraction += 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 '_EmissionShaded' in wrd.world_defs: if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n') f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\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) f.write("""#if defined(HLSL) || defined(METAL)
#define _InvY #define _InvY
@ -672,16 +684,16 @@ const float waterReflect = """ + str(round(rpdat.lnx_water_reflect * 100) / 100)
f'const float ditherStrengthValue = {rpdat.lnx_dithering_strength};\n' f'const float ditherStrengthValue = {rpdat.lnx_dithering_strength};\n'
) )
if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'SSGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight: if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight:
f.write( f.write(
"""const float ssaoRadius = """ + str(round(rpdat.lnx_ssgi_radius * 100) / 100) + """; """const float ssaoRadius = """ + str(round(rpdat.lnx_ssgi_radius * 100) / 100) + """;
const float ssaoStrength = """ + str(round(rpdat.lnx_ssgi_strength * 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") + """; const float ssaoScale = """ + ("2.0" if rpdat.lnx_ssgi_half_res else "20.0") + """;
""") """)
if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_ssgi == 'SSGI' : if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO':
f.write( f.write(
"""const int ssgiSamples = """ + str(rpdat.lnx_ssgi_samples) + """; """const int ssgiMaxSteps = """ + str(rpdat.lnx_ssgi_max_steps) + """;
const float ssgiRayStep = 0.005 * """ + str(round(rpdat.lnx_ssgi_step * 100) / 100) + """; const float ssgiRayStep = 0.005 * """ + str(round(rpdat.lnx_ssgi_step * 100) / 100) + """;
const float ssgiStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """; const float ssgiStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """;
""") """)
@ -828,7 +840,6 @@ const float voxelgiRange = """ + str(round(rpdat.lnx_voxelgi_range * 100) / 100)
const float voxelgiOffset = """ + str(round(rpdat.lnx_voxelgi_offset * 1000) / 1000) + """; const float voxelgiOffset = """ + str(round(rpdat.lnx_voxelgi_offset * 1000) / 1000) + """;
const float voxelgiAperture = """ + str(round(rpdat.lnx_voxelgi_aperture * 100) / 100) + """; const float voxelgiAperture = """ + str(round(rpdat.lnx_voxelgi_aperture * 100) / 100) + """;
const float voxelgiShad = """ + str(round(rpdat.lnx_voxelgi_shad * 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': if rpdat.rp_voxels == 'Voxel GI':
f.write(""" f.write("""