Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 2 months ago by AstroEngineer360

Why Are LineSegment Meshes Not Rendering on iPhone Safari in My Three.js Project?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I'm experiencing an issue with my Three.js project where LineSegment meshes (and similar mesh types) do not render on iPhone Safari. I tested the project on two different iPhones, and while other meshes show up correctly, the lines are completely missing. I didn't see any errors in the eruda console. You can check out a live example here: https://sepweb.dev/linetest5

This is the code that sets up the scene, initializes the lines, and handles the animation:

JAVASCRIPT
import './reset.css'; import * as Three from 'three'; let scene, vpAspect, camera, camSocket, renderer, canvas; let lineGeo, lines; const lineCount = 10000; let lastUpdate; const camDepth = 300; const cameraOffsetBuffer = 5000; const lineMaxLength = 1000; const lineMinLength = 400; document.addEventListener("DOMContentLoaded", async () => { initWorld(); }); function initWorld() { scene = new Three.Scene(); vpAspect = window.innerWidth / window.innerHeight; camera = new Three.PerspectiveCamera(60, vpAspect, 1, 4000); camSocket = new Three.Object3D(); camSocket.position.set(-1000, 0, 0); scene.add(camSocket); camSocket.add(camera); camera.position.set(0, 0, camDepth); camera.rotation.set(0, 0, 0); canvas = document.querySelector('#main'); renderer = new Three.WebGLRenderer ({ canvas: canvas, antialias: true, // preserveDrawingBuffer: false, //various settings I've tried // alpha: true, // premultipliedAlpha: false }); renderer.setClearColor(0x000000); const winW = window.innerWidth; const winH = window.innerHeight; renderer.setSize(winW, winH); initLines(); animate(); } function initLines() { const positions = new Float32Array(lineCount * 6); // 6 values per line (x1, y1, z1, x2, y2, z2) const initialYPositions = new Float32Array(lineCount); const colors = new Float32Array(lineCount * 3); // 3 values per vertex color (r, g, b) const velocities = new Float32Array(lineCount); const accelerations = new Float32Array(lineCount); const lengths = new Float32Array(lineCount); for(let i=0; i<lineCount;++i) { const range = cameraOffsetBuffer; const halfRange = range * 0.5; const x = Math.random() * 2 * range - range; const y = Math.random() * range - halfRange; const z = Math.random() * range - halfRange; const length = Math.random() * (lineMaxLength - lineMinLength) + lineMinLength; lengths[i] = length; //const height = Math.random() * 19 + 1; initialYPositions[i] = y; positions[i * 6] = x; positions[i * 6 + 1] = y; positions[i * 6 + 2] = z; positions[i * 6 + 3] = x - length; positions[i * 6 + 4] = y; // Adjust length of the line positions[i * 6 + 5] = z; setLineColor(colors, i); velocities[i] = 0; accelerations[i] = Math.random() * 0.001 + 0.015; } lineGeo = new Three.BufferGeometry(); lineGeo.setAttribute('position', new Three.BufferAttribute(positions, 3)); lineGeo.setAttribute('color', new Three.BufferAttribute(colors, 3)); lineGeo.setAttribute('velocity', new Three.BufferAttribute(velocities, 1)); lineGeo.setAttribute('acceleration', new Three.BufferAttribute(accelerations, 1)); lineGeo.setAttribute('length', new Three.BufferAttribute(lengths, 1)); lineGeo.setAttribute('initialYPosition', new Three.BufferAttribute(initialYPositions, 1)); const lineMaterial = new Three.LineBasicMaterial({ vertexColors: true, linewidth: 1 }); lines = new Three.LineSegments(lineGeo, lineMaterial); scene.add(lines); } function animate(time) { time = isNaN(time) ? 0 : time; let delta = getDelta(time); //updateLines(delta) renderer.render(scene, camera); requestAnimationFrame(animate); } function getDelta(time) { let delta = isNaN(lastUpdate) ? 0 : time - lastUpdate; lastUpdate = time; delta = Math.min(12, Math.max(delta, 0)); return delta; } function setLineColor(colorArr, i) { const color = getRandomColor(); colorArr[i * 3] = color.r;//Math.random(); // Red colorArr[i * 3 + 1] = color.g; // Green colorArr[i * 3 + 2] = color.b; // Blue } function getRandomColor() { const r = Math.random(); const g = Math.random(); const b = Math.random(); return new Three.Color(r,g,b); }

If anyone has encountered this issue or has ideas on why iPhone Safari might not be rendering these line segments, please share your suggestions.

0

Comments 0

Answers 1

Views 24

1 Answer

Answer by StackOverflowTychoAI Agent 9 days ago

0

Three.js Line Rendering Issues on iPhone Safari

Based on your code and the issue you're experiencing with lines not rendering on iPhone Safari, there are a few potential solutions to consider.

Possible Issues and Solutions

1. Camera Far Plane vs. Line Positions

Your camera's far plane is set to 4000:

JAVASCRIPT
camera = new Three.PerspectiveCamera(60, vpAspect, 1, 4000);

But your lines are positioned with a buffer of 5000:

JAVASCRIPT
const cameraOffsetBuffer = 5000;

This means many of your lines might be positioned beyond the camera's far plane, making them invisible. Try increasing your camera's far plane:

JAVASCRIPT
camera = new Three.PerspectiveCamera(60, vpAspect, 1, 10000);

2. Consider Using Line2 Instead

The standard LineSegments class has known issues on some mobile devices. Three.js provides alternative line implementations that might work better on iOS:

JAVASCRIPT
// Import the necessary classes import { Line2 } from 'three/examples/jsm/lines/Line2.js'; import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; // Then replace your line creation code function initLines() { // Create positions array as before const lineGeometry = new LineGeometry(); lineGeometry.setPositions(positions); const lineMaterial = new LineMaterial({ color: 0xffffff, linewidth: 5, // in pixels vertexColors: true, resolution: new Three.Vector2(window.innerWidth, window.innerHeight) }); lines = new Line2(lineGeometry, lineMaterial); scene.add(lines); }

3. WebGL Limitations on iOS

iOS Safari has stricter WebGL limitations. Try reducing the number of lines:

JAVASCRIPT
const lineCount = 1000; // Instead of 10000

4. Renderer Settings

Try these renderer settings which might help with iOS compatibility:

JAVASCRIPT
renderer = new Three.WebGLRenderer({ canvas: canvas, antialias: true, powerPreference: 'high-performance', precision: 'highp' });

5. Update Window Resize Handler

Make sure to update the renderer and camera when the window resizes, especially important for mobile:

JAVASCRIPT
window.addEventListener('resize', () => { const width = window.innerWidth; const height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); // If using Line2/LineMaterial, update resolution if (lines.material) { lines.material.resolution.set(width, height); } });

Summary

The most likely issues are:

  1. Lines positioned beyond the camera's far plane
  2. Basic line rendering limitations on iOS Safari
  3. Too many lines for mobile processing

Try the Line2/LineGeometry/LineMaterial approach first, as it's specifically designed to address line rendering issues across different platforms.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Discussion

No comments yet.