hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/assets/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'assets/shaders')
-rw-r--r--assets/shaders/blur.glsl60
-rw-r--r--assets/shaders/blur.slang60
-rw-r--r--assets/shaders/equirect_to_cubemap.glsl39
-rw-r--r--assets/shaders/equirect_to_cubemap.slang33
-rw-r--r--assets/shaders/geodesic.slang (renamed from assets/shaders/geodesic.glsl)327
-rw-r--r--assets/shaders/grid.glsl40
-rw-r--r--assets/shaders/grid.slang34
-rw-r--r--assets/shaders/skybox.glsl31
-rw-r--r--assets/shaders/skybox.slang23
-rw-r--r--assets/shaders/sphere.glsl69
-rw-r--r--assets/shaders/sphere.slang67
-rw-r--r--assets/shaders/textured_quad.glsl28
-rw-r--r--assets/shaders/textured_quad.slang28
13 files changed, 405 insertions, 434 deletions
diff --git a/assets/shaders/blur.glsl b/assets/shaders/blur.glsl
deleted file mode 100644
index 984f0ba..0000000
--- a/assets/shaders/blur.glsl
+++ /dev/null
@@ -1,60 +0,0 @@
-#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, 0.0, 1.0);
- v_TexCoord = a_TexCoord;
-}
-
-#type fragment
-
-#version 330 core
-
-in vec2 v_TexCoord;
-out vec4 o_FragColor;
-
-uniform sampler2D u_ScreenTexture;
-uniform vec2 u_Resolution;
-uniform float u_BlurStrength;
-uniform float u_GlowIntensity;
-
-void main()
-{
- vec2 texelSize = 1.0 / u_Resolution;
- vec4 centerColor = texture(u_ScreenTexture, v_TexCoord);
-
- float brightness = (centerColor.r + centerColor.g + centerColor.b) / 3.0;
- float glowMask = smoothstep(0.05, 0.3, brightness);
-
- vec4 blurredColor = vec4(0.0);
- float totalWeight = 0.0;
-
- for (int x = -8; x <= 8; x++)
- {
- for (int y = -8; y <= 8; y++)
- {
- vec2 offset = vec2(x, y) * texelSize * u_BlurStrength;
- vec4 sampleColor = texture(u_ScreenTexture, v_TexCoord + offset);
-
- float weight = exp(-(x*x + y*y) / (2.0 * 8.0 * 8.0));
- blurredColor += sampleColor * weight;
- totalWeight += weight;
- }
- }
-
- blurredColor /= totalWeight;
-
- vec3 emissionColor = vec3(1.0, 0.8, 0.6);
- vec3 glowColor = emissionColor * glowMask * u_GlowIntensity * 2.0;
- vec3 auraColor = blurredColor.rgb * glowMask * u_GlowIntensity * 0.8;
- vec3 finalColor = centerColor.rgb + glowColor + auraColor;
-
- o_FragColor = vec4(finalColor, centerColor.a);
-}
diff --git a/assets/shaders/blur.slang b/assets/shaders/blur.slang
new file mode 100644
index 0000000..17e4eae
--- /dev/null
+++ b/assets/shaders/blur.slang
@@ -0,0 +1,60 @@
+struct VSInput
+{
+ float2 position : POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct VSOutput
+{
+ float4 position : SV_Position;
+ float2 texCoord : TEXCOORD0;
+};
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ output.position = float4(input.position, 0.0, 1.0);
+ output.texCoord = input.texCoord;
+ return output;
+}
+
+Sampler2D u_ScreenTexture;
+uniform float2 u_Resolution;
+uniform float u_BlurStrength;
+uniform float u_GlowIntensity;
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ float2 texelSize = 1.0 / u_Resolution;
+ float4 centerColor = u_ScreenTexture.Sample(input.texCoord);
+
+ float brightness = (centerColor.r + centerColor.g + centerColor.b) / 3.0;
+ float glowMask = smoothstep(0.05, 0.3, brightness);
+
+ float4 blurredColor = float4(0.0, 0.0, 0.0, 0.0);
+ float totalWeight = 0.0;
+
+ for (int x = -8; x <= 8; x++)
+ {
+ for (int y = -8; y <= 8; y++)
+ {
+ float2 offset = float2(x, y) * texelSize * u_BlurStrength;
+ float4 sampleColor = u_ScreenTexture.Sample(input.texCoord + offset);
+
+ float weight = exp(-float(x * x + y * y) / (2.0 * 8.0 * 8.0));
+ blurredColor += sampleColor * weight;
+ totalWeight += weight;
+ }
+ }
+
+ blurredColor /= totalWeight;
+
+ float3 emissionColor = float3(1.0, 0.8, 0.6);
+ float3 glowColor = emissionColor * glowMask * u_GlowIntensity * 2.0;
+ float3 auraColor = blurredColor.rgb * glowMask * u_GlowIntensity * 0.8;
+ float3 finalColor = centerColor.rgb + glowColor + auraColor;
+
+ return float4(finalColor, centerColor.a);
+}
diff --git a/assets/shaders/equirect_to_cubemap.glsl b/assets/shaders/equirect_to_cubemap.glsl
deleted file mode 100644
index 690706f..0000000
--- a/assets/shaders/equirect_to_cubemap.glsl
+++ /dev/null
@@ -1,39 +0,0 @@
-#type vertex
-
-#version 330 core
-
-layout (location = 0) in vec3 a_Pos;
-out vec3 v_WorldPos;
-
-uniform mat4 u_Projection;
-uniform mat4 u_View;
-
-void main()
-{
- v_WorldPos = a_Pos;
- gl_Position = u_Projection * u_View * vec4(v_WorldPos, 1.0);
-}
-
-#type fragment
-
-#version 330 core
-
-out vec4 o_FragColor;
-in vec3 v_WorldPos;
-
-uniform sampler2D u_EquirectangularMap;
-const vec2 invAtan = vec2(0.1591, 0.3183);
-
-vec2 SampleSphericalMap(vec3 v)
-{
- vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
- uv *= invAtan;
- uv += 0.5;
- return uv;
-}
-void main()
-{
- vec2 uv = SampleSphericalMap(normalize(v_WorldPos));
- vec3 color = texture(u_EquirectangularMap, uv).rgb;
- o_FragColor = vec4(color, 1.0);
-}
diff --git a/assets/shaders/equirect_to_cubemap.slang b/assets/shaders/equirect_to_cubemap.slang
new file mode 100644
index 0000000..9b2ea4b
--- /dev/null
+++ b/assets/shaders/equirect_to_cubemap.slang
@@ -0,0 +1,33 @@
+uniform float4x4 u_Projection;
+uniform float4x4 u_View;
+
+struct VSInput { float3 position : POSITION; };
+struct VSOutput { float4 position : SV_Position; float3 worldPos : TEXCOORD0; };
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ output.worldPos = input.position;
+ output.position = mul(u_Projection, mul(u_View, float4(input.position, 1.0)));
+ return output;
+}
+
+Sampler2D u_EquirectangularMap;
+static const float2 invAtan = float2(0.1591, 0.3183);
+
+float2 SampleSphericalMap(float3 v)
+{
+ float2 uv = float2(atan2(v.z, v.x), asin(v.y));
+ uv *= invAtan;
+ uv += 0.5;
+ return uv;
+}
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ float2 uv = SampleSphericalMap(normalize(input.worldPos));
+ float3 color = u_EquirectangularMap.Sample(uv).rgb;
+ return float4(color, 1.0);
+}
diff --git a/assets/shaders/geodesic.glsl b/assets/shaders/geodesic.slang
index 52ea69e..9490f21 100644
--- a/assets/shaders/geodesic.glsl
+++ b/assets/shaders/geodesic.slang
@@ -1,35 +1,29 @@
-#type vertex
-#version 410 core
+struct VSInput { float2 position : POSITION; float2 texCoord : TEXCOORD0; };
+struct VSOutput { float4 position : SV_Position; float2 texCoord : TEXCOORD0; };
-layout(location = 0) in vec2 a_Position;
-
-void main()
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
{
- gl_Position = vec4(a_Position, 0.0, 1.0);
+ VSOutput output;
+ output.position = float4(input.position, 0.0, 1.0);
+ output.texCoord = input.texCoord;
+ return output;
}
-#type fragment
-#version 410 core
-
-out vec4 fragColor;
-
-uniform vec2 u_Resolution;
-
-uniform samplerCube u_HDRIEnvironment;
-
-layout(std140) uniform Camera
+struct 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;
+ float3 camPos; float _pad0;
+ float3 camRight; float _pad1;
+ float3 camUp; float _pad2;
+ float3 camForward; float _pad3;
+ float tanHalfFov;
+ float aspect;
+ bool moving;
+ int _pad4;
+};
+ConstantBuffer<Camera> cam;
-layout(std140) uniform Disk
+struct Disk
{
float disk_r1;
float disk_r2;
@@ -37,92 +31,99 @@ layout(std140) uniform Disk
float thickness;
float disk_density;
};
+ConstantBuffer<Disk> disk;
-layout(std140) uniform Objects
+struct Objects
{
int numObjects;
- vec4 objPosRadius[16];
- vec4 objColor[16];
+ float4 objPosRadius[16];
+ float4 objColor[16];
float mass[16];
};
+ConstantBuffer<Objects> obj;
-layout(std140) uniform Simulation
+struct Simulation
{
int maxStepsMoving;
int maxStepsStatic;
float earlyExitDistance;
float time;
};
+ConstantBuffer<Simulation> sim;
+
+SamplerCube u_HDRIEnvironment;
-const float SagA_rs = 1.269e10;
-const float D_LAMBDA = 1e7;
-const float ESCAPE_R = 1e30;
+static const float SagA_rs = 1.269e10;
+static const float D_LAMBDA = 1e7;
+static const float ESCAPE_R = 1e30;
-const int DEFAULT_MAX_STEPS_MOVING = 12000;
-const int DEFAULT_MAX_STEPS_STATIC = 8000;
-const float DEFAULT_EARLY_EXIT_DISTANCE = 2e12;
+static const int DEFAULT_MAX_STEPS_MOVING = 12000;
+static const int DEFAULT_MAX_STEPS_STATIC = 8000;
+static const float DEFAULT_EARLY_EXIT_DISTANCE = 2e12;
-const float MIN_STEP_SIZE = 1e6;
-const float MAX_STEP_SIZE = 5e7;
-const float STEP_ADAPTATION_FACTOR = 1.5;
+static const float MIN_STEP_SIZE = 1e6;
+static const float MAX_STEP_SIZE = 5e7;
-vec4 objectColor = vec4(0.0);
-vec3 hitCenter = vec3(0.0);
-float hitRadius = 0.0;
+struct Hit
+{
+ float4 objectColor;
+ float3 hitCenter;
+ float hitRadius;
+};
-vec3 SampleHDRI(vec3 direction)
+float3 SampleHDRI(float3 direction)
{
- return texture(u_HDRIEnvironment, direction).rgb;
+ return u_HDRIEnvironment.Sample(direction).rgb;
}
float hash(float p)
{
- p = fract(p * 0.1031);
+ p = frac(p * 0.1031);
p *= p + 33.33;
p *= p + p;
- return fract(p);
+ return frac(p);
}
-float hash(vec2 p)
+float hash(float2 p)
{
- vec3 p3 = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));
+ float3 p3 = frac(float3(p.xyx) * float3(0.1031, 0.1030, 0.0973));
p3 += dot(p3, p3.yzx + 33.33);
- return fract((p3.x + p3.y) * p3.z);
+ return frac((p3.x + p3.y) * p3.z);
}
-float hash(vec3 p)
+float hash(float3 p)
{
- p = fract(p * vec3(0.1031, 0.1030, 0.0973));
+ p = frac(p * float3(0.1031, 0.1030, 0.0973));
p += dot(p, p.yxz + 33.33);
- return fract((p.x + p.y) * p.z);
+ return frac((p.x + p.y) * p.z);
}
-float noise(vec3 x)
+float noise(float3 x)
{
- vec3 i = floor(x);
- vec3 frac = fract(x);
+ float3 i = floor(x);
+ float3 fr = frac(x);
- vec3 u = frac * frac * (3.0 - 2.0 * frac);
+ float3 u = fr * fr * (3.0 - 2.0 * fr);
float a = hash(i);
- float b = hash(i + vec3(1.0, 0.0, 0.0));
- float c = hash(i + vec3(0.0, 1.0, 0.0));
- float d = hash(i + vec3(1.0, 1.0, 0.0));
- float e = hash(i + vec3(0.0, 0.0, 1.0));
- float f = hash(i + vec3(1.0, 0.0, 1.0));
- float g = hash(i + vec3(0.0, 1.0, 1.0));
- float h = hash(i + vec3(1.0, 1.0, 1.0));
+ float b = hash(i + float3(1.0, 0.0, 0.0));
+ float c = hash(i + float3(0.0, 1.0, 0.0));
+ float d = hash(i + float3(1.0, 1.0, 0.0));
+ float e = hash(i + float3(0.0, 0.0, 1.0));
+ float f = hash(i + float3(1.0, 0.0, 1.0));
+ float g = hash(i + float3(0.0, 1.0, 1.0));
+ float h = hash(i + float3(1.0, 1.0, 1.0));
- return mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y),
- mix(mix(e, f, u.x), mix(g, h, u.x), u.y), u.z);
+ return lerp(lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y),
+ lerp(lerp(e, f, u.x), lerp(g, h, u.x), u.y), u.z);
}
-float fbm(vec3 x, int octaves)
+float fbm(float3 x, int octaves)
{
float v = 0.0;
float a = 0.5;
float f = 1.0;
- vec3 shift = vec3(100, 200, 300);
+ float3 shift = float3(100, 200, 300);
for (int i = 0; i < octaves; ++i)
{
@@ -134,33 +135,31 @@ float fbm(vec3 x, int octaves)
return v;
}
-float GetCloudDensity(vec3 pos)
+float GetCloudDensity(float3 pos)
{
- float r_cyl = length(vec2(pos.x, pos.z));
- float r_norm = (r_cyl - disk_r1) / (disk_r2 - disk_r1);
+ float r_cyl = length(float2(pos.x, pos.z));
+ float r_norm = (r_cyl - disk.disk_r1) / (disk.disk_r2 - disk.disk_r1);
if (r_norm < 0.0 || r_norm > 1.0)
return 0.0;
- float h_norm = abs(pos.y) / thickness;
+ float h_norm = abs(pos.y) / disk.thickness;
float vertical_falloff = exp(-h_norm * h_norm * 3.0);
float radial_density = 1.0 - r_norm * 0.5;
- vec3 noise_pos = pos * 1e-10;
float keplerian_speed = 1.0 / sqrt(r_norm + 0.1);
- float rotation_angle = time * keplerian_speed * 0.5;
- vec3 rotated_pos = vec3(
+ float rotation_angle = sim.time * keplerian_speed * 0.5;
+ float3 rotated_pos = float3(
pos.x * cos(rotation_angle) - pos.z * sin(rotation_angle),
pos.y,
pos.x * sin(rotation_angle) + pos.z * cos(rotation_angle)
) * 1e-10;
float large_turbulence = fbm(rotated_pos * 1.2, 5);
-
- float medium_wisps = fbm(rotated_pos * 2.5, 4);
- float small_detail = fbm(rotated_pos * 6.0, 3);
- float fine_detail = fbm(rotated_pos * 10.0, 2);
+ float medium_wisps = fbm(rotated_pos * 2.5, 4);
+ float small_detail = fbm(rotated_pos * 6.0, 3);
+ float fine_detail = fbm(rotated_pos * 10.0, 2);
float noise_mask = large_turbulence * 0.4 +
medium_wisps * 0.3 +
@@ -169,16 +168,16 @@ float GetCloudDensity(vec3 pos)
noise_mask = smoothstep(0.25, 0.75, noise_mask);
- float angle = atan(pos.z, pos.x);
- float rotated_angle = angle + time * 0.5;
+ float angle = atan2(pos.z, pos.x);
+ float rotated_angle = angle + sim.time * 0.5;
float spiral_arms = sin(rotated_angle * 3.0 + r_norm * 15.0) * 0.15 + 0.85;
- float orbital_angle = angle + time * keplerian_speed * 0.8;
+ float orbital_angle = angle + sim.time * keplerian_speed * 0.8;
float orbital_pattern = sin(orbital_angle * 2.0 + r_norm * 8.0) * 0.2 + 0.8;
float density = vertical_falloff * radial_density * noise_mask * spiral_arms * orbital_pattern;
- return density * disk_density;
+ return density * disk.disk_density;
}
struct Ray
@@ -189,7 +188,7 @@ struct Ray
float E, L;
};
-Ray InitRay(vec3 pos, vec3 dir)
+Ray InitRay(float3 pos, float3 dir)
{
Ray ray;
ray.x = pos.x;
@@ -197,7 +196,7 @@ Ray InitRay(vec3 pos, vec3 dir)
ray.z = pos.z;
ray.r = length(pos);
ray.theta = acos(pos.z / ray.r);
- ray.phi = atan(pos.y, pos.x);
+ ray.phi = atan2(pos.y, pos.x);
float dx = dir.x;
float dy = dir.y;
@@ -230,14 +229,14 @@ bool Intercept(Ray ray, float rs)
return ray.r <= rs;
}
-bool InterceptObject(Ray ray)
+bool InterceptObject(Ray ray, inout Hit hit)
{
- vec3 P = vec3(ray.x, ray.y, ray.z);
+ float3 P = float3(ray.x, ray.y, ray.z);
- for (int i = 0; i < numObjects; ++i)
+ for (int i = 0; i < obj.numObjects; ++i)
{
- vec3 center = objPosRadius[i].xyz;
- float radius = objPosRadius[i].w;
+ float3 center = obj.objPosRadius[i].xyz;
+ float radius = obj.objPosRadius[i].w;
float distSq = dot(P - center, P - center);
if (distSq > radius * radius * 4.0)
@@ -245,9 +244,9 @@ bool InterceptObject(Ray ray)
if (distSq <= radius * radius)
{
- objectColor = objColor[i];
- hitCenter = center;
- hitRadius = radius;
+ hit.objectColor = obj.objColor[i];
+ hit.hitCenter = center;
+ hit.hitRadius = radius;
return true;
}
}
@@ -255,7 +254,7 @@ bool InterceptObject(Ray ray)
return false;
}
-void GeodesicRHS(Ray ray, out vec3 d1, out vec3 d2)
+void GeodesicRHS(Ray ray, out float3 d1, out float3 d2)
{
float r = ray.r;
float theta = ray.theta;
@@ -265,7 +264,7 @@ void GeodesicRHS(Ray ray, out vec3 d1, out vec3 d2)
float f = 1.0 - SagA_rs / r;
float dt_dL = ray.E / f;
- d1 = vec3(dr, dtheta, dphi);
+ d1 = float3(dr, dtheta, dphi);
d2.x = - (SagA_rs / (2.0 * r*r)) * f * dt_dL * dt_dL
+ (SagA_rs / (2.0 * r*r * f)) * dr * dr
+ r * (dtheta*dtheta + sin(theta)*sin(theta)*dphi*dphi);
@@ -275,7 +274,7 @@ void GeodesicRHS(Ray ray, out vec3 d1, out vec3 d2)
void RK4Step(inout Ray ray, float dL)
{
- vec3 k1a, k1b;
+ float3 k1a, k1b;
GeodesicRHS(ray, k1a, k1b);
ray.r += dL * k1a.x;
@@ -290,102 +289,95 @@ void RK4Step(inout Ray ray, float dL)
ray.z = ray.r * cos(ray.theta);
}
-bool IsInDiskVolume(vec3 pos)
+bool IsInDiskVolume(float3 pos)
{
- float r_cyl = length(vec2(pos.x, pos.z));
- return (r_cyl >= disk_r1 && r_cyl <= disk_r2 && abs(pos.y) <= thickness);
+ float r_cyl = length(float2(pos.x, pos.z));
+ return (r_cyl >= disk.disk_r1 && r_cyl <= disk.disk_r2 && abs(pos.y) <= disk.thickness);
}
-vec4 SampleDiskColor(vec3 pos)
+float4 SampleDiskColor(float3 pos)
{
- float r_cyl = length(vec2(pos.x, pos.z));
- float r_norm = (r_cyl - disk_r1) / (disk_r2 - disk_r1);
+ float r_cyl = length(float2(pos.x, pos.z));
+ float r_norm = (r_cyl - disk.disk_r1) / (disk.disk_r2 - disk.disk_r1);
- vec3 innerColor = vec3(1.0, 0.9, 0.5);
- vec3 midColor = vec3(1.0, 0.6, 0.2);
- vec3 outerColor = vec3(0.9, 0.3, 0.1);
+ float3 innerColor = float3(1.0, 0.9, 0.5);
+ float3 midColor = float3(1.0, 0.6, 0.2);
+ float3 outerColor = float3(0.9, 0.3, 0.1);
- vec3 baseColor;
+ float3 baseColor;
if (r_norm < 0.5)
- baseColor = mix(innerColor, midColor, r_norm * 2.0);
+ baseColor = lerp(innerColor, midColor, r_norm * 2.0);
else
- baseColor = mix(midColor, outerColor, (r_norm - 0.5) * 2.0);
+ baseColor = lerp(midColor, outerColor, (r_norm - 0.5) * 2.0);
- float r_norm_rot = (r_cyl - disk_r1) / (disk_r2 - disk_r1);
+ float r_norm_rot = (r_cyl - disk.disk_r1) / (disk.disk_r2 - disk.disk_r1);
float keplerian_speed = 1.0 / sqrt(r_norm_rot + 0.1);
- vec3 noise_pos = pos * 1e-10;
-
- float color_rotation_angle = time * keplerian_speed * 0.3;
- vec3 rotated_color_pos = vec3(
+ float color_rotation_angle = sim.time * keplerian_speed * 0.3;
+ float3 rotated_color_pos = float3(
pos.x * cos(color_rotation_angle) - pos.z * sin(color_rotation_angle),
pos.y,
pos.x * sin(color_rotation_angle) + pos.z * cos(color_rotation_angle)
) * 1e-10;
- float large_color = fbm(rotated_color_pos * 1.8, 4);
+ float large_color = fbm(rotated_color_pos * 1.8, 4);
float medium_color = fbm(rotated_color_pos * 4.0, 3);
- float small_color = fbm(rotated_color_pos * 8.0, 2);
+ float small_color = fbm(rotated_color_pos * 8.0, 2);
float colorVariation = (large_color * 0.5 + medium_color * 0.3 + small_color * 0.2) * 0.6;
baseColor = baseColor * (1.0 + colorVariation);
float density = GetCloudDensity(pos);
- vec3 brightness_noise_pos = pos * 1e-10;
- float brightness_rotation_angle = time * keplerian_speed * 0.7;
- vec3 rotated_brightness_pos = vec3(
+ float brightness_rotation_angle = sim.time * keplerian_speed * 0.7;
+ float3 rotated_brightness_pos = float3(
pos.x * cos(brightness_rotation_angle) - pos.z * sin(brightness_rotation_angle),
pos.y,
pos.x * sin(brightness_rotation_angle) + pos.z * cos(brightness_rotation_angle)
) * 1e-10;
- float brightness_large = fbm(rotated_brightness_pos * 3.0, 3);
+ float brightness_large = fbm(rotated_brightness_pos * 3.0, 3);
float brightness_medium = fbm(rotated_brightness_pos * 5.0, 2);
- float brightness_small = fbm(rotated_brightness_pos * 7.0, 2);
- float brightness_noise = (brightness_large * 0.6 + brightness_medium * 0.3 + brightness_small * 0.1);
+ float brightness_small = fbm(rotated_brightness_pos * 7.0, 2);
+ float brightness_noise = (brightness_large * 0.6 + brightness_medium * 0.3 + brightness_small * 0.1);
float baseBrightness = 1.0 + density * 1.5;
float glowBrightness = brightness_noise * 0.8;
float brightness = baseBrightness + glowBrightness;
- return vec4(baseColor * brightness, density);
+ return float4(baseColor * brightness, density);
}
float CalculateAdaptiveStepSize(Ray ray, float baseStepSize)
{
float r_factor = clamp(ray.r / (SagA_rs * 10.0), 0.1, 1.0);
- float curvature = length(vec3(ray.dr, ray.dtheta * ray.r, ray.dphi * ray.r * sin(ray.theta)));
+ float curvature = length(float3(ray.dr, ray.dtheta * ray.r, ray.dphi * ray.r * sin(ray.theta)));
float curvature_factor = clamp(1e12 / (curvature + 1e6), 0.1, 2.0);
return clamp(baseStepSize * r_factor * curvature_factor, MIN_STEP_SIZE, MAX_STEP_SIZE);
}
-void main()
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
{
- ivec2 pix = ivec2(gl_FragCoord.xy);
- int WIDTH = int(u_Resolution.x);
- int HEIGHT = int(u_Resolution.y);
-
- float u = (2.0 * (pix.x + 0.5) / WIDTH - 1.0) *
- cam.aspect * cam.tanHalfFov;
- float v = (1.0 - 2.0 * (pix.y + 0.5) / HEIGHT) *
- cam.tanHalfFov;
- vec3 dir = normalize(u * cam.camRight -
- v * cam.camUp +
- cam.camForward);
+ float u = (2.0 * input.texCoord.x - 1.0) * cam.aspect * cam.tanHalfFov;
+ float v = (1.0 - 2.0 * input.texCoord.y) * cam.tanHalfFov;
+ float3 dir = normalize(u * cam.camRight - v * cam.camUp + cam.camForward);
Ray ray = InitRay(cam.camPos, dir);
- vec4 color = vec4(0.0);
- vec3 prevPos = vec3(ray.x, ray.y, ray.z);
- float lambda = 0.0;
+ float4 color = float4(0.0, 0.0, 0.0, 0.0);
bool hitBlackHole = false;
bool hitObject = false;
- vec4 accumulatedColor = vec4(0.0);
- float transmittance = 1.0;
+ Hit hit;
+ hit.objectColor = float4(0.0, 0.0, 0.0, 0.0);
+ hit.hitCenter = float3(0.0, 0.0, 0.0);
+ hit.hitRadius = 0.0;
- int maxSteps = cam.moving ? maxStepsMoving : maxStepsStatic;
+ float4 accumulatedColor = float4(0.0, 0.0, 0.0, 0.0);
+ float transmittance = 1.0;
+
+ int maxSteps = cam.moving ? sim.maxStepsMoving : sim.maxStepsStatic;
if (maxSteps <= 0)
maxSteps = cam.moving ? DEFAULT_MAX_STEPS_MOVING : DEFAULT_MAX_STEPS_STATIC;
@@ -401,12 +393,12 @@ void main()
ray.r > SagA_rs * 200.0)
maxSteps = maxSteps / 2;
- float currentStepSize = D_LAMBDA;
+ float lambda = 0.0;
int objectCheckInterval = 5;
for (int i = 0; i < maxSteps; ++i)
{
- float exitDistance = earlyExitDistance > 0.0 ? earlyExitDistance : DEFAULT_EARLY_EXIT_DISTANCE;
+ float exitDistance = sim.earlyExitDistance > 0.0 ? sim.earlyExitDistance : DEFAULT_EARLY_EXIT_DISTANCE;
if (ray.r > exitDistance)
break;
if (ray.r > ESCAPE_R)
@@ -418,18 +410,18 @@ void main()
break;
}
- currentStepSize = CalculateAdaptiveStepSize(ray, D_LAMBDA);
+ float currentStepSize = CalculateAdaptiveStepSize(ray, D_LAMBDA);
RK4Step(ray, currentStepSize);
lambda += currentStepSize;
- vec3 newPos = vec3(ray.x, ray.y, ray.z);
+ float3 newPos = float3(ray.x, ray.y, ray.z);
if (IsInDiskVolume(newPos))
{
- vec4 diskSample = SampleDiskColor(newPos);
- float density = diskSample.a;
- vec3 diskColor = diskSample.rgb;
+ float4 diskSample = SampleDiskColor(newPos);
+ float density = diskSample.a;
+ float3 diskColor = diskSample.rgb;
float stepLength = currentStepSize * 1e-8;
@@ -439,13 +431,13 @@ void main()
float stepTransmittance = exp(-extinction);
- vec3 emission = diskColor * density * stepLength * 4.0 * sqrt(disk_density);
+ float3 emission = diskColor * density * stepLength * 4.0 * sqrt(disk.disk_density);
- vec3 glowColor = mix(diskColor, vec3(1.0, 0.8, 0.6), 0.3);
- float glowIntensity = density * stepLength * 2.0;
- vec3 atmosphericGlow = glowColor * glowIntensity * 0.8;
+ float3 glowColor = lerp(diskColor, float3(1.0, 0.8, 0.6), 0.3);
+ float glowIntensity = density * stepLength * 2.0;
+ float3 atmosphericGlow = glowColor * glowIntensity * 0.8;
- vec3 totalEmission = emission + atmosphericGlow;
+ float3 totalEmission = emission + atmosphericGlow;
accumulatedColor.rgb += totalEmission * transmittance;
transmittance *= stepTransmittance;
@@ -457,14 +449,12 @@ void main()
}
}
- if (i % objectCheckInterval == 0 && InterceptObject(ray))
+ if (i % objectCheckInterval == 0 && InterceptObject(ray, hit))
{
hitObject = true;
break;
}
- prevPos = newPos;
-
if (ray.dr > 0.0 && ray.r > SagA_rs * 100.0 && lambda > 2e8)
break;
}
@@ -472,26 +462,29 @@ void main()
accumulatedColor.a = 1.0 - transmittance;
if (hitBlackHole)
- color = vec4(0.0, 0.0, 0.0, 1.0);
+ {
+ color = float4(0.0, 0.0, 0.0, 1.0);
+ }
else if (hitObject)
{
- vec3 P = vec3(ray.x, ray.y, ray.z);
- vec3 N = normalize(P - hitCenter);
- vec3 V = normalize(cam.camPos - P);
+ float3 P = float3(ray.x, ray.y, ray.z);
+ float3 N = normalize(P - hit.hitCenter);
+ float3 V = normalize(cam.camPos - P);
float ambient = 0.1;
float diff = max(dot(N, V), 0.0);
float intensity = ambient + (1.0 - ambient) * diff;
- vec3 shaded = objectColor.rgb * intensity;
+ float3 shaded = hit.objectColor.rgb * intensity;
- color = vec4(shaded, objectColor.a);
- color = mix(accumulatedColor, color, color.a);
- } else
+ color = float4(shaded, hit.objectColor.a);
+ color = lerp(accumulatedColor, color, color.a);
+ }
+ else
{
- vec3 rayDirection = normalize(vec3(ray.x, ray.y, ray.z) - cam.camPos);
- vec3 hdriColor = SampleHDRI(rayDirection);
- color = vec4(mix(accumulatedColor.rgb, hdriColor, 1.0 - accumulatedColor.a), 1.0);
+ float3 rayDirection = normalize(float3(ray.x, ray.y, ray.z) - cam.camPos);
+ float3 hdriColor = SampleHDRI(rayDirection);
+ color = float4(lerp(accumulatedColor.rgb, hdriColor, 1.0 - accumulatedColor.a), 1.0);
}
- fragColor = color;
+ return color;
}
diff --git a/assets/shaders/grid.glsl b/assets/shaders/grid.glsl
deleted file mode 100644
index 81523b3..0000000
--- a/assets/shaders/grid.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-#type vertex
-
-#version 330 core
-
-layout(location = 0) in vec3 a_Position;
-
-uniform mat4 u_ViewProjection;
-uniform mat4 u_Transform;
-uniform float u_GridSize;
-
-void main()
-{
- vec3 scaledPosition = a_Position * (u_GridSize / 50.0);
- gl_Position = u_ViewProjection * u_Transform * vec4(scaledPosition, 1.0);
-}
-
-#type fragment
-
-#version 330 core
-
-uniform vec3 u_GridColor;
-uniform float u_GridAlpha;
-uniform float u_GridSize;
-uniform vec3 u_CameraPos;
-
-out vec4 o_FragColor;
-
-void main()
-{
- float distance = length(u_CameraPos);
- float fadeFactor = 1.0 - clamp(distance / 100.0, 0.0, 0.8);
-
- vec3 color = u_GridColor;
- float alpha = u_GridAlpha * fadeFactor;
-
- float gridFade = 1.0 - clamp(distance / 50.0, 0.0, 0.9);
- alpha *= gridFade;
-
- o_FragColor = vec4(color, alpha);
-}
diff --git a/assets/shaders/grid.slang b/assets/shaders/grid.slang
new file mode 100644
index 0000000..ea7d263
--- /dev/null
+++ b/assets/shaders/grid.slang
@@ -0,0 +1,34 @@
+uniform float4x4 u_ViewProjection;
+uniform float4x4 u_Transform;
+uniform float u_GridSize;
+
+struct VSInput { float3 position : POSITION; };
+struct VSOutput { float4 position : SV_Position; };
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ float3 scaledPosition = input.position * (u_GridSize / 50.0);
+ output.position = mul(u_ViewProjection, mul(u_Transform, float4(scaledPosition, 1.0)));
+ return output;
+}
+
+uniform float3 u_GridColor;
+uniform float u_GridAlpha;
+uniform float3 u_CameraPos;
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ float dist = length(u_CameraPos);
+ float fadeFactor = 1.0 - clamp(dist / 100.0, 0.0, 0.8);
+
+ float3 color = u_GridColor;
+ float alpha = u_GridAlpha * fadeFactor;
+
+ float gridFade = 1.0 - clamp(dist / 50.0, 0.0, 0.9);
+ alpha *= gridFade;
+
+ return float4(color, alpha);
+}
diff --git a/assets/shaders/skybox.glsl b/assets/shaders/skybox.glsl
deleted file mode 100644
index 654bed1..0000000
--- a/assets/shaders/skybox.glsl
+++ /dev/null
@@ -1,31 +0,0 @@
-#type vertex
-
-#version 330 core
-
-layout (location = 0) in vec3 aPos;
-
-out vec3 TexCoords;
-
-uniform mat4 u_Projection;
-uniform mat4 u_View;
-
-void main()
-{
- TexCoords = aPos;
- vec4 pos = u_Projection * u_View * vec4(aPos, 1.0);
- gl_Position = pos.xyww;
-}
-
-#type fragment
-
-#version 330 core
-
-out vec4 FragColor;
-in vec3 TexCoords;
-
-uniform samplerCube u_Skybox;
-
-void main()
-{
- FragColor = texture(u_Skybox, TexCoords);
-}
diff --git a/assets/shaders/skybox.slang b/assets/shaders/skybox.slang
new file mode 100644
index 0000000..cffffcd
--- /dev/null
+++ b/assets/shaders/skybox.slang
@@ -0,0 +1,23 @@
+uniform float4x4 u_Projection;
+uniform float4x4 u_View;
+
+struct VSInput { float3 position : POSITION; };
+struct VSOutput { float4 position : SV_Position; float3 texCoords : TEXCOORD0; };
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ output.texCoords = input.position;
+ float4 pos = mul(u_Projection, mul(u_View, float4(input.position, 1.0)));
+ output.position = pos.xyww;
+ return output;
+}
+
+SamplerCube u_Skybox;
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ return u_Skybox.Sample(input.texCoords);
+}
diff --git a/assets/shaders/sphere.glsl b/assets/shaders/sphere.glsl
deleted file mode 100644
index 2d1a46e..0000000
--- a/assets/shaders/sphere.glsl
+++ /dev/null
@@ -1,69 +0,0 @@
-#type vertex
-
-#version 330 core
-
-layout(location = 0) in vec3 a_Position;
-layout(location = 1) in vec3 a_Normal;
-
-uniform mat4 u_ViewProjection;
-uniform mat4 u_Transform;
-
-out vec3 v_Normal;
-out vec3 v_WorldPos;
-
-void main()
-{
- v_WorldPos = vec3(u_Transform * vec4(a_Position, 1.0));
- v_Normal = mat3(transpose(inverse(u_Transform))) * a_Normal;
- gl_Position = u_ViewProjection * vec4(v_WorldPos, 1.0);
-}
-
-#type fragment
-
-#version 330 core
-
-in vec3 v_Normal;
-in vec3 v_WorldPos;
-
-uniform vec3 u_Color;
-uniform float u_Specular;
-uniform float u_Emission;
-uniform vec3 u_LightPos;
-uniform vec3 u_CameraPos;
-uniform int u_IsSelected;
-uniform vec3 u_OutlineColor;
-uniform float u_OutlineWidth;
-uniform samplerCube u_HDRIEnvironment;
-
-out vec4 o_FragColor;
-
-void main()
-{
- vec3 normal = normalize(v_Normal);
- vec3 lightDir = normalize(u_LightPos - v_WorldPos);
- vec3 viewDir = normalize(u_CameraPos - v_WorldPos);
- vec3 reflectDir = reflect(-lightDir, normal);
-
- vec3 hdriLight = texture(u_HDRIEnvironment, normal).rgb;
- float hdriIntensity = 0.3;
-
- float diff = max(dot(normal, lightDir), 0.0);
- float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
-
- vec3 diffuse = u_Color * (diff + hdriIntensity * hdriLight);
- vec3 specular = vec3(u_Specular) * spec;
- vec3 emission = u_Color * u_Emission;
-
- vec3 result = diffuse + specular + emission;
-
- if (u_IsSelected > 0)
- {
- float ndotv = max(dot(normal, viewDir), 0.0);
- float rim = 1.0 - ndotv;
- float width = clamp(u_OutlineWidth, 0.0, 1.0);
- float outlineMask = step(1.0 - u_OutlineWidth, rim);;
- result = mix(result, u_OutlineColor, outlineMask);
- }
-
- o_FragColor = vec4(result, 1.0);
-}
diff --git a/assets/shaders/sphere.slang b/assets/shaders/sphere.slang
new file mode 100644
index 0000000..0871438
--- /dev/null
+++ b/assets/shaders/sphere.slang
@@ -0,0 +1,67 @@
+uniform float4x4 u_ViewProjection;
+uniform float4x4 u_Transform;
+
+struct VSInput
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+};
+
+struct VSOutput
+{
+ float4 position : SV_Position;
+ float3 normal : TEXCOORD0;
+ float3 worldPos : TEXCOORD1;
+};
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ output.worldPos = mul(u_Transform, float4(input.position, 1.0)).xyz;
+ float3x3 normalMatrix = (float3x3)u_Transform;
+ output.normal = mul(normalMatrix, input.normal);
+ output.position = mul(u_ViewProjection, float4(output.worldPos, 1.0));
+ return output;
+}
+
+uniform float3 u_Color;
+uniform float u_Specular;
+uniform float u_Emission;
+uniform float3 u_LightPos;
+uniform float3 u_CameraPos;
+uniform int u_IsSelected;
+uniform float3 u_OutlineColor;
+uniform float u_OutlineWidth;
+SamplerCube u_HDRIEnvironment;
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ float3 normal = normalize(input.normal);
+ float3 lightDir = normalize(u_LightPos - input.worldPos);
+ float3 viewDir = normalize(u_CameraPos - input.worldPos);
+ float3 reflectDir = reflect(-lightDir, normal);
+
+ float3 hdriLight = u_HDRIEnvironment.Sample(normal).rgb;
+ float hdriIntensity = 0.3;
+
+ float diff = max(dot(normal, lightDir), 0.0);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
+
+ float3 diffuse = u_Color * (diff + hdriIntensity * hdriLight);
+ float3 specular = float3(u_Specular, u_Specular, u_Specular) * spec;
+ float3 emission = u_Color * u_Emission;
+
+ float3 result = diffuse + specular + emission;
+
+ if (u_IsSelected > 0)
+ {
+ float ndotv = max(dot(normal, viewDir), 0.0);
+ float rim = 1.0 - ndotv;
+ float outlineMask = step(1.0 - u_OutlineWidth, rim);
+ result = lerp(result, u_OutlineColor, outlineMask);
+ }
+
+ return float4(result, 1.0);
+}
diff --git a/assets/shaders/textured_quad.glsl b/assets/shaders/textured_quad.glsl
deleted file mode 100644
index 95f433d..0000000
--- a/assets/shaders/textured_quad.glsl
+++ /dev/null
@@ -1,28 +0,0 @@
-#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, 0.0, 1.0);
- v_TexCoord = a_TexCoord;
-}
-
-#type fragment
-
-#version 330 core
-
-in vec2 v_TexCoord;
-out vec4 o_FragColor;
-
-uniform sampler2D u_ScreenTexture;
-
-void main()
-{
- o_FragColor = texture(u_ScreenTexture, v_TexCoord);
-}
diff --git a/assets/shaders/textured_quad.slang b/assets/shaders/textured_quad.slang
new file mode 100644
index 0000000..52d46ed
--- /dev/null
+++ b/assets/shaders/textured_quad.slang
@@ -0,0 +1,28 @@
+struct VSInput
+{
+ float2 position : POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct VSOutput
+{
+ float4 position : SV_Position;
+ float2 texCoord : TEXCOORD0;
+};
+
+[shader("vertex")]
+VSOutput vertexMain(VSInput input)
+{
+ VSOutput output;
+ output.position = float4(input.position, 0.0, 1.0);
+ output.texCoord = input.texCoord;
+ return output;
+}
+
+Sampler2D u_ScreenTexture;
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ return u_ScreenTexture.Sample(input.texCoord);
+}