#javascript #three.js #shader #webgl
Вопрос:
Поэтому я сделал этот объект галактики, состоящий из точек, плавающих вокруг его центра
const parameters = {}
parameters.count = 4500
parameters.size = 0.005
parameters.radius = 0.7
parameters.branches = 4
parameters.spin = 1
parameters.randomness = 0.1
parameters.randomnessPower = 5
parameters.insideColor = '#d42b2b'
parameters.outsideColor = '#14be4c'
let galaxyGeometry = null
let galaxyMaterial = null
let galaxyPoints = null
const generateGalaxy = () =>
{
//DESTROY STUFF
if(galaxyPoints !== null)
{
galaxyGeometry.dispose()
galaxyMaterial.dispose()
scene.remove(galaxyPoints)
}
//GALAXY GEOM AND PARTICLES
galaxyGeometry = new THREE.BufferGeometry()
const positions = new Float32Array(parameters.count * 3)
const randomness = new Float32Array(parameters.count * 3)
const galaxyColors = new Float32Array(parameters.count * 3)
const galaxyScales = new Float32Array(parameters.count * 1)
const colorInside = new THREE.Color(parameters.insideColor)
const colorOutside = new THREE.Color(parameters.outsideColor)
for(let i = 0; i < parameters.count; i )
{
const i3 = i * 3
//POSITION
const radius = Math.random() * parameters.radius
const branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2
const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1: -1) * parameters.randomness * radius
const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1: -1) * parameters.randomness * radius
const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1: -1) * parameters.randomness * radius
positions[i3 ] = Math.cos(branchAngle) * radius
positions[i3 1] = 0
positions[i3 2] = Math.sin(branchAngle) * radius
randomness[i3 ] = randomX
randomness[i3 1] = randomY
randomness[i3 2] = randomZ
//COLORS
// Color
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / parameters.radius)
galaxyColors[i3 ] = mixedColor.r
galaxyColors[i3 1] = mixedColor.g
galaxyColors[i3 2] = mixedColor.b
// Scale
galaxyScales[i] = Math.random()
}
galaxyGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
galaxyGeometry.setAttribute('aRandomness', new THREE.BufferAttribute(randomness, 3))
galaxyGeometry.setAttribute('color', new THREE.BufferAttribute(galaxyColors, 3))
galaxyGeometry.setAttribute('aScale', new THREE.BufferAttribute(galaxyColors, 3))
//GALAXY PARTICLE MATERIALS
galaxyMaterial = new THREE.ShaderMaterial({
depthWrite: false,
blending: THREE.AdditiveBlending,
vertexColors: true,
uniforms:
{
vAlpha: { value: 1.0 },
uTime: { value: 0 },
uSize: { value: 40 * renderer.getPixelRatio() }
},
vertexShader: galaxyVertex,
fragmentShader: galaxyFragment,
})
if(galaxyMaterial.uniforms.vAlpha.value !== 1.0)
{
galaxyGeometry.dispose()
galaxyMaterial.dispose()
scene.remove(galaxyPoints)
}
//GALAXY MESH
galaxyPoints = new THREE.Points(galaxyGeometry, galaxyMaterial)
console.log(galaxyPoints.position)
scene.add(galaxyPoints)
}
вместе со своей вершиной
uniform float uTime;
uniform float uSize;
attribute vec3 aRandomness;
attribute float aScale;
varying vec3 vColor;
void main()
{
//POSITION
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
// Rotate
float angle = atan(modelPosition.x, modelPosition.z);
float distanceToCenter = length(modelPosition.xz);
float angleOffset = (1.0 / distanceToCenter) * uTime * 3.0;
angle = angleOffset;
modelPosition.x = cos(angle) * distanceToCenter;
modelPosition.y = sin(angle) * distanceToCenter;
// Randomness
modelPosition.xyz = aRandomness;
vec4 viewPosition = viewMatrix * modelPosition;
vec4 projectedPosition = projectionMatrix * viewPosition;
gl_Position = projectedPosition;
//SIZE
gl_PointSize = uSize * aScale;
gl_PointSize *= (1.0 / - viewPosition.z);
//COLOR
vColor = color;
}
и шейдер фрагментов
varying vec3 vColor;
uniform float vAlpha;
void main()
{
//LIGHT PATTERN
float strength = distance(gl_PointCoord, vec2(0.5));
strength = 1.0 - strength;
strength = pow(strength, 8.0);
//FINAL COLOR
vec3 color = mix(vec3(0.0), vColor, strength);
gl_FragColor = vec4(color, vAlpha);
}
. Итак, мой вопрос вот в чем.Как можно перемещать объект по сцене, не меняя его первоначальный вид (например, галактика/портал). Поскольку я новичок в трех js, единственный известный мне способ перемещения объекта-это подобрать сетку и установить ее положение в соответствии с тем, что необходимо. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что точки движутся вокруг центральной точки. Когда я пытаюсь переместить сетку, вся галактика распадается. Каков здесь правильный подход, чтобы переместить всю галактику , скажем, на 2,0 по оси x, y или z? Я был бы очень признателен за объяснение того, почему это также происходит. Заранее спасибо.
Комментарии:
1. Сможете ли вы преобразовать опубликованный вами код в фрагмент, пригодный для выполнения? Было бы намного легче наблюдать за тем, что происходит, если бы мы могли запустить всю систему.
2. Кодовый код Извиняюсь за опоздание с ответом. Я терял клетки мозга, пытаясь понять это, но без особого результата :/ . Я надеюсь, что кодовая панель работает. @TheJim01
3. @TheJim01 Как вы можете видеть в коде, вся эта штука с «вихрем» находится в середине экрана. Что я хочу сделать, так это попытаться переместить его вверх и вниз, влево или вправо, как обычный объект с тремя точками. С помощью простых сеток это довольно просто, я просто задаю позицию-например, mesh.position.set(3, 3, 3) — и все работает нормально. Но в связи с тем, что мой галактический объект сделан с точками, необходимо использовать другой подход. Скорее всего, это связано с математикой, в которой я, честно говоря, очень плохо разбираюсь.