- В Интернете работает правильно.
- Черный экран в эмуляторе 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