Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
Vulkan Schnee Blender Exporter Plugin

Blender plugin that extends the glTF 2.0 exporter with two custom extensions for Vulkan Schnee Engine data.

File: AirHockey/Blender/pythonScripts/ExporterPlugin/

Extensions

The exporter adds two glTF extensions:

VULKAN_SCHNEE_engine_properties

Per-object metadata attached to glTF nodes. Contains mesh behavior, lighting settings, and lightmap configuration.

VULKAN_SCHNEE_materials

Per-material shader configuration attached to glTF materials. Contains shader type, parameters, and PBR texture/factor data.

Installation

Install as a standard Blender addon via Edit > Preferences > Add-ons > Install.... Requires the io_scene_gltf2 addon (Blender's built-in glTF exporter).

Export Options

The plugin adds a "Vulkan Schnee Engine" panel to the glTF export dialog:

Option Description
Export Engine Properties Enables VULKAN_SCHNEE_engine_properties and VULKAN_SCHNEE_materials extensions. Default: enabled.
Validate Properties Runs pre-export validation and logs issues to console. Default: enabled.
Copy Baked Lightmaps Copies lightmaps/ folder from .blend directory to export directory. Default: disabled.

VULKAN_SCHNEE_engine_properties Extension

Exported for each mesh object. Reads properties from the editor plugin's vulkan_schnee_properties object attribute.

JSON Structure

{
"version": "1.0.0",
"meshProperties": {
"isStatic": false,
"collisionEnabled": true
},
"lightingProperties": {
"castShadows": true,
"receiveShadows": true,
"hasLightmaps": false
},
"lightmapProperties": {
"lightmapPath": "lightmaps/object_lightmap.hdr",
"lightmapUvIndex": 1,
"lightmapResolution": 1024,
"lightOnly": false
},
"metadata": {
"exportedFromBlender": true,
"blenderObjectName": "Cube",
"exportTimestamp": 1
}
}

Fields

meshProperties:

  • isStatic (bool) - Object does not move. Engine can optimize draw calls.
  • collisionEnabled (bool) - Object has physics collision.

lightingProperties:

  • castShadows (bool) - Object casts shadows.
  • receiveShadows (bool) - Object receives shadows.
  • hasLightmaps (bool) - Object has baked lightmap texture.

lightmapProperties (only present if hasLightmaps is true):

  • lightmapPath (string) - Path to lightmap image relative to glTF file.
  • lightmapUvIndex (int) - UV attribute index for lightmap coordinates (0-7). Typically 1 for TEXCOORD_1.
  • lightmapResolution (int) - Lightmap texture resolution (e.g., 512, 1024).
  • lightOnly (bool) - Lightmap contains only lighting (no albedo baked in).

Legacy Property Fallback

If vulkan_schnee_properties does not exist, the exporter checks for legacy custom properties:

  • HasLightmapslightingProperties.hasLightmaps
  • LightMapPathlightmapProperties.lightmapPath
  • LightMapUvIndexlightmapProperties.lightmapUvIndex

Materials without properties get a basic metadata-only extension.

VULKAN_SCHNEE_materials Extension

Exported for each material. Reads shader node data from Vulkan Schnee shader nodes in the material's node tree.

File: AirHockey/Blender/pythonScripts/ExporterPlugin/MaterialExtension.py

JSON Structure

{
"shaderType": "movableDiffuseShader",
"shaderParameters": {
"Base Color": {
"type": "connected",
"socketType": "RGBA"
},
"Normal Map": {
"type": "value",
"value": [0.5, 0.5, 1.0, 1.0],
"socketType": "RGBA"
},
"Roughness Factor": {
"type": "value",
"value": 0.8,
"socketType": "VALUE"
}
},
"nodeProperties": {
"sh_scale": 0.15,
"ambient_term": 0.1,
"debug_mode": 0,
"tone_mapping": "REINHARD"
},
"pbrFactors": {
"base_color_factor": [1.0, 1.0, 1.0, 1.0],
"roughness_factor": 0.8,
"metallic_factor": 0.0,
"normal_scale": 1.0,
"emissive_factor": [0.0, 0.0, 0.0]
}
}

Shader Types

Shader types correspond to Vulkan Schnee shader nodes defined in the editor plugin:

Shader Type Description Debug Modes Tone Mapping
diffuseFlatColor Solid color None None
diffuseShader Basic texture None None
movableDiffuseShader Full PBR + SH lighting 0-5 Reinhard/ACES
normalsShader Normal visualization Fixed (1) None
staticLightmap Baked lightmap (UV2) 0-2, 6 Reinhard/ACES
l0Shader SH L0 only (ambient) Fixed (3) None
l1Shader SH L1 only (directional) Fixed (4) None
l2Shader SH L2 only (quadratic) Fixed (5) None
dynamicTextures Full PBR + SH (ACES) 0-5 ACES

Debug Modes:

  • 0 - Normal rendering with tone mapping
  • 1 - Normals as RGB (normal * 0.5 + 0.5)
  • 2 - Raw SH values without tone mapping
  • 3 - L0 term only (ambient)
  • 4 - L1 terms only (directional)
  • 5 - L2 terms only (quadratic)
  • 6 - Lightmap UV coordinates

PBR Texture Export

The exporter automatically maps Vulkan Schnee shader node inputs to standard glTF PBR fields:

Texture Mappings:

VS Input Socket glTF Field glTF UV Attribute
Base Color pbrMetallicRoughness.baseColorTexture TEXCOORD_0
Roughness pbrMetallicRoughness.metallicRoughnessTexture TEXCOORD_0
Metallic (same as Roughness) TEXCOORD_0
Normal Map normalTexture TEXCOORD_0
Emissive emissiveTexture TEXCOORD_0
Lightmap Texture (stored in extension only) TEXCOORD_1

Factor Mappings:

VS Input Socket glTF Field
Base Color (unconnected) pbrMetallicRoughness.baseColorFactor
Roughness Factor pbrMetallicRoughness.roughnessFactor
Metallic Factor pbrMetallicRoughness.metallicFactor
Normal Scale normalTexture.scale
Emissive Factor emissiveFactor

glTF requires metallic and roughness in a single texture (green=roughness, blue=metallic). The exporter uses the roughness texture if both are connected. Separate metallic textures generate a warning.

Node Discovery

The exporter searches the material's node tree for Vulkan Schnee shader nodes:

  1. Custom nodes with bl_idname starting with VulkanSchneeShader
  2. Node groups with a shader_type custom property

If multiple nodes exist, the first is used. Materials without VS nodes get a default diffuseFlatColor shader with "defaulted": true in metadata.

Validation

When "Validate Properties" is enabled, the exporter runs pre-export checks:

Object Validation:

  • Lightmaps enabled but no lightmapPath specified
  • Invalid lightmapUvIndex (not 0-7)

Material Validation:

  • Counts materials with Vulkan Schnee shaders
  • Logs shader types to console

Validation warnings print to the Blender system console (Window > Toggle System Console on Windows).

Implementation Details

Export Hooks

The plugin implements the glTF2ExportUserExtension interface:

Hook Purpose
gather_gltf_extensions_hook() Registers extension names in extensionsUsed
gather_node_hook() Exports VULKAN_SCHNEE_engine_properties per object
gather_material_hook() Exports VULKAN_SCHNEE_materials per material
pre_export_hook() Validates scene and logs statistics
post_export_hook() Copies lightmap files to export directory

Lightmap Copying

When "Copy Baked Lightmaps" is enabled:

  1. Looks for lightmaps/ folder next to the .blend file
  2. Copies entire folder to export directory
  3. Uses shutil.copytree() with dirs_exist_ok=True (overwrites existing)

Engine Import

The engine reads these extensions in GltfLoader.cpp:

VULKAN_SCHNEE_engine_properties:

GltfLoader::VulkanSchneeExtension extension(node.extensions["VULKAN_SCHNEE_engine_properties"]);
if (extension.hasLightmapProperties()) {
// Load lightmap texture using lightmapPath and lightmapUvIndex
}

VULKAN_SCHNEE_materials:

GltfLoader::MaterialExtensions matExt(material.extensions);
if (matExt.hasVulkanSchneeMaterialExtension()) {
std::string shaderType = matExt.vulkanSchneeMaterialExtension.shaderType;
// Select pipeline based on shaderType
}

See GltfLoader for complete import implementation.

Development Workflow

After modifying exporter code:

. ./repo-commands.ps1
zip-plugin

This rebuilds the plugin zip for distribution. Reload the plugin in Blender to test changes.

Related Documentation

  • Editor Plugin - Defines the shader nodes that the exporter reads
  • glTF Loader - Engine-side import of these extensions