From f67d9e4e04d43ca2b768aee4183f56d28e7cccb7 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 16 May 2026 15:49:41 -0500 Subject: [PATCH] blaze3D shaders work on both GL and Vulkan --- .../core/render/EDhRenderApi.java | 12 +++ .../render/AbstractDhRenderApiDefinition.java | 2 + .../shaders/apply/blaze/frag.fsh | 23 +++++- .../shaders/fade/blaze/dh_fade.fsh | 22 +++++- .../shaders/fade/blaze/vanilla_fade.fsh | 64 ++++++++-------- .../shaders/fog/blaze/frag.fsh | 26 +++++-- .../shaders/generic/blaze/vert.vsh | 27 ------- .../shaders/ssao/blaze/frag.fsh | 76 +++++++++++++++---- 8 files changed, 166 insertions(+), 86 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/EDhRenderApi.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/EDhRenderApi.java b/core/src/main/java/com/seibel/distanthorizons/core/render/EDhRenderApi.java new file mode 100644 index 000000000..0369d6f3d --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/EDhRenderApi.java @@ -0,0 +1,12 @@ +package com.seibel.distanthorizons.core.render; + +/** + * VULKAN,
+ * OPEN_GL,
+ */ +public enum EDhRenderApi +{ + VULKAN, + OPEN_GL; + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java index 6a695b821..4738f1a2b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java @@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.jar.EPlatform; +import com.seibel.distanthorizons.core.render.EDhRenderApi; import com.seibel.distanthorizons.core.render.EDhRenderDepth; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; @@ -31,6 +32,7 @@ public abstract class AbstractDhRenderApiDefinition implements IBindable public boolean useSingleIbo() { return this.useSingleIbo; } public abstract EDhRenderDepth getRenderDepth(); + public abstract EDhRenderApi getRenderApi(); //endregion diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh index 2b0745aec..b4b16683c 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh @@ -4,6 +4,11 @@ in vec2 TexCoord; out vec4 fragColor; +layout (std140) uniform baseFragUniformBlock +{ + bool uIsVulkan; +}; + uniform sampler2D uSourceColorTexture; uniform sampler2D uSourceDepthTexture; @@ -11,11 +16,21 @@ uniform sampler2D uSourceDepthTexture; void main() { fragColor = vec4(0.0); - - // a fragment depth of "1" means the fragment wasn't drawn to, - // only update fragments that were drawn to float fragmentDepth = texture(uSourceDepthTexture, TexCoord).r; - if (fragmentDepth != 1) + + bool drawnTo; + if (uIsVulkan) + { + drawnTo = (fragmentDepth != 0.0f); + } + else + { + // a fragment depth of "1" means the fragment wasn't drawn to + drawnTo = (fragmentDepth != 1.0f); + } + + // only update fragments that were drawn to + if (drawnTo) { fragColor = texture(uSourceColorTexture, TexCoord); } diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh index 876f9869b..46fc45a26 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh @@ -11,6 +11,8 @@ layout (std140) uniform fragUniformBlock // inverted model view matrix and projection matrix mat4 uDhInvMvmProj; + + bool uIsVulkan; }; uniform sampler2D uMcColorTexture; @@ -18,16 +20,30 @@ uniform sampler2D uDhDepthTexture; uniform sampler2D uDhColorTexture; -vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) +/** + * this method is shared across several shaders, + * if updated, make sure to update the other versions as well. + */ +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) { // normalized device coordinates vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); - ndc.xyz = ndc.xyz * 2.0 - 1.0; - + if (uIsVulkan) + { + // Z already in [0,1], don't remap + ndc.xy = ndc.xy * 2.0 - 1.0; + } + else + { + // UV [0,1] -> NDC [-1,+1] + ndc.xyz = ndc.xyz * 2.0 - 1.0; + } + vec4 eyeCoord = invMvmProj * ndc; return eyeCoord.xyz / eyeCoord.w; } + /** * Used to fade out vanilla chunks so the transition * between DH and vanilla is smoother. diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh index c72b3a11b..d384688d8 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh @@ -21,42 +21,35 @@ layout (std140) uniform fragUniformBlock // inverted model view matrix and projection matrix mat4 uDhInvMvmProj; mat4 uMcInvMvmProj; + + bool uIsVulkan; }; -vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) +/** + * this method is shared across several shaders, + * if updated, make sure to update the other versions as well. + */ +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) { // normalized device coordinates - vec4 ndc = vec4( - TexCoord.x, // UV [0,1] - TexCoord.y, - fragmentDepth, // depth [0,1] - 1.0 - ); - // AKA: remap the [0,1] UV coordinates and depth value - // into the [-1,1] positions used by - // the NDC cube rendering stage - ndc.xyz = ndc.xyz * 2.0 - 1.0; - + vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); + if (uIsVulkan) + { + // Z already in [0,1], don't remap + ndc.xy = ndc.xy * 2.0 - 1.0; + } + else + { + // UV [0,1] -> NDC [-1,+1] + ndc.xyz = ndc.xyz * 2.0 - 1.0; + } + vec4 eyeCoord = invMvmProj * ndc; return eyeCoord.xyz / eyeCoord.w; } -// TODO vulkan -vec3 calcReversedZViewPosition(float fragmentDepth, mat4 invMvmProj) -{ - // Vulkan NDC: xy in [-1,+1], z already in [0,1] — don't remap z - vec4 ndc = vec4( - TexCoord.x * 2.0 - 1.0, // UV [0,1] -> NDC [-1,+1] - TexCoord.y * 2.0 - 1.0, - fragmentDepth, // no remapping needed, this depth is already in the [0,1] range - 1.0 // w=1 placeholder for matrix multiplication - ); - - vec4 eyeCoord = invMvmProj * ndc; - return eyeCoord.xyz / eyeCoord.w; -} /** * Used to fade out vanilla chunks so the transition @@ -88,19 +81,28 @@ void main() float mcFragmentDepth = texture(uMcDepthTexture, TexCoord).r; float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj); + + // we only want to fade vanilla rendered objects, not to the sky or LODs + bool isGround; + if (uIsVulkan) + { + isGround = (mcFragmentDepth > 0); + } + else + { + // a fragment depth of "1" means the fragment wasn't drawn to + isGround = (mcFragmentDepth < 1.0); + } // this is a work around to prevent MC clouds rendering behind DH clouds if (dhVertexWorldPos.y > uMaxLevelHeight) { fragColor = vec4(combinedMcDhColor.rgb, 0.0); } -// // a fragment depth of "1" means the fragment wasn't drawn to, -// // we only want to fade vanilla rendered objects, not to the sky or LODs -// else if (mcFragmentDepth < 1.0) - else if (mcFragmentDepth > 0) + else if (isGround) { // fade based on distance from the camera - vec3 mcVertexWorldPos = calcReversedZViewPosition(mcFragmentDepth, uMcInvMvmProj); + vec3 mcVertexWorldPos = calcViewPosition(mcFragmentDepth, uMcInvMvmProj); float mcFragmentDistance = length(mcVertexWorldPos.xzy); diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh index 9b0614970..a6036262a 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh @@ -40,6 +40,8 @@ layout (std140) uniform fragUniformBlock // inverted model view matrix and projection matrix mat4 uInvMvmProj; + + bool uIsVulkan; }; uniform sampler2D uDhDepthTexture; @@ -50,7 +52,7 @@ uniform sampler2D uDhDepthTexture; // method definitions // //====================// -vec3 calcViewPosition(float fragmentDepth); +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj); float getFarFogThickness(float dist); float getHeightFogThickness(float dist); @@ -84,7 +86,7 @@ void main() if (fogDebugMode == 0) { // render fog based on distance from the camera - vec3 vertexWorldPos = calcViewPosition(fragmentDepth); + vec3 vertexWorldPos = calcViewPosition(fragmentDepth, uInvMvmProj); float horizontalWorldDistance = length(vertexWorldPos.xz) * uFogScale; float worldDistance = length(vertexWorldPos.xyz) * uFogScale; @@ -132,12 +134,26 @@ void main() // helper methods // //================// -vec3 calcViewPosition(float fragmentDepth) +/** + * this method is shared across several shaders, + * if updated, make sure to update the other versions as well. + */ +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) { + // normalized device coordinates vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); - ndc.xyz = ndc.xyz * 2.0 - 1.0; + if (uIsVulkan) + { + // Z already in [0,1], don't remap + ndc.xy = ndc.xy * 2.0 - 1.0; + } + else + { + // UV [0,1] -> NDC [-1,+1] + ndc.xyz = ndc.xyz * 2.0 - 1.0; + } - vec4 eyeCoord = uInvMvmProj * ndc; + vec4 eyeCoord = invMvmProj * ndc; return eyeCoord.xyz / eyeCoord.w; } diff --git a/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh index 68931fe9a..8e69ce9f8 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh @@ -1,21 +1,5 @@ #version 330 core -//layout (location = 1) in vec4 aColor; // RGBA_FLOAT_COLOR -//layout (location = 2) in vec3 aScale; // VEC3_SCALE -//layout (location = 3) in ivec3 aTranslateChunk; // IVEC3_SCALE -//layout (location = 4) in vec3 aTranslateSubChunk; // VEC3_SCALE -//layout (location = 5) in int aMaterial; // IRIS_MATERIAL - -//uniform sampler2D /*vec4*/ uColorMap; -//uniform sampler2D /*vec3*/ uScaleMap; -//uniform sampler2D /*int*/ uTranslateChunkXMap; -//uniform sampler2D /*int*/ uTranslateChunkYMap; -//uniform sampler2D /*int*/ uTranslateChunkZMap; -//uniform sampler2D /*vec3*/ uTranslateSubChunkMap; -//uniform sampler2D /*int*/ uMaterialMap; -// -//in vec3 vPosition; - in vec3 vPosition; in vec4 aColor; // RGBA_FLOAT_COLOR in int aMaterial; // IRIS_MATERIAL @@ -52,17 +36,6 @@ void main() aScale = vec3(2); } -// vec4 aColor = texelFetch(uColorMap, ivec2(gl_InstanceID,0), 0); -// vec3 aScale = texelFetch(uScaleMap, ivec2(gl_InstanceID,0), 0).xyz; -// -// float chunkX = int(texelFetch(uTranslateChunkXMap, ivec2(gl_InstanceID,0), 0).x); -// float chunkY = int(texelFetch(uTranslateChunkYMap, ivec2(gl_InstanceID,0), 0).x); -// float chunkZ = int(texelFetch(uTranslateChunkZMap, ivec2(gl_InstanceID,0), 0).x); -// ivec3 aTranslateChunk = ivec3(chunkX, chunkY, chunkZ); -// -// vec3 aTranslateSubChunk = texelFetch(uTranslateSubChunkMap, ivec2(gl_InstanceID,0), 0).xyz; -// int aMaterial = int(texelFetch(uMaterialMap, ivec2(gl_InstanceID,0), 0).x); - // aTranslate - moves the vertex to the boxGroup's relative position // uOffset - moves the vertex to the boxGroup's world position // uCameraPos - moves the vertex into camera space diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh index b76132619..6e7f99a10 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh @@ -21,7 +21,9 @@ layout (std140) uniform fragUniformBlock float uFadeDistanceInBlocks; mat4 uInvProj; - mat4 uProj; + mat4 uProj; + + bool uIsVulkan; }; uniform sampler2D uDhDepthTexture; @@ -33,10 +35,7 @@ const float PI = 3.1415926538; const float TAU = PI * 2.0; -vec3 unproject(vec4 pos) -{ - return pos.xyz / pos.w; -} +vec3 unproject(vec4 pos) { return pos.xyz / pos.w; } float InterleavedGradientNoise(const in vec2 pixel) { @@ -44,12 +43,30 @@ float InterleavedGradientNoise(const in vec2 pixel) return fract(MAGIC.z * fract(x)); } -vec3 calcViewPosition(const in vec3 clipPos) +/** + * this method is shared across several shaders, + * if updated, make sure to update the other versions as well. + */ +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) { - vec4 viewPos = uInvProj * vec4(clipPos * 2.0 - 1.0, 1.0); - return viewPos.xyz / viewPos.w; + // normalized device coordinates + vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); + if (uIsVulkan) + { + // Z already in [0,1], don't remap + ndc.xy = ndc.xy * 2.0 - 1.0; + } + else + { + // UV [0,1] -> NDC [-1,+1] + ndc.xyz = ndc.xyz * 2.0 - 1.0; + } + + vec4 eyeCoord = invMvmProj * ndc; + return eyeCoord.xyz / eyeCoord.w; } + float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 viewNormal) { float dither = InterleavedGradientNoise(gl_FragCoord.xy); @@ -61,7 +78,8 @@ float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 float ao = 0.0; int sampleCount = 0; float radius = rStep; - for (int i = 0; i < clamp(uSampleCount, 1, SAMPLE_MAX); i++) { + for (int i = 0; i < clamp(uSampleCount, 1, SAMPLE_MAX); i++) + { vec2 offset = vec2( sin(rotatePhase), cos(rotatePhase) @@ -75,11 +93,27 @@ float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 sampleClipPos = saturate(sampleClipPos); float sampleClipDepth = textureLod(uDhDepthTexture, sampleClipPos.xy, 0.0).r; - if (sampleClipDepth >= 1.0 - EPSILON) continue; - - sampleClipPos.z = sampleClipDepth; - sampleViewPos = unproject(uInvProj * vec4(sampleClipPos * 2.0 - 1.0, 1.0)); + if (sampleClipDepth >= 1.0 - EPSILON) + { + continue; + } + if (uIsVulkan) + { + vec4 ndc = vec4( + sampleClipPos.x * 2.0 - 1.0, // UV [0,1] -> NDC [-1,+1] + sampleClipPos.y * 2.0 - 1.0, + sampleClipDepth, + 1.0 // w=1 placeholder for matrix multiplication + ); + sampleViewPos = unproject(uInvProj * ndc); + } + else + { + sampleClipPos.z = sampleClipDepth; + sampleViewPos = unproject(uInvProj * vec4(sampleClipPos * 2.0 - 1.0, 1.0)); + } + vec3 diff = sampleViewPos - viewPos; float sampleDist = length(diff); vec3 sampleNormal = diff / sampleDist; @@ -102,10 +136,20 @@ void main() float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; float occlusion = 0.0; - // Do not apply to sky - if (fragmentDepth < 1.0) + bool isGround; + if (uIsVulkan) { - vec3 viewPos = calcViewPosition(vec3(TexCoord, fragmentDepth)); + isGround = (fragmentDepth > 0.0f); + } + else + { + isGround = (fragmentDepth < 1.0f); + } + + // Do not apply to sky + if (isGround) + { + vec3 viewPos = calcViewPosition(fragmentDepth, uInvProj); // fading is done to prevent banding/noise // at super far distance