Rework the fog, so it doesn't need the alpha component anymore.

This also fixes #93 as a side effect
This could also theoretically improve performance due to using a smaller image format, but I couldn't measure a bit difference on my computer, it might be that my driver/hardware just pads the alpha component.
This commit is contained in:
IntegratedQuantum 2023-09-29 17:28:38 +02:00
parent cc6fb4b55a
commit 044ab3bb62
6 changed files with 43 additions and 39 deletions

View File

@ -43,22 +43,20 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
}
}
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
float fogFactor = exp(fogDistance);
inColor *= fogFactor;
inColor += fogColor;
inColor -= fogColor*fogFactor;
return inColor;
}
vec3 fetch(ivec2 pos) {
vec4 rgba = texelFetch(color, pos, 0);
float densityAdjustment = sqrt(dot(tanXY*(normalizedTexCoords*2 - 1), tanXY*(normalizedTexCoords*2 - 1)) + 1);
float fogDistance = calculateFogDistance(texelFetch(depthTexture, pos, 0).r, fog.density*densityAdjustment);
vec3 fogColor = fog.color;
float fogFactor = exp(fogDistance);
vec4 sourceColor = vec4(fogColor, 1);
sourceColor.a = 1.0/fogFactor;
sourceColor.rgb *= sourceColor.a;
sourceColor.rgb -= fogColor;
vec3 source2Color = vec3(1);
rgba = vec4(
source2Color*rgba.rgb + rgba.a*sourceColor.rgb,
rgba.a*sourceColor.a
);
if(rgba.a < 1) return vec3(0); // Prevent t-junctions from transparency from making a huge mess.
rgba.rgb = applyFrontfaceFog(fogDistance, fog.color, rgba.rgb);
return rgba.rgb/rgba.a;
}

View File

@ -105,17 +105,19 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
void applyFrontfaceFog(float fogDistance, vec3 fogColor) {
float fogFactor = exp(fogDistance);
fragColor.a = 1.0/fogFactor;
fragColor.rgb = fragColor.a*fogColor;
fragColor.rgb -= fogColor;
fragColor.rgb *= fogFactor;
fragColor.rgb += fogColor;
fragColor.rgb -= fogColor*fogFactor;
fragColor.a = fogFactor;
}
void applyBackfaceFog(float fogDistance, vec3 fogColor) {
float fogFactor = exp(fogDistance);
float oldAlpha = fragColor.a;
fragColor.a *= fogFactor;
fragColor.rgb -= oldAlpha*fogColor;
fragColor.rgb += fragColor.a*fogColor;
fragColor.rgb *= 1.0/fogFactor;
fragColor.rgb -= fogColor/fogFactor;
fragColor.rgb += fogColor;
fragColor.a *= 1.0/fogFactor;
}
vec2 getTextureCoordsNormal(vec3 voxelPosition, int textureDir) {
@ -181,7 +183,7 @@ void main() {
// Apply the texture+absorption
fragColor.rgb *= blendColor.rgb;
fragColor.rgb += textureColor.rgb*fragColor.a;
fragColor.rgb += textureColor.rgb;
// Apply the air fog:
applyBackfaceFog(airFogDistance, fog.color);
@ -193,9 +195,11 @@ void main() {
vec4 textureColor = texture(texture_sampler, vec3(getTextureCoordsNormal(startPosition/16, faceNormal), textureIndex))*vec4(ambientLight*normalVariation, 1);
blendColor.rgb = vec3(1 - textureColor.a);
fragColor.rgb *= blendColor.rgb;
fragColor.rgb += textureColor.rgb*textureColor.a*fragColor.a;
fragColor.rgb += textureColor.rgb*textureColor.a;
// Apply the block fog:
applyBackfaceFog(fogDistance, fogColor);
}
blendColor.rgb *= fragColor.a;
fragColor.a = 1;
}

View File

@ -41,22 +41,19 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
}
}
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
float fogFactor = exp(fogDistance);
inColor *= fogFactor;
inColor += fogColor;
inColor -= fogColor*fogFactor;
return inColor;
}
void main() {
fragColor = texture(color, texCoords);
float densityAdjustment = sqrt(dot(tanXY*(texCoords*2 - 1), tanXY*(texCoords*2 - 1)) + 1);
float fogDistance = calculateFogDistance(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r, fog.density*densityAdjustment);
vec3 fogColor = fog.color;
float fogFactor = exp(fogDistance);
vec4 sourceColor = vec4(fogColor, 1);
sourceColor.a = 1.0/fogFactor;
sourceColor.rgb *= sourceColor.a;
sourceColor.rgb -= fogColor;
vec3 source2Color = vec3(1);
fragColor = vec4(
source2Color*fragColor.rgb + fragColor.a*sourceColor.rgb,
fragColor.a*sourceColor.a
);
fragColor.rgb /= fragColor.a;
fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb);
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
fragColor.rgb = fragColor.rgb/maxColor;
}

View File

@ -9,7 +9,6 @@ uniform bool transparent;
void main() {
fragColor = texture(color, texCoords);
if(transparent) {
fragColor.rgb /= fragColor.a;
fragColor.a = 1;
// TODO: Remove the background color. Somehow?
}

View File

@ -1701,7 +1701,13 @@ const block_texture = struct {
depthTexture = Texture.init();
depthTexture.bind();
var data: [128*128]f32 = undefined;
@memset(&data, main.renderer.zNear/132.0);
const z: f32 = 134;
const near = main.renderer.zNear;
const far = main.renderer.zFar;
const depth = ((far + near)/(near - far)*z + 2*near*far/(near - far))/-z*0.5 + 0.5;
@memset(&data, depth);
c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_R32F, textureSize, textureSize, 0, c.GL_RED, c.GL_FLOAT, &data);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_NEAREST);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_NEAREST);
@ -1745,8 +1751,8 @@ pub fn generateBlockTexture(blockType: u16) !Texture {
main.game.camera.viewMatrix = Mat4f.rotationX(std.math.pi/4.0).mul(Mat4f.rotationY(-std.math.pi/4.0));
defer main.game.camera.viewMatrix = oldViewMatrix;
if(block.transparent()) {
c.glBlendEquationSeparate(c.GL_FUNC_ADD, c.GL_FUNC_ADD);
c.glBlendFuncSeparate(c.GL_DST_ALPHA, c.GL_SRC1_COLOR, c.GL_DST_ALPHA, c.GL_ZERO);
c.glBlendEquation(c.GL_FUNC_ADD);
c.glBlendFunc(c.GL_ONE, c.GL_SRC1_COLOR);
main.chunk.meshing.bindTransparentShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);
} else {
main.chunk.meshing.bindShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);

View File

@ -58,7 +58,7 @@ pub fn init() !void {
deferredRenderPassShader = try Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", &deferredUniforms);
fakeReflectionShader = try Shader.initAndGetUniforms("assets/cubyz/shaders/fake_reflection.vs", "assets/cubyz/shaders/fake_reflection.fs", &fakeReflectionUniforms);
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGBA16F);
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGB16F);
try Bloom.init();
try MeshSelection.init();
try MenuBackGround.init();
@ -109,7 +109,7 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void {
lastFov = fov;
c.glViewport(0, 0, width, height);
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(f32, fov), @as(f32, @floatFromInt(width))/@as(f32, @floatFromInt(height)), zNear, zFar);
worldFrameBuffer.updateSize(width, height, c.GL_RGBA16F);
worldFrameBuffer.updateSize(width, height, c.GL_RGB16F);
worldFrameBuffer.unbind();
}
@ -227,8 +227,8 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
c.glTextureBarrier();
chunk.meshing.bindTransparentShaderAndUniforms(game.projectionMatrix, ambientLight, time);
c.glBlendEquationSeparate(c.GL_FUNC_ADD, c.GL_FUNC_ADD);
c.glBlendFuncSeparate(c.GL_DST_ALPHA, c.GL_SRC1_COLOR, c.GL_DST_ALPHA, c.GL_ZERO);
c.glBlendEquation(c.GL_FUNC_ADD);
c.glBlendFunc(c.GL_ONE, c.GL_SRC1_COLOR);
c.glDepthFunc(c.GL_LEQUAL);
c.glDepthMask(c.GL_FALSE);
{