JSFiddle - React, Tailwind, and code Playground
HTML
<script type="x-shader/x-vertex" id="vertexShader">
attribute vec3 center;
varying vec3 vCenter;
void main() {
vCenter = center;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
uniform float widthFactor;
varying vec3 vCenter;
float edgeFactorTri() {
vec3 d = fwidth( vCenter.xyz );
vec3 a3 = smoothstep( vec3( 0.0 ), d * widthFactor, vCenter.xyz );
return min( min( a3.x, a3.y ), a3.z );
}
void main() {
if ( edgeFactorTri() > 0.99 ) discard;
gl_FragColor = gl_FrontFacing ? vec4( 0.9, 0.9, 1.0, 1.0 ) : vec4( 0.4, 0.4, 0.5, 1.0 );
}
</script>
JavaScript
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.126.1/build/three.module.js';
let renderer, scene, camera, mesh1, mesh2;
init();
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 500 );
camera.position.z = 150;
new THREE.BufferGeometryLoader().load( 'https://threejs.org/examples/models/json/WaltHeadLo_buffergeometry.json', function ( geometry ) {
// on the left
const material1 = new THREE.MeshBasicMaterial( {
color: 0xe0e0ff,
wireframe: true
} );
mesh1 = new THREE.Mesh( geometry, material1 );
mesh1.position.set( - 40, 0, 0 );
scene.add( mesh1 );
// on the right
const uniforms = { 'widthFactor': { value: 1 } };
const material2 = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
side: THREE.DoubleSide
} );
geometry.deleteAttribute( 'normal' );
geometry.deleteAttribute( 'uv' );
setupAttributes( geometry );
mesh2 = new THREE.Mesh( geometry, material2 );
mesh2.position.set( 40, 0, 0 );
scene.add( mesh2 );
//
animate();
} );
window.addEventListener( 'resize', onWindowResize );
}
function setupAttributes( geometry ) {
const vectors = [
new THREE.Vector3( 1, 0, 0 ),
new THREE.Vector3( 0, 1, 0 ),
new THREE.Vector3( 0, 0, 1 )
];
const position = geometry.attributes.position;
const centers = new Float32Array( position.count * 3 );
for ( let i = 0, l = position.count; i < l; i ++ ) {
vectors[ i % 3 ].toArray( centers, i * 3 );
}
geometry.setAttribute( 'center', new THREE.BufferAttribute( centers, 3 ) );
}
function...