Jarvis, Optimise my shit
This commit is contained in:
parent
d1abde919d
commit
9424b29d0a
50 changed files with 1469 additions and 1232 deletions
29
resources/EngineResources/shaders/bloom_extract_frag.glsl
Normal file
29
resources/EngineResources/shaders/bloom_extract_frag.glsl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outBloomColour;
|
||||
layout(set = 0, binding = 0) uniform sampler2D inputTexture;
|
||||
|
||||
layout(push_constant) uniform PassConfig {
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec2 bloomSize;
|
||||
} config;
|
||||
|
||||
vec3 extractBloom(vec2 uv) {
|
||||
vec3 color = max(texture(inputTexture, uv).rgb, vec3(0.0));
|
||||
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
float contribution = max(brightness - 1.0, 0.0);
|
||||
return color * (contribution / (contribution + 0.5));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 offset = 0.25 / config.bloomSize;
|
||||
vec3 bloom = extractBloom(inTextCoord + vec2(-offset.x, -offset.y))
|
||||
+ extractBloom(inTextCoord + vec2( offset.x, -offset.y))
|
||||
+ extractBloom(inTextCoord + vec2(-offset.x, offset.y))
|
||||
+ extractBloom(inTextCoord + vec2( offset.x, offset.y));
|
||||
outBloomColour = vec4(bloom * 0.25, 1.0);
|
||||
}
|
||||
|
|
@ -1,61 +1,30 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
layout(location = 0) in vec2 TexCoords;
|
||||
layout(set = 0, binding = 0) uniform sampler2D bloomImage;
|
||||
|
||||
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;
|
||||
layout(push_constant) uniform PassConfig {
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec3 padding;
|
||||
vec2 bloomSize;
|
||||
} config;
|
||||
|
||||
const float weight[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
|
||||
|
||||
|
||||
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));
|
||||
vec3 safeBloomSample(vec2 uv) {
|
||||
return max(texture(bloomImage, uv).rgb, vec3(0.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));
|
||||
void main() {
|
||||
vec2 tex_offset = config.blur_radius / vec2(textureSize(bloomImage, 0));
|
||||
vec2 direction = config.horizontal != 0 ? vec2(tex_offset.x, 0.0) : vec2(0.0, tex_offset.y);
|
||||
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];
|
||||
}
|
||||
for (int i = 1; i < 5; i++) {
|
||||
result += safeBloomSample(TexCoords + direction * i) * weight[i];
|
||||
result += safeBloomSample(TexCoords - direction * i) * 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,9 +68,12 @@ float chebyshevUpperBound(vec2 moments, float t) {
|
|||
return p_max;
|
||||
}
|
||||
|
||||
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias, vec2 texelSize) {
|
||||
float calcVisibility(vec4 worldPosition, uint cascadeIndex, vec2 texelSize) {
|
||||
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
|
||||
|
||||
if (!(shadowMapPosition.w > 0.0) || any(isnan(shadowMapPosition)) || any(isinf(shadowMapPosition))) {
|
||||
return 1.0;
|
||||
}
|
||||
shadowMapPosition.xyz /= shadowMapPosition.w;
|
||||
|
||||
vec2 uv = vec2(
|
||||
|
|
@ -82,17 +85,27 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias, ve
|
|||
|
||||
if (uv.x < 0.0 || uv.x > 1.0 ||
|
||||
uv.y < 0.0 || uv.y > 1.0 ||
|
||||
depth < ShadowBias || depth > 1.0) {
|
||||
depth < 0.0 || depth > 1.0) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float shadow = 0.0;
|
||||
|
||||
// vec2 moments = texture(shadowSampler, vec3((uv), cascadeIndex)).rg;
|
||||
// float visibility = chebyshevUpperBound(moments, depth);
|
||||
// shadow += visibility;
|
||||
|
||||
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;
|
||||
vec2 sampleUV = uv + vec2(x, y) * texelSize;
|
||||
if (any(lessThan(sampleUV, vec2(0.0))) || any(greaterThan(sampleUV, vec2(1.0)))) {
|
||||
shadow += 1.0;
|
||||
continue;
|
||||
}
|
||||
sampleUV = clamp(sampleUV, texelSize * 0.5, vec2(1.0) - texelSize * 0.5);
|
||||
vec2 moments = texture(shadowSampler, vec3(sampleUV, cascadeIndex)).rg;
|
||||
float visibility = chebyshevUpperBound(moments, depth);
|
||||
shadow += visibility;
|
||||
}
|
||||
|
|
@ -212,8 +225,6 @@ void main() {
|
|||
// outFragColor = vec4(emissive,1);
|
||||
// return;
|
||||
|
||||
float ShadowBias = 0.05f;
|
||||
|
||||
float opacityf = Opacity.x + Opacity.y + Opacity.z;
|
||||
opacityf = opacityf/3.0;
|
||||
|
||||
|
|
@ -228,18 +239,21 @@ void main() {
|
|||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
uint cascadeIndex = 0;
|
||||
vec4 viewPos = sceneInfo.viewMatrix * worldPosW;
|
||||
for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) {
|
||||
if (viewPos.z < shadows.cascadeshadows[i].splitDistance.x) {
|
||||
cascadeIndex = i + 1;
|
||||
uint cascadeIndex = SHADOW_MAP_CASCADE_COUNT;
|
||||
vec4 viewPos = sceneInfo.viewMatrix * vec4(worldPos, 1.0);
|
||||
float lastSplit = shadows.cascadeshadows[SHADOW_MAP_CASCADE_COUNT - 1].splitDistance.x;
|
||||
float shadow = 1.0;
|
||||
if (lastSplit < 0.0 && viewPos.z < 0.0 && viewPos.z >= lastSplit) {
|
||||
cascadeIndex = 0;
|
||||
for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) {
|
||||
if (viewPos.z < shadows.cascadeshadows[i].splitDistance.x) {
|
||||
cascadeIndex = i + 1;
|
||||
}
|
||||
}
|
||||
vec2 texelSizeShadow = 1.0 / textureSize(shadowSampler, 0).rg;
|
||||
shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex, texelSizeShadow);
|
||||
}
|
||||
|
||||
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++) {
|
||||
Light light = lights.lights[i];
|
||||
|
|
@ -254,7 +268,7 @@ void main() {
|
|||
outFragColor = vec4(Lo + ambient, 1.0f);
|
||||
outFragColor = vec4(outFragColor.xyz/2 + (outFragColor.xyz/2) * vec3(ssao,ssao,ssao),1);
|
||||
|
||||
if (DEBUG_SHADOWS == 1) {
|
||||
if (DEBUG_SHADOWS == 1 && cascadeIndex < SHADOW_MAP_CASCADE_COUNT) {
|
||||
switch (cascadeIndex) {
|
||||
case 0:
|
||||
outFragColor.rgb *= vec3(1.0f, 0.25f, 0.25f);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outBloomColour;
|
||||
layout(set = 0, binding = 0) uniform sampler2DMS inputTexture;
|
||||
|
||||
layout(push_constant) uniform PassConfig {
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec2 bloomSize;
|
||||
} config;
|
||||
|
||||
vec3 extractBloom(vec2 uv) {
|
||||
ivec2 size = textureSize(inputTexture);
|
||||
ivec2 pixel = clamp(ivec2(uv * vec2(size)), ivec2(0), size - 1);
|
||||
int samples = textureSamples(inputTexture);
|
||||
vec3 color = vec3(0.0);
|
||||
for (int i = 0; i < samples; i++) color += texelFetch(inputTexture, pixel, i).rgb;
|
||||
color = max(color / float(samples), vec3(0.0));
|
||||
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
float contribution = max(brightness - 1.0, 0.0);
|
||||
return color * (contribution / (contribution + 0.5));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 offset = 0.25 / config.bloomSize;
|
||||
vec3 bloom = extractBloom(inTextCoord + vec2(-offset.x, -offset.y))
|
||||
+ extractBloom(inTextCoord + vec2( offset.x, -offset.y))
|
||||
+ extractBloom(inTextCoord + vec2(-offset.x, offset.y))
|
||||
+ extractBloom(inTextCoord + vec2( offset.x, offset.y));
|
||||
outBloomColour = vec4(bloom * 0.25, 1.0);
|
||||
}
|
||||
|
|
@ -1,72 +1,42 @@
|
|||
#version 450
|
||||
|
||||
layout(constant_id = 0) const int USE_AA = 0;
|
||||
|
||||
const float GAMMA_CONST = 0.4545;
|
||||
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 sampler2DMS inputTexture;
|
||||
layout(set = 0, binding = 1) uniform sampler2D bloomImage;
|
||||
|
||||
layout(set = 1, binding = 0) uniform ScreenSize{
|
||||
vec2 size;
|
||||
} screenSize;
|
||||
layout(push_constant) uniform PassConfig {
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec2 bloomSize;
|
||||
} config;
|
||||
|
||||
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 msaa(int sampleCount, sampler2DMS textureIn, vec2 TextCoord) {
|
||||
ivec2 size = textureSize(textureIn);
|
||||
ivec2 pixelCoords = clamp(ivec2(TextCoord * vec2(size)), ivec2(0), size - 1);
|
||||
vec4 colorSum = vec4(0.0);
|
||||
|
||||
for(int i = 0; i < sampleCount; ++i) {
|
||||
vec4 sampleColor = texelFetch(textureIn, pixelCoords, i);
|
||||
colorSum += sampleColor;
|
||||
}
|
||||
for (int i = 0; i < sampleCount; i++) colorSum += texelFetch(textureIn, pixelCoords, i);
|
||||
return colorSum / float(sampleCount);
|
||||
}
|
||||
|
||||
void main(){
|
||||
ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture));
|
||||
vec3 bloomAt(ivec2 pixel, ivec2 size) {
|
||||
return texelFetch(bloomImage, clamp(pixel, ivec2(0), size - 1), 0).rgb;
|
||||
}
|
||||
|
||||
outFragColor = texelFetch(inputTexture, pixelCoords, 0);
|
||||
vec3 upsampleBloom(vec2 uv) {
|
||||
ivec2 size = textureSize(bloomImage, 0);
|
||||
vec2 pixel = uv * vec2(size) - 0.5;
|
||||
ivec2 base = ivec2(floor(pixel));
|
||||
vec2 blend = fract(pixel);
|
||||
return mix(mix(bloomAt(base, size), bloomAt(base + ivec2(1, 0), size), blend.x),
|
||||
mix(bloomAt(base + ivec2(0, 1), size), bloomAt(base + ivec2(1, 1), size), blend.x), blend.y);
|
||||
}
|
||||
|
||||
if(USE_AA == 0){
|
||||
outFragColor = texelFetch(inputTexture,pixelCoords,0);
|
||||
}
|
||||
if(USE_AA == 1){
|
||||
outFragColor = texelFetch(inputTexture,pixelCoords,0);
|
||||
}
|
||||
if(USE_AA == 2){
|
||||
outFragColor = msaa(2,inputTexture,inTextCoord);
|
||||
}
|
||||
if(USE_AA == 3){
|
||||
outFragColor = msaa(4,inputTexture,inTextCoord);
|
||||
}
|
||||
if(USE_AA == 4){
|
||||
outFragColor = msaa(8,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);
|
||||
}
|
||||
void main() {
|
||||
vec4 sceneColor = msaa(textureSamples(inputTexture), inputTexture, inTextCoord);
|
||||
vec3 hdrColour = max(sceneColor.rgb + upsampleBloom(inTextCoord), vec3(0.0));
|
||||
vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure);
|
||||
outFragColor = vec4(pow(result, vec3(1.0 / config.GAMMA_CONST)), sceneColor.a);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,11 @@ void main() {
|
|||
|
||||
vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex];
|
||||
vec3 Offset = vec3(0,0,0);
|
||||
if (gl_InstanceIndex != 0) {
|
||||
uint encoded = uint(gl_InstanceIndex);
|
||||
Offset = vec3(int(encoded & 1023u) - 512, int((encoded >> 10u) & 1023u) - 512,
|
||||
int((encoded >> 20u) & 1023u) - 512) * 16.0;
|
||||
}
|
||||
vec3 worldPos = localPos + Offset + push_constants.ModelOffset.xyz * 16.0;
|
||||
|
||||
vec4 worldPosVec4 = vec4(worldPos, 1.0);
|
||||
|
|
|
|||
|
|
@ -2,36 +2,27 @@
|
|||
|
||||
layout(constant_id = 0) const int USE_AA = 0;
|
||||
|
||||
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;
|
||||
layout(set = 0, binding = 1) uniform sampler2D bloomImage;
|
||||
|
||||
layout(set = 1, binding = 0) uniform ScreenSize{
|
||||
vec2 size;
|
||||
} 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;
|
||||
}
|
||||
layout(push_constant) uniform PassConfig {
|
||||
int horizontal;
|
||||
float GAMMA_CONST;
|
||||
float Exposure;
|
||||
float blur_radius;
|
||||
vec2 bloomSize;
|
||||
} config;
|
||||
|
||||
// Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa
|
||||
vec4 fxaa(sampler2D tex, vec2 uv) {
|
||||
vec2 u_texel = 1.0 / screenSize.size;
|
||||
vec2 u_texel = 1.0 / vec2(textureSize(inputTexture, 0));
|
||||
|
||||
//Sample center and 4 corners
|
||||
vec3 rgbCC = texture(tex, uv).rgb;
|
||||
|
|
@ -79,36 +70,22 @@ vec4 fxaa(sampler2D tex, vec2 uv) {
|
|||
return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B;
|
||||
}
|
||||
|
||||
vec3 bloomAt(ivec2 pixel, ivec2 size) {
|
||||
return texelFetch(bloomImage, clamp(pixel, ivec2(0), size - 1), 0).rgb;
|
||||
}
|
||||
|
||||
vec3 upsampleBloom(vec2 uv) {
|
||||
ivec2 size = textureSize(bloomImage, 0);
|
||||
vec2 pixel = uv * vec2(size) - 0.5;
|
||||
ivec2 base = ivec2(floor(pixel));
|
||||
vec2 blend = fract(pixel);
|
||||
return mix(mix(bloomAt(base, size), bloomAt(base + ivec2(1, 0), size), blend.x),
|
||||
mix(bloomAt(base + ivec2(0, 1), size), bloomAt(base + ivec2(1, 1), size), blend.x), blend.y);
|
||||
}
|
||||
|
||||
void main(){
|
||||
|
||||
if(USE_AA == 1){
|
||||
outFragColor = fxaa(inputTexture, inTextCoord);
|
||||
}
|
||||
else if(USE_AA == 2){
|
||||
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
else if(USE_AA == 3){
|
||||
|
||||
outFragColor = texture(inputTexture, inTextCoord);
|
||||
}
|
||||
else if(USE_AA == 4){
|
||||
|
||||
outFragColor = 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);
|
||||
vec4 sceneColor = USE_AA == 1 ? fxaa(inputTexture, inTextCoord) : texture(inputTexture, inTextCoord);
|
||||
vec3 hdrColour = max(sceneColor.rgb + upsampleBloom(inTextCoord), vec3(0.0));
|
||||
vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure);
|
||||
outFragColor = vec4(pow(result, vec3(1.0 / config.GAMMA_CONST)), sceneColor.a);
|
||||
}
|
||||
|
|
@ -10,9 +10,7 @@ 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;
|
||||
|
|
@ -30,13 +28,12 @@ float edgeFade(vec2 uv) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
vec4 sceneColor = texture(albedoSampler, fragTexCoord);
|
||||
outColor = vec4(0.0);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -54,11 +51,10 @@ void main() {
|
|||
|
||||
float materialReflection = reflectiveness + (refractiveness - 1.05);
|
||||
materialReflection *= mix(0.75, 1.0, metallic);
|
||||
materialReflection *= smoothstep(0.7, 0.05, roughness);
|
||||
materialReflection *= 1.0 - smoothstep(0.05, 0.7, roughness);
|
||||
materialReflection *= mix(0.45, 1.0, fresnel);
|
||||
|
||||
if (materialReflection <= MIN_REFLECTION) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +62,6 @@ void main() {
|
|||
vec3 reflectDir = normalize(reflect(viewDir, worldNormal));
|
||||
|
||||
if (dot(reflectDir, worldNormal) <= 0.0) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +110,6 @@ void main() {
|
|||
}
|
||||
|
||||
if (!hitFound) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -124,5 +118,5 @@ void main() {
|
|||
float fade = edgeFade(hitUV);
|
||||
float weight = clamp(materialReflection * fade, 0.0, 0.85);
|
||||
|
||||
outColor = vec4(mix(sceneColor.rgb, reflectedColor, weight), sceneColor.a);
|
||||
outColor = vec4(reflectedColor * weight, weight);
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ void main()
|
|||
} else {
|
||||
albedo = material.diffuseColor;
|
||||
}
|
||||
if (albedo.a < 0.5 || Translucency > 0.5 || Opacity < 0.5) {
|
||||
if (albedo.a < 0.5 || Translucency > 0.95 || Opacity < 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
|
@ -77,5 +77,5 @@ void main()
|
|||
float dy = dFdy(depth);
|
||||
moment2 += 0.25 * (dx * dx + dy * dy);
|
||||
|
||||
outFragColor = vec2(moment1, moment2);
|
||||
outFragColor = vec2(moment1, moment2) * (1 - Translucency);
|
||||
}
|
||||
|
|
@ -80,59 +80,11 @@ const vec3 FACE_CORNERS[8][4] = vec3[8][4](
|
|||
vec3[4](vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)) // Face 7 (cross model pane 2)
|
||||
);
|
||||
|
||||
vec3 buildFaceCornerPosition(uvec3 voxelPos, uint faceId, uint cornerIndex) {
|
||||
vec3 p = vec3(voxelPos);
|
||||
|
||||
if (faceId == 0u) {
|
||||
if (cornerIndex == 0u) return p + vec3(0.0, 1.0, 0.0);
|
||||
if (cornerIndex == 1u) return p + vec3(0.0, 1.0, 1.0);
|
||||
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0);
|
||||
return p + vec3(1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
if (faceId == 1u) {
|
||||
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
|
||||
if (cornerIndex == 1u) return p + vec3(1.0, 0.0, 0.0);
|
||||
if (cornerIndex == 2u) return p + vec3(1.0, 0.0, 1.0);
|
||||
return p + vec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
if (faceId == 2u) {
|
||||
if (cornerIndex == 0u) return p + vec3(1.0, 0.0, 0.0);
|
||||
if (cornerIndex == 1u) return p + vec3(1.0, 1.0, 0.0);
|
||||
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0);
|
||||
return p + vec3(1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
if (faceId == 3u) {
|
||||
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
|
||||
if (cornerIndex == 1u) return p + vec3(0.0, 0.0, 1.0);
|
||||
if (cornerIndex == 2u) return p + vec3(0.0, 1.0, 1.0);
|
||||
return p + vec3(0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
if (faceId == 4u) {
|
||||
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 1.0);
|
||||
if (cornerIndex == 1u) return p + vec3(1.0, 0.0, 1.0);
|
||||
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0);
|
||||
return p + vec3(0.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
|
||||
if (cornerIndex == 1u) return p + vec3(0.0, 1.0, 0.0);
|
||||
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 0.0);
|
||||
return p + vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
||||
uint triangleVertex = (uint(gl_VertexIndex))% 6u;
|
||||
uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
||||
|
||||
//uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
||||
//uint triangleVertex = uint(gl_VertexIndex) % 6u;
|
||||
//uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
||||
|
||||
uint packedFace = faces[faceRecordIndex];
|
||||
|
||||
uint voxelX = packedFace & 0xFu;
|
||||
|
|
@ -143,14 +95,6 @@ void main() {
|
|||
uint texIdxX = (packedFace >> 26u) & 0x7u;
|
||||
uint texIdxY = (packedFace >> 29u) & 0x7u;
|
||||
|
||||
// (voxelPos.x & 0xFu) |
|
||||
// ((voxelPos.y & 0xFu) << 4u) |
|
||||
// ((voxelPos.z & 0xFu) << 8u) |
|
||||
// ((faceIndex & 0x7u) << 12u) |
|
||||
// ((materialId & 0x7FFu) << 15u) |
|
||||
// ((textureIndexX & 0x7u) << 26u) |
|
||||
// ((textureIndexY & 0x7u) << 29u);
|
||||
|
||||
vec2 texID = vec2((texIdxX)/4.0,(texIdxY)/4.0);
|
||||
vec2 scalar = vec2(1.0/4.0,1.0/4.0);
|
||||
|
||||
|
|
@ -158,6 +102,11 @@ void main() {
|
|||
|
||||
vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex];
|
||||
vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0;
|
||||
if (gl_InstanceIndex != 0) {
|
||||
uint encoded = uint(gl_InstanceIndex);
|
||||
worldPos += vec3(int(encoded & 1023u) - 512, int((encoded >> 10u) & 1023u) - 512,
|
||||
int((encoded >> 20u) & 1023u) - 512) * 16.0;
|
||||
}
|
||||
|
||||
outTextCoord = CORNER_UVS_GRASS_BLOCK[faceId][cornerIndex] * scalar + texID;
|
||||
outMaterialIdx = matId;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ 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 centerAO = texture(ssaoSampler, inTextCoord).r;
|
||||
float centerDepth = texture(viewPosSampler, inTextCoord).z;
|
||||
|
|
@ -15,7 +15,7 @@ void main() {
|
|||
float totalAO = centerAO;
|
||||
float totalWeight = 1.0;
|
||||
|
||||
float weights[4] = float[](0.227027, 0.1216216, 0.054054, 0.016216);
|
||||
float weights[4] = float[](0.1216216, 0.1945946, 0.1945946, 0.1216216);
|
||||
int offsets[4] = int[](-2, -1, 1, 2);
|
||||
const float Sharpness = 20.0;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
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;
|
||||
|
|
@ -19,65 +18,52 @@ layout(set = 2, binding = 0) uniform SSAOInfo {
|
|||
float radius; //140
|
||||
float bias; //144
|
||||
int kernelSize; //148
|
||||
float ResolutionScale; //152;
|
||||
vec2 Padding; //160;
|
||||
} ssao;
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 ScreenSize = ssao.screenSize * ssao.ResolutionScale;
|
||||
|
||||
int KERNEL_SIZE = ssao.kernelSize;
|
||||
int KERNEL_SIZE = clamp(ssao.kernelSize, 1, 64);
|
||||
vec3 fragPos = texture(posSampler, inTextCoord).xyz;
|
||||
vec3 worldNorm = normalize(texture(normalSampler, inTextCoord).xyz);
|
||||
vec3 worldNorm = texture(normalSampler, inTextCoord).xyz;
|
||||
|
||||
if (dot(worldNorm, worldNorm) < 0.001) {
|
||||
if (dot(worldNorm, worldNorm) < 0.001 || fragPos.z >= 0.0) {
|
||||
outAO = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 normal = normalize(mat3(ssao.view) * worldNorm);
|
||||
|
||||
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 randomVec = texelFetch(noiseSampler, ivec2(gl_FragCoord.xy) % 4, 0).xyz;
|
||||
vec3 tangent = randomVec - normal * dot(randomVec, normal);
|
||||
if (dot(tangent, tangent) < 0.0001) {
|
||||
tangent = cross(normal, abs(normal.z) < 0.9 ? vec3(0, 0, 1) : vec3(0, 1, 0));
|
||||
}
|
||||
tangent = normalize(tangent);
|
||||
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 Passes = 0.0f;
|
||||
|
||||
for (int i = 0; i < dynamicKernelSize; i++) {
|
||||
vec3 samplePos = fragPos + (TBN * kernel.samples[i].xyz) * ssao.radius;
|
||||
for (int i = 0; i < KERNEL_SIZE; i++) {
|
||||
// Cover the complete radius distribution, even with a smaller sample budget.
|
||||
int sampleIndex = i * 64 / KERNEL_SIZE;
|
||||
vec3 samplePos = fragPos + (TBN * kernel.samples[sampleIndex].xyz) * ssao.radius;
|
||||
vec4 offset = ssao.projection * vec4(samplePos, 1.0);
|
||||
if (offset.w <= 0.0) continue;
|
||||
offset.xyz /= offset.w;
|
||||
offset.xyz = offset.xyz * 0.5 + 0.5;
|
||||
vec2 sampleUV = clamp(vec2(offset.x, 1.0 - offset.y), 0.0, 1.0);
|
||||
vec2 sampleUV = vec2(offset.x, 1.0 - offset.y);
|
||||
if (any(lessThan(sampleUV, vec2(0))) || any(greaterThan(sampleUV, vec2(1)))) continue;
|
||||
vec3 sampleViewPos = texture(posSampler, sampleUV).xyz;
|
||||
if (sampleViewPos.z >= 0.0) continue;
|
||||
float sampleDepth = -sampleViewPos.z;
|
||||
float depthDelta = abs(fragDepth - sampleDepth);
|
||||
if (depthDelta > ssao.radius * 2.0) {
|
||||
continue;
|
||||
}
|
||||
float rangeCheck = smoothstep(0.0, 1.0, ssao.radius / depthDelta);
|
||||
float rangeCheck = smoothstep(0.0, 1.0, ssao.radius / max(depthDelta, 0.0001));
|
||||
float isOccluded = step(samplePos.z + ssao.bias, sampleViewPos.z);
|
||||
occlusion += isOccluded * rangeCheck;
|
||||
Passes += 1.0;
|
||||
|
|
|
|||
34
resources/EngineResources/shaders/ssr_composite_frag.glsl
Normal file
34
resources/EngineResources/shaders/ssr_composite_frag.glsl
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D sceneSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D reflectionSampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D pbrSampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D normalSampler;
|
||||
|
||||
vec4 reflectionAt(ivec2 pixel, ivec2 size) {
|
||||
return texelFetch(reflectionSampler, clamp(pixel, ivec2(0), size - 1), 0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 sceneColor = texture(sceneSampler, fragTexCoord);
|
||||
vec4 pbr = texture(pbrSampler, fragTexCoord);
|
||||
vec4 normal = texture(normalSampler, fragTexCoord);
|
||||
float materialReflection = (pbr.a + normal.a - 1.05) * (1.0 - smoothstep(0.05, 0.7, pbr.g));
|
||||
if (dot(normal.xyz, normal.xyz) < 0.001 || materialReflection <= 0.01) {
|
||||
outColor = sceneColor;
|
||||
return;
|
||||
}
|
||||
|
||||
// The shared sampler is nearest-filtered. Upsample only premultiplied reflections.
|
||||
ivec2 size = textureSize(reflectionSampler, 0);
|
||||
vec2 pixel = fragTexCoord * vec2(size) - 0.5;
|
||||
ivec2 base = ivec2(floor(pixel));
|
||||
vec2 blend = fract(pixel);
|
||||
vec4 reflection = mix(
|
||||
mix(reflectionAt(base, size), reflectionAt(base + ivec2(1, 0), size), blend.x),
|
||||
mix(reflectionAt(base + ivec2(0, 1), size), reflectionAt(base + ivec2(1, 1), size), blend.x), blend.y);
|
||||
outColor = vec4(sceneColor.rgb * (1.0 - reflection.a) + reflection.rgb, sceneColor.a);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue