Объект выглядит полупрозрачным, хотя непрозрачность равна 1 из трех jsJavascript

Форум по Javascript
Ответить
Anonymous
 Объект выглядит полупрозрачным, хотя непрозрачность равна 1 из трех js

Сообщение Anonymous »

Почему мой куб Three.js выглядит полупрозрачным, когда я меняю металличность, шероховатость и цвет, хотя непрозрачность остается равной 1.
Прозрачность появляется только при прямоугольном освещении, а не точечный источник света.
Посмотрите демонстрационное видео, и вы увидите, что свет появляется снаружи, как если бы коробка была полупрозрачной.

Код: Выделить всё



Simple Rectangle Light

body { margin: 0; }
canvas { display: block; }
#controls {
position: fixed;
top: 10px;
left: 10px;
background: rgba(0,0,0,0.7);
padding: 10px;
border-radius: 5px;
color: white;
font-family: Arial;
}




 Rectangle Light

  Point Light


Rectangle Light Position:

X: 

Y: 

Z: 

Rectangle Light Rotation:

X: 

Y: 

Z: 

Rectangle Light Size:

Width: 

Height: 

Material Properties:

Color: 

Roughness: 

Metalness: 



{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/examples/jsm/controls/OrbitControls.js": "https://unpkg.com/three@0.160.0/examples/jsm/controls/OrbitControls.js",
"three/examples/jsm/lights/RectAreaLightUniformsLib.js": "https://unpkg.com/three@0.160.0/examples/jsm/lights/RectAreaLightUniformsLib.js",
"three/examples/jsm/helpers/RectAreaLightHelper.js": "https://unpkg.com/three@0.160.0/examples/jsm/helpers/RectAreaLightHelper.js"
}
}


import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js';
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js';

// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);

// Camera setup
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// Renderer setup
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Initialize rect area light uniforms
RectAreaLightUniformsLib.init();

// Controls
const controls = new OrbitControls(camera, renderer.domElement);

// Comment out texture loading
// const textureLoader = new THREE.TextureLoader();
// const skinTexture = textureLoader.load('skin-image.png');

// Add material definition before box creation
const material = new THREE.MeshStandardMaterial({
color: 0x333333,
roughness: 0.9,
metalness: 0.0,
opacity: 1.0,
transparent: false
});

// Create box
const outerSize = 2;
const thickness = 0.2;  // Back to original thickness
const box = new THREE.Group();

// Bottom
const bottom = new THREE.Mesh(
new THREE.BoxGeometry(outerSize, thickness, outerSize),
material
);
bottom.position.y = -outerSize/2;
box.add(bottom);

// Front wall
const front = new THREE.Mesh(
new THREE.BoxGeometry(outerSize, outerSize, thickness),
material
);
front.position.z = outerSize/2 - thickness/2;
front.position.y = -thickness/2;
box.add(front);

// Back wall
const back = new THREE.Mesh(
new THREE.BoxGeometry(outerSize, outerSize, thickness),
material
);
back.position.z = -outerSize/2 + thickness/2;
back.position.y = -thickness/2;
box.add(back);

// Left wall
const left = new THREE.Mesh(
new THREE.BoxGeometry(thickness, outerSize, outerSize),
material
);
left.position.x = -outerSize/2 + thickness/2;
left.position.y = -thickness/2;
box.add(left);

// Right wall
const right = new THREE.Mesh(
new THREE.BoxGeometry(thickness, outerSize, outerSize),
material
);
right.position.x = outerSize/2 - thickness/2;
right.position.y = -thickness/2;
box.add(right);

scene.add(box);

// Rectangle light at bottom
const width = 1.0;   // Smaller than inner width (was 1.8)
const height = 1.0;  // Make it square like the box (was 1.8)
const intensity = 10;
const rectLight = new THREE.RectAreaLight(0xff0000, intensity, width, height);
rectLight.position.set(0, -0.9 + 0.01, 0); // Keep it just above bottom
rectLight.rotation.x = Math.PI / 2; // Face up
scene.add(rectLight);

// Add visible helper for the light
const helper = new RectAreaLightHelper(rectLight);
rectLight.add(helper);

// Move ambient light before PMREM setup
const ambientLight = new THREE.AmbientLight(0xffffff, 2.0);
scene.add(ambientLight);

// Add point light inside box
const pointLight = new THREE.PointLight(0xff0000, 10.0);
pointLight.position.set(0, -0.5, 0);
pointLight.distance = 3;  // How far the light reaches
pointLight.decay = 1;     // How quickly it fades with distance
scene.add(pointLight);

// Make the visualization sphere bigger
const sphereGeometry = new THREE.SphereGeometry(0.2, 16, 16);  // Increase from 0.05 to 0.2
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const lightSphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
lightSphere.position.copy(pointLight.position);
scene.add(lightSphere);

// Animation
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();

// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});

document.getElementById('rectLight').addEventListener('change', (e) => {
rectLight.visible = e.target.checked;
helper.visible = e.target.checked;
});

document.getElementById('pointLight').addEventListener('change', (e) => {
pointLight.visible = e.target.checked;
lightSphere.visible = e.target.checked;
});

document.getElementById('rectX').addEventListener('input', (e) => {
rectLight.position.x = parseFloat(e.target.value);
updateURL();
});

document.getElementById('rectY').addEventListener('input', (e) => {
rectLight.position.y = parseFloat(e.target.value) + 0.01; // Keep slight offset from bottom
});

document.getElementById('rectZ').addEventListener('input', (e) => {
rectLight.position.z = parseFloat(e.target.value);
});

document.getElementById('rectRotX').addEventListener('input', (e) => {
rectLight.rotation.x = parseFloat(e.target.value);
});

document.getElementById('rectRotY').addEventListener('input', (e) =>  {
rectLight.rotation.y = parseFloat(e.target.value);
});

document.getElementById('rectRotZ').addEventListener('input', (e) => {
rectLight.rotation.z = parseFloat(e.target.value);
});

document.getElementById('rectWidth').addEventListener('input', (e) => {
rectLight.width = parseFloat(e.target.value);
helper.update(); // Update the helper to show new size
});

document.getElementById('rectHeight').addEventListener('input', (e) => {
rectLight.height = parseFloat(e.target.value);
helper.update(); // Update the helper to show new size
});

document.getElementById('matColor').addEventListener('input', (e) => {
const value = parseInt(e.target.value);
material.color.setRGB(value/255, value/255, value/255);
updateURL();
});

document.getElementById('matRough').addEventListener('input', (e) => {
material.roughness = parseFloat(e.target.value);
});

document.getElementById('matMetal').addEventListener('input', (e) => {
material.metalness = parseFloat(e.target.value);
});

// Add function to update URL with current settings
function updateURL() {
const params = new URLSearchParams();

// Material settings
params.set('color', document.getElementById('matColor').value);
params.set('rough', document.getElementById('matRough').value);
params.set('metal', document.getElementById('matMetal').value);

// Light visibility
params.set('rectVisible', document.getElementById('rectLight').checked);
params.set('pointVisible', document.getElementById('pointLight').checked);

// Rectangle light settings
params.set('rectX', document.getElementById('rectX').value);
params.set('rectY', document.getElementById('rectY').value);
params.set('rectZ', document.getElementById('rectZ').value);
params.set('rectRotX', document.getElementById('rectRotX').value);
params.set('rectRotY', document.getElementById('rectRotY').value);
params.set('rectRotZ', document.getElementById('rectRotZ').value);
params.set('rectWidth', document.getElementById('rectWidth').value);
params.set('rectHeight', document.getElementById('rectHeight').value);

window.history.replaceState({}, '', `${window.location.pathname}?${params.toString()}`);
}

// Also add function to load settings from URL on page load
function loadFromURL() {
const params = new URLSearchParams(window.location.search);

// Helper function to load a parameter
function loadParam(id, prop, obj, converter = parseFloat) {
if(params.has(id)) {
const value = converter(params.get(id));
document.getElementById(id).value = value;
if(obj && prop) obj[prop] = value;
}
}

// Load all parameters
loadParam('color', null, null, value => {
const v = parseInt(value);
material.color.setRGB(v/255, v/255, v/255);
return v;
});
loadParam('rough', 'roughness', material);
loadParam('metal', 'metalness', material);
loadParam('rectX', 'x', rectLight.position);
// ... etc for all parameters
}

// Call on page load
loadFromURL();


 



Подробнее здесь: https://stackoverflow.com/questions/793 ... n-three-js
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»