Skip to content

Commit 9873058

Browse files
committed
Almost done with PBR SKY
1 parent 6ea2db0 commit 9873058

File tree

11 files changed

+239
-52
lines changed

11 files changed

+239
-52
lines changed

include/engine/core/scene/skybox.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ namespace Core {
2020
Settings for Procedural Sky Rendering
2121
*/
2222
struct SkySettings {
23-
float sunElevationDeg = 45.0f; // 0=horizon, 90=zenith
24-
uint32_t month = 0; // 0-11, January to December
25-
float altitude = 0.5f; // km
26-
SkyAerosolType aerosol = SkyAerosolType::URBAN;
27-
Vec4 groundAlbedo = Vec4(0.3);
28-
uint32_t resolution = 1024;
29-
bool useForIBL = true;
30-
UpdateType updateType = UpdateType::PER_FRAME;
23+
float sunElevationDeg = 45.0f; // 0=horizon, 90=zenith
24+
uint32_t month = 0; // 0-11, January to December
25+
float altitude = 0.5f; // km
26+
SkyAerosolType aerosol = SkyAerosolType::URBAN;
27+
Vec4 groundAlbedo = Vec4(0.3);
28+
float aerosolTurbidity = 1.0f;
29+
uint32_t resolution = 512;
30+
bool useForIBL = true;
31+
UpdateType updateType = UpdateType::ON_DEMAND;
3132
};
3233
/*
3334
Skybox for rendering enviroments and IBL
@@ -114,11 +115,19 @@ class Skybox
114115
m_irradianceResolution = r;
115116
m_updateEnviroment = true;
116117
}
118+
inline void set_sky_type(EnviromentType type) {
119+
m_updateEnviroment = true;
120+
m_envType = type;
121+
}
122+
inline EnviromentType get_sky_type() const {
123+
return m_envType;
124+
}
117125
/*
118126
Procedural Sky
119127
*/
120128
inline void set_sky_settings(SkySettings settings) {
121-
m_proceduralSky = settings;
129+
m_proceduralSky = settings;
130+
m_updateEnviroment = true;
122131
}
123132
/*
124133
Procedural Sky

include/engine/tools/widgets.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,13 @@ class ExplorerWidget : public Widget
313313
Core::Object3D* m_selectedObject{nullptr};
314314

315315
bool m_showRendererSettings{false};
316+
bool m_showSkySettings{false};
316317

317318
virtual void render();
318319

319320
void displayObject(Core::Object3D* const obj, int& counter);
320321
void displayRendererSettings();
322+
void displaySkySettings();
321323

322324
public:
323325
ExplorerWidget(Core::Scene* scene, Systems::BaseRenderer* renderer)

resources/shaders/env/panorama_converter.glsl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ layout(location = 0) in vec2 otexCoord;
5353

5454
layout(location = 0) out vec4 fragmentColor;
5555

56+
layout(push_constant) uniform Settings {
57+
int type;
58+
} settings;
59+
5660
layout(set = 0, binding = 0) uniform sampler2D u_panorama;
61+
layout(set = 0, binding = 3) uniform sampler2D u_panoramaProcedural;
5762

5863
vec3 uvToXYZ(int face, vec2 uv)
5964
{
@@ -90,7 +95,7 @@ vec3 panoramaToCubeMap(int face, vec2 texCoord)
9095
vec3 direction = normalize(scan);
9196
vec2 src = dirToUV(direction);
9297

93-
return texture(u_panorama, src).rgb;
98+
return settings.type == 0 ? texture( u_panorama , src).rgb : texture( u_panoramaProcedural , src).rgb;
9499
}
95100

96101

resources/shaders/env/sky_generation.glsl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ void main() {
1818

1919
layout(location = 0) in vec2 v_uv;
2020

21+
layout(push_constant) uniform Settings {
22+
SkySettings sky;
23+
} settings;
2124
layout(set = 0, binding = 0) uniform sampler2D transmitanceLUT;
2225

2326
layout(location = 0) out vec4 outColor;
2427

2528
vec4 compute_inscattering(vec3 ray_origin, vec3 ray_dir, float t_d, out vec4 transmittance)
2629
{
27-
vec3 sun_dir = get_sun_direction(5.0);
30+
vec3 sun_dir = get_sun_direction(settings.sky.sunElevationDeg);
2831
float cos_theta = dot(-ray_dir, sun_dir);
2932

3033
float molecular_phase = molecular_phase_function(cos_theta);
@@ -51,6 +54,8 @@ vec4 compute_inscattering(vec3 ray_origin, vec3 ray_dir, float t_d, out vec4 tra
5154
vec4 extinction;
5255
get_atmosphere_collision_coefficients(
5356
altitude,
57+
settings.sky.month,
58+
settings.sky.aerosolTurbidity,
5459
aerosol_absorption, aerosol_scattering,
5560
molecular_absorption, molecular_scattering,
5661
extinction);
@@ -59,7 +64,7 @@ vec4 compute_inscattering(vec3 ray_origin, vec3 ray_dir, float t_d, out vec4 tra
5964
transmitanceLUT, sample_cos_theta, normalized_altitude);
6065

6166
vec4 ms = get_multiple_scattering(
62-
transmitanceLUT, sample_cos_theta, normalized_altitude,
67+
transmitanceLUT, settings.sky.groundAlbedo, sample_cos_theta, normalized_altitude,
6368
distance_to_earth_center);
6469

6570
vec4 S = sun_spectral_irradiance *
@@ -93,12 +98,13 @@ void main()
9398
cos(elev) * sin(azimuth),
9499
sin(elev));
95100

101+
const float EYE_DISTANCE_TO_EARTH_CENTER = EARTH_RADIUS + settings.sky.altitude;
96102
vec3 ray_origin = vec3(0.0, 0.0, EYE_DISTANCE_TO_EARTH_CENTER);
97103

98104
float atmos_dist = ray_sphere_intersection(ray_origin, ray_dir, ATMOSPHERE_RADIUS);
99105
float ground_dist = ray_sphere_intersection(ray_origin, ray_dir, EARTH_RADIUS);
100106
float t_d;
101-
if (EYE_ALTITUDE < ATMOSPHERE_THICKNESS) {
107+
if (settings.sky.altitude < ATMOSPHERE_THICKNESS) {
102108
// We are inside the atmosphere
103109
if (ground_dist < 0.0) {
104110
// No ground collision, use the distance to the outer atmosphere

resources/shaders/env/sky_projection.glsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void main()
5757
// Undo the non-linear transformation from the sky-view LUT
5858
float elev = sqrt(abs(theta) / (PI * 0.5)) * sign(theta) * 0.5 + 0.5;
5959

60-
vec3 col = texture(sky, vec2(azimuth, elev)).rgb;
60+
vec3 col = texture(sky, vec2(azimuth, 1.0 -elev)).rgb;
6161

6262
// #if TONEMAPPING_TECHNIQUE == 0
6363
// // Apply exposure

resources/shaders/env/sky_tt_compute.glsl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ void main() {
2626

2727
layout(location = 0) in vec2 v_uv;
2828

29+
layout(push_constant) uniform Settings {
30+
SkySettings sky;
31+
} settings;
2932

3033
layout(location = 0) out vec4 outColor;
3134

@@ -56,6 +59,8 @@ void main()
5659

5760
get_atmosphere_collision_coefficients(
5861
altitude,
62+
settings.sky.month,
63+
settings.sky.aerosolTurbidity,
5964
aerosol_absorption, aerosol_scattering,
6065
molecular_absorption, molecular_scattering,
6166
extinction);

resources/shaders/include/sky.glsl

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
// Configurable parameters
2+
struct SkySettings {
3+
float sunElevationDeg;
4+
int month;
5+
float altitude;
6+
int aerosol;
7+
8+
vec4 groundAlbedo;
9+
10+
float aerosolTurbidity;
11+
int resolution;
12+
bool useForIBL;
13+
int updateType;
14+
};
215

316
#define ANIMATE_SUN 0
4-
// 0=equirectangular, 1=fisheye, 2=projection
5-
#define CAMERA_TYPE 2
17+
618
// 0=Background, 1=Desert Dust, 2=Maritime Clean, 3=Maritime Mineral,
719
// 4=Polar Antarctic, 5=Polar Artic, 6=Remote Continental, 7=Rural, 8=Urban
820
#define AEROSOL_TYPE 8
921

10-
const float SUN_ELEVATION_DEGREES = 0.0; // 0=horizon, 90=zenith
11-
const float EYE_ALTITUDE = 0.5; // km
12-
const int MONTH = 0; // 0-11, January to December
1322
const float AEROSOL_TURBIDITY = 1.0;
14-
const vec4 GROUND_ALBEDO = vec4(0.3);
1523

1624
// Ray marching steps. More steps mean better accuracy but worse performance
1725
const int TRANSMITTANCE_STEPS = 32;
@@ -49,9 +57,8 @@ const float gg = g*g;
4957
const float EARTH_RADIUS = 6371.0; // km
5058
const float ATMOSPHERE_THICKNESS = 100.0; // km
5159
const float ATMOSPHERE_RADIUS = EARTH_RADIUS + ATMOSPHERE_THICKNESS;
52-
const float EYE_DISTANCE_TO_EARTH_CENTER = EARTH_RADIUS + EYE_ALTITUDE;
53-
const float SUN_ZENITH_COS_ANGLE = cos(radians(90.0 - SUN_ELEVATION_DEGREES));
54-
const vec3 SUN_DIR = vec3(-sqrt(1.0 - SUN_ZENITH_COS_ANGLE*SUN_ZENITH_COS_ANGLE), 0.0, SUN_ZENITH_COS_ANGLE);
60+
61+
5562

5663
#if ENABLE_SPECTRAL == 1
5764
// Extraterrestial Solar Irradiance Spectra, units W * m^-2 * nm^-1
@@ -162,14 +169,10 @@ const float aerosol_background_divided_by_base_density = aerosol_background_dens
162169

163170
//-----------------------------------------------------------------------------
164171

165-
vec3 get_sun_direction(float time)
172+
vec3 get_sun_direction(float sunElevationDeg)
166173
{
167-
#if ANIMATE_SUN == 0
168-
return SUN_DIR;
169-
#else
170-
float a = sin(time*0.5 - 1.5) * 0.55 + 0.45;
171-
return vec3(-sqrt(1.0 - a*a), 0.0, a);
172-
#endif
174+
float sunZenithCosAngle = cos(radians(90.0 - sunElevationDeg));
175+
return vec3(-sqrt(1.0 - sunZenithCosAngle*sunZenithCosAngle), 0.0, sunZenithCosAngle);
173176
}
174177

175178
/*
@@ -216,7 +219,7 @@ float aerosol_phase_function(float cos_theta)
216219
return INV_4PI * (1.0 - gg) / (den * sqrt(den));
217220
}
218221

219-
vec4 get_multiple_scattering(sampler2D transmittance_lut, float cos_theta, float normalized_height, float d)
222+
vec4 get_multiple_scattering(sampler2D transmittance_lut, vec4 groundAlbedo, float cos_theta, float normalized_height, float d)
220223
{
221224
#if ENABLE_MULTIPLE_SCATTERING == 1
222225
// Solid angle subtended by the planet from a point at d distance
@@ -230,7 +233,7 @@ vec4 get_multiple_scattering(sampler2D transmittance_lut, float cos_theta, float
230233
transmittance_from_lut(transmittance_lut, 1.0, normalized_height);
231234

232235
// 2nd order scattering from the ground
233-
vec4 L_ground = PHASE_ISOTROPIC * omega * (GROUND_ALBEDO / PI) * T_to_ground * T_ground_to_sample * cos_theta;
236+
vec4 L_ground = PHASE_ISOTROPIC * omega * (groundAlbedo / PI) * T_to_ground * T_ground_to_sample * cos_theta;
234237

235238
// Fit of Earth's multiple scattering coming from other points in the atmosphere
236239
vec4 L_ms = 0.02 * vec4(0.217, 0.347, 0.594, 1.0) * (1.0 / (1.0 + 5.0 * exp(-17.92 * cos_theta)));
@@ -254,12 +257,12 @@ vec4 get_molecular_scattering_coefficient(float h)
254257
* Return the molecular volume absorption coefficient (km^-1) for a given altitude
255258
* in kilometers.
256259
*/
257-
vec4 get_molecular_absorption_coefficient(float h)
260+
vec4 get_molecular_absorption_coefficient(float h, int month)
258261
{
259262
h += 1e-4; // Avoid division by 0
260263
float t = log(h) - 3.22261;
261264
float density = 3.78547397e20 * (1.0 / h) * exp(-t * t * 5.55555555);
262-
return ozone_absorption_cross_section * ozone_mean_monthly_dobson[MONTH] * density;
265+
return ozone_absorption_cross_section * ozone_mean_monthly_dobson[month] * density;
263266
}
264267

265268
float get_aerosol_density(float h)
@@ -277,6 +280,8 @@ float get_aerosol_density(float h)
277280
* atmospheric medium for a given point at an altitude h.
278281
*/
279282
void get_atmosphere_collision_coefficients(in float h,
283+
in int month,
284+
in float turbidity,
280285
out vec4 aerosol_absorption,
281286
out vec4 aerosol_scattering,
282287
out vec4 molecular_absorption,
@@ -289,10 +294,10 @@ void get_atmosphere_collision_coefficients(in float h,
289294
aerosol_scattering = vec4(0.0);
290295
#else
291296
float aerosol_density = get_aerosol_density(h);
292-
aerosol_absorption = aerosol_absorption_cross_section * aerosol_density * AEROSOL_TURBIDITY;
293-
aerosol_scattering = aerosol_scattering_cross_section * aerosol_density * AEROSOL_TURBIDITY;
297+
aerosol_absorption = aerosol_absorption_cross_section * aerosol_density * turbidity;
298+
aerosol_scattering = aerosol_scattering_cross_section * aerosol_density * turbidity;
294299
#endif
295-
molecular_absorption = get_molecular_absorption_coefficient(h);
300+
molecular_absorption = get_molecular_absorption_coefficient(h, month);
296301
molecular_scattering = get_molecular_scattering_coefficient(h);
297302
extinction = aerosol_absorption + aerosol_scattering + molecular_absorption + molecular_scattering;
298303
}

src/core/passes/enviroment_pass.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ void EnviromentPass::setup_uniforms(std::vector<Graphics::Frame>& frames) {
3939
LayoutBinding panoramaTextureBinding(UniformDataType::UNIFORM_COMBINED_IMAGE_SAMPLER, SHADER_STAGE_FRAGMENT, 0);
4040
LayoutBinding enviromentTextureBinding(UniformDataType::UNIFORM_COMBINED_IMAGE_SAMPLER, SHADER_STAGE_FRAGMENT, 1);
4141
LayoutBinding auxBufferBinding(UniformDataType::UNIFORM_BUFFER, SHADER_STAGE_FRAGMENT, 2);
42-
m_descriptorPool.set_layout(0, {panoramaTextureBinding, enviromentTextureBinding, auxBufferBinding});
42+
LayoutBinding proceduralPanoramaTextureBinding(
43+
UniformDataType::UNIFORM_COMBINED_IMAGE_SAMPLER, SHADER_STAGE_FRAGMENT, 3);
44+
m_descriptorPool.set_layout(
45+
0, {panoramaTextureBinding, enviromentTextureBinding, auxBufferBinding, proceduralPanoramaTextureBinding});
4346

4447
m_descriptorPool.allocate_descriptor_set(0, &m_envDescriptorSet);
4548

@@ -83,6 +86,7 @@ void EnviromentPass::setup_shader_passes() {
8386
{UV_ATTRIBUTE, true},
8487
{TANGENT_ATTRIBUTE, false},
8588
{COLOR_ATTRIBUTE, false}};
89+
converterPass->settings.pushConstants = {PushConstant(SHADER_STAGE_FRAGMENT, sizeof(float))};
8690

8791
converterPass->build_shader_stages();
8892
converterPass->build(m_descriptorPool);
@@ -130,11 +134,17 @@ void EnviromentPass::render(Graphics::Frame& currentFrame, Scene* const scene, u
130134
cmd.set_viewport(m_imageExtent);
131135
ShaderPass* shaderPass = m_shaderPasses["converter"];
132136
cmd.bind_shaderpass(*shaderPass);
137+
int panoramaType = static_cast<int>(scene->get_skybox()->get_sky_type());
138+
cmd.push_constants(*shaderPass, SHADER_STAGE_FRAGMENT, &panoramaType, sizeof(float));
133139
cmd.bind_descriptor_set(m_envDescriptorSet, 0, *shaderPass);
134140
cmd.draw_geometry(*get_VAO(BasePass::vignette));
135141
cmd.end_renderpass(m_renderpass, m_framebuffers[0]);
136142

137143
/*Draw Diffuse Irradiance*/
144+
if (scene->get_skybox()->get_sky_type() == EnviromentType::PROCEDURAL_ENV &&
145+
!scene->get_skybox()->get_sky_settings().useForIBL)
146+
goto jump;
147+
138148
cmd.begin_renderpass(m_renderpass, m_framebuffers[1]);
139149
cmd.set_viewport(m_irradianceResolution);
140150
shaderPass = m_shaderPasses["irr"];
@@ -143,13 +153,14 @@ void EnviromentPass::render(Graphics::Frame& currentFrame, Scene* const scene, u
143153
cmd.draw_geometry(*get_VAO(BasePass::vignette));
144154
cmd.end_renderpass(m_renderpass, m_framebuffers[1]);
145155

156+
jump:
146157
/* Everything is updated, set to sleep */
147158
scene->get_skybox()->update_enviroment(false);
148159
set_active(false);
149160
}
150161

151162
void EnviromentPass::link_previous_images(std::vector<Graphics::Image> images) {
152-
// m_descriptorPool.update_descriptor(&images[0], LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_envDescriptorSet, 0);
163+
m_descriptorPool.update_descriptor(&images[0], LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_envDescriptorSet, 3);
153164
}
154165
void EnviromentPass::update_uniforms(uint32_t frameIndex, Scene* const scene) {
155166
if (!scene->get_skybox())

src/core/passes/sky_pass.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void SkyPass::setup_shader_passes() {
6161
{TANGENT_ATTRIBUTE, false},
6262
{COLOR_ATTRIBUTE, false}};
6363

64+
6465
ttPass->build_shader_stages();
6566
ttPass->build(m_descriptorPool);
6667

@@ -71,6 +72,7 @@ void SkyPass::setup_shader_passes() {
7172
skyPass->settings.pushConstants = {PushConstant(SHADER_STAGE_FRAGMENT, sizeof(Core::SkySettings))};
7273
skyPass->settings.descriptorSetLayoutIDs = ttPass->settings.descriptorSetLayoutIDs;
7374
skyPass->graphicSettings.attributes = ttPass->graphicSettings.attributes;
75+
7476

7577
skyPass->build_shader_stages();
7678
skyPass->build(m_descriptorPool);
@@ -134,4 +136,30 @@ void SkyPass::render(Graphics::Frame& currentFrame, Scene* const scene, uint32_t
134136

135137
} // namespace Core
136138

139+
// struct Matrix4x4 {
140+
// float m[4][4];
141+
// };
142+
143+
// struct EulerAngles {
144+
// float pitch; // Rotation around X-axis
145+
// float yaw; // Rotation around Y-axis
146+
// float roll; // Rotation around Z-axis
147+
// };
148+
149+
// // Function to extract Euler angles from the view matrix
150+
// EulerAngles extractEulerAnglesFromViewMatrix(const Matrix4x4& viewMatrix) {
151+
// // Extract the rotation matrix (upper-left 3x3)
152+
// float r00 = viewMatrix.m[0][0], r01 = viewMatrix.m[0][1], r02 = viewMatrix.m[0][2];
153+
// float r10 = viewMatrix.m[1][0], r11 = viewMatrix.m[1][1], r12 = viewMatrix.m[1][2];
154+
// float r20 = viewMatrix.m[2][0], r21 = viewMatrix.m[2][1], r22 = viewMatrix.m[2][2];
155+
156+
// // Calculate yaw, pitch, and roll
157+
// float yaw = std::atan2(r10, r00); // Yaw (rotation around Y-axis)
158+
// float pitch = std::atan2(-r20, std::sqrt(r00 * r00 + r10 * r10)); // Pitch (rotation around X-axis)
159+
// float roll = std::atan2(r21, r22); // Roll (rotation around Z-axis)
160+
161+
// // Return Euler angles
162+
// return { pitch, yaw, roll };
163+
// }
164+
137165
VULKAN_ENGINE_NAMESPACE_END

0 commit comments

Comments
 (0)