mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-02 18:57:10 -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) {
|
||||
float fogFactor = exp(fogDistance);
|
||||
float fogFactor = exp(-fogDistance);
|
||||
inColor *= fogFactor;
|
||||
inColor += fogColor;
|
||||
inColor -= fogColor*fogFactor;
|
||||
@ -54,7 +54,7 @@ vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 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);
|
||||
float fogDistance = texelFetch(depthTexture, pos, 0).r*fog.density*densityAdjustment;
|
||||
vec3 fogColor = fog.color;
|
||||
rgba.rgb = applyFrontfaceFog(fogDistance, fog.color, rgba.rgb);
|
||||
return rgba.rgb/rgba.a;
|
||||
|
@ -1,5 +1,9 @@
|
||||
#version 430
|
||||
|
||||
#extension GL_ARB_fragment_shader_interlock : require
|
||||
layout(sample_interlock_ordered) in;
|
||||
layout(early_fragment_tests) in;
|
||||
|
||||
in vec3 mvVertexPos;
|
||||
in vec3 direction;
|
||||
in vec3 light;
|
||||
@ -16,7 +20,7 @@ uniform samplerCube reflectionMap;
|
||||
uniform float reflectionMapSize;
|
||||
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 = 1) out vec4 blendColor;
|
||||
@ -91,9 +95,9 @@ void applyFrontfaceFog(float fogDistance, vec3 fogColor) {
|
||||
}
|
||||
|
||||
void applyBackfaceFog(float fogDistance, vec3 fogColor) {
|
||||
float fogFactor = exp(-fogDistance);
|
||||
fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
|
||||
fragColor.a *= fogFactor;
|
||||
//float fogFactor = exp(-fogDistance);
|
||||
//fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
|
||||
//fragColor.a *= fogFactor;
|
||||
}
|
||||
|
||||
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() {
|
||||
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];
|
||||
vec3 textureCoords = vec3(uv, animatedTextureIndex);
|
||||
float normalVariation = lightVariation(normal);
|
||||
float densityAdjustment = sqrt(dot(mvVertexPos, mvVertexPos))/abs(mvVertexPos.y);
|
||||
float dist = zFromDepth(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r);
|
||||
float fogDistance = calculateFogDistance(dist, fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment);
|
||||
float airFogDistance = calculateFogDistance(dist, fog.density*densityAdjustment);
|
||||
float dist = abs(mvVertexPos.y) - prevDepth;//zFromDepth(texelFetch(depthTexture1, ivec2(gl_FragCoord.xy), 0).r);
|
||||
float fogDistance = dist*fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment;
|
||||
float airFogDistance = dist*fog.density*densityAdjustment;
|
||||
vec3 fogColor = unpackColor(fogData[int(animatedTextureIndex)].fogColor);
|
||||
vec3 pixelLight = max(light*normalVariation, texture(emissionSampler, textureCoords).r*4);
|
||||
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) {
|
||||
float fogFactor = exp(fogDistance);
|
||||
float fogFactor = exp(-fogDistance);
|
||||
inColor *= fogFactor;
|
||||
inColor += fogColor;
|
||||
inColor -= fogColor*fogFactor;
|
||||
@ -54,7 +54,7 @@ void main() {
|
||||
fragColor = texture(color, texCoords);
|
||||
fragColor += texture(bloomColor, texCoords);
|
||||
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);
|
||||
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
std.debug.assert(self.hasDepthTexture);
|
||||
c.glActiveTexture(target);
|
||||
|
@ -43,6 +43,11 @@ var deferredUniforms: struct {
|
||||
zNear: c_int,
|
||||
zFar: c_int,
|
||||
} = undefined;
|
||||
var depthCopyShader: graphics.Shader = undefined;
|
||||
var depthCopyUniforms: struct {
|
||||
zNear: c_int,
|
||||
zFar: c_int,
|
||||
} = undefined;
|
||||
var fakeReflectionShader: graphics.Shader = undefined;
|
||||
var fakeReflectionUniforms: struct {
|
||||
normalVector: c_int,
|
||||
@ -60,8 +65,11 @@ var reflectionCubeMap: graphics.CubeMapTexture = undefined;
|
||||
pub fn init() void {
|
||||
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);
|
||||
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.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();
|
||||
MeshSelection.init();
|
||||
MenuBackGround.init() catch |err| {
|
||||
@ -78,6 +86,7 @@ pub fn deinit() void {
|
||||
deferredRenderPassShader.deinit();
|
||||
fakeReflectionShader.deinit();
|
||||
worldFrameBuffer.deinit();
|
||||
transparentDepthFrameBuffer.deinit();
|
||||
Bloom.deinit();
|
||||
MeshSelection.deinit();
|
||||
MenuBackGround.deinit();
|
||||
@ -108,6 +117,7 @@ fn initReflectionCubeMap() void {
|
||||
}
|
||||
|
||||
var worldFrameBuffer: graphics.FrameBuffer = undefined;
|
||||
var transparentDepthFrameBuffer: graphics.FrameBuffer = undefined;
|
||||
|
||||
var lastWidth: 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);
|
||||
worldFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_RGB16F);
|
||||
worldFrameBuffer.unbind();
|
||||
transparentDepthFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_R16F);
|
||||
transparentDepthFrameBuffer.unbind();
|
||||
}
|
||||
|
||||
pub fn render(playerPosition: Vec3d) void {
|
||||
@ -221,9 +233,27 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
|
||||
gpu_performance_measuring.stopQuery();
|
||||
|
||||
// Render transparent chunk meshes:
|
||||
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5);
|
||||
|
||||
|
||||
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.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);
|
||||
if(activeFrameBuffer == 0) c.glViewport(0, 0, main.Window.width, main.Window.height);
|
||||
worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
|
||||
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE4);
|
||||
transparentDepthFrameBuffer.bindTexture(c.GL_TEXTURE4);
|
||||
worldFrameBuffer.unbind();
|
||||
deferredRenderPassShader.bind();
|
||||
c.glUniform1i(deferredUniforms.color, 3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user