forked from LeenkxTeam/LNXSDK
Patch_2
This commit is contained in:
@ -1,25 +1,8 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _Clusters
|
||||
#include "std/clusters.glsl"
|
||||
#endif
|
||||
#ifdef _ShadowMap
|
||||
#include "std/shadows.glsl"
|
||||
#endif
|
||||
#ifdef _LTC
|
||||
#include "std/ltc.glsl"
|
||||
#endif
|
||||
#ifdef _LightIES
|
||||
#include "std/ies.glsl"
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
#include "std/light_common.glsl"
|
||||
#endif
|
||||
#include "std/constants.glsl"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
@ -27,480 +10,179 @@ uniform sampler2D gbufferD;
|
||||
#ifdef _EmissionShaded
|
||||
uniform sampler2D gbufferEmission;
|
||||
#endif
|
||||
uniform sampler2D sveloc;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 screenSize;
|
||||
uniform mat4 invVP;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec3 fragColor;
|
||||
|
||||
float metallic;
|
||||
uint matid;
|
||||
|
||||
#ifdef _SMSizeUniform
|
||||
//!uniform vec2 smSizeUniform;
|
||||
#endif
|
||||
|
||||
#ifdef _Clusters
|
||||
uniform vec4 lightsArray[maxLights * 3];
|
||||
#ifdef _Spot
|
||||
uniform vec4 lightsArraySpot[maxLights * 2];
|
||||
#endif
|
||||
uniform sampler2D clustersData;
|
||||
uniform vec2 cameraPlane;
|
||||
#endif
|
||||
|
||||
#ifdef _SinglePoint // Fast path for single light
|
||||
uniform vec3 pointPos;
|
||||
uniform vec3 pointCol;
|
||||
#ifdef _ShadowMap
|
||||
uniform float pointBias;
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
uniform vec3 spotDir;
|
||||
uniform vec3 spotRight;
|
||||
uniform vec4 spotData;
|
||||
#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
|
||||
uniform mat4 P;
|
||||
uniform mat4 invP;
|
||||
uniform mat3 V3;
|
||||
|
||||
#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
|
||||
|
||||
#ifdef _LightIES
|
||||
visibility *= iesAttenuation(-l);
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
#ifndef _Spot
|
||||
visibility *= PCFCube(shadowMapPoint[0],
|
||||
shadowMapPointTransparent[0],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
visibility *= PCFFakeCube(
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
, ld, -l, bias, lightProj, n, index, transparent
|
||||
);
|
||||
#else
|
||||
if (index == 0) visibility *= PCFCube(shadowMapPoint[0],
|
||||
shadowMapPointTransparent[0],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 1) visibility *= PCFCube(shadowMapPoint[1],
|
||||
shadowMapPointTransparent[1],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 2) visibility *= PCFCube(shadowMapPoint[2],
|
||||
shadowMapPointTransparent[2],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
else if (index == 3) visibility *= PCFCube(shadowMapPoint[3],
|
||||
shadowMapPointTransparent[3],
|
||||
ld, -l, bias, lightProj, n, transparent);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
vec3 getVisibility(vec3 p, vec3 n, float depth, vec2 uv) {
|
||||
vec3 visibility = vec3(0.0);
|
||||
#ifdef _Sun
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _CSM
|
||||
visibility = shadowTestCascade(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias, false
|
||||
);
|
||||
#else
|
||||
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
|
||||
if (lPos.w > 0.0) {
|
||||
visibility = shadowTest(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias, false
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 PPComp12;
|
||||
#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
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
#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
|
||||
const int RAY_STEPS = 12;
|
||||
|
||||
vec2 getProjectedCoord(const vec3 viewPos) {
|
||||
vec4 projectedCoord = P * vec4(viewPos, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
#ifdef _InvY
|
||||
projectedCoord.y = 1.0 - projectedCoord.y;
|
||||
#endif
|
||||
return projectedCoord.xy;
|
||||
}
|
||||
|
||||
vec3 cosineSampleHemisphere(vec3 n, vec2 rand) {
|
||||
float phi = PI * 2.0 * rand.x;
|
||||
float cosTheta = sqrt(1.0 - rand.y);
|
||||
float sinTheta = sqrt(rand.y);
|
||||
|
||||
vec3 h = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
|
||||
|
||||
vec3 tangent, bitangent;
|
||||
vec3 absN = abs(n);
|
||||
|
||||
if (absN.x <= absN.y && absN.x <= absN.z) {
|
||||
tangent = normalize(cross(n, vec3(1.0, 0.0, 0.0)));
|
||||
} else if (absN.y <= absN.z) {
|
||||
tangent = normalize(cross(n, vec3(0.0, 1.0, 0.0)));
|
||||
} else {
|
||||
tangent = normalize(cross(n, vec3(0.0, 0.0, 1.0)));
|
||||
}
|
||||
bitangent = cross(n, tangent);
|
||||
|
||||
return normalize(tangent * h.x + bitangent * h.y + n * h.z);
|
||||
}
|
||||
|
||||
vec3 traceRay(vec3 origin, vec3 dir, float maxDist, float minDist) {
|
||||
float stepSize = maxDist / float(RAY_STEPS);
|
||||
vec3 pos = origin + dir * minDist;
|
||||
|
||||
float prevDepthDiff = 0.0;
|
||||
float hadValidPrev = 0.0;
|
||||
|
||||
for (int i = 1; i <= RAY_STEPS; i++) {
|
||||
pos += dir * stepSize;
|
||||
vec2 uv = getProjectedCoord(pos);
|
||||
|
||||
vec2 sampleUV = clamp(uv, vec2(0.001), vec2(0.999));
|
||||
|
||||
float sampleDepth = textureLod(gbufferD, sampleUV, 0.0).r * 2.0 - 1.0;
|
||||
if (sampleDepth == 1.0) {
|
||||
hadValidPrev = 0.0;
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3 sampleViewPos = getPosView2(invP, sampleDepth, sampleUV);
|
||||
float depthDiff = pos.z - sampleViewPos.z;
|
||||
float rayDist = length(pos - origin);
|
||||
float thickness = 0.15 + rayDist * 0.25;
|
||||
|
||||
float crossed = hadValidPrev * step(0.0, prevDepthDiff) * step(depthDiff, 0.0);
|
||||
float withinThickness = step(abs(depthDiff), thickness);
|
||||
|
||||
if (crossed > 0.5 || withinThickness > 0.5) {
|
||||
float distWeight = 1.0 - (rayDist / maxDist);
|
||||
distWeight = max(0.0, distWeight * distWeight);
|
||||
|
||||
return vec3(sampleUV, distWeight);
|
||||
}
|
||||
|
||||
prevDepthDiff = depthDiff;
|
||||
hadValidPrev = 1.0;
|
||||
}
|
||||
|
||||
return vec3(-1.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r;
|
||||
if (depth >= 1.0) {
|
||||
fragColor = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
|
||||
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 pos = getWorldPos(texCoord, depth);
|
||||
vec3 normal = getNormal(texCoord);
|
||||
vec3 centerColor = textureLod(gbuffer1, texCoord, 0.0).rgb;
|
||||
|
||||
float radius = ssaoRadius;
|
||||
|
||||
vec3 gi = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float angle = fract(sin(dot(texCoord, vec2(12.9898, 78.233))) * 100.0);
|
||||
|
||||
for (int i = 0; i < ssgiSamples; i++) {
|
||||
// Use quasi-random sequence for better coverage
|
||||
float r = sqrt((float(i) + 0.5) / float(ssgiSamples)) * radius;
|
||||
float a = (float(i) * GOLDEN_ANGLE) + angle;
|
||||
|
||||
vec2 offset = vec2(cos(a), sin(a)) * r * radius;
|
||||
vec2 sampleUV = clamp(texCoord + offset * (BayerMatrix8[int(gl_FragCoord.x + velocity.x) % 8][int(gl_FragCoord.y + velocity.y) % 8] - 0.5) / screenSize, vec2(0.001), vec2(0.999));
|
||||
|
||||
float sampleDepth = textureLod(gbufferD, sampleUV, 0.0).r;
|
||||
if (sampleDepth >= 1.0) continue;
|
||||
|
||||
vec3 samplePos = getWorldPos(sampleUV, sampleDepth);
|
||||
vec3 sampleNormal = getNormal(sampleUV);
|
||||
|
||||
// Apply small bias to sample position to avoid self-occlusion
|
||||
samplePos += sampleNormal * SAMPLE_BIAS;
|
||||
|
||||
vec3 dir = pos - samplePos;
|
||||
float dist = length(dir);
|
||||
|
||||
if (abs(pos.z - samplePos.z) > MAX_DEPTH_DIFFERENCE) continue;;
|
||||
|
||||
vec3 sampleColor = calculateIndirectLight(sampleUV, samplePos, sampleNormal, sampleDepth);
|
||||
float weight = 1.0 / (1.0 + dist * dist * 2.0) * max(dot(sampleNormal, n), 0.0);
|
||||
|
||||
gi += sampleColor * weight;
|
||||
totalWeight += weight;
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
if (depth == 1.0) {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Normalize and apply intensity
|
||||
if (totalWeight > 0.0) {
|
||||
gi /= totalWeight;
|
||||
#ifdef _CPostprocess
|
||||
gi *= PPComp12.x;
|
||||
#else
|
||||
gi *= ssaoStrength;
|
||||
#endif
|
||||
}
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 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);
|
||||
n = normalize(n);
|
||||
|
||||
#ifdef _EmissionShadeless
|
||||
if (matid == 1) { // pure emissive material, color stored in basecol
|
||||
gi += textureLod(gbuffer1, texCoord, 0.0).rgb;
|
||||
}
|
||||
vec3 viewNormal = V3 * n;
|
||||
vec3 viewPos = getPosView2(invP, depth, texCoord);
|
||||
|
||||
#ifdef _CPostprocess
|
||||
float radius = PPComp12.y;
|
||||
float strength = PPComp12.x;
|
||||
#else
|
||||
float radius = ssgiRadius;
|
||||
float strength = ssgiStrength;
|
||||
#endif
|
||||
|
||||
float noise = fract(52.9829189 * fract(0.06711056 * texCoord.x * 1000.0 + 0.00583715 * texCoord.y * 1000.0));
|
||||
|
||||
vec3 gi = vec3(0.0);
|
||||
int validSamples = 0;
|
||||
|
||||
// min distance to avoid self shadowing artiffacts
|
||||
float minDist = radius * 0.05;
|
||||
|
||||
for (int i = 0; i < ssgiSamples; i++) {
|
||||
float fi = float(i) + noise;
|
||||
vec2 rand = vec2(
|
||||
fract(fi * 0.7548776662 + noise),
|
||||
fract(fi * 0.5698402909 + noise * 1.5)
|
||||
);
|
||||
|
||||
vec3 rayDir = cosineSampleHemisphere(viewNormal, rand);
|
||||
vec3 hitResult = traceRay(viewPos, rayDir, radius, minDist);
|
||||
|
||||
if (hitResult.x < 0.0) continue;
|
||||
|
||||
vec2 hitUV = hitResult.xy;
|
||||
float distWeight = hitResult.z;
|
||||
|
||||
vec3 hitAlbedo = textureLod(gbuffer1, hitUV, 1.0).rgb;
|
||||
|
||||
#ifdef _Sun
|
||||
vec4 hitG0 = textureLod(gbuffer0, hitUV, 0.0);
|
||||
vec2 hitEnc = hitG0.rg;
|
||||
vec3 hitN;
|
||||
hitN.z = 1.0 - abs(hitEnc.x) - abs(hitEnc.y);
|
||||
hitN.xy = hitN.z >= 0.0 ? hitEnc.xy : octahedronWrap(hitEnc.xy);
|
||||
hitN = normalize(hitN);
|
||||
float hitNdotL = max(0.0, dot(hitN, sunDir));
|
||||
vec3 hitRadiance = hitAlbedo * sunCol * hitNdotL;
|
||||
#else
|
||||
vec3 hitRadiance = hitAlbedo * 0.5;
|
||||
#endif
|
||||
|
||||
#ifdef _EmissionShaded
|
||||
hitRadiance += textureLod(gbufferEmission, hitUV, 0.0).rgb;
|
||||
#endif
|
||||
|
||||
gi += hitRadiance * distWeight;
|
||||
validSamples++;
|
||||
}
|
||||
|
||||
if (validSamples > 0) {
|
||||
gi /= float(validSamples);
|
||||
}
|
||||
|
||||
gi *= strength;
|
||||
|
||||
#ifdef _EmissionShaded
|
||||
#ifdef _EmissionShadeless
|
||||
else {
|
||||
#endif
|
||||
gi += textureLod(gbufferEmission, texCoord, 0.0).rgb;
|
||||
#ifdef _EmissionShadeless
|
||||
}
|
||||
#endif
|
||||
gi += textureLod(gbufferEmission, texCoord, 0.0).rgb * 0.3;
|
||||
#endif
|
||||
fragColor = gi / (gi + vec3(1.0)); // Reinhard tone mapping
|
||||
|
||||
fragColor = vec4(min(gi, vec3(2.0)), 1.0);
|
||||
}
|
||||
|
||||
@ -6,60 +6,18 @@
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "P",
|
||||
"link": "_projectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "invP",
|
||||
"link": "_inverseProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "V3",
|
||||
"link": "_viewMatrix3"
|
||||
},
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
},
|
||||
{
|
||||
"name": "PPComp12",
|
||||
"link": "_PPComp12",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArraySpot",
|
||||
"link": "_lightsArraySpot",
|
||||
"ifdef": ["_Clusters", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArray",
|
||||
"link": "_lightsArray",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "clustersData",
|
||||
"link": "_clustersData",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "cameraPlane",
|
||||
"link": "_cameraPlane",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "sunDir",
|
||||
"link": "_sunDirection",
|
||||
@ -71,128 +29,13 @@
|
||||
"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"]
|
||||
"name": "PPComp12",
|
||||
"link": "_PPComp12",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass_viewray.vert.glsl",
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "ssgi_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user