With the use three.js size does not create a scene change text

With the use three.js size does not create a scene change text, the following two steps:

1, the text drawn onto the canvas.

2, to create a material shader, the text inside the three-dimensional scene.

advantage:

1, compared with the text used to achieve html, the text may be obscured models, more three-dimensional effect.

2, will not end with a scene rotation scaling to change the size, the situation is far not see does not exist for three-dimensional mark.

Renderings:

 

Sample Code. 1: https://github.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/object/text/UnscaledText.js

Sample Code 2: https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/object/text/UnscaledText.js

 

Implementation

 

1, using canvas draw text, drawn first strokes in black, then painted with white text. Black Stroke mainly to be able to see your text at the white background.

 

let context = canvas.getContext('2d');

context.imageSmoothingQuality = 'high';
context.textBaseline = 'middle';
context.textAlign = 'center';
context.lineWidth = 4;

let halfWidth = canvas.width / 2;
let halfHeight = canvas.height / 2;

// 画描边
context.font = `16px "Microsoft YaHei"`;
context.strokeStyle = '#000';
context.strokeText(text, halfWidth, halfHeight);

// 画文字
context.fillStyle = '#fff';
context.fillText(text, halfWidth, halfHeight);

 

 

2. Create the shader material, the text is on the screen, to render three-dimensional scene.

 

let geometry = new THREE.PlaneBufferGeometry();
let material = new THREE.ShaderMaterial({
    vertexShader: UnscaledTextVertexShader,
    fragmentShader: UnscaledTextFragmentShader,
    uniforms: {
        tDiffuse: {
            value: new THREE.CanvasTexture(canvas)
        },
        width: {
            value: canvas.width
        },
        height: {
            value: canvas.height
        },
        domWidth: {
            value: renderer.domElement.width
        },
        domHeight: {
            value: renderer.domElement.height
        }
    },
    transparent: true
});

let mesh = new THREE.Mesh(geometry, material);

 

Description: Because the text edge drawn on the canvas is translucent, semi-transparent material to be provided to achieve a smoothing effect text edge.

 
UnscaledTextVertexShader
 
precision highp float;

uniform float width;
uniform float height;
uniform float domWidth;
uniform float domHeight;

varying vec2 vUv;
 
void main() {
    vUv = uv;
    vec4 proj = projectionMatrix * modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
    gl_Position = vec4(
        proj.x / proj.w  + position.x * width / domWidth * 2.0,
        proj.y / proj.w + position.y * height / domHeight * 2.0,
        proj.z /proj.w,
         1.0 
    ); 
}

 

Description:

a, (0.0, 0.0, 0.0) is the center of the world coordinate plane, rear left and take modelViewMatrix projectionMatrix, get the coordinates of the screen coordinate system.

b, proj.x / proj.w + position.x * width / domWidth * 2.0 means that the center of the panel into the correct position in the world coordinate system, so that the width of the flat panel display is exactly equal to the number of pixels on the screen, to avoid text zoom.

C, is multiplied by 2.0 is generated by default because three.js plates 1 are the width and height, width and height of the screen coordinate system are from -1 to 1, 2.

d, gl_Position.w is 1.0, orthogonal projection, the model change of the screen size does not change with depth.

 
UnscaledTextFragmentShader
 
HighP Precision float ; 

Uniform sampler2D tDiffuse; 
Uniform float width; 
Uniform float height; 
 
VARYING vec2 vUv; 
 
void main () {
     // Note vUv must take color from the canvas integer coordinates, otherwise it will result in text blurred problems. 
    _uv = vec2 vec2 ( 
        (Floor (vUv.s * width) + 0.5) / width, 
        (Floor (vUv.t * height) + 0.5) / height 
    ); 

    gl_FragColor = texture2D (tDiffuse, _uv); 
}

 

Description:

1, uv coordinates must be exactly the corresponding pixel on the canvas, otherwise it will result in text blurred problems.

 

Text solutions blur

Three.js or using WebGL rendering text, it is easy to come across vague word problems, the following main reasons aspects.
 
 
1, the Canvas draw lines, two pixels from the center of stippling.
 
Draw 1px integer pixel lines, the lines on both sides 1px fact, there 0.5px translucent lines actually drawn 2px. When drawing, you must do (integer + 0.5px) pixel to start drawing.
 
With specific reference to "canvas canvas 1px lines to solve the problem of blurred": https://www.jianshu.com/p/c0970eecd843
 
In the above code, the font size and line width is even, there is no problem.
 
 
2, based on uv coordinates from maps to take color, be sure to just get to the integer pixel on the map, otherwise it will be color interpolation, leading to blurred.
 
My question is this card for a long time, the phenomenon is specific as to change the angle of view, the text sometimes clear, sometimes vague , sparking.
 
The solution is automatic interpolation uv coordinates "rounding" the sources shader, just taken to (integer + 0.5 pixels). Why plus 0.5, see the above article "canvas canvas resolve ambiguous 1px line problem".
 
Implementation code:
 
vec2 _uv = vec2(
    (floor(vUv.s * width) + 0.5) / width,
    (floor(vUv.t * height) + 0.5) / height
);

 

Wherein, width, and height are the width and height of the texture.
 
. 3, gl_Position.xy exactly corresponding pixel on the screen.
 
This is one of the reasons I guess, according to the reason 2 be modified text is not blurred. So, this is not carefully tested.
 
 

Reference material

1, based on open source three.js three-dimensional scene editor: https://github.com/tengge1/ShadowEditor
2, canvas canvas 1px lines to solve the problem of blurred: https://www.jianshu.com/p/c0970eecd843
 
 
 

Guess you like

Origin www.cnblogs.com/tengge/p/11979854.html