سایه‌ها (Shadows)

۱️⃣ فعال‌سازی سایه‌ها در Renderer

برای اینکه سایه‌ها نمایش داده بشن، ابتدا باید Renderer رو برای سایه‌ها فعال کنیم:

const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; // فعال‌سازی سایه‌ها document.body.appendChild(renderer.domElement);

۲️⃣ انواع سایه‌ها

  • castShadow → مشخص می‌کند که شیء سایه ایجاد کند

  • receiveShadow → مشخص می‌کند که شیء سایه دیگران را دریافت کند

مثال:

// مکعب می‌تونه سایه بیندازه cube.castShadow = true; // صفحه می‌تونه سایه رو دریافت کنه plane.receiveShadow = true;

۳️⃣ نورها و سایه‌ها

برای اینکه یک نور سایه تولید کند، باید castShadow = true داشته باشد:

const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(5, 10, 5); directionalLight.castShadow = true; // فعال‌سازی سایه برای نور scene.add(directionalLight);

📌 اکثر نورها قابلیت سایه دارن، از جمله:

  • DirectionalLight ✅

  • SpotLight ✅

  • PointLight ✅

  • AmbientLight ❌ (نور محیطی سایه ایجاد نمی‌کنه)

۴️⃣ تنظیمات پیشرفته سایه

  • shadow.mapSize → کیفیت سایه (عدد بالاتر → سایه دقیق‌تر)

  • shadow.bias → رفع مشکلات سایه‌ها (مثل سایه شناور یا z-fighting)

directionalLight.shadow.mapSize.width = 1024; directionalLight.shadow.mapSize.height = 1024; directionalLight.shadow.bias = -0.001;

۵️⃣ مثال کامل با سایه‌ها

const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.z = 10; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; // فعال کردن سایه‌ها document.body.appendChild(renderer.domElement); // مکعب const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); cube.castShadow = true; cube.position.y = 1; scene.add(cube); // صفحه const planeGeometry = new THREE.PlaneGeometry(10, 10); const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xaaaaaa }); const plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -Math.PI / 2; plane.position.y = 0; plane.receiveShadow = true; scene.add(plane); // نور جهت‌دار const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(5, 10, 5); directionalLight.castShadow = true; scene.add(directionalLight); // حلقه انیمیشن function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate();

📌 این مثال نشان می‌دهد:

  1. مکعب سایه می‌اندازد

  2. صفحه سایه دریافت می‌کند

  3. DirectionalLight سایه را تولید می‌کند

۶️⃣ نکات مهم

  • همیشه Renderer باید shadowMap.enabled = true باشد

  • AmbientLight سایه تولید نمی‌کند، باید نور جهت‌دار یا نقطه‌ای داشته باشیم

  • سایه‌ها روی GPU پردازش می‌شوند، پس کیفیت بالاتر → مصرف منابع بیشتر

  • ترکیب نورها و سایه‌ها به صحنه واقع‌گرایانه بودن می‌دهد