Anonymous
3D-компонент Expo/Three.js корректно отображается в Интернете, но на эмуляторе Android отображается черный экран, а на р
Сообщение
Anonymous » 25 дек 2025, 18:11
Я пытаюсь визуализировать компонент Three.js с помощью Expo (expo-gl, expo-three).
В Интернете работает правильно.
Черный экран в эмуляторе Android.
3d-компонент не отображается на реальном устройстве Android, в то время как другие функции работают должным образом.
Нет ошибок или предупреждений в консоли.
Ожидаемая ситуация: 3D-компонент должен отображаться и анимироваться на Android так же, как и в Интернете.
Вот код.
Код: Выделить всё
import Constants from "expo-constants";
import { GLView } from "expo-gl";
import { Renderer } from "expo-three";
import * as THREE from "three";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass.js";
import fragmentMain from "@/shaders/fragmentMain";
import fragmentPars from "@/shaders/fragmentPars";
import vertexMain from "@/shaders/vertexMain";
import vertexPars from "@/shaders/vertexPars";
import { RootState } from "@/store/store";
import { router } from "expo-router";
import { useEffect, useRef, useState } from "react";
import { Button, View } from "react-native";
export default function App() {
// Animated wave strength for smooth transitions
const currentWaveStrength = useRef(0);
const targetWaveStrength = useRef(1);
return (
{
const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
/* ---------------- Renderer ---------------- */
const renderer = new Renderer({ gl });
renderer.setSize(width, height);
renderer.autoClear = true;
/* ---------------- Scene ---------------- */
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
width / height,
0.1,
1000
);
camera.position.z = 5;
/* ---------------- Lights ---------------- */
scene.add(new THREE.AmbientLight(0x4255ff, 0.5));
const directionalLight = new THREE.DirectionalLight(0x526cff, 1);
directionalLight.position.set(2, 2, 2);
scene.add(directionalLight);
/* ---------------- Geometry ---------------- */
const geometry = new THREE.IcosahedronGeometry(1, 80);
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
metalness: 1.0,
});
material.onBeforeCompile = (shader) => {
material.userData.shader = shader;
shader.uniforms.uTime = { value: 0 };
shader.uniforms.uWaveStrength = { value: 0.0 };
shader.vertexShader = shader.vertexShader
.replace(
`#include `,
`#include \n${vertexPars}`
)
.replace(
`#include `,
`#include \n${vertexMain}`
);
shader.fragmentShader = shader.fragmentShader
.replace(
`#include `,
`#include \n${fragmentPars}`
)
.replace(
`#include `,
`#include \n${fragmentMain}`
);
};
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
/* ---------------- BLOOM ---------------- */
const composer = new EffectComposer(renderer);
composer.setSize(width, height);
composer.addPass(new RenderPass(scene, camera));
const bloomPass = new UnrealBloomPass(
new THREE.Vector2(width, height),
1.6, // strength
0.45, // radius
0.08 // threshold
);
composer.addPass(bloomPass);
/* ---------------- Animation Loop ---------------- */
const render = (time: number) => {
if (material.userData.shader) {
material.userData.shader.uniforms.uTime.value = time * 0.001;
const lerpSpeed = 0.1;
currentWaveStrength.current = THREE.MathUtils.lerp(
currentWaveStrength.current,
targetWaveStrength.current,
lerpSpeed
);
material.userData.shader.uniforms.uWaveStrength.value =
currentWaveStrength.current;
}
mesh.rotation.x += 0.004;
mesh.rotation.y += 0.004;
// Animate bloom pulse only when there's wave activity
const baseIntensity =
currentWaveStrength.current > 0.01 ? 1.0 : 0.3;
const pulseAmount = currentWaveStrength.current > 0.01 ? 0.6 : 0.1;
material.emissiveIntensity =
baseIntensity + Math.sin(time * 0.002) * pulseAmount;
// IMPORTANT: render via composer
composer.render();
gl.endFrameEXP();
requestAnimationFrame(render);
};
requestAnimationFrame(render);
}}
/>
);
}
Нужна помощь, чтобы приложение работало и отображалось так же, как в Интернете.
Подробнее здесь:
https://stackoverflow.com/questions/798 ... -screen-on
1766675502
Anonymous
Я пытаюсь визуализировать компонент Three.js с помощью Expo (expo-gl, expo-three). [list] [*]В Интернете работает правильно. [*]Черный экран в эмуляторе Android. [*]3d-компонент не отображается на реальном устройстве Android, в то время как другие функции работают должным образом. [*]Нет ошибок или предупреждений в консоли. [/list] Ожидаемая ситуация: 3D-компонент должен отображаться и анимироваться на Android так же, как и в Интернете. Вот код. [code]import Constants from "expo-constants"; import { GLView } from "expo-gl"; import { Renderer } from "expo-three"; import * as THREE from "three"; import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"; import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"; import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass.js"; import fragmentMain from "@/shaders/fragmentMain"; import fragmentPars from "@/shaders/fragmentPars"; import vertexMain from "@/shaders/vertexMain"; import vertexPars from "@/shaders/vertexPars"; import { RootState } from "@/store/store"; import { router } from "expo-router"; import { useEffect, useRef, useState } from "react"; import { Button, View } from "react-native"; export default function App() { // Animated wave strength for smooth transitions const currentWaveStrength = useRef(0); const targetWaveStrength = useRef(1); return ( { const { drawingBufferWidth: width, drawingBufferHeight: height } = gl; /* ---------------- Renderer ---------------- */ const renderer = new Renderer({ gl }); renderer.setSize(width, height); renderer.autoClear = true; /* ---------------- Scene ---------------- */ const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 ); camera.position.z = 5; /* ---------------- Lights ---------------- */ scene.add(new THREE.AmbientLight(0x4255ff, 0.5)); const directionalLight = new THREE.DirectionalLight(0x526cff, 1); directionalLight.position.set(2, 2, 2); scene.add(directionalLight); /* ---------------- Geometry ---------------- */ const geometry = new THREE.IcosahedronGeometry(1, 80); const material = new THREE.MeshStandardMaterial({ color: 0xffffff, metalness: 1.0, }); material.onBeforeCompile = (shader) => { material.userData.shader = shader; shader.uniforms.uTime = { value: 0 }; shader.uniforms.uWaveStrength = { value: 0.0 }; shader.vertexShader = shader.vertexShader .replace( `#include `, `#include \n${vertexPars}` ) .replace( `#include `, `#include \n${vertexMain}` ); shader.fragmentShader = shader.fragmentShader .replace( `#include `, `#include \n${fragmentPars}` ) .replace( `#include `, `#include \n${fragmentMain}` ); }; const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); /* ---------------- BLOOM ---------------- */ const composer = new EffectComposer(renderer); composer.setSize(width, height); composer.addPass(new RenderPass(scene, camera)); const bloomPass = new UnrealBloomPass( new THREE.Vector2(width, height), 1.6, // strength 0.45, // radius 0.08 // threshold ); composer.addPass(bloomPass); /* ---------------- Animation Loop ---------------- */ const render = (time: number) => { if (material.userData.shader) { material.userData.shader.uniforms.uTime.value = time * 0.001; const lerpSpeed = 0.1; currentWaveStrength.current = THREE.MathUtils.lerp( currentWaveStrength.current, targetWaveStrength.current, lerpSpeed ); material.userData.shader.uniforms.uWaveStrength.value = currentWaveStrength.current; } mesh.rotation.x += 0.004; mesh.rotation.y += 0.004; // Animate bloom pulse only when there's wave activity const baseIntensity = currentWaveStrength.current > 0.01 ? 1.0 : 0.3; const pulseAmount = currentWaveStrength.current > 0.01 ? 0.6 : 0.1; material.emissiveIntensity = baseIntensity + Math.sin(time * 0.002) * pulseAmount; // IMPORTANT: render via composer composer.render(); gl.endFrameEXP(); requestAnimationFrame(render); }; requestAnimationFrame(render); }} /> ); } [/code] Нужна помощь, чтобы приложение работало и отображалось так же, как в Интернете. Подробнее здесь: [url]https://stackoverflow.com/questions/79854912/expo-three-js-3d-component-renders-correctly-on-web-but-shows-black-screen-on[/url]