scaling (pixelation)

This commit is contained in:
2022-03-22 18:42:56 -05:00
parent da78983719
commit fa391ba7d4
2 changed files with 105 additions and 52 deletions

View File

@@ -3,7 +3,7 @@ import Text3D from './text';
function App() { function App() {
return ( return (
<Text3D width={800} height={500} style={'border: 1px solid black'} scale={0.5}>text</Text3D> <Text3D width={800} height={500} style={'border: 1px solid black'} zoom={2} scale={1/8}>text</Text3D>
) )
} }

View File

@@ -2,20 +2,12 @@ import * as THREE from 'three';
import { Font as FontLoader } from 'three/examples/jsm/loaders/FontLoader'; import { Font as FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'; import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import { ComponentProps } from 'preact'; import { ComponentProps } from 'preact';
import helvetiker_regular from './fonts/helvetiker_regular.typeface.json' import helvetiker_regular from './fonts/helvetiker_regular.typeface.json'; //taken from threejs's website
function runThree(canvas: HTMLCanvasElement, text: string, scale: number) {
//get canvas size
const Bounds = canvas.getBoundingClientRect();
function getTextGeometry(text: string): TextGeometry {
//get font //get font
const Font = new FontLoader(helvetiker_regular); const Font = new FontLoader(helvetiker_regular);
//create scene
const scene = new THREE.Scene();
//create text
const geometry = new TextGeometry(text, { const geometry = new TextGeometry(text, {
font: Font, font: Font,
size: 20, size: 20,
@@ -27,55 +19,103 @@ function runThree(canvas: HTMLCanvasElement, text: string, scale: number) {
bevelOffset: 0, bevelOffset: 0,
bevelSegments: 2 bevelSegments: 2
}); });
geometry.center();
return geometry;
}
interface runThreeArgs {
canvas: HTMLCanvasElement;
text: string;
zoom?: number;
scale?: number;
width?: number;
height?: number;
}
function runThree({ canvas, text, zoom = 1, scale = 1, width, height }: runThreeArgs) {
if (!width && !height) {
return;
}
//create scene
const scene = new THREE.Scene();
//create text
const geometry = getTextGeometry(text);
//create mesh from text //create mesh from text
// const material = new THREE.MeshNormalMaterial(); const material = new THREE.MeshNormalMaterial();
const material = new THREE.ShaderMaterial({ // const material = new THREE.ShaderMaterial({
uniforms: { // uniforms: {
'tDiffuse': { // 'tDiffuse': {
value: null // value: null
}, // },
'resolution': { // 'resolution': {
value: null // value: null
}, // },
'pixelSize': { // 'pixelSize': {
value: 100 // value: 100
} // }
}, // },
vertexShader: // vertexShader:
/* glsl */ // /* glsl */
` // `
varying highp vec2 vUv; // varying highp vec2 vUv;
void main() { // void main() {
vUv = uv; // vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); // gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`, // }`,
fragmentShader: // fragmentShader:
/* glsl */ // /* glsl */
` // `
uniform sampler2D tDiffuse; // uniform sampler2D tDiffuse;
uniform float pixelSize; // uniform float pixelSize;
uniform vec2 resolution; // uniform vec2 resolution;
varying highp vec2 vUv; // varying highp vec2 vUv;
void main(){ // void main(){
vec2 dxy = pixelSize / resolution; // vec2 dxy = pixelSize / resolution;
vec2 coord = dxy * floor( vUv / dxy ); // vec2 coord = dxy * floor( vUv / dxy );
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); // gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}` // }`
}); // });
const mesh = new THREE.Mesh(geometry, material); const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); scene.add(mesh);
//center mesh //set canvas size
mesh.geometry.center(); {
//get size of text
geometry.computeBoundingBox();
let textW = Math.abs(geometry.boundingBox!.min.x) + Math.abs(geometry.boundingBox!.max.x),
textH = Math.abs(geometry.boundingBox!.min.y) + Math.abs(geometry.boundingBox!.max.y),
aspect = textW / textH;
//calculate width and height
if (width && !height) {
height = width / aspect;
} else if (!width && height) {
width = height * aspect;
}
console.log(width! * scale, height! * scale)
canvas.width = width! * scale;
canvas.height = height! * scale;
canvas.style.width = `${width!}px`;
canvas.style.height = `${height!}px`;
}
//create camera //create camera
const Bounds = canvas.getBoundingClientRect();
const camera = new THREE.PerspectiveCamera(70, Bounds.width / Bounds.height, 0.01, 1000); const camera = new THREE.PerspectiveCamera(70, Bounds.width / Bounds.height, 0.01, 1000);
camera.position.set(0, 0, 50 / scale); camera.position.set(0, 0, 100 / zoom);
//set render settings //set render settings
const renderer = new THREE.WebGLRenderer({ const renderer = new THREE.WebGLRenderer({
antialias: false, antialias: false,
precision: 'lowp',
canvas: canvas, canvas: canvas,
alpha: true alpha: true
}); });
@@ -96,20 +136,33 @@ function runThree(canvas: HTMLCanvasElement, text: string, scale: number) {
interface Text3DArgs extends ComponentProps<'canvas'> { interface Text3DArgs extends ComponentProps<'canvas'> {
children: string; children: string;
scale: number; /**
* zoom < 100
*/
zoom?: number;
scale?: number;
width?: number;
height?: number;
} }
export default function Text3D({ children: text, scale, ...props }: Text3DArgs) { export default function Text3D({ children: text, zoom, scale, width, height, ...props }: Text3DArgs) {
if (!width && !height) {
return (null);
}
function runRef(canvas: HTMLCanvasElement | null) { function runRef(canvas: HTMLCanvasElement | null) {
if (!canvas) if (!canvas)
return; return;
runThree(canvas, text, scale); runThree({
canvas, text, zoom, scale, width, height
});
} }
return ( return (
<canvas {...props} ref={runRef} /> <canvas width={width} height={height} {...props} ref={runRef} />
) )
} }