mitiru::render
Higher-level renderer built on top of `mitiru::gfx`. Sprite, mesh, particle, post-process, and 3D-scene rendering.
Higher-level renderer built on top of `mitiru::gfx`. Sprite, mesh, particle, post-process, and 3D-scene rendering.
Free functions and typedefs
inline void mitiru::validate::DrawCallValidator::attach(Screen& screen)inline void mitiru::validate::DrawCallValidator::drawDebugOverlay(Screen& screen) constclass Screen 92
`using TtDrawFunc = void(*)(void* font, Screen& scr, float x, float y, std::string_view text, float fontSize, const sgc::Colorf& color);`using TtMeasureFunc = sgc::Vec2f(*)(void* font, std::string_view text, float fontSize);using SdfDrawFunc = TtDrawFunc;using SdfMeasureFunc = TtMeasureFunc;using Transform2D = render::Transform2D;enum `TextAlignH` { Left, Center, Right }enum `TextAlignV` { Top, Middle, Bottom }enum `PatternType` { Checkerboard, HStripes, VStripes, DiagStripes, Dots }explicit Screen(int width, int height) noexceptvoid setPipeline(render::RenderPipeline2D* pipeline) noexcept[[nodiscard]] render::RenderPipeline2D* pipeline() const noexceptvoid setTrueTypeFont(void* font, TtDrawFunc drawFn, TtMeasureFunc measureFn) noexcept[[nodiscard]] void* trueTypeFont() const noexceptvoid setSdfFont(void* font, SdfDrawFunc drawFn, SdfMeasureFunc measureFn) noexcept[[nodiscard]] void* sdfFont() const noexceptvoid clearSdfFont() noexceptvoid registerFont(const std::string& name, void* font, TtDrawFunc drawFn, TtMeasureFunc measureFn)void setFont(const std::string& name)void setValidator(validate::DrawCallValidator* validator) noexcept[[nodiscard]] validate::DrawCallValidator* validator() const noexceptvoid clear(const sgc::Colorf& color = sgc::Colorf{0.0f, 0.0f, 0.0f, 1.0f})void drawStyledRect(const sgc::Rectf& rect, const render::Style& style)void drawStyledCircle(const sgc::Vec2f& center, float radius, const render::Style& style)void draw(const render::ShapeData& shape, const render::Style& style)void drawZigzagEdge(const sgc::Rectf& rect, const render::ZigzagStyle& zs)void drawScanlines(const sgc::Rectf& rect, float lineHeight, const sgc::Colorf& color)void drawDashedLine(const sgc::Vec2f& from, const sgc::Vec2f& to, float thickness, float dashLen, float gapLen, const sgc::Colorf& color)void drawRect(const sgc::Rectf& rect, const sgc::Colorf& color)void drawRectFrame(const sgc::Rectf& rect, const sgc::Colorf& color, float thickness = 1.0f)void drawRoundedRect(const sgc::Rectf& rect, const sgc::Colorf& color, float radius = 8.0f)void drawRoundedRectFrame(const sgc::Rectf& rect, const sgc::Colorf& color, float radius = 8.0f, float thickness = 1.0f)void drawPie(const sgc::Vec2f& center, float radius, float startAngle, float endAngle, const sgc::Colorf& color)void drawArc(const sgc::Vec2f& center, float radius, float startAngle, float endAngle, const sgc::Colorf& color, float thickness = 2.0f)void drawTriangle(const sgc::Vec2f& p0, const sgc::Vec2f& p1, const sgc::Vec2f& p2, const sgc::Colorf& color)void drawCircle(const sgc::Vec2f& center, float radius, const sgc::Colorf& color)void drawCircleFrame(const sgc::Vec2f& center, float radius, const sgc::Colorf& color, float thickness = 2.0f)void drawLine(const sgc::Vec2f& from, const sgc::Vec2f& to, const sgc::Colorf& color, float thickness = 1.0f)void drawText(const sgc::Vec2f& position, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f)[[nodiscard]] sgc::Vec2f measureText(std::string_view text, float fontSize = 16.0f) const[[nodiscard]] bool textFitsInRect(const sgc::Rectf& rect, const sgc::Vec2f& position, std::string_view text, float fontSize = 16.0f) constvoid drawTextClipped(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, float padX = 0.0f, float padY = 0.0f)void drawTextInRect(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, TextAlignH alignH = TextAlignH::Left, TextAlignV alignV = TextAlignV::Top, float padX = 4.0f, float padY = 2.0f)void drawTextWrapped(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, float padX = 4.0f, float padY = 2.0f, float lineSpacing = 1.4f)void drawTextHQ(const sgc::Vec2f& position, std::string_view text, const sgc::Colorf& color, float fontSize)void drawPolygon(const std::vector<sgc::Vec2f>& points, const sgc::Colorf& color)void drawEllipse(const sgc::Vec2f& center, float radiusX, float radiusY, const sgc::Colorf& color)void drawRing(const sgc::Vec2f& center, float outerRadius, float innerRadius, const sgc::Colorf& color)void drawGradientRectH(const sgc::Rectf& rect, const sgc::Colorf& leftColor, const sgc::Colorf& rightColor)void drawGradientRect4(const sgc::Rectf& rect, const sgc::Colorf& topLeft, const sgc::Colorf& topRight, const sgc::Colorf& bottomRight, const sgc::Colorf& bottomLeft)void drawRoundedRect4(const sgc::Rectf& rect, const sgc::Colorf& color, float tl, float tr, float br, float bl)void drawRectRotated(const sgc::Rectf& rect, const sgc::Colorf& color, float angleDeg)void drawTextWithShadow(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize, const sgc::Colorf& shadowColor, float shadowOffsetX = 2.0f, float shadowOffsetY = 2.0f, TextAlignH alignH = TextAlignH::Center, TextAlignV alignV = TextAlignV::Middle)void drawTextOutlined(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, const sgc::Colorf& outlineColor, float outlineWidth = 1.0f, float fontSize = 16.0f, TextAlignH alignH = TextAlignH::Center, TextAlignV alignV = TextAlignV::Middle)void drawTextStrikethrough(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, TextAlignH alignH = TextAlignH::Left, TextAlignV alignV = TextAlignV::Middle)void drawTextBold(const sgc::Rectf& rect, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, TextAlignH alignH = TextAlignH::Left, TextAlignV alignV = TextAlignV::Middle)void drawTextSpaced(const sgc::Vec2f& position, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f, float letterSpacing = 2.0f)void drawGradientRect(const sgc::Rectf& rect, const sgc::Colorf& topColor, const sgc::Colorf& bottomColor)void drawRectPattern(const sgc::Rectf& rect, PatternType pattern, float cellSize, const sgc::Colorf& color1, const sgc::Colorf& color2)void drawInnerShadow(const sgc::Rectf& rect, const sgc::Colorf& shadowColor, float blurSize = 8.0f, float offsetX = 0.0f, float offsetY = 0.0f)void drawFrostedRect(const sgc::Rectf& rect, const sgc::Colorf& tintColor, int layers = 3)void drawRectPerspective(const sgc::Rectf& rect, const sgc::Colorf& color, bool vanishTop = true, float strength = 0.2f)void drawRectPerspectiveGradient(const sgc::Rectf& rect, const sgc::Colorf& topColor, const sgc::Colorf& bottomColor, bool vanishTop = true, float strength = 0.2f)void drawSprite(const render::Texture& texture, const sgc::Rectf& dstRect)void drawPixelGrid(const sgc::Rectf& dest, const std::uint32_t* pixels, int pixelWidth, int pixelHeight)void drawPixelGrid(const sgc::Rectf& dest, const std::uint32_t* pixels, int pixelWidth, int pixelHeight, render::PixelArtFilter filter)void drawSprite(const render::Texture& texture, const sgc::Rectf& dstRect, const sgc::Colorf& tintColor)void renderUI(const ui::UINode& root, const ui::UITheme& theme)void pushClipRect(const sgc::Rectf& rect)void popClipRect()void setBlendMode(gfx::BlendMode mode)void pushTransform(float tx = 0.0f, float ty = 0.0f, float sx = 1.0f, float sy = 1.0f)void pushTransform(const Transform2D& t)void pushRotation(float rad, float pivotX = 0.0f, float pivotY = 0.0f)void popTransform()[[nodiscard]] sgc::Rectf applyTransform(const sgc::Rectf& rect) const[[nodiscard]] sgc::Vec2f applyTransform(const sgc::Vec2f& pos) consttemplate <typename Fn> void drawGroup(const sgc::Vec2f& position, float rotationDeg, Fn&& drawFn)void present()[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexcept[[nodiscard]] int drawCallCount() const noexceptvoid resetDrawCallCount() noexcept[[nodiscard]] const sgc::Colorf& clearColor() const noexceptvoid resize(int width, int height) noexcept[[nodiscard]] render::SpriteBatch& spriteBatch() noexcept[[nodiscard]] const render::SpriteBatch& spriteBatch() const noexcept[[nodiscard]] render::ShapeRenderer& shapeRenderer() noexcept[[nodiscard]] const render::ShapeRenderer& shapeRenderer() const noexceptvoid enableSoftwareFramebuffer() noexcept[[nodiscard]] bool hasSoftwareFramebuffer() const noexcept[[nodiscard]] const std::vector<std::uint8_t>& pixels() const noexcept[[nodiscard]] sgc::Colorf pixelAt(int x, int y) const noexceptstruct GpuParticle 16
float posX = 0float posY = 0float posZ = 0float velX = 0float velY = 0float velZ = 0float accelX = 0float accelY = 0float accelZ = 0float colorR = 1float colorG = 1float colorB = 1float colorA = 1float size = 0.1ffloat lifetime = 2float age = 0struct ParticleSimConstants 8
float deltaTime = 0float gravityX = 0float gravityY = -9.81ffloat gravityZ = 0float drag = 0.1fstd::uint32_t maxParticles = 0std::uint32_t activeParticles = 0float padding = 0struct ParticleRenderConstants 5
sgc::Mat4f viewProjectionsgc::Vec3f cameraRightfloat padding0 = 0sgc::Vec3f cameraUpfloat padding1 = 0class IGpuParticleSystem 12
/// @brief デストラクタ virtual ~IGpuParticleSystem() = default/// @brief エミッター設定を適用する /// @param emitter エミッター設定 virtual void setEmitter(const ParticleEmitter& emitter) = 0/// @brief エミッター設定を取得する /// @return 現在のエミッター設定への参照 [[nodiscard]] virtual const ParticleEmitter& emitter() const noexcept = 0/// @brief 個別パーティクルを放出する /// @param position 放出位置 /// @param velocity 初期速度 /// @param lifetime 寿命(秒) /// @param color 初期色 /// @param size 初期サイズ virtual void emit(const sgc::Vec3f& position, const sgc::Vec3f& velocity, float lifetime, const sgc::Colorf& color, float size) = 0/// @brief エミッター設定に基づいてパーティクルを自動放出する /// @param dt デルタタイム(秒) virtual void emitFromEmitter(float dt) = 0/// @brief バースト放出を行う /// @param count 放出数 virtual void burst(std::uint32_t count) = 0/// @brief GPUシミュレーションを実行する(重力・抵抗・寿命減衰) /// @param dt デルタタイム(秒) virtual void update(float dt) = 0/// @brief パーティクルをインスタンス描画する /// @param camera 描画に使用するカメラ virtual void render(const mitiru::render::Camera3D& camera) = 0/// @brief アクティブパーティクル数を取得する /// @return 現在生存中のパーティクル数 [[nodiscard]] virtual std::uint32_t activeCount() const noexcept = 0/// @brief 最大パーティクル数を取得する /// @return サポートする最大パーティクル数 [[nodiscard]] virtual std::uint32_t maxCount() const noexcept = 0/// @brief 全パーティクルをクリアする virtual void clear() = 0/// @brief システムが有効かどうかを判定する [[nodiscard]] virtual bool isValid() const noexcept = 0enum ToneMapOperator 4
Reinhard = 0ACES = 1Uncharted2 = 2Exposure = 3enum BokehShape 29
CircleHexagon`constexpr std::string_view PP_SSAO_PS = R"hlsl(`constexpr std::string_view PP_SSAO_BLUR_PS = R"hlsl(`constexpr std::string_view PP_HDR_TONEMAP_PS = R"hlsl(`constexpr std::string_view PP_TAA_PS = R"hlsl(`constexpr std::string_view PP_DOF_PS = R"hlsl(Texture2D normalTexture : register(t1)SamplerState pointSampler : register(s0)cbuffer SSAOParams : register(b0)float3 reconstructViewPos(float2 uv)float rand2d(float2 co)SamplerState pointSampler : register(s0)cbuffer BlurParams : register(b0)SamplerState linearSampler : register(s0)cbuffer HDRParams : register(b0)float3 reinhardTonemap(float3 c, float wp)float3 acesFilmic(float3 x)float3 uc2(float3 x)float3 uncharted2Tonemap(float3 c, float wp)float3 exposureTonemap(float3 c)Texture2D historyTexture : register(t1)Texture2D motionTexture : register(t2)SamplerState linearSampler : register(s0)cbuffer TAAParams : register(b0)Texture2D depthTexture : register(t1)SamplerState linearSampler : register(s0)cbuffer DoFParams : register(b0)float linearDepth(float d)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct SSAOConfig 5
float radius = 0.5ffloat bias = 0.025ffloat intensity = 1.0fint kernelSize = 16int blurPasses = 1class SSAOPass : public PostProcessPass 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>SSAOPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler, std::uint32_t screenW, std::uint32_t screenH)void setConfig(const SSAOConfig& cfg) noexceptvoid setProjection(const float* proj4x4, const float* invProj4x4) noexceptvoid setNormalSRV(ID3D11ShaderResourceView* normalSRV) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const SSAOConfig& config() const noexceptstruct HDRConfig 4
float exposure = 1.0fToneMapOperator op = ToneMapOperator::ACESfloat whitePoint = 4.0ffloat gamma = 2.2fclass HDRToneMappingPass : public PostProcessPass 6
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>HDRToneMappingPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const HDRConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const HDRConfig& config() const noexceptstruct TAAConfig 3
float blendFactor = 0.1ffloat jitterScale = 1.0fbool enabled = trueclass TAAPass : public PostProcessPass 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>TAAPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler, std::uint32_t screenW, std::uint32_t screenH)void setConfig(const TAAConfig& cfg) noexceptvoid setMotionVectorSRV( ID3D11ShaderResourceView* motionSRV) noexcept[[nodiscard]] std::array<float, 2> getJitter( std::uint32_t frameIndex, std::uint32_t screenW, std::uint32_t screenH) const noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const TAAConfig& config() const noexceptstruct DoFConfig 7
float focusDistance = 10.0ffloat aperture = 0.1ffloat focalLength = 50.0ffloat maxBlur = 8.0ffloat nearPlane = 0.1ffloat farPlane = 1000.0fBokehShape bokehShape = BokehShape::Circleclass DepthOfFieldPass : public PostProcessPass 7
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>DepthOfFieldPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const DoFConfig& cfg) noexceptvoid setDepthSRV( ID3D11ShaderResourceView* depthSRV) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const DoFConfig& config() const noexceptenum BlendFunc 5
NormalAdditiveMultiplyScreenOverlaystruct AlphaBlend 7
[[nodiscard]] static constexpr float saturate(float v) noexcept[[nodiscard]] static constexpr sgc::Colorf over( const sgc::Colorf& src, const sgc::Colorf& dst) noexcept[[nodiscard]] static constexpr sgc::Colorf overWithAlpha( const sgc::Colorf& srcRgb, float alpha, const sgc::Colorf& dst) noexcept[[nodiscard]] static constexpr sgc::Colorf premultiply( const sgc::Colorf& color) noexcept[[nodiscard]] static constexpr sgc::Colorf unpremultiply( const sgc::Colorf& color) noexcept[[nodiscard]] static constexpr sgc::Colorf blend( const sgc::Colorf& src, const sgc::Colorf& dst, BlendFunc func) noexcept[[nodiscard]] static constexpr sgc::Colorf lerp( const sgc::Colorf& a, const sgc::Colorf& b, float t) noexceptenum Loop 3
OnceInfiniteCountenum Direction 4
NormalReverseAlternateAlternateReversestruct LoopMode 5
Loop type = Loop::Onceint count = 1static LoopMode once()static LoopMode infinite()static LoopMode times(int n)struct Transition 8
float duration = 0.3ffloat delay = 0.0fEasing easing = Easing::ease()void target(const Style& newTarget)void update(float dt)[[nodiscard]] const Style& current() const[[nodiscard]] bool isAnimating() constvoid reset(const Style& initial)struct KeyframeEntry 2
float offsetStyle stylestruct Keyframes 9
std::vector<KeyframeEntry> framesfloat duration = 1.0fDirection direction = Direction::NormalEasing easing = Easing::linear()LoopMode loop = LoopMode::once()[[nodiscard]] Style evaluate(float time) const[[nodiscard]] bool isComplete(float time) const[[nodiscard]] inline Pipeline2DResult createPipeline2DFor( gfx::IDevice* device, int screenWidth, int screenHeight)[[nodiscard]] inline std::unique_ptr<IRenderer3D> createRenderer3DFor( gfx::IDevice* device, int screenWidth, int screenHeight, int windowWidth, int windowHeight)struct Pipeline2DResult 2
std::optional<RenderPipeline2D> pipelinestd::shared_ptr<PostProcessManager> postProcessstruct BillboardInstance 4
sgc::Vec3f positionfloat width = 1.0ffloat height = 1.0ffloat rotation = 0.0fclass Billboard3D 7
Billboard3D()void add(const BillboardInstance& instance)void clear()[[nodiscard]] sgc::Mat4f computeWorldMatrix(const BillboardInstance& bb, const Camera3D& camera) const noexcept[[nodiscard]] const Mesh& quadMesh() const noexcept[[nodiscard]] const std::vector<BillboardInstance>& instances() const noexcept[[nodiscard]] std::size_t instanceCount() const noexceptclass BitmapFont 3
[[nodiscard]] static constexpr std::array<std::uint8_t, 8> glyph(char ch) noexcept[[nodiscard]] static constexpr int textWidth(std::string_view text, int scale = 1) noexcept[[nodiscard]] static constexpr int textHeight(int scale = 1) noexceptclass Camera2D 13
explicit Camera2D(float screenWidth = 1280.0f, float screenHeight = 720.0f) noexceptvoid setPosition(const sgc::Vec2f& position) noexcept[[nodiscard]] const sgc::Vec2f& position() const noexceptvoid setZoom(float zoom) noexcept[[nodiscard]] float zoom() const noexceptvoid setRotation(float radians) noexcept[[nodiscard]] float rotation() const noexcept[[nodiscard]] sgc::Mat4f viewMatrix() const noexcept[[nodiscard]] sgc::Vec2f screenToWorld(const sgc::Vec2f& screenPos) const noexcept[[nodiscard]] sgc::Vec2f worldToScreen(const sgc::Vec2f& worldPos) const noexceptvoid shake(float intensity, float duration) noexceptvoid updateShake(float deltaTime) noexceptvoid setScreenSize(float width, float height) noexceptclass Camera3D 29
Camera3D() noexcept = defaultCamera3D(const sgc::Vec3f& position, const sgc::Vec3f& target, const sgc::Vec3f& up, float fov, float aspectRatio, float nearClip, float farClip) noexceptvoid setPosition(const sgc::Vec3f& position) noexcept[[nodiscard]] const sgc::Vec3f& position() const noexceptvoid setTarget(const sgc::Vec3f& target) noexcept[[nodiscard]] const sgc::Vec3f& target() const noexceptvoid setUp(const sgc::Vec3f& up) noexcept[[nodiscard]] const sgc::Vec3f& up() const noexceptvoid setFov(float fov) noexcept[[nodiscard]] float fov() const noexceptvoid setAspectRatio(float ratio) noexcept[[nodiscard]] float aspectRatio() const noexceptvoid setNearClip(float nearClip) noexcept[[nodiscard]] float nearClip() const noexceptvoid setFarClip(float farClip) noexcept[[nodiscard]] float farClip() const noexceptvoid setOrthographic(bool ortho) noexcept[[nodiscard]] bool isOrthographic() const noexceptvoid setOrthoParams(float left, float right, float bottom, float top) noexcept[[nodiscard]] sgc::Mat4f viewMatrix() const noexcept[[nodiscard]] sgc::Mat4f projectionMatrix() const noexcept[[nodiscard]] sgc::Mat4f viewProjectionMatrix() const noexcept[[nodiscard]] sgc::Vec3f worldToScreen(const sgc::Vec3f& worldPos, float screenWidth, float screenHeight) const noexcept[[nodiscard]] bool isInFront(const sgc::Vec3f& worldPos) const noexcept[[nodiscard]] sgc::Vec3f forwardDirection() const noexcept[[nodiscard]] sgc::Vec3f rightDirection() const noexcept[[nodiscard]] sgc::Vec3f upDirection() const noexceptvoid orbitAround(const sgc::Vec3f& orbitTarget, float yawRadians, float pitchRadians, float distance) noexceptvoid lookDirection(float yawRadians, float pitchRadians) noexceptstruct ClusterLight 2
float radius = 10.0ffloat intensity = 1.0fstruct ClusterConfig 6
int gridX = 16int gridY = 9int gridZ = 24float nearPlane = 0.1ffloat farPlane = 100.0fint maxLightsPerCluster = 32struct Cluster 2
int lightCount = 0std::vector<int> lightIndicesclass ClusteredLighting 9
void configure(const ClusterConfig& config)void setLights(const std::vector<ClusterLight>& lights)void addLight(const ClusterLight& light)void buildClusters(const float viewMatrix[16], [[maybe_unused]] const float projMatrix[16], int screenWidth, int screenHeight)[[nodiscard]] const Cluster& getCluster(int x, int y, int z) const[[nodiscard]] int totalClusters() const noexcept[[nodiscard]] int lightCount() const noexcept[[nodiscard]] const ClusterConfig& config() const noexceptvoid clearLights()enum CubeFace : std::uint8_t 7
PosX = 0NegX = 1PosY = 2NegY = 3PosZ = 4NegZ = 5constexpr int kCubemapFaceCount = 6class Cubemap 18
Cubemap() = defaultexplicit Cubemap(const std::array<Texture, kCubemapFaceCount>& faces) noexcept[[nodiscard]] static Cubemap solid(int size, const sgc::Colorf& color) noexcept[[nodiscard]] static Cubemap verticalGradient( int size, const sgc::Colorf& zenith, const sgc::Colorf& nadir) noexcept[[nodiscard]] const Texture& face(CubeFace f) const noexcept[[nodiscard]] const Texture& face(int index) const noexcept[[nodiscard]] int faceSize() const noexcept[[nodiscard]] bool valid() const noexceptusing DecalId = std::uint32_t;`constexpr std::string_view DECAL_VS = R"hlsl(`constexpr std::string_view DECAL_PS = R"hlsl(VSOutput VSMain(VSInput input)Texture2D normalTexture : register(t1)Texture2D decalTexture : register(t2)Texture2D decalNormalMap : register(t3)SamplerState linearSampler : register(s0)cbuffer CbDecalTransform : register(b0)PSOutput PSMain(PSInput input)struct DecalConfig 3
int maxDecals = 256float fadeDuration = 3.0ffloat defaultSize = 1.0fstruct Decal 4
std::string textureKeystd::string normalMapKeyfloat opacity = 1.0ffloat fadeTime = 0.0fstruct VSInput 1
float3 Position : POSITIONstruct VSOutput 2
float4 Position : SV_POSITIONfloat4 ScreenPos : TEXCOORD0struct PSInput 2
float4 Position : SV_POSITIONfloat4 ScreenPos : TEXCOORD0struct PSOutput 2
float4 Albedo : SV_TARGET0float4 Normal : SV_TARGET1class DecalSystem 30
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>DecalSystem() noexcept = defaultvoid init(ID3D11Device* device, const DecalConfig& config = {})[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] DecalId addDecal(const Decal& decal)void removeDecal(DecalId id)void update(float dt)[[nodiscard]] int decalCount() const noexceptvoid render(ID3D11DeviceContext* context, ID3D11ShaderResourceView* depthSRV, ID3D11ShaderResourceView* normalSRV, const float viewProj[16], const float invViewProj[16])`constexpr std::string_view DEFAULT_VS_2D = R"hlsl(`constexpr std::string_view DEFAULT_PS_2D = R"hlsl(`constexpr std::string_view SDF_RECT_VS = R"hlsl(`constexpr std::string_view SDF_RECT_PS = R"hlsl(`constexpr std::string_view SDF_CIRCLE_VS = R"hlsl(`constexpr std::string_view SDF_CIRCLE_PS = R"hlsl(VSOutput VSMain(VSInput input)SamplerState sampler0 : register(s0)cbuffer PSConstants : register(b0)VSOutput VSMain(VSInput input)// up to 8 stop colors (RGBA each) float4 gradientOffsetsPacked[2]// type(0=solid,1=linear,2=radial), cos(angle), sin(angle), stopCount float4 strokeColor/// @brief グラデーションオフセット配列から値を取得する float getGradientOffset(int idx)/// @brief マルチストップグラデーションを評価する float4 sampleGradient(float t, int stopCount)/// @brief 角丸矩形のSDF(符号付き距離関数) float roundedBoxSDF(float2 p, float2 halfSize, float4 radii)VSOutput VSMain(VSInput input)// up to 8 stop colors (RGBA each) float4 gradientOffsetsPacked[2]// type(0=solid,1=linear,2=radial), cos(angle), sin(angle), stopCount float4 strokeColor/// @brief グラデーションオフセット配列から値を取得する float getGradientOffset(int idx)/// @brief マルチストップグラデーションを評価する float4 sampleGradient(float t, int stopCount)/// @brief 楕円の近似SDF float ellipseSDF(float2 p, float2 halfSize)struct VSInput 3
float2 position : POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct VSOutput 3
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct PSInput 3
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct VSInput 4
float2 position : POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1struct VSOutput 4
float4 position : SV_POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1struct PSInput 4
float4 position : SV_POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1struct VSInput 4
float2 position : POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1struct VSOutput 4
float4 position : SV_POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1struct PSInput 8
float4 position : SV_POSITIONfloat2 localUV : TEXCOORD0float4 color : COLOR0float4 shapeRect : TEXCOORD1constexpr const char* DEFAULT_VS_3D = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; float4 worldPos = mul(float4(input.Position, 1.0), World); output.WorldPos = worldPos.xyz; output.WorldNorm = normalize(mul(input.Normal, (float3x3)World)); float4 viewPos = mul(worldPos, View); output.Position = mul(viewPos, Projection); output.TexCoord = input.TexCoord; output.Color = input.Color; return output; } )hlsl"constexpr const char* DEFAULT_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); float3 R = reflect(-L, N); float3 ambient = AmbientColor * MaterialDiffuse.rgb; float NdotL = max(dot(N, L), 0.0); float3 diffuse = LightColor * MaterialDiffuse.rgb * NdotL; float3 H = normalize(L + V); float NdotH = max(dot(N, H), 0.0); float specFactor = pow(NdotH, MaterialShininess); float3 specular = LightColor * MaterialSpecular.rgb * specFactor; float3 finalColor = ambient + diffuse + specular; float alpha = MaterialDiffuse.a * input.Color.a; return float4(finalColor * input.Color.rgb, alpha); } )hlsl"constexpr const char* UNLIT_VS_3D = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; float4 worldPos = mul(float4(input.Position, 1.0), World); float4 viewPos = mul(worldPos, View); output.Position = mul(viewPos, Projection); output.TexCoord = input.TexCoord; output.Color = input.Color; return output; } )hlsl"constexpr const char* UNLIT_PS_3D = R"hlsl( struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { return input.Color; } )hlsl"class DeferredPipeline 16
DeferredPipeline() noexcept = defaultvoid initialize(int width, int height, const ShadowMapConfig& shadowConfig = {})[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] const ShadowMap& shadowMap() const noexcept[[nodiscard]] const GBuffer& gBuffer() const noexceptvoid render(const Scene3D& scene, const Camera3D& camera, RenderTexture& output)void setClearColor(const sgc::Colorf& color) noexcept`constexpr std::string_view DOF_COC_PS = R"hlsl(`constexpr std::string_view DOF_BLUR_PS = R"hlsl(SamplerState pointClampSampler : register(s0)cbuffer DofCoCParams : register(b0)float linearizeDepth(float d)Texture2D cocTexture : register(t1)SamplerState linearClampSampler : register(s0)SamplerState pointClampSampler : register(s1)cbuffer DofBlurParams : register(b0)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct DepthOfFieldConfig 7
float focusDistance = 5.0ffloat aperture = 2.8ffloat focalLength = 0.05ffloat nearPlane = 0.1ffloat farPlane = 100.0ffloat maxCoCRadius = 10.0ffloat blurScale = 1.0fclass DepthOfFieldEffect 6
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>void init(ID3D11Device* device, std::uint32_t screenW, std::uint32_t screenH)void setDepthSRV( ID3D11ShaderResourceView* depthSRV) noexceptvoid setConfig( const DepthOfFieldConfig& cfg) noexcept[[nodiscard]] const DepthOfFieldConfig& config() const noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH)struct GlyphInfo 6
char32_t codepoint = 0float advance = 0.0ffloat bearingX = 0.0ffloat bearingY = 0.0ffloat width = 0.0ffloat height = 0.0fstruct FontData 3
std::string namefloat size = 0.0fstd::map<char32_t, GlyphInfo> glyphsclass DxTextRenderer 4
void registerFont(const std::string& name, float size, const FontData& data)[[nodiscard]] bool hasFont(const std::string& name) const[[nodiscard]] sgc::Vec2f measureText(const std::string& text, float fontSize) constvoid drawText(sgc::graphics::IRenderer2D& renderer, sgc::Vec2f pos, const std::string& text, float fontSize, sgc::graphics::Color color)struct Easing 17
static Easing linear()static Easing ease()static Easing easeIn()static Easing easeOut()static Easing easeInOut()static Easing cubicBezier(float x1, float y1, float x2, float y2)[[nodiscard]] float evaluate(float t) const`constexpr std::string_view FSR_EASU_PS = R"hlsl(`constexpr std::string_view FSR_RCAS_PS = R"hlsl(SamplerState linearClampSampler : register(s0)SamplerState pointClampSampler : register(s1)cbuffer EASUParams : register(b0)// ── Lanczos2重み関数 ─────────────────────────── float lanczos2(float x)// ── 輝度を計算する ───────────────────────────── float luminance(float3 c)SamplerState pointClampSampler : register(s0)cbuffer RCASParams : register(b0)float luminance(float3 c)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct FSRConfig 5
std::uint32_t inputWidth = 960std::uint32_t inputHeight = 540std::uint32_t outputWidth = 1920std::uint32_t outputHeight = 1080float sharpness = 0.5fclass FSREffect 5
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>void init(ID3D11Device* device, const FSRConfig& cfg)void setConfig(const FSRConfig& cfg)[[nodiscard]] const FSRConfig& config() const noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV)enum FXAAQuality 8
LowMediumHigh`constexpr std::string_view PP_FXAA_PS = R"hlsl(SamplerState linearSampler : register(s0)cbuffer FXAAParams : register(b0)// ── 知覚輝度計算(緑チャネル重み付き) ────────────────── float FxaaLuma(float3 rgb)// ── オフセットテクスチャサンプル ────────────────────── float3 FxaaTexOff(float2 uv, float2 offset)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct FXAAConfig 4
float subpixQuality = 0.75ffloat edgeThreshold = 0.166ffloat edgeThresholdMin = 0.0833f[[nodiscard]] static FXAAConfig fromQuality( FXAAQuality quality) noexceptclass FXAAPass : public PostProcessPass 10
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>FXAAPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)[[nodiscard]] static FXAAPass low( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)[[nodiscard]] static FXAAPass medium( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)[[nodiscard]] static FXAAPass high( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const FXAAConfig& cfg) noexceptvoid setQuality( float subpixel, float edgeThreshold, float edgeThresholdMin) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const FXAAConfig& config() const noexceptclass FontAtlas 5
[[nodiscard]] static Texture generate(int scale = 2)[[nodiscard]] static constexpr int cellWidth(int scale = 2) noexcept[[nodiscard]] static constexpr int cellHeight(int scale = 2) noexceptstatic void glyphUV(char ch, int scale, float& outU0, float& outV0, float& outU1, float& outV1)template <typename T> [[nodiscard]] std::vector<T> cullObjects( const std::vector<CullEntry<T>>& entries, const Frustum& frustum)struct AABB 2
float minX = 0.0f, minY = 0.0f, minZ = 0.0ffloat maxX = 0.0f, maxY = 0.0f, maxZ = 0.0fstruct Plane 6
float a = 0.0ffloat b = 0.0ffloat c = 0.0ffloat d = 0.0fvoid normalize() noexcept[[nodiscard]] float distanceTo(float x, float y, float z) const noexceptclass Frustum 4
void extractFromViewProj(const float m[16]) noexcept[[nodiscard]] bool isBoxVisible(const AABB& box) const noexcept[[nodiscard]] bool isSphereVisible(float cx, float cy, float cz, float radius) const noexcept[[nodiscard]] const std::array<Plane, 6>& planes() const noexceptstruct GBufferPixel 1
float depth = 1.0fclass GBuffer 9
GBuffer() noexcept = defaultvoid initialize(int width, int height)[[nodiscard]] bool isInitialized() const noexceptvoid clear()void writePixel(int x, int y, const GBufferPixel& pixel)[[nodiscard]] const GBufferPixel& readPixel(int x, int y) const noexcept[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexcept[[nodiscard]] const std::vector<GBufferPixel>& pixels() const noexceptclass GameViewRT 17
bool create(ID3D11Device* device, std::uint32_t width, std::uint32_t height)void release()void beginCapture(ID3D11DeviceContext* ctx)void endCapture(ID3D11DeviceContext* ctx)[[nodiscard]] ID3D11ShaderResourceView* srv() const[[nodiscard]] std::uint32_t width() const noexcept[[nodiscard]] std::uint32_t height() const noexceptinline glm::vec3 toGlm(const sgc::Vec3f& v)inline glm::vec2 toGlm(const sgc::Vec2f& v)inline glm::mat4 toGlm(const sgc::Mat4f& m)inline void toHLSL(float dst[4][4], const glm::mat4& m)inline void toColumnMajor(float dst[4][4], const glm::mat4& m)inline glm::mat4 lookAt(const sgc::Vec3f& eye, const sgc::Vec3f& target, const sgc::Vec3f& up)inline glm::mat4 perspective(float fovRadians, float aspect, float nearZ, float farZ)inline glm::mat4 modelMatrix(const sgc::Vec3f& pos, const sgc::Vec3f& rot, const sgc::Vec3f& scale)inline glm::mat4 orthographic(float left, float right, float bottom, float top, float nearZ, float farZ)using BakeProgressCallback = std::function<void(float progress, const std::string& phase)>;struct VoxelGIConfig 8
int resolution = 128float worldSize = 50.0fint maxBounces = 2float coneSpread = 0.1ffloat aoDistance = 5.0ffloat indirectIntensity = 1.0fbool enableSpecular = truebool enableDiffuse = truestruct LightmapConfig 7
int textureSize = 1024int samplesPerTexel = 64int maxBounces = 3float biasOffset = 0.001fbool enableAO = truebool enableDirectional = falsefloat aoRadius = 1.0fstruct IrradianceSample 1
float confidence = 0.0fclass GISystem 22
virtual ~GISystem() = defaultGISystem(const GISystem&) = deleteGISystem& operator=(const GISystem&) = deletevirtual bool initVoxelGI(const VoxelGIConfig& config) = 0virtual void updateVoxelGI(float deltaTime) = 0virtual void revoxelize() = 0virtual bool bake(const LightmapConfig& config, BakeProgressCallback callback = nullptr) = 0virtual bool saveLightmap(const std::string& outputPath) const = 0virtual bool loadLightmap(const std::string& inputPath) = 0[[nodiscard]] virtual IrradianceSample getIrradiance( float worldX, float worldY, float worldZ) const = 0[[nodiscard]] virtual bool isEnabled() const noexcept = 0virtual void setEnabled(bool enabled) = 0[[nodiscard]] inline float readFloat(const cgltf_accessor* accessor, cgltf_size index, cgltf_size component)[[nodiscard]] inline sgc::Vec3f readVec3(const cgltf_accessor* accessor, cgltf_size index)[[nodiscard]] inline sgc::Vec2f readVec2(const cgltf_accessor* accessor, cgltf_size index)[[nodiscard]] inline uint32_t readIndex(const cgltf_accessor* accessor, cgltf_size index)[[nodiscard]] inline sgc::Vec3f computeFlatNormal( const sgc::Vec3f& v0, const sgc::Vec3f& v1, const sgc::Vec3f& v2)[[nodiscard]] inline GltfMeshPrimitive convertPrimitive(const cgltf_primitive& prim)[[nodiscard]] inline std::optional<GltfSceneData> loadGltfFromMemory( const void* data, std::size_t size)[[nodiscard]] inline std::optional<GltfSceneData> loadGltfSceneFromFile(const std::string& filePath)[[nodiscard]] inline std::optional<Mesh> loadGltfMeshFromFile(const std::string& filePath)[[nodiscard]] inline Material convertGltfMaterial(const GltfMaterialData& gltfMat)class GltfMaterialConverter 3
[[nodiscard]] static Material convertPBR(const GltfMaterialData& gltf)[[nodiscard]] static Material convertPBRForToon(const GltfMaterialData& gltf)[[nodiscard]] static std::vector<Material> convertAll( const std::vector<GltfMaterialData>& gltfMaterials, bool toonMode = false)struct GltfMeshPrimitive 3
std::vector<Vertex3D> verticesstd::vector<uint32_t> indicesint materialIndex = -1struct GltfMeshData 2
std::string namestd::vector<GltfMeshPrimitive> primitivesstruct GltfMaterialData 5
std::string namefloat metallic = 0.0ffloat roughness = 1.0fstd::string baseColorTexturePathstd::string normalTexturePathstruct GltfSceneData 5
std::vector<GltfMeshData> meshesstd::vector<GltfMaterialData> materialsinline constexpr int kMaxBones = 128struct alignas(16) CbSkinningconstexpr const char* SKINNING_VS = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; cbuffer CbSkinning : register(b3) { float4x4 BoneMatrices[128]; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; uint4 BoneIndices : BLENDINDICES; float4 BoneWeights : BLENDWEIGHT; }; struct VSOutput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; // Apply up to 4 bone influences per vertex float4 skinnedPos = float4(0, 0, 0, 0); float3 skinnedNormal = float3(0, 0, 0); for (int i = 0; i < 4; i++) { float w = input.BoneWeights[i]; if (w > 0) { float4x4 bone = BoneMatrices[input.BoneIndices[i]]; skinnedPos += mul(bone, float4(input.Position, 1)) * w; skinnedNormal += mul((float3x3)bone, input.Normal) * w; } } float4 worldPos = mul(skinnedPos, World); output.WorldPos = worldPos.xyz; output.WorldNorm = normalize(mul(skinnedNormal, (float3x3)World)); float4 viewPos = mul(worldPos, View); output.Position = mul(viewPos, Projection); output.TexCoord = input.TexCoord; output.Color = input.Color; return output; } )hlsl"struct SkinnedVertex 2
constexpr SkinnedVertex() noexcept = defaultconstexpr SkinnedVertex(const sgc::Vec3f& pos, const sgc::Vec3f& nrm, const sgc::Vec2f& uv, const sgc::Colorf& col, const std::array<uint32_t, 4>& indices, const std::array<float, 4>& weights) noexceptclass GpuSkinner 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>GpuSkinner() noexcept = default[[nodiscard]] bool isInitialized() const noexceptvoid init(ID3D11Device* device)void updateBones(ID3D11DeviceContext* context, const sgc::Mat4f* matrices, size_t count)void bindSkinning(ID3D11DeviceContext* context)void unbindSkinning(ID3D11DeviceContext* context)[[nodiscard]] ID3D11InputLayout* inputLayout() const noexceptenum SpriteBlendMode : std::uint8_t 4
AlphaBlendAdditiveMultiplyNoneenum SamplerMode : std::uint8_t 7
BilinearPointAnisotropic`constexpr std::string_view GPU_SPRITE_VS = R"hlsl(`constexpr std::string_view GPU_SPRITE_PS = R"hlsl(VSOutput VSMain(VSInput input)SamplerState samp : register(s0)struct VSInput 3
float2 position : POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct VSOutput 3
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct PSInput 3
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0class GpuTexture2D 9
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>GpuTexture2D() noexcept = default[[nodiscard]] static GpuTexture2D createFromPixels( ID3D11Device* device, int width, int height, std::span<const std::uint8_t> pixels)template <typename TextureT> [[nodiscard]] static GpuTexture2D createFromTexture( ID3D11Device* device, const TextureT& texture)[[nodiscard]] static GpuTexture2D createWhitePixel( ID3D11Device* device)[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexcept[[nodiscard]] ID3D11ShaderResourceView* getSRV() const noexcept[[nodiscard]] bool isValid() const noexceptstruct GpuSpriteBatchVertex 8
float x = 0.0ffloat y = 0.0ffloat u = 0.0ffloat v = 0.0ffloat r = 1.0ffloat g = 1.0ffloat b = 1.0ffloat a = 1.0fclass GpuSpriteBatch 11
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>GpuSpriteBatch() noexcept = defaultvoid init(ID3D11Device* device, int maxSprites = 4096)void begin(ID3D11DeviceContext* context, float screenW, float screenH, SpriteBlendMode blendMode = SpriteBlendMode::AlphaBlend, SamplerMode samplerMode = SamplerMode::Bilinear)void draw(ID3D11ShaderResourceView* textureSrv, float srcX, float srcY, float srcW, float srcH, float dstX, float dstY, float dstW, float dstH, float r, float g, float b, float a, float rotation = 0.0f)void drawUV(ID3D11ShaderResourceView* textureSrv, float u0, float v0, float u1, float v1, float dstX, float dstY, float dstW, float dstH, float r, float g, float b, float a, float rotation = 0.0f)void drawRect(float dstX, float dstY, float dstW, float dstH, float r, float g, float b, float a)void end()[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] int flushCount() const noexcept[[nodiscard]] const GpuTexture2D& whiteTexture() const noexceptenum ShaderMode3D : uint8_t 10
Phong = 0ToonUnlitFlatPosterizeHalftoneHatchingGradientMapSilhouetteWatercolorenum OutlineMode : int 7
DepthSobel = 0DepthLaplacian = 1DepthSobelNdotV = 2ColorEdge = 3DepthColorCombo = 4Fresnel = 5constexpr int OUTLINE_MODE_COUNT = 6class IRenderer3D 33
virtual ~IRenderer3D() = default[[nodiscard]] virtual bool isInitialized() const noexcept = 0virtual void beginFrame(const sgc::Colorf& clearColor = {0.2f, 0.2f, 0.3f, 1.0f}) = 0virtual void endFrame() = 0virtual void setCamera(const Camera3D& camera) = 0virtual void setLight(const Light& light) = 0virtual void setLights(std::span<const Light> lights)virtual void setUseMultiLight(bool )[[nodiscard]] virtual bool useMultiLight() const noexceptvirtual void setSkybox(const Cubemap& )virtual void setSkyboxEnabled(bool )[[nodiscard]] virtual bool isSkyboxEnabled() const noexceptvirtual void setAmbientColor(const sgc::Colorf& )[[nodiscard]] virtual sgc::Colorf ambientColor() const noexceptvirtual void drawMesh(const Mesh& mesh, const sgc::Mat4f& worldTransform, const Material& material = {}) = 0virtual void resetFrameActive() noexcept = 0[[nodiscard]] virtual bool isFrameActive() const noexcept = 0[[nodiscard]] virtual int drawCallCount() const noexcept = 0virtual void setShaderMode([[maybe_unused]] ShaderMode3D mode)virtual void setOutlineEnabled(bool )[[nodiscard]] virtual bool isOutlineEnabled() const noexceptvirtual void setOutlineMode(OutlineMode )[[nodiscard]] virtual OutlineMode outlineMode() const noexceptvirtual void setTonemapExposure(float )[[nodiscard]] virtual float tonemapExposure() const noexceptvirtual void setTonemapGamma(float )[[nodiscard]] virtual float tonemapGamma() const noexceptvirtual void setOverlayScreen(const Screen* )[[nodiscard]] virtual bool hasOverlaySupport() const noexcept[[nodiscard]] virtual void* nativeCommandList() const noexcept[[nodiscard]] virtual void* nativeDevice() const noexcept[[nodiscard]] virtual void* nativeSwapChain() const noexceptvirtual void finalizeFrame()class ImageLoader 6
[[nodiscard]] static Texture fromMemory(const std::uint8_t* data, int dataSize)[[nodiscard]] static Texture fromFile(const std::string& path)[[nodiscard]] static std::string lastError()struct alignas(16) InstanceDatainline constexpr const char* kInstancedVS = R"hlsl( cbuffer CbViewProj : register(b0) { float4x4 viewProj; }; struct VSInput { // Per-vertex (slot 0) float3 position : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD; // Per-instance (slot 1) float4 instWorld0 : INST_WORLD0; float4 instWorld1 : INST_WORLD1; float4 instWorld2 : INST_WORLD2; float4 instWorld3 : INST_WORLD3; float4 instColor : INST_COLOR; float4 instCustom : INST_CUSTOM; }; struct PSInput { float4 position : SV_POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD; float4 color : COLOR; float4 custom : CUSTOM; }; PSInput main(VSInput input) { PSInput output; float4x4 world = float4x4( input.instWorld0, input.instWorld1, input.instWorld2, input.instWorld3 ); float4 worldPos = mul(float4(input.position, 1.0), world); output.position = mul(worldPos, viewProj); output.normal = mul(float4(input.normal, 0.0), world).xyz; output.texcoord = input.texcoord; output.color = input.instColor; output.custom = input.instCustom; return output; } )hlsl"inline constexpr const char* kInstancedPS = R"hlsl( struct PSInput { float4 position : SV_POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD; float4 color : COLOR; float4 custom : CUSTOM; }; float4 main(PSInput input) : SV_TARGET { float3 lightDir = normalize(float3(0.3, -1.0, 0.5)); float ndotl = saturate(dot(normalize(input.normal), -lightDir)); float3 lit = input.color.rgb * (ndotl * 0.7 + 0.3); return float4(lit, input.color.a); } )hlsl"class InstancedRenderer 14
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>InstancedRenderer() noexcept = default[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] std::uint32_t instanceCount() const noexcept[[nodiscard]] std::uint32_t maxInstances() const noexcept[[nodiscard]] int drawCallCount() const noexcept[[nodiscard]] int totalInstancesDrawn() const noexceptvoid init(ID3D11Device* device, ID3D11DeviceContext* context, std::uint32_t maxInstances = 10000)void beginBatch(ID3D11DeviceContext* context, ID3D11Buffer* meshVertexBuffer, ID3D11Buffer* meshIndexBuffer, std::uint32_t indexCount)void addInstance(const float worldMatrix[4][4], const float color[4])void addInstance(const InstanceData& data)void setViewProjection(const float viewProj[4][4])void flush(ID3D11DeviceContext* context)void resetStats() noexceptstruct LODLevel 5
Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBufferMicrosoft::WRL::ComPtr<ID3D11Buffer> indexBufferstd::uint32_t indexCount = 0float maxDistance = 0.0ffloat transitionRange = 5.0fstruct LODGroup 2
std::vector<LODLevel> levelsstd::uint32_t currentLevel = 0struct LODSelection 2
std::uint32_t level = 0float blendFactor = 0.0fstruct LODConfig 4
float bias = 0.0fstd::uint32_t maxLevel = 0float crossFadeDuration = 0.5ffloat hysteresis = 2.0fstruct LODObject 2
std::string groupIdstd::uint32_t currentLevel = 0class LODManager 12
LODManager() noexcept = default[[nodiscard]] const LODConfig& config() const noexceptvoid setConfig(const LODConfig& cfg) noexceptvoid registerGroup(const std::string& id, std::vector<LODLevel> levels)[[nodiscard]] bool hasGroup(const std::string& id) const[[nodiscard]] const LODGroup& getGroup(const std::string& id) const[[nodiscard]] const LODLevel& selectLOD( const std::string& groupId, const float cameraPos[3], const float objectPos[3]) const[[nodiscard]] LODSelection selectLODSmooth( const std::string& groupId, const float cameraPos[3], const float objectPos[3])void update(const float cameraPos[3], std::vector<LODObject>& objects)[[nodiscard]] int lodTransitionCount() const noexcept[[nodiscard]] int drawCallsSaved() const noexceptvoid resetStats() noexceptenum LightType 3
DirectionalPointSpotstruct Light 9
LightType type = LightType::Directionalfloat intensity = 1.0ffloat range = 100.0ffloat spotAngle = 45.0f[[nodiscard]] static Light directional( const sgc::Vec3f& dir, const sgc::Colorf& col = {1.0f, 1.0f, 1.0f, 1.0f})[[nodiscard]] static Light point( const sgc::Vec3f& pos, float lightRange = 100.0f, const sgc::Colorf& col = {1.0f, 1.0f, 1.0f, 1.0f})[[nodiscard]] static Light spot( const sgc::Vec3f& pos, const sgc::Vec3f& dir, float angle = 45.0f, float lightRange = 100.0f, const sgc::Colorf& col = {1.0f, 1.0f, 1.0f, 1.0f})struct alignas(16) LightEntryGpustruct alignas(16) LightArrayCBstruct Material 8
float shininess = 32.0fstd::string diffuseTexturePathstd::string normalTexturePathfloat metallic = 0.0ffloat roughness = 1.0fconst Texture* albedoTexture = nullptr[[nodiscard]] static Material defaultMaterial() noexcept[[nodiscard]] std::string toJson() constclass Mesh 11
Mesh() noexcept = defaultvoid setVertices(std::vector<Vertex3D> vertices)void setIndices(std::vector<uint32_t> indices)[[nodiscard]] std::size_t vertexCount() const noexcept[[nodiscard]] std::size_t indexCount() const noexcept[[nodiscard]] AABB computeAABB() const noexcept[[nodiscard]] const std::vector<Vertex3D>& vertices() const noexcept[[nodiscard]] const std::vector<uint32_t>& indices() const noexcept[[nodiscard]] static Mesh createCube(float size = 1.0f)[[nodiscard]] static Mesh createSphere(float radius = 0.5f, int segments = 16)[[nodiscard]] static Mesh createPlane(float width = 1.0f, float height = 1.0f)class MeshCache 4
MeshCache() = default[[nodiscard]] const Mesh* loadMesh(const std::string& objPath)void clear() noexcept[[nodiscard]] std::size_t size() const noexceptstruct MeshBounds 3
[[nodiscard]] sgc::Vec3f center() const noexcept[[nodiscard]] sgc::Vec3f size() const noexcept[[nodiscard]] float maxDimension() const noexceptclass MeshNormalizer 3
[[nodiscard]] static MeshBounds computeBounds(const Mesh& mesh)static void normalize(Mesh& mesh, float targetSize = 1.0f, bool centerXZ = true, bool bottomY0 = true)static void convertZUpToYUp(Mesh& mesh)enum MipmapFilterMode : std::uint8_t 2
BoxLanczosstruct MipmapConfig 3
MipmapFilterMode filterMode = MipmapFilterMode::Boxstd::uint32_t maxLevel = 0std::uint32_t anisotropicLevel = 1class MipmapGenerator 15
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>MipmapGenerator() noexcept = defaultvoid generateMipmaps(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture)[[nodiscard]] ComPtr<ID3D11Texture2D> createTextureWithMipmaps( ID3D11Device* device, std::uint32_t width, std::uint32_t height, const void* pixels)[[nodiscard]] ComPtr<ID3D11ShaderResourceView> createSRVWithMipmaps( ID3D11Device* device, ID3D11Texture2D* texture)[[nodiscard]] ComPtr<ID3D11SamplerState> createAnisotropicSampler( ID3D11Device* device, std::uint32_t level)[[nodiscard]] const MipmapConfig& config() const noexceptvoid setConfig(const MipmapConfig& cfg) noexcept[[nodiscard]] static std::uint32_t calculateMipLevels( std::uint32_t width, std::uint32_t height) noexceptinline constexpr const char* MULTI_LIGHT_VS_3D = R"HLSL( cbuffer CbTransform : register(b0) { float4x4 world; float4x4 view; float4x4 projection; }; struct VSIn { float3 pos : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; float4 color : COLOR0; }; struct VSOut { float4 svpos : SV_POSITION; float3 worldPos : TEXCOORD0; float3 worldNrm : NORMAL; float2 uv : TEXCOORD1; float4 color : COLOR0; }; VSOut VSMain(VSIn i) { VSOut o; float4 wp = mul(float4(i.pos, 1.0), world); o.worldPos = wp.xyz; o.svpos = mul(mul(wp, view), projection); // 法線変換は world の 3x3 部分(無一様 scale 非対応の簡易版)。 o.worldNrm = normalize(mul(float4(i.normal, 0.0), world).xyz); o.uv = i.uv; o.color = i.color; return o; } )HLSL"inline constexpr const char* MULTI_LIGHT_PS_3D = R"HLSL( struct LightEntry { float4 typeAndIntensity; // x=type (0=Dir,1=Point,2=Spot), y=intensity, z=spotInnerCos, w=spotOuterCos float4 position; // xyz=position float4 direction; // xyz=direction float4 color; // rgb=color, a=range }; cbuffer CbLighting : register(b1) { float4 _lightDir; // 未使用(multi-light は b2 を使う) float4 _lightColor; // 未使用 float4 ambientColor_b1; // 未使用(b2 の ambient を使う) float4 cameraPos; float4 materialDiffuse; float4 materialSpecular; float materialShininess; float3 _pad_lighting; }; cbuffer CbLightArray : register(b2) { int lightCount; int3 _pad_la; float4 sceneAmbient; LightEntry lights[8]; }; Texture2D g_albedo : register(t0); SamplerState g_samp : register(s0); struct VSOut { float4 svpos : SV_POSITION; float3 worldPos : TEXCOORD0; float3 worldNrm : NORMAL; float2 uv : TEXCOORD1; float4 color : COLOR0; }; float3 evaluateLight(LightEntry L, float3 worldPos, float3 N, float3 V, float3 albedo) { int type = (int)L.typeAndIntensity.x; float intensity = L.typeAndIntensity.y; float3 Lcol = L.color.rgb * intensity; float range = L.color.a; float3 Ldir; float attenuation = 1.0; if (type == 0) { // Directional: L からの光は -direction 方向から来る。 Ldir = normalize(-L.direction.xyz); } else { // Point / Spot: 光源位置から worldPos へのベクトル。 float3 toLight = L.position.xyz - worldPos; float dist = length(toLight); Ldir = toLight / max(dist, 1e-4); // smooth distance attenuation: 1 at center, 0 at range. attenuation = saturate(1.0 - dist / max(range, 1e-4)); attenuation *= attenuation; if (type == 2) { // Spot: dot(Ldir, -direction) > outerCos で減衰開始。 float3 spotDir = normalize(L.direction.xyz); float cosTheta = dot(-Ldir, spotDir); float inner = L.typeAndIntensity.z; float outer = L.typeAndIntensity.w; float spotFactor = saturate( (cosTheta - outer) / max(inner - outer, 1e-4)); attenuation *= spotFactor; } } float NdotL = saturate(dot(N, Ldir)); // Phong specular float3 H = normalize(Ldir + V); float specPow = max(materialShininess, 1.0); float NdotH = saturate(dot(N, H)); float spec = pow(NdotH, specPow) * NdotL; float3 diffuse = albedo * NdotL; float3 specular = materialSpecular.rgb * spec; return (diffuse + specular) * Lcol * attenuation; } float4 PSMain(VSOut i) : SV_TARGET { float3 N = normalize(i.worldNrm); float3 V = normalize(cameraPos.xyz - i.worldPos); float4 texCol = g_albedo.Sample(g_samp, i.uv); float3 albedo = materialDiffuse.rgb * i.color.rgb * texCol.rgb; float3 result = sceneAmbient.rgb * albedo; [unroll] for (int n = 0; n < 8; ++n) { if (n >= lightCount) break; result += evaluateLight(lights[n], i.worldPos, N, V, albedo); } float alpha = materialDiffuse.a * i.color.a * texCol.a; return float4(result, alpha); } )HLSL"inline constexpr int kMaxLights = 16struct alignas(16) GpuLightDatastruct alignas(16) CbLightsconstexpr const char* kMultiLightPS = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColorLegacy; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct LightData { float3 position; float type; // 0=Directional, 1=Point, 2=Spot float3 direction; float range; float4 color; // rgb + intensity in w float innerCone; float outerCone; float2 padding; }; cbuffer CbLights : register(b2) { LightData lights[16]; int lightCount; float3 ambientColor; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 V = normalize(CameraPos - input.WorldPos); float3 totalDiffuse = float3(0, 0, 0); float3 totalSpecular = float3(0, 0, 0); for (int i = 0; i < lightCount; i++) { float3 lightColor = lights[i].color.rgb * lights[i].color.w; float3 L; float attenuation = 1.0; if (lights[i].type < 0.5) { // Directional light L = normalize(-lights[i].direction); } else { // Point or Spot light float3 toLight = lights[i].position - input.WorldPos; float dist = length(toLight); L = toLight / max(dist, 0.0001); // Distance attenuation with range cutoff float rangeSq = lights[i].range * lights[i].range; attenuation = max(1.0 - (dist * dist) / rangeSq, 0.0); attenuation *= attenuation; if (lights[i].type > 1.5) { // Spot light: cone angle falloff float cosAngle = dot(-L, normalize(lights[i].direction)); float spotFactor = saturate( (cosAngle - lights[i].outerCone) / max(lights[i].innerCone - lights[i].outerCone, 0.0001)); attenuation *= spotFactor * spotFactor; } } // Diffuse float NdotL = max(dot(N, L), 0.0); totalDiffuse += lightColor * NdotL * attenuation; // Specular (Blinn-Phong) float3 H = normalize(L + V); float NdotH = max(dot(N, H), 0.0); float specFactor = pow(NdotH, MaterialShininess); totalSpecular += lightColor * MaterialSpecular.rgb * specFactor * attenuation; } float3 ambient = ambientColor * MaterialDiffuse.rgb; float3 diffuse = totalDiffuse * MaterialDiffuse.rgb; float3 finalColor = ambient + diffuse + totalSpecular; float alpha = MaterialDiffuse.a * input.Color.a; return float4(finalColor * input.Color.rgb, alpha); } )hlsl"class MultiLightSystem 23
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>MultiLightSystem() noexcept = default[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] int lightCount() const noexceptvoid init(ID3D11Device* device)void setLights(const std::vector<Light>& lights)void setAmbient(const sgc::Colorf& color) noexceptvoid bind(ID3D11DeviceContext* context)void unbind(ID3D11DeviceContext* context)constexpr const char* FLAT_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float NdotL = max(dot(N, L), 0.0); // 完全2値: 明か暗か float shade = (NdotL > 0.3) ? 1.0 : 0.55; float3 color = MaterialDiffuse.rgb * shade; return float4(color * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"constexpr const char* POSTERIZE_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); float3 ambient = AmbientColor * MaterialDiffuse.rgb; float NdotL = max(dot(N, L), 0.0); float3 diffuse = LightColor * MaterialDiffuse.rgb * NdotL; float3 raw = ambient + diffuse; // 4段階にポスタライズ float levels = 4.0; raw = floor(raw * levels + 0.5) / levels; return float4(raw * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"constexpr const char* HALFTONE_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float NdotL = max(dot(N, L), 0.0); float brightness = NdotL * 0.7 + 0.3; // スクリーン空間のドットパターン float2 screenUV = input.Position.xy; float dotSize = 6.0; float2 cell = fmod(screenUV, dotSize) / dotSize - 0.5; float dist = length(cell); float dotThreshold = (1.0 - brightness) * 0.5; float pattern = (dist < dotThreshold) ? 0.4 : 1.0; float3 color = MaterialDiffuse.rgb * pattern; return float4(color * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"constexpr const char* HATCHING_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float NdotL = max(dot(N, L), 0.0); float brightness = NdotL * 0.6 + 0.4; // スクリーン空間の斜線パターン float2 screenUV = input.Position.xy; // 明るさに応じてハッチング密度を変える float hatch1 = fmod(screenUV.x + screenUV.y, 4.0) < 1.0 ? 0.0 : 1.0; float hatch2 = fmod(screenUV.x - screenUV.y, 6.0) < 1.0 ? 0.0 : 1.0; float hatch3 = fmod(screenUV.x + screenUV.y * 0.5, 3.0) < 0.8 ? 0.0 : 1.0; float pattern = 1.0; if (brightness < 0.3) pattern = hatch1 * hatch2 * hatch3; // 3層ハッチング(暗い) else if (brightness < 0.55) pattern = hatch1 * hatch2; // 2層(中間) else if (brightness < 0.8) pattern = hatch1; // 1層(やや明) // ベース色 + ハッチングパターン float3 paperColor = float3(0.95, 0.92, 0.88); // 紙の色 float3 inkColor = MaterialDiffuse.rgb * 0.15; // インクの色 float3 color = lerp(inkColor, paperColor, pattern); return float4(color, 1.0); } )hlsl"constexpr const char* GRADIENT_MAP_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float NdotL = max(dot(N, L), 0.0) * 0.8 + 0.2; // 暖色(影)→ 素材色(中間)→ 明るい暖色(ハイライト) float3 shadowColor = MaterialDiffuse.rgb * float3(0.4, 0.3, 0.5); // 紫がかった影 float3 midColor = MaterialDiffuse.rgb; float3 highlightColor = MaterialDiffuse.rgb * float3(1.1, 1.05, 0.9); // 暖色ハイライト float3 color; if (NdotL < 0.5) color = lerp(shadowColor, midColor, NdotL * 2.0); else color = lerp(midColor, highlightColor, (NdotL - 0.5) * 2.0); return float4(saturate(color) * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"constexpr const char* SILHOUETTE_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 V = normalize(CameraPos - input.WorldPos); // エッジ検出: 視線と法線の角度が大きい→エッジ float edge = 1.0 - abs(dot(N, V)); edge = smoothstep(0.3, 0.8, edge); // エッジ部分は素材色、中心は薄い色 float3 edgeColor = MaterialDiffuse.rgb * 0.2; float3 fillColor = MaterialDiffuse.rgb * 0.85; float3 color = lerp(fillColor, edgeColor, edge); // 強いリムライト float rim = pow(1.0 - saturate(dot(N, V)), 3.0); color += rim * 0.4 * MaterialDiffuse.rgb; return float4(color * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"constexpr const char* WATERCOLOR_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); float NdotL = max(dot(N, L), 0.0); // ソフトなトゥーン(滑らかな遷移) float shade = smoothstep(0.0, 0.6, NdotL) * 0.6 + 0.4; // 紙のテクスチャ風ノイズ(スクリーン空間) float2 uv = input.Position.xy * 0.03; float noise = frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); noise = noise * 0.08 - 0.04; // 微小な変動 // 色を少し彩度上げてパステル調に float3 baseColor = MaterialDiffuse.rgb; float grey = dot(baseColor, float3(0.299, 0.587, 0.114)); baseColor = lerp(float3(grey, grey, grey), baseColor, 1.3); // 彩度ブースト baseColor = lerp(baseColor, float3(1, 1, 1), 0.15); // 白っぽく(水彩の透明感) float3 color = baseColor * shade + noise; // エッジを少し暗くする(水彩の輪郭にじみ) float edge = 1.0 - abs(dot(N, V)); edge = smoothstep(0.5, 0.9, edge); color = lerp(color, baseColor * 0.5, edge * 0.3); return float4(saturate(color) * input.Color.rgb, MaterialDiffuse.a * input.Color.a); } )hlsl"`constexpr std::string_view NORMAL_MAP_VS = R"hlsl(`constexpr std::string_view NORMAL_MAP_PS = R"hlsl(VSOutput VSMain(VSInput input)Texture2D NormalTexture : register(t1)SamplerState samp : register(s0)cbuffer CbLighting : register(b1)cbuffer CbNormalMap : register(b2)struct VertexWithTangent 3
constexpr VertexWithTangent() noexcept = defaultconstexpr VertexWithTangent( const sgc::Vec3f& position, const sgc::Vec3f& normal, const sgc::Vec2f& texCoord, const sgc::Colorf& color, const sgc::Vec4f& tangent) noexceptexplicit constexpr VertexWithTangent(const Vertex3D& v) noexceptstruct NormalMapTexture 5
Microsoft::WRL::ComPtr<ID3D11Texture2D> textureMicrosoft::WRL::ComPtr<ID3D11ShaderResourceView> srvstd::uint32_t width = 0std::uint32_t height = 0[[nodiscard]] bool valid() const noexceptstruct VSInput 5
float3 Position : POSITIONfloat3 Normal : NORMALfloat2 TexCoord : TEXCOORD0float4 Color : COLOR0float4 Tangent : TANGENT0struct VSOutput 7
float4 Position : SV_POSITIONfloat3 WorldPos : TEXCOORD0float3 WorldNorm : TEXCOORD1float2 TexCoord : TEXCOORD2float4 Color : COLOR0float3 WorldTan : TEXCOORD3float3 WorldBitan : TEXCOORD4struct PSInput 7
float4 Position : SV_POSITIONfloat3 WorldPos : TEXCOORD0float3 WorldNorm : TEXCOORD1float2 TexCoord : TEXCOORD2float4 Color : COLOR0float3 WorldTan : TEXCOORD3float3 WorldBitan : TEXCOORD4class NormalMapHelper 17
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>NormalMapHelper() noexcept = defaultvoid init(ID3D11Device* device)[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] NormalMapTexture createNormalMapFromMemory( ID3D11Device* device, const std::uint8_t* pixels, int width, int height)static void computeTangents( const std::vector<Vertex3D>& vertices, const std::vector<std::uint32_t>& indices, std::vector<VertexWithTangent>& outVertices)void setNormalMap(std::uint32_t meshId, const NormalMapTexture& normalMap)void removeNormalMap(std::uint32_t meshId)[[nodiscard]] bool hasNormalMap(std::uint32_t meshId) const noexceptvoid bind(ID3D11DeviceContext* context, std::uint32_t meshId, float normalMapStrength = 1.0f)void unbind(ID3D11DeviceContext* context)[[nodiscard]] const ComPtr<ID3D11InputLayout>& inputLayout() const noexcept[[nodiscard]] const ComPtr<ID3D11VertexShader>& vertexShader() const noexcept[[nodiscard]] const ComPtr<ID3D11PixelShader>& pixelShader() const noexcept[[nodiscard]] inline ObjVertexKey parseFaceVertex(const std::string& token)[[nodiscard]] inline std::optional<Mesh> loadObjFromString(std::string_view objData)[[nodiscard]] inline std::optional<Mesh> loadObjFromFile(const std::string& filePath)struct ObjVertexKey 4
int posIdx = -1int texIdx = -1int normIdx = -1bool operator==(const ObjVertexKey& other) const noexceptstruct ObjVertexKeyHash 2
std::size_t operator()(const ObjVertexKey& key) const noexcept[[nodiscard]] inline std::optional<Mesh> loadObjWithMaterials(const std::string& filePath)struct CullAABB 2
float minX, minY, minZfloat maxX, maxY, maxZstruct CullResult 3
int totalObjects = 0int visibleObjects = 0int culledObjects = 0class OcclusionCuller 4
void resize(int width, int height)void updateDepth(const float* depthData, int width, int height)[[nodiscard]] bool isOccluded(const CullAABB& aabb, const float viewProj[16]) const[[nodiscard]] CullResult testBatch( const std::vector<CullAABB>& aabbs, const float viewProj[16]) constclass OffscreenRenderer3D 14
OffscreenRenderer3D(int width, int height)void beginScene()void addMesh(const Mesh& mesh, const sgc::Vec3f& position = {}, const sgc::Vec3f& rotation = {}, const sgc::Vec3f& scale = {1,1,1}, const Material& material = Material::defaultMaterial())void addLight(const Light& light)void render(const Camera3D& camera)[[nodiscard]] Texture texture() const[[nodiscard]] const RenderTexture& renderTexture() const noexceptvoid resize(int width, int height)[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexceptvoid setClearColor(const sgc::Colorf& color) noexcept[[nodiscard]] Scene3D& scene() noexcept[[nodiscard]] const Scene3D& scene() const noexceptstruct alignas(16) PBRShaderConstantsstruct PBRMaterial 12
float metallic = 0.0ffloat roughness = 0.5ffloat ao = 1.0fstd::string albedoMapKeystd::string normalMapKeystd::string metallicRoughnessMapKeystd::string aoMapKeystd::string emissiveMapKey[[nodiscard]] bool hasAnyMap() const noexcept[[nodiscard]] static PBRMaterial defaultMaterial() noexcept[[nodiscard]] static PBRMaterial metal(const sgc::Colorf& color, float rough = 0.3f) noexcept[[nodiscard]] static PBRMaterial dielectric(const sgc::Colorf& color, float rough = 0.5f) noexceptstruct PBREnvironment 5
std::string irradianceMapKeystd::string prefilteredMapKeystd::string brdfLutKeyfloat ambientIntensity = 1.0f[[nodiscard]] bool isValid() const noexceptclass PBRRenderer 79
PBRRenderer() noexcept = defaultbool init(ID3D11Device* device)bool initShaders(ID3D11Device* device)[[nodiscard]] const PBRShaderSet& shaders() const noexcept[[nodiscard]] bool isInitialized() const noexceptvoid setMaterial(const PBRMaterial& material) noexcept[[nodiscard]] const PBRMaterial& material() const noexceptvoid setEnvironment(const PBREnvironment& env) noexcept[[nodiscard]] const PBREnvironment& environment() const noexcept[[nodiscard]] static bool shouldUsePBR(const PBRMaterial& mat) noexceptvoid drawMesh(const sgc::Mat4f& worldMatrix, const sgc::Mat4f& viewMatrix, const sgc::Mat4f& projMatrix, const sgc::Vec3f& cameraPos, const sgc::Vec3f& lightDir, const sgc::Colorf& lightColor, float lightIntensity = 1.0f)[[nodiscard]] sgc::Colorf computeLighting( const sgc::Vec3f& worldPos, const sgc::Vec3f& normal, const sgc::Vec3f& cameraPos, const sgc::Vec3f& lightDir, const sgc::Colorf& lightColor, float lightIntensity = 1.0f) const noexcept`constexpr std::string_view kPBR_VS = R"hlsl(`constexpr std::string_view kPBR_BRDF_COMMON = R"hlsl(`constexpr std::string_view kPBR_CBUFFER_COMMON = R"hlsl(`constexpr std::string_view kPBR_PS_BODY = R"hlsl(`constexpr std::string_view kPBR_IBL_PS_BODY = R"hlsl(`constexpr std::string_view kPBR_SHADOW_PS_BODY = R"hlsl(`constexpr std::string_view kIBL_IRRADIANCE_PS = R"hlsl(`constexpr std::string_view kIBL_PREFILTER_PS = R"hlsl(`constexpr std::string_view kIBL_BRDF_LUT_PS = R"hlsl(`constexpr std::string_view kFULLSCREEN_QUAD_VS = R"hlsl(`constexpr std::string_view kCUBEMAP_FACE_VS = R"hlsl(VSOutput VSMain(VSInput input)// ── GGX / Trowbridge-Reitz Normal Distribution ──────────── float DistributionGGX(float3 N, float3 H, float roughness)// ── Schlick-GGX Geometry (single direction) ─────────────── float GeometrySchlickGGX(float NdotV, float roughness)// ── Smith's Geometry (combined) ─────────────────────────── float GeometrySmith(float3 N, float3 V, float3 L, float roughness)// ── Schlick-GGX for IBL (different k remapping) ────────── float GeometrySchlickGGX_IBL(float NdotV, float roughness)float GeometrySmith_IBL(float3 N, float3 V, float3 L, float roughness)// ── Fresnel (Schlick approximation) ────────────────────── float3 FresnelSchlick(float cosTheta, float3 F0)// ── Fresnel with roughness (for IBL ambient) ──────────── float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)// ── ACES Filmic Tone Mapping ───────────────────────────── float3 ACESFilm(float3 x)// ── Normal mapping via TBN matrix ──────────────────────── float3 ApplyNormalMap(float3 sampledNormal, float3 T, float3 B, float3 N)// ── Textures & Samplers ───────────────────────────────── Texture2D tAlbedo : register(t0)Texture2D tNormal : register(t1)Texture2D tMetalRough : register(t2)Texture2D tAO : register(t3)Texture2D tEmissive : register(t4)SamplerState sSampler : register(s0)// ── Lighting Calculation ──────────────────────────────── // Evaluate Cook-Torrance for a single directional light float3 EvalDirectionalLight(float3 N, float3 V, float3 lightDir, float3 lightColor, float lightIntensity, float3 albedo, float metallic, float roughness, float3 F0)// Evaluate Cook-Torrance for a single point light float3 EvalPointLight(float3 N, float3 V, float3 worldPos, float3 lightPos, float3 lightColor, float lightRange, float3 albedo, float metallic, float roughness, float3 F0)// ── Textures & Samplers ───────────────────────────────── Texture2D tAlbedo : register(t0)Texture2D tNormal : register(t1)Texture2D tMetalRough : register(t2)Texture2D tAO : register(t3)Texture2D tEmissive : register(t4)TextureCube tIrradiance : register(t5)TextureCube tPrefiltered : register(t6)Texture2D tBRDFLut : register(t7)SamplerState sSampler : register(s0)SamplerState sClampSampler : register(s1)Texture2D tAlbedo : register(t0)Texture2D tNormal : register(t1)Texture2D tMetalRough : register(t2)Texture2D tAO : register(t3)Texture2D tEmissive : register(t4)Texture2DArray tShadowMap : register(t8)SamplerState sSampler : register(s0)SamplerComparisonState sShadowSampler : register(s2)// ── Cascade Shadow Map Selection ──────────────────────── int SelectCascade(float viewDepth)// ── PCF 3x3 Shadow Sampling ──────────────────────────── float SampleShadowPCF(float3 worldPos, int cascadeIndex)SamplerState sSampler : register(s0)cbuffer CbIrradiance : register(b0)SamplerState sSampler : register(s0)cbuffer CbPrefilter : register(b0)// GGX NDF for prefilter float DistributionGGX_Prefilter(float NdotH, float roughness)// Radical inverse (Van der Corput sequence) float RadicalInverse_VdC(uint bits)float2 Hammersley(uint i, uint N)// GGX importance sampling float3 ImportanceSampleGGX(float2 Xi, float3 N, float roughness)float RadicalInverse_VdC(uint bits)float2 Hammersley(uint i, uint N)float3 ImportanceSampleGGX(float2 Xi, float3 N, float roughness)float GeometrySchlickGGX_IBL(float NdotV, float roughness)float GeometrySmith_IBL(float NdotV, float NdotL, float roughness)float2 IntegrateBRDF(float NdotV, float roughness)VSOutput VSMain(uint vertexID : SV_VertexID)VSOutput VSMain(uint vertexID : SV_VertexID)inline bool CompilePBRShader(std::string_view source, const char* entryPoint, const char* target, ID3DBlob** blob)[[nodiscard]] inline PBRShaderSet CompilePBRShaders(ID3D11Device* device)struct VSInput 4
float3 Position : POSITIONfloat3 Normal : NORMALfloat2 TexCoord : TEXCOORD0float4 Tangent : TANGENTstruct VSOutput 6
float4 Position : SV_POSITIONfloat3 WorldPos : TEXCOORD0float3 WorldNorm : TEXCOORD1float3 WorldTan : TEXCOORD2float3 WorldBitan : TEXCOORD3float2 TexCoord : TEXCOORD4struct PSInput 6
float4 Position : SV_POSITIONfloat3 WorldPos : TEXCOORD0float3 WorldNorm : TEXCOORD1float3 WorldTan : TEXCOORD2float3 WorldBitan : TEXCOORD3float2 TexCoord : TEXCOORD4struct PSInput 2
float4 Position : SV_POSITIONfloat3 WorldDir : TEXCOORD0struct PSInput 2
float4 Position : SV_POSITIONfloat3 WorldDir : TEXCOORD0struct VSOutput 2
float4 Position : SV_POSITIONfloat3 WorldDir : TEXCOORD0struct PBRShaderSet 12
Microsoft::WRL::ComPtr<ID3D11VertexShader> pbrVSMicrosoft::WRL::ComPtr<ID3D11PixelShader> pbrPSMicrosoft::WRL::ComPtr<ID3D11PixelShader> pbrIBL_PSMicrosoft::WRL::ComPtr<ID3D11PixelShader> pbrShadowPSMicrosoft::WRL::ComPtr<ID3D11PixelShader> iblIrradiancePSMicrosoft::WRL::ComPtr<ID3D11PixelShader> iblPrefilterPSMicrosoft::WRL::ComPtr<ID3D11PixelShader> iblBrdfLutPSMicrosoft::WRL::ComPtr<ID3D11VertexShader> fullscreenQuadVSMicrosoft::WRL::ComPtr<ID3D11VertexShader> cubemapFaceVSMicrosoft::WRL::ComPtr<ID3D11InputLayout> pbrInputLayoutbool valid = falsestatic constexpr std::string_view PARTICLE_COLLISION_CS_HLSL = R"( struct Particle { float3 position; float pad0; float3 velocity; float life; }; struct CollisionEvent { uint particleIndex; float contactX; float contactY; float contactZ; float penetrationDepth; float pad0; float pad1; float pad2; }; cbuffer CollisionParams : register(b0) { float4x4 viewProj; // CPU側で transposed() してアップロード済み float depthThreshold; float restitution; float friction; float deltaTime; int depthWidth; int depthHeight; int maxParticles; int _pad; }; RWStructuredBuffer<Particle> particles : register(u0); AppendStructuredBuffer<CollisionEvent> events : register(u1); Texture2D<float> depthBuffer : register(t0); [numthreads(64, 1, 1)] void CSMain(uint3 dtid : SV_DispatchThreadID) { uint id = dtid.x; if (id >= (uint)maxParticles) { return; } Particle p = particles[id]; if (p.life <= 0.0) { return; } // mul(matrix, column_vec): CPU側 transposed() + HLSL左matrix → sgc * vec float4 clip = mul(viewProj, float4(p.position, 1.0)); if (clip.w <= 0.0) { return; } float3 ndc = clip.xyz / clip.w; if (any(abs(ndc.xy) > 1.0)) { return; } if (ndc.z < 0.0 || ndc.z > 1.0) { return; } float2 uv = ndc.xy * float2(0.5, -0.5) + 0.5; int2 px = int2(uv * float2((float)depthWidth, (float)depthHeight)); px = clamp(px, int2(0,0), int2(depthWidth-1, depthHeight-1)); float scene_z = depthBuffer.Load(int3(px, 0)); float diff = ndc.z - scene_z; if (diff > depthThreshold) { // 反射応答(Y軸法線を仮定) float3 normal = float3(0.0, 1.0, 0.0); float vDotN = dot(p.velocity, normal); if (vDotN < 0.0) { p.velocity = p.velocity - (1.0 + restitution) * vDotN * normal; p.velocity.xz *= (1.0 - friction); } particles[id] = p; CollisionEvent ev; ev.particleIndex = id; ev.contactX = p.position.x; ev.contactY = p.position.y; ev.contactZ = p.position.z; ev.penetrationDepth = diff; ev.pad0 = 0.0; ev.pad1 = 0.0; ev.pad2 = 0.0; events.Append(ev); } } )"struct ParticleCollisionConfig 7
float depthThreshold = 0.01ffloat restitution = 0.3ffloat friction = 0.5ffloat stickyThreshold = 0.05fbool enableCollision = truebool enableSticky = falseint maxCollisionsPerFrame = 1024struct ParticleCollisionEvent 2
std::uint32_t particleIndex = 0float penetrationDepth = 0.0fstruct ParticleCollisionStats 4
int totalParticles = 0int collisionsDetected = 0int collisionsResolved = 0float resolveTimeMs = 0.0fstruct CollisionParticle 4
float position[3]float pad0float velocity[3]float lifestruct CollisionEvent_GPU 6
std::uint32_t particleIndexfloat contactXfloat contactYfloat contactZfloat penetrationDepthfloat pad[3]class ParticleCollisionResolver 17
ParticleCollisionResolver() = default~ParticleCollisionResolver()ParticleCollisionResolver(const ParticleCollisionResolver&) = deleteParticleCollisionResolver& operator=(const ParticleCollisionResolver&) = deleteParticleCollisionResolver(ParticleCollisionResolver&&) noexcept = defaultParticleCollisionResolver& operator=(ParticleCollisionResolver&&) noexcept = defaultbool init(int maxParticles, const ParticleCollisionConfig& config = {})void setCamera(const float* viewMatrix, const float* projMatrix)[[nodiscard]] std::vector<ParticleCollisionEvent> resolve(float deltaTime)[[nodiscard]] ParticleCollisionStats stats() const noexcept[[nodiscard]] ParticleCollisionConfig& config() noexcept[[nodiscard]] const ParticleCollisionConfig& config() const noexceptbool init(ID3D11Device* device, int maxParticles, const ParticleCollisionConfig& cfg = {})void shutdown()void setCameraVP(const float* vpRowMajor)void uploadParticles(const CollisionParticle* data, int count)void uploadDepth(const float* data, int width, int height)struct Particle3D 5
float size = 0.2ffloat endSize = 0.0ffloat life = 1.0ffloat maxLife = 1.0fbool alive = falsestruct ParticleEmitter3D 9
float emitSpread = 0.5ffloat emitSpeed = 2.0ffloat emitSpeedVariance = 0.5ffloat startSize = 0.3ffloat endSize = 0.0ffloat particleLife = 1.0ffloat particleLifeVariance = 0.3ffloat emitRate = 10.0fbool active = trueclass ParticleSystem3D 8
explicit ParticleSystem3D(int maxParticles = 256)void setEmitter(const ParticleEmitter3D& emitter)ParticleEmitter3D& emitter() noexceptconst ParticleEmitter3D& emitter() const noexceptvoid update(float dt)void fillBillboards(Billboard3D& billboards) const[[nodiscard]] int aliveCount() const noexceptvoid clear()enum RenderMode 2
ForwardDeferredstruct DrawCommand3D 3
const Mesh* mesh = nullptrsgc::Mat4f transformMaterial materialclass Pipeline3D 15
Pipeline3D() noexcept = defaultvoid setDevice(gfx::IDevice* device) noexceptvoid setRenderMode(RenderMode mode) noexcept[[nodiscard]] RenderMode renderMode() const noexcept[[nodiscard]] gfx::IDevice* device() const noexceptvoid begin(const Camera3D& camera)void submitMesh(const Mesh& mesh, const sgc::Mat4f& transform, const Material& material)void submitLight(const Light& light)void end()[[nodiscard]] int drawCallCount() const noexcept[[nodiscard]] const std::vector<DrawCommand3D>& drawCommands() const noexcept[[nodiscard]] const std::vector<Light>& lights() const noexcept[[nodiscard]] const sgc::Mat4f& viewMatrix() const noexcept[[nodiscard]] const sgc::Mat4f& projectionMatrix() const noexcept[[nodiscard]] const sgc::Mat4f& viewProjectionMatrix() const noexceptclass PostEffects 4
static void bloom(RenderTexture& rt, float threshold = 0.7f, float intensity = 0.5f, int radius = 3)static void vignette(RenderTexture& rt, float strength = 0.5f, float radius = 0.8f)static void saturation(RenderTexture& rt, float amount = 1.2f)static void contrast(RenderTexture& rt, float amount = 1.1f)class PostProcessManager 52
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>PostProcessManager() noexcept = defaultvoid init(ID3D11Device* device, int screenW, int screenH)void resize(int w, int h)void setConfig(const PostProcessConfig& config)void beginScene(ID3D11DeviceContext* context)void endScene( ID3D11DeviceContext* context, ID3D11RenderTargetView* backbufferRTV)[[nodiscard]] bool isEnabled() const noexceptvoid setEnabled(bool enabled) noexceptvoid enableBloom(float threshold = 0.8f, float intensity = 1.0f)void enableVignette(float intensity = 0.5f, float radius = 0.8f)void enableColorGrading( float brightness = 0.0f, float contrast = 1.0f, float saturation = 1.0f)void enableFrostGlass(float blurAmount = 2.0f)void enableFXAA(FXAAQuality quality = FXAAQuality::Medium)void disableFXAA()void disableAll()[[nodiscard]] GpuTexture2D captureSceneTexture()[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] ID3D11ShaderResourceView* sceneTextureSRV() const noexcept[[nodiscard]] ID3D11DepthStencilView* depthStencilView() const noexcept[[nodiscard]] PostProcessChain* chain() const noexcept[[nodiscard]] const PostProcessConfig& config() const noexcept`constexpr std::string_view PP_FULLSCREEN_VS = R"hlsl(`constexpr std::string_view PP_BLOOM_EXTRACT_PS = R"hlsl(`constexpr std::string_view PP_BLOOM_COMBINE_PS = R"hlsl(`constexpr std::string_view PP_GAUSSIAN_BLUR_PS = R"hlsl(`constexpr std::string_view PP_COLOR_GRADING_PS = R"hlsl(`constexpr std::string_view PP_VIGNETTE_PS = R"hlsl(`constexpr std::string_view PP_CHROMATIC_ABERRATION_PS = R"hlsl(`constexpr std::string_view PP_FILM_GRAIN_PS = R"hlsl(`constexpr std::string_view PP_FADE_PS = R"hlsl(`constexpr std::string_view PP_FROST_GLASS_PS = R"hlsl(VSOutput VSMain(uint vertexId : SV_VertexID)SamplerState linearSampler : register(s0)cbuffer BloomParams : register(b0)Texture2D bloomTexture : register(t1)SamplerState linearSampler : register(s0)SamplerState linearSampler : register(s0)cbuffer BlurParams : register(b0)float gaussWeight(int offset, float s)SamplerState linearSampler : register(s0)cbuffer ColorGradingParams : register(b0)SamplerState linearSampler : register(s0)cbuffer VignetteParams : register(b0)SamplerState linearSampler : register(s0)cbuffer ChromaticParams : register(b0)SamplerState linearSampler : register(s0)cbuffer FilmGrainParams : register(b0)SamplerState linearSampler : register(s0)cbuffer FadeParams : register(b0)SamplerState linearSampler : register(s0)cbuffer FrostParams : register(b0)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 8
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0inline constexpr bool kUsePrecompiledShaders = trueinline constexpr bool kUsePrecompiledShaders = false[[nodiscard]] inline ShaderBytecode precompiledVS3D() noexcept[[nodiscard]] inline ShaderBytecode precompiledPS3D() noexcept[[nodiscard]] inline ShaderBytecode precompiledVS2D() noexcept[[nodiscard]] inline ShaderBytecode precompiledPS2D() noexceptstruct ShaderBytecode 3
const uint8_t* data = nullptrstd::size_t size = 0[[nodiscard]] bool valid() const noexceptstruct RenderPass 3
std::string namebool enabled = truestd::function<void()> executeclass RenderGraph 7
void addPass(const std::string& name, std::function<void()> executeFunc)bool setPassEnabled(const std::string& name, bool enabled)[[nodiscard]] int execute()[[nodiscard]] std::size_t passCount() const noexceptvoid clear() noexcept[[nodiscard]] const std::vector<RenderPass>& passes() const noexcept#pragma once #include <algorithm> #include <cstdint> #include <cstring> #include <memory> #include <stack> #include <vector> #include <sgc/math/Rect.hpp> #include <mitiru/gfx/IBuffer.hpp> #include <mitiru/gfx/ICommandList.hpp> #include <mitiru/gfx/IDevice.hpp> #include <mitiru/gfx/IPipeline.hpp> #include <mitiru/render/DefaultShaders.hpp> #include <mitiru/render/StyledRectBatch.hpp> #include <mitiru/render/Vertex2D.hpp> #ifdef __EMSCRIPTEN__ #include <GLES3/gl3.h> #include <mitiru/gfx/webgl/WebGlShader.hpp> #include <mitiru/gfx/webgl/WebGlBuffer.hpp> #endif #ifdef _WIN32 #include <mitiru/gfx/dx11/Dx11Buffer.hpp> #include <mitiru/gfx/dx11/Dx11CommandList.hpp> #include <mitiru/gfx/dx11/Dx11Device.hpp> #include <mitiru/gfx/dx11/Dx11Pipeline.hpp> #include <mitiru/gfx/dx11/Dx11Shader.hpp> #include <d3d12.h> #include <d3dcompiler.h> #include <wrl/client.h> #include <mitiru/gfx/dx12/Dx12Device.hpp> #include <mitiru/gfx/dx12/Dx12SwapChain.hpp> #pragma comment(lib, "d3dcompiler.lib") #endif namespace mitiru::renderstruct ValidationReport 7
int totalTests = 0int passed = 0int failed = 0std::vector<std::string> errorsvoid record(const std::string& name, bool success, const std::string& errorMsg = {})[[nodiscard]] bool allPassed() const noexceptvoid merge(const ValidationReport& other)class RenderPipelineValidator 6
RenderPipelineValidator() noexcept = default[[nodiscard]] ValidationReport validateDX11Pipeline(Renderer3D& renderer) const[[nodiscard]] ValidationReport validateDX12Pipeline( Renderer3D_DX12& renderer) const[[nodiscard]] ValidationReport validateToonPipeline( ToonPipeline& pipeline) const[[nodiscard]] ValidationReport validatePBRShaders( ID3D11Device* device) const[[nodiscard]] ValidationReport validateStub() constenum CullMode 3
NoneBackFrontstruct RenderState3D 11
bool wireframe = falseCullMode cullMode = CullMode::Backbool depthTest = truebool depthWrite = truebool blendEnabled = false[[nodiscard]] static constexpr RenderState3D opaque() noexcept[[nodiscard]] static constexpr RenderState3D transparent() noexcept[[nodiscard]] static constexpr RenderState3D wireframeState() noexcept[[nodiscard]] static constexpr RenderState3D noCull() noexcept[[nodiscard]] constexpr bool operator==(const RenderState3D& other) const noexcept[[nodiscard]] constexpr bool operator!=(const RenderState3D& other) const noexceptclass RenderTexture 9
RenderTexture(int width, int height)void clear(const sgc::Colorf& color = {0, 0, 0, 1})void drawRect(const sgc::Rectf& rect, const sgc::Colorf& color)void setPixel(int x, int y, const sgc::Colorf& color)[[nodiscard]] Texture texture() const[[nodiscard]] sgc::Colorf pixelAt(int x, int y) const noexcept[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexcept[[nodiscard]] const std::vector<uint8_t>& pixels() const noexceptclass Renderer2D 16
Renderer2D() noexcept = defaultexplicit Renderer2D(float screenWidth, float screenHeight) noexceptvoid beginFrame() noexceptvoid endFrame() noexceptvoid drawRect(const sgc::Rectf& rect, const sgc::Colorf& color)void drawRectFrame(const sgc::Rectf& rect, const sgc::Colorf& color, float thickness = 1.0f)void drawCircle(const sgc::Vec2f& center, float radius, const sgc::Colorf& color, int segments = 32)void drawLine(const sgc::Vec2f& from, const sgc::Vec2f& to, const sgc::Colorf& color, float thickness = 1.0f)void drawTriangle(const sgc::Vec2f& p0, const sgc::Vec2f& p1, const sgc::Vec2f& p2, const sgc::Colorf& color)void drawText(const sgc::Vec2f& position, std::string_view text, const sgc::Colorf& color, float fontSize = 16.0f)void setCamera(const Camera2D& camera) noexcept[[nodiscard]] Camera2D& camera() noexcept[[nodiscard]] const Camera2D& camera() const noexcept[[nodiscard]] int totalDrawCalls() const noexcept[[nodiscard]] SpriteBatch& spriteBatch() noexcept[[nodiscard]] ShapeRenderer& shapeRenderer() noexceptstruct Renderer2DBridgeConfig 3
float screenW = 1280.0ffloat screenH = 720.0fbool vsync = trueclass Renderer2DBridge 24
explicit Renderer2DBridge(std::unique_ptr<sgc::graphics::IRenderer2D> inner) noexceptvoid drawCircle(sgc::Vec2f center, float radius, sgc::graphics::Color fill)void drawCircleOutline(sgc::Vec2f center, float radius, sgc::graphics::Color stroke, float thickness)void drawRect(sgc::Vec2f pos, sgc::Vec2f size, sgc::graphics::Color fill)void drawRectOutline(sgc::Vec2f pos, sgc::Vec2f size, sgc::graphics::Color stroke, float thickness)void drawLine(sgc::Vec2f from, sgc::Vec2f to, sgc::graphics::Color color, float thickness)void drawTriangle(sgc::Vec2f a, sgc::Vec2f b, sgc::Vec2f c, sgc::graphics::Color fill)void drawPolygon(const std::vector<sgc::Vec2f>& points, sgc::graphics::Color fill)void drawBezier(sgc::Vec2f p0, sgc::Vec2f p1, sgc::Vec2f p2, sgc::Vec2f p3, sgc::graphics::Color color, float thickness, int segments = 32)void drawText(sgc::Vec2f pos, const std::string& text, float fontSize, sgc::graphics::Color color)void setViewMatrix(const sgc::Mat4f& mat)[[nodiscard]] sgc::Vec2f getScreenSize() constvoid beginFrame()void endFrame()void drawCircleWithGlow(sgc::Vec2f center, float radius, sgc::graphics::Color fillColor, sgc::graphics::Color glowColor, float glowRadius)void drawRectWithGlow(sgc::Vec2f pos, sgc::Vec2f size, sgc::graphics::Color fillColor, sgc::graphics::Color glowColor, float glowRadius)void drawLineWithGlow(sgc::Vec2f from, sgc::Vec2f to, sgc::graphics::Color color, sgc::graphics::Color glowColor, float thickness, float glowThickness)void pushTransform(const sgc::Mat4f& mat)void popTransform()[[nodiscard]] int transformStackDepth() const noexceptvoid setCamera(const sgc::graphics::Camera2D& camera)[[nodiscard]] sgc::graphics::IRenderer2D& inner() noexcept[[nodiscard]] const sgc::graphics::IRenderer2D& inner() const noexcept#pragma once #include <cstdint> #include <cstring> #include <memory> #include <vector> #include <sgc/math/Mat4.hpp> #include <sgc/math/Vec3.hpp> #include <sgc/math/Vec4.hpp> #include <sgc/types/Color.hpp> #include <mitiru/render/GlmBridge.hpp> #include <mitiru/render/Camera3D.hpp> #include <mitiru/render/DefaultShaders3D.hpp> #include <mitiru/render/ToonShaders3D.hpp> #include <mitiru/render/NPRShaders3D.hpp> #include <mitiru/render/MultiLightShaders3D.hpp> #include <mitiru/render/Light.hpp> #include <mitiru/render/LightArrayCB.hpp> #include <mitiru/render/Cubemap.hpp> #include <mitiru/render/Skybox.hpp> #include <mitiru/render/Material.hpp> #include <mitiru/render/Mesh.hpp> #include <mitiru/render/RenderState3D.hpp> #include <mitiru/render/Texture.hpp> #include <mitiru/render/Vertex3D.hpp> #include <mitiru/gfx/IBuffer.hpp> #include <mitiru/gfx/IDevice.hpp> #include <mitiru/render/IRenderer3D.hpp> #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef NOMINMAX #define NOMINMAX #endif #include <Windows.h> #include <d3d11.h> #include <d3dcompiler.h> #include <wrl/client.h> #pragma comment(lib, "d3dcompiler.lib") #pragma comment(lib, "d3d11.lib") #include <mitiru/gfx/dx11/Dx11Buffer.hpp> #include <mitiru/gfx/dx11/Dx11Device.hpp> #include <mitiru/gfx/dx11/Dx11Shader.hpp> #endif namespace mitiru::renderclass Renderer3D_DX12 : public IRenderer3D 78
Renderer3D_DX12()~Renderer3D_DX12()Renderer3D_DX12(const Renderer3D_DX12&) = deleteRenderer3D_DX12& operator=(const Renderer3D_DX12&) = deleteRenderer3D_DX12(Renderer3D_DX12&&) noexcept = defaultRenderer3D_DX12& operator=(Renderer3D_DX12&&) noexcept = defaultvoid initialize(gfx::Dx12Device* device, const Config& cfg = {})[[nodiscard]] bool isInitialized() const noexcept overridevoid resize(float width, float height)void beginFrame(const sgc::Colorf& clearColor = {0.2f, 0.2f, 0.3f, 1.0f}) overridevoid setCamera(const Camera3D& camera) overridevoid setLight(const Light& light) overridevoid setAmbientColor(const sgc::Colorf& color) override[[nodiscard]] sgc::Colorf ambientColor() const noexcept overridevoid drawMesh(const Mesh& mesh, const sgc::Mat4f& worldTransform, const Material& material) overridevoid endFrame() overridevoid finalizeFrame()[[nodiscard]] int drawCallCount() const noexcept overridevoid setOutlineEnabled(bool enabled) noexcept override[[nodiscard]] bool isOutlineEnabled() const noexcept overridevoid setOutlineMode(OutlineMode mode) noexcept override[[nodiscard]] OutlineMode outlineMode() const noexcept overridevoid setTonemapExposure(float exposure) override[[nodiscard]] float tonemapExposure() const noexcept overridevoid setTonemapGamma(float gamma) override[[nodiscard]] float tonemapGamma() const noexcept overridevoid setFXAAEnabled(bool enabled) noexcept[[nodiscard]] bool isFXAAEnabled() const noexceptvoid setFXAAQuality(float subpixQuality, float edgeThreshold, float edgeThresholdMin) noexcept[[nodiscard]] ID3D12GraphicsCommandList* getCommandList() noexcept[[nodiscard]] ID3D12Device* getNativeDevice() noexcept[[nodiscard]] gfx::Dx12Device* getDx12Device() noexcept[[nodiscard]] ID3D12Resource* getDepthBuffer() noexcept[[nodiscard]] ID3D12Resource* getNormalBuffer() noexcept[[nodiscard]] ID3D12RootSignature* getMainRootSignature() noexcept[[nodiscard]] ID3D12RootSignature* getOutlinePostRootSig() noexcept[[nodiscard]] ID3D12DescriptorHeap* getDepthSRVHeap() noexcept[[nodiscard]] ComPtr<ID3D12Resource> createUploadBufferPublic(UINT64 sizeBytes) constvoid keepTempResource(ComPtr<ID3D12Resource> resource)void restoreMainState()static void getInputLayout(D3D12_INPUT_ELEMENT_DESC* desc, UINT& count)void destroy()[[nodiscard]] bool isFrameActive() const noexcept overridevoid resetFrameActive() noexcept overridevoid setOverlayScreen(const Screen* screen) noexcept overridevoid setLights(std::span<const Light> lights) overridevoid setUseMultiLight(bool useMulti) override[[nodiscard]] bool useMultiLight() const noexcept overridevoid setShaderMode(ShaderMode3D mode) override[[nodiscard]] ShaderMode3D shaderMode() const noexceptvoid setShadowEnabled(bool enabled) noexcept[[nodiscard]] bool isShadowEnabled() const noexceptvoid setShadowDirection(const sgc::Vec3f& dir) noexcept[[nodiscard]] DirectionalShadowConfig& shadowConfig() noexcept[[nodiscard]] const DirectionalShadowConfig& shadowConfig() const noexcept[[nodiscard]] std::span<const Light> lights() const noexceptvoid setSkybox(const Cubemap& cubemap) overridevoid setSkyboxEnabled(bool enabled) override[[nodiscard]] bool isSkyboxEnabled() const noexcept override[[nodiscard]] bool hasOverlaySupport() const noexcept override[[nodiscard]] ID3D12GraphicsCommandList* getCommandList() const noexcept[[nodiscard]] void* nativeCommandList() const noexcept override[[nodiscard]] void* nativeDevice() const noexcept override[[nodiscard]] void* nativeSwapChain() const noexcept override`constexpr std::string_view PP_SSAO_PS = R"hlsl(`constexpr std::string_view PP_SSAO_BLUR_PS = R"hlsl(`constexpr std::string_view PP_SSAO_COMPOSITE_PS = R"hlsl(Texture2D noiseTexture : register(t1)SamplerState pointClampSampler : register(s0)SamplerState noiseWrapSampler : register(s1)cbuffer SSAOParams : register(b0)// ── 深度値からビュー空間Z座標を復元する ────────────────── float linearizeDepth(float d)// ── UV+深度からビュー空間位置を復元する ───────────────── float3 reconstructViewPos(float2 uv, float depth)// ── 深度バッファから近似法線を求める ──────────────────── float3 estimateNormal(float2 uv, float2 texelSize)SamplerState pointClampSampler : register(s0)cbuffer SSAOBlurParams : register(b0)Texture2D aoTexture : register(t1)SamplerState linearSampler : register(s0)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct SSAOConfig 5
float radius = 0.5ffloat bias = 0.025ffloat intensity = 1.0ffloat nearPlane = 0.1ffloat farPlane = 100.0fclass SSAOPass : public PostProcessPass 9
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>SSAOPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler, std::uint32_t screenW, std::uint32_t screenH)void setDepthSRV( ID3D11ShaderResourceView* depthSRV) noexceptvoid setProjection(const float* proj) noexceptvoid setConfig(const SSAOConfig& cfg) noexcept[[nodiscard]] ID3D11ShaderResourceView* aoSRV() const noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] const SSAOConfig& config() const noexceptclass Scene3D 8
Scene3D() noexcept = defaultvoid addObject(RenderObject obj)void addLight(Light light)void clear()[[nodiscard]] const std::vector<RenderObject>& objects() const noexcept[[nodiscard]] const std::vector<Light>& lights() const noexcept[[nodiscard]] std::size_t objectCount() const noexcept[[nodiscard]] std::size_t lightCount() const noexceptclass ScenePlacer 5
static void placeOnSurface(Scene3D& scene, const Mesh& mesh, float surfaceY, sgc::Vec2f xz, float scale, const Material& material)static void place(Scene3D& scene, const Mesh& mesh, sgc::Vec3f position, float scale, const Material& material)static void placeOnTop(Scene3D& scene, const Mesh& itemMesh, const Mesh& baseMesh, sgc::Vec3f basePosition, float baseScale, sgc::Vec2f offsetXZ, float itemScale, const Material& material)static void placeRow(Scene3D& scene, const Mesh& mesh, sgc::Vec3f startPos, float spacing, int count, float scale, const Material& material)[[nodiscard]] inline ScreenshotData capture( const gfx::IDevice& device, int width, int height, std::uint64_t frameNumber = 0)struct ScreenshotData 9
std::vector<std::uint8_t> pixelsint width = 0int height = 0std::uint64_t frameNumber = 0[[nodiscard]] bool isValid() const noexcept[[nodiscard]] std::uint8_t pixelR(int x, int y) const noexcept[[nodiscard]] std::uint8_t pixelG(int x, int y) const noexcept[[nodiscard]] std::uint8_t pixelB(int x, int y) const noexcept[[nodiscard]] std::uint8_t pixelA(int x, int y) const noexceptenum ButtonState 4
NormalHoveredPressedDisabledenum NotificationType 4
InfoSuccessWarningErrorenum ArrowDirection 4
UpDownLeftRightstruct PanelStyle 6
float cornerRadius = 0.0ffloat borderWidth = 0.0ffloat shadowBlur = 0.0ffloat backdropBlur = 0.0ffloat opacity = 1.0ffloat gradientAngle = 0.0fstruct ButtonStyle 5
PanelStyle normalPanelStyle hoveredPanelStyle pressedPanelStyle disabledfloat fontSize = 16.0fstruct CardStyle 5
PanelStyle panelfloat titleFontSize = 18.0ffloat bodyFontSize = 14.0ffloat imageHeight = 120.0ffloat padding = 12.0fstruct ProgressBarStyle 3
PanelStyle trackfloat cornerRadius = 4.0ffloat height = 8.0fstruct PostProcessSettings 8
bool bloomEnabled = falsefloat bloomThreshold = 1.0ffloat bloomIntensity = 0.5fbool vignetteEnabled = falsefloat vignetteIntensity = 0.3ffloat brightness = 1.0ffloat contrast = 1.0ffloat saturation = 1.0fclass ScreenEnhanced 27
explicit ScreenEnhanced(Screen& screen) noexcept[[nodiscard]] Screen& screen() noexcept[[nodiscard]] const Screen& screen() const noexcept[[nodiscard]] bool hasSdfFont() const noexceptvoid setSdfFontReady(bool ready) noexceptvoid drawSdfText(const sgc::Vec2f& pos, std::string_view text, float fontSize, const sgc::Colorf& color)void drawSdfTextWithOutline(const sgc::Vec2f& pos, std::string_view text, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& outlineColor, float outlineWidth)void drawSdfTextWithShadow(const sgc::Vec2f& pos, std::string_view text, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& shadowColor, const sgc::Vec2f& shadowOffset)void drawRoundedRect(const sgc::Rectf& rect, float cornerRadius, const sgc::Colorf& fillColor)void drawRoundedRectWithBorder(const sgc::Rectf& rect, float cornerRadius, const sgc::Colorf& fillColor, const sgc::Colorf& borderColor, float borderWidth)void drawRoundedRectWithShadow(const sgc::Rectf& rect, float cornerRadius, const sgc::Colorf& fillColor, const sgc::Colorf& shadowColor, float shadowBlur, const sgc::Vec2f& shadowOffset)void drawPill(const sgc::Rectf& rect, const sgc::Colorf& fillColor)void drawPanel(const sgc::Rectf& rect, const PanelStyle& style)void drawLinearGradient(const sgc::Rectf& rect, float angleDeg, const sgc::Colorf& colorFrom, const sgc::Colorf& colorTo)void drawRadialGradient(const sgc::Rectf& rect, const sgc::Colorf& centerColor, const sgc::Colorf& edgeColor)void drawButton(const sgc::Rectf& rect, std::string_view text, ButtonState state, const ButtonStyle& style)void drawCard(const sgc::Rectf& rect, std::string_view title, std::string_view body, const Texture* imageTexture, const CardStyle& style)void drawTooltip(const sgc::Rectf& rect, std::string_view text, ArrowDirection arrowDir)void drawNotification(const sgc::Rectf& rect, std::string_view icon, std::string_view title, std::string_view message, NotificationType type)void drawProgressBar(const sgc::Rectf& rect, float progress, const ProgressBarStyle& style)void beginPostProcess()void endPostProcess()void setBloom(bool enabled, float threshold = 1.0f, float intensity = 0.5f) noexceptvoid setVignette(bool enabled, float intensity = 0.3f) noexceptvoid setColorGrading(float brightness, float contrast, float saturation) noexcept[[nodiscard]] const PostProcessSettings& postProcessSettings() const noexceptvoid drawRoundedRectBorderOnly(const sgc::Rectf& rect, float cornerRadius, const sgc::Colorf& borderColor, float borderWidth)class SdfTextRenderer 16
SdfTextRenderer() = defaultexplicit SdfTextRenderer(const SdfFontAtlas& atlas) noexceptvoid setAtlas(const SdfFontAtlas& atlas) noexcept[[nodiscard]] bool ready() const noexcept[[nodiscard]] SdfTextSize measureText(std::string_view text, float fontSize) const[[nodiscard]] std::vector<SdfWrappedLine> wrapText( std::string_view text, float fontSize, float maxWidth) consttemplate <typename BatchType> void drawText(BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& color) consttemplate <typename BatchType> void drawTextWithOutline(BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& outlineColor, float outlineWidth = 0.1f) consttemplate <typename BatchType> void drawTextWithShadow(BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& shadowColor, const sgc::Vec2f& shadowOffset = {2.0f, 2.0f}) consttemplate <typename BatchType> void drawTextWithGlow(BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& glowColor, float glowRadius = 0.2f) consttemplate <typename BatchType> void drawTextWithEffect(BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const SdfTextEffect& effect) consttemplate <typename ScreenType> void drawTextSoftware(ScreenType& screen, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& color) consttemplate <typename ScreenType> void drawTextSoftwareWithOutline(ScreenType& screen, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& outlineColor, float outlineWidth = 0.1f) consttemplate <typename ScreenType> void drawTextSoftwareWithShadow(ScreenType& screen, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& shadowColor, const sgc::Vec2f& shadowOffset = {2.0f, 2.0f}, float shadowSoftness = 0.15f) consttemplate <typename ScreenType> void drawTextSoftwareWithGlow(ScreenType& screen, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& glowColor, float glowRadius = 0.2f) consttemplate <typename ScreenType> void drawTextSoftwareWithEffect(ScreenType& screen, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const SdfTextEffect& effect) conststruct SdfShaderLogic 10
[[nodiscard]] static float textAlpha(float dist, float smoothing) noexcept[[nodiscard]] static float outlineAlpha(float dist, float smoothing, float outlineWidth) noexcept[[nodiscard]] static float glowAlpha(float dist, float smoothing, float glowRadius) noexcept[[nodiscard]] static sgc::Colorf compositeOutline( const sgc::Colorf& textColor, const sgc::Colorf& outlineColor, float textA, float outlineA) noexcept`constexpr std::string_view GPU_SDF_PS = R"hlsl(SamplerState samp : register(s0)cbuffer SdfParams : register(b1)[[nodiscard]] inline Microsoft::WRL::ComPtr<ID3D11PixelShader> createSdfPixelShader(ID3D11Device* device)inline void beginSdfRendering(ID3D11DeviceContext* context, SdfFontGpu& gpu, GpuSpriteBatch& batch)inline void endSdfRendering(ID3D11DeviceContext* context, SdfFontGpu& gpu, GpuSpriteBatch& batch)struct PSInput 3
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0float4 color : COLOR0struct SdfShaderParams 3
float outlineWidth = 0.0ffloat glowRadius = 0.0ffloat smoothing = 1.0fclass SdfFontGpu 11
SdfFontGpu() noexcept = defaultvoid init(ID3D11Device* device, const SdfFontAtlas& atlas)void beginSdfRendering(ID3D11DeviceContext* context, GpuSpriteBatch& batch)void endSdfRendering(ID3D11DeviceContext* context, GpuSpriteBatch& batch)void drawText(GpuSpriteBatch& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& color)void drawTextWithOutline(GpuSpriteBatch& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& outlineColor, float outlineWidth)void drawTextWithShadow(GpuSpriteBatch& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& shadowColor, float shadowOffsetX, float shadowOffsetY)void drawTextWithGlow(GpuSpriteBatch& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& textColor, const sgc::Colorf& glowColor, float glowRadius)[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] const GpuTexture2D& atlasTexture() const noexcept[[nodiscard]] bool isSdfActive() const noexceptclass ShaderLoader 6
static void setShaderDirectory(const std::string& dir)[[nodiscard]] static const std::string& getShaderDirectory()[[nodiscard]] static std::optional<std::string> loadFromFile( const std::string& relativePath)[[nodiscard]] static std::string load( const std::string& relativePath, std::string_view fallback)static void clearCache()[[nodiscard]] static const std::string& loadCached( const std::string& relativePath, std::string_view fallback)struct DirectionalShadowConfig 6
int mapSize = 1024float orthoHalfExtent = 20.0ffloat nearClip = 0.1ffloat farClip = 100.0ffloat depthBias = 0.001ffloat pcfRadius = 1.5fclass DirectionalShadow 6
[[nodiscard]] DirectionalShadowConfig& config() noexcept[[nodiscard]] const DirectionalShadowConfig& config() const noexceptvoid setLightDirection(const sgc::Vec3f& dir) noexcept[[nodiscard]] sgc::Vec3f lightDirection() const noexcept[[nodiscard]] sgc::Mat4f lightViewMatrix(const sgc::Vec3f& sceneFocus) const noexcept[[nodiscard]] sgc::Mat4f lightProjectionMatrix() const noexceptstruct ShadowMapConfig 4
int resolution = 2048float orthoSize = 50.0ffloat nearPlane = 0.1ffloat farPlane = 100.0fclass ShadowMap 12
ShadowMap() noexcept = defaultvoid initialize(const ShadowMapConfig& cfg)[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] const ShadowMapConfig& config() const noexceptvoid beginShadowPass(const Light& light)void recordMesh(const Mesh& mesh, const sgc::Mat4f& worldTransform)void endShadowPass() noexcept[[nodiscard]] const sgc::Mat4f& lightVP() const noexcept[[nodiscard]] float sampleDepth(float u, float v) const noexcept[[nodiscard]] bool isInShadow( const sgc::Vec3f& worldPos, float bias = 0.005f) const noexcept[[nodiscard]] const std::vector<float>& depthBuffer() const noexceptconstexpr const char* SHADOW_DEPTH_VS = R"hlsl( cbuffer LightVP : register(b0) { float4x4 lightViewProj; }; struct VSInput { float3 position : POSITION; }; struct VSOutput { float4 position : SV_POSITION; }; VSOutput main(VSInput input) { VSOutput o; // 行列は転置済みで upload されるため HLSL では mul(mat, col_vec) = sgc * vec o.position = mul(lightViewProj, float4(input.position, 1.0)); return o; } )hlsl"struct ShadowMapConfig3D 5
int resolution = 1024float orthoSize = 15.0ffloat nearPlane = 0.1ffloat farPlane = 50.0ffloat bias = 0.005fclass ShadowPass3D 19
using ComPtr = Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>;ShadowPass3D() = default~ShadowPass3D()ShadowPass3D(const ShadowPass3D&) = deleteShadowPass3D& operator=(const ShadowPass3D&) = deleteShadowPass3D(ShadowPass3D&&) = defaultShadowPass3D& operator=(ShadowPass3D&&) = defaultvoid setConfig(const ShadowMapConfig3D& config)const ShadowMapConfig3D& config() const noexcept[[nodiscard]] sgc::Mat4f computeLightVP(const Light& light) const noexcept[[nodiscard]] const sgc::Mat4f& lightViewProjection() const noexceptvoid setLightViewProjection(const sgc::Mat4f& vp) noexcept[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] bool init(ID3D11Device* device)void shutdown()void beginShadowRender(ID3D11DeviceContext* ctx)void endShadowRender(ID3D11DeviceContext* ctx)[[nodiscard]] ID3D11ShaderResourceView* getShadowSRV() const noexcept[[nodiscard]] void* getShadowSRV() const noexceptenum ShadowFilterMode 3
HardPCFVSMstruct ShadowConfig 7
int cascadeCount = 4int mapSize = 2048ShadowFilterMode filterMode = ShadowFilterMode::PCFint pcfRadius = 1float bias = 0.005ffloat normalBias = 0.02ffloat vsmBlurRadius = 2.0fstruct CascadeInfo 9
sgc::Mat4f lightViewProjfloat splitNear = 0.0ffloat splitFar = 0.0ffloat bias = 0.005fstd::vector<float> depthBufferstd::vector<float> momentBufferMicrosoft::WRL::ComPtr<ID3D11Texture2D> shadowTextureMicrosoft::WRL::ComPtr<ID3D11DepthStencilView> dsvMicrosoft::WRL::ComPtr<ID3D11ShaderResourceView> srvclass CascadedShadowMap 14
CascadedShadowMap() noexcept = defaultvoid initialize(const ShadowConfig& cfg = {})[[nodiscard]] bool isInitialized() const noexcept[[nodiscard]] int cascadeCount() const noexcept[[nodiscard]] const ShadowConfig& config() const noexcept[[nodiscard]] const CascadeInfo& cascade(int index) constvoid updateCascades(const sgc::Mat4f& cameraView, const sgc::Mat4f& cameraProj, const sgc::Vec3f& lightDir, float cameraNear, float cameraFar)void beginShadowPass(int cascadeIndex)void recordMesh(const Mesh& mesh, const sgc::Mat4f& worldTransform)void endShadowPass()[[nodiscard]] float sampleShadow(const sgc::Vec3f& worldPos, float cameraDepth) const noexcept[[nodiscard]] const std::vector<float>& depthBuffer(int cascadeIndex) constconstexpr const char* SHADOWED_VS_3D = R"hlsl( cbuffer CameraVP : register(b0) { float4x4 cameraViewProj; }; cbuffer LightVP : register(b1) { float4x4 lightViewProj; }; struct VSInput { float3 position : POSITION; }; struct VSOutput { float4 clipPos : SV_POSITION; float4 shadowPos : SHADOWPOS; }; VSOutput VSMain(VSInput input) { VSOutput o; float4 worldPos = float4(input.position, 1.0); // 行列は転置済みで upload されるため HLSL では mul(mat, col_vec) = sgc * vec o.clipPos = mul(cameraViewProj, worldPos); o.shadowPos = mul(lightViewProj, worldPos); return o; } )hlsl"constexpr const char* SHADOWED_PS_3D = R"hlsl( Texture2D<float> shadowMap : register(t0); SamplerComparisonState shadowSampler : register(s0); struct PSInput { float4 clipPos : SV_POSITION; float4 shadowPos : SHADOWPOS; }; float4 PSMain(PSInput input) : SV_TARGET { // shadowPos.xyz / shadowPos.w で NDC→[0,1] テクスチャ座標へ変換 float3 shadowNdc = input.shadowPos.xyz / input.shadowPos.w; float2 shadowUv = shadowNdc.xy * float2(0.5, -0.5) + float2(0.5, 0.5); float receiverZ = shadowNdc.z - 0.005; // バイアス // テクスチャ範囲外はライト扱い float lit = 1.0; if (shadowUv.x >= 0.0 && shadowUv.x <= 1.0 && shadowUv.y >= 0.0 && shadowUv.y <= 1.0) { lit = shadowMap.SampleCmpLevelZero(shadowSampler, shadowUv, receiverZ); } // 視覚スポットチェック用に強コントラスト: シャドウ=黒、ライト=白 // (将来 Phong 拡張時に置き換える) return float4(lit, lit, lit, 1.0); } )hlsl"class ShapeRenderer 12
void drawCircle(const sgc::Vec2f& center, float radius, const sgc::Colorf& color, int segments = 32)void drawLine(const sgc::Vec2f& from, const sgc::Vec2f& to, const sgc::Colorf& color, float thickness = 1.0f)void drawTriangle(const sgc::Vec2f& p0, const sgc::Vec2f& p1, const sgc::Vec2f& p2, const sgc::Colorf& color)void drawPolygon(std::span<const sgc::Vec2f> points, const sgc::Colorf& color)void drawEllipse(const sgc::Vec2f& center, float radiusX, float radiusY, const sgc::Colorf& color, int segments = 32)void drawRing(const sgc::Vec2f& center, float outerR, float innerR, const sgc::Colorf& color, int segments = 32)void flush() noexcept[[nodiscard]] std::size_t vertexCount() const noexcept[[nodiscard]] std::size_t indexCount() const noexcept[[nodiscard]] int drawCallCount() const noexcept[[nodiscard]] const std::vector<Vertex2D>& vertices() const noexcept[[nodiscard]] const std::vector<std::uint32_t>& indices() const noexceptstruct Bone 4
std::string nameint parentIndex = -1sgc::Mat4f bindPosesgc::Mat4f localTransformstruct AnimationKeyframe 1
float time = 0.0fstruct BoneTrack 2
int boneIndex = -1std::vector<AnimationKeyframe> keyframesstruct AnimationClip 4
std::string namefloat duration = 0.0fbool looping = truestd::vector<BoneTrack> tracksstruct MorphTarget 3
std::string namestd::vector<sgc::Vec3f> positionDeltasfloat weight = 0.0fclass Skeleton 7
void addBone(const Bone& bone)[[nodiscard]] int boneCount() const noexcept[[nodiscard]] const Bone& bone(int index) constBone& bone(int index)[[nodiscard]] int findBone(const std::string& name) const[[nodiscard]] std::vector<sgc::Mat4f> computeWorldTransforms() const[[nodiscard]] std::vector<sgc::Mat4f> computeSkinningMatrices() constclass AnimationPlayer3D 6
void setSkeleton(Skeleton* skeleton) noexceptvoid play(const AnimationClip& clip)void stop()void update(float dt)[[nodiscard]] bool isPlaying() const noexcept[[nodiscard]] float currentTime() const noexceptclass Skybox 15
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>Skybox() = defaultexplicit Skybox(Cubemap cubemap) noexcept[[nodiscard]] const Cubemap& cubemap() const noexceptvoid setCubemap(Cubemap cubemap) noexcept[[nodiscard]] bool hasValidCubemap() const noexcept[[nodiscard]] bool isInitialized() const noexceptbool initializeDx11(gfx::Dx11Device* device)bool initializeDx11(ID3D11Device* d3d)void drawDx11(ID3D11DeviceContext* ctx, const Camera3D& camera) constvoid drawDx11(ID3D11DeviceContext* ctx, const sgc::Mat4f& viewMatrix, const sgc::Mat4f& projMatrix) constbool initializeDx11(void* )void drawDx11(void* , const Camera3D& ) constinline constexpr const char* SKYBOX_VS_HLSL = R"HLSL( cbuffer CbSkyTransform : register(b0) { float4x4 viewNoTranslation; float4x4 projection; }; struct VSIn { float3 pos : POSITION; }; struct VSOut { float4 svpos : SV_POSITION; float3 dir : TEXCOORD0; }; VSOut VSMain(VSIn i) { VSOut o; o.dir = i.pos; float4 wp = mul(float4(i.pos, 0.0), viewNoTranslation); wp = mul(wp, projection); // svpos.z = w -> NDC z = 1, i.e. furthest plane, so depth test // LESS_EQUAL with a cleared 1.0 depth buffer leaves the skybox // visible only where no scene geometry has drawn. o.svpos = wp.xyww; return o; } )HLSL"inline constexpr const char* SKYBOX_PS_HLSL = R"HLSL( TextureCube g_sky : register(t0); SamplerState g_samp : register(s0); struct VSOut { float4 svpos : SV_POSITION; float3 dir : TEXCOORD0; }; float4 PSMain(VSOut i) : SV_TARGET { return g_sky.Sample(g_samp, normalize(i.dir)); } )HLSL"struct Triangle3D 5
sgc::Vec3f asgc::Vec3f bsgc::Vec3f csgc::Colorf color[[nodiscard]] float avgZ() const noexceptclass SoftwareRenderer3D 17
SoftwareRenderer3D(float screenW, float screenH) noexceptvoid setCamera(const sgc::Vec3f& eye, const sgc::Vec3f& target, const sgc::Vec3f& up)void setProjection(float fovRad, float nearZ, float farZ)[[nodiscard]] sgc::Vec2f project(const sgc::Vec3f& worldPos) constvoid drawTriangle3D(Screen& screen, const sgc::Vec3f& a, const sgc::Vec3f& b, const sgc::Vec3f& c, const sgc::Colorf& color) constvoid drawBox(Screen& screen, const sgc::Vec3f& center, const sgc::Vec3f& size, const sgc::Colorf& color) constvoid drawAxes(Screen& screen, float length) constvoid drawFilledTriangle3D(Screen& screen, const sgc::Vec3f& a, const sgc::Vec3f& b, const sgc::Vec3f& c, const sgc::Colorf& color) constvoid drawFilledBox(Screen& screen, const sgc::Vec3f& center, const sgc::Vec3f& size, const sgc::Colorf& color) constvoid drawFilledPyramid(Screen& screen, const sgc::Vec3f& base, float baseSize, float height, const sgc::Colorf& color) constvoid drawSphere(Screen& screen, const sgc::Vec3f& center, float radius, int rings, int segments, const sgc::Colorf& color) constvoid drawFloorPlane(Screen& screen, const sgc::Vec3f& center, float extent, const sgc::Colorf& color) constvoid drawGrid(Screen& screen, float extent, int divisions, const sgc::Colorf& color) constvoid drawScene(Screen& screen, std::vector<Triangle3D>& tris) constvoid drawTexturedTriangle3D(Screen& screen, const sgc::Vec3f& a, const sgc::Vec3f& b, const sgc::Vec3f& c, const Texture& tex, float u0, float v0, float u1, float v1, float u2, float v2) constvoid drawTexturedQuad3D(Screen& screen, const sgc::Vec3f& v0, const sgc::Vec3f& v1, const sgc::Vec3f& v2, const sgc::Vec3f& v3, const Texture& tex) constvoid drawTexturedBox(Screen& screen, const sgc::Vec3f& center, const sgc::Vec3f& size, const Texture& tex) constclass OctreeNode 5
explicit OctreeNode(const AABB& bounds, int maxDepth = 6, int maxObjects = 8) noexceptvoid insert(const T& object, const AABB& objBounds)[[nodiscard]] std::vector<T> query(const AABB& region) constvoid clear() noexcept[[nodiscard]] std::size_t size() const noexceptclass GridPartition2D 6
GridPartition2D(float originX, float originY, float width, float height, float cellSize)void insert(const T& object, float x, float y)[[nodiscard]] std::vector<T> queryRadius(float cx, float cy, float radius) constvoid clear()[[nodiscard]] int cols() const noexcept[[nodiscard]] int rows() const noexceptenum SpritePivot : std::uint8_t 12
CenterBottomCenter[[nodiscard]] inline sgc::Mat4f cylindricalBillboardMatrix( const sgc::Vec3f& objectPos, const sgc::Vec3f& cameraPos) noexcept[[nodiscard]] inline float bounceOut(float t) noexcept[[nodiscard]] inline float elasticOut(float t) noexcept[[nodiscard]] inline float cubicOut(float t) noexcept[[nodiscard]] inline float backOut(float t, float overshoot = 1.70158f) noexcept[[nodiscard]] inline sgc::Mat4f popupRotationMatrix(float angle) noexcept[[nodiscard]] inline sgc::Mat4f sprite3DWorldMatrix( const sgc::Vec3f& position, const sgc::Vec3f& cameraPos, float popupAngle = 0.0f, float scale = 1.0f) noexceptconstexpr const char* SPRITE3D_VERTEX_SHADER = R"glsl(#version 300 es precision highp float; layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 aTexCoord; uniform mat4 uMVP; out vec2 vTexCoord; void main() { gl_Position = uMVP * vec4(aPos, 1.0); vTexCoord = aTexCoord; } )glsl"constexpr const char* SPRITE3D_FRAGMENT_SHADER = R"glsl(#version 300 es precision highp float; in vec2 vTexCoord; uniform sampler2D uTexture; uniform vec4 uTint; // スプライトのティント色(デフォルト白) uniform float uAlphaClip; // アルファクリッピング閾値(通常0.1〜0.5) out vec4 fragColor; void main() { vec4 texel = texture(uTexture, vTexCoord) * uTint; // アルファクリッピング: // 透過ピクセル(α < threshold)を完全に破棄し、 // Zバッファへの書き込みを防ぐ。 // これにより半透明の重なり順が正しく処理される。 if (texel.a < uAlphaClip) { discard; } fragColor = texel; } )glsl"constexpr const char* SPRITE3D_FLAT_FRAGMENT_SHADER = R"glsl(#version 300 es precision highp float; in vec2 vTexCoord; uniform vec4 uTint; uniform float uAlphaClip; out vec4 fragColor; void main() { if (uTint.a < uAlphaClip) { discard; } fragColor = uTint; } )glsl"struct Vertex3DSprite 2
sgc::Vec3f positionsgc::Vec2f texCoordstruct QuadMesh 3
std::array<Vertex3DSprite, 4> verticesstd::array<std::uint32_t, 6> indices[[nodiscard]] static QuadMesh create(float width, float height, SpritePivot pivot = SpritePivot::Center) noexceptstruct PopupAnimation 8
float duration = 0.4ffloat elapsed = 0.0fbool active = falsebool finished = falsevoid start(float dur = 0.4f) noexceptvoid update(float dt) noexcept[[nodiscard]] float progress() const noexcept[[nodiscard]] float rotationX() const noexceptstruct Sprite3DInstance 8
float width = 1.0ffloat height = 1.5ffloat scale = 1.0ffloat alphaClip = 0.1fSpritePivot pivot = SpritePivot::BottomCenterPopupAnimation popupbool billboard = true[[nodiscard]] sgc::Mat4f worldMatrix( const sgc::Vec3f& cameraPos, const sgc::Vec3f* cameraRight = nullptr, const sgc::Vec3f* cameraUp = nullptr) const noexceptclass Sprite3DRenderer 5
bool init()void submit(const Sprite3DInstance& instance, GLuint textureId = 0)void flush(const Camera3D& camera)[[nodiscard]] GLuint loadTexture(const std::string& path)[[nodiscard]] bool isInitialized() const noexceptenum AnimatorState 4
PlayingPausedStoppedFinishedenum AnimatorDirection 2
ForwardReversestruct SpriteFrame 3
float duration = 0.1ffloat offsetX = 0.0ffloat offsetY = 0.0fstruct SpriteAnimation 5
std::string namestd::vector<SpriteFrame> framesbool looping = falsebool pingPong = false[[nodiscard]] float totalDuration() const noexceptclass SpriteAnimationSet 6
void add(const SpriteAnimation& animation)void add(SpriteAnimation&& animation)[[nodiscard]] const SpriteAnimation* get(const std::string& name) const[[nodiscard]] std::vector<std::string> names() const[[nodiscard]] std::size_t count() const noexcept[[nodiscard]] bool contains(const std::string& name) constclass SpriteSheet 9
SpriteSheet() = default[[nodiscard]] static SpriteSheet create(const Texture& texture, int frameWidth, int frameHeight, int frameCount = 0)[[nodiscard]] static SpriteSheet createFromFrames(const Texture& texture, std::vector<SpriteFrame> frames)[[nodiscard]] SpriteFrame getFrame(int index) const[[nodiscard]] int frameCount() const noexcept[[nodiscard]] const Texture& texture() const noexcept[[nodiscard]] int frameWidth() const noexcept[[nodiscard]] int frameHeight() const noexcept[[nodiscard]] const std::vector<SpriteFrame>& frames() const noexceptclass SpriteAnimator 20
using AnimationCallback = std::function<void(const std::string& animationName)>;using FrameCallback = std::function<void(int frameIndex)>;void setAnimationSet(const SpriteAnimationSet& animationSet)void play(const std::string& animationName)void pause() noexceptvoid resume() noexceptvoid stop() noexceptvoid update(float dt)[[nodiscard]] SpriteFrame currentFrame() const[[nodiscard]] int currentFrameIndex() const noexcept[[nodiscard]] bool isPlaying() const noexcept[[nodiscard]] bool isFinished() const noexcept[[nodiscard]] AnimatorState state() const noexceptvoid setSpeed(float multiplier) noexcept[[nodiscard]] float speed() const noexceptvoid setDirection(AnimatorDirection direction) noexcept[[nodiscard]] AnimatorDirection direction() const noexcept[[nodiscard]] const std::string& currentAnimationName() const noexceptvoid onAnimationComplete(AnimationCallback callback)void onFrameChanged(FrameCallback callback)class SpriteAnimationBuilder 7
explicit SpriteAnimationBuilder(std::string name)SpriteAnimationBuilder& addFrame(const sgc::Recti& sourceRect, float duration, float offsetX = 0.0f, float offsetY = 0.0f)SpriteAnimationBuilder& addFrame(const SpriteFrame& frame)SpriteAnimationBuilder& addFramesFromSheet(const SpriteSheet& sheet, int startIndex, int count, float frameDuration)SpriteAnimationBuilder& setLooping(bool looping)SpriteAnimationBuilder& setPingPong(bool pingPong)[[nodiscard]] SpriteAnimation build() constclass SpriteAnimationCache 7
void store(const std::string& name, const SpriteAnimationSet& animationSet)void store(const std::string& name, SpriteAnimationSet&& animationSet)[[nodiscard]] const SpriteAnimationSet* retrieve(const std::string& name) const[[nodiscard]] bool contains(const std::string& name) constbool remove(const std::string& name)void clear()[[nodiscard]] std::size_t count() const noexceptclass SpriteBatch 14
void begin() noexceptvoid drawSprite(std::uint32_t textureId, const sgc::Rectf& destRect, const sgc::Rectf& srcRect, const sgc::Colorf& color, float rotation = 0.0f)void drawRect(const sgc::Rectf& rect, const sgc::Colorf& color)void drawRectGradient4(const sgc::Rectf& rect, const sgc::Colorf& tl, const sgc::Colorf& tr, const sgc::Colorf& br, const sgc::Colorf& bl)void drawQuadGradient4(const sgc::Vec2f corners[4], const sgc::Colorf& tl, const sgc::Colorf& tr, const sgc::Colorf& br, const sgc::Colorf& bl)void drawRectFrame(const sgc::Rectf& rect, const sgc::Colorf& color, float thickness = 1.0f)void end() noexcept[[nodiscard]] std::size_t vertexCount() const noexcept[[nodiscard]] std::size_t indexCount() const noexcept[[nodiscard]] int drawCallCount() const noexcept[[nodiscard]] const std::vector<Vertex2D>& vertices() const noexcept[[nodiscard]] const std::vector<std::uint32_t>& indices() const noexceptusing TextureId = std::uint32_t;inline constexpr TextureId kInvalidTextureId = 0class SpriteRenderer 15
SpriteRenderer() = default~SpriteRenderer()SpriteRenderer(const SpriteRenderer&) = deleteSpriteRenderer& operator=(const SpriteRenderer&) = deleteSpriteRenderer(SpriteRenderer&& other) noexceptSpriteRenderer& operator=(SpriteRenderer&& other) noexceptbool init(ID3D11Device* device, ID3D11DeviceContext* context) noexcept[[nodiscard]] TextureId loadTexture(const std::string& path)[[nodiscard]] TextureId createFromPixels(std::uint32_t width, std::uint32_t height, const void* pixels)void drawSprite(TextureId tex, const sgc::Rectf& dest, const sgc::Rectf& src = {}, float alpha = 1.0f, bool flipX = false)[[nodiscard]] ID3D11ShaderResourceView* getSRV(TextureId tex) const[[nodiscard]] std::uint32_t getWidth(TextureId tex) const noexcept[[nodiscard]] std::uint32_t getHeight(TextureId tex) const noexcept[[nodiscard]] std::size_t textureCount() const noexceptvoid release()struct PackedSprite 3
std::string namesgc::Rectf sourceRectsgc::Rectf destRectstruct PackResult 5
Texture atlasstd::vector<PackedSprite> spritesint atlasWidth = 0int atlasHeight = 0bool success = falseclass SpriteSheetPacker 8
SpriteSheetPacker() = defaultvoid addImage(std::string_view name, const Texture& texture)void addDirectory(std::string_view path, std::string_view extension)[[nodiscard]] PackResult pack(int maxWidth = 2048, int maxHeight = 2048, int padding = 1)[[nodiscard]] std::string exportJson() const[[nodiscard]] Texture exportTexture() constvoid clear()[[nodiscard]] std::size_t sourceCount() const noexceptstruct AsepriteParseResult 2
SpriteSheet sheetSpriteAnimationSet animationsclass SpriteSheetParser 2
[[nodiscard]] static SpriteAnimationSet parseAsepriteJson(const std::string& jsonString)[[nodiscard]] static AsepriteParseResult parseAsepriteJsonWithTexture( const std::string& jsonString, const Texture& texture)enum Edge 4
TopRightBottomLeftenum PathCommand : uint8_t 7
MoveToLineToQuadToCubicToCloseusing Fill = Gradient;`using ShapeData = std::variant< ShapeRect, ShapeCircle, ShapeEllipse, ShapeTriangle, ShapeLine, ShapeArc, ShapePie, ShapeRing, ShapePolygon, ShapePath>;`struct Color 7
static constexpr sgc::Colorf hex(uint32_t rgb)static constexpr sgc::Colorf rgb(uint8_t r, uint8_t g, uint8_t b)static constexpr sgc::Colorf rgba(uint8_t r, uint8_t g, uint8_t b, float a)static constexpr sgc::Colorf rgba(float r, float g, float b, float a)static constexpr sgc::Colorf white()static constexpr sgc::Colorf black()static constexpr sgc::Colorf transparent()struct ColorStop 1
float offset = 0struct Gradient 10
enum `Type` { Solid, Linear, Radial }Type type = Type::Solidfloat angle = 0float radius = 0.5fuint8_t stopCount = 0static Gradient solid(sgc::Colorf c)static Gradient linear(float angleDeg, std::initializer_list<ColorStop> stopList)static Gradient radial(sgc::Vec2f ctr, float rad, std::initializer_list<ColorStop> stopList)Gradient(sgc::Colorf c)Gradient() = defaultstruct Shadow 3
float x = 0float y = 0float blur = 0struct Corners 5
float tl = 0float tr = 0float br = 0float bl = 0static constexpr Corners all(float r)struct Stroke 1
float width = 0struct StyleTransform 1
float rotate = 0struct Style 3
float opacity = 1.0fstatic Style lerp(const Style& a, const Style& b, float t)static Style merge(const Style& base, const Style& over)struct ZigzagStyle 2
float toothSize = 12Edge edge = Edge::Bottomstruct ShapeRect 1
sgc::Rectf rectstruct ShapeCircle 2
sgc::Vec2f centerfloat radius = 0struct ShapeEllipse 3
sgc::Vec2f centerfloat rx = 0float ry = 0struct ShapeTriangle 3
sgc::Vec2f p0sgc::Vec2f p1sgc::Vec2f p2struct ShapeLine 3
sgc::Vec2f fromsgc::Vec2f tofloat thickness = 1struct ShapeArc 4
sgc::Vec2f centerfloat radius = 0float startAngle = 0float endAngle = 0struct ShapePie 4
sgc::Vec2f centerfloat radius = 0float startAngle = 0float endAngle = 0struct ShapeRing 3
sgc::Vec2f centerfloat outer = 0float inner = 0struct ShapePolygon 1
std::vector<sgc::Vec2f> pointsstruct PathPoint 1
PathCommand cmd = PathCommand::MoveTostruct ShapePath 6
std::vector<PathPoint> commandsShapePath& moveTo(float x, float y)ShapePath& lineTo(float x, float y)ShapePath& quadTo(float cx, float cy, float x, float y)ShapePath& cubicTo(float c1x, float c1y, float c2x, float c2y, float x, float y)ShapePath& close()struct StyledVertex2D 2
constexpr StyledVertex2D() noexcept = defaultconstexpr StyledVertex2D(const sgc::Vec2f& pos, const sgc::Vec2f& uv, const sgc::Colorf& col, const sgc::Vec4f& rect) noexceptclass StyledRectBatch 7
void begin() noexceptvoid addRect(const sgc::Rectf& rect, const Style& style, const Transform2D& worldXform = Transform2D::identity())void end() noexcept[[nodiscard]] const std::vector<StyledVertex2D>& vertices() const noexcept[[nodiscard]] const std::vector<std::uint32_t>& indices() const noexcept[[nodiscard]] const StyleConstants& currentStyle() const noexcept[[nodiscard]] bool hasData() const noexceptclass StyledCircleBatch 8
void begin() noexceptvoid addCircle(const sgc::Vec2f& center, float radius, const Style& style, const Transform2D& worldXform = Transform2D::identity())void addEllipse(const sgc::Vec2f& center, float rx, float ry, const Style& style, const Transform2D& worldXform = Transform2D::identity())void end() noexcept[[nodiscard]] const std::vector<StyledVertex2D>& vertices() const noexcept[[nodiscard]] const std::vector<std::uint32_t>& indices() const noexcept[[nodiscard]] const StyleConstants& currentStyle() const noexcept[[nodiscard]] bool hasData() const noexceptclass StyledShapeRenderer 14
void begin()void end()void drawCircle(const ShapeCircle& shape, const Style& style)void drawEllipse(const ShapeEllipse& shape, const Style& style)void drawTriangle(const ShapeTriangle& shape, const Style& style)void drawLine(const ShapeLine& shape, const Style& style)void drawArc(const ShapeArc& shape, const Style& style)void drawPie(const ShapePie& shape, const Style& style)void drawRing(const ShapeRing& shape, const Style& style)void drawPolygon(const ShapePolygon& shape, const Style& style)void drawPath(const ShapePath& shape, const Style& style)[[nodiscard]] const std::vector<Vertex2D>& vertices() const[[nodiscard]] const std::vector<uint32_t>& indices() const[[nodiscard]] bool hasData() constenum SSSProfile : int 8
Skin = 0MarbleWaxMilk`constexpr std::string_view SSS_BLUR_PS = R"hlsl(Texture2D depthTexture : register(t1)SamplerState linearClampSampler : register(s0)cbuffer SSSParams : register(b0)struct PSInput 2
float4 position : SV_Positionfloat2 uv : TEXCOORD0struct SSSConfig 4
float sssWidth = 0.012ffloat maxDepthDiff = 0.01ffloat correction = 80.0fbool enabled = trueclass SubsurfaceScatterEffect 23
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>SubsurfaceScatterEffect() = default~SubsurfaceScatterEffect() = defaultSubsurfaceScatterEffect(const SubsurfaceScatterEffect&) = deleteSubsurfaceScatterEffect& operator=(const SubsurfaceScatterEffect&) = deleteSubsurfaceScatterEffect(SubsurfaceScatterEffect&&) noexcept = defaultSubsurfaceScatterEffect& operator=(SubsurfaceScatterEffect&&) noexcept = defaultbool init(ID3D11Device* device, int width, int height)void apply(ID3D11DeviceContext* context, ID3D11ShaderResourceView* sceneSRV, ID3D11ShaderResourceView* depthSRV, ID3D11RenderTargetView* outputRTV) constvoid setProfile(SSSProfile profile) noexcept[[nodiscard]] SSSConfig& config() noexcept[[nodiscard]] const SSSConfig& config() const noexcept[[nodiscard]] ID3D11ShaderResourceView* pingRTSRV() const noexcept`constexpr std::string_view TAA_RESOLVE_PS = R"hlsl(`constexpr std::string_view TAA_COPY_PS = R"hlsl(Texture2D historyTexture : register(t1)Texture2D depthTexture : register(t2)SamplerState linearClampSampler : register(s0)SamplerState pointClampSampler : register(s1)cbuffer TAAParams : register(b0)// ── 近傍のAABBを計算する ───────────────────────── void computeNeighborhoodAABB( float2 uv, float2 texel, out float3 aabbMin, out float3 aabbMax)// ── ヒストリー色をAABBにクランプする ────────────────── float3 clipToAABB(float3 color, float3 aabbMin, float3 aabbMax)SamplerState pointClampSampler : register(s0)struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct TAAConfig 2
float blendFactor = 0.1ffloat motionScale = 1.0fclass TAAEffect 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>void init(ID3D11Device* device, std::uint32_t screenW, std::uint32_t screenH)void setDepthSRV( ID3D11ShaderResourceView* depthSRV) noexceptvoid setConfig(const TAAConfig& cfg) noexcept[[nodiscard]] const TAAConfig& config() const noexcept[[nodiscard]] std::array<float, 2> currentJitter() const noexceptvoid advanceFrame() noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH)class Texture 9
Texture() = defaultTexture(int width, int height, const std::vector<std::uint8_t>& pixels)[[nodiscard]] static Texture solid(int w, int h, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255)[[nodiscard]] static Texture checker(int w, int h, int tileSize, std::uint8_t r1, std::uint8_t g1, std::uint8_t b1, std::uint8_t r2, std::uint8_t g2, std::uint8_t b2)[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexcept[[nodiscard]] const std::vector<std::uint8_t>& pixels() const noexcept[[nodiscard]] bool valid() const noexcept[[nodiscard]] std::uint32_t pixelAt(int x, int y) conststruct AtlasRegion 11
int x = 0int y = 0int width = 0int height = 0int atlasWidth = 0int atlasHeight = 0[[nodiscard]] float u0() const noexcept[[nodiscard]] float v0() const noexcept[[nodiscard]] float u1() const noexcept[[nodiscard]] float v1() const noexcept[[nodiscard]] bool valid() const noexceptclass TextureAtlas 10
explicit TextureAtlas(int atlasSize = 2048)AtlasRegion add(const std::string& name, const Texture& tex)[[nodiscard]] AtlasRegion getRegion(const std::string& name) const[[nodiscard]] const Texture& texture() const noexcept[[nodiscard]] int regionCount() const noexcept[[nodiscard]] int atlasSize() const noexceptconstexpr std::uint32_t FLIPPED_HORIZONTALLY = 0x80000000uconstexpr std::uint32_t FLIPPED_VERTICALLY = 0x40000000uconstexpr std::uint32_t FLIPPED_DIAGONALLY = 0x20000000u`constexpr std::uint32_t ALL_FLAGS = FLIPPED_HORIZONTALLY | FLIPPED_VERTICALLY | FLIPPED_DIAGONALLY`struct TiledObject 9
int id = 0std::string namestd::string typefloat x = 0.0ffloat y = 0.0ffloat width = 0.0ffloat height = 0.0fbool visible = true[[nodiscard]] sgc::Rectf toRect() const noexceptstruct TiledObjectLayer 3
std::string namestd::vector<TiledObject> objectsbool visible = truestruct TiledMapResult 5
Tilemap tilemapstd::vector<TiledObjectLayer> objectLayers[[nodiscard]] const TiledObjectLayer* findObjectLayer( const std::string& name) const[[nodiscard]] std::vector<sgc::Rectf> collectCollisionRects() const[[nodiscard]] std::vector<TiledObject> findObjectsByType( const std::string& typeName) constclass TiledMapLoader 1
[[nodiscard]] static std::optional<TiledMapResult> loadTiledMap( const std::string& jsonString)enum TileFlip : std::uint8_t 4
None = 0Horizontal = 1 << 0Vertical = 1 << 1Diagonal = 1 << 2enum AutoTileNeighbor : std::uint8_t 14
None = 0Top = 1 << 0TopRight = 1 << 1Right = 1 << 2BottomRight= 1 << 3Bottom = 1 << 4BottomLeft = 1 << 5Left = 1 << 6TopLeft = 1 << 7[[nodiscard]] constexpr TileFlip operator|(TileFlip a, TileFlip b) noexcept[[nodiscard]] constexpr TileFlip operator&(TileFlip a, TileFlip b) noexcept[[nodiscard]] constexpr bool hasFlag(TileFlip flags, TileFlip test) noexcept[[nodiscard]] constexpr AutoTileNeighbor operator|(AutoTileNeighbor a, AutoTileNeighbor b) noexcept[[nodiscard]] constexpr AutoTileNeighbor operator&(AutoTileNeighbor a, AutoTileNeighbor b) noexceptstruct TilesetConfig 9
Texture textureint tileWidth = 16int tileHeight = 16int columns = 1int spacing = 0int margin = 0int firstGid = 1[[nodiscard]] sgc::Rectf getTileRect(int tileId) const noexcept[[nodiscard]] sgc::Rectf getTileUV(int tileId) const noexceptstruct AnimatedTile 3
std::vector<int> tileIdsfloat frameDuration = 0.2f[[nodiscard]] int currentTileId(float elapsedTime) const noexceptstruct AutoTileRules 4
std::unordered_map<std::uint8_t, int> maskToTileIdint defaultTileId = 0void addRule(std::uint8_t mask, int tileId)[[nodiscard]] int resolve(std::uint8_t mask) conststruct TilemapLayer 15
std::string nameint width = 0int height = 0std::vector<int> databool visible = truefloat opacity = 1.0ffloat offsetX = 0.0ffloat offsetY = 0.0ffloat parallaxX = 1.0ffloat parallaxY = 1.0f[[nodiscard]] int getTile(int tileX, int tileY) const noexceptvoid setTile(int tileX, int tileY, int tileId) noexcept[[nodiscard]] TileFlip getFlip(int tileX, int tileY) const noexceptvoid setFlip(int tileX, int tileY, TileFlip flip) noexceptvoid resize(int w, int h)struct Tilemap 5
std::vector<TilemapLayer> layersstd::vector<TilesetConfig> tilesetsint mapWidth = 0int mapHeight = 0[[nodiscard]] const TilesetConfig* findTileset(int gid) const noexceptclass TilemapCollision 8
TilemapCollision(const TilemapLayer& collisionLayer, int tileWidth, int tileHeight, std::vector<int> solidTileIds = {})[[nodiscard]] bool isSolid(int tileX, int tileY) const noexcept[[nodiscard]] int getTileAt(float worldX, float worldY) const noexcept[[nodiscard]] sgc::Rectf getCollisionRect(int tileX, int tileY) const noexcept[[nodiscard]] bool overlapsAnySolid(const sgc::Rectf& rect) const noexcept[[nodiscard]] const TilemapLayer& layer() const noexcept[[nodiscard]] int tileWidth() const noexcept[[nodiscard]] int tileHeight() const noexceptclass TilemapRenderer 21
TilemapRenderer() noexcept = defaultvoid setAnimatedTile(int baseTileId, AnimatedTile anim)void removeAnimatedTile(int baseTileId)void updateAnimation(float dt) noexceptvoid resetAnimation() noexceptvoid setAutoTileRules(int terrainTileId, AutoTileRules rules)void applyAutoTile(TilemapLayer& layer, int terrainTileId) constvoid drawLayer(Screen& screen, const TilemapLayer& layer, const TilesetConfig& tileset, float cameraX, float cameraY, float viewportW, float viewportH) constvoid drawTilemap(Screen& screen, const Tilemap& tilemap, float cameraX, float cameraY) constvoid drawTilemap(Screen& screen, const Tilemap& tilemap, float cameraX, float cameraY, float viewportW, float viewportH) const[[nodiscard]] int lastDrawnTileCount() const noexcept[[nodiscard]] float elapsedTime() const noexceptconstexpr const char* kTOON_VS = R"hlsl( cbuffer CbToon : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; float3 CameraPos; float _pad0; float3 LightDir; float _pad1; // lighting params (pixel shader only) float4 BandThresholds[2]; // 8 floats packed into 2 float4 float4 BandBrightness[2]; int BandCount; float AmbientStrength; float SpecularSize; float SpecularSmoothness; float4 SpecularColor; float4 ShadowColor; float RimEnabled; float RimWidth; float RimSmoothness; float _pad2; float4 RimColor; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; float3 ViewDir : TEXCOORD3; }; VSOutput VSMain(VSInput input) { VSOutput output; float4 worldPos = mul(float4(input.Position, 1.0), World); output.WorldPos = worldPos.xyz; output.WorldNorm = normalize(mul(input.Normal, (float3x3)World)); float4 viewPos = mul(worldPos, View); output.Position = mul(viewPos, Projection); output.TexCoord = input.TexCoord; output.Color = input.Color; output.ViewDir = normalize(CameraPos - worldPos.xyz); return output; } )hlsl"constexpr const char* kTOON_PS = R"hlsl( cbuffer CbToon : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; float3 CameraPos; float _pad0; float3 LightDir; float _pad1; float4 BandThresholds[2]; // [0].xyzw = bands 0-3, [1].xyzw = bands 4-7 float4 BandBrightness[2]; int BandCount; float AmbientStrength; float SpecularSize; float SpecularSmoothness; float4 SpecularColor; float4 ShadowColor; float RimEnabled; float RimWidth; float RimSmoothness; float _pad2; float4 RimColor; }; Texture2D albedoTex : register(t0); SamplerState sampLinear : register(s0); struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; float3 ViewDir : TEXCOORD3; }; float getBandThreshold(int idx) { return (idx < 4) ? BandThresholds[0][idx] : BandThresholds[1][idx - 4]; } float getBandBrightness(int idx) { return (idx < 4) ? BandBrightness[0][idx] : BandBrightness[1][idx - 4]; } float4 PSMain(PSInput input) : SV_TARGET { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(input.ViewDir); float3 H = normalize(L + V); float NdotL = dot(N, L); float NdotH = max(dot(N, H), 0.0); float NdotV = max(dot(N, V), 0.0); // --- N-band quantized diffuse --- float brightness = getBandBrightness(BandCount - 1); // darkest band default for (int i = 0; i < BandCount; ++i) { float threshold = getBandThreshold(i); float edge = smoothstep(threshold - 0.02, threshold + 0.02, NdotL); brightness = lerp(brightness, getBandBrightness(i), edge); } // shadow color tinting: blend toward shadow color in dark areas float shadowFactor = 1.0 - brightness; float3 tintedLight = lerp(float3(1, 1, 1), ShadowColor.rgb, shadowFactor); // --- Specular (step-based) --- float specMask = smoothstep(SpecularSize - SpecularSmoothness, SpecularSize + SpecularSmoothness, NdotH); // Only show specular on lit side float litSide = step(0.01, NdotL); float3 specContrib = SpecularColor.rgb * SpecularColor.a * specMask * litSide; // --- Rim light (fresnel) --- float3 rimContrib = float3(0, 0, 0); if (RimEnabled > 0.5) { float rim = 1.0 - NdotV; float rimMask = smoothstep(RimWidth - RimSmoothness, RimWidth + RimSmoothness, rim); // Rim visible on lit side only for artistic look float rimLit = smoothstep(-0.1, 0.3, NdotL); rimContrib = RimColor.rgb * RimColor.a * rimMask * rimLit; } // --- Combine --- float4 albedo = albedoTex.Sample(sampLinear, input.TexCoord) * input.Color; float3 ambient = albedo.rgb * AmbientStrength; float3 diffuse = albedo.rgb * brightness * tintedLight; float3 finalColor = ambient + diffuse + specContrib + rimContrib; return float4(finalColor, albedo.a); } )hlsl"constexpr const char* kOUTLINE_HULL_VS = R"hlsl( cbuffer CbOutline : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; float3 CameraPos; float OutlineWidth; float4 OutlineColor; float ScaleWithDistance; float3 _pad; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; }; VSOutput VSMain(VSInput input) { VSOutput output; float3 worldPos = mul(float4(input.Position, 1.0), World).xyz; float3 worldNormal = normalize(mul(input.Normal, (float3x3)World)); // Distance-based width scaling float dist = length(CameraPos - worldPos); float scale = (ScaleWithDistance > 0.5) ? saturate(dist * 0.1) : 1.0; // Expand along normal in world space float3 expanded = worldPos + worldNormal * OutlineWidth * scale; float4 viewPos = mul(float4(expanded, 1.0), View); output.Position = mul(viewPos, Projection); return output; } )hlsl"constexpr const char* kOUTLINE_PS = R"hlsl( cbuffer CbOutline : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; float3 CameraPos; float OutlineWidth; float4 OutlineColor; float ScaleWithDistance; float3 _pad; }; struct PSInput { float4 Position : SV_POSITION; }; float4 PSMain(PSInput input) : SV_TARGET { return OutlineColor; } )hlsl"constexpr const char* kOUTLINE_SCREEN_PS = R"hlsl( Texture2D sceneTexture : register(t0); Texture2D depthTexture : register(t1); Texture2D normalTexture : register(t2); SamplerState sampPoint : register(s0); cbuffer CbScreenOutline : register(b0) { float2 TexelSize; // 1.0/screenW, 1.0/screenH float DepthThreshold; float NormalThreshold; float4 OutlineColor; float LineWidth; int Mode; // 0=depth, 1=normal, 2=both float2 _pad; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; // Roberts Cross edge detection (sharper than Sobel for thin lines) float robertsCrossDepth(float2 uv) { float2 offset = TexelSize * LineWidth; float d00 = depthTexture.Sample(sampPoint, uv).r; float d11 = depthTexture.Sample(sampPoint, uv + offset).r; float d10 = depthTexture.Sample(sampPoint, uv + float2(offset.x, 0)).r; float d01 = depthTexture.Sample(sampPoint, uv + float2(0, offset.y)).r; float g1 = d00 - d11; float g2 = d10 - d01; return sqrt(g1 * g1 + g2 * g2); } float robertsCrossNormal(float2 uv) { float2 offset = TexelSize * LineWidth; float3 n00 = normalTexture.Sample(sampPoint, uv).rgb; float3 n11 = normalTexture.Sample(sampPoint, uv + offset).rgb; float3 n10 = normalTexture.Sample(sampPoint, uv + float2(offset.x, 0)).rgb; float3 n01 = normalTexture.Sample(sampPoint, uv + float2(0, offset.y)).rgb; float3 g1 = n00 - n11; float3 g2 = n10 - n01; return sqrt(dot(g1, g1) + dot(g2, g2)); } float4 PSMain(PSInput input) : SV_TARGET { float4 scene = sceneTexture.Sample(sampPoint, input.TexCoord); float edge = 0.0; if (Mode == 0 || Mode == 2) // depth { float depthEdge = robertsCrossDepth(input.TexCoord); edge = max(edge, step(DepthThreshold, depthEdge)); } if (Mode == 1 || Mode == 2) // normal { float normalEdge = robertsCrossNormal(input.TexCoord); edge = max(edge, step(NormalThreshold, normalEdge)); } float3 result = lerp(scene.rgb, OutlineColor.rgb, edge * OutlineColor.a); return float4(result, scene.a); } )hlsl"constexpr const char* kFULLSCREEN_VS = R"hlsl( struct VSOutput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; VSOutput VSMain(uint vertexId : SV_VertexID) { VSOutput output; output.TexCoord = float2((vertexId << 1) & 2, vertexId & 2); output.Position = float4( output.TexCoord.x * 2.0 - 1.0, -(output.TexCoord.y * 2.0 - 1.0), 0.0, 1.0); return output; } )hlsl"struct alignas(16) CbToonstruct alignas(16) CbOutlinestruct alignas(16) CbScreenOutlinestruct ToonLightingConfig 7
int bandCount = 3float specularSize = 0.9ffloat specularSmoothness = 0.05fbool rimEnabled = truefloat rimWidth = 0.3ffloat rimSmoothness = 0.1ffloat ambientStrength = 0.1fstruct ToonOutlineConfig 6
enum `Method : uint8_t` { InvertedHull, ScreenSpaceDepth, ScreenSpaceNormal, ScreenSpaceDepthNormal, None }Method method = Method::InvertedHullfloat width = 0.02ffloat depthThreshold = 0.1ffloat normalThreshold = 0.4fbool scaleWithDistance = truestruct ToonConfig 2
ToonLightingConfig lightingToonOutlineConfig outlineclass ToonPipeline 27
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>ToonPipeline() noexcept = defaultbool init(ID3D11Device* device)void shutdown()void setConfig(const ToonConfig& cfg)[[nodiscard]] const ToonConfig& config() const noexcept[[nodiscard]] bool isInitialized() const noexceptvoid beginToonPass(ID3D11DeviceContext* ctx)void drawMesh(ID3D11DeviceContext* ctx, ID3D11Buffer* vb, ID3D11Buffer* ib, int indexCount, const float* worldMatrix, const float* viewMatrix, const float* projMatrix, const float* lightDir, const float* cameraPos)void endToonPass(ID3D11DeviceContext* ctx)void beginOutlinePass(ID3D11DeviceContext* ctx)void drawOutline(ID3D11DeviceContext* ctx, ID3D11Buffer* vb, ID3D11Buffer* ib, int indexCount, const float* worldMatrix, const float* viewMatrix, const float* projMatrix, const float* cameraPos)void endOutlinePass(ID3D11DeviceContext* ctx)void applyScreenSpaceOutline(ID3D11DeviceContext* ctx, ID3D11ShaderResourceView* sceneSRV, ID3D11ShaderResourceView* depthSRV, ID3D11ShaderResourceView* normalSRV, ID3D11RenderTargetView* outputRTV, int screenW, int screenH)bool initDemo(ID3D11Device* device)void renderDemo(ID3D11DeviceContext* ctx, ID3D11RenderTargetView* rtv, ID3D11DepthStencilView* dsv, int screenW, int screenH, float timeSeconds)constexpr const char* TOON_VS_3D = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; float4 worldPos = mul(World, float4(input.Position, 1.0)); output.WorldPos = worldPos.xyz; output.WorldNorm = normalize(mul((float3x3)World, input.Normal)); float4 viewPos = mul(View, worldPos); output.Position = mul(Projection, viewPos); output.TexCoord = input.TexCoord; output.Color = input.Color; return output; } )hlsl"constexpr const char* TOON_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; PSOutput PSMain(PSInput input) { PSOutput output; float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); // アンビエント float3 ambient = AmbientColor * MaterialDiffuse.rgb; // ディフューズ — NdotLを量子化 float rawNdotL = max(dot(N, L), 0.0); float toon = (rawNdotL > 0.5) ? 1.0 : (rawNdotL > 0.15) ? 0.6 : 0.3; float3 diffuse = LightColor * MaterialDiffuse.rgb * toon; // スペキュラー float3 H = normalize(L + V); float NdotH = max(dot(N, H), 0.0); float specFactor = pow(NdotH, MaterialShininess) * 0.3; float3 specular = LightColor * MaterialSpecular.rgb * specFactor; float3 finalColor = ambient + diffuse + specular; float alpha = MaterialDiffuse.a * input.Color.a; output.Color = float4(finalColor * input.Color.rgb, alpha); // 法線をRT1に出力([0,1]にパック + NdotVをアルファに) float NdotV = max(dot(N, V), 0.0); output.Normal = float4(N * 0.5 + 0.5, NdotV); return output; } )hlsl"constexpr const char* OUTLINE_VS_3D = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; float3 expandedPos = input.Position + input.Normal * 0.012; float4 worldPos = mul(World, float4(expandedPos, 1.0)); float4 viewPos = mul(View, worldPos); output.Position = mul(Projection, viewPos); // アウトラインをメインパスの奥に押し出す(深度バッファで隠れる) output.Position.z += 0.002 * output.Position.w; output.Color = float4(0.1, 0.08, 0.06, 1.0); return output; } )hlsl"constexpr const char* OUTLINE_PS_3D = R"hlsl( struct PSInput { float4 Position : SV_POSITION; float4 Color : COLOR0; }; float4 PSMain(PSInput input) : SV_TARGET { return input.Color; } )hlsl"constexpr const char* OUTLINE_POST_VS = R"hlsl( struct VSOutput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; VSOutput VSMain(uint vertexID : SV_VertexID) { VSOutput output; // フルスクリーン三角形(3頂点、頂点バッファ不要) output.TexCoord = float2((vertexID << 1) & 2, vertexID & 2); output.Position = float4(output.TexCoord * float2(2, -2) + float2(-1, 1), 0, 1); return output; } )hlsl"constexpr const char* OUTLINE_POST_PS = R"hlsl( // MSAA 4x (ENG-105 v2) — sample 0 のみ参照 Texture2DMS<float, 4> DepthTexture : register(t0); Texture2DMS<float4, 4> NormalTexture : register(t1); cbuffer CbOutline : register(b0) { float2 TexelSize; // 1.0 / viewport size float OutlineWidth; // アウトライン太さ(ピクセル) float Threshold; // エッジ検出閾値 }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float sampleDepth(int2 pos) { return DepthTexture.Load(pos, 0); } float linearizeDepth(float d, float near, float far) { return near * far / (far - d * (far - near)); } float4 PSMain(PSInput input) : SV_TARGET { int2 pos = int2(input.Position.xy); int w = max(int(OutlineWidth), 1); float nearZ = 0.1; float farZ = 100.0; // 中心基準の深度差分(二重線防止)+ NdotVフィルタ float dC = linearizeDepth(sampleDepth(pos), nearZ, farZ); float dL = linearizeDepth(sampleDepth(pos + int2(-w, 0)), nearZ, farZ); float dR = linearizeDepth(sampleDepth(pos + int2( w, 0)), nearZ, farZ); float dU = linearizeDepth(sampleDepth(pos + int2( 0,-w)), nearZ, farZ); float dD = linearizeDepth(sampleDepth(pos + int2( 0, w)), nearZ, farZ); float edge = max(max(abs(dC - dL), abs(dC - dR)), max(abs(dC - dU), abs(dC - dD))); float4 normalData = NormalTexture.Load(pos, 0); float NdotV = normalData.a; if (edge > Threshold && NdotV > 0.15) { return float4(0.1, 0.08, 0.06, 1.0); } discard; return float4(0, 0, 0, 0); } )hlsl"constexpr const char* OUTLINE_POST_PS_LAPLACIAN = R"hlsl( // MSAA 4x (ENG-105 v2) — sample 0 のみ参照 Texture2DMS<float, 4> DepthTexture : register(t0); Texture2DMS<float4, 4> NormalTexture : register(t1); cbuffer CbOutline : register(b0) { float2 TexelSize; float OutlineWidth; float Threshold; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float3 unpackNormal(float4 data) { return data.rgb * 2.0 - 1.0; } float4 PSMain(PSInput input) : SV_TARGET { int2 pos = int2(input.Position.xy); int w = max(int(OutlineWidth), 1); // 中心と4近傍の法線を取得 float3 nC = unpackNormal(NormalTexture.Load(pos, 0)); float3 nL = unpackNormal(NormalTexture.Load(pos + int2(-w, 0), 0)); float3 nR = unpackNormal(NormalTexture.Load(pos + int2( w, 0), 0)); float3 nU = unpackNormal(NormalTexture.Load(pos + int2( 0,-w), 0)); float3 nD = unpackNormal(NormalTexture.Load(pos + int2( 0, w), 0)); // 法線の差異: 1 - dot(n1, n2) で角度差を測定 float edge = max(max(1.0 - dot(nC, nL), 1.0 - dot(nC, nR)), max(1.0 - dot(nC, nU), 1.0 - dot(nC, nD))); float NdotV = NormalTexture.Load(pos, 0).a; if (edge > Threshold && NdotV > 0.15) { return float4(0.1, 0.08, 0.06, 1.0); } discard; return float4(0, 0, 0, 0); } )hlsl"constexpr const char* OUTLINE_POST_PS_DEPTH_NDOTV = R"hlsl( // MSAA 4x (ENG-105 v2) — sample 0 のみ参照 Texture2DMS<float, 4> DepthTexture : register(t0); Texture2DMS<float4, 4> NormalTexture : register(t1); cbuffer CbOutline : register(b0) { float2 TexelSize; float OutlineWidth; float Threshold; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float sampleDepth(int2 pos) { return DepthTexture.Load(pos, 0); } float linearizeDepth(float d, float nearZ, float farZ) { return nearZ * farZ / (farZ - d * (farZ - nearZ)); } float4 PSMain(PSInput input) : SV_TARGET { int2 pos = int2(input.Position.xy); int w = max(int(OutlineWidth), 1); float nearZ = 0.1; float farZ = 100.0; // 中心基準の深度差分(二重線防止) float dC = linearizeDepth(sampleDepth(pos), nearZ, farZ); float dL = linearizeDepth(sampleDepth(pos + int2(-w, 0)), nearZ, farZ); float dR = linearizeDepth(sampleDepth(pos + int2( w, 0)), nearZ, farZ); float dU = linearizeDepth(sampleDepth(pos + int2( 0,-w)), nearZ, farZ); float dD = linearizeDepth(sampleDepth(pos + int2( 0, w)), nearZ, farZ); float edge = max(max(abs(dC - dL), abs(dC - dR)), max(abs(dC - dU), abs(dC - dD))); // NdotVフィルタ: 凹面内部(NdotV低)を抑制 float4 normalData = NormalTexture.Load(pos, 0); float NdotV = normalData.a; float ndotVMask = smoothstep(0.1, 0.35, NdotV); if (edge * ndotVMask > Threshold) { return float4(0.1, 0.08, 0.06, 1.0); } discard; return float4(0, 0, 0, 0); } )hlsl"constexpr const char* OUTLINE_POST_PS_COLOR_EDGE = R"hlsl( // MSAA 4x (ENG-105 v2) — sample 0 のみ参照 Texture2DMS<float, 4> DepthTexture : register(t0); Texture2DMS<float4, 4> NormalTexture : register(t1); cbuffer CbOutline : register(b0) { float2 TexelSize; float OutlineWidth; float Threshold; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float sampleDepth(int2 pos) { return DepthTexture.Load(pos, 0); } float linearizeDepth(float d, float nearZ, float farZ) { return nearZ * farZ / (farZ - d * (farZ - nearZ)); } float3 unpackNormal(float4 data) { return data.rgb * 2.0 - 1.0; } float4 PSMain(PSInput input) : SV_TARGET { int2 pos = int2(input.Position.xy); int w = max(int(OutlineWidth), 1); float nearZ = 0.1; float farZ = 100.0; // 中心基準の深度差分 float dC = linearizeDepth(sampleDepth(pos), nearZ, farZ); float dL = linearizeDepth(sampleDepth(pos + int2(-w, 0)), nearZ, farZ); float dR = linearizeDepth(sampleDepth(pos + int2( w, 0)), nearZ, farZ); float dU = linearizeDepth(sampleDepth(pos + int2( 0,-w)), nearZ, farZ); float dD = linearizeDepth(sampleDepth(pos + int2( 0, w)), nearZ, farZ); float depthEdge = max(max(abs(dC - dL), abs(dC - dR)), max(abs(dC - dU), abs(dC - dD))); // 法線差分 float3 nC = unpackNormal(NormalTexture.Load(pos, 0)); float3 nL = unpackNormal(NormalTexture.Load(pos + int2(-w, 0), 0)); float3 nR = unpackNormal(NormalTexture.Load(pos + int2( w, 0), 0)); float3 nU = unpackNormal(NormalTexture.Load(pos + int2( 0,-w), 0)); float3 nD = unpackNormal(NormalTexture.Load(pos + int2( 0, w), 0)); float normalEdge = max(max(1.0 - dot(nC, nL), 1.0 - dot(nC, nR)), max(1.0 - dot(nC, nU), 1.0 - dot(nC, nD))); float NdotV = NormalTexture.Load(pos, 0).a; // 深度エッジ OR (法線エッジ AND 深度エッジ弱) bool hasEdge = depthEdge > Threshold || (normalEdge > Threshold * 0.8 && depthEdge > Threshold * 0.2); if (hasEdge && NdotV > 0.15) { return float4(0.1, 0.08, 0.06, 1.0); } discard; return float4(0, 0, 0, 0); } )hlsl"constexpr const char* OUTLINE_POST_PS_DEPTH_COLOR = R"hlsl( // MSAA 4x (ENG-105 v2) — sample 0 のみ参照 Texture2DMS<float, 4> DepthTexture : register(t0); Texture2DMS<float4, 4> NormalTexture : register(t1); Texture2D<float4> ColorTexture : register(t2); cbuffer CbOutline : register(b0) { float2 TexelSize; float OutlineWidth; float Threshold; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float sampleDepth(int2 pos) { return DepthTexture.Load(pos, 0); } float linearizeDepth(float d, float nearZ, float farZ) { return nearZ * farZ / (farZ - d * (farZ - nearZ)); } float luminance(float3 c) { return dot(c, float3(0.299, 0.587, 0.114)); } float4 PSMain(PSInput input) : SV_TARGET { int2 pos = int2(input.Position.xy); float nearZ = 0.1; float farZ = 100.0; int w = max(int(OutlineWidth), 1); // 中心基準の4方向深度差分(中心と比較するので二重線にならない) float dC = linearizeDepth(sampleDepth(pos), nearZ, farZ); float dL = linearizeDepth(sampleDepth(pos + int2(-w, 0)), nearZ, farZ); float dR = linearizeDepth(sampleDepth(pos + int2( w, 0)), nearZ, farZ); float dU = linearizeDepth(sampleDepth(pos + int2( 0,-w)), nearZ, farZ); float dD = linearizeDepth(sampleDepth(pos + int2( 0, w)), nearZ, farZ); float depthEdge = max(max(abs(dC - dL), abs(dC - dR)), max(abs(dC - dU), abs(dC - dD))); // 中心基準の色差分 float lC = luminance(ColorTexture.Load(int3(pos, 0)).rgb); float lL = luminance(ColorTexture.Load(int3(pos + int2(-w, 0), 0)).rgb); float lR = luminance(ColorTexture.Load(int3(pos + int2( w, 0), 0)).rgb); float lU = luminance(ColorTexture.Load(int3(pos + int2( 0,-w), 0)).rgb); float lD = luminance(ColorTexture.Load(int3(pos + int2( 0, w), 0)).rgb); float colorEdge = max(max(abs(lC - lL), abs(lC - lR)), max(abs(lC - lU), abs(lC - lD))); // NdotVフィルタ float4 normalData = NormalTexture.Load(pos, 0); float NdotV = normalData.a; // 深度エッジと色エッジの複合判定 float depthThresh = Threshold; float colorThresh = Threshold * 0.3; bool hasDepthEdge = depthEdge > depthThresh; bool hasColorEdge = colorEdge > colorThresh; if ((hasDepthEdge || (hasColorEdge && depthEdge > depthThresh * 0.3)) && NdotV > 0.15) { return float4(0.1, 0.08, 0.06, 1.0); } discard; return float4(0, 0, 0, 0); } )hlsl"constexpr const char* TOON_PS_3D_FRESNEL = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; PSOutput PSMain(PSInput input) { PSOutput output; float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); // アンビエント float3 ambient = AmbientColor * MaterialDiffuse.rgb; // ディフューズ — NdotLを量子化 float rawNdotL = max(dot(N, L), 0.0); float toon = (rawNdotL > 0.5) ? 1.0 : (rawNdotL > 0.15) ? 0.6 : 0.3; float3 diffuse = LightColor * MaterialDiffuse.rgb * toon; // スペキュラー float3 H = normalize(L + V); float NdotH = max(dot(N, H), 0.0); float specFactor = pow(NdotH, MaterialShininess) * 0.3; float3 specular = LightColor * MaterialSpecular.rgb * specFactor; // Fresnel: シルエット付近(NdotV小)を暗化してアウトラインに float NdotV = max(dot(N, V), 0.0); float fresnelEdge = 1.0 - smoothstep(0.0, 0.4, NdotV); float3 outlineColor = float3(0.08, 0.06, 0.04); float3 finalColor = ambient + diffuse + specular; finalColor = lerp(finalColor, outlineColor, fresnelEdge * 0.95); float alpha = MaterialDiffuse.a * input.Color.a; output.Color = float4(finalColor * input.Color.rgb, alpha); output.Normal = float4(N * 0.5 + 0.5, NdotV); return output; } )hlsl"struct Transform2D 24
float a = 1.0ffloat b = 0.0ffloat c = 0.0ffloat d = 1.0ffloat tx = 0.0ffloat ty = 0.0f[[nodiscard]] static constexpr Transform2D identity() noexcept[[nodiscard]] static constexpr Transform2D translate(float tx, float ty) noexcept[[nodiscard]] static constexpr Transform2D scale(float sx, float sy) noexcept[[nodiscard]] static Transform2D rotate(float rad) noexcept[[nodiscard]] static Transform2D rotateAround(float rad, float px, float py) noexcept[[nodiscard]] constexpr Transform2D operator*(const Transform2D& r) const noexcept[[nodiscard]] constexpr sgc::Vec2f apply(const sgc::Vec2f& p) const noexcept[[nodiscard]] constexpr sgc::Vec2f apply(float x, float y) const noexcept[[nodiscard]] sgc::Rectf applyBounds(const sgc::Rectf& r) const noexcept[[nodiscard]] float avgScale() const noexcept[[nodiscard]] float scaleX() const noexcept[[nodiscard]] float scaleY() const noexcept[[nodiscard]] float rotation() const noexcept[[nodiscard]] bool isIdentity() const noexcept[[nodiscard]] bool isTranslationOnly() const noexcept[[nodiscard]] bool hasRotation() const noexcept[[nodiscard]] float translateX() const noexcept[[nodiscard]] float translateY() const noexceptstruct SortedDrawCommand 2
const Scene3D::RenderObject* objectfloat distanceToCameraclass TransparencySort 2
static void sortScene(const Scene3D& scene, const Camera3D& camera, std::vector<const Scene3D::RenderObject*>& opaqueOut, std::vector<const Scene3D::RenderObject*>& transparentOut)class [[deprecated("Use mitiru::vn::TrueTypeFont instead")]] TrueTypeFontclass TrueTypeRenderer 6
bool loadFont(const std::string& fontPath, float pixelHeight = 32.0f)[[nodiscard]] Texture renderText(const std::string& text, uint8_t r = 255, uint8_t g = 255, uint8_t b = 255, uint8_t a = 255) const[[nodiscard]] bool isLoaded() const noexcept[[nodiscard]] float pixelHeight() const noexcept[[nodiscard]] inline std::string utf8Substr(std::string_view text, std::size_t maxCodepoints)[[nodiscard]] inline std::size_t utf8Length(std::string_view text)class TrueTypeScreenRenderer 3
static void drawText(vn::TrueTypeFont& font, Screen& screen, float x, float y, std::string_view text, float fontSize, const sgc::Colorf& color)static float measureWidth(vn::TrueTypeFont& font, std::string_view text, float fontSize)static float measureHeight(vn::TrueTypeFont& font, float fontSize)struct Vertex2D 3
constexpr Vertex2D() noexcept = defaultconstexpr Vertex2D(const sgc::Vec2f& position, const sgc::Vec2f& texCoord, const sgc::Colorf& color) noexceptconstexpr Vertex2D(const sgc::Vec2f& position, const sgc::Colorf& color) noexceptstruct Vertex3D 3
constexpr Vertex3D() noexcept = defaultconstexpr Vertex3D(const sgc::Vec3f& position, const sgc::Vec3f& normal, const sgc::Vec2f& texCoord, const sgc::Colorf& color) noexceptconstexpr Vertex3D(const sgc::Vec3f& position, const sgc::Vec3f& normal) noexceptstruct VisualPresets 18
VisualPresets() = delete[[nodiscard]] static PanelStyle modernPanel() noexcept[[nodiscard]] static PanelStyle glassmorphism() noexcept[[nodiscard]] static PanelStyle neonGlow() noexcept[[nodiscard]] static PanelStyle flatMinimal() noexcept[[nodiscard]] static PanelStyle gameHud() noexcept[[nodiscard]] static PanelStyle tooltip() noexcept[[nodiscard]] static PanelStyle notification(NotificationType type) noexcept[[nodiscard]] static PanelStyle modalBackdrop() noexcept`constexpr std::string_view VOLUMETRIC_GODRAYS_PS = R"hlsl(`constexpr std::string_view VOLUMETRIC_FOG_PS = R"hlsl(Texture2D depthTexture : register(t1)SamplerState linearSampler : register(s0)cbuffer VolumetricParams : register(b0)Texture2D depthTexture : register(t1)SamplerState linearSampler : register(s0)cbuffer FogParams : register(b0)float linearizeDepth(float d, float near, float far)struct VolumetricConfig 6
float density = 0.5ffloat scattering = 0.3fint numSteps = 32float decay = 0.97ffloat exposure = 0.25ffloat weight = 0.5fstruct FogConfig 4
float density = 0.02ffloat startDistance = 10.0ffloat heightFalloff = 0.1ffloat maxFogFactor = 0.95fstruct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0struct PSInput 2
float4 position : SV_POSITIONfloat2 texCoord : TEXCOORD0class VolumetricLightPass 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>VolumetricLightPass() noexcept = defaultvoid init(ID3D11Device* device, int width, int height)[[nodiscard]] bool isInitialized() const noexceptvoid setConfig(const VolumetricConfig& config) noexcept[[nodiscard]] const VolumetricConfig& config() const noexceptvoid resize(std::uint32_t width, std::uint32_t height) noexceptvoid apply(ID3D11DeviceContext* context, ID3D11ShaderResourceView* sceneSRV, ID3D11ShaderResourceView* depthSRV, ID3D11RenderTargetView* outputRTV)class VolumetricFogPass 8
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>VolumetricFogPass() noexcept = defaultvoid init(ID3D11Device* device, int width, int height)[[nodiscard]] bool isInitialized() const noexceptvoid setConfig(const FogConfig& config) noexcept[[nodiscard]] const FogConfig& config() const noexceptvoid resize(std::uint32_t width, std::uint32_t height) noexceptvoid apply(ID3D11DeviceContext* context, ID3D11ShaderResourceView* sceneSRV, ID3D11ShaderResourceView* depthSRV, ID3D11RenderTargetView* outputRTV, const float cameraPos[3], float nearPlane, float farPlane)enum WorldUIType : uint8_t 3
ProgressBarLabelIconstruct WorldUIElement 9
WorldUIType type = WorldUIType::Labelsgc::Vec3f worldPositionfloat progress = 0.0ffloat barWidth = 60.0ffloat barHeight = 8.0fstd::string textfloat fontSize = 12.0ffloat iconSize = 16.0fbool visible = trueclass WorldUI 35
void add(const WorldUIElement& element)void clear()void render(Screen& screen, const Camera3D& camera, float screenWidth, float screenHeight) const[[nodiscard]] std::size_t elementCount() const noexceptinline RenderPipeline2D RenderPipeline2D::createFromDx11( gfx::Dx11Device* dx11Device, float screenWidth, float screenHeight)inline void RenderPipeline2D::submitBatchDx11( const std::vector<Vertex2D>& vertices, const std::vector<std::uint32_t>& indices)inline Microsoft::WRL::ComPtr<ID3D11InputLayout> RenderPipeline2D::createSdfInputLayout(ID3D11Device* device, const gfx::Dx11Shader& vs)inline Microsoft::WRL::ComPtr<ID3D11BlendState> RenderPipeline2D::createSdfBlendState(ID3D11Device* device)inline Microsoft::WRL::ComPtr<ID3D11RasterizerState> RenderPipeline2D::createSdfRasterizerState(ID3D11Device* device)inline void RenderPipeline2D::submitStyledBatchDx11( const std::vector<StyledVertex2D>& vertices, const std::vector<std::uint32_t>& indices, const StyleConstants& style, std::string_view vsSource, std::string_view psSource, std::unique_ptr<gfx::Dx11Shader>& cachedVS, std::unique_ptr<gfx::Dx11Shader>& cachedPS, Microsoft::WRL::ComPtr<ID3D11InputLayout>& cachedLayout)inline RenderPipeline2D RenderPipeline2D::createFromDx12( gfx::Dx12Device* dx12Device, float screenWidth, float screenHeight)inline D3D12_ROOT_SIGNATURE_DESC makeDx12PointRootSigDesc( D3D12_DESCRIPTOR_RANGE& srvRange, D3D12_ROOT_PARAMETER (¶ms)[3], D3D12_STATIC_SAMPLER_DESC& sampler)inline Microsoft::WRL::ComPtr<ID3D12RootSignature> createDx12PointRootSig(ID3D12Device* device, const D3D12_ROOT_SIGNATURE_DESC& rsd)inline void RenderPipeline2D::buildDx12PointFilterResources( ID3D12Device* device, ID3DBlob* vsBlob, ID3DBlob* psBlob, const D3D12_INPUT_ELEMENT_DESC* layout, UINT layoutCount)inline void RenderPipeline2D::submitBatchDx12( const std::vector<Vertex2D>& vertices, const std::vector<std::uint32_t>& indices)inline void RenderPipeline2D::submitStyledBatchDx12( const std::vector<StyledVertex2D>& vertices, const std::vector<std::uint32_t>& indices, const StyleConstants& style, std::string_view vsSource, std::string_view psSource, Microsoft::WRL::ComPtr<ID3D12PipelineState>& cachedPso)inline void RenderPipeline2D::ensureDx12SdfResources( std::string_view vsSource, std::string_view psSource, Microsoft::WRL::ComPtr<ID3DBlob>& cachedVs, Microsoft::WRL::ComPtr<ID3DBlob>& cachedPs, Microsoft::WRL::ComPtr<ID3D12PipelineState>& cachedPso)inline Microsoft::WRL::ComPtr<ID3D12Resource> RenderPipeline2D::createUploadBufferDx12(ID3D12Device* device, std::uint32_t sizeBytes)inline void RenderPipeline2D::updateCbDx12(ID3D12Resource* cb, const void* data, size_t bytes)inline void RenderPipeline2D::updateDx12Buffer( Microsoft::WRL::ComPtr<ID3D12Resource>& buf, std::uint32_t& capacity, const void* data, std::uint32_t bytes)inline Microsoft::WRL::ComPtr<ID3D12PipelineState> RenderPipeline2D::buildDx12Pso(ID3D12Device* device, ID3D12RootSignature* rootSig, ID3DBlob* vs, ID3DBlob* ps, const D3D12_INPUT_ELEMENT_DESC* layout, UINT layoutCount)inline void RenderPipeline2D::waitDx12Fence()inline void RenderPipeline2D::submitPixelGrid( const sgc::Rectf& dest, const std::uint32_t* pixels, int pw, int ph, float screenW, float screenH, PixelArtFilter filter)inline void RenderPipeline2D::submitPixelGridDx12( const sgc::Rectf& dest, const std::uint32_t* pixels, int pw, int ph, PixelArtFilter filter)inline constexpr const char* DX12_FXAA_PS_3D = R"hlsl( Texture2D sceneTexture : register(t0); SamplerState linearSampler : register(s0); cbuffer FXAAParams : register(b0) { float2 rcpFrame; // 1.0 / screenSize float subpixQuality; // サブピクセル品質 (0.0-1.0) float edgeThreshold; // エッジ検出閾値 float edgeThresholdMin; // 最小エッジ閾値 float3 fxaaPadding; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; float FxaaLuma(float3 rgb) { return dot(rgb, float3(0.299, 0.587, 0.114)); } float3 FxaaTexOff(float2 uv, float2 offset) { return sceneTexture.Sample(linearSampler, uv + offset * rcpFrame).rgb; } float4 PSMain(PSInput input) : SV_TARGET { float2 uv = input.TexCoord; // ── ステップ 1: 中心 + 4 近傍の輝度 ───────────────────── float3 rgbM = sceneTexture.Sample(linearSampler, uv).rgb; float lumaM = FxaaLuma(rgbM); float lumaN = FxaaLuma(FxaaTexOff(uv, float2( 0, -1))); float lumaS = FxaaLuma(FxaaTexOff(uv, float2( 0, 1))); float lumaE = FxaaLuma(FxaaTexOff(uv, float2( 1, 0))); float lumaW = FxaaLuma(FxaaTexOff(uv, float2(-1, 0))); // ── ステップ 2: 局所コントラストで reject ─────────────── float lumaMin = min(lumaM, min(min(lumaN, lumaS), min(lumaE, lumaW))); float lumaMax = max(lumaM, max(max(lumaN, lumaS), max(lumaE, lumaW))); float lumaRange = lumaMax - lumaMin; if (lumaRange < max(edgeThresholdMin, lumaMax * edgeThreshold)) { return float4(rgbM, 1.0); } // ── ステップ 3: 対角輝度を取り、水平/垂直エッジを判定 ──── float lumaNW = FxaaLuma(FxaaTexOff(uv, float2(-1, -1))); float lumaNE = FxaaLuma(FxaaTexOff(uv, float2( 1, -1))); float lumaSW = FxaaLuma(FxaaTexOff(uv, float2(-1, 1))); float lumaSE = FxaaLuma(FxaaTexOff(uv, float2( 1, 1))); float lumaNS = lumaN + lumaS; float lumaEW = lumaE + lumaW; float lumaNWSW = lumaNW + lumaSW; float lumaNESE = lumaNE + lumaSE; float lumaNWNE = lumaNW + lumaNE; float lumaSWSE = lumaSW + lumaSE; float edgeHorz = abs(lumaNWSW - 2.0 * lumaW) + abs(lumaNS - 2.0 * lumaM) * 2.0 + abs(lumaNESE - 2.0 * lumaE); float edgeVert = abs(lumaNWNE - 2.0 * lumaN) + abs(lumaEW - 2.0 * lumaM) * 2.0 + abs(lumaSWSE - 2.0 * lumaS); bool isHorizontal = (edgeHorz >= edgeVert); // ── ステップ 4: ステップ方向 ───────────────────────────── float stepLength = isHorizontal ? rcpFrame.y : rcpFrame.x; float luma1 = isHorizontal ? lumaN : lumaW; float luma2 = isHorizontal ? lumaS : lumaE; float gradient1 = luma1 - lumaM; float gradient2 = luma2 - lumaM; bool is1Steepest = abs(gradient1) >= abs(gradient2); float gradientScaled = 0.25 * max(abs(gradient1), abs(gradient2)); if (!is1Steepest) stepLength = -stepLength; float lumaLocalAvg = is1Steepest ? 0.5 * (luma1 + lumaM) : 0.5 * (luma2 + lumaM); float2 currentUV = uv; if (isHorizontal) currentUV.y += stepLength * 0.5; else currentUV.x += stepLength * 0.5; // ── ステップ 5: エッジ端点探索 (最大 12 ステップ) ──────── float2 offset2 = isHorizontal ? float2(rcpFrame.x, 0.0) : float2(0.0, rcpFrame.y); float2 uv1 = currentUV - offset2; float2 uv2 = currentUV + offset2; float lumaEnd1 = FxaaLuma(sceneTexture.Sample(linearSampler, uv1).rgb) - lumaLocalAvg; float lumaEnd2 = FxaaLuma(sceneTexture.Sample(linearSampler, uv2).rgb) - lumaLocalAvg; bool reached1 = abs(lumaEnd1) >= gradientScaled; bool reached2 = abs(lumaEnd2) >= gradientScaled; bool reachedBoth = reached1 && reached2; if (!reached1) uv1 -= offset2; if (!reached2) uv2 += offset2; static const float QUALITY[12] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.5, 2.0, 2.0, 2.0, 2.0, 4.0, 8.0 }; [unroll] for (int i = 0; i < 12 && !reachedBoth; i++) { if (!reached1) { lumaEnd1 = FxaaLuma( sceneTexture.Sample(linearSampler, uv1).rgb) - lumaLocalAvg; } if (!reached2) { lumaEnd2 = FxaaLuma( sceneTexture.Sample(linearSampler, uv2).rgb) - lumaLocalAvg; } reached1 = abs(lumaEnd1) >= gradientScaled; reached2 = abs(lumaEnd2) >= gradientScaled; reachedBoth = reached1 && reached2; if (!reached1) uv1 -= offset2 * QUALITY[i]; if (!reached2) uv2 += offset2 * QUALITY[i]; } // ── ステップ 6: ブレンド係数 ────────────────────────────── float dist1 = isHorizontal ? (uv.x - uv1.x) : (uv.y - uv1.y); float dist2 = isHorizontal ? (uv2.x - uv.x) : (uv2.y - uv.y); bool isDir1 = dist1 < dist2; float distFinal = min(dist1, dist2); float edgeLength = dist1 + dist2; float pixelOffset = -distFinal / max(edgeLength, 1e-5) + 0.5; bool isLumaCenterSmaller = lumaM < lumaLocalAvg; bool correctVariation = ((isDir1 ? lumaEnd1 : lumaEnd2) < 0.0) != isLumaCenterSmaller; float finalOffset = correctVariation ? pixelOffset : 0.0; // サブピクセル AA をブレンド float lumaAvg = (1.0 / 12.0) * (2.0 * lumaNS + 2.0 * lumaEW + lumaNWSW + lumaNESE); float subpixOffset1 = saturate( abs(lumaAvg - lumaM) / max(lumaRange, 1e-5)); float subpixOffset2 = (-2.0 * subpixOffset1 + 3.0) * subpixOffset1 * subpixOffset1; float subpixOffsetFinal = subpixOffset2 * subpixOffset2 * subpixQuality; finalOffset = max(finalOffset, subpixOffsetFinal); // 最終サンプリング float2 finalUV = uv; if (isHorizontal) finalUV.y += finalOffset * stepLength; else finalUV.x += finalOffset * stepLength; float3 finalColor = sceneTexture.Sample(linearSampler, finalUV).rgb; return float4(finalColor, 1.0); } )hlsl"inline constexpr const char* DX12_MULTI_LIGHT_PS_3D = R"HLSL( cbuffer CbLighting : register(b1) { float3 _unusedLightDir; float _pad0; float3 _unusedLightColor; float _pad1; float3 _unusedAmbient_b1; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; struct LightEntry { float4 typeAndIntensity; float4 position; float4 direction; float4 color; }; cbuffer CbLightArray : register(b2) { int lightCount; int3 _pad_la; float4 SceneAmbient; LightEntry Lights[8]; }; Texture2D g_albedo : register(t0); SamplerState g_samp : register(s0); struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; float3 evaluateLight(LightEntry L, float3 worldPos, float3 N, float3 V, float3 albedo, float3 specularCol, float shininess) { int type = (int)L.typeAndIntensity.x; float intensity = L.typeAndIntensity.y; float3 Lcol = L.color.rgb * intensity; float range = L.color.a; float3 Ldir; float attenuation = 1.0; if (type == 0) { Ldir = normalize(-L.direction.xyz); } else { float3 toLight = L.position.xyz - worldPos; float dist = length(toLight); Ldir = toLight / max(dist, 1e-4); attenuation = saturate(1.0 - dist / max(range, 1e-4)); attenuation *= attenuation; if (type == 2) { float3 spotDir = normalize(L.direction.xyz); float cosTheta = dot(-Ldir, spotDir); float inner = L.typeAndIntensity.z; float outer = L.typeAndIntensity.w; float spotFactor = saturate( (cosTheta - outer) / max(inner - outer, 1e-4)); attenuation *= spotFactor; } } float NdotL = saturate(dot(N, Ldir)); float3 H = normalize(Ldir + V); float specPow = max(shininess, 1.0); float NdotH = saturate(dot(N, H)); float spec = pow(NdotH, specPow) * NdotL; float3 diffuse = albedo * NdotL; float3 specular = specularCol * spec; return (diffuse + specular) * Lcol * attenuation; } PSOutput PSMain(PSInput input) { float3 N = normalize(input.WorldNorm); float3 V = normalize(CameraPos - input.WorldPos); float4 texSample = g_albedo.Sample(g_samp, input.TexCoord); float3 albedo = MaterialDiffuse.rgb * input.Color.rgb * texSample.rgb; float3 result = SceneAmbient.rgb * albedo; [unroll] for (int n = 0; n < 8; ++n) { if (n >= lightCount) break; result += evaluateLight(Lights[n], input.WorldPos, N, V, albedo, MaterialSpecular.rgb, MaterialShininess); } float alpha = MaterialDiffuse.a * input.Color.a * texSample.a; PSOutput o; o.Color = float4(result, alpha); float NdotV = max(dot(N, V), 0.0); o.Normal = float4(N * 0.5 + 0.5, NdotV); return o; } )HLSL"inline constexpr const char* DX12_TOON_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; Texture2D g_albedo : register(t0); SamplerState g_samp : register(s0); // LightSpacePos は VS が出力するため PSInput でも宣言してレジスタ整合を取る。 struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; PSOutput PSMain(PSInput input) { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); float4 texSample = g_albedo.Sample(g_samp, input.TexCoord); float3 albedo = MaterialDiffuse.rgb * input.Color.rgb * texSample.rgb; // アンビエント float3 ambient = AmbientColor * albedo; // ディフューズ — NdotL を 3 段階に量子化(toon 帯) float rawNdotL = saturate(dot(N, L)); float toon = (rawNdotL > 0.5) ? 1.0 : (rawNdotL > 0.15) ? 0.6 : 0.3; float3 diffuse = LightColor * albedo * toon; // ハイライト float3 H = normalize(L + V); float NdotH = saturate(dot(N, H)); float specFactor = pow(NdotH, max(MaterialShininess, 1.0)) * 0.3; float3 specular = LightColor * MaterialSpecular.rgb * specFactor; float alpha = MaterialDiffuse.a * input.Color.a * texSample.a; PSOutput o; o.Color = float4(ambient + diffuse + specular, alpha); float NdotV = saturate(dot(N, V)); o.Normal = float4(N * 0.5 + 0.5, NdotV); return o; } )hlsl"inline constexpr const char* DX12_PHONG_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; Texture2D g_albedo : register(t0); Texture2D g_shadow : register(t1); SamplerState g_samp : register(s0); SamplerComparisonState g_pcf : register(s1); struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; // 3x3 PCF (depth bias 込み) float samplePCF(float3 ndc) { // ndc: [-1,1] xy → UV [0,1], z → DX [0,1] そのまま float2 uv = float2(ndc.x * 0.5 + 0.5, -ndc.y * 0.5 + 0.5); float depthRef = ndc.z - 0.001; // shadow acne 抑制 if (any(uv < 0) || any(uv > 1)) return 1.0; // light frustum 外は影なし float shadow = 0.0; const float texelSize = 1.0 / 1024.0; // map size に整合させること [unroll] for (int y = -1; y <= 1; ++y) { [unroll] for (int x = -1; x <= 1; ++x) { float2 offset = float2(x, y) * texelSize; shadow += g_shadow.SampleCmpLevelZero(g_pcf, uv + offset, depthRef); } } return shadow / 9.0; } PSOutput PSMain(PSInput input) { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float3 V = normalize(CameraPos - input.WorldPos); float4 texSample = g_albedo.Sample(g_samp, input.TexCoord); float3 albedo = MaterialDiffuse.rgb * input.Color.rgb * texSample.rgb; // shadow factor (1.0 = unshadowed) float3 lsNdc = input.LightSpacePos.xyz / max(input.LightSpacePos.w, 1e-4); float shadow = samplePCF(lsNdc); float3 ambient = AmbientColor * albedo; float NdotL = saturate(dot(N, L)); float3 diffuse = LightColor * albedo * NdotL * shadow; float3 H = normalize(L + V); float NdotH = saturate(dot(N, H)); float specPow = max(MaterialShininess, 1.0); float specFactor = pow(NdotH, specPow) * NdotL * shadow; float3 specular = LightColor * MaterialSpecular.rgb * specFactor; float alpha = MaterialDiffuse.a * input.Color.a * texSample.a; PSOutput o; o.Color = float4(ambient + diffuse + specular, alpha); float NdotV = saturate(dot(N, V)); o.Normal = float4(N * 0.5 + 0.5, NdotV); return o; } )hlsl"inline constexpr const char* DX12_UNLIT_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 _unusedLightDir; float _pad0; float3 _unusedLightColor; float _pad1; float3 _unusedAmbient; float _pad2; float3 _unusedCameraPos; float _pad3; float4 MaterialDiffuse; float4 _unusedSpecular; float _unusedShininess; float3 _pad4; }; Texture2D g_albedo : register(t0); SamplerState g_samp : register(s0); struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; PSOutput PSMain(PSInput input) { float3 N = normalize(input.WorldNorm); float4 texSample = g_albedo.Sample(g_samp, input.TexCoord); float3 albedo = MaterialDiffuse.rgb * input.Color.rgb * texSample.rgb; float alpha = MaterialDiffuse.a * input.Color.a * texSample.a; PSOutput o; o.Color = float4(albedo, alpha); o.Normal = float4(N * 0.5 + 0.5, 1.0); return o; } )hlsl"inline constexpr const char* DX12_FLAT_PS_3D = R"hlsl( cbuffer CbLighting : register(b1) { float3 LightDir; float _pad0; float3 LightColor; float _pad1; float3 AmbientColor; float _pad2; float3 CameraPos; float _pad3; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialShininess; float3 _pad4; }; Texture2D g_albedo : register(t0); SamplerState g_samp : register(s0); struct PSInput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; nointerpolation float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; struct PSOutput { float4 Color : SV_TARGET0; float4 Normal : SV_TARGET1; }; PSOutput PSMain(PSInput input) { float3 N = normalize(input.WorldNorm); float3 L = normalize(-LightDir); float4 texSample = g_albedo.Sample(g_samp, input.TexCoord); float3 albedo = MaterialDiffuse.rgb * input.Color.rgb * texSample.rgb; float3 ambient = AmbientColor * albedo; float NdotL = saturate(dot(N, L)); float3 diffuse = LightColor * albedo * NdotL; float alpha = MaterialDiffuse.a * input.Color.a * texSample.a; PSOutput o; o.Color = float4(ambient + diffuse, alpha); o.Normal = float4(N * 0.5 + 0.5, NdotL); return o; } )hlsl"inline constexpr const char* DX12_DEFAULT_VS_3D = R"hlsl( cbuffer CbTransform : register(b0) { float4x4 World; float4x4 View; float4x4 Projection; }; cbuffer CbShadow : register(b3) { float4x4 LightViewProj; }; struct VSInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; struct VSOutput { float4 Position : SV_POSITION; float3 WorldPos : TEXCOORD0; float3 WorldNorm : TEXCOORD1; float2 TexCoord : TEXCOORD2; float4 LightSpacePos : TEXCOORD3; float4 Color : COLOR0; }; VSOutput VSMain(VSInput input) { VSOutput output; float4 worldPos = mul(World, float4(input.Position, 1.0)); output.WorldPos = worldPos.xyz; output.WorldNorm = normalize(mul((float3x3)World, input.Normal)); float4 viewPos = mul(View, worldPos); output.Position = mul(Projection, viewPos); // ライト空間位置 — シャドウサンプル PS で参照 output.LightSpacePos = mul(LightViewProj, worldPos); output.TexCoord = input.TexCoord; output.Color = input.Color; return output; } )hlsl"constexpr const char* OVERLAY2D_VS = R"hlsl( cbuffer CbOverlay2D : register(b0) { float4x4 OrthoProjection; }; struct VS_IN { float2 pos : POSITION; float2 uv : TEXCOORD; float4 color : COLOR; }; struct VS_OUT { float4 pos : SV_POSITION; float2 uv : TEXCOORD; float4 color : COLOR; }; VS_OUT VSMain(VS_IN i) { VS_OUT o; o.pos = mul(OrthoProjection, float4(i.pos, 0.0, 1.0)); o.uv = i.uv; o.color = i.color; return o; } )hlsl"constexpr const char* OVERLAY2D_PS = R"hlsl( struct VS_OUT { float4 pos : SV_POSITION; float2 uv : TEXCOORD; float4 color : COLOR; }; float4 PSMain(VS_OUT i) : SV_TARGET { return i.color; } )hlsl"struct alignas(256) DX12CbTransformstruct alignas(256) DX12CbLightingstruct Overlay2DVertex 3
float x, yfloat u, vfloat r, g, b, astruct OutlineDrawCommand 40
const Mesh* mesh = nullptrconstexpr const char* DX12_TONEMAP_VS = R"HLSL( struct VSOutput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; VSOutput VSMain(uint vertexID : SV_VertexID) { VSOutput output; output.TexCoord = float2((vertexID << 1) & 2, vertexID & 2); output.Position = float4(output.TexCoord * float2(2, -2) + float2(-1, 1), 0, 1); return output; } )HLSL"constexpr const char* DX12_TONEMAP_PS = R"HLSL( Texture2D<float4> g_hdr : register(t0); SamplerState g_samp : register(s0); cbuffer CbTonemap : register(b0) { float Exposure; // EV stops を線形係数に変換した値 (default 1.0) float Gamma; // 出力ガンマ (default 2.2) float2 _pad0; }; struct PSInput { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; }; // ACES filmic (Krzysztof Narkowicz 近似) // https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ float3 acesFilmic(float3 x) { const float a = 2.51f; const float b = 0.03f; const float c = 2.43f; const float d = 0.59f; const float e = 0.14f; return saturate((x * (a * x + b)) / (x * (c * x + d) + e)); } float4 PSMain(PSInput input) : SV_TARGET { float4 hdr = g_hdr.Sample(g_samp, input.TexCoord); float3 exposed = hdr.rgb * Exposure; float3 mapped = acesFilmic(exposed); // Gamma encode (linear → sRGB approximation) float invG = 1.0f / max(Gamma, 1e-4f); float3 outRGB = pow(max(mapped, 0.0f), invG.xxx); return float4(outRGB, hdr.a); } )HLSL"struct alignas(16) TonemapCB`constexpr std::string_view SSR_PS = R"hlsl(`constexpr std::string_view PARALLAX_HLSL_FUNCTION = R"hlsl(`constexpr std::string_view SSS_PS = R"hlsl(`constexpr std::string_view TESSELLATION_HS = R"hlsl(`constexpr std::string_view TESSELLATION_DS = R"hlsl(`constexpr std::string_view OIT_ACCUMULATE_PS = R"hlsl(`constexpr std::string_view OIT_COMPOSITE_PS = R"hlsl(`constexpr std::string_view PARTICLE_CS = R"hlsl(struct alignas(16) SSRCBDataTexture2D sceneDepth : register(t1)Texture2D sceneNormal : register(t2)SamplerState samp : register(s0)cbuffer SSRParams : register(b0)float curH = heightMap.SampleLevel(samp, curUV, 0).rfloat before = heightMap.SampleLevel(samp, prevUV, 0).r - curD + layerDreturn lerp(curUV, prevUV, w)struct alignas(16) SSSCBDataTexture2D thicknessMap : register(t1)SamplerState samp : register(s0)cbuffer SSSParams : register(b0)float3 sssKernel(float off, float rad)struct alignas(16) TessCBDataHConst HSConst(InputPatch<VOut,3> p, uint pid : SV_PrimitiveID)[domain("tri")][partitioning("fractional_odd")][outputtopology("triangle_cw")] [outputcontrolpoints(3)][patchconstantfunc("HSConst")] HOut HSMain(InputPatch<VOut,3> p, uint id : SV_OutputControlPointID)cbuffer MB : register(b1)Texture2D hmap : register(t0)SamplerState samp : register(s0)[domain("tri")] DOut DSMain(HConst hc, float3 b : SV_DomainLocation, const OutputPatch<HOut,3> p)PSOut PSMain(PSIn i)Texture2D revealTex : register(t1)SamplerState samp : register(s0)struct alignas(16) ParticleUpdateCBcbuffer U : register(b0)RWStructuredBuffer<P> particles : register(u0)float hash(uint s)[numthreads(256,1,1)] void CSMain(uint3 tid : SV_DispatchThreadID)struct SSRConfig 4
int maxSteps = 64float stepSize = 0.05ffloat thickness = 0.5ffloat fadeEdge = 0.1fstruct PSIn 2
float4 pos : SV_POSITIONfloat2 uv : TEXCOORD0class SSRPass : public PostProcessPass 5
explicit SSRPass(ID3D11Device* dev, const SSRConfig& cfg = {})void apply(ID3D11DeviceContext* ctx, ID3D11ShaderResourceView* in, ID3D11RenderTargetView* out, std::uint32_t w, std::uint32_t h) override[[nodiscard]] std::string_view name() const noexcept overridevoid setConfig(const SSRConfig& c) noexcept[[nodiscard]] const SSRConfig& config() const noexceptstruct ParallaxConfig 3
float heightScale = 0.05fint minLayers = 8int maxLayers = 32struct SSSConfig 2
float scatterRadius = 0.01ffloat thickness = 1.0fstruct PSIn 2
float4 pos : SV_POSITIONfloat2 uv : TEXCOORD0class SSSPass : public PostProcessPass 5
explicit SSSPass(ID3D11Device* dev, const SSSConfig& cfg = {})void apply(ID3D11DeviceContext* ctx, ID3D11ShaderResourceView* in, ID3D11RenderTargetView* out, std::uint32_t w, std::uint32_t h) override[[nodiscard]] std::string_view name() const noexcept overridevoid setConfig(const SSSConfig& c) noexcept[[nodiscard]] const SSSConfig& config() const noexceptstruct TessellationConfig 3
float tessellationFactor = 8.0ffloat displacementScale = 0.1fstd::string heightMapKeystruct VOut 3
float4 pos : SV_POSITIONfloat3 norm : NORMALfloat2 uv : TEXCOORD0struct HOut 3
float4 pos : SV_POSITIONfloat3 norm : NORMALfloat2 uv : TEXCOORD0struct HConst 2
float et[3] : SV_TessFactorfloat it : SV_InsideTessFactorstruct HOut 3
float4 pos : SV_POSITIONfloat3 norm : NORMALfloat2 uv : TEXCOORD0struct HConst 2
float et[3] : SV_TessFactorfloat it : SV_InsideTessFactorstruct DOut 3
float4 pos : SV_POSITIONfloat3 norm : NORMALfloat2 uv : TEXCOORD0class TessellationShaders 5
explicit TessellationShaders(ID3D11Device* dev, const TessellationConfig& cfg = {})void bind(ID3D11DeviceContext* ctx) conststatic void unbind(ID3D11DeviceContext* ctx)void setConfig(const TessellationConfig& c) noexcept[[nodiscard]] const TessellationConfig& config() const noexceptstruct OITConfig 1
bool enabled = truestruct PSOut 2
float4 accum : SV_TARGET0float reveal : SV_TARGET1struct PSIn 2
float4 pos : SV_POSITIONfloat2 uv : TEXCOORD0class OITPass 7
explicit OITPass(ID3D11Device* dev, const OITConfig& cfg = {})void resize(std::uint32_t w, std::uint32_t h)void beginTransparentPass(ID3D11DeviceContext* ctx) conststatic void endTransparentPass(ID3D11DeviceContext* ctx)void composite(ID3D11DeviceContext* ctx, ID3D11RenderTargetView* out) constvoid setConfig(const OITConfig& c) noexcept[[nodiscard]] const OITConfig& config() const noexceptstruct GPUParticleConfig 4
std::uint32_t maxParticles = 100000float gravity = -9.81ffloat drag = 0.98ffloat emitRate = 1000.0fstruct GPUParticle 7
float pos[3]float lifefloat vel[3]float maxLifefloat color[4]float sizefloat pad[3]class ComputeShaderParticles 6
explicit ComputeShaderParticles(ID3D11Device* dev, const GPUParticleConfig& cfg = {})void update(ID3D11DeviceContext* ctx, float deltaTime)[[nodiscard]] ID3D11ShaderResourceView* particleSRV() const noexcept[[nodiscard]] std::uint32_t particleCount() const noexceptvoid setConfig(const GPUParticleConfig& c) noexcept[[nodiscard]] const GPUParticleConfig& config() const noexceptstruct VignetteConfig 3
float intensity = 0.5ffloat radius = 0.8ffloat softness = 0.5fclass VignettePass : public PostProcessPass 4
VignettePass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const VignetteConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct ChromaticAberrationConfig 1
float intensity = 1.0fclass ChromaticAberrationPass : public PostProcessPass 4
ChromaticAberrationPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig( const ChromaticAberrationConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct FilmGrainConfig 2
float intensity = 0.05ffloat speed = 1.0fclass FilmGrainPass : public PostProcessPass 5
FilmGrainPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const FilmGrainConfig& cfg) noexceptvoid updateTime(float deltaTime) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct BloomConfig 3
float threshold = 0.8ffloat intensity = 1.0fint blurRadius = 8class BloomPass : public PostProcessPass 4
BloomPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler, std::uint32_t screenW, std::uint32_t screenH)void setConfig(const BloomConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct ColorGradingConfig 7
float brightness = 1.0ffloat contrast = 1.0ffloat saturation = 1.0ffloat gamma = 1.0ffloat tintR = 1.0ffloat tintG = 1.0ffloat tintB = 1.0fclass ColorGradingPass : public PostProcessPass 4
ColorGradingPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const ColorGradingConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct GaussianBlurConfig 2
int radius = 8float sigma = 4.0fclass GaussianBlurPass : public PostProcessPass 6
GaussianBlurPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler, std::uint32_t screenW, std::uint32_t screenH)void setConfig(const GaussianBlurConfig& cfg) noexceptvoid applyBlur( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH)void apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept override[[nodiscard]] ID3D11ShaderResourceView* intermediateSRV() const noexceptstruct PostProcessConfig 8
bloomcolorGradingvignettechromaticAberrationfilmGrainfadefrostGlassfxaaclass PostProcessChain 9
PostProcessChain( ID3D11Device* device, std::uint32_t screenW, std::uint32_t screenH)void addPass(std::unique_ptr<PostProcessPass> pass)void removePass(std::size_t index)[[nodiscard]] PostProcessPass* getPass( std::size_t index) const noexcept[[nodiscard]] std::size_t passCount() const noexcept[[nodiscard]] std::size_t enabledPassCount() const noexceptvoid execute( ID3D11DeviceContext* context, ID3D11ShaderResourceView* sceneTextureSRV, ID3D11RenderTargetView* finalRTV)void resize(std::uint32_t screenW, std::uint32_t screenH)[[nodiscard]] static PostProcessChain createFromConfig( ID3D11Device* device, std::uint32_t screenW, std::uint32_t screenH, const PostProcessConfig& config)class PostProcessPass 12
virtual ~PostProcessPass() = defaultvirtual void apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) = 0[[nodiscard]] bool isEnabled() const noexceptvoid setEnabled(bool enabled) noexcept[[nodiscard]] virtual std::string_view name() const noexcept = 0using ComPtr = Microsoft::WRL::ComPtr<T>;[[nodiscard]] inline PostProcessRT createRenderTarget( ID3D11Device* device, std::uint32_t w, std::uint32_t h, DXGI_FORMAT format = DXGI_FORMAT_R16G16B16A16_FLOAT)[[nodiscard]] inline ComPtr<ID3D11PixelShader> compilePostProcessPS( ID3D11Device* device, std::string_view source, const char* entryPoint = "PSMain")[[nodiscard]] inline ComPtr<ID3D11VertexShader> compileFullscreenVS( ID3D11Device* device)[[nodiscard]] inline ComPtr<ID3D11Buffer> createConstantBuffer( ID3D11Device* device, std::uint32_t sizeBytes)inline void updateConstantBuffer( ID3D11DeviceContext* context, ID3D11Buffer* buffer, const void* data, std::uint32_t sizeBytes)[[nodiscard]] inline ComPtr<ID3D11SamplerState> createLinearClampSampler( ID3D11Device* device)struct PostProcessRT 5
ComPtr<ID3D11Texture2D> textureComPtr<ID3D11ShaderResourceView> srvComPtr<ID3D11RenderTargetView> rtvstd::uint32_t width = 0std::uint32_t height = 0struct FadeConfig 5
float colorR = 0.0ffloat colorG = 0.0ffloat colorB = 0.0ffloat colorA = 1.0ffloat progress = 0.0fclass FadePass : public PostProcessPass 4
FadePass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const FadeConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct FrostGlassConfig 5
float blurAmount = 2.0ffloat tintR = 0.9ffloat tintG = 0.95ffloat tintB = 1.0ffloat time = 0.0fclass FrostGlassPass : public PostProcessPass 4
FrostGlassPass( ID3D11Device* device, const ComPtr<ID3D11VertexShader>& fullscreenVS, const ComPtr<ID3D11SamplerState>& sampler)void setConfig(const FrostGlassConfig& cfg) noexceptvoid apply( ID3D11DeviceContext* context, ID3D11ShaderResourceView* inputSRV, ID3D11RenderTargetView* outputRTV, std::uint32_t screenW, std::uint32_t screenH) override[[nodiscard]] std::string_view name() const noexcept overridestruct SdfOutlineEffect 2
bool enabled = falsefloat width = 0.1fstruct SdfShadowEffect 4
bool enabled = falsefloat offsetX = 2.0ffloat offsetY = 2.0ffloat softness = 0.15fstruct SdfGlowEffect 2
bool enabled = falsefloat radius = 0.2fstruct SdfTextEffect 7
SdfOutlineEffect outlineSdfShadowEffect shadowSdfGlowEffect glow[[nodiscard]] static SdfTextEffect none() noexcept[[nodiscard]] static SdfTextEffect withOutline( const sgc::Colorf& color, float width = 0.1f)[[nodiscard]] static SdfTextEffect withShadow( const sgc::Colorf& color, float offsetX = 2.0f, float offsetY = 2.0f)[[nodiscard]] static SdfTextEffect withGlow( const sgc::Colorf& color, float radius = 0.2f)struct SdfGlyphInfo 11
std::uint32_t codepoint = 0int x0 = 0int y0 = 0int x1 = 0int y1 = 0float xoff = 0.0ffloat yoff = 0.0ffloat xadvance = 0.0fint sdfPadding = 0[[nodiscard]] int width() const noexcept[[nodiscard]] int height() const noexceptstruct SdfFontMetrics 5
float ascent = 0.0ffloat descent = 0.0ffloat lineGap = 0.0ffloat lineHeight = 0.0ffloat sdfPixelSize = 0.0fclass SdfFontAtlas 27
SdfFontAtlas() = defaultexplicit SdfFontAtlas(std::vector<std::uint8_t> fontData, float sdfPixelSize = 32.0f, int sdfPadding = 6)SdfFontAtlas(SdfFontAtlas&& other) noexceptSdfFontAtlas& operator=(SdfFontAtlas&& other) noexceptSdfFontAtlas(const SdfFontAtlas&) = deleteSdfFontAtlas& operator=(const SdfFontAtlas&) = deletevoid addCodepointRange(std::uint32_t first, std::uint32_t last)void addCodepoint(std::uint32_t codepoint)void addAsciiRange()void addHiraganaRange()void addKatakanaRange()void addCommonKanjiRange()void addFromString(std::string_view text)void addCjkPunctuationRange()void addFullwidthRange()bool buildAtlas(int atlasPadding = 2)[[nodiscard]] bool valid() const noexcept[[nodiscard]] const Texture& texture() const noexcept[[nodiscard]] int atlasWidth() const noexcept[[nodiscard]] int atlasHeight() const noexcept[[nodiscard]] const SdfFontMetrics& metrics() const noexcept[[nodiscard]] float sdfPixelSize() const noexcept[[nodiscard]] int sdfPadding() const noexcept[[nodiscard]] const SdfGlyphInfo* findGlyph(std::uint32_t codepoint) const noexcept[[nodiscard]] float kerning(std::uint32_t cp1, std::uint32_t cp2, float fontSize) const noexcept[[nodiscard]] std::size_t glyphCount() const noexcept[[nodiscard]] const std::unordered_map<std::uint32_t, SdfGlyphInfo>& glyphs() const noexceptstruct SdfTextSize 2
float width = 0.0ffloat height = 0.0fstruct SdfWrappedLine 9
std::string_view textfloat width = 0.0f[[nodiscard]] inline float sampleAtlasBilinear( const std::vector<std::uint8_t>& pixels, int w, int h, float x, float y) noexcepttemplate <typename ScreenType> inline void renderGlyphSoftware(ScreenType& screen, const SdfGlyphInfo& gi, const std::vector<std::uint8_t>& atlasPixels, int atlasW, int atlasH, float cursorX, float baseY, float displayScale, const sgc::Colorf& color, float threshold, float extraSmoothing)template <typename BatchType> inline void drawText(const SdfFontAtlas& atlas, BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& color)template <typename BatchType> inline void drawTextExpanded(const SdfFontAtlas& atlas, BatchType& batch, std::string_view text, float x, float y, float fontSize, const sgc::Colorf& color, float expand)[[nodiscard]] inline std::vector<std::uint32_t> toCodepoints(std::string_view sv)[[nodiscard]] inline int nextPow2(int v) noexcept[[nodiscard]] inline float smoothstep(float edge0, float edge1, float x) noexceptclass Utf8Decoder 4
Utf8Decoder(const char* str, std::size_t len) noexceptexplicit Utf8Decoder(std::string_view sv) noexcept[[nodiscard]] bool hasNext() const noexcept[[nodiscard]] std::uint32_t next() noexceptSourced from docs/API_CATALOG.md, auto-generated by tools/generate_api_catalog.py.