We got a skybox
This commit is contained in:
38
destrum/assets_src/shaders/cubemap.frag
Normal file
38
destrum/assets_src/shaders/cubemap.frag
Normal 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;
|
||||
}
|
||||
42
destrum/assets_src/shaders/cubemap.vert
Normal file
42
destrum/assets_src/shaders/cubemap.vert
Normal 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);
|
||||
}
|
||||
10
destrum/assets_src/shaders/fullscreen_triangle.vert
Normal file
10
destrum/assets_src/shaders/fullscreen_triangle.vert
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
35
destrum/assets_src/shaders/skybox.frag
Normal file
35
destrum/assets_src/shaders/skybox.frag
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user