ThreeJS - Outline Test 5
Based on: https://jsfiddle.net/tfoller/qvrac41L/10/
by tfoller
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.5/dat.gui.min.js"></script>
<script>
var vertexShader = `
varying vec2 vUv;
attribute float alpha;
varying float vAlpha;
attribute vec3 center;
varying vec3 vCenter;
void main() {
vUv = uv;
vAlpha = alpha;
vCenter = center;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
var fragmentShader = `
//in vec2 ouv;
//uniform vec3 colors[_LENGTH_];
//uniform float steps[_LENGTH_];
//precision mediump float;
uniform vec3 color1;
uniform float color1Alpha;
uniform vec3 borderColor;
uniform float borderThickness;
uniform float lines[_LINEPOINTS_];
varying vec2 vUv;
varying float vAlpha;
varying vec3 vCenter;
bool pointInTriangle(float x2, float y2, float x3, float y3, float x, float y, out float dist)
{
float den = 1.0 / (x2 * y3 - x3 * y2);
float wa = ((y2 - y3) * x + (x3 - x2) * y - x3 * y2 + x2 * y3) * den;
if(wa < 0.0 || wa > 1.0) return false;
float wb = (y3 * x - x3 * y) * den;
if(wb < 0.0 || wb > 1.0) return false;
float wc = 1.0 - wa - wb;
if(wc < 0.0 || wc > 1.0) return false;
den = -x * (y2 - y3) + y * (x2 - x3);
float crx = x * (x2 * y3 - y2 * x3)/den;
float cry = y * (x2 * y3 - y2 * x3)/den;
dist = length(vec2(x,y)) / length(vec2(crx, cry));
return true;
}
void main() {
float dist = 0.0;
vec2 uv = vUv;// + 10.0;
for(int j = 0; j < _LINEPOINTS_; j+=4) {
if(pointInTriangle(lines[j], lines[j+1], lines[j+2], lines[j+3], vUv.x, vUv.y, dist)) break;
...
CSS
body {
overflow: hidden;
margin: 0;
}
JavaScript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 50);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
const printRounded = (label, arr) => {
const rarr = [...arr].map(e=>Math.round(e));
console.log(label, rarr);
};
var plane, ellipse, triangle;
var ellipseSegments = 6;
var xRadius = 20;
var yRadius = 10;
const x = 0, y = 0;
const heartShape = new THREE.Shape();
heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
const hgeom = new THREE.ShapeGeometry( heartShape );
function createEllipse(_geom) {
var shape = new THREE.Shape().absellipse(
0, 0, // ax, aY
xRadius, xRadius, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
shape.autoClose = true;
var geom = _geom ||
new THREE.ShapeBufferGeometry(
shape,
ellipseSegments
);
// HEART
let _shape;
if(_geom) {
_shape = [];
const _pos = _geom.attributes.position.array;
const _uv = _geom.attributes.uv.array;
for(let i = 6; i < _pos.length; i+=3)
_shape.push({x: _pos[i], y: _pos[i + 1]});
// shift uvs
for(let i = 0; i < _uv.length; i+=2) {
_uv[i] -= 5;
_uv[i + 1] -= 10;
}
}
// 2D array of points, world
const pos = [];
const shp = _shape ||...