SSAO, performance sucks and it flickers so tweaking is needed, also more material support
This commit is contained in:
parent
5b231d6920
commit
577836a03f
39 changed files with 889 additions and 74 deletions
95
resources/EngineResources/shaders/ssao_frag.glsl
Normal file
95
resources/EngineResources/shaders/ssao_frag.glsl
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out float outAO;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D posSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D normalSampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D noiseSampler;
|
||||
|
||||
layout(set = 1, binding = 0) readonly buffer SSAOKernel {
|
||||
vec4 samples[];
|
||||
} kernel;
|
||||
|
||||
layout(set = 2, binding = 0) uniform SSAOInfo {
|
||||
mat4 projection; //64
|
||||
mat4 view; //128
|
||||
vec2 screenSize; // 136
|
||||
float radius; //140
|
||||
float bias; //144
|
||||
int kernelSize; //160
|
||||
} ssao;
|
||||
|
||||
void main() {
|
||||
vec2 uv = inTextCoord;
|
||||
|
||||
vec3 worldPos = texture(posSampler, uv).xyz;
|
||||
vec3 worldNormal = normalize(texture(normalSampler, uv).xyz);
|
||||
|
||||
vec2 noiseScale = ssao.screenSize / 4.0;
|
||||
|
||||
if (length(worldNormal) < 0.001) {
|
||||
outAO = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 fragPos = vec3(ssao.view * vec4(worldPos, 1.0));
|
||||
vec3 normal = normalize(mat3(ssao.view) * worldNormal);
|
||||
|
||||
vec3 randomVec = normalize(texture(noiseSampler, inTextCoord * noiseScale).xyz);
|
||||
|
||||
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
mat3 TBN = mat3(tangent, bitangent, normal);
|
||||
|
||||
float occlusion = 0.0;
|
||||
float validSamples = 0.0;;
|
||||
|
||||
for (int i = 0; i < ssao.kernelSize; i++) {
|
||||
vec3 samplePos = TBN * kernel.samples[i].xyz;
|
||||
samplePos = fragPos + samplePos * ssao.radius;
|
||||
|
||||
vec4 offset = vec4(samplePos, 1.0);
|
||||
offset = ssao.projection * offset;
|
||||
offset.xyz /= offset.w;
|
||||
offset.xyz = offset.xyz * 0.5 + 0.5;
|
||||
|
||||
vec2 sampleUV = offset.xy;
|
||||
sampleUV.y = 1 - sampleUV.y;
|
||||
|
||||
if (sampleUV.x < 0.0 || sampleUV.x > 1.0 ||
|
||||
sampleUV.y < 0.0 || sampleUV.y > 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3 sampleWorldPos = texture(posSampler, sampleUV).xyz;
|
||||
vec3 sampleWorldNormal = texture(normalSampler, sampleUV).xyz;
|
||||
|
||||
if (length(sampleWorldNormal) < 0.001) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3 sampleViewPos = vec3(ssao.view * vec4(sampleWorldPos, 1.0));
|
||||
|
||||
float depthDelta = abs(fragPos.z - sampleViewPos.z);
|
||||
if (depthDelta > ssao.radius) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float rangeCheck = 1.0 - depthDelta / ssao.radius;
|
||||
rangeCheck = rangeCheck * rangeCheck * (3.0 - 2.0 * rangeCheck);
|
||||
|
||||
if (sampleViewPos.z >= samplePos.z + ssao.bias) {
|
||||
occlusion += rangeCheck;
|
||||
}
|
||||
validSamples += 1;
|
||||
}
|
||||
|
||||
if (validSamples <= 0.0) {
|
||||
outAO = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
occlusion = 1.0 - occlusion / validSamples;
|
||||
outAO = occlusion * pow(occlusion, 3.0);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue