From b3bd6494ebead25360dbdeb38f2b1ed959b43126 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Aug 2024 00:02:07 +0300 Subject: [PATCH] fix black hole shader --- .../sky_renderers/black_hole_orbit.json | 35 +------ .../assets/gcyr/shaders/core/black_hole.fsh | 82 ++++++++++++---- .../assets/gcyr/shaders/core/black_hole.json | 9 +- .../assets/gcyr/shaders/core/black_hole.vsh | 6 +- .../assets/gcyr/shaders/include/utils.glsl | 94 +++++++++++++++++++ 5 files changed, 170 insertions(+), 56 deletions(-) create mode 100644 src/main/resources/assets/gcyr/shaders/include/utils.glsl diff --git a/src/main/resources/assets/gcyr/gcyr/planet_assets/sky_renderers/black_hole_orbit.json b/src/main/resources/assets/gcyr/gcyr/planet_assets/sky_renderers/black_hole_orbit.json index 6391515c..cb5a13ed 100644 --- a/src/main/resources/assets/gcyr/gcyr/planet_assets/sky_renderers/black_hole_orbit.json +++ b/src/main/resources/assets/gcyr/gcyr/planet_assets/sky_renderers/black_hole_orbit.json @@ -16,39 +16,6 @@ "horizon_angle": -90, "full_sky": true, "sky_objects": [ - { - "texture": "gcyr:textures/sky/sun.png", - "blending": true, - "render_type": "dynamic", - "scale": 30.0, - "rotation": [ - 0.0, - -90.0, - 0.0 - ] - }, - { - "texture": "gcyr:textures/sky/earth.png", - "blending": false, - "render_type": "static", - "scale": 9.0, - "rotation": [ - 30.0, - 0.0, - 0.0 - ] - }, - { - "texture": "gcyr:textures/sky/light.png", - "blending": true, - "render_type": "static", - "scale": 25.0, - "color": 8438015, - "rotation": [ - 30.0, - 0.0, - 0.0 - ] - } + ] } diff --git a/src/main/resources/assets/gcyr/shaders/core/black_hole.fsh b/src/main/resources/assets/gcyr/shaders/core/black_hole.fsh index 2def88d8..07417f14 100644 --- a/src/main/resources/assets/gcyr/shaders/core/black_hole.fsh +++ b/src/main/resources/assets/gcyr/shaders/core/black_hole.fsh @@ -1,24 +1,67 @@ -#version 150 +#version 330 -uniform sampler2D Sampler0; +#moj_import +#moj_import -uniform mat4 IViewRotMat; +uniform mat4 ProjMat; uniform mat4 ModelViewMat; +uniform vec4 ColorModulator; +uniform float FogStart; +uniform float FogEnd; +uniform vec4 FogColor; + uniform float GameTime; +uniform vec2 ScreenSize; uniform vec3 Light0_Direction; +uniform vec3 Light1_Direction; -in vec2 texCoord0; in vec3 ViewPos; +in float vertexDistance; +in vec2 texCoord0; out vec4 fragColor; - -int frameCounter = int(fract(GameTime * 1200.)); -float frameTimeCounter = fract(GameTime * 1200. * 6.); +int frameCounter = int(fract(GameTime * 1200. * 60.)); +float frameTimeCounter = GameTime * 1200.; const float PI = 3.14159265359; -float BlueNoise(const float ir){ - return fract(texelFetch(Sampler0, ivec2(gl_FragCoord.xy)%64, 0).x + ir * (frameCounter % 64)); +float near = 0.1; +float far = 1000.0; +float LinearizeDepth(float depth) +{ + float z = depth * 2.0 - 1.0; + return (near * far) / (far + near - z * (far - near)); +} + +// Inspired by Job van der Zwan’s research https://observablehq.com/@jobleonard/pseudo-blue-noise +// and NuSan’s shader https://www.shadertoy.com/view/7lV3Ry +// JavaScript version at https://observablehq.com/@fil/pseudoblue +// The x and y axes are separated for better randomness +// 1 / 307 == 0.003257328990228013 +// 1 / 499 == 0.002004008016032064 +int xmix(int x, int y) { + return int(float((x * 212281 + y * 384817) & 0x5555555) * 0.003257328990228013); +} +int ymix(int x, int y) { + return int(float((x * 484829 + y * 112279) & 0x5555555) * 0.002004008016032064); +} + +const int s = 8; + +float BlueNoise(int x, int y) { + int v = 0; + int a; + int b; + for (int i = 0; i < s; ++i) { + a = x; + b = y; + x = x >> 1; + y = y >> 1; + a = 1 & (a ^ xmix(x, y)); + b = 1 & (b ^ ymix(x, y)); + v = (v << 2) | (a + (b << 1) + 1) % 4; + } + return float(v) / float(1 << (s << 1)); } float saturate(float x){ @@ -105,7 +148,8 @@ float Calculate3DNoise(vec3 position){ vec3 b = curve(fract(position)); vec2 uv = 17.0 * p.z + p.xy + b.xy; - vec2 rg = texture(Sampler0, (uv + 0.5) / 64.0).zy; + uv = (uv + 0.5) / 64.0 * 10.; + vec2 rg = vec2(BlueNoise(int(uv.x), int(uv.y)), BlueNoise(int(p.z), int(p.x))); return mix(rg.x, rg.y, b.z); } @@ -120,7 +164,7 @@ float CalculateCloudFBM(vec3 position, vec3 shift){ float alpha = 0.5; for (int i = 0; i < octaves; i++) { - accum += alpha * Calculate3DNoise(position); + accum += alpha * 0.5 * curve(fract(position)).z; //Calculate3DNoise(position); position = (position + shift) * octScale; alpha *= octAlpha; } @@ -134,23 +178,23 @@ float pcurve(float x, float a, float b){ } void main(){ - fragColor = vec4(0.0); + fragColor = linear_fog(ColorModulator, vertexDistance, FogStart, FogEnd, FogColor); - vec3 worldPos = mat3(IViewRotMat) * ViewPos; + vec3 worldPos = getWorldMat(Light0_Direction, Light1_Direction) * ViewPos; vec3 worldDir = normalize(worldPos); const float steps = 50.0; const float rSteps = 1.0 / steps; const float stepLength = 0.2; - const float discRadius = 2.25; - const float discWidth = 3.5; - const float discInner = discRadius - discWidth * 0.5; - const float discOuter = discRadius + discWidth * 0.5; + const float discRadius = 40.; + const float discWidth = 39.5; + const float discInner = discRadius - discWidth; + const float discOuter = discRadius + discWidth; - float noise = BlueNoise(1.61803398); + float noise = 0.2343424;//BlueNoise(16398, -13398); - vec3 eye = -Light0_Direction * 8.0; + vec3 eye = Light0_Direction * 4.0; vec3 rayPos = eye + worldDir * 3.0; mat3 rotation = RotateMatrix(0.1, 0.0, -0.35); diff --git a/src/main/resources/assets/gcyr/shaders/core/black_hole.json b/src/main/resources/assets/gcyr/shaders/core/black_hole.json index 2eff9d0e..181422b0 100644 --- a/src/main/resources/assets/gcyr/shaders/core/black_hole.json +++ b/src/main/resources/assets/gcyr/shaders/core/black_hole.json @@ -10,14 +10,19 @@ "Position" ], "samplers": [ - { "name": "Sampler0" } ], "uniforms": [ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] }, { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "Light0_Direction", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } + { "name": "ScreenSize", "type": "float", "count": 2, "values": [ 0.0, 0.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] } ] } diff --git a/src/main/resources/assets/gcyr/shaders/core/black_hole.vsh b/src/main/resources/assets/gcyr/shaders/core/black_hole.vsh index 6b3a41ac..7e4daa3e 100644 --- a/src/main/resources/assets/gcyr/shaders/core/black_hole.vsh +++ b/src/main/resources/assets/gcyr/shaders/core/black_hole.vsh @@ -1,4 +1,4 @@ -#version 150 +#version 330 #moj_import @@ -6,10 +6,14 @@ in vec3 Position; uniform mat4 ProjMat; uniform mat4 ModelViewMat; +uniform int FogShape; out vec3 ViewPos; +out float vertexDistance; void main() { gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0); ViewPos = Position; + + vertexDistance = fog_distance(ModelViewMat, Position, FogShape); } diff --git a/src/main/resources/assets/gcyr/shaders/include/utils.glsl b/src/main/resources/assets/gcyr/shaders/include/utils.glsl new file mode 100644 index 00000000..fdfcf878 --- /dev/null +++ b/src/main/resources/assets/gcyr/shaders/include/utils.glsl @@ -0,0 +1,94 @@ +/* + * Created by Onnowhere (https://github.com/onnowhere) + * Utility functions for Minecraft core vertex shaders + * https://github.com/onnowhere/core_shaders/blob/master/.shader_utils/vsh_util.glsl + */ + +#define LIGHT0_DIRECTION vec3(0.2, 1.0, -0.7) // Default light 0 direction everywhere except in inventory +#define LIGHT1_DIRECTION vec3(-0.2, 1.0, 0.7) // Default light 1 direction everywhere except in nether and inventory + +/* + * Returns the FOV in degrees + * Calculates using the fact that top/near = tan(theta / 2) + */ +float getFOV(mat4 ProjMat) { + return atan(1.0, ProjMat[1][1]) * 114.591559; +} + +/* + * Returns if rendering in a GUI + * In the GUI, the value is guaranteed to be 0.0 + */ +bool isGUI(mat4 ProjMat) { + return ProjMat[2][3] == 0.0; +} + +/* + * Returns if rendering in the main menu background panorama + * Checks the far clipping plane value so this should only be used with position_tex_color + */ +bool isPanorama(mat4 ProjMat) { + float far = ProjMat[3][2] / (ProjMat[2][2] + 1); + return far < 9.99996 && far > 9.99995; +} + +/* + * Returns if rendering in the nether given light directions + * In the nether, the light directions are parallel but in opposite directions + */ +bool isNether(vec3 light0, vec3 light1) { + return light0 == -light1; +} + +/* + * Returns camera to world space matrix given light directions + * Creates matrix by comparing world space light directions to camera space light directions + */ +mat3 getWorldMat(vec3 light0, vec3 light1) { + if (isNether(light0, light1)) { + // Cannot determine matrix in the nether due to parallel light directions + return mat3(0.0); + } + mat3 V = mat3(normalize(LIGHT0_DIRECTION), normalize(LIGHT1_DIRECTION), normalize(cross(LIGHT0_DIRECTION, LIGHT1_DIRECTION))); + mat3 W = mat3(normalize(light0), normalize(light1), normalize(cross(light0, light1))); + return W * inverse(V); +} + +/* + * Returns far clipping plane distance + * Evaluates far clipping plane by extracting it from the projection matrix + */ +float getFarClippingPlane(mat4 ProjMat) { + vec4 distProbe = inverse(ProjMat) * vec4(0.0, 0.0, 1.0, 1.0); + return length(distProbe.xyz / distProbe.w); +} + +/* + * Returns render distance based on far clipping plane + * Uses far clipping plane distance to get render distance in chunks + */ +float getRenderDistance(mat4 ProjMat) { + return round(getFarClippingPlane(ProjMat) / 64.0); +} + +/* + * Returns orthographic transformation matrix + * Creates matrix by extracting values from projection matrix + */ +mat4 getOrthoMat(mat4 ProjMat, float Zoom) { + float far = getFarClippingPlane(ProjMat); + float near = -1000.0; // Avoid clipping distance + + float fixed_near = 0.05; // Fixed distance that should never change + float left = -(0.5 / (ProjMat[0][0] / (2.0 * fixed_near))) / Zoom; + float right = -left; + float top = (0.5 / (ProjMat[1][1] / (2.0 * fixed_near))) / Zoom; + float bottom = -top; + + return mat4( + 2.0 / (right - left), 0.0, 0.0, 0.0, + 0.0, 2.0 / (top - bottom), 0.0, 0.0, + 0.0, 0.0, -2.0 / (far - near), 0.0, + -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1.0 + ); +}