When attempting to use THREE.InfiniteGridHelper there doesn’t seem to be a way to import the code that doesn’t generate an error. Even copying and pasting the code does not work.
Currently I have the code copied and pasted into my main.js page and this gives the error it gives
Uncaught TypeError: "InfiniteGridHelper" is read-only
http://127.0.0.1:5000/static/main.js:10
I have also tried pasting the code into its own InfiniteGridHelper.js page to be run locally , importing the code from https://mevedia.com/share/InfiniteGridHelper.js?c, import maps, and using a regular script tag. the results tend to cycle between errors like
Uncaught TypeError: THREE.InfiniteGridHelper is not a constructor
http://127.0.0.1:5000/static/main.js:142
"SyntaxError: import declarations may only appear at top level of a module"
Uncaught SyntaxError: The requested module ‘http://127.0.0.1:5000/static/InfiniteGridHelper.js’ doesn’t provide an export named: ‘InfiniteGridHelper’
Uncaught ReferenceError: THREE is not defined
http://127.0.0.1:5000/static/InfiniteGridHelper.js:3
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mevedia.com/share/InfiniteGridHelper.js?c. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
There is a forum on this library that seems to have been abandoned but it looks like other people were able to get it to work and it also seems to work on codepen. I’m just not able to figure out a way to get it to run locally.
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)
THREE.InfiniteGridHelper = function InfiniteGridHelper( size1, size2, color, distance, axes = 'xzy' ) {
color = color || new THREE.Color( 'white' );
size1 = size1 || 10;
size2 = size2 || 100;
distance = distance || 8000;
const planeAxes = axes.substr( 0, 2 );
const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );
const material = new THREE.ShaderMaterial( {
side: THREE.DoubleSide,
uniforms: {
uSize1: {
value: size1
},
uSize2: {
value: size2
},
uColor: {
value: color
},
uDistance: {
value: distance
}
},
transparent: true,
vertexShader: `
varying vec3 worldPosition;
uniform float uDistance;
void main() {
vec3 pos = position.${axes} * uDistance;
pos.${planeAxes} += cameraPosition.${planeAxes};
worldPosition = pos;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
varying vec3 worldPosition;
uniform float uSize1;
uniform float uSize2;
uniform vec3 uColor;
uniform float uDistance;
float getGrid(float size) {
vec2 r = worldPosition.${planeAxes} / size;
vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
float line = min(grid.x, grid.y);
return 1.0 - min(line, 1.0);
}
void main() {
float d = 1.0 - min(distance(cameraPosition.${planeAxes}, worldPosition.${planeAxes}) / uDistance, 1.0);
float g1 = getGrid(uSize1);
float g2 = getGrid(uSize2);
gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
if ( gl_FragColor.a <= 0.0 ) discard;
}
`,
extensions: {
derivatives: true
}
} );
THREE.Mesh.call( this, geometry, material );
this.frustumCulled = false;
};
THREE.InfiniteGridHelper.prototype = {
...THREE.Mesh.prototype,
...THREE.Object3D.prototype,
...THREE.EventDispatcher.prototype
};
if ( parseInt( THREE.REVISION ) > 126 ) {
class InfiniteGridHelper extends THREE.Mesh {
constructor ( size1, size2, color, distance, axes = 'xzy' ) {
color = color || new THREE.Color( 'white' );
size1 = size1 || 10;
size2 = size2 || 100;
distance = distance || 8000;
const planeAxes = axes.substr( 0, 2 );
const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );
const material = new THREE.ShaderMaterial( {
side: THREE.DoubleSide,
uniforms: {
uSize1: {
value: size1
},
uSize2: {
value: size2
},
uColor: {
value: color
},
uDistance: {
value: distance
}
},
transparent: true,
vertexShader: `
varying vec3 worldPosition;
uniform float uDistance;
void main() {
vec3 pos = position.${axes} * uDistance;
pos.${planeAxes} += cameraPosition.${planeAxes};
worldPosition = pos;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
varying vec3 worldPosition;
uniform float uSize1;
uniform float uSize2;
uniform vec3 uColor;
uniform float uDistance;
float getGrid(float size) {
vec2 r = worldPosition.${planeAxes} / size;
vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
float line = min(grid.x, grid.y);
return 1.0 - min(line, 1.0);
}
void main() {
float d = 1.0 - min(distance(cameraPosition.${planeAxes}, worldPosition.${planeAxes}) / uDistance, 1.0);
float g1 = getGrid(uSize1);
float g2 = getGrid(uSize2);
gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
if ( gl_FragColor.a <= 0.0 ) discard;
}
`,
extensions: {
derivatives: true
}
} );
super( geometry, material );
this.frustumCulled = false;
}
}
Object.assign( InfiniteGridHelper.prototype, THREE.InfiniteGridHelper.prototype );
THREE.InfiniteGridHelper = InfiniteGridHelper;
}
// creating the scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth /
window.innerHeight, 0.1, 1000);
camera.position.set(0,0,5);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize',function(){
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect=window.innerWidth/ window.innerHeight;
camera.updateProjectionMatrix();
})
const controls = new OrbitControls( camera, renderer.domElement );
controls.update()
// Infinite Grid Helper
const gridHelper = new THREE.InfiniteGridHelper(10, 100);
scene.add(gridHelper);
scene.add( gridHelper );
// Create a simple cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial(); // MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
controls.update()
}
animate();
<!DOCTYPE html>
<html>
<head>
<title>Three.js Scene</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script type="importmap"> { "imports":
{ "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"}}
</script>
<script type="module" src="static/main.js"></script>
</body>
</html>
2
Answers
I tried running your example and I faced the same
read-only
TypeError.Following the way
OrbitControls
was implemented, I made a few changes in the implementation of theInfiniteGridHelper
. So, the proposed implementation is below:An export of the
InfiniteGridHelper
class was created and taking into account thatPlaneBufferGeometry
has been deprecated since r145, it was replaced withPlaneGeometry
.Then, we have to import it to our script:
Finally, we have to include it in the HTML file:
Running it from a local server, will produce the following result:
this module code succesfully loads your script (as import or fetch for that script is not allowed):
console message:
full code: