We got a skybox

This commit is contained in:
2026-01-21 06:05:35 +01:00
parent b9878f2a06
commit a5b26f3bdd
27 changed files with 843 additions and 42 deletions

View File

@@ -0,0 +1,38 @@
#version 450
#extension GL_GOOGLE_include_directive : require
#include "bindless.glsl"
layout(location = 0) in vec3 localPos;
// Input equirectangular HDR texture
layout(location = 0) out vec4 outColor;
const float PI = 3.14159265359;
layout(push_constant) uniform PushConstants {
mat4 view;
mat4 proj;
uint skyboxId;
} pcs;
vec2 sampleSphericalMap(vec3 v) {
// Convert direction to spherical coordinates
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
uv /= vec2(2.0 * PI, PI);
uv += 0.5;
return uv;
}
void main() {
// Normalize direction vector
vec3 dir = normalize(localPos);
// Sample from equirectangular texture
vec2 uv = sampleSphericalMap(dir);
vec4 color = sampleTexture2DNearest(pcs.skyboxId, uv);
outColor = color;
}

View File

@@ -0,0 +1,42 @@
#version 450
// Hardcoded cube vertices (36 vertices for 12 triangles)
const vec3 positions[36] = vec3[](
// Front face
vec3(-1.0, -1.0, 1.0), vec3( 1.0, -1.0, 1.0), vec3( 1.0, 1.0, 1.0),
vec3( 1.0, 1.0, 1.0), vec3(-1.0, 1.0, 1.0), vec3(-1.0, -1.0, 1.0),
// Back face
vec3(-1.0, -1.0, -1.0), vec3(-1.0, 1.0, -1.0), vec3( 1.0, 1.0, -1.0),
vec3( 1.0, 1.0, -1.0), vec3( 1.0, -1.0, -1.0), vec3(-1.0, -1.0, -1.0),
// Top face
vec3(-1.0, 1.0, -1.0), vec3(-1.0, 1.0, 1.0), vec3( 1.0, 1.0, 1.0),
vec3( 1.0, 1.0, 1.0), vec3( 1.0, 1.0, -1.0), vec3(-1.0, 1.0, -1.0),
// Bottom face
vec3(-1.0, -1.0, -1.0), vec3( 1.0, -1.0, -1.0), vec3( 1.0, -1.0, 1.0),
vec3( 1.0, -1.0, 1.0), vec3(-1.0, -1.0, 1.0), vec3(-1.0, -1.0, -1.0),
// Right face
vec3( 1.0, -1.0, -1.0), vec3( 1.0, 1.0, -1.0), vec3( 1.0, 1.0, 1.0),
vec3( 1.0, 1.0, 1.0), vec3( 1.0, -1.0, 1.0), vec3( 1.0, -1.0, -1.0),
// Left face
vec3(-1.0, -1.0, -1.0), vec3(-1.0, -1.0, 1.0), vec3(-1.0, 1.0, 1.0),
vec3(-1.0, 1.0, 1.0), vec3(-1.0, 1.0, -1.0), vec3(-1.0, -1.0, -1.0)
);
// Hardcoded UVs aren't needed for cube map rendering
layout(location = 0) out vec3 localPos;
// Push constants for view and projection matrices
layout(push_constant) uniform PushConstants {
mat4 view;
mat4 proj;
uint skyboxId;
} pc;
void main() {
// Get hardcoded vertex position
vec3 pos = positions[gl_VertexIndex];
localPos = pos; // Pass to fragment shader
// Apply view and projection matrices
gl_Position = pc.proj * pc.view * vec4(pos, 1.0);
}

View File

@@ -0,0 +1,10 @@
#version 460
layout (location = 0) out vec2 outUV;
void main()
{
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
// gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f);
gl_Position = vec4(outUV * 2.0 - 1.0, 1.0, 1.0);
}

View File

@@ -18,7 +18,7 @@ void main()
{
MaterialData material = pcs.sceneData.materials.data[pcs.materialID];
vec4 diffuse = sampleTexture2DLinear(material.diffuseTex, inUV);
vec4 diffuse = sampleTexture2DLinear(material.diffuseTex, inUV) * material.baseColor;
outFragColor = diffuse;

View File

@@ -0,0 +1,35 @@
#version 450
#extension GL_GOOGLE_include_directive : require
#extension GL_EXT_nonuniform_qualifier : enable
#include "bindless.glsl"
layout(location = 0) in vec2 uv; // from fullscreen triangle: 0..2 range
layout(location = 0) out vec4 outColor;
layout(push_constant) uniform SkyboxPC {
mat4 invViewProj; // inverse(Proj * View) (your current setup)
vec4 cameraPos; // xyz = camera world position
uint skyboxTextureId; // index into textureCubes[]
} pcs;
void main()
{
// Fullscreen-triangle trick gives uv in [0..2]. Convert to [0..1].
vec2 uv01 = uv * 0.5;
// Build an NDC point on the far plane.
// Vulkan NDC is x,y in [-1..1], z in [0..1]. Using z=1 means "far".
vec4 ndc = vec4(uv01 * 2.0 - 1.0, 1.0, 1.0);
// Unproject to world space
vec4 world = pcs.invViewProj * ndc;
vec3 worldPos = world.xyz / world.w;
// Direction from camera through this pixel
vec3 dir = normalize(worldPos - pcs.cameraPos.xyz);
// Sample cubemap directly
outColor = sampleTextureCubeLinear(pcs.skyboxTextureId, dir);
// outColor = sampleTextureCubeNearest(pcs.skyboxTextureId, dir);
}