simvx.graphics.materials.custom_shader¶
Custom shader material system — user-facing API for custom GLSL shaders.
Provides ShaderMaterial for per-object custom shaders, UniformBuffer for GPU-side uniform data, and ShaderMaterialManager for pipeline caching and hot-reload.
Module Contents¶
Classes¶
User-facing custom shader material. |
|
GPU buffer for custom shader uniforms (std140 layout). |
|
Caches compiled pipelines by shader combination and manages hot-reload. |
Data¶
API¶
- simvx.graphics.materials.custom_shader.__all__¶
[‘ShaderMaterial’, ‘UniformBuffer’, ‘ShaderMaterialManager’]
- simvx.graphics.materials.custom_shader.log¶
‘getLogger(…)’
- class simvx.graphics.materials.custom_shader.ShaderMaterial(vertex_path: str | pathlib.Path | None = None, fragment_path: str | pathlib.Path | None = None, *, vertex_source: str | None = None, fragment_source: str | None = None)¶
User-facing custom shader material.
Allows using custom GLSL vertex/fragment shaders with user-defined uniforms. Works alongside the engine’s existing uber-shader pipeline by creating its own separate Vulkan pipeline.
Example::
mat = ShaderMaterial( vertex_path="shaders/wave.vert", fragment_path="shaders/gradient.frag", ) mat.set_uniform("time", 0.0) mat.set_uniform("color", (1.0, 0.5, 0.2, 1.0))Or with inline source::
mat = ShaderMaterial( vertex_source=""" #version 450 layout(location=0) in vec3 pos; void main() { gl_Position = vec4(pos, 1.0); } """, fragment_source=""" #version 450 layout(location=0) out vec4 out_color; void main() { out_color = vec4(1.0, 0.0, 0.0, 1.0); } """, )Initialization
- property is_compiled: bool¶
Whether shaders have been compiled to SPIR-V and loaded.
- property uniforms: dict[str, Any]¶
All current uniform values.
- set_uniform(name: str, value: Any) None¶
Set a shader uniform by name.
Supported types: float, int, vec2, vec3, vec4, mat4, and numpy arrays. Type is inferred automatically from the value.
- set_uniform_typed(name: str, value: Any, utype: str) None¶
Set a uniform with an explicit GLSL type string.
- get_uniform(name: str) Any¶
Get the current value of a uniform. Raises KeyError if not set.
- compile(device: Any, shader_dir: pathlib.Path | None = None) None¶
Compile shaders to SPIR-V and create Vulkan shader modules.
Uses file paths if provided, otherwise writes inline source to temp files for compilation via glslc.
Args: device: Vulkan logical device handle. shader_dir: Base directory for resolving relative shader paths and includes.
- get_pipeline_key() tuple¶
Return a hashable key unique to this shader combination.
Used for pipeline caching in ShaderMaterialManager.
- has_source_changed() bool¶
Check if shader source files have been modified since last compile.
- cleanup(device: Any) None¶
Destroy Vulkan shader modules.
- class simvx.graphics.materials.custom_shader.UniformBuffer(max_size: int = 1024)¶
GPU buffer for custom shader uniforms (std140 layout).
Manages a host-visible Vulkan buffer and descriptor set for binding user-defined uniforms to a custom shader pipeline.
The buffer is laid out according to std140 rules so it can be directly consumed by a GLSL uniform block.
Initialization
- property is_created: bool¶
- create(device: Any, physical_device: Any) None¶
Create the GPU buffer and descriptor resources.
- update(device: Any, uniform_data: dict[str, Any], uniform_types: dict[str, str]) None¶
Upload uniform values to the GPU buffer using std140 layout.
Args: device: Vulkan logical device. uniform_data: Name-to-value mapping of uniforms. uniform_types: Name-to-GLSL-type mapping (e.g. {“time”: “float”}).
- get_descriptor_set() Any¶
Return the Vulkan descriptor set for binding to a pipeline.
- get_descriptor_layout() Any¶
Return the descriptor set layout for pipeline creation.
- cleanup(device: Any) None¶
Destroy GPU resources.
- class simvx.graphics.materials.custom_shader.ShaderMaterialManager¶
Caches compiled pipelines by shader combination and manages hot-reload.
Tracks all registered ShaderMaterial instances and their compiled pipelines. Pipelines are cached by the shader source/path combination so that multiple objects sharing the same shaders reuse one pipeline.
Example::
manager = ShaderMaterialManager() pipeline, layout = manager.get_or_create_pipeline( material, device, physical_device, render_pass, extent, ssbo_layout, )Initialization
- register_material(material: simvx.graphics.materials.custom_shader.ShaderMaterial) None¶
Track a ShaderMaterial for hot-reload monitoring.
- get_or_create_pipeline(material: simvx.graphics.materials.custom_shader.ShaderMaterial, device: Any, physical_device: Any, render_pass: Any, extent: tuple[int, int], ssbo_layout: Any, texture_layout: Any | None = None, shader_dir: pathlib.Path | None = None) tuple[Any, Any]¶
Get a cached pipeline for this material, or compile and create one.
Args: material: The ShaderMaterial to get/create a pipeline for. device: Vulkan logical device. physical_device: Vulkan physical device. render_pass: Vulkan render pass. extent: Swapchain extent (width, height). ssbo_layout: Descriptor set layout for SSBOs (set 0). texture_layout: Optional texture descriptor layout. shader_dir: Base directory for shader file resolution.
Returns: Tuple of (VkPipeline, VkPipelineLayout).
- get_uniform_buffer(material: simvx.graphics.materials.custom_shader.ShaderMaterial) simvx.graphics.materials.custom_shader.UniformBuffer | None¶
Get the UniformBuffer associated with a material, if any.
- update_uniforms(material: simvx.graphics.materials.custom_shader.ShaderMaterial, device: Any) None¶
Upload current uniform values for a material to its GPU buffer.
- check_hot_reload(device: Any, physical_device: Any, render_pass: Any, extent: tuple[int, int], ssbo_layout: Any, texture_layout: Any | None = None, shader_dir: pathlib.Path | None = None) list[simvx.graphics.materials.custom_shader.ShaderMaterial]¶
Check all registered materials for source file changes and recompile.
Returns a list of materials that were recompiled.
- cleanup(device: Any) None¶
Destroy all cached pipelines, uniform buffers, and shader modules.