Skip to content

Add Vulkan backend for 3D rendering with advanced features#1446

Merged
yuto-trd merged 79 commits intomainfrom
feat/3d2
Jan 29, 2026
Merged

Add Vulkan backend for 3D rendering with advanced features#1446
yuto-trd merged 79 commits intomainfrom
feat/3d2

Conversation

@yuto-trd
Copy link
Copy Markdown
Member

Description

Implement a comprehensive Vulkan backend for 3D rendering, introducing core components such as scene management, camera systems, lighting, and materials. Enhance the architecture with support for offscreen rendering, texture downloads, and a new shader compilation interface.

Breaking changes

None.

Fixed issues

None.

@yuto-trd

This comment was marked as resolved.

Core 3D Components:
- Scene3D: Main 3D scene Drawable with camera, objects, and lights
- Scene3DRenderNode: Custom render node for GraphicsContext2D integration
- Object3D: Base class for 3D objects with transform properties
- Cube3D: Procedural cube primitive

Camera System:
- Camera3D: Abstract base with view matrix and clipping planes
- PerspectiveCamera: Field of view based projection
- OrthographicCamera: Width based orthographic projection

Lighting:
- Light3D: Base class for lights
- DirectionalLight3D: Sun-like directional lighting

Materials:
- Material3D: Base material class
- BasicMaterial: Simple diffuse color material

Meshes:
- Mesh: Vertex/index data container with bounding box
- CubeMesh: Procedural cube mesh generator
- Vertex3D: Position, normal, texcoord vertex structure

Vulkan Backend:
- VulkanBuffer: GPU buffer with staging upload
- VulkanTexture2D: 2D texture with format conversion
- VulkanRenderPass3D: Render pass with color/depth attachments
- VulkanPipeline3D: Graphics pipeline with shader management
- VulkanFramebuffer3D: Framebuffer with shared texture output
- VulkanDescriptorSet: Uniform buffer binding
- VulkanShaderCompiler: GLSL to SPIR-V compilation via shaderc
- Vulkan3DRenderer: Main 3D rendering orchestrator

Backend Abstractions:
- IBuffer, ITexture2D, IRenderPass3D, IPipeline3D
- IFramebuffer3D, IDescriptorSet, IShaderCompiler
- TextureFormatExtensions: Centralized format conversions

Also refactored to eliminate code duplication:
- Moved FindMemoryType to VulkanContext
- Created TextureFormatExtensions for format conversions
- Consolidated mesh generation in CubeMesh
Add DownloadPixels() method to ISharedTexture interface for reading
texture data back from GPU to CPU memory via staging buffers. This
enables offscreen rendering verification and image export.

Create Beutl.Graphics3DTests console project that demonstrates:
- Vulkan initialization and GPU selection
- 3D scene setup (camera, cube, directional light)
- Offscreen rendering to texture
- Pixel data download and PNG export
- Added VulkanRenderPass3D class for managing Vulkan render passes in 3D.
- Introduced VulkanSetup class for environment setup specific to Vulkan.
- Created VulkanShaderCompiler for compiling shaders using shaderc.
- Implemented VulkanSharedTexture for shared texture management in Vulkan.
- Added VulkanTexture2D for 2D texture handling in Vulkan.
- Updated RenderTarget to support Vulkan backend.
- Defined I3DRenderer interface for 3D rendering abstraction.
- Created Vertex3D struct for standard 3D vertex representation.
- Refactored Scene3D to utilize I3DRenderer for rendering.
- Updated Scene3DRenderNode to create and manage 3D renderer instances.
- Modified tests to initialize graphics context and renderer through the new abstraction.
Move Renderer3D to Graphics3D namespace and make it backend-agnostic by:
- Adding factory methods to IGraphicsContext for creating buffers, shaders,
  render passes, framebuffers, pipelines, and descriptor sets
- Creating abstracted flag types (BufferUsage, MemoryProperty, DescriptorType,
  ShaderStage) in Beutl.Graphics.Backend
- Adding VulkanFlagConverter to convert between abstracted and Vulkan flags
- Adding draw methods to IRenderPass3D (BindPipeline, BindVertexBuffer,
  BindIndexBuffer, BindDescriptorSet, DrawIndexed)
- Implementing the new interface methods in VulkanRenderPass3D
Make graphics backend types public while keeping Vulkan-specific implementation
details internal. Introduce GraphicsDeviceInfo and GraphicsDeviceType as public
abstractions for VulkanPhysicalDeviceInfo, allowing external code to query
available graphics devices without depending on Vulkan types.
Extract UniformBufferObject struct and shader source code into dedicated
files to improve code organization and maintainability.

- UniformBufferObject.cs: UBO struct with transformation matrices and lighting data
- BasicShaderSources.cs: Static class containing GLSL vertex/fragment shaders
Refactor 3D mesh and object architecture to follow the existing 2D
Geometry/Shape pattern for consistency and better resource management:

- Mesh: Now abstract EngineObject with ApplyTo method and Resource
  containing cached vertices/indices with version-based change detection
- CubeMesh: Extends Mesh with ApplyTo implementation for cube generation
- Object3D.Resource: Add abstract GetMesh() method returning Mesh.Resource
- Cube3D: Follow RectShape pattern with internal CubeMesh and PostUpdate
  synchronization for Width/Height/Depth properties
- Renderer3D: Manage IBuffer creation in EnsureMeshBuffers(), store
  buffers in Mesh.Resource with BuffersDirty flag for change detection
- I3DRenderer: Simplify Render signature to take IReadOnlyList<Object3D.Resource>
- Scene3DRenderNode: Simplified to pass object resources directly

This change improves memory management by storing GPU buffers in
Mesh.Resource and disposing them properly in PostDispose.
…nagement

- Add backend abstraction types (DescriptorBinding, DescriptorPoolSize, DescriptorType, MemoryProperty)
- Create VulkanFlagConverter for converting between abstract and Vulkan-specific types
- Move shader and pipeline management from Renderer3D to Material3D derived classes
- Replace Vulkan3DRenderer with backend-agnostic Renderer3D
- Extend IGraphicsContext and IRenderPass3D interfaces for 3D rendering operations
- Update VulkanBuffer and related classes to use abstracted enums
- Add RenderContext3D to pass rendering state to materials
- Add abstract EnsurePipeline() and Bind() methods to Material3D.Resource
- Implement shader/pipeline management in BasicMaterial.Resource
- Remove BasicShaderSources.cs and UniformBufferObject.cs (moved to BasicMaterial)
- Each material now manages its own shaders, pipeline, and descriptor sets
- Add PBRMaterial with Cook-Torrance BRDF shader
  - Metallic-roughness workflow
  - Supports albedo, metallic, roughness, AO, emissive
  - Tone mapping and gamma correction
- Add PointLight3D for omnidirectional point lights
  - Position-based with distance attenuation
- Add SpotLight3D for cone-shaped spotlights
  - Inner/outer cone angles with smooth falloff
- Add LightData struct for shader-compatible light representation
- Update RenderContext3D to support multiple lights (up to 8)
- Update Renderer3D to convert Light3D resources to LightData
- Update test program to demonstrate PBR with multiple light types
…ization

- Add SphereMesh: procedural UV sphere with configurable radius, segments, rings
- Add Sphere3D: sphere primitive following the Cube3D pattern
- Update test to show 7x7 grid of spheres with varying Metallic/Roughness
- Grid clearly demonstrates PBR material properties:
  - Horizontal: Metallic 0->1 (dielectric to metal)
  - Vertical: Roughness 0->1 (smooth to rough)
…aphics3D

- Abstract BufferUsage, MemoryProperty, DescriptorType, and DescriptorBinding
  to remove Vulkan-specific types from IGraphicsContext interface
- Add VulkanFlagConverter to convert between abstract and Vulkan types
- Extend IRenderPass3D with binding and drawing methods
- Move 3D renderer from Backend/Vulkan to Graphics3D layer (Renderer3D)
- Update IGraphicsContext with factory methods for buffers, shaders,
  render passes, framebuffers, pipelines, and descriptor sets
- Update BasicMaterial to output G-Buffer data (position, normal, albedo+roughness, emission+AO)
- Update PBRMaterial to output G-Buffer data instead of performing lighting calculations
- Remove lighting code from materials (lighting is now done in the lighting pass)
- Convert BasicMaterial's shininess to roughness for PBR compatibility
- Simplify material UBOs by removing light-related uniforms
…ndering

- Add ISampler interface with filter and address mode configuration
- Implement VulkanSampler for Vulkan backend
- Add CreateSampler method to IGraphicsContext
- Update IDescriptorSet.UpdateTexture to require ISampler parameter
- Create and use sampler in Renderer3D for G-Buffer texture sampling

This fixes the purple output issue caused by CombinedImageSampler
descriptors not having a valid sampler bound.
…line3D

Replace dedicated CreateFullscreenPipeline3D method with flexible parameters
on CreatePipeline3D allowing external specification of vertex input description
and pipeline options (depth test, cull mode).

- Add VertexInputDescription and PipelineOptions abstractions in Backend
- Add Vertex3D.GetVertexInputDescription() helper for 3D mesh pipelines
- Use VertexInputDescription.Empty and PipelineOptions.Fullscreen for lighting pass
- Add CopyTexture method for ITexture2D to ISharedTexture transfers
- Remove VulkanVertex3D helper class (no longer needed)
…asses

Introduce a node-based architecture for 3D render passes to support future extensibility:
- Add RenderNode3D as the abstract base class for all 3D nodes
- Add GraphicsNode3D as the base class for render passes (inherits RenderNode3D)
- Extract GeometryPass (G-Buffer rendering) into its own class
- Extract LightingPass (PBR deferred lighting) into its own class
- Simplify Renderer3D to act as a coordinator (714 lines → 149 lines)

This architecture enables future additions like ShadowPass, SSAOPass, BloomPass,
and ComputeNode3D for GPU compute operations.
Add FlipPass as the final render pass to resolve vertical flip issue
caused by coordinate system differences between Vulkan and Skia.
The pass uses a fullscreen triangle with inverted Y texture coordinates
to flip the image before output.
- Implemented CreateTextureCube and CreateTextureArray methods in CompositeContext and VulkanContext.
- Added UpdateTextureCube and UpdateTextureArray methods in IDescriptorSet interface.
- Introduced ITextureCube and ITextureArray interfaces for cube map and 2D texture array abstractions.
- Developed VulkanTextureCube and VulkanTextureArray classes for Vulkan-specific implementations.
- Enhanced VulkanCommandPool with a method to transition image layouts.
- Updated VulkanRenderPass3D to support push constants for bound pipelines.
- Added ShadowPass class for rendering directional and spot light shadow maps.
- Introduced ShadowManager to manage shadow rendering for multiple lights.
- Updated Renderer3D to integrate shadow rendering into the rendering pipeline.
- Created tests for directional, point, and spot light shadows, including multiple light scenarios.
- Ensured proper resource management and cleanup for shadow-related resources.
- Add CopyTextureToArrayLayer to IGraphicsContext for copying shadow maps to array layers
- Change shadow map binding from single texture to sampler2DArray for multiple shadow support
- Fix shadow bias: use normal offset (normalBias) for sample position and small depth bias (0.0001)
- Remove harmful TransitionAllToSampled call that was discarding shadow map data
- Update SpotLight test position for clearer shadow testing
…bject properties

Add localization support for 3D graphics system by adding Display attributes
to properties across cameras, lights, materials, meshes, models, primitives,
scene, and textures. This enables proper UI display names in the editor.
Introduced new resource string properties for 3D graphics elements such as cameras, lights, materials, meshes, and related attributes in Strings.Designer.cs. This supports localization and UI display for upcoming 3D features.
@yuto-trd yuto-trd marked this pull request as ready for review January 29, 2026 10:13
Copilot AI review requested due to automatic review settings January 29, 2026 10:14
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dcf955dd88

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics3D/Renderer3D.cs
Comment thread src/Beutl.Engine/Graphics3D/Materials/BasicMaterial.cs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive Vulkan-based 3D rendering backend for Beutl, introducing extensive infrastructure for real-time 3D graphics. The implementation adds scene management, camera systems, lighting, materials, mesh generation, shader compilation, and UI integration for 3D camera manipulation.

Changes:

  • Implements Vulkan backend with support for textures, buffers, pipelines, render passes, and descriptor sets
  • Adds 3D rendering components including Scene3D, cameras (perspective/orthographic), lights (directional/point/spot), and materials
  • Introduces procedural mesh generation for primitives (cube, sphere, plane) and model loading via Assimp
  • Integrates 3D camera mode into the PlayerView UI with gizmo controls for transformation manipulation

Reviewed changes

Copilot reviewed 141 out of 142 changed files in this pull request and generated 58 comments.

Show a summary per file
File Description
tests/Beutl.Graphics3DTests/Beutl.Graphics3DTests.csproj New test project configuration for 3D graphics testing
src/Beutl/Views/PlayerView.* UI integration for 3D camera mode with keyboard/pointer input and gizmo controls
src/Beutl/Views/Editors/Editor. Property editors for texture and model sources
src/Beutl/ViewModels/* View models for property editors and player interactions with 3D scenes
src/Beutl/Converters/GizmoModeConverters.cs Value converters for gizmo mode UI binding
src/Beutl.Operators/Source/*Operator.cs Operators for 3D objects, lights, and scene management
src/Beutl.Operators/LibraryRegistrar.cs Registration of 3D components in the library system
src/Beutl.Engine/Graphics3D/* Core 3D rendering infrastructure including scenes, cameras, lighting, materials, meshes
src/Beutl.Engine/Graphics/Backend/Vulkan/* Vulkan backend implementation with texture, buffer, pipeline, and shader compiler classes
src/Beutl.Engine/Graphics/Backend/* Abstract interfaces for graphics backend (ITexture2D, IBuffer, IPipeline3D, etc.)
src/Beutl.Engine/Graphics/Rendering/RenderTarget.cs Updated to use ITexture2D instead of ISharedTexture
src/Beutl.Core/JsonConverters/* JSON converters for Vector3 and Quaternion serialization
Directory.Packages.props Added dependencies for Silk.NET.Shaderc and Silk.NET.Assimp
Files not reviewed (1)
  • src/Beutl.Language/Strings.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Beutl.Engine/Graphics/Rendering/RenderTarget.cs Outdated
Comment thread src/Beutl/ViewModels/PlayerViewModel.cs
Comment thread src/Beutl.Core/JsonConverters/Vector3JsonConverter.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Backend/Metal/MetalVulkanTexture2D.cs
Comment thread src/Beutl/ViewModels/PlayerViewModel.cs
Comment thread src/Beutl.Engine/Graphics/Backend/Vulkan/VulkanContext.cs
Comment thread src/Beutl.Engine/Graphics/Backend/Vulkan/VulkanRenderPass3D.cs
Comment thread src/Beutl.Engine/Graphics3D/Meshes/SphereMesh.cs
Comment thread src/Beutl.Engine/Graphics3D/Meshes/Vertex3D.cs
Comment thread src/Beutl.Engine/Graphics3D/Meshes/Vertex3D.cs
@github-actions
Copy link
Copy Markdown
Contributor

No TODO comments were found.

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
Beutl.Operators 2% 0% 106
Beutl.Editor 98% 94% 602
Beutl.Core 39% 36% 2964
Beutl.Engine 21% 19% 13586
Beutl.Threading 100% 94% 118
Beutl.Utilities 73% 67% 358
Beutl.Configuration 39% 19% 288
Beutl.Extensibility 14% 16% 100
Beutl.ProjectSystem 19% 11% 1877
Beutl.Language 0% 0% 912
Summary 25% (13027 / 51267) 25% (3573 / 14381) 20911

Minimum allowed line rate is 0%

@yuto-trd yuto-trd merged commit 184d38c into main Jan 29, 2026
4 checks passed
@yuto-trd yuto-trd deleted the feat/3d2 branch January 29, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants