百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

预言已显,新月将至!Threejs复刻原神绝美空月之歌场景

yund56 2025-07-20 07:15 17 浏览

预言已显,新月将至!Threejs复刻原神绝美空月之歌场景


不得不说原神的美工这一块真的没话说,身为一个前端切图仔,马上被他的 web 特效吸引。刚好最近在学习 Three.js,想着能否通过复刻一个新活动场景来练练手。于是,我开始了这场 Three.js 的奇妙之旅。


个人精力有限,只做了一个页面,历时五天。差不多还原了这个页面的 90% 的功能。

二、场景分析

这个页面其实不太难,在动手之前,我先仔细观察了原神空月之歌场景,发现主要有以下几个部分:

  • 主体背景:包括渐变的主体背景和左上角旋落的流星、场景中会闪现随机分布的星星。
  • 星环:由多个同心圆环组成,具有动态旋转效果。
  • 坐标轴:场景中的坐标轴装饰。

2.1 主体背景实现

主体背景是一个静态的图片,要实现的话直接导入就可以。

我直接从原神的活动页面抓取了背景图片资源。通过分析网络请求,找到了背景图片的链接,并将其下载到本地项目中。在 Three.js 中,使用 THREE.TextureLoader 加载背景图片,并将其设置为场景的背景。

  1. 勾选请求类型 image
  2. 右侧下载


可以看到除了背景也有很多其他的资源,我们全部 copy 下来放到我们的项目中。使用 Threejs 进行加载:

const textureLoader = new THREE.TextureLoader();
const backgroundTexture = textureLoader.load('path/to/background.jpg');
scene.background = backgroundTexture;

使用 threejs 加载后,为了符合深空的背景,我整体使用紫色和暗色调。在使用 gui 调整整体的透明度,旋转、位置等参数后,得到了初步的效果。


背景中还有一些散落的星星,我在抓包的时候看到老米使用的背景星星好像是使用贴图是不断放大缩小实现的,我觉得这样还是太敷衍了。所以我决定使用 Threejs 中的网格自己实现一个。


首先,创建了一个包含大量点的 THREE.Points 网格每里面大量的点的位置是随机的。

// 创建星星点点
function createStarField() {
const vertices = [];
for (let i = 0; i < 10000; i++) {
const x = (Math.random() - 0.5) * 2000;
const y = (Math.random() - 0.5) * 2000;
const z = (Math.random() - 0.5) * 2000;
vertices.push(x, y, z);
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 1,
transparent: true
});
return new THREE.Points(geometry, material);
}


然后对于每个点我们再使用 shader 进行优化,为了让星星具有闪烁效果,使用了自定义的 ShaderMaterial,通过在顶点着色器和片段着色器中添加时间变量,控制星星的透明度和亮度变化。以下是部分着色器代码:

// 顶点着色器
varying vec3 vPosition;
void main() {
vPosition = position;
gl_PointSize = 1.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// 片段着色器
uniform float time;
varying vec3 vPosition;
void main() {
float brightness = sin(time + length(vPosition)) * 0.5 + 0.5;
gl_FragColor = vec4(vec3(brightness), brightness);
}


通过不断调整着色器中的参数,最终实现了星星的闪烁效果,使其更加贴近原神中的视觉表现。

2.2 星环实现

星环是整个场景中最复杂的部分之一。为了实现星环的动态旋转效果,需要创建了多个同心圆环,并为每个圆环添加了不同的旋转速度和方向。每个圆环由一系列点组成,这些点同样使用了自定义的着色器来实现发光和闪烁效果。

export function createCircle(
imagePath = CirclePath,
circleName = "circlename",
defaultValue = {
circleSize: 3.5,
rotationSpeed: 0.5, // 默认旋转速度
opacity: 0.5,
}
) {
// 添加图片到圆环中心
const textureLoader = new THREE.TextureLoader();
const circleTexture = textureLoader.load(imagePath);
const circleGeometry = new THREE.PlaneGeometry(1, 1); // 平面大小根据图片调整
const circleMaterial = new THREE.MeshBasicMaterial({
map: circleTexture,
transparent: true,
side: THREE.DoubleSide,
alphaMap: alphaTexture,
opacity: defaultValue.opacity,
alphaTest: 0.1,
});
const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);
circleMesh.scale.set(Number(defaultValue.circleSize), Number(defaultValue.circleSize), 1);
circleMesh.position.z = 0.1; // 稍微调整z轴避免与星星重叠
const folder = gui.addFolder(circleName);
folder.close(); // 默认收起面板
const controls = {
...defaultValue,
};
// 新增图片大小控制
folder.add(controls, "circleSize", 1, 10).onChange((value) => {
circleMesh.scale.set(Number(value), Number(value), 1);
});
// 添加旋转速度控制
folder.add(controls, "rotationSpeed", -0.1, 0.1).name("旋转速度");
function animate() {
// return
requestAnimationFrame(animate);
// 更新圆环旋转
circleMesh.rotation.z += controls.rotationSpeed * 0.01;
}
animate();
return circleMesh;
}

如果直接加载图片的话会显得不那么真实,看到老米的星环是有一种模糊的质感,于是通过分析发现老米应该是用了贴图纹理,找到资源中相关的图片,将星环加上质感。


// 加载星环纹理
const starRingTexture = textureLoader.load('path/to/star-ring-texture.png');
starRingTexture.wrapS = THREE.RepeatWrapping;
starRingTexture.wrapT = THREE.RepeatWrapping;

2.3 、坐标轴

图片场景还有一个坐标轴,我们直接使用 Point 将点随机分布在坐标轴上就行。

export function createAxisStars() {
const geometry = new THREE.BufferGeometry();
const vertices = [];
for (let i = 0; i < 100; i++) {
const x = -500;
const y = (Math.random() - 0.5) * 1000;
const z = (Math.random() - 0.5) * 1000;
vertices.push(x, y, z);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 2
});
return new THREE.Points(geometry, material);
}

三、最中相机视角确定

目前我们已经完成了需要使用到的所有组件,但是目前我们还是在一个三维的视角中。


现在需要完成最终相机的位置确定,就是用户最终看到的画面。 为了方便,我们将背景的坐标固定在 xy 平面上,将中间倾斜的主体放到一个 group中进行整体旋转

const galaxyGroup = new THREE.Group();
galaxyGroup.add(ringItem1);
galaxyGroup.add(ringItem2);
galaxyGroup.add(startRing1);
galaxyGroup.add(startRing2);
galaxyGroup.add(startRing3);
galaxyGroup.add(startRing4);
galaxyGroup.add(circle1);
galaxyGroup.add(circle2);
galaxyGroup.add(circle3);
galaxyGroup.add(circle4);
galaxyGroup.add(circle5);
galaxyGroup.add(axisStar);
galaxyGroup.rotation.x = -0.8;
galaxyGroup.rotation.y = -0.21;
galaxyGroup.rotation.z = -0.18;

然再调整相关的参数(炼丹),就大差不差了:


四、整体优化

最后,再对整个场景进行了优化,以确保在不同设备上都能流畅运行。

  • 性能优化:通过减少星星和星环的数量、降低着色器的复杂度等方式,在保证视觉效果的同时提高渲染性能。
  • 响应式设计:添加了窗口大小变化的监听器,使场景能够自适应不同的屏幕尺寸。
  • 参数调整:使用 dat.GUI 添加了调试界面,方便在运行时调整各个元素的参数,如星星的大小、星环的旋转速度等。
const gui = new dat.GUI();
gui.add(material.uniforms.size, 'value', 0.1, 5).name('星星大小');
gui.add(material.uniforms.glowIntensity, 'value', 0, 2).name('发光强度');

通过不断调试和优化,最终实现了与原神空月之歌场景相似的视觉效果。

相关推荐

SM小分队Girls on Top,女神战队少了f(x)?

这次由SM娱乐公司在冬季即将开演的smtown里,将公司的所有女团成员集结成了一个小分队project。第一位这是全面ACE的大姐成员权宝儿(BoA),出道二十年,在日本单人销量过千万,韩国国内200...

韩国女团 aespa 首场 VR 演唱会或暗示 Quest 3 将于 10 月推出

AmazeVR宣布将在十月份举办一场现场VR音乐会,观众将佩戴MetaQuest3进行体验。韩国女团aespa于2020年11月出道,此后在日本推出了三张金唱片,在韩国推出了...

韩网热议!女团aespa成员Giselle在长腿爱豆中真的是legend

身高163的Giselle,长腿傲人,身材比例绝了...

假唱而被骂爆的女团:IVE、NewJeans、aespa上榜

在韩国,其实K-pop偶像并不被认为是真正的歌手,因为偶像们必须兼备舞蹈能力、也经常透过对嘴来完成舞台。由于科技的日渐发达,也有许多网友会利用消音软体来验证K-pop偶像到底有没有开麦唱歌,导致假唱这...

新女团Aespa登时尚大片 四个少女四种style

来源:环球网

韩国女团aespa新歌MV曝光 画面梦幻造型超美

12月20日,韩国女团aespa翻唱曲《DreamsComeTrue》MV公开,视频中,她们的造型超美!WINTER背后长出一双梦幻般的翅膀。柳智敏笑容甜美。宁艺卓皮肤白皙。GISELLE五官精致...

女网友向拳头维权,自称是萨勒芬妮的原型?某韩国女团抄袭KDA

女英雄萨勒芬妮(Seraphine)是拳头在2020年推出的第五位新英雄,在还没有正式上线时就备受lsp玩家的关注,因为她实在是太可爱了。和其他新英雄不同的是,萨勒芬妮在没上线时就被拳头当成虚拟偶像来...

人气TOP女团是?INS粉丝数见分晓;TWICE成员为何在演唱会落泪?

现在的人气TOP女团是?INS粉丝数见分晓!现在爱豆和粉丝之间的交流方法变得多种多样,但是Instagram依然是主要的交流手段。很多粉丝根据粉丝数评价偶像的人气,拥有数百、数千万粉丝的组合作为全球偶...

韩国女团MVaespa Drama MV_韩国女团穿超短裙子跳舞

WelcometoDrama.Pleasefollow4ruleswhilewatchingtheDrama.·1)Lookbackimmediatelywhenyoufe...

aespa师妹团今年将出道! SM职员亲口曝「新女团风格、人数」

记者刘宛欣/综合报导南韩造星工厂SM娱乐曾打造出东方神起、SUPERJUNIOR、少女时代、SHINee、EXO等传奇团体,近年推出的aespa、RIIZE更是双双成为新生代一线团体,深受大众与粉丝...

南韩最活跃的女团aespa,新专辑《Girls》即将发布,盘点昔日经典

女团aespa歌曲盘点,新专辑《Girls》即将发布,期待大火。明天也就是2022年的7月8号,aespa新专辑《Girls》即将发行。这是继首张专辑《Savage》之后,时隔19个月的第二张专辑,这...

章泽天女团aespa出席戛纳晚宴 宋康昊携新片亮相

搜狐娱乐讯(山今/文玄反影/图科明/视频)法国时间5月23日晚,女团aespa、宋康昊、章泽天等明星亮相戛纳晚宴。章泽天身姿优越。章泽天肩颈线优越。章泽天双臂纤细。章泽天仪态端正。女团aespa亮...

Aespa舞台暴露身高比例,宁艺卓脸大,柳智敏有“TOP”相

作为SM公司最新女团aespa,初舞台《BlackMamba》公开,在初舞台里,看得出来SM公司是下了大功夫的,虽然之前SM公司新出的女团都有很长的先导片,但是aespa显然是有“特殊待遇”。运用了...

AESPA女团成员柳智敏karina大美女

真队内速度最快最火达成队内首个且唯一两百万点赞五代男女团中输断层第一(图转自微博)...

对来学校演出的女团成员语言性骚扰?韩国这所男高的学生恶心透了

哕了……本月4日,景福男子高中相关人士称已经找到了在SNS中上传对aespa成员进行性骚扰文章的学生,并开始着手调查。2日,SM娱乐创始人李秀满的母校——景福高中迎来了建校101周年庆典活动。当天,S...