diff options
Diffstat (limited to 'assets/shaders')
| -rw-r--r-- | assets/shaders/blur.glsl | 60 | ||||
| -rw-r--r-- | assets/shaders/blur.slang | 60 | ||||
| -rw-r--r-- | assets/shaders/equirect_to_cubemap.glsl | 39 | ||||
| -rw-r--r-- | assets/shaders/equirect_to_cubemap.slang | 33 | ||||
| -rw-r--r-- | assets/shaders/geodesic.slang (renamed from assets/shaders/geodesic.glsl) | 327 | ||||
| -rw-r--r-- | assets/shaders/grid.glsl | 40 | ||||
| -rw-r--r-- | assets/shaders/grid.slang | 34 | ||||
| -rw-r--r-- | assets/shaders/skybox.glsl | 31 | ||||
| -rw-r--r-- | assets/shaders/skybox.slang | 23 | ||||
| -rw-r--r-- | assets/shaders/sphere.glsl | 69 | ||||
| -rw-r--r-- | assets/shaders/sphere.slang | 67 | ||||
| -rw-r--r-- | assets/shaders/textured_quad.glsl | 28 | ||||
| -rw-r--r-- | assets/shaders/textured_quad.slang | 28 |
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); +} |
