aboutsummaryrefslogtreecommitdiff
path: root/Assets
diff options
context:
space:
mode:
Diffstat (limited to 'Assets')
-rw-r--r--Assets/Shaders/Basic.glsl31
-rw-r--r--Assets/Shaders/Compute.glsl24
-rw-r--r--Assets/Shaders/Geodesic.glsl215
-rw-r--r--Assets/Shaders/Grid.glsl19
-rw-r--r--Assets/Shaders/ImageProcessing.glsl31
-rw-r--r--Assets/Shaders/ParticleSystem.glsl58
-rw-r--r--Assets/Shaders/Quad.glsl25
-rw-r--r--Assets/Shaders/TextureProcessor.glsl43
-rw-r--r--Assets/Shaders/Textured.glsl41
9 files changed, 259 insertions, 228 deletions
diff --git a/Assets/Shaders/Basic.glsl b/Assets/Shaders/Basic.glsl
deleted file mode 100644
index f6016f7..0000000
--- a/Assets/Shaders/Basic.glsl
+++ /dev/null
@@ -1,31 +0,0 @@
-#type vertex
-#version 330 core
-
-layout(location = 0) in vec3 a_Position;
-layout(location = 1) in vec4 a_Color;
-
-uniform mat4 u_ViewProjection;
-uniform mat4 u_Transform;
-
-out vec3 v_Position;
-out vec4 v_Color;
-
-void main()
-{
- v_Position = a_Position;
- v_Color = a_Color;
- gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
-}
-
-#type fragment
-#version 330 core
-
-layout(location = 0) out vec4 color;
-
-in vec3 v_Position;
-in vec4 v_Color;
-
-void main()
-{
- color = v_Color;
-}
diff --git a/Assets/Shaders/Compute.glsl b/Assets/Shaders/Compute.glsl
deleted file mode 100644
index 9a36a84..0000000
--- a/Assets/Shaders/Compute.glsl
+++ /dev/null
@@ -1,24 +0,0 @@
-#type compute
-#version 430 core
-
-layout(local_size_x = 256) in;
-
-layout(std430, binding = 0) buffer InputBuffer
-{
- float data[];
-} inputBuffer;
-
-layout(std430, binding = 1) buffer OutputBuffer
-{
- float data[];
-} outputBuffer;
-
-uniform float u_Scale;
-uniform float u_Offset;
-
-void main()
-{
- uint index = gl_GlobalInvocationID.x;
- float inputValue = inputBuffer.data[index];
- outputBuffer.data[index] = inputValue * u_Scale + u_Offset;
-}
diff --git a/Assets/Shaders/Geodesic.glsl b/Assets/Shaders/Geodesic.glsl
new file mode 100644
index 0000000..c44b58d
--- /dev/null
+++ b/Assets/Shaders/Geodesic.glsl
@@ -0,0 +1,215 @@
+#version 430
+layout(local_size_x = 16, local_size_y = 16) in;
+
+layout(binding = 0, rgba8) writeonly uniform image2D outImage;
+
+layout(std140, binding = 1) uniform Camera
+{
+ vec3 camPos; float _pad0;
+ vec3 camRight; float _pad1;
+ vec3 camUp; float _pad2;
+ vec3 camForward; float _pad3;
+ float tanHalfFov;
+ float aspect;
+ bool moving;
+ int _pad4;
+} cam;
+
+layout(std140, binding = 2) uniform Disk
+{
+ float disk_r1;
+ float disk_r2;
+ float disk_num;
+ float thickness;
+};
+
+layout(std140, binding = 3) uniform Objects
+{
+ int numObjects;
+ vec4 objPosRadius[16];
+ vec4 objColor[16];
+ float mass[16];
+};
+
+const float SagA_rs = 1.269e10;
+const float D_LAMBDA = 1e7;
+const double ESCAPE_R = 1e30;
+
+vec4 objectColor = vec4(0.0);
+vec3 hitCenter = vec3(0.0);
+float hitRadius = 0.0;
+
+struct Ray
+{
+ float x, y, z, radius, theta, phi;
+ float dRadius, dTheta, dPhi;
+ float energy, angularMomentum;
+};
+
+Ray InitRay(vec3 position, vec3 direction)
+{
+ Ray ray;
+ ray.x = position.x;
+ ray.y = position.y;
+ ray.z = position.z;
+ ray.radius = length(position);
+ ray.theta = acos(position.z / ray.radius);
+ ray.phi = atan(position.y, position.x);
+
+ float dx = direction.x, dy = direction.y, dz = direction.z;
+ ray.dRadius = sin(ray.theta) * cos(ray.phi) * dx + sin(ray.theta) * sin(ray.phi) * dy + cos(ray.theta) * dz;
+ ray.dTheta = (cos(ray.theta) * cos(ray.phi) * dx + cos(ray.theta) * sin(ray.phi) * dy - sin(ray.theta) * dz) / ray.radius;
+ ray.dPhi = (-sin(ray.phi) * dx + cos(ray.phi) * dy) / (ray.radius * sin(ray.theta));
+
+ ray.angularMomentum = ray.radius * ray.radius * sin(ray.theta) * ray.dPhi;
+ float f = 1.0 - SagA_rs / ray.radius;
+ float dt_dL = sqrt((ray.dRadius * ray.dRadius) / f + ray.radius * ray.radius * (ray.dTheta * ray.dTheta + sin(ray.theta) * sin(ray.theta) * ray.dPhi * ray.dPhi));
+ ray.energy = f * dt_dL;
+
+ return ray;
+}
+
+bool Intercept(Ray ray, float schwarzschildRadius)
+{
+ return ray.radius <= schwarzschildRadius;
+}
+
+bool InterceptObject(Ray ray)
+{
+ vec3 position = vec3(ray.x, ray.y, ray.z);
+
+ for (int i = 0; i < numObjects; ++i)
+ {
+ vec3 center = objPosRadius[i].xyz;
+ float radius = objPosRadius[i].w;
+
+ if (distance(position, center) <= radius)
+ {
+ objectColor = objColor[i];
+ hitCenter = center;
+ hitRadius = radius;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void GeodesicRHS(Ray ray, out vec3 derivatives1, out vec3 derivatives2)
+{
+ float radius = ray.radius, theta = ray.theta;
+ float dRadius = ray.dRadius, dTheta = ray.dTheta, dPhi = ray.dPhi;
+ float f = 1.0 - SagA_rs / radius;
+ float dt_dL = ray.energy / f;
+
+ derivatives1 = vec3(dRadius, dTheta, dPhi);
+ derivatives2.x = -(SagA_rs / (2.0 * radius * radius)) * f * dt_dL * dt_dL
+ + (SagA_rs / (2.0 * radius * radius * f)) * dRadius * dRadius
+ + radius * (dTheta * dTheta + sin(theta) * sin(theta) * dPhi * dPhi);
+ derivatives2.y = -2.0 * dRadius * dTheta / radius + sin(theta) * cos(theta) * dPhi * dPhi;
+ derivatives2.z = -2.0 * dRadius * dPhi / radius - 2.0 * cos(theta) / sin(theta) * dTheta * dPhi;
+}
+
+void RK4Step(inout Ray ray, float deltaLambda)
+{
+ vec3 k1a, k1b;
+ GeodesicRHS(ray, k1a, k1b);
+
+ ray.radius += deltaLambda * k1a.x;
+ ray.theta += deltaLambda * k1a.y;
+ ray.phi += deltaLambda * k1a.z;
+ ray.dRadius += deltaLambda * k1b.x;
+ ray.dTheta += deltaLambda * k1b.y;
+ ray.dPhi += deltaLambda * k1b.z;
+
+ ray.x = ray.radius * sin(ray.theta) * cos(ray.phi);
+ ray.y = ray.radius * sin(ray.theta) * sin(ray.phi);
+ ray.z = ray.radius * cos(ray.theta);
+}
+
+bool CrossesEquatorialPlane(vec3 oldPosition, vec3 newPosition)
+{
+ bool crossed = (oldPosition.y * newPosition.y < 0.0);
+ float radius = length(vec2(newPosition.x, newPosition.z));
+ return crossed && (radius >= disk_r1 && radius <= disk_r2);
+}
+
+void main()
+{
+ ivec2 pixel = ivec2(gl_GlobalInvocationID.xy);
+ int width = imageSize(outImage).x;
+ int height = imageSize(outImage).y;
+
+ if (pixel.x >= width || pixel.y >= height)
+ return;
+
+ float u = (2.0 * (pixel.x + 0.5) / width - 1.0) * cam.aspect * cam.tanHalfFov;
+ float v = (1.0 - 2.0 * (pixel.y + 0.5) / height) * cam.tanHalfFov;
+ vec3 direction = normalize(u * cam.camRight - v * cam.camUp + cam.camForward);
+ Ray ray = InitRay(cam.camPos, direction);
+
+ vec4 color = vec4(0.0);
+ vec3 prevPosition = vec3(ray.x, ray.y, ray.z);
+ float lambda = 0.0;
+
+ bool hitBlackHole = false;
+ bool hitDisk = false;
+ bool hitObject = false;
+
+ int steps = cam.moving ? 60000 : 60000;
+
+ for (int i = 0; i < steps; ++i)
+ {
+ if (Intercept(ray, SagA_rs))
+ {
+ hitBlackHole = true;
+ break;
+ }
+
+ RK4Step(ray, D_LAMBDA);
+ lambda += D_LAMBDA;
+
+ vec3 newPosition = vec3(ray.x, ray.y, ray.z);
+
+ if (CrossesEquatorialPlane(prevPosition, newPosition))
+ {
+ hitDisk = true;
+ break;
+ }
+
+ if (InterceptObject(ray))
+ {
+ hitObject = true;
+ break;
+ }
+
+ prevPosition = newPosition;
+
+ if (ray.radius > ESCAPE_R)
+ break;
+ }
+
+ if (hitDisk)
+ {
+ double radius = length(vec3(ray.x, ray.y, ray.z)) / disk_r2;
+ vec3 diskColor = vec3(1.0, radius, 0.2);
+ color = vec4(diskColor, radius);
+ }
+ else if (hitBlackHole)
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+ else if (hitObject)
+ {
+ vec3 position = vec3(ray.x, ray.y, ray.z);
+ vec3 normal = normalize(position - hitCenter);
+ vec3 viewDirection = normalize(cam.camPos - position);
+ float ambient = 0.1;
+ float diffuse = max(dot(normal, viewDirection), 0.0);
+ float intensity = ambient + (1.0 - ambient) * diffuse;
+ vec3 shaded = objectColor.rgb * intensity;
+ color = vec4(shaded, objectColor.a);
+ }
+ else
+ color = vec4(0.0);
+
+ imageStore(outImage, pixel, color);
+} \ No newline at end of file
diff --git a/Assets/Shaders/Grid.glsl b/Assets/Shaders/Grid.glsl
new file mode 100644
index 0000000..66096c4
--- /dev/null
+++ b/Assets/Shaders/Grid.glsl
@@ -0,0 +1,19 @@
+#type vertex
+#version 330 core
+layout (location = 0) in vec3 aPos;
+
+uniform mat4 viewProj;
+
+void main()
+{
+ gl_Position = viewProj * vec4(aPos, 1.0);
+}
+
+#type fragment
+#version 330 core
+out vec4 FragColor;
+
+void main()
+{
+ FragColor = vec4(0.5, 0.5, 0.5, 0.3);
+}
diff --git a/Assets/Shaders/ImageProcessing.glsl b/Assets/Shaders/ImageProcessing.glsl
deleted file mode 100644
index 3a05425..0000000
--- a/Assets/Shaders/ImageProcessing.glsl
+++ /dev/null
@@ -1,31 +0,0 @@
-#type compute
-#version 430 core
-
-layout(local_size_x = 16, local_size_y = 16) in;
-
-layout(binding = 0) uniform sampler2D u_InputTexture;
-layout(binding = 1, rgba8) uniform image2D u_OutputTexture;
-
-uniform vec2 u_TextureSize;
-uniform float u_Brightness;
-uniform float u_Contrast;
-uniform float u_Saturation;
-
-void main()
-{
- ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy);
-
- if (pixelCoord.x >= int(u_TextureSize.x) || pixelCoord.y >= int(u_TextureSize.y))
- return;
-
- vec2 texCoord = (vec2(pixelCoord) + 0.5) / u_TextureSize;
- vec4 color = texture(u_InputTexture, texCoord);
-
- color.rgb = (color.rgb - 0.5) * u_Contrast + 0.5 + u_Brightness;
-
- float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114));
- color.rgb = mix(vec3(luminance), color.rgb, u_Saturation);
- color.rgb = clamp(color.rgb, 0.0, 1.0);
-
- imageStore(u_OutputTexture, pixelCoord, color);
-}
diff --git a/Assets/Shaders/ParticleSystem.glsl b/Assets/Shaders/ParticleSystem.glsl
deleted file mode 100644
index d40726d..0000000
--- a/Assets/Shaders/ParticleSystem.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-#type compute
-#version 430 core
-
-layout(local_size_x = 256) in;
-
-struct Particle
-{
- vec4 position; // xyz = position, w = lifetime
- vec4 velocity; // xyz = velocity, w = mass
- vec4 color; // rgba = color
-};
-
-layout(std430, binding = 0) buffer ParticleBuffer
-{
- Particle particles[];
-} particleBuffer;
-
-uniform float u_DeltaTime;
-uniform vec3 u_Gravity;
-uniform vec3 u_EmitterPosition;
-uniform float u_EmissionRate;
-uniform float u_ParticleLifetime;
-uniform float u_Time;
-
-void main()
-{
- uint index = gl_GlobalInvocationID.x;
-
- if (index >= particles.length())
- return;
-
- Particle particle = particleBuffer.particles[index];
-
- particle.position.w -= u_DeltaTime;
-
- if (particle.position.w <= 0.0)
- {
- particle.position.xyz = u_EmitterPosition;
- particle.position.w = u_ParticleLifetime;
-
- float angle = fract(sin(dot(vec2(index, u_Time), vec2(12.9898, 78.233))) * 43758.5453) * 2.0 * 3.14159;
- float speed = 2.0 + fract(sin(dot(vec2(index + 1, u_Time), vec2(12.9898, 78.233))) * 43758.5453) * 3.0;
- particle.velocity.xyz = vec3(cos(angle) * speed, 5.0, sin(angle) * speed);
- particle.velocity.w = 1.0;
-
- particle.color = vec4(1.0, 0.5 + 0.5 * fract(sin(index * 123.456) * 43758.5453), 0.2, 1.0);
- }
- else
- {
- particle.velocity.xyz += u_Gravity * u_DeltaTime;
- particle.position.xyz += particle.velocity.xyz * u_DeltaTime;
-
- float lifeRatio = particle.position.w / u_ParticleLifetime;
- particle.color.a = lifeRatio;
- }
-
- particleBuffer.particles[index] = particle;
-}
diff --git a/Assets/Shaders/Quad.glsl b/Assets/Shaders/Quad.glsl
new file mode 100644
index 0000000..57693a6
--- /dev/null
+++ b/Assets/Shaders/Quad.glsl
@@ -0,0 +1,25 @@
+#type vertex
+#version 330 core
+layout(location = 0) in vec2 a_Pos;
+layout(location = 1) in vec2 a_TexCoord;
+
+out vec2 v_TexCoord;
+
+void main()
+{
+ gl_Position = vec4(a_Pos.xy, 0.0, 1.0);
+ v_TexCoord = a_TexCoord;
+}
+
+#type fragment
+#version 330 core
+out vec4 FragColor;
+
+in vec2 v_TexCoord;
+
+uniform sampler2D screenTexture;
+
+void main()
+{
+ FragColor = texture(screenTexture, v_TexCoord);
+}
diff --git a/Assets/Shaders/TextureProcessor.glsl b/Assets/Shaders/TextureProcessor.glsl
deleted file mode 100644
index a234ac8..0000000
--- a/Assets/Shaders/TextureProcessor.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-#type compute
-#version 430 core
-
-layout(local_size_x = 16, local_size_y = 16) in;
-
-layout(binding = 0) uniform sampler2D u_InputTexture;
-layout(binding = 1, rgba8) uniform image2D u_OutputTexture;
-
-uniform vec2 u_TextureSize;
-uniform float u_Time;
-uniform float u_Brightness;
-uniform float u_Contrast;
-uniform float u_Saturation;
-
-void main()
-{
- ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy);
-
- if (pixelCoord.x >= int(u_TextureSize.x) || pixelCoord.y >= int(u_TextureSize.y))
- return;
-
- vec2 texCoord = (vec2(pixelCoord) + 0.5) / u_TextureSize;
- vec4 color = texture(u_InputTexture, texCoord);
-
- float time = u_Time * 2.0f;
- float u = texCoord.x;
- float v = texCoord.y;
-
- float wave = sin(u * 10.0f + time) * cos(v * 10.0f + time * 0.5f);
- wave = (wave + 1.0f) * 0.5f;
-
- vec4 animatedColor = vec4(wave, 1.0f - wave, (u + v) * 0.5f, 1.0f);
- color = mix(color, animatedColor, 0.3f);
-
- color.rgb = (color.rgb - 0.5) * u_Contrast + 0.5 + u_Brightness;
-
- float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114));
- color.rgb = mix(vec3(luminance), color.rgb, u_Saturation);
-
- color.rgb = clamp(color.rgb, 0.0, 1.0);
-
- imageStore(u_OutputTexture, pixelCoord, color);
-}
diff --git a/Assets/Shaders/Textured.glsl b/Assets/Shaders/Textured.glsl
deleted file mode 100644
index ad135fe..0000000
--- a/Assets/Shaders/Textured.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-#type vertex
-#version 330 core
-
-layout(location = 0) in vec3 a_Position;
-layout(location = 1) in vec4 a_Color;
-layout(location = 2) in vec2 a_TexCoord;
-
-uniform mat4 u_ViewProjection;
-uniform mat4 u_Transform;
-
-out vec3 v_Position;
-out vec4 v_Color;
-out vec2 v_TexCoord;
-
-void main()
-{
- v_Position = a_Position;
- v_Color = a_Color;
- v_TexCoord = a_TexCoord;
- gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
-}
-
-#type fragment
-#version 330 core
-
-layout(location = 0) out vec4 color;
-
-in vec3 v_Position;
-in vec4 v_Color;
-in vec2 v_TexCoord;
-
-uniform sampler2D u_Texture;
-
-void main()
-{
- vec4 texColor = texture(u_Texture, v_TexCoord);
- if (texColor.rgb == vec3(0.0))
- color = v_Color;
- else
- color = v_Color * texColor;
-}