Doodle3D-Slicer/three.js-master/examples/webgl_shaders_vector.html
2017-06-22 13:21:07 +02:00

380 lines
8.7 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - vector - text</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 10px;
width: 100%;
text-align: center;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> webgl - Resolution-Independent Vector Fonts. <a href="https://github.com/mrdoob/three.js/issues/4746">info</a>.
</div>
<script src="../build/three.min.js"></script>
<script src="./js/controls/OrbitControls.js"></script>
<script src="js/libs/stats.min.js"></script>
<!-- load the font file from canvas-text -->
<script src="fonts/helvetiker_regular.typeface.js"></script>
<script type="x-shader/x-fragment" id="fs">
varying vec2 vUv;
varying float flip;
uniform vec3 color;
float inCurve(vec2 uv) {
return uv.x * uv.x - uv.y;
}
float delta = 0.1;
void main() {
float x = inCurve(vUv);
if (x * flip > 0.) discard;
gl_FragColor = vec4(color, 1.);
}
</script>
<script type="x-shader/x-vertex" id="vs">
varying vec2 vUv;
attribute float invert;
varying float flip;
void main() {
vUv = uv;
flip = invert;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script>
var stats;
var camera, scene, renderer, controls;
var group, text;
var t = false;
function toggle() {
if ( t ) {
text2.visible = 0;
text1.visible = 1;
} else {
text2.visible = 1;
text1.visible = 0;
}
t = !t;
}
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 100, 500 );
controls = new THREE.OrbitControls( camera );
controls.center.set( 0, 100, 0 );
scene = new THREE.Scene();
var theText = "&"; // i % & j b 8
var options = {
size: 180,
height: 20,
curveSegments: 2,
font: "helvetiker",
bevelEnabled: false
};
group = new THREE.Group();
scene.add( group );
var textMaterial = new THREE.MeshBasicMaterial( { color: new THREE.Color(0, 0, 1 ), overdraw: 0.5, wireframe: true, side: THREE.DoubleSide } );
textShapes = THREE.FontUtils.generateShapes( theText, options );
text3d = new THREE.ShapeGeometry( textShapes );
text3d.computeBoundingBox();
var centerOffset = -0.5 * ( text3d.boundingBox.max.x - text3d.boundingBox.min.x );
text = new THREE.Mesh( text3d, textMaterial );
text.position.x = centerOffset - 150;
group.add( text );
//
vA = new THREE.Vector2();
vB = new THREE.Vector2();
vDot = new THREE.Vector2();
function processShape(path, reverse) {
var pts = []; // bigger area (convex hull)
var pts2 = []; // smaller area (full solid shapes)
var beziers = []; // quad bezier points
var invert = [];
var z;
var wind;
pts.push( path[0].getPoint(0) );
pts2.push( path[0].getPoint(0) );
for (var i=0; i < path.length; i++) {
curve = path[i];
if (curve instanceof THREE.LineCurve) {
pts.push( curve.v2 );
pts2.push( curve.v2 );
} else if (curve instanceof THREE.QuadraticBezierCurve) {
vA = vA.subVectors( curve.v1, curve.v0 ); // .normalize()
vB = vB.subVectors( curve.v2, curve.v1 );
z = vA.x * vB.y - vA.y * vB.x; // z component of cross Production
wind = z < 0; // clockwise/anticlock wind
// if (reverse) wind = !wind;
// console.log(z, wind , wind ? 'clockwise' : 'anti');
if (wind) {
pts.push( curve.v1 );
pts.push( curve.v2 );
pts2.push( curve.v2 );
} else {
pts.push( curve.v2 );
pts2.push( curve.v1 );
pts2.push( curve.v2 );
}
var flip = wind ? 1 : -1;
// if (reverse) flip *= -1;
invert.push(flip, flip, flip);
beziers.push( curve.v0, curve.v1, curve.v2);
}
}
return {
pts: pts,
pts2: pts2,
beziers: beziers,
invert: invert
};
}
var subshape;
var convexhullShapeGroup = [];
var solidShapeGroup = [];
var beziers = [], invert = [];
for (var s=0;s<textShapes.length;s++) {
subshape = textShapes[s];
var process = processShape(subshape.curves);
pts = process.pts;
pts2 = process.pts2;
beziers = beziers.concat(process.beziers);
invert = invert.concat(process.invert);
convexhullShape = new THREE.Shape( pts );
solidShape = new THREE.Shape( pts2 );
convexhullShapeGroup.push( convexhullShape );
solidShapeGroup.push( solidShape );
for (var i=0; i<subshape.holes.length;i++) {
hole = subshape.holes[i];
// console.log('hole', hole);
process = processShape(hole.curves, true);
pts = process.pts;
pts2 = process.pts2;
beziers = beziers.concat(process.beziers);
invert = invert.concat(process.invert);
convexhullShape.holes.push(new THREE.Shape(pts));
solidShape.holes.push(new THREE.Shape(pts2));
}
} // end of subshape
bezierGeometry = new THREE.Geometry();
for (var i=0;i<beziers.length;i++) {
p = beziers[i];
bezierGeometry.vertices.push( new THREE.Vector3(p.x, p.y, 0) );
}
for (i=0;i<beziers.length;i+=3) {
bezierGeometry.faces.push( new THREE.Face3(i, i+1, i+2) );
bezierGeometry.faceVertexUvs[0].push( [
new THREE.Vector2(0, 0),
new THREE.Vector2(0.5, 0),
new THREE.Vector2(1, 1)
] );
}
text3d = new THREE.ShapeGeometry( convexhullShapeGroup );
text3d.computeBoundingBox();
var centerOffset = -0.5 * ( text3d.boundingBox.max.x - text3d.boundingBox.min.x );
text1 = new THREE.Mesh( text3d, textMaterial );
text1.position.x = centerOffset + 150;
group.add( text1 );
text3d = new THREE.ShapeGeometry( solidShapeGroup );
text3d.computeBoundingBox();
var centerOffset = -0.5 * ( text3d.boundingBox.max.x - text3d.boundingBox.min.x );
text2 = new THREE.Mesh( text3d, new THREE.MeshBasicMaterial( { color: new THREE.Color(1, 0, 0 ), side: THREE.DoubleSide, wireframe: true } ) );
text2.position.x = centerOffset + 150;
group.add( text2 );
//
bezierGeometry.computeBoundingBox();
bezierGeometry.computeFaceNormals();
bezierGeometry.computeVertexNormals();
//
var uniforms = {
color: { type: 'c', value: new THREE.Color(0.45 * 0xffffff) }
};
var vertexShader = document.getElementById( 'vs' ).textContent;
var fragmentShader = document.getElementById( 'fs' ).textContent;
newMaterial = new THREE.ShaderMaterial({
attributes: { invert: { type: 'f', value: invert } },
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.DoubleSide
});
text = new THREE.Mesh( bezierGeometry, newMaterial );
text.position.x = centerOffset;
text.position.y = 0;
text.position.z = 0;
text.rotation.x = 0;
text.rotation.y = Math.PI * 2;
group.add( text );
//
text3d = new THREE.ShapeGeometry( solidShapeGroup );
text3d.computeBoundingBox();
text = new THREE.Mesh( text3d, new THREE.MeshBasicMaterial( { color: 0.45 * 0xffffff, side: THREE.DoubleSide } ) );
text.position.x = centerOffset;
text.position.y = 0;
text.position.z = 0;
text.rotation.x = 0;
text.rotation.y = Math.PI * 2;
group.add( text );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.body.appendChild( stats.domElement );
document.addEventListener( 'mousedown', toggle, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>