Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -141,7 +141,6 @@ def build_lighting_prompt(azimuth: float, elevation: float) -> str:
|
|
| 141 |
Returns:
|
| 142 |
Formatted prompt string for the LoRA
|
| 143 |
"""
|
| 144 |
-
# Snap to nearest valid values
|
| 145 |
azimuth_snapped = snap_to_nearest(azimuth, list(AZIMUTH_MAP.keys()))
|
| 146 |
elevation_snapped = snap_to_nearest(elevation, list(ELEVATION_MAP.keys()))
|
| 147 |
|
|
@@ -246,9 +245,6 @@ class LightingControl3D(gr.HTML):
|
|
| 246 |
const scene = new THREE.Scene();
|
| 247 |
scene.background = new THREE.Color(0x1a1a1a);
|
| 248 |
|
| 249 |
-
// Fog for light ray effect
|
| 250 |
-
scene.fog = new THREE.FogExp2(0x1a1a1a, 0.05);
|
| 251 |
-
|
| 252 |
const camera = new THREE.PerspectiveCamera(50, wrapper.clientWidth / wrapper.clientHeight, 0.1, 1000);
|
| 253 |
camera.position.set(4.5, 3, 4.5);
|
| 254 |
camera.lookAt(0, 0.75, 0);
|
|
@@ -388,57 +384,58 @@ class LightingControl3D(gr.HTML):
|
|
| 388 |
updateTextureFromUrl(props.imageUrl);
|
| 389 |
}
|
| 390 |
|
| 391 |
-
// --- NEW LIGHT MODEL:
|
| 392 |
const lightGroup = new THREE.Group();
|
| 393 |
|
| 394 |
-
// 1.
|
| 395 |
-
const
|
| 396 |
-
const
|
| 397 |
color: 0x222222,
|
| 398 |
-
roughness: 0.
|
| 399 |
-
metalness: 0.
|
| 400 |
});
|
| 401 |
-
const
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
// 2. Torch Head (Flared Bezel)
|
| 407 |
-
const headGeo = new THREE.CylinderGeometry(0.12, 0.07, 0.2, 32);
|
| 408 |
-
const head = new THREE.Mesh(headGeo, torchMat);
|
| 409 |
-
head.rotation.x = Math.PI / 2;
|
| 410 |
-
head.position.z = -0.1;
|
| 411 |
-
lightGroup.add(head);
|
| 412 |
-
|
| 413 |
-
// 3. Bulb/Lens (Bright Emissive Circle)
|
| 414 |
-
const lensGeo = new THREE.CircleGeometry(0.1, 32);
|
| 415 |
-
const lensMat = new THREE.MeshStandardMaterial({
|
| 416 |
color: 0xffffff,
|
| 417 |
-
emissive: 0xffffff,
|
| 418 |
-
emissiveIntensity: 3.0
|
|
|
|
| 419 |
});
|
| 420 |
-
const
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
//
|
| 425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
const beamMat = new THREE.MeshBasicMaterial({
|
| 427 |
-
color:
|
| 428 |
transparent: true,
|
| 429 |
-
opacity: 0.
|
| 430 |
side: THREE.DoubleSide,
|
| 431 |
-
depthWrite: false,
|
| 432 |
-
blending: THREE.AdditiveBlending
|
| 433 |
});
|
|
|
|
| 434 |
const beam = new THREE.Mesh(beamGeo, beamMat);
|
| 435 |
-
beam.
|
| 436 |
-
beam
|
| 437 |
-
|
|
|
|
| 438 |
|
| 439 |
-
// Actual Light Source
|
| 440 |
-
const spotLight = new THREE.SpotLight(0xffffff,
|
| 441 |
-
spotLight.position.set(0, 0,
|
| 442 |
spotLight.castShadow = true;
|
| 443 |
spotLight.shadow.mapSize.width = 1024;
|
| 444 |
spotLight.shadow.mapSize.height = 1024;
|
|
@@ -494,7 +491,7 @@ class LightingControl3D(gr.HTML):
|
|
| 494 |
elevationHandle.userData.type = 'elevation';
|
| 495 |
scene.add(elevationHandle);
|
| 496 |
|
| 497 |
-
// --- REFRESH BUTTON
|
| 498 |
const refreshBtn = document.createElement('button');
|
| 499 |
refreshBtn.innerHTML = 'Reset View';
|
| 500 |
refreshBtn.style.position = 'absolute';
|
|
@@ -794,7 +791,7 @@ css = '''
|
|
| 794 |
#main-title h1 {font-size: 2.4em !important;}
|
| 795 |
'''
|
| 796 |
with gr.Blocks(css=css) as demo:
|
| 797 |
-
gr.Markdown("
|
| 798 |
gr.Markdown("Control lighting directions using the **3D viewport** or **sliders**. Use [Multi-Angle-Lighting](https://huggingface.co/dx8152/Qwen-Edit-2509-Multi-Angle-Lighting) LoRA for precise lighting control, paired with [Rapid-AIO-V19](https://huggingface.co/prithivMLmods/Qwen-Image-Edit-Rapid-AIO-V19).")
|
| 799 |
|
| 800 |
with gr.Row():
|
|
|
|
| 141 |
Returns:
|
| 142 |
Formatted prompt string for the LoRA
|
| 143 |
"""
|
|
|
|
| 144 |
azimuth_snapped = snap_to_nearest(azimuth, list(AZIMUTH_MAP.keys()))
|
| 145 |
elevation_snapped = snap_to_nearest(elevation, list(ELEVATION_MAP.keys()))
|
| 146 |
|
|
|
|
| 245 |
const scene = new THREE.Scene();
|
| 246 |
scene.background = new THREE.Color(0x1a1a1a);
|
| 247 |
|
|
|
|
|
|
|
|
|
|
| 248 |
const camera = new THREE.PerspectiveCamera(50, wrapper.clientWidth / wrapper.clientHeight, 0.1, 1000);
|
| 249 |
camera.position.set(4.5, 3, 4.5);
|
| 250 |
camera.lookAt(0, 0.75, 0);
|
|
|
|
| 384 |
updateTextureFromUrl(props.imageUrl);
|
| 385 |
}
|
| 386 |
|
| 387 |
+
// --- NEW LIGHT MODEL: STUDIO SQUARE WITH RAYS ---
|
| 388 |
const lightGroup = new THREE.Group();
|
| 389 |
|
| 390 |
+
// 1. Studio Housing (Black/Dark Grey)
|
| 391 |
+
const housingGeo = new THREE.BoxGeometry(0.7, 0.7, 0.2);
|
| 392 |
+
const housingMat = new THREE.MeshStandardMaterial({
|
| 393 |
color: 0x222222,
|
| 394 |
+
roughness: 0.3,
|
| 395 |
+
metalness: 0.7
|
| 396 |
});
|
| 397 |
+
const housing = new THREE.Mesh(housingGeo, housingMat);
|
| 398 |
+
|
| 399 |
+
// 2. Light Surface (Bright White Square)
|
| 400 |
+
const faceGeo = new THREE.PlaneGeometry(0.65, 0.65);
|
| 401 |
+
const faceMat = new THREE.MeshStandardMaterial({
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
color: 0xffffff,
|
| 403 |
+
emissive: 0xffffff,
|
| 404 |
+
emissiveIntensity: 3.0,
|
| 405 |
+
roughness: 0.0
|
| 406 |
});
|
| 407 |
+
const face = new THREE.Mesh(faceGeo, faceMat);
|
| 408 |
+
face.position.z = 0.105; // Slightly in front of housing
|
| 409 |
+
housing.add(face);
|
| 410 |
+
|
| 411 |
+
// 3. Light Rays (Volumetric Beam Effect)
|
| 412 |
+
// Using a transparent cylinder to simulate a beam
|
| 413 |
+
const beamHeight = 4.0;
|
| 414 |
+
// Cylinder top (0.5) is light size, bottom (1.2) is spread
|
| 415 |
+
const beamGeo = new THREE.CylinderGeometry(0.5, 1.2, beamHeight, 32, 1, true);
|
| 416 |
+
|
| 417 |
+
// Shift geometry so narrow end starts at 0 and extends positive
|
| 418 |
+
beamGeo.translate(0, -beamHeight / 2, 0);
|
| 419 |
+
beamGeo.rotateX(-Math.PI / 2); // Rotate to point along +Z axis
|
| 420 |
+
|
| 421 |
const beamMat = new THREE.MeshBasicMaterial({
|
| 422 |
+
color: 0xffffff,
|
| 423 |
transparent: true,
|
| 424 |
+
opacity: 0.06,
|
| 425 |
side: THREE.DoubleSide,
|
| 426 |
+
depthWrite: false,
|
| 427 |
+
blending: THREE.AdditiveBlending
|
| 428 |
});
|
| 429 |
+
|
| 430 |
const beam = new THREE.Mesh(beamGeo, beamMat);
|
| 431 |
+
beam.position.z = 0.12; // Start just in front of the face
|
| 432 |
+
housing.add(beam);
|
| 433 |
+
|
| 434 |
+
lightGroup.add(housing);
|
| 435 |
|
| 436 |
+
// Actual Light Source
|
| 437 |
+
const spotLight = new THREE.SpotLight(0xffffff, 15, 20, Math.PI / 3, 0.5, 1);
|
| 438 |
+
spotLight.position.set(0, 0, 0.1);
|
| 439 |
spotLight.castShadow = true;
|
| 440 |
spotLight.shadow.mapSize.width = 1024;
|
| 441 |
spotLight.shadow.mapSize.height = 1024;
|
|
|
|
| 491 |
elevationHandle.userData.type = 'elevation';
|
| 492 |
scene.add(elevationHandle);
|
| 493 |
|
| 494 |
+
// --- REFRESH BUTTON ---
|
| 495 |
const refreshBtn = document.createElement('button');
|
| 496 |
refreshBtn.innerHTML = 'Reset View';
|
| 497 |
refreshBtn.style.position = 'absolute';
|
|
|
|
| 791 |
#main-title h1 {font-size: 2.4em !important;}
|
| 792 |
'''
|
| 793 |
with gr.Blocks(css=css) as demo:
|
| 794 |
+
gr.Markdown("Qwen-Image-Edit-2511-3D-Lighting-Control", elem_id="main-title")
|
| 795 |
gr.Markdown("Control lighting directions using the **3D viewport** or **sliders**. Use [Multi-Angle-Lighting](https://huggingface.co/dx8152/Qwen-Edit-2509-Multi-Angle-Lighting) LoRA for precise lighting control, paired with [Rapid-AIO-V19](https://huggingface.co/prithivMLmods/Qwen-Image-Edit-Rapid-AIO-V19).")
|
| 796 |
|
| 797 |
with gr.Row():
|