mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Fog with ARB_fragment_shader_interlock: quick and dirty prototype
a prototype of #817
This commit is contained in:
parent
c495e8406c
commit
b85681573b
@ -44,7 +44,7 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
|
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
|
||||||
float fogFactor = exp(fogDistance);
|
float fogFactor = exp(-fogDistance);
|
||||||
inColor *= fogFactor;
|
inColor *= fogFactor;
|
||||||
inColor += fogColor;
|
inColor += fogColor;
|
||||||
inColor -= fogColor*fogFactor;
|
inColor -= fogColor*fogFactor;
|
||||||
@ -54,7 +54,7 @@ vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
|
|||||||
vec3 fetch(ivec2 pos) {
|
vec3 fetch(ivec2 pos) {
|
||||||
vec4 rgba = texelFetch(color, pos, 0);
|
vec4 rgba = texelFetch(color, pos, 0);
|
||||||
float densityAdjustment = sqrt(dot(tanXY*(normalizedTexCoords*2 - 1), tanXY*(normalizedTexCoords*2 - 1)) + 1);
|
float densityAdjustment = sqrt(dot(tanXY*(normalizedTexCoords*2 - 1), tanXY*(normalizedTexCoords*2 - 1)) + 1);
|
||||||
float fogDistance = calculateFogDistance(texelFetch(depthTexture, pos, 0).r, fog.density*densityAdjustment);
|
float fogDistance = texelFetch(depthTexture, pos, 0).r*fog.density*densityAdjustment;
|
||||||
vec3 fogColor = fog.color;
|
vec3 fogColor = fog.color;
|
||||||
rgba.rgb = applyFrontfaceFog(fogDistance, fog.color, rgba.rgb);
|
rgba.rgb = applyFrontfaceFog(fogDistance, fog.color, rgba.rgb);
|
||||||
return rgba.rgb/rgba.a;
|
return rgba.rgb/rgba.a;
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#version 430
|
#version 430
|
||||||
|
|
||||||
|
#extension GL_ARB_fragment_shader_interlock : require
|
||||||
|
layout(sample_interlock_ordered) in;
|
||||||
|
layout(early_fragment_tests) in;
|
||||||
|
|
||||||
in vec3 mvVertexPos;
|
in vec3 mvVertexPos;
|
||||||
in vec3 direction;
|
in vec3 direction;
|
||||||
in vec3 light;
|
in vec3 light;
|
||||||
@ -16,7 +20,7 @@ uniform samplerCube reflectionMap;
|
|||||||
uniform float reflectionMapSize;
|
uniform float reflectionMapSize;
|
||||||
uniform float contrast;
|
uniform float contrast;
|
||||||
|
|
||||||
layout(binding = 5) uniform sampler2D depthTexture;
|
layout(binding = 5, r16f) coherent uniform image2D depthTexture;
|
||||||
|
|
||||||
layout (location = 0, index = 0) out vec4 fragColor;
|
layout (location = 0, index = 0) out vec4 fragColor;
|
||||||
layout (location = 0, index = 1) out vec4 blendColor;
|
layout (location = 0, index = 1) out vec4 blendColor;
|
||||||
@ -91,9 +95,9 @@ void applyFrontfaceFog(float fogDistance, vec3 fogColor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void applyBackfaceFog(float fogDistance, vec3 fogColor) {
|
void applyBackfaceFog(float fogDistance, vec3 fogColor) {
|
||||||
float fogFactor = exp(-fogDistance);
|
//float fogFactor = exp(-fogDistance);
|
||||||
fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
|
//fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
|
||||||
fragColor.a *= fogFactor;
|
//fragColor.a *= fogFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
|
vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
|
||||||
@ -106,13 +110,17 @@ vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
beginInvocationInterlockARB();
|
||||||
|
float prevDepth = imageLoad(depthTexture, ivec2(gl_FragCoord.xy)).r;
|
||||||
|
imageStore(depthTexture, ivec2(gl_FragCoord.xy), vec4(abs(mvVertexPos.y), 0, 0, 0));
|
||||||
|
endInvocationInterlockARB();
|
||||||
float animatedTextureIndex = animatedTexture[textureIndex];
|
float animatedTextureIndex = animatedTexture[textureIndex];
|
||||||
vec3 textureCoords = vec3(uv, animatedTextureIndex);
|
vec3 textureCoords = vec3(uv, animatedTextureIndex);
|
||||||
float normalVariation = lightVariation(normal);
|
float normalVariation = lightVariation(normal);
|
||||||
float densityAdjustment = sqrt(dot(mvVertexPos, mvVertexPos))/abs(mvVertexPos.y);
|
float densityAdjustment = sqrt(dot(mvVertexPos, mvVertexPos))/abs(mvVertexPos.y);
|
||||||
float dist = zFromDepth(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r);
|
float dist = abs(mvVertexPos.y) - prevDepth;//zFromDepth(texelFetch(depthTexture1, ivec2(gl_FragCoord.xy), 0).r);
|
||||||
float fogDistance = calculateFogDistance(dist, fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment);
|
float fogDistance = dist*fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment;
|
||||||
float airFogDistance = calculateFogDistance(dist, fog.density*densityAdjustment);
|
float airFogDistance = dist*fog.density*densityAdjustment;
|
||||||
vec3 fogColor = unpackColor(fogData[int(animatedTextureIndex)].fogColor);
|
vec3 fogColor = unpackColor(fogData[int(animatedTextureIndex)].fogColor);
|
||||||
vec3 pixelLight = max(light*normalVariation, texture(emissionSampler, textureCoords).r*4);
|
vec3 pixelLight = max(light*normalVariation, texture(emissionSampler, textureCoords).r*4);
|
||||||
vec4 textureColor = texture(texture_sampler, textureCoords)*vec4(pixelLight, 1);
|
vec4 textureColor = texture(texture_sampler, textureCoords)*vec4(pixelLight, 1);
|
||||||
|
@ -43,7 +43,7 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
|
vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
|
||||||
float fogFactor = exp(fogDistance);
|
float fogFactor = exp(-fogDistance);
|
||||||
inColor *= fogFactor;
|
inColor *= fogFactor;
|
||||||
inColor += fogColor;
|
inColor += fogColor;
|
||||||
inColor -= fogColor*fogFactor;
|
inColor -= fogColor*fogFactor;
|
||||||
@ -54,7 +54,7 @@ void main() {
|
|||||||
fragColor = texture(color, texCoords);
|
fragColor = texture(color, texCoords);
|
||||||
fragColor += texture(bloomColor, texCoords);
|
fragColor += texture(bloomColor, texCoords);
|
||||||
float densityAdjustment = sqrt(dot(tanXY*(texCoords*2 - 1), tanXY*(texCoords*2 - 1)) + 1);
|
float densityAdjustment = sqrt(dot(tanXY*(texCoords*2 - 1), tanXY*(texCoords*2 - 1)) + 1);
|
||||||
float fogDistance = calculateFogDistance(texture(depthTexture, texCoords).r, fog.density*densityAdjustment);
|
float fogDistance = texture(depthTexture, texCoords).r*fog.density*densityAdjustment;
|
||||||
fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb);
|
fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb);
|
||||||
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
|
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
|
||||||
fragColor.rgb = fragColor.rgb/maxColor;
|
fragColor.rgb = fragColor.rgb/maxColor;
|
||||||
|
16
assets/cubyz/shaders/depth_copy.fs
Normal file
16
assets/cubyz/shaders/depth_copy.fs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#version 430
|
||||||
|
out vec4 fragColor;
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
|
||||||
|
layout(binding = 5) uniform sampler2D depthBuffer;
|
||||||
|
|
||||||
|
float zFromDepth(float depthBufferValue) {
|
||||||
|
return zNear*zFar/(depthBufferValue*(zNear - zFar) + zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragColor.r = zFromDepth(texture(depthBuffer, texCoords).r);
|
||||||
|
}
|
10
assets/cubyz/shaders/depth_copy.vs
Normal file
10
assets/cubyz/shaders/depth_copy.vs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location=0) in vec2 inTexCoords;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texCoords = inTexCoords;
|
||||||
|
gl_Position = vec4(inTexCoords*2 - vec2(1, 1), 0, 1);
|
||||||
|
}
|
@ -1565,6 +1565,10 @@ pub const FrameBuffer = struct { // MARK: FrameBuffer
|
|||||||
c.glBindTexture(c.GL_TEXTURE_2D, self.texture);
|
c.glBindTexture(c.GL_TEXTURE_2D, self.texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bindImage(self: *const FrameBuffer, binding: u5, format: c_uint) void {
|
||||||
|
c.glBindImageTexture(binding, self.texture, 0, c.GL_FALSE, 0, c.GL_READ_WRITE, format);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bindDepthTexture(self: *const FrameBuffer, target: c_uint) void {
|
pub fn bindDepthTexture(self: *const FrameBuffer, target: c_uint) void {
|
||||||
std.debug.assert(self.hasDepthTexture);
|
std.debug.assert(self.hasDepthTexture);
|
||||||
c.glActiveTexture(target);
|
c.glActiveTexture(target);
|
||||||
|
@ -43,6 +43,11 @@ var deferredUniforms: struct {
|
|||||||
zNear: c_int,
|
zNear: c_int,
|
||||||
zFar: c_int,
|
zFar: c_int,
|
||||||
} = undefined;
|
} = undefined;
|
||||||
|
var depthCopyShader: graphics.Shader = undefined;
|
||||||
|
var depthCopyUniforms: struct {
|
||||||
|
zNear: c_int,
|
||||||
|
zFar: c_int,
|
||||||
|
} = undefined;
|
||||||
var fakeReflectionShader: graphics.Shader = undefined;
|
var fakeReflectionShader: graphics.Shader = undefined;
|
||||||
var fakeReflectionUniforms: struct {
|
var fakeReflectionUniforms: struct {
|
||||||
normalVector: c_int,
|
normalVector: c_int,
|
||||||
@ -60,8 +65,11 @@ var reflectionCubeMap: graphics.CubeMapTexture = undefined;
|
|||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
deferredRenderPassShader = Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", "", &deferredUniforms);
|
deferredRenderPassShader = Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", "", &deferredUniforms);
|
||||||
fakeReflectionShader = Shader.initAndGetUniforms("assets/cubyz/shaders/fake_reflection.vs", "assets/cubyz/shaders/fake_reflection.fs", "", &fakeReflectionUniforms);
|
fakeReflectionShader = Shader.initAndGetUniforms("assets/cubyz/shaders/fake_reflection.vs", "assets/cubyz/shaders/fake_reflection.fs", "", &fakeReflectionUniforms);
|
||||||
|
depthCopyShader = Shader.initAndGetUniforms("assets/cubyz/shaders/depth_copy.vs", "assets/cubyz/shaders/depth_copy.fs", "", &depthCopyUniforms);
|
||||||
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
|
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
|
||||||
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGB16F);
|
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGB16F);
|
||||||
|
transparentDepthFrameBuffer.init(false, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
|
||||||
|
transparentDepthFrameBuffer.updateSize(Window.width, Window.height, c.GL_R16F);
|
||||||
Bloom.init();
|
Bloom.init();
|
||||||
MeshSelection.init();
|
MeshSelection.init();
|
||||||
MenuBackGround.init() catch |err| {
|
MenuBackGround.init() catch |err| {
|
||||||
@ -78,6 +86,7 @@ pub fn deinit() void {
|
|||||||
deferredRenderPassShader.deinit();
|
deferredRenderPassShader.deinit();
|
||||||
fakeReflectionShader.deinit();
|
fakeReflectionShader.deinit();
|
||||||
worldFrameBuffer.deinit();
|
worldFrameBuffer.deinit();
|
||||||
|
transparentDepthFrameBuffer.deinit();
|
||||||
Bloom.deinit();
|
Bloom.deinit();
|
||||||
MeshSelection.deinit();
|
MeshSelection.deinit();
|
||||||
MenuBackGround.deinit();
|
MenuBackGround.deinit();
|
||||||
@ -108,6 +117,7 @@ fn initReflectionCubeMap() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var worldFrameBuffer: graphics.FrameBuffer = undefined;
|
var worldFrameBuffer: graphics.FrameBuffer = undefined;
|
||||||
|
var transparentDepthFrameBuffer: graphics.FrameBuffer = undefined;
|
||||||
|
|
||||||
var lastWidth: u31 = 0;
|
var lastWidth: u31 = 0;
|
||||||
var lastHeight: u31 = 0;
|
var lastHeight: u31 = 0;
|
||||||
@ -119,6 +129,8 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void {
|
|||||||
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(fov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar);
|
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(fov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar);
|
||||||
worldFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_RGB16F);
|
worldFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_RGB16F);
|
||||||
worldFrameBuffer.unbind();
|
worldFrameBuffer.unbind();
|
||||||
|
transparentDepthFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_R16F);
|
||||||
|
transparentDepthFrameBuffer.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(playerPosition: Vec3d) void {
|
pub fn render(playerPosition: Vec3d) void {
|
||||||
@ -221,9 +233,27 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
|
|||||||
gpu_performance_measuring.stopQuery();
|
gpu_performance_measuring.stopQuery();
|
||||||
|
|
||||||
// Render transparent chunk meshes:
|
// Render transparent chunk meshes:
|
||||||
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5);
|
|
||||||
|
|
||||||
gpu_performance_measuring.startQuery(.transparent_rendering_preparation);
|
gpu_performance_measuring.startQuery(.transparent_rendering_preparation);
|
||||||
|
|
||||||
|
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5);
|
||||||
|
c.glTextureBarrier();
|
||||||
|
transparentDepthFrameBuffer.bind();
|
||||||
|
depthCopyShader.bind();
|
||||||
|
c.glUniform1f(depthCopyUniforms.zNear, zNear);
|
||||||
|
c.glUniform1f(depthCopyUniforms.zFar, zFar);
|
||||||
|
c.glDisable(c.GL_DEPTH_TEST);
|
||||||
|
c.glDisable(c.GL_CULL_FACE);
|
||||||
|
c.glDisable(c.GL_BLEND);
|
||||||
|
c.glBindVertexArray(graphics.draw.rectVAO);
|
||||||
|
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
c.glEnable(c.GL_BLEND);
|
||||||
|
c.glEnable(c.GL_DEPTH_TEST);
|
||||||
|
c.glEnable(c.GL_CULL_FACE);
|
||||||
|
worldFrameBuffer.bind();
|
||||||
|
transparentDepthFrameBuffer.bindImage(5, c.GL_R16F);
|
||||||
|
c.glMemoryBarrier(c.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||||
c.glTextureBarrier();
|
c.glTextureBarrier();
|
||||||
|
|
||||||
c.glBlendEquation(c.GL_FUNC_ADD);
|
c.glBlendEquation(c.GL_FUNC_ADD);
|
||||||
@ -260,7 +290,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
|
|||||||
gpu_performance_measuring.startQuery(.final_copy);
|
gpu_performance_measuring.startQuery(.final_copy);
|
||||||
if(activeFrameBuffer == 0) c.glViewport(0, 0, main.Window.width, main.Window.height);
|
if(activeFrameBuffer == 0) c.glViewport(0, 0, main.Window.width, main.Window.height);
|
||||||
worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
|
worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
|
||||||
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE4);
|
transparentDepthFrameBuffer.bindTexture(c.GL_TEXTURE4);
|
||||||
worldFrameBuffer.unbind();
|
worldFrameBuffer.unbind();
|
||||||
deferredRenderPassShader.bind();
|
deferredRenderPassShader.bind();
|
||||||
c.glUniform1i(deferredUniforms.color, 3);
|
c.glUniform1i(deferredUniforms.color, 3);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user