Creating a dashed line in Three.js that remains uniform relative to the camera

I am currently working on showcasing geometric figures in 3D using three.js.

When manually drawing hidden lines as dashed lines, the 'dashes' appear to be consistent for all of them. Whether it's a line parallel to the camera plane or one that's nearly perpendicular to the camera plane, they should have the same length and gap.

However, I've encountered an issue with LineDashedMaterial where this consistency doesn't seem to hold true.

https://i.sstatic.net/58GmV.jpg

For the example provided, I'm using this basic code snippet:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();

renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var geometry = new THREE.BoxGeometry( 2, 2, 2 );
var LINES_DASHED = new THREE.LineSegments(
    new THREE.EdgesGeometry(geometry),
    new THREE.LineDashedMaterial({
        linewidth: 2,
        color: 0x000000,
        dashSize: 0.2,
        gapSize: 0.1,
        depthTest: false,
        polygonOffset: true, polygonOffsetFactor: 1, polygonOffsetUnits: 1
    })
);
LINES_DASHED.computeLineDistances();
scene.add( LINES_DASHED );
scene.background = new THREE.Color( 0xffffff);
camera.position.z = 5;

var animate = function () {
    requestAnimationFrame( animate );
    LINES_DASHED.rotation.x += 0.01;
    LINES_DASHED.rotation.y += 0.01;
    renderer.render( scene, camera );
};

animate();
body { margin: 0; }
canvas { width: 100%; height: 100% }
<script src="https://threejs.org/build/three.min.js"></script>

Example in action:

I thought that by using:

line.computeLineDistance();

it would resolve the issue. However, it appears to calculate the line length in 3D space, which makes sense logically.

Is there something crucial that I might be overlooking?

Thank you for your assistance!

Answer №1

Handling this task internationally seems challenging. According to the documentation, THREE.LineDashedMaterial does not offer direct support for it.
However, a workaround involves creating a custom shader with a THREE.ShaderMaterial.

The key lies in determining the line's starting point within the fragment shader. This can be achieved by using the flat interpolation qualifier, which unfortunately is not supported by WebGL 1.0 / GLSL ES 1.00. Therefore, transitioning to WebGL 2.0 / GLSL ES 3.00 becomes necessary.
While OpenGL ES offers the extension

GL_NV_shader_noperspective_interpolation
, WebGL lacks a parallel extension (Refer to WebGL Extension Registry).

To proceed, create a THREE.WebGLRenderer instance with a WebGL2 context as outlined in How to use WebGL2:

var canvas = document.createElement('canvas');
var context = canvas.getContext('webgl2');
var renderer = new THREE.WebGLRenderer({ canvas: canvas, context: context });

In the vertex shader, ensure passing the normalized device coordinates to the fragment shader. This includes both default and 'flat' interpolation versions for correct handling of position data.

... (remaining content unchanged) ...

I incorporated the recommendations into your existing codebase. Check out the preview and example:

https://i.sstatic.net/yFnQd.gif

[Further details on implementation are present in the provided code snippet.]

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Bitly API in JavaScript to launch a popup window

I have implemented a script that dynamically generates short links for my Tweet buttons. It is working perfectly fine, but I am encountering an issue with opening the link either in a new tab or a popup window. I've tried adjusting the window.locatio ...

Having trouble transferring ASP server control value to a Javascript function

Currently working with ASP.NET 2.0. My Entry Form contains various ASP.NET Server Controls, such as TextBoxes. I want to pass the value of a TextBox on the onBlur event. Here is an example of a TextBox code: <asp:TextBox ID="txtTotalTw" Width="80px" r ...

The HTML grid is causing an irritating excess space on the right side of my website

After brainstorming an idea, I decided to create this website for testing purposes. However, the grid layout seems to be causing an unwanted margin on the right side of the page that is not associated with any HTML tag, disrupting the zoom functionality. ...

Tips on implementing ng-template within an Angular application

I'm in the process of developing a client-side angular application and have encountered an issue regarding the implementation of angular's ng-template. Currently, I have a navbar set up as follows: <nav class="navbar navbar-inverse" > ...

Creating Dynamic Latex Text with react-three/fiber's 3D Rendering

I am exploring ways to incorporate 3D math equations using react-three/fiber, and have been on the lookout for a solution that integrates latex seamlessly. Currently, I have been utilizing the Text3D component from @react-three/drei but have yet to find a ...

Unable to view videos shared by users in PeerJS and WebRTC video chat application from different tabs

Recently, I embarked on the task of creating a Video chat Website using Peer Js. Initially, everything seemed to be working fine as I was able to see my own video stream. However, a problem arose when attempting to view the video stream from another tab or ...

When iterating through a loop, the final value in an array is often overlooked

I have been attempting to iterate through an array to determine if any of the values, when compared to all other values in the array using the modulo operation, do not return a 0. Essentially, this process should only return the prime numbers in the array ...

How about, "Enhance your website navigation with a sleek anchor

After many attempts to implement smooth scrolling on my Bootstrap project, I have tried numerous Youtube tutorials and Google search results without any success. The latest attempt I made was following this Stack Overflow post Smooth scrolling when clickin ...

Every Dynamic Post automatically defaults to the initial object

I am currently developing an app that retrieves feeds from a Wordpress site and displays individual posts in a jQuery mobile list format. Here is the JavaScript code I am using: $(document).ready(function () { var url = 'http://howtodeployit.com/ ...

import jQuery into a JavaScript file

I'm currently working on a Chrome extension that relies on background.js to perform basic tasks. I need to include jquery.js in my background.js file so that I can utilize its ajax function, but I'm unsure of how to achieve this. Is it even possi ...

Can someone help me identify the issue with my JavaScript code?

Recently, I attempted to transfer data from JavaScript to HTML using Angular. Here is the code snippet: phonecatControllers.controller('start', ['$scope', function($scope){ $scope.lloadd=true; console.log('data - '+$ ...

Concealing the nearest object

I am currently working on using jquery to hide certain content on a website's index page. Within the fiddle, there is commented out code which I have been experimenting with - however, it hides all content divs if any toggle link is clicked. HTML & ...

Why is my MySQL query not returning the most recent results when using setInterval()?

I am currently facing an issue with the setInterval function within the $(document).ready(function(){} My approach involves using setInterval to call a PHP script that executes MySQL queries to check the status of 4 switches and then updating the screen w ...

RegEx unable to extract a number ranging from 0 to 23

Can you figure out why this JavaScript regex is having trouble parsing a number between 0 and 23? pattern = /([0-1]?[0-9]|2[0-3])/ "12".match(pattern) // => matches 12 "23".match(pattern) // => matches 2 (should match 23) ...

Unable to create a clickable button within a CSS3DObject using Three.js

How can I create an interactive button on a CSS3DObject within a cube made up of 6 sides? The button is located on the yellow side, but I'm facing issues with clicking on it. Whenever I attempt to click on the button, the event.target always points to ...

Unexpected output from nested loop implementation

Having some arrays, I am now trying to iterate through all tab names and exclude the values present in the exclusion list. json1 ={ "sku Brand": "abc", "strngth": "ALL", "area ...

Using Jquery to make an Ajax request to an Asp.net Web Method

My current approach involves using a jquery method to transmit only the member identification # from the client side to the server side. On the server side, I have a traditional Web Method in place to receive the data and execute SQL queries accordingly. ...

Angular 2: Encounter with 504 Error (Gateway Timeout)

I am struggling with handling errors in my Angular 2 application. Whenever the backend server is offline, an uncaught error appears in the console: GET http://localhost:4200/api/public/index.php/data 504 (Gateway Timeout) This is how my http.get me ...

Is there a way for me to generate a tab that shows content when hovered over?

Is it possible to create a tab that displays a vertical list of redirections when the mouse hovers over it, and hides when the mouse is moved away? This seems like a challenging task. Can someone guide me on how to achieve this, especially if it involves ...

Adding a fresh item into an element within an array using Javascript

Hello everyone! I've been thinking about how to insert a new element into an existing element in an array. I need to handle collisions in hash maps by inserting the new element at the same index where a previous element was stored. Thanks for your he ...