A single premium furniture model from providers like Designconnected, 3dsky, or CGTrader can contain 500,000 to 2,000,000 polygons. A fully furnished residential interior requires 30–60 individual furniture pieces. At those counts, you are looking at 15–80 million polygons from furniture alone — before adding architectural geometry, vegetation, or decorative objects. Your viewport becomes unusable above 20 million visible polygons on most workstations, and render memory consumption climbs to levels that crash scenes on 64 GB systems.
V-Ray proxies solve this by storing high-resolution geometry externally in .vrmesh files that are loaded only at render time. In the viewport, each proxy displays as a lightweight bounding box, point cloud, or simplified preview mesh. The production benefits are transformative: viewport navigation stays responsive at 30+ FPS regardless of furniture complexity, RAM consumption drops 60–80% during scene editing, and render-time memory is managed through V-Ray's on-demand geometry loading system.
The challenge is that converting a large furniture library to proxies is tedious when done manually. The workflow below automates the entire pipeline — from batch conversion to material preservation to library organization.
Batch Proxy Conversion Script
This MaxScript converts selected objects to V-Ray proxies in batch. For each object, it exports the high-resolution mesh to a .vrmesh file, replaces the original object with a VRayProxy reference, and preserves all material assignments. This is the core automation that transforms a manual 5-minute-per-object process into a 2-second-per-object batch operation.
MaxScript-- RenderVault: Batch V-Ray Proxy Converter with Material Preservation
-- Converts selected objects to .vrmesh proxies while maintaining materials
(
-- CONFIGURATION
local proxyOutputDir = @"E:\Libraries\VRayProxies\Furniture\"
local previewType = 2 -- 0=None, 1=BBox, 2=Preview, 3=Full mesh
local previewFaces = 5000 -- Face count for preview mesh
local exportAnimation = false
-- Validate output directory
if not doesDirectoryExist proxyOutputDir do
makeDir proxyOutputDir all:true
local selectedObjects = for obj in selection where superClassOf obj == GeometryClass collect obj
if selectedObjects.count == 0 do (
messageBox "Select geometry objects to convert."
return undefined
)
format "Converting % objects to V-Ray proxies...\n" selectedObjects.count
local successCount = 0
local failCount = 0
for obj in selectedObjects do (
-- Store original properties
local origName = obj.name
local origMat = obj.material
local origTransform = obj.transform
local origLayer = obj.layer
local origParent = obj.parent
-- Generate clean filename
local cleanName = substituteString origName " " "_"
cleanName = substituteString cleanName ":" "_"
local vrmeshPath = proxyOutputDir + cleanName + ".vrmesh"
try (
-- Export to .vrmesh
select obj
vrayMeshExport vrmeshPath \
selectedMeshes:#selection \
autoCreateProxies:false \
exportAnimation:exportAnimation \
facesPerVoxel:20000
-- Create VRayProxy replacement
local proxyObj = VRayProxy()
proxyObj.name = origName + "_proxy"
proxyObj.filename = vrmeshPath
proxyObj.display = previewType
proxyObj.preview_faces = previewFaces
proxyObj.transform = origTransform
-- Restore material
if origMat != undefined do
proxyObj.material = origMat
-- Restore hierarchy
if origLayer != undefined do
origLayer.addNode proxyObj
if origParent != undefined do
proxyObj.parent = origParent
-- Delete original high-poly object
delete obj
successCount += 1
format " ✓ % → %\n" origName (filenameFromPath vrmeshPath)
) catch (
failCount += 1
format " ✗ FAILED: % — %\n" origName (getCurrentException())
)
)
format "\n=== Conversion Complete ===\n"
format "Success: % | Failed: %\n" successCount failCount
format "Proxy directory: %\n" proxyOutputDir
)
Key configuration notes: previewFaces at 5000 provides a visually recognizable preview in the viewport without significant performance cost. For furniture with important silhouette details (chairs, decorative objects), increase to 10,000–15,000. For simple box-like items (cabinets, appliances), reduce to 2,000–3,000. The facesPerVoxel parameter (20,000) controls how V-Ray partitions the proxy geometry for on-demand loading — lower values reduce peak RAM at the cost of slightly slower render initialization.
Material Preservation: The Critical Detail
The most common problem with proxy workflows is material loss. When you export geometry to .vrmesh and reimport it as a proxy, the material assignment is not stored inside the .vrmesh file — it must be maintained separately. The batch script above preserves materials by transferring the original object's material to the proxy node. However, there are edge cases that require additional handling:
Multi-Sub Materials
Objects with Multi/Sub-Object materials require that the material ID assignments in the original mesh are preserved in the .vrmesh export. V-Ray handles this automatically, but verify by spot-checking a converted proxy: render a close-up of a multi-material furniture piece (e.g., a chair with different materials for fabric, wood, and metal) and compare against the original. If materials are scrambled, the source mesh likely has inconsistent material ID assignments that need cleaning before proxy conversion.
Material Library Sidecar File
For shared proxy libraries used across multiple projects, create a sidecar material library (.mat) alongside each .vrmesh file. This script exports the material assignment data:
MaxScript-- RenderVault: Proxy Material Library Exporter
-- Saves material assignments alongside .vrmesh files for portable libraries
(
local proxyDir = @"E:\Libraries\VRayProxies\Furniture\"
for obj in objects where classof obj == VRayProxy do (
if obj.material == undefined do continue
local vrmeshName = getFilenameFile obj.filename
local matLibPath = proxyDir + vrmeshName + ".mat"
-- Create material library with this object's material
local tempLib = materialLibrary()
append tempLib obj.material
saveTempMaterialLibrary tempLib matLibPath
deleteFile (matLibPath + ".bak") -- clean backup
format " Saved: % → %\n" obj.name (filenameFromPath matLibPath)
)
format "Material libraries exported alongside .vrmesh files.\n"
)
LOD System for Mixed-Fidelity Workflows
Not every furniture piece needs full-resolution geometry at render time. Background furniture — items more than 5 meters from the camera, partially occluded by foreground objects, or visible only in reflections — can use simplified geometry without visible quality loss. A proper LOD (Level of Detail) system within your proxy library can reduce render memory by an additional 30–40% on top of the base proxy savings.
Three-Tier LOD Standard
- LOD0 (Full): Original geometry, all bevels, stitching detail, hardware. For hero furniture within 3 meters of camera. 100% of original poly count.
- LOD1 (Medium): ProOptimizer at 30% reduction. Remove stitching, micro-bevels, internal geometry not visible from camera angle. For mid-ground furniture at 3–8 meters.
- LOD2 (Low): ProOptimizer at 70% reduction. Simplified silhouette only. For background fills and reflection-only visibility. 30% of original poly count.
Automate LOD generation with this MaxScript that applies ProOptimizer to selected objects at configurable reduction levels:
MaxScript-- RenderVault: Automatic LOD Generator for Proxy Library
-- Creates LOD variants of selected furniture using ProOptimizer
(
local lodLevels = #(
#("LOD0", 0.0), -- No reduction (original)
#("LOD1", 0.30), -- 30% vertex reduction
#("LOD2", 0.70) -- 70% vertex reduction
)
local outputDir = @"E:\Libraries\VRayProxies\Furniture\"
for obj in selection where superClassOf obj == GeometryClass do (
local baseName = obj.name
for lod in lodLevels do (
local lodName = lod[1]
local reduction = lod[2]
if reduction == 0.0 then (
-- LOD0: export original as-is
format " % [%] — original (no reduction)\n" baseName lodName
) else (
-- Create copy for optimization
local lodCopy = copy obj
lodCopy.name = baseName + "_" + lodName
-- Apply ProOptimizer
local proOpt = ProOptimizer()
addModifier lodCopy proOpt
proOpt.OptLevel = reduction * 100.0
proOpt.Calculate = true
-- Collapse to editable mesh
collapseStack lodCopy
local origVerts = (getNumVerts obj)
local lodVerts = (getNumVerts lodCopy)
format " % [%] — % → % verts (-%)\n" baseName lodName \
origVerts lodVerts \
(((origVerts - lodVerts) as float / origVerts * 100) as integer)
-- Export LOD .vrmesh
select lodCopy
local lodPath = outputDir + baseName + "_" + lodName + ".vrmesh"
vrayMeshExport lodPath selectedMeshes:#selection autoCreateProxies:false
delete lodCopy
)
)
)
format "\nLOD generation complete.\n"
)
Library Organization and Naming Convention
A proxy library is only useful if you can find what you need quickly. After converting hundreds of furniture models, organization becomes critical. We use this directory structure across all studio projects:
Directory StructureVRayProxies/
├── Furniture/
│ ├── Seating/
│ │ ├── Chair_Eames_LOD0.vrmesh
│ │ ├── Chair_Eames_LOD0.mat
│ │ ├── Chair_Eames_LOD1.vrmesh
│ │ ├── Chair_Eames_LOD2.vrmesh
│ │ └── ...
│ ├── Tables/
│ ├── Storage/
│ ├── Lighting_Fixtures/
│ └── Decorative/
├── Vegetation/
│ ├── Trees/
│ ├── Shrubs/
│ └── GroundCover/
└── _Thumbnails/
├── Chair_Eames.jpg
└── ...
The _Thumbnails folder contains 256×256 pixel renders of each proxy for quick visual browsing. Generate these automatically during the batch conversion process by rendering a quick clay-material turntable frame for each object before proxy conversion.
Key Takeaways
A properly automated V-Ray proxy workflow transforms furniture library management from a constant friction point into a streamlined, scalable system. Batch conversion with material preservation handles the initial setup, LOD generation provides memory optimization for complex scenes, and consistent organization makes the library accessible across projects and team members. The MaxScript tools in this article can convert and organize a 200-piece furniture library in under 30 minutes — versus the 15–20 hours it would take to process the same library manually.
Managing an exceptionally large proxy library? Tell us about your setup — we feature reader library architectures in our studio spotlight series.