Files
minecraft-pt/shaders/Lib/Programs/Composite/SkyImage_CS.glsl
T

76 lines
2.4 KiB
GLSL

// MinecraftPT — SkyImage_CS
// Precomputes the sky panorama (skyBox2D, 3:2 cubemap cross) using the analytic
// atmosphere model, for sampling by the path tracer and reflections.
#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
#include "/Lib/BasicFunctions/LightingConstants.glsl"
#include "/Lib/BasicFunctions/PrecomputedAtmosphere.glsl"
#include "/Lib/IndividualFunctions/EndSky.glsl"
#include "/Lib/IndividualFunctions/PlanarClouds.glsl"
const ivec3 workGroups = ivec3(int(ceil(float(SKYBOX_RESOLUTION_X) / 8.0)), int(ceil(float(SKYBOX_RESOLUTION_Y) / 8.0)), 1);
layout (local_size_x = 8, local_size_y = 8) in;
layout (rgba16f) uniform writeonly image2D img_skyBox2D;
void main(){
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
// Panorama layout: 3:2 cross (like a cubemap cross folded)
vec2 resolution = vec2(SKYBOX_RESOLUTION_X, SKYBOX_RESOLUTION_Y);
vec2 uv = (vec2(texel) + 0.5) / resolution;
// Determine face and local UV
float tileX = SKYBOX_RESOLUTION / resolution.x; // 1/3
float tileY = SKYBOX_RESOLUTION / resolution.y; // 1/2
int face = int(floor(uv.x / tileX));
vec2 faceUV = vec2(
(uv.x - float(face) * tileX) / tileX,
(uv.y - float(face < 3 ? 0 : 1) * tileY) / tileY
);
faceUV = faceUV * 2.0 - 1.0;
// Cubemap cross mapping (Standard OpenGL cross layout, 4x3 grid):
// faces: 0=+X, 1=-X, 2=+Y, 3=-Y, 4=+Z, 5=-Z (top row: +X -X +Y; bottom row: -Y +Z -Z)
// This panorama is a 3x2 layout, so: top row = +X, -X, +Y; bottom row = -Y, +Z, -Z
vec3 dir;
if (face == 0){ // +X
dir = vec3(1.0, -faceUV.y, -faceUV.x);
}else if (face == 1){ // -X
dir = vec3(-1.0, -faceUV.y, faceUV.x);
}else if (face == 2){ // +Y
dir = vec3(faceUV.x, 1.0, -faceUV.y);
}else if (face == 3){ // -Y
dir = vec3(faceUV.x, -1.0, faceUV.y);
}else if (face == 4){ // +Z
dir = vec3(faceUV.x, -faceUV.y, 1.0);
}else{ // -Z
dir = vec3(-faceUV.x, -faceUV.y, -1.0);
}
dir = normalize(dir);
vec3 sunDir = GetSunDirWorld();
// Sky radiance from analytic atmosphere
vec3 color = GetSkyRadiance(dir, sunDir);
// Stars at night
float night = 1.0 - curve(saturate(sunDir.y * 10.0 + 0.5));
if (night > 0.5){
float stars = 0.0;
vec3 starSeed = floor(dir * 64.0);
float star = hash1(starSeed);
stars = step(0.998, star) * 2.0;
color += vec3(1.0, 1.0, 1.0) * stars * night;
}
// End dimension sky
#ifdef DIMENSION_END
color = GetEndSky(dir, sunDir);
#endif
imageStore(img_skyBox2D, texel, vec4(color, 0.0));
}