Generating identical circles using PointsMaterial and CircleGeometry

My goal is to generate circles using two different methods:

  • By utilizing a circle sprite and drawing it with Points and PointsMaterial
  • Using basic circle buffer geometries

Unfortunately, I am facing challenges trying to align them due to the size discrepancy in the PointsMaterial.

const width = window.innerWidth;
const height = window.innerHeight;

const fov = 40;
const near = 10;
const far = 200;

const camera = new THREE.PerspectiveCamera(fov, width / height, near, far);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

const circle_sprite = new THREE.TextureLoader().load(
  'https://fastforwardlabs.github.io/visualization_assets/circle-sprite.png'
);

const factor = 280;

const positions = [
  { x: 100, y: -5 },
  { x: 6, y: 50 }
];

const circleRadius = 20;

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xefefef);

/* First approach */
const pointsGeometry = new THREE.Geometry();

const colors = [];
for (const position of positions) {
  const vertex = new THREE.Vector3(position.x, position.y, 0);
  pointsGeometry.vertices.push(vertex);
  const color = new THREE.Color(0xff0000);
  colors.push(color);
}
pointsGeometry.colors = colors;

const pointsMaterial = new THREE.PointsMaterial({
  size: (factor * circleRadius) / fov,
  sizeAttenuation: false,
  vertexColors: true,
  map: circle_sprite,
  transparent: true,
  opacity: 0.5
});

const firstPoints = new THREE.Points(pointsGeometry, pointsMaterial);
scene.add(firstPoints);

/* Second approach */
const circleGeometry = new THREE.CircleBufferGeometry(circleRadius, 32);
const circleMaterial = new THREE.MeshBasicMaterial({
  color: 0xffff00,
  transparent: true,
  opacity: 0.5
});
positions.forEach((position) => {
  const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);
  circleMesh.position.set(position.x, position.y, 0);
  scene.add(circleMesh);
});

/* Render loop */
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

camera.position.set(0, 0, far);

I'm attempting to determine the value for the factor variable, but it seems that both width and height play a role in this calculation. Any suggestions on how I can create consistent circles using PointsMaterial?

Answer №1

By going to the following link: https://github.com/mrdoob/three.js/issues/12150#issuecomment-327874431, you will be able to calculate the size of points accurately.

body {
  overflow: hidden;
  margin: 0;
}
<script type="module>
import * as THREE from "https://threejs.org/build/three.module.js";
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

var grid = new THREE.GridHelper(10, 10);
grid.rotation.x = Math.PI * 0.5;
scene.add(grid);

// geometry

var cGeom = new THREE.CircleBufferGeometry(1, 32);
var cMat = new THREE.MeshBasicMaterial({
  color: "magenta"
});
var circle = new THREE.Mesh(cGeom, cMat);
circle.position.set(0, 3, 0);
scene.add(circle);

// points

var g = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3()]);
var c = document.createElement("canvas");
c.width = 128;
c.height = 128;
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, 128, 128);
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(64, 64, 64, 0, 2 * Math.PI);
ctx.fill();

var tex = new THREE.CanvasTexture(c);

var desiredSize = 2;
var pSize = desiredSize / Math.tan( THREE.Math.degToRad( camera.fov / 2 ) );

var m = new THREE.PointsMaterial({
  size: pSize,
  color: "aqua",
  map: tex,
  alphaMap: tex,
  alphaTest: 0.5
});
var p = new THREE.Points(g, m);
scene.add(p);

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera)
});

</script>

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

"Encountered a problem while setting up the Mailgun webhook to handle both multipart and URL encoded

I have been working on creating a web hook listener for Mailgun, and I encountered an issue when I realized that Mailgun can post webhooks using either multipart or x-www-form-urlencoded content-types. Currently, my code uses Multer to handle multipart b ...

Prevent regex from matching leading and trailing white spaces when validating email addresses with JavaScript

In my current setup, I utilize the following regular expression for email validation: /^[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/ My attempt to validate the email is shown below: if (!event.target.value.match(/^[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\. ...

React Native ScrollView with a custom footer that adjusts its size based on the content inside (

I've implemented the code below to ensure that the blue area in image 1 remains non-scrollable when there is sufficient space, but becomes scrollable when space is limited. However, I'm facing an issue where the ScrollView component is adding ext ...

apostrophe cutting off a portion of the input field's value

I am facing an issue with a reloaded input box on a web page that is updated through an ajax call. Whenever the input contains a single quote, the rest of the value gets cut off. How can I resolve this problem? The value assigned to myVal dynamically from ...

`The ultimate guide to fixing the node.js ENOENT error`

Currently, I am utilizing express.js to execute this code snippet: var repl = require("repl"); var express = require('express'); var app = express(); var server = require('http').createServer(app); var io = require('socket.io&apos ...

Tooltips will display on all Nivo charts except for the Nivo Line chart

I'm having an issue with nivo charts where the tooltip isn't showing up for my line chart. Even after copying and pasting the example from here: Other chart examples work fine with tooltips appearing, but for some reason, it's just not work ...

Express.js encountered a FetchError due to receiving an invalid JSON response body from https://api.twitter.com

I am currently working on a project that involves getting the tweet id as form input and using the Twitter API to retrieve data about that specific tweet. However, I have encountered an issue where the JSON data is not being returned properly. router.post( ...

"Change the value of a style setting in React to 'unset

One of the components has CSS properties such as `right` and `bottom` that are set with a classname. I tried to override these values using the `style` prop but have only been successful in setting numerical values like `10px` or `0px`, not `unset`. Wha ...

Having trouble transferring files to an unfamiliar directory using Node.js?

const { resolve } = require("path"); const prompt = require('prompt'); const fsPath = require('fs-path'); // Retrieve files from Directory const getFiles = dir => { const stack = [resolve(dir)]; const files = []; whi ...

Error encountered in Three.js: ShaderPass.js is unable to read the property 'prototype' of undefined

I'm currently facing an issue while trying to implement a basic GlitchPass in a Three.js demo. I keep encountering the error message Uncaught TypeError: Cannot read property 'prototype' of undefined at ShaderPass.js. For this particular dem ...

Executing JavaScript when a specific portion of a webpage loads in the presence of AJAX: A guide

As I tackle a project that involves loading elements via AJAX within a CMS-type software, I find myself restricted in accessing the AJAX code and its callbacks. One specific challenge I face is running my function only when a certain part of the page is l ...

Can someone explain how to replicate the jQuery .css function using native JavaScript?

When referencing an external CSS file, the code may look something like this: #externalClass { font-family: arial; } Within the HTML file, you would use it like so: <a href="#" id="externalClass">Link</a> In the JavaScript file, you can ret ...

Strange Node.js Issue

I don't have much experience with node.js, but I had to use it for launching on Heroku. Everything was going smoothly until a few days ago when suddenly these errors started appearing. Error: /app/index.jade:9 7| meta(name='viewport', co ...

selecting the ajax url for the datatable

I need to select the datatable ajax URL based on whether it contains data1, data2, or data3. Below is my code snippet: $(document).ready(function() { var $table = $('#datatable1'); $table.DataTable({ "columnDefs": [ ...

Identify whether the application is built with nextJS, react, or react-native

I'm currently developing a library for React applications and I anticipate that certain features will function differently depending on the environment. I am seeking a method to identify whether the current environment is a ReactJS application (creat ...

Welcome to the awe-inspiring universe of Typescript, where the harmonious combination of

I have a question that may seem basic, but I need some guidance. So I have this element in my HTML template: <a href=# data-bind="click: $parent.test">«</a> And in my Typescript file, I have the following code: public test() { alert( ...

Manipulate elements by adding and removing classes sequentially based on an array

Previously, some had difficulty understanding my question. I have an array of variables representing the ids of 5 divs. My goal is to change the color of each div sequentially for a brief moment before reverting back, mimicking the behavior of traffic ligh ...

A guide on setting up ExpressJS Error Handling to display custom error messages based on the corresponding HTTP Status codes

I am struggling to figure out how to implement this task. You need to create an error on the /error path and pass it to the next function. Make sure to use appropriate error status codes for displaying different types of error messages. I attempted using ...

The functionality of the Protractor right click feature is smooth, however, there seems to be an issue with selecting

https://i.sstatic.net/KoGto.png Even though I can locate the button within the context menu, I am facing difficulty in clicking it. The code mentioned below is successfully able to click the button, but an error message pops up indicating: Failed: script ...

NextJs's React-Quill is unable to effectively highlight syntax using the highlightJS library

I have been working on a NextJs application (blog) that utilizes react-quill as a rich text-editor. As part of my setup, I am making use of the Next custom 'app' feature, where my UserProvider component wraps everything to provide global access t ...