- BillboardInstance: per-instance uv sub-rect, feet anchor, turn, dithered alpha, flash; BillboardBatch::sharedTexture; Texture createEmpty/update/cellUV/cellAnchor/nearest - SpriteAtlas: fixed-cell runtime atlas with gutters - hd2d::ui: Octopath-style panels, fonts (Cinzel, EB Garamond), dialogue box with typewriter + portraits + choices, menus, nameplates, toasts, ImGui theme - DayCycle (dawn/day/dusk/night keyframes, sun + moon arcs), Weather overcast/mist/ lightning, night-aware presets, stars and moon in the sky - Hidden-window offscreen captures (Window visible=false, Renderer output FBO, OffscreenTarget); --screenshot never opens a window - Camera::worldToScreen; CMake usable via add_subdirectory (HD2D_BUILD_DEMO, HD2D_ENGINE_ASSET_DIR)
111 lines
3.9 KiB
C++
111 lines
3.9 KiB
C++
#pragma once
|
|
#include "hd2d/Camera.h"
|
|
#include "hd2d/RenderTarget.h"
|
|
#include "hd2d/Scene.h"
|
|
#include "hd2d/Shader.h"
|
|
|
|
#include <glm/glm.hpp>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
namespace hd2d {
|
|
|
|
// All tunable look parameters of the HD-2D pipeline.
|
|
struct RenderSettings {
|
|
// Shadows
|
|
int shadowMapSize = 4096;
|
|
float shadowExtent = 34.0f; // half-size of the sun's ortho frustum, world units
|
|
float shadowSoftness = 1.5f; // PCF radius in texels
|
|
|
|
// Dappled canopy light ("cookie" projected along the sun direction)
|
|
float cookieStrength = 0.55f;
|
|
float cookieScale = 0.13f;
|
|
float cookieSpeed = 0.05f;
|
|
float cookieCoverage = 0.48f; // fraction of light blocked
|
|
// God ray beams: the same implied canopy, sparser, applied inside the fog
|
|
float shaftStrength = 0.9f; // 1 = sun scatters only inside beams
|
|
float shaftCoverage = 0.62f; // higher = fewer, narrower beams
|
|
float shaftScale = 0.45f; // beam pattern frequency (larger = thinner beams)
|
|
|
|
// Volumetric fog + god rays
|
|
bool volumetrics = true;
|
|
glm::vec3 fogColor{0.30f, 0.36f, 0.45f}; // ambient fog in-scatter tint
|
|
float fogDensity = 0.008f;
|
|
float fogHeightFalloff = 0.15f;
|
|
float fogBaseHeight = 0.0f;
|
|
float fogNoise = 0.6f;
|
|
float fogAnisotropy = 0.62f; // Henyey-Greenstein g (forward scattering)
|
|
float godRayIntensity = 4.5f;
|
|
float fogMaxDistance = 90.0f;
|
|
int fogSteps = 56;
|
|
|
|
// Wind for foliage
|
|
glm::vec2 windDirection{0.8f, 0.35f};
|
|
float windStrength = 0.06f;
|
|
float windGustSpeed = 1.2f;
|
|
|
|
// Depth of field (tilt-shift miniature look)
|
|
bool dof = true;
|
|
float focusRange = 6.0f; // fully sharp half-width around the focus distance
|
|
float focusTransition = 12.0f; // distance over which blur ramps up
|
|
float dofMaxRadius = 9.0f; // max blur radius in half-res pixels
|
|
float tiltShift = 0.35f; // extra blur toward screen top/bottom
|
|
|
|
// Bloom
|
|
bool bloom = true;
|
|
float bloomStrength = 0.075f;
|
|
float bloomRadius = 1.0f;
|
|
|
|
// Color grading
|
|
float exposure = 1.0f;
|
|
float contrast = 1.08f;
|
|
float saturation = 1.12f;
|
|
glm::vec3 lift{0.012f, 0.010f, 0.025f}; // added to shadows
|
|
glm::vec3 gain{1.04f, 1.00f, 0.93f}; // multiplied into highlights
|
|
float vignette = 0.42f;
|
|
float chromaticAberration = 0.0015f;
|
|
float grain = 0.025f;
|
|
|
|
bool reflections = true;
|
|
bool occluderFade = true; // dither away 3D scenery between the camera and the player
|
|
|
|
// Screen-space ambient occlusion (contact darkening everywhere; the baked
|
|
// GroundOcclusion handles the large soft shade under trees)
|
|
bool ssao = true;
|
|
bool groundOcclusion = true; // use Scene::groundOcclusion (baked contact AO)
|
|
float ssaoRadius = 0.7f; // world units
|
|
float ssaoIntensity = 1.6f;
|
|
|
|
int maxRainDrops = 18000; // streaks drawn at Scene::rain = 1
|
|
};
|
|
|
|
class Renderer {
|
|
public:
|
|
Renderer();
|
|
~Renderer();
|
|
bool init(const std::string& shaderDir, int width, int height);
|
|
void resize(int width, int height);
|
|
bool reloadShaders();
|
|
void render(const Scene& scene, const Camera& camera, float time);
|
|
|
|
// Framebuffer the final tonemap pass writes to (0 = the window's
|
|
// backbuffer). render() leaves it bound with a full-size viewport, so UI
|
|
// drawn afterwards (DebugUI, ImGui) lands in it too. It must be at least
|
|
// the size given to init()/resize() and use a non-sRGB RGBA8 color
|
|
// attachment like the default framebuffer (the tonemap shader
|
|
// gamma-encodes itself); OffscreenTarget in Screenshot.h does this.
|
|
void setOutputFramebuffer(GLuint fbo) { outputFbo_ = fbo; }
|
|
GLuint outputFramebuffer() const { return outputFbo_; }
|
|
|
|
RenderSettings settings;
|
|
float gpuFrameMs() const { return gpuMs_; }
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl_;
|
|
float gpuMs_ = 0.0f;
|
|
GLuint outputFbo_ = 0;
|
|
};
|
|
|
|
} // namespace hd2d
|