You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
float3 (host, CUDARenderer.h:89) ↔ CUDA float3 — both 12 bytes, 4-byte alignment
ANY layout change must update BOTH sides simultaneously.
Scene Data Flow
ImGui modifies Scene directly via structured bindings (glm::value_ptr)
CPU path reads m_ActiveScene pointer → always gets latest data
GPU path: UploadSceneToGPU() called when scene.Version changes → cudaMemcpy host→device
GPU realloc only when sphere/material counts change (CUDARenderer.cu:158-219)
Scene version tracking: Scene::Version incremented on any ImGui change; m_LastSceneVersion compared to skip uploads
Rendering Pipeline (Multi-Backend)
Renderer::Render orchestrates: stores scene/camera pointers, delegates to m_Backend->Render()
GPU path (CUDABackend): Scene data upload (version-tracked) → camera upload → ray dirs upload (dirty-tracked) → RenderKernel → PostProcessKernel → (OptiX denoise) → output (interop zero-copy or D2H)
CPU path (CPUBackend): ISPC SIMD SoA packing → ISPCRenderPixels kernel → unpack + accumulate, or C++ std::execution::par fallback with PerPixel()
Factory CreateBackend() selects GPU if PN_CUDA defined, falls back to CPU
Renderer handles output delivery: checks Backend->OutputDelivered() to decide between interop path (GPU) or SetData path
Emission Integration Order
Both CPU and GPU: light += contribution * emission BEFORE BRDF updates contribution
Matches path tracing integral: Le · prod(previous BSDFs)
With GGX BRDF: contribution updated via (spec + diff) * NdotL / pdf (replaces old contribution *= albedo)
Naming
PascalCase for classes/structs, camelCase for methods/members
m_ prefix for member variables (m_Camera, m_FrameIndex)
k prefix (no underscore) for compile-time constants (kPi, kRoughnessMin, kMultithreaded, kMaxBounces)
GPU types prefixed with GPU (GPUSphere, GPUMaterial, GPUScene, GPUHitPayload)
Host-side GPU packing structs prefixed with GPUPacked
CUDA interop: C API functions prefixed with CUDARenderer_; RAII class VkCUDAInterop
ANTI-PATTERNS
Peanut may be modified freely — it is an independent fork (diverged from Walnut), no upstream merge requirement. Changes should prioritize general-purpose improvements (new features, performance, bugfixes) usable by any Peanut application. Avoid RayTracing-specific logic in Peanut; keep domain-specific code in RayTracing/src/.
NEVER suppress CUDA errors — always check cudaMalloc/cudaMemcpy/cudaStreamCreate return values
NEVER assume scene data is synced to GPU — increment Scene::Version on any scene change
NEVER change GPUPacked* struct layout without updating GPUMaterial/GPUSphere in CUDATypes.cuh
NEVER use --remote on git submodule update — vendor deps are pinned by Peanut
NEVER create/destroy VkCUDAInterop during CUDA kernel execution — set up before render, destroy after sync
NEVER call OptiXDenoiser::Denoise before Initialize — check IsValid() first
NEVER assume non-interop output path is active — check m_InteropEnabled before using CUDARenderer_GetOutput
UNIQUE STYLES
Structured bindings for sphere/material field access: auto& [Position, Radius, MaterialIndex] = spheres[i]
Box-drawing comment separators: // --- Section Title ---
No sky/environment light — all illumination from emissive materials only
m_NeedsRender flag for conditional re-render (ImGui change detection)
m_RayDirsDirty flag for lazy camera ray direction re-upload
Scene::Version for dirty-tracked GPU scene upload dedup
Two-stage GPU pipeline: raw sample → accumulation + post-process (separate kernels on same stream)
VS IntelliSense: Directory.Build.props at project root auto-discovered by MSBuild. Contains only GLFW_INCLUDE_NONE and IMGUI_DEFINE_MATH_OPERATORS defines, plus C++23 standard. Include paths delegated to xmake-generated vcxproj XmakeIncludeDirs.
set_default(true) on target("RayTracing") sets it as VS startup project in .sln (lost in .slnx migration).
Dependencies
Dep
Version
Source
ImGui
v1.91+ (docking)
ocornut/imgui:docking (vendor submodule)
GLFW
3.4
glfw/glfw (vendor submodule on master / xrepo on feat/xmake-packages)
glm
1.0.3
g-truc/glm (vendor submodule on master / xrepo on feat/xmake-packages)
stb_image
latest
nothings/stb (vendored on master / xrepo on feat/xmake-packages)
Known Quirks
glm 1.0.3 requires GLM_ENABLE_EXPERIMENTAL — added before #include <glm/gtx/quaternion.hpp> in Camera.cpp:3.