(Three.js) Как создать сферу с градиентовой заливкой?
В моём коде ничего не работает, что касается света, следовательно я не могу сделать тень для своей модели планеты. Я думаю, что можно было бы на месте сферы с текстурой создать ещё одну сферу чуть побольше, которая имела бы градиентовую заливку чёрного цвета и прозрачного цвета, но нигде не могу найти эту информацию. Как это можно сделать правильно?
window.onload = () => {
const
canvas = document.getElementById('canv')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true})
renderer.setClearColor(0x000000)
renderer.shadowMapEnabled = true
const
scene = new THREE.Scene() // Заносим сцену
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 5000) // Заносим камеру (угол обзора, пропорции, видимость от и до)
camera.position.z = 30
camera.position.x = 30
camera.position.y = 32
//const controls = new THREE.OrbitControls( camera, canvas )
const
light = new THREE.SpotLight()
light.position.set(80, 0, 0)
light.castShadow = true
scene.add(light)
const
texture = new THREE.TextureLoader().load('model/texture.jpg')
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(6, 6)
material = new THREE.MeshBasicMaterial({map: texture})
geometry = new THREE.SphereGeometry(48, 100, 100)
mesh = new THREE.Mesh(geometry, material)
mesh.receiveShadow = true
scene.add(mesh)
const
outlineMaterial = new THREE.MeshBasicMaterial( { color: 0x0d0d0d, side: THREE.BackSide } )
outlineMesh = new THREE.Mesh( geometry, outlineMaterial )
outlineMesh.position = mesh.position
outlineMesh.scale.multiplyScalar(1.005)
scene.add( outlineMesh )
const rendering = () => {
mesh.rotation.y += 0.0001
renderer.render(scene, camera)
requestAnimationFrame(rendering)
}
camera.rotation.set(0, 0, 0)
rendering()
}
Ответы (1 шт):
Чтобы объекты затенялись, необходимо использовать материалы, отличные от MeshBasicMaterial и MeshNormalMaterial, так как эти два материала никак не реагируют на наличие источников освещения в сцене.
Материалы, реагирующие на свет: MeshLambertMaterial, MeshPhongMaterial, MeshStandardMaterial. Описание свойств данных материалов можно найти в справке.
body {
overflow: hidden;
margin: 0;
}
<canvas id="canv"></canvas>
<script type="module">
import * as THREE from "http://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
let canvas = document.getElementById('canv')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
})
//renderer.setClearColor(0x000000)
renderer.shadowMap.enabled = true
let scene = new THREE.Scene() // Заносим сцену
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 5000) // Заносим камеру (угол обзора, пропорции, видимость от и до)
camera.position.set(30, 30, 20).setLength(100);
camera.lookAt(scene.position);
const controls = new OrbitControls( camera, renderer.domElement )
let light = new THREE.SpotLight()
light.position.set(200, 0, 0)
light.castShadow = true
scene.add(light)
let texture = new THREE.TextureLoader().load('https://threejs.org/examples/textures/uv_grid_opengl.jpg')
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(6, 6)
let material = new THREE.MeshLambertMaterial({
map: texture
})
let geometry = new THREE.SphereGeometry(48, 100, 100)
let mesh = new THREE.Mesh(geometry, material)
mesh.receiveShadow = true
scene.add(mesh)
let outlineMaterial = new THREE.MeshBasicMaterial({
color: 0xd0d0d0,
side: THREE.BackSide
})
let outlineMesh = new THREE.Mesh(geometry, outlineMaterial)
outlineMesh.position.copy(mesh.position);
outlineMesh.scale.setScalar(1.005)
scene.add(outlineMesh)
const rendering = () => {
mesh.rotation.y += 0.0001
renderer.render(scene, camera)
requestAnimationFrame(rendering)
}
//camera.rotation.set(0, 0, 0)
rendering()
</script>
PS Возможно, имеет смысл использовать DirectionalLight вместо SpotLight.
