- {activeRightTab === "Scene" ? (
- <>
-
- >
- ) : activeRightTab === "Transform" ? (
-
-
-
- {!selectedObject || !selectedObject.transformProps ? (
-
-
- Select an object to edit its transform
-
- ) : (
- <>
- {/* Position */}
-
-
Position
- {['x', 'y', 'z'].map((axis, i) => (
-
- {axis}
- {
- const newPos = [...selectedObject.transformProps!.position] as [number, number, number];
- newPos[i] = parseFloat(e.target.value);
- updateObjectTransform(selectedObject.id, { position: newPos });
- }}
- className="flex-1 bg-zinc-800 border-none rounded py-1 px-2 text-[10px] text-zinc-300"
- />
-
- ))}
-
-
- {/* Rotation */}
-
-
Rotation
- {['x', 'y', 'z'].map((axis, i) => (
-
- {axis}
- {
- const newRot = [...selectedObject.transformProps!.rotation] as [number, number, number];
- newRot[i] = parseFloat(e.target.value);
- updateObjectTransform(selectedObject.id, { rotation: newRot });
- }}
- className="flex-1 bg-zinc-800 border-none rounded py-1 px-2 text-[10px] text-zinc-300"
- />
-
- ))}
-
-
- {/* Scale */}
-
-
Scale
- {['x', 'y', 'z'].map((axis, i) => (
-
- {axis}
- {
- const newScale = [...selectedObject.transformProps!.scale] as [number, number, number];
- newScale[i] = parseFloat(e.target.value);
- updateObjectTransform(selectedObject.id, { scale: newScale });
- }}
- className="flex-1 bg-zinc-800 border-none rounded py-1 px-2 text-[10px] text-zinc-300"
- />
-
- ))}
-
- >
- )}
-
-
-
Position and Orientation
-
-
-
- {/* Mode Toggle */}
-
-
-
-
-
- {/* Spherical Controls */}
- {cameraProps.cameraMode === "spherical" && (
-
-
-
- Distance
- {cameraProps.spherical.distance.toFixed(3)} m
-
-
{
- const dist = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, spherical: { ...prev.spherical, distance: dist } }));
- // Update camera position based on spherical
- if (orbitControlsRef.current) {
- const controls = orbitControlsRef.current;
- const phi = (90 - cameraProps.spherical.inclination) * (Math.PI / 180);
- const theta = cameraProps.spherical.azimuth * (Math.PI / 180);
- const x = dist * Math.sin(phi) * Math.cos(theta) + cameraProps.target[0];
- const y = dist * Math.cos(phi) + cameraProps.target[1];
- const z = dist * Math.sin(phi) * Math.sin(theta) + cameraProps.target[2];
- controls.object.position.set(x, y, z);
- controls.update();
- }
- }}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Azimuth
- {cameraProps.spherical.azimuth.toFixed(3)} °
-
-
{
- const az = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, spherical: { ...prev.spherical, azimuth: az } }));
- if (orbitControlsRef.current) {
- const controls = orbitControlsRef.current;
- const phi = (90 - cameraProps.spherical.inclination) * (Math.PI / 180);
- const theta = az * (Math.PI / 180);
- const x = cameraProps.spherical.distance * Math.sin(phi) * Math.cos(theta) + cameraProps.target[0];
- const y = cameraProps.spherical.distance * Math.cos(phi) + cameraProps.target[1];
- const z = cameraProps.spherical.distance * Math.sin(phi) * Math.sin(theta) + cameraProps.target[2];
- controls.object.position.set(x, y, z);
- controls.update();
- }
- }}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Inclination
- {cameraProps.spherical.inclination.toFixed(3)} °
-
-
{
- const inc = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, spherical: { ...prev.spherical, inclination: inc } }));
- if (orbitControlsRef.current) {
- const controls = orbitControlsRef.current;
- const phi = (90 - inc) * (Math.PI / 180);
- const theta = cameraProps.spherical.azimuth * (Math.PI / 180);
- const x = cameraProps.spherical.distance * Math.sin(phi) * Math.cos(theta) + cameraProps.target[0];
- const y = cameraProps.spherical.distance * Math.cos(phi) + cameraProps.target[1];
- const z = cameraProps.spherical.distance * Math.sin(phi) * Math.sin(theta) + cameraProps.target[2];
- controls.object.position.set(x, y, z);
- controls.update();
- }
- }}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- )}
-
- {/* Absolute Position Controls */}
- {cameraProps.cameraMode === "absolute" && (
-
-
Position (Absolute)
-
- {["x", "y", "z"].map((axis, i) => (
-
- {axis}
- {
- const newPos = [...cameraProps.position] as [number, number, number];
- newPos[i] = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, position: newPos }));
- if (orbitControlsRef.current) {
- orbitControlsRef.current.object.position.set(...newPos);
- orbitControlsRef.current.update();
- }
- }}
- className="w-full bg-zinc-900 border border-zinc-800 rounded px-1 py-0.5 text-[10px] text-zinc-300"
- />
-
- ))}
-
-
- )}
-
- {/* Target Controls */}
-
-
Target
-
- {["x", "y", "z"].map((axis, i) => (
-
- {axis}
- {
- const newTarget = [...cameraProps.target] as [number, number, number];
- newTarget[i] = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, target: newTarget }));
- if (orbitControlsRef.current) {
- orbitControlsRef.current.target.set(...newTarget);
- orbitControlsRef.current.update();
- }
- }}
- className="w-full bg-zinc-900 border border-zinc-800 rounded px-1 py-0.5 text-[10px] text-zinc-300"
- />
-
- ))}
-
-
-
- {/* Pivot Controls */}
-
-
Pivot
-
- {["x", "y", "z"].map((axis, i) => (
-
- {axis}
- {
- const newPivot = [...cameraProps.pivot] as [number, number, number];
- newPivot[i] = parseFloat(e.target.value);
- setCameraProps(prev => ({ ...prev, pivot: newPivot }));
- }}
- className="w-full bg-zinc-900 border border-zinc-800 rounded px-1 py-0.5 text-[10px] text-zinc-300"
- />
-
- ))}
-
-
-
- {/* Standard Views */}
-
-
Standard Views
-
- {["front", "back", "top", "bottom", "left", "right", "isometric"].map((view) => (
-
- ))}
-
-
-
-
-
- {/* Camera Type */}
-
-
-
-
-
- {/* Focal Length / FOV */}
- {!cameraProps.orthographic && (
- <>
-
-
- Focal Length
- {fovToFocalLength(cameraProps.fov).toFixed(1)} mm
-
-
setCameraProps(prev => ({ ...prev, fov: focalLengthToFov(parseInt(e.target.value)) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Field of View
- {cameraProps.fov.toFixed(1)}°
-
-
setCameraProps(prev => ({ ...prev, fov: parseInt(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
- >
- )}
-
- {/* Zoom */}
-
-
- Zoom Level
- {cameraProps.zoom.toFixed(2)}x
-
-
setCameraProps(prev => ({ ...prev, zoom: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Depth of Field Toggle */}
-
-
- Depth of Field
- Enable bokeh effect
-
-
-
-
- {/* DOF Settings */}
- {cameraProps.depthOfField.enabled && (
-
-
-
- Focus Distance
- {cameraProps.depthOfField.focusDistance.toFixed(3)}
-
-
setCameraProps(prev => ({ ...prev, depthOfField: { ...prev.depthOfField, focusDistance: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Bokeh Scale
- {cameraProps.depthOfField.bokehScale.toFixed(1)}
-
-
setCameraProps(prev => ({ ...prev, depthOfField: { ...prev.depthOfField, bokehScale: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- )}
-
- {/* Post Processing Section */}
-
-
- {/* Bloom Toggle */}
-
-
- Bloom
- Add glow to highlights
-
-
-
-
- {/* Bloom Settings */}
- {cameraProps.bloom.enabled && (
-
-
-
- Intensity
- {cameraProps.bloom.intensity.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, bloom: { ...prev.bloom, intensity: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Threshold
- {cameraProps.bloom.luminanceThreshold.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, bloom: { ...prev.bloom, luminanceThreshold: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- )}
-
- {/* Vignette Toggle */}
-
-
- Vignette
- Darken image edges
-
-
-
-
- {/* Vignette Settings */}
- {cameraProps.vignette.enabled && (
-
-
-
- Darkness
- {cameraProps.vignette.darkness.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, vignette: { ...prev.vignette, darkness: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- )}
-
- {/* Color Grading Toggle */}
-
-
- Color Grading
- Adjust brightness & color
-
-
-
-
- {/* Color Grading Settings */}
- {cameraProps.colorGrading.enabled && (
-
-
-
- Brightness
- {cameraProps.colorGrading.brightness.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, colorGrading: { ...prev.colorGrading, brightness: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Contrast
- {cameraProps.colorGrading.contrast.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, colorGrading: { ...prev.colorGrading, contrast: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Saturation
- {cameraProps.colorGrading.saturation.toFixed(2)}
-
-
setCameraProps(prev => ({ ...prev, colorGrading: { ...prev.colorGrading, saturation: parseFloat(e.target.value) } }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- )}
-
- {/* Grid and Ground Options */}
-
-
-
- Ground Grid
- Show grid on floor
-
-
-
-
-
-
- Stay Above Ground
- Limit camera height
-
-
-
-
-
- {/* Auto Rotate */}
-
-
- Auto-Rotate
- Rotate around model
-
-
-
-
- {/* Camera Presets */}
-
-
-
Camera Presets
-
-
-
-
-
- {cameraPresets.map((preset) => (
-
-
-
- {preset.id !== 'default' && (
-
- )}
-
-
- ))}
-
-
-
-
-
-
-
-
-
Viewport Background
-
-
-
- {/* Background Type Toggle */}
-
-
-
-
-
- {/* Background Color & Image Selection */}
- {(backgroundType === "color" || backgroundType === "image") && (
-
-
-
-
Background Color
-
-
-
-
-
-
-
-
- Backplate Image
- {backgroundType === "image" && (
-
- )}
-
-
-
- {[
- { name: "Studio", url: "https://picsum.photos/seed/studio/1920/1080?blur=4" },
- { name: "Outdoor", url: "https://picsum.photos/seed/outdoor/1920/1080?blur=4" },
- { name: "Interior", url: "https://picsum.photos/seed/interior/1920/1080?blur=4" },
- { name: "Abstract", url: "https://picsum.photos/seed/abstract/1920/1080?blur=4" }
- ].map((plate) => (
-
- ))}
-
-
-
-
Custom Backplate URL
-
- {
- if (e.target.value) {
- setBackplateImage(e.target.value);
- setBackgroundType("image");
- }
- }}
- />
-
-
-
-
-
- )}
-
- {/* Environment Rotation Wheel */}
-
-
- Environment Rotation
- {envRotation}°
-
-
-
{
- const rect = e.currentTarget.getBoundingClientRect();
- const centerX = rect.left + rect.width / 2;
- const centerY = rect.top + rect.height / 2;
-
- const handleMouseMove = (moveEvent: MouseEvent) => {
- const angle = Math.atan2(moveEvent.clientY - centerY, moveEvent.clientX - centerX);
- let deg = angle * (180 / Math.PI) + 90;
- if (deg < 0) deg += 360;
- setEnvRotation(Math.round(deg));
- };
-
- const handleMouseUp = () => {
- window.removeEventListener('mousemove', handleMouseMove);
- window.removeEventListener('mouseup', handleMouseUp);
- };
-
- window.addEventListener('mousemove', handleMouseMove);
- window.addEventListener('mouseup', handleMouseUp);
- }}
- >
- {/* Degree markers */}
- {[0, 45, 90, 135, 180, 225, 270, 315].map(deg => (
-
- ))}
- {/* Pointer */}
-
-
-
-
-
setEnvRotation(parseInt(e.target.value))}
- className="w-full accent-blue-500 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer"
- />
-
- 0°
- 180°
- 360°
-
-
-
-
-
- {/* Grid Toggle */}
-
-
- Viewport Grid
- Show spatial reference
-
-
-
-
-
-
- {/* Light Intensity */}
-
-
- Intensity
- {lightProps.intensity.toFixed(2)}
-
-
setLightProps(prev => ({ ...prev, intensity: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Light Color */}
-
-
- Light Color
- setLightProps(prev => ({ ...prev, color: e.target.value }))}
- className="w-6 h-6 rounded border border-zinc-700 bg-transparent cursor-pointer"
- />
-
-
-
- {/* Advanced Lighting Controls */}
-
-
-
- Shadow Advanced
-
-
-
- Shadow Bias
- {lightProps.shadowBias.toFixed(4)}
-
-
setLightProps(prev => ({ ...prev, shadowBias: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Shadow Radius
- {lightProps.shadowRadius.toFixed(1)}
-
-
setLightProps(prev => ({ ...prev, shadowRadius: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- {/* Additional Lights Section */}
-
-
-
Additional Lights
-
-
-
-
-
-
-
- {/* Additional Lights List */}
-
- {additionalLights.map((light, index) => (
-
-
-
-
- {light.type} Light {index + 1}
-
-
-
-
-
-
-
- Intensity
- {light.intensity.toFixed(1)}
-
-
setAdditionalLights(prev => prev.map(l => l.id === light.id ? { ...l, intensity: parseFloat(e.target.value) } : l))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
- Color
- setAdditionalLights(prev => prev.map(l => l.id === light.id ? { ...l, color: e.target.value } : l))}
- className="w-4 h-4 rounded border border-zinc-700 bg-transparent cursor-pointer"
- />
-
-
-
-
-
-
Position (X, Y, Z)
-
- {[0, 1, 2].map(i => (
- {
- const newPos = [...light.position] as [number, number, number];
- newPos[i] = parseFloat(e.target.value);
- setAdditionalLights(prev => prev.map(l => l.id === light.id ? { ...l, position: newPos } : l));
- }}
- className="bg-zinc-900 border border-zinc-800 rounded px-1.5 py-1 text-[10px] text-zinc-300"
- />
- ))}
-
-
-
- ))}
- {additionalLights.length === 0 && (
-
- No additional lights added
-
- )}
-
-
-
-
- {/* Ground Shadow Toggle */}
-
-
- Ground Shadow
- Enable soft shadows
-
-
-
-
- {/* Shadow Controls */}
- {groundProps.showShadow && (
- <>
-
-
- Shadow Intensity
- {groundProps.shadowIntensity.toFixed(2)}
-
-
setGroundProps(prev => ({ ...prev, shadowIntensity: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Shadow Softness
- {groundProps.shadowSoftness.toFixed(2)}
-
-
setGroundProps(prev => ({ ...prev, shadowSoftness: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Shadow Length
- {groundProps.shadowLength.toFixed(1)}
-
-
setGroundProps(prev => ({ ...prev, shadowLength: parseFloat(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
-
-
- Shadow Rotation
- {groundProps.shadowRotation}°
-
-
-
-
-
-
setGroundProps(prev => ({ ...prev, shadowRotation: parseInt(e.target.value) }))}
- className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10"
- />
-
-
-
-
setGroundProps(prev => ({ ...prev, shadowRotation: parseInt(e.target.value) }))}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
- 0°
- 180°
- 360°
-
-
-
-
- >
- )}
-
-
-
Environment Presets
-
-
-
-
-
-
- {customHdri && (
-
- )}
-
- {[
- { id: 'studio', name: 'Studio', desc: 'Clean, neutral lighting' },
- { id: 'apartment', name: 'Apartment', desc: 'Indoor home lighting' },
- { id: 'city', name: 'City', desc: 'Urban outdoor lighting' },
- { id: 'dawn', name: 'Dawn', desc: 'Soft morning light' },
- { id: 'forest', name: 'Forest', desc: 'Natural outdoor light' },
- { id: 'lobby', name: 'Lobby', desc: 'Commercial indoor light' },
- { id: 'night', name: 'Night', desc: 'Low light, dark environment' },
- { id: 'park', name: 'Park', desc: 'Bright outdoor light' },
- { id: 'sunset', name: 'Sunset', desc: 'Warm evening light' },
- { id: 'warehouse', name: 'Warehouse', desc: 'Industrial lighting' },
- ].map((preset) => (
-
- ))}
-
-
-
-
Material Properties
-
-
-
- {!selectedObject || (selectedObject.type !== 'mesh' && selectedObject.type !== 'model') ? (
-
-
-
Select a model or mesh to edit its material properties
-
- ) : (
- <>
-
- {selectedObject.name}
- {selectedObject.type === 'model' ? "Bulk Editing Model" : "Mesh Editor"}
-
-
- {/* Fill Settings */}
-
-
-
Mesh Fill
-
-
-
- {selectedObject.fillProps?.enabled && (
- <>
-
-
-
-
-
-
-
- Height
- {Math.round(selectedObject.fillProps.height * 100)}%
-
-
{
- const newObjects = sceneObjects.map(obj =>
- obj.id === selectedObject.id ? { ...obj, fillProps: { ...obj.fillProps!, height: parseFloat(e.target.value) } } : obj
- );
- setSceneObjects(newObjects);
- }}
- onMouseUp={() => pushToHistory(sceneObjects)}
- className="w-full accent-primary"
- />
-
-
-
-
Fill Color
-
-
-
{
- const newObjects = sceneObjects.map(obj =>
- obj.id === selectedObject.id ? { ...obj, fillProps: { ...obj.fillProps!, color: e.target.value } } : obj
- );
- setSceneObjects(newObjects);
- }}
- onBlur={() => pushToHistory(sceneObjects)}
- className="opacity-0 w-5 h-5 cursor-pointer absolute right-0"
- />
-
-
- >
- )}
-
-
- {/* Color Picker */}
-
-
-
updateObjectMaterial(selectedObject.id, { color: e.target.value })}
- className="w-full h-8 bg-zinc-800 border-none rounded cursor-pointer"
- />
-
-
- {/* Texture Mapping */}
-
-
- Texture Map
- {selectedObject.materialProps?.map ? (
-
- ) : (
- None
- )}
-
-
-
textureInputRef.current?.click()}
- className={cn(
- "w-full h-24 rounded border-2 border-dashed flex flex-col items-center justify-center gap-2 cursor-pointer transition-all",
- selectedObject.materialProps?.map
- ? "border-blue-500/50 bg-blue-500/5 overflow-hidden"
- : "border-zinc-800 hover:border-zinc-700 bg-zinc-800/30"
- )}
- >
- {selectedObject.materialProps?.map ? (
-

- ) : (
- <>
-
-
Upload Texture
- >
- )}
-
-
-
-
- {/* UV Scale & Mapping */}
-
-
-
-
-
-
-
- {/* UV Projection Dropdown */}
-
- UV Projection
-
-
-
- {/* UV Offset */}
-
-
- {/* UV Scale / Tiling */}
-
-
- {/* UV Rotation */}
-
-
- Rotation
- {(selectedObject.materialProps?.uvRotation ?? 0).toFixed(0)}°
-
-
updateObjectMaterial(selectedObject.id, { uvRotation: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500" />
-
-
-
- {/* Roughness */}
-
-
- Roughness
- {(selectedObject.materialProps?.roughness ?? 0.5).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { roughness: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Metalness */}
-
-
- Metalness
- {(selectedObject.materialProps?.metalness ?? 0.5).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { metalness: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Clearcoat */}
-
-
- Clearcoat
- {(selectedObject.materialProps?.clearcoat ?? 0).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { clearcoat: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Transmission */}
-
-
- Transmission
- {(selectedObject.materialProps?.transmission ?? 0).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { transmission: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* IOR */}
-
-
- Index of Refraction
- {(selectedObject.materialProps?.ior ?? 1.5).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { ior: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Thickness */}
-
-
- Thickness
- {(selectedObject.materialProps?.thickness ?? 0).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { thickness: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Sheen */}
-
-
- Sheen
- {(selectedObject.materialProps?.sheen ?? 0).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { sheen: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Opacity */}
-
-
- Opacity
- {(selectedObject.materialProps?.opacity ?? 1).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { opacity: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Specular Intensity */}
-
-
- Specular Intensity
- {(selectedObject.materialProps?.specularIntensity ?? 1).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { specularIntensity: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Emissive */}
-
-
-
updateObjectMaterial(selectedObject.id, { emissive: e.target.value })}
- className="w-full h-8 bg-zinc-800 border-none rounded cursor-pointer"
- />
-
-
-
-
- Emissive Intensity
- {(selectedObject.materialProps?.emissiveIntensity ?? 0).toFixed(2)}
-
-
updateObjectMaterial(selectedObject.id, { emissiveIntensity: parseFloat(e.target.value) })}
- className="w-full h-1 bg-zinc-800 rounded-lg appearance-none cursor-pointer accent-blue-500"
- />
-
-
- {/* Advanced Maps */}
-
-
Advanced Maps
- {/* Normal Map */}
-
-
- Normal Map
- {selectedObject.materialProps?.normalMap && (
-
- )}
-
-
normalInputRef.current?.click()}
- className={cn(
- "w-full h-12 rounded border border-dashed flex items-center justify-center gap-2 cursor-pointer transition-all",
- selectedObject.materialProps?.normalMap ? "border-blue-500/50 bg-blue-500/5" : "border-zinc-800 hover:border-zinc-700 bg-zinc-800/30"
- )}
- >
- {selectedObject.materialProps?.normalMap ? "Normal Map Loaded" : "Upload Normal Map"}
-
-
handleTextureUpload(e, 'normalMap')} accept="image/*" className="hidden" />
-
-
- {/* Specular Map */}
-
-
- Specular Map
- {selectedObject.materialProps?.specularMap && (
-
- )}
-
-
specularInputRef.current?.click()}
- className={cn(
- "w-full h-12 rounded border border-dashed flex items-center justify-center gap-2 cursor-pointer transition-all",
- selectedObject.materialProps?.specularMap ? "border-blue-500/50 bg-blue-500/5" : "border-zinc-800 hover:border-zinc-700 bg-zinc-800/30"
- )}
- >
- {selectedObject.materialProps?.specularMap ? "Specular Map Loaded" : "Upload Specular Map"}
-
-
handleTextureUpload(e, 'specularMap')} accept="image/*" className="hidden" />
-
-
- {/* Alpha Map */}
-
-
- Alpha Map
- {selectedObject.materialProps?.alphaMap && (
-
- )}
-
-
alphaInputRef.current?.click()}
- className={cn(
- "w-full h-12 rounded border border-dashed flex items-center justify-center gap-2 cursor-pointer transition-all",
- selectedObject.materialProps?.alphaMap ? "border-blue-500/50 bg-blue-500/5" : "border-zinc-800 hover:border-zinc-700 bg-zinc-800/30"
- )}
- >
- {selectedObject.materialProps?.alphaMap ? "Alpha Map Loaded" : "Upload Alpha Map"}
-
-
handleTextureUpload(e, 'alphaMap')} accept="image/*" className="hidden" />
-
-
-
-
-
-
- >
- )}
-