HDR, Bloom and SSR
This commit is contained in:
parent
577836a03f
commit
04befce27d
44 changed files with 1377 additions and 269 deletions
61
resources/EngineResources/shaders/bloom_pass_frag.glsl
Normal file
61
resources/EngineResources/shaders/bloom_pass_frag.glsl
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#version 450
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
layout(location = 0) in vec2 TexCoords;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D image;
|
||||
layout(set = 0, binding = 1) uniform sampler2D bloomImage;
|
||||
layout(set = 1 , binding = 0) uniform PassConfig{
|
||||
int ApplyToFinalImage;
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec3 padding;
|
||||
} config;
|
||||
|
||||
|
||||
|
||||
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
|
||||
|
||||
vec3 safeBloomSample(vec2 uv)
|
||||
{
|
||||
vec3 value = texture(bloomImage, uv).rgb;
|
||||
return clamp(value, vec3(0.0), vec3(8.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if(config.ApplyToFinalImage != 0){
|
||||
vec3 bloomColour = safeBloomSample(TexCoords);
|
||||
vec3 hdrColour = texture(image, TexCoords).rgb;
|
||||
hdrColour += bloomColour;
|
||||
vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure);
|
||||
result = pow(result, vec3(1.0 / config.GAMMA_CONST));
|
||||
FragColor = vec4(result, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float blurRadius = config.blur_radius;
|
||||
vec2 tex_offset = blurRadius / vec2(textureSize(bloomImage, 0));
|
||||
vec3 result = safeBloomSample(TexCoords) * weight[0];
|
||||
|
||||
if(config.horizontal != 0)
|
||||
{
|
||||
for(int i = 1; i < 5; ++i)
|
||||
{
|
||||
result += safeBloomSample(TexCoords + vec2(tex_offset.x * i, 0.0)) * weight[i];
|
||||
result += safeBloomSample(TexCoords - vec2(tex_offset.x * i, 0.0)) * weight[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 1; i < 5; ++i)
|
||||
{
|
||||
result += safeBloomSample(TexCoords + vec2(0.0, tex_offset.y * i)) * weight[i];
|
||||
result += safeBloomSample(TexCoords - vec2(0.0, tex_offset.y * i)) * weight[i];
|
||||
}
|
||||
}
|
||||
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
|
|
@ -26,7 +26,8 @@ layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
|
|||
layout(set = 0, binding = 4) uniform sampler2D emissiveSampler;
|
||||
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
|
||||
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
|
||||
layout(set = 0, binding = 7) uniform sampler2D ssaoBlur;
|
||||
layout(set = 0, binding = 7) uniform sampler2D ViewPos;
|
||||
layout(set = 0, binding = 8) uniform sampler2D ssaoBlur;
|
||||
|
||||
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
|
||||
Light lights[];
|
||||
|
|
@ -128,17 +129,18 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
|
|||
|
||||
void main() {
|
||||
vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
|
||||
vec3 normal = texture(normalsSampler, inTextCoord).rgb;
|
||||
vec4 normalW = texture(normalsSampler, inTextCoord);
|
||||
vec3 normal = normalW.rgb;
|
||||
vec3 viewPos = texture(ViewPos, inTextCoord).rgb;
|
||||
vec3 worldPos = texture(posSampler, inTextCoord).rgb;
|
||||
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
|
||||
vec4 pbr = texture(pbrSampler, inTextCoord);
|
||||
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
|
||||
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
|
||||
float emissiveness = emissive.r;
|
||||
|
||||
// outFragColor = vec4(vec3(texture(ssaoBlur, inTextCoord).r), 1);
|
||||
// return;
|
||||
|
||||
float ssao = texture(ssaoBlur, inTextCoord).r;
|
||||
outFragColor = vec4(vec3(normalW.a/2.0,normalW.a/2.0,normalW.a/2.0), 1);
|
||||
return;
|
||||
|
||||
float roughness = pbr.g;
|
||||
float metallic = pbr.b;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -30,8 +30,9 @@ layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
|
|||
layout(set = 0, binding = 4) uniform sampler2D emissiveSampler;
|
||||
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
|
||||
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
|
||||
layout(set = 0, binding = 7) uniform sampler2D ssaoBlur;
|
||||
layout(set = 0, binding = 8) uniform sampler2DArray shadowSampler;
|
||||
layout(set = 0, binding = 7) uniform sampler2D viewPos;
|
||||
layout(set = 0, binding = 8) uniform sampler2D ssaoBlur;
|
||||
layout(set = 0, binding = 9) uniform sampler2DArray shadowSampler;
|
||||
|
||||
|
||||
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
|
||||
|
|
@ -62,12 +63,12 @@ float chebyshevUpperBound(vec2 moments, float t) {
|
|||
float p_max = variance / (variance + d * d);
|
||||
|
||||
// Reduce light bleeding
|
||||
p_max = smoothstep(0.2, 1.0, p_max);
|
||||
p_max = smoothstep(0.5, 1.0, p_max);
|
||||
|
||||
return p_max;
|
||||
}
|
||||
|
||||
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
|
||||
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias, vec2 texelSize) {
|
||||
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
|
||||
|
||||
shadowMapPosition.xyz /= shadowMapPosition.w;
|
||||
|
|
@ -87,19 +88,18 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
|
|||
|
||||
float shadow = 0.0;
|
||||
|
||||
vec2 texelSize = 1.0 / textureSize(shadowSampler, 0).rg;
|
||||
for(int x = -1; x <= 1; ++x)
|
||||
{
|
||||
for(int y = -1; y <= 1; ++y)
|
||||
{
|
||||
vec2 moments = texture(shadowSampler, vec3((uv + vec2(x, y) * texelSize), cascadeIndex)).rg;
|
||||
float visibility = chebyshevUpperBound(moments, depth);
|
||||
shadow += depth - ShadowBias > visibility ? 1.0 : 0.0;
|
||||
shadow += visibility;
|
||||
}
|
||||
}
|
||||
shadow /= 9.0;
|
||||
|
||||
return 1 - shadow;
|
||||
return shadow;
|
||||
}
|
||||
|
||||
float distributionGGX(vec3 N, vec3 H, float roughness) {
|
||||
|
|
@ -193,13 +193,17 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
|
|||
|
||||
void main() {
|
||||
vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
|
||||
vec3 normal = texture(normalsSampler, inTextCoord).rgb;
|
||||
vec4 normalW = texture(normalsSampler, inTextCoord);
|
||||
vec3 normal = normalW.rgb;
|
||||
vec4 worldPosW = texture(posSampler, inTextCoord);
|
||||
vec3 worldPos = worldPosW.xyz;
|
||||
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
|
||||
vec4 pbrW = texture(pbrSampler, inTextCoord);
|
||||
vec3 pbr = pbrW.rgb;
|
||||
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
|
||||
vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb;
|
||||
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
|
||||
float Reflectivity = pbrW.a;
|
||||
float Refractivity = normalW.a;
|
||||
|
||||
float emissiveness = emissive.r;
|
||||
float translucencyf = translucency.r;
|
||||
|
|
@ -231,7 +235,10 @@ void main() {
|
|||
cascadeIndex = i + 1;
|
||||
}
|
||||
}
|
||||
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias);
|
||||
|
||||
vec2 texelSizeShadow = 1.0 / textureSize(shadowSampler, 0).rg;
|
||||
|
||||
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias, texelSizeShadow);
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
for (uint i = 0; i < sceneInfo.numLights; i++) {
|
||||
|
|
@ -242,7 +249,7 @@ void main() {
|
|||
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
|
||||
}
|
||||
}
|
||||
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao);;
|
||||
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao);
|
||||
if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive;
|
||||
outFragColor = vec4(Lo + ambient, 1.0f);
|
||||
outFragColor = vec4(outFragColor.xyz/2 + (outFragColor.xyz/2) * vec3(ssao,ssao,ssao),1);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const float REDUCE_MUL = 1.0/32.0;
|
|||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
layout(location = 1) out vec4 outBloomColour;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2DMS inputTexture;
|
||||
|
||||
|
|
@ -19,7 +20,12 @@ layout(set = 1, binding = 0) uniform ScreenSize{
|
|||
vec4 gamma(vec4 color){
|
||||
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
|
||||
}
|
||||
|
||||
vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){
|
||||
vec3 hdrColor = texture(Texture, TexCoords).rgb;
|
||||
vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure);
|
||||
mapped = pow(mapped, vec3(1.0 / Gamma));
|
||||
return mapped;
|
||||
}
|
||||
vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){
|
||||
ivec2 pixelCoords = ivec2(TextCoord * textureSize(textureIn));
|
||||
vec4 colorSum = vec4(0.0);
|
||||
|
|
@ -34,6 +40,8 @@ vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){
|
|||
void main(){
|
||||
ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture));
|
||||
|
||||
outFragColor = texelFetch(inputTexture, pixelCoords, 0);
|
||||
|
||||
if(USE_AA == 0){
|
||||
outFragColor = texelFetch(inputTexture,pixelCoords,0);
|
||||
}
|
||||
|
|
@ -49,5 +57,16 @@ void main(){
|
|||
if(USE_AA == 4){
|
||||
outFragColor = msaa(8,inputTexture,inTextCoord);
|
||||
}
|
||||
outFragColor = gamma(outFragColor);
|
||||
|
||||
vec3 color = outFragColor.rgb;
|
||||
|
||||
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
float threshold = 1.0;
|
||||
float softKnee = 0.5;
|
||||
|
||||
float contribution = max(brightness - threshold, 0.0);
|
||||
contribution = contribution / max(contribution + softKnee, 0.0001);
|
||||
|
||||
outBloomColour = vec4(color * contribution, 1.0);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
layout(constant_id = 0) const int USE_AA = 0;
|
||||
|
||||
const float GAMMA_CONST = 0.8545;
|
||||
const float GAMMA_CONST = 0.4545;
|
||||
const float Exposure = 2.0;
|
||||
const float SPAN_MAX = 8.0;
|
||||
const float REDUCE_MIN = 1.0/128.0;
|
||||
const float REDUCE_MUL = 1.0/32.0;
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
layout(location = 1) out vec4 outBloomColour;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D inputTexture;
|
||||
|
||||
|
|
@ -20,6 +22,13 @@ vec4 gamma(vec4 color){
|
|||
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
|
||||
}
|
||||
|
||||
vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){
|
||||
vec3 hdrColor = texture(Texture, TexCoords).rgb;
|
||||
vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure);
|
||||
mapped = pow(mapped, vec3(1.0 / Gamma));
|
||||
return mapped;
|
||||
}
|
||||
|
||||
// Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa
|
||||
vec4 fxaa(sampler2D tex, vec2 uv) {
|
||||
vec2 u_texel = 1.0 / screenSize.size;
|
||||
|
|
@ -74,17 +83,32 @@ void main(){
|
|||
|
||||
if(USE_AA == 1){
|
||||
outFragColor = fxaa(inputTexture, inTextCoord);
|
||||
outFragColor = gamma(outFragColor);
|
||||
return;
|
||||
}
|
||||
if(USE_AA == 2){
|
||||
else if(USE_AA == 2){
|
||||
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
if(USE_AA == 3){
|
||||
else if(USE_AA == 3){
|
||||
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
if(USE_AA == 4){
|
||||
else if(USE_AA == 4){
|
||||
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
outFragColor = gamma(texture(inputTexture,inTextCoord));
|
||||
else {
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
|
||||
vec3 color = outFragColor.rgb;
|
||||
|
||||
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
float threshold = 1.0;
|
||||
float softKnee = 0.5;
|
||||
|
||||
float contribution = max(brightness - threshold, 0.0);
|
||||
contribution = contribution / max(contribution + softKnee, 0.0001);
|
||||
|
||||
outBloomColour = vec4(color * contribution, 1.0);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 0) out vec4 outAlbedo;
|
||||
layout(location = 1) out vec4 outViewPos;
|
||||
|
||||
struct Material {
|
||||
vec4 diffuseColor; //16
|
||||
|
|
@ -29,6 +31,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
|
||||
|
|
@ -37,6 +43,7 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
|
|||
|
||||
layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
|
||||
|
||||
|
||||
layout(push_constant) uniform pc{
|
||||
layout(offset = 64) uint materialIdx;
|
||||
} push_constants;
|
||||
|
|
@ -44,13 +51,15 @@ layout(push_constant) uniform pc{
|
|||
void main()
|
||||
{
|
||||
|
||||
Material material = matUniform.materials[inMaterialIdx];
|
||||
vec4 viewPos = vec4(viewMatrix * inPos);
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
outAlbedo = vec4(0.0,0.0,1.0,1.0);
|
||||
return;
|
||||
}
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
if(material.hasTexture == 1){
|
||||
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
|
||||
outAlbedo = texColor;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -8,6 +8,7 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 1) out vec4 outAlbedo ;
|
||||
layout(location = 0) out vec4 outPos;
|
||||
|
|
@ -16,6 +17,7 @@ layout(location = 3) out vec4 outPBR;
|
|||
layout(location = 4) out vec4 outEmissive;
|
||||
layout(location = 5) out vec4 outTranslucency;
|
||||
layout(location = 6) out vec4 outOpacity;
|
||||
layout(location = 7) out vec4 outViewPos;
|
||||
|
||||
struct Material {
|
||||
vec4 diffuseColor; //16
|
||||
|
|
@ -36,6 +38,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||
Material materials[];
|
||||
|
|
@ -62,6 +68,9 @@ void main()
|
|||
{
|
||||
outPos = inPos;
|
||||
|
||||
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
|
|
@ -95,7 +104,7 @@ void main()
|
|||
|
||||
mat3 TBN = mat3(inTangent, inBitangent, inNormal);
|
||||
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
|
||||
outNormal = vec4(newNormal, 1.0f);
|
||||
|
||||
|
||||
float ao = 0.5f;
|
||||
float roughnessFactor = 0.0f;
|
||||
|
|
@ -121,6 +130,9 @@ void main()
|
|||
}
|
||||
outTranslucency = Translucency;
|
||||
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f);
|
||||
float Refractiveness = material.refractiveness;
|
||||
float Reflectiveness = material.reflectiveness;
|
||||
|
||||
outNormal = vec4(newNormal, Refractiveness);
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -8,8 +8,10 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 0) out vec4 outAlbedo;
|
||||
layout(location = 1) out vec4 outViewPos;
|
||||
|
||||
struct Material {
|
||||
vec4 diffuseColor; //16
|
||||
|
|
@ -30,6 +32,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
|
||||
|
|
@ -44,6 +50,9 @@ layout(push_constant) uniform pc{
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 viewPos = vec4(viewMatrix * inPos);
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 1) out vec4 outAlbedo ;
|
||||
layout(location = 0) out vec4 outPos;
|
||||
|
|
@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR;
|
|||
layout(location = 4) out vec4 outEmissive;
|
||||
layout(location = 5) out vec4 outTranslucency;
|
||||
layout(location = 6) out vec4 outOpacity;
|
||||
layout(location = 7) out vec4 outViewPos;
|
||||
|
||||
const float bayerMatrix[16] = float[](
|
||||
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
|
||||
|
|
@ -42,6 +44,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||
Material materials[];
|
||||
|
|
@ -68,6 +74,9 @@ void main()
|
|||
{
|
||||
outPos = inPos;
|
||||
|
||||
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
|
|
@ -84,11 +93,6 @@ void main()
|
|||
} else {
|
||||
outAlbedo = material.diffuseColor;
|
||||
}
|
||||
/*int Intensity = 4;
|
||||
int x = int(gl_FragCoord.x) % Intensity;
|
||||
int y = int(gl_FragCoord.y) % Intensity;
|
||||
float threshold = bayerMatrix[y * Intensity + x];
|
||||
if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/
|
||||
|
||||
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
|
||||
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
|
||||
|
|
@ -102,12 +106,11 @@ void main()
|
|||
|
||||
outAlbedo = vec4(outAlbedo.rgb, opacityf);
|
||||
|
||||
if(outAlbedo.a < 0.75) discard;
|
||||
|
||||
if(outAlbedo.a < 0.9) discard;
|
||||
|
||||
mat3 TBN = mat3(inTangent, inBitangent, inNormal);
|
||||
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
|
||||
outNormal = vec4(newNormal, outAlbedo.a);
|
||||
|
||||
|
||||
float ao = 0.5f;
|
||||
float roughnessFactor = 0.0f;
|
||||
|
|
@ -133,6 +136,9 @@ void main()
|
|||
}
|
||||
outTranslucency = Translucency;
|
||||
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
|
||||
float Refractiveness = material.refractiveness;
|
||||
float Reflectiveness = material.reflectiveness;
|
||||
|
||||
outNormal = vec4(newNormal, Refractiveness);
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 0) out vec4 outAlbedo;
|
||||
layout(location = 1) out vec4 outViewPos;
|
||||
|
||||
struct Material {
|
||||
vec4 diffuseColor; //16
|
||||
|
|
@ -29,6 +31,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
|
||||
Material materials[];
|
||||
|
|
@ -42,6 +48,10 @@ layout(push_constant) uniform pc{
|
|||
|
||||
void main()
|
||||
{
|
||||
|
||||
vec4 viewPos = vec4(viewMatrix * inPos);
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal;
|
|||
layout(location = 2) in vec3 inTangent;
|
||||
layout(location = 3) in vec3 inBitangent;
|
||||
layout(location = 4) in vec2 inTextCoords;
|
||||
layout(location = 5) in mat4 viewMatrix;
|
||||
|
||||
layout(location = 1) out vec4 outAlbedo ;
|
||||
layout(location = 0) out vec4 outPos;
|
||||
|
|
@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR;
|
|||
layout(location = 4) out vec4 outEmissive;
|
||||
layout(location = 5) out vec4 outTranslucency;
|
||||
layout(location = 6) out vec4 outOpacity;
|
||||
layout(location = 7) out vec4 outViewPos;
|
||||
|
||||
const float bayerMatrix[16] = float[](
|
||||
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
|
||||
|
|
@ -43,6 +45,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||
|
|
@ -69,6 +75,10 @@ layout(push_constant) uniform pc {
|
|||
void main()
|
||||
{
|
||||
outPos = inPos;
|
||||
|
||||
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
|
||||
outViewPos = viewPos;
|
||||
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
|
|
@ -98,11 +108,11 @@ void main()
|
|||
|
||||
outAlbedo = vec4(outAlbedo.rgb, opacityf);
|
||||
|
||||
if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard;
|
||||
if(outAlbedo.a >= 0.9 || outAlbedo.a <= 0.1) discard;
|
||||
|
||||
mat3 TBN = mat3(inTangent, inBitangent, inNormal);
|
||||
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
|
||||
outNormal = vec4(newNormal, outAlbedo.a);
|
||||
|
||||
|
||||
float ao = 0.5f;
|
||||
float roughnessFactor = 0.0f;
|
||||
|
|
@ -128,6 +138,9 @@ void main()
|
|||
}
|
||||
outTranslucency = Translucency;
|
||||
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
|
||||
float Refractiveness = material.refractiveness;
|
||||
float Reflectiveness = material.reflectiveness;
|
||||
|
||||
outNormal = vec4(newNormal, Refractiveness);
|
||||
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -11,7 +11,7 @@ layout(location = 1) out vec3 outNormal;
|
|||
layout(location = 2) out vec3 outTangent;
|
||||
layout(location = 3) out vec3 outBitangent;
|
||||
layout(location = 4) out vec2 outTextCoords;
|
||||
|
||||
layout(location = 5) out mat4 viewMatrix;
|
||||
|
||||
layout(set = 0, binding = 0) uniform ProjUniform{
|
||||
mat4 matrix;
|
||||
|
|
@ -27,6 +27,7 @@ layout(push_constant) uniform pc{
|
|||
|
||||
void main()
|
||||
{
|
||||
viewMatrix = viewUniform.matrix;
|
||||
vec4 worldPos = push_constants.modelMatrix * vec4(inPos,1);
|
||||
gl_Position = projUniform.matrix * viewUniform.matrix * push_constants.modelMatrix * vec4(inPos,1);
|
||||
mat3 mNormal = transpose(inverse(mat3(push_constants.modelMatrix)));
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,128 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D albedoSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D worldPosSampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D normalSampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
|
||||
|
||||
layout(set = 1, binding = 0) uniform CameraProperties {
|
||||
mat4 projection;
|
||||
mat4 invProjection;
|
||||
mat4 view;
|
||||
mat4 invView;
|
||||
float ssrStepSize;
|
||||
float ssrMaxDistance;
|
||||
int maxSteps;
|
||||
int padding;
|
||||
vec4 cameraWorldPos;
|
||||
} ubo;
|
||||
|
||||
const float THICKNESS = 0.35;
|
||||
const float MIN_REFLECTION = 0.01;
|
||||
|
||||
float edgeFade(vec2 uv) {
|
||||
vec2 fade = smoothstep(vec2(0.0), vec2(0.08), uv) *
|
||||
smoothstep(vec2(0.0), vec2(0.08), vec2(1.0) - uv);
|
||||
return fade.x * fade.y;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 sceneColor = texture(albedoSampler, fragTexCoord);
|
||||
vec4 posSample = texture(worldPosSampler, fragTexCoord);
|
||||
vec4 normalSample = texture(normalSampler, fragTexCoord);
|
||||
vec4 pbrSample = texture(pbrSampler, fragTexCoord);
|
||||
|
||||
if (posSample.a == 0.0 || length(posSample.xyz) == 0.0 || length(normalSample.xyz) < 0.001) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 worldPos = posSample.xyz;
|
||||
vec3 worldNormal = normalize(normalSample.xyz);
|
||||
|
||||
float roughness = clamp(pbrSample.g, 0.0, 1.0);
|
||||
float metallic = clamp(pbrSample.b, 0.0, 1.0);
|
||||
float reflectiveness = clamp(pbrSample.a, 0.0, 1.0);
|
||||
float refractiveness = clamp(normalSample.a, 0.0, 2.0);
|
||||
|
||||
vec3 viewDirToCamera = normalize(ubo.cameraWorldPos.xyz - worldPos);
|
||||
float NoV = clamp(dot(worldNormal, viewDirToCamera), 0.0, 1.0);
|
||||
float fresnel = pow(1.0 - NoV, 5.0);
|
||||
|
||||
float materialReflection = reflectiveness + refractiveness - 1;
|
||||
materialReflection *= mix(0.75, 1.0, metallic);
|
||||
materialReflection *= smoothstep(0.7, 0.05, roughness);
|
||||
materialReflection *= mix(0.45, 1.0, fresnel);
|
||||
|
||||
if (materialReflection <= MIN_REFLECTION) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 viewDir = normalize(worldPos - ubo.cameraWorldPos.xyz);
|
||||
vec3 reflectDir = normalize(reflect(viewDir, worldNormal));
|
||||
|
||||
if (dot(reflectDir, worldNormal) <= 0.0) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
int steps = clamp(ubo.maxSteps, 1, 128);
|
||||
float stepSize = max(ubo.ssrStepSize, 0.01);
|
||||
float maxDistance = max(ubo.ssrMaxDistance, stepSize);
|
||||
|
||||
vec3 rayPos = worldPos;
|
||||
vec2 hitUV = vec2(0.0);
|
||||
bool hitFound = false;
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
rayPos += reflectDir * stepSize;
|
||||
|
||||
if (distance(rayPos, worldPos) > maxDistance) {
|
||||
break;
|
||||
}
|
||||
|
||||
vec4 clip = ubo.projection * ubo.view * vec4(rayPos, 1.0);
|
||||
if (clip.w <= 0.0) {
|
||||
break;
|
||||
}
|
||||
|
||||
vec2 uv = clip.xy / clip.w;
|
||||
uv = uv * 0.5 + 0.5;
|
||||
uv.y = 1.0 - uv.y;
|
||||
|
||||
if (uv.x <= 0.0 || uv.x >= 1.0 || uv.y <= 0.0 || uv.y >= 1.0) {
|
||||
break;
|
||||
}
|
||||
|
||||
vec4 surfaceWorld = texture(worldPosSampler, uv);
|
||||
if (surfaceWorld.a == 0.0 || length(surfaceWorld.xyz) == 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float rayViewZ = abs((ubo.view * vec4(rayPos, 1.0)).z);
|
||||
float surfaceViewZ = abs((ubo.view * vec4(surfaceWorld.xyz, 1.0)).z);
|
||||
|
||||
float depthDelta = rayViewZ - surfaceViewZ;
|
||||
if (depthDelta >= 0.0 && depthDelta < THICKNESS) {
|
||||
hitUV = uv;
|
||||
hitFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hitFound) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 reflectedColor = texture(albedoSampler, hitUV).rgb;
|
||||
|
||||
float fade = edgeFade(hitUV);
|
||||
float weight = clamp(materialReflection * fade, 0.0, 0.85);
|
||||
|
||||
outColor = vec4(mix(sceneColor.rgb, reflectedColor, weight), sceneColor.a);
|
||||
}
|
||||
|
|
@ -27,6 +27,10 @@ struct Material {
|
|||
uint hasOpacityMap; //88
|
||||
uint OpacityMapIdx; //92
|
||||
float OpacityFactor; //96
|
||||
float reflectiveness; //100
|
||||
float refractiveness; //104
|
||||
float Padding1; //108
|
||||
float Padding2; //112
|
||||
};
|
||||
layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||
|
|
@ -35,7 +39,21 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
|||
|
||||
void main()
|
||||
{
|
||||
|
||||
Material material = matUniform.materials[inMaterialIdx];
|
||||
|
||||
float Refractiveness = material.refractiveness;
|
||||
float Reflectiveness = material.reflectiveness;
|
||||
float Translucency = material.translucencyFactor;
|
||||
float Opacity = material.OpacityFactor;
|
||||
if(material.hasTranslucencyMap > 0){
|
||||
vec4 translucencyMap = texture(textSampler[material.translucencyMapIdx], inTextCoords);
|
||||
Translucency = (translucencyMap.x + translucencyMap.y + translucencyMap.z)/3.0;
|
||||
}
|
||||
if(material.hasOpacityMap > 0){
|
||||
vec4 opacityMap = texture(textSampler[material.OpacityMapIdx], inTextCoords);
|
||||
Opacity = (opacityMap.x + opacityMap.y + opacityMap.z)/3.0;
|
||||
}
|
||||
int textureIndex = int(material.textureIdx);
|
||||
if (textureIndex >= MAX_TEXTURES){
|
||||
outFragColor = vec2(0.0,0.0);
|
||||
|
|
@ -47,7 +65,7 @@ void main()
|
|||
} else {
|
||||
albedo = material.diffuseColor;
|
||||
}
|
||||
if (albedo.a < 0.5) {
|
||||
if (albedo.a < 0.5 || Translucency > 0.5 || Opacity < 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +73,6 @@ void main()
|
|||
float moment1 = depth;
|
||||
float moment2 = depth * depth;
|
||||
|
||||
// Adjust moments to avoid light bleeding
|
||||
float dx = dFdx(depth);
|
||||
float dy = dFdy(depth);
|
||||
moment2 += 0.25 * (dx * dx + dy * dy);
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ layout(location = 1) out vec4 outColor;
|
|||
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
|
||||
|
||||
void main() {
|
||||
outColor = texture(skyboxSampler, outTexCoords) * vec4(0.0,0.05,0.1,1);
|
||||
outColor = texture(skyboxSampler, outTexCoords);// * vec4(3,1.0,0.65,1);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -4,18 +4,42 @@ layout(location = 0) in vec2 inTextCoord;
|
|||
layout(location = 0) out float outAO;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D ssaoSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D viewPosSampler;
|
||||
|
||||
void main() {
|
||||
vec2 texelSize = 2.0 / vec2(textureSize(ssaoSampler, 0));
|
||||
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(ssaoSampler, 0));
|
||||
float result = 0.0;
|
||||
float centerAO = texture(ssaoSampler, inTextCoord).r;
|
||||
float centerDepth = texture(viewPosSampler, inTextCoord).z;
|
||||
|
||||
for (int x = -2; x <= 2; x++) {
|
||||
for (int y = -2; y <= 2; y++) {
|
||||
vec2 offset = vec2(float(x), float(y)) * texelSize;
|
||||
result += texture(ssaoSampler, vec2(inTextCoord.x,inTextCoord.y) + offset).r;
|
||||
}
|
||||
float totalAO = centerAO;
|
||||
float totalWeight = 1.0;
|
||||
|
||||
float weights[4] = float[](0.227027, 0.1216216, 0.054054, 0.016216);
|
||||
int offsets[4] = int[](-2, -1, 1, 2);
|
||||
const float Sharpness = 20.0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
vec2 offsetH = vec2(float(offsets[i]), 0.0) * texelSize;
|
||||
vec2 uvH = inTextCoord + offsetH;
|
||||
|
||||
float neighborAOH = texture(ssaoSampler, uvH).r;
|
||||
float neighborDepthH = texture(viewPosSampler, uvH).z;
|
||||
|
||||
float weightH = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthH));
|
||||
totalAO += neighborAOH * weightH;
|
||||
totalWeight += weightH;
|
||||
|
||||
vec2 offsetV = vec2(0.0, float(offsets[i])) * texelSize;
|
||||
vec2 uvV = inTextCoord + offsetV;
|
||||
|
||||
float neighborAOV = texture(ssaoSampler, uvV).r;
|
||||
float neighborDepthV = texture(viewPosSampler, uvV).z;
|
||||
|
||||
float weightV = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthV));
|
||||
totalAO += neighborAOV * weightV;
|
||||
totalWeight += weightV;
|
||||
}
|
||||
|
||||
outAO = result / 25.0;
|
||||
outAO = totalAO / totalWeight;
|
||||
}
|
||||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out float outAO;
|
||||
layout(location = 1) out vec4 viewPos;
|
||||
|
||||
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[];
|
||||
layout(set = 1, binding = 0) uniform SSAOKernel {
|
||||
vec4 samples[64];
|
||||
} kernel;
|
||||
|
||||
layout(set = 2, binding = 0) uniform SSAOInfo {
|
||||
|
|
@ -17,79 +18,75 @@ layout(set = 2, binding = 0) uniform SSAOInfo {
|
|||
vec2 screenSize; // 136
|
||||
float radius; //140
|
||||
float bias; //144
|
||||
int kernelSize; //160
|
||||
int kernelSize; //148
|
||||
float ResolutionScale; //152;
|
||||
vec2 Padding; //160;
|
||||
} ssao;
|
||||
|
||||
void main() {
|
||||
vec2 uv = inTextCoord;
|
||||
|
||||
vec3 worldPos = texture(posSampler, uv).xyz;
|
||||
vec3 worldNormal = normalize(texture(normalSampler, uv).xyz);
|
||||
vec2 ScreenSize = ssao.screenSize * ssao.ResolutionScale;
|
||||
|
||||
vec2 noiseScale = ssao.screenSize / 4.0;
|
||||
int KERNEL_SIZE = ssao.kernelSize;
|
||||
vec3 fragPos = texture(posSampler, inTextCoord).xyz;
|
||||
vec3 worldNorm = normalize(texture(normalSampler, inTextCoord).xyz);
|
||||
|
||||
if (length(worldNormal) < 0.001) {
|
||||
if (dot(worldNorm, worldNorm) < 0.001) {
|
||||
outAO = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 fragPos = vec3(ssao.view * vec4(worldPos, 1.0));
|
||||
vec3 normal = normalize(mat3(ssao.view) * worldNormal);
|
||||
vec3 normal = normalize(mat3(ssao.view) * worldNorm);
|
||||
|
||||
vec3 randomVec = normalize(texture(noiseSampler, inTextCoord * noiseScale).xyz);
|
||||
viewPos = vec4(fragPos, 1);
|
||||
|
||||
vec2 noiseScale = ScreenSize / 4.0;
|
||||
vec3 randomVec = 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 fragDepth = -fragPos.z;
|
||||
|
||||
float minOptimalDistance = 15;
|
||||
float maxKernelSize = float(ssao.kernelSize);
|
||||
|
||||
// Calculate a dynamic loop limit based on proximity
|
||||
// If closer than 1.5 units, smoothly scale down the loop count
|
||||
int dynamicKernelSize = int(KERNEL_SIZE);
|
||||
if (fragDepth < minOptimalDistance) {
|
||||
float proximityFactor = clamp(fragDepth / minOptimalDistance, 0.2, 1.0);
|
||||
dynamicKernelSize = int(maxKernelSize * proximityFactor);
|
||||
}
|
||||
|
||||
// Force a hard minimum baseline of samples so SSAO doesn't completely disappear
|
||||
dynamicKernelSize = max(dynamicKernelSize, 16);
|
||||
|
||||
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;
|
||||
float Passes = 0.0f;
|
||||
|
||||
vec4 offset = vec4(samplePos, 1.0);
|
||||
offset = ssao.projection * offset;
|
||||
for (int i = 0; i < dynamicKernelSize; i++) {
|
||||
vec3 samplePos = fragPos + (TBN * kernel.samples[i].xyz) * ssao.radius;
|
||||
vec4 offset = ssao.projection * vec4(samplePos, 1.0);
|
||||
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) {
|
||||
vec2 sampleUV = clamp(vec2(offset.x, 1.0 - offset.y), 0.0, 1.0);
|
||||
vec3 sampleViewPos = texture(posSampler, sampleUV).xyz;
|
||||
float sampleDepth = -sampleViewPos.z;
|
||||
float depthDelta = abs(fragDepth - sampleDepth);
|
||||
if (depthDelta > ssao.radius * 2.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;
|
||||
float rangeCheck = smoothstep(0.0, 1.0, ssao.radius / depthDelta);
|
||||
float isOccluded = step(samplePos.z + ssao.bias, sampleViewPos.z);
|
||||
occlusion += isOccluded * rangeCheck;
|
||||
Passes += 1.0;
|
||||
}
|
||||
|
||||
if (validSamples <= 0.0) {
|
||||
outAO = 1.0;
|
||||
return;
|
||||
float Subtraction = 0.0;
|
||||
if(Passes > 0){
|
||||
Subtraction = (occlusion / Passes);
|
||||
}
|
||||
|
||||
occlusion = 1.0 - occlusion / validSamples;
|
||||
outAO = occlusion * pow(occlusion, 3.0);
|
||||
occlusion = 1.0 - Subtraction;
|
||||
outAO = clamp(pow(occlusion, 3), 0.0, 1.0);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue