VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
sky.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis on 09.10.2025.
5//
6
7#include "sky.h"
8
9#include "spdlog/spdlog.h"
12#include "scene/scene.h"
13
14namespace visutwin::canvas
15{
16 Sky::Sky(const std::shared_ptr<GraphicsDevice>& device, Scene* scene) : _device(device), _scene(scene)
17 {
18 }
19
21 {
22 }
23
24 void Sky::setType(const int value)
25 {
26 if (_type != value) {
27 _type = value;
29 }
30 }
31
32 void Sky::setDepthWrite(const bool value)
33 {
34 _depthWrite = value;
35 }
36
38 {
39 if (!_scene) {
41 return;
42 }
43
44 // When atmosphere scattering is enabled, the sky mesh is needed even
45 // without a cubemap/envAtlas — the fragment shader computes sky color
46 // procedurally via nishitaScatter(). Create a 1×1 dummy texture and
47 // use it as the sky texture. Also install it as the scene's envAtlas
48 // so the texture binder properly binds it at fragment slot 2 (Metal
49 // requires valid textures at all declared slots even when not sampled).
50 if (_scene->atmosphereEnabled() && !_scene->skybox() && !_scene->envAtlas()) {
51 if (!_atmosphereDummyTexture) {
52 TextureOptions dummyOpts;
53 dummyOpts.width = 1;
54 dummyOpts.height = 1;
55 dummyOpts.mipmaps = false;
58 dummyOpts.name = "atmosphere-dummy";
59 _atmosphereDummyTexture = std::make_shared<Texture>(_device.get(), dummyOpts);
60 // Initialize with black pixels so the GPU texture is not reading uninitialized memory.
61 const uint8_t black[4] = {0, 0, 0, 255};
62 _atmosphereDummyTexture->setLevelData(0, black, sizeof(black));
63 _atmosphereDummyTexture->upload();
64 }
65 if (_atmosphereDummyTexture) {
66 // Use SKYTYPE_ATMOSPHERE (sphere mesh + infinite behavior).
67 // The box mesh creates visible seams at face edges; a sphere has
68 // continuous topology so view directions interpolate smoothly.
69 spdlog::debug("Sky::updateSkyMesh: creating SkyMesh for atmosphere (sphere, layers={})",
70 _scene->layers() ? "yes" : "no");
72 _skyMesh = std::make_unique<SkyMesh>(_device, _scene, &_node, _atmosphereDummyTexture.get(), SKYTYPE_ATMOSPHERE);
73 return;
74 }
75 }
76
77 // need either skybox cubemap or envAtlas to create the sky mesh
78 if (!_scene->skybox() && !_scene->envAtlas()) {
79 spdlog::debug("Sky::updateSkyMesh: no scene or skybox/envAtlas — resetting");
81 return;
82 }
83
84 // _getSkyboxTex() priority:
85 // skyboxMip == 0: prefer skyboxCubeMap > envAtlas
86 // skyboxMip > 0: prefer envAtlas (blurred mip levels)
87 Texture* skyTex = nullptr;
88 if (_scene->skyboxMip() == 0 && _scene->skybox()) {
89 skyTex = _scene->skybox();
90 } else {
91 skyTex = _scene->envAtlas();
92 }
93
94 if (!skyTex) {
95 // Fallback: use whatever is available
96 skyTex = _scene->skybox() ? _scene->skybox() : _scene->envAtlas();
97 }
98
99 if (!skyTex) {
100 resetSkyMesh();
101 return;
102 }
103
104 spdlog::debug("Sky::updateSkyMesh: creating SkyMesh (type={}, tex={}x{}, cubemap={}, layers={})",
105 _type, skyTex->width(), skyTex->height(),
106 skyTex->isCubemap() ? "yes" : "no",
107 _scene->layers() ? "yes" : "no");
108 resetSkyMesh();
109 _skyMesh = std::make_unique<SkyMesh>(_device, _scene, &_node, skyTex, _type);
110 }
111
113 {
114 _skyMesh.reset();
115 }
116
118 {
119 if (!_skyMesh) {
121 }
122 return _skyMesh.get();
123 }
124
126 {
127 // transform the local center by the sky node's world transform
128 return const_cast<GraphNode&>(_node).worldTransform().transformPoint(_center);
129 }
130}
Hierarchical scene graph node with local/world transforms and parent-child relationships.
Definition graphNode.h:28
Container for the scene graph, lighting environment, fog, skybox, and layer composition.
Definition scene.h:29
Vector3 centerWorldPos() const
Definition sky.cpp:125
void updateSkyMesh()
Definition sky.cpp:37
SkyMesh * skyMesh()
Definition sky.cpp:117
void setType(int value)
Definition sky.cpp:24
void setDepthWrite(bool value)
Definition sky.cpp:32
Sky(const std::shared_ptr< GraphicsDevice > &device, Scene *scene)
Definition sky.cpp:16
GPU texture resource supporting 2D, cubemap, volume, and array formats with mipmap management.
Definition texture.h:57
uint32_t width() const
Definition texture.h:63
bool isCubemap() const
Definition texture.h:85
uint32_t height() const
Definition texture.h:65
3D vector for positions, directions, and normals with multi-backend SIMD acceleration.
Definition vector3.h:29