three-bmfont-text
Advanced tools
Comparing version 1.2.0 to 2.0.0
213
index.js
var createLayout = require('layout-bmfont-text') | ||
var inherits = require('inherits') | ||
var createIndices = require('quad-indices') | ||
var buffer = require('three-buffer-vertex-data') | ||
var assign = require('object-assign') | ||
var vertices = require('./lib/vertices') | ||
var utils = require('./lib/utils') | ||
@@ -8,84 +12,85 @@ | ||
module.exports = function(opt) { | ||
return new TextMesh(opt) | ||
module.exports = function createTextGeometry (opt) { | ||
return new TextGeometry(opt) | ||
} | ||
function TextMesh(opt) { | ||
function TextGeometry (opt) { | ||
Base.call(this) | ||
var multipage = opt && opt.multipage | ||
this.layout = null | ||
this._positions = new THREE.BufferAttribute(null, 2) | ||
this._uvs = new THREE.BufferAttribute(null, 2) | ||
if (multipage) | ||
this._pages = new THREE.BufferAttribute(null, 1) | ||
this._indices = new THREE.BufferAttribute(null, 1) | ||
if (typeof opt === 'string') { | ||
opt = { text: opt } | ||
} | ||
if (opt) | ||
this.update(opt) | ||
// use these as default values for any subsequent | ||
// calls to update() | ||
this._opt = assign({}, opt) | ||
this.addAttribute('position', this._positions) | ||
this.addAttribute('uv', this._uvs) | ||
if (multipage) | ||
this.addAttribute('page', this._pages) | ||
this.addAttribute('index', this._indices) | ||
// also do an initial setup... | ||
if (opt) this.update(opt) | ||
} | ||
inherits(TextMesh, Base) | ||
inherits(TextGeometry, Base) | ||
TextMesh.prototype.update = function(opt) { | ||
opt = opt||{} | ||
this.layout = createLayout(opt) | ||
TextGeometry.prototype.update = function (opt) { | ||
if (typeof opt === 'string') { | ||
opt = { text: opt } | ||
} | ||
//don't allow a deferred creation of multipage | ||
//since it requires different buffer layout | ||
if (opt.multipage && !this._pages) { | ||
throw new Error('must specify multipage: true in constructor') | ||
// use constructor defaults | ||
opt = assign({}, this._opt, opt) | ||
if (!opt.font) { | ||
throw new TypeError('must specify a { font } in options') | ||
} | ||
this.layout = createLayout(opt) | ||
// get vec2 texcoords | ||
var flipY = opt.flipY !== false | ||
// the desired BMFont data | ||
var font = opt.font | ||
//determine texture size from font file | ||
// determine texture size from font file | ||
var texWidth = font.common.scaleW | ||
var texHeight = font.common.scaleH | ||
//get visible glyphs | ||
var glyphs = this.layout.glyphs.filter(function(glyph) { | ||
// get visible glyphs | ||
var glyphs = this.layout.glyphs.filter(function (glyph) { | ||
var bitmap = glyph.data | ||
return bitmap.width * bitmap.height > 0 | ||
}) | ||
//provide visible glyphs for convenience | ||
this.visibleGlyphs = glyphs; | ||
//get vec2 quad positions | ||
var positions = getQuadPositions(glyphs, this.layout) | ||
// provide visible glyphs for convenience | ||
this.visibleGlyphs = glyphs | ||
//get vec2 texcoords | ||
var flipY = opt.flipY !== false | ||
var uvs = getQuadUVs(glyphs, texWidth, texHeight, flipY) | ||
if (opt.multipage) { | ||
var pages = getQuadPages(glyphs) | ||
this._pages.array = pages | ||
this._pages.needsUpdate = true | ||
} | ||
// get common vertex data | ||
var positions = vertices.positions(glyphs) | ||
var uvs = vertices.uvs(glyphs, texWidth, texHeight, flipY) | ||
var indices = createIndices({ | ||
clockwise: true, | ||
type: 'uint16', | ||
count: glyphs.length | ||
}) | ||
//get indices | ||
var quadCount = glyphs.length | ||
var indices = createIndices({ clockwise: true, count: quadCount }) | ||
// update vertex data | ||
buffer.index(this, indices, 1, 'uint16') | ||
buffer.attr(this, 'position', positions, 2) | ||
buffer.attr(this, 'uv', uvs, 2) | ||
this._uvs.array = uvs | ||
this._uvs.needsUpdate = true | ||
this._indices.array = indices | ||
this._indices.needsUpdate = true | ||
this._positions.array = positions | ||
this._positions.needsUpdate = true | ||
// update multipage data | ||
if (!opt.multipage && 'page' in this.attributes) { | ||
// disable multipage rendering | ||
this.removeAttribute('page') | ||
} else if (opt.multipage) { | ||
var pages = vertices.pages(glyphs) | ||
// enable multipage rendering | ||
buffer.attr(this, 'page', pages, 1) | ||
} | ||
} | ||
TextMesh.prototype.computeBoundingSphere = function() { | ||
if (this.boundingSphere === null) | ||
this.boundingSphere = new THREE.Sphere() | ||
TextGeometry.prototype.computeBoundingSphere = function () { | ||
if (this.boundingSphere === null) { | ||
this.boundingSphere = new THREE.Sphere() | ||
} | ||
@@ -100,11 +105,13 @@ var positions = this.attributes.position.array | ||
utils.computeSphere(positions, this.boundingSphere) | ||
if (isNaN(this.boundingSphere.radius)) | ||
console.error('THREE.BufferGeometry.computeBoundingSphere(): ' | ||
+ 'Computed radius is NaN. The ' | ||
+ '"position" attribute is likely to have NaN values.') | ||
if (isNaN(this.boundingSphere.radius)) { | ||
console.error('THREE.BufferGeometry.computeBoundingSphere(): ' + | ||
'Computed radius is NaN. The ' + | ||
'"position" attribute is likely to have NaN values.') | ||
} | ||
} | ||
TextMesh.prototype.computeBoundingBox = function() { | ||
if (this.boundingBox === null) | ||
this.boundingBox = new THREE.Box3() | ||
TextGeometry.prototype.computeBoundingBox = function () { | ||
if (this.boundingBox === null) { | ||
this.boundingBox = new THREE.Box3() | ||
} | ||
@@ -120,81 +127,1 @@ var bbox = this.boundingBox | ||
} | ||
function getQuadPages(glyphs) { | ||
var pages = new Float32Array(glyphs.length * 4 * 1) | ||
var i = 0 | ||
glyphs.forEach(function(glyph) { | ||
var id = glyph.data.page || 0 | ||
pages[i++] = id | ||
pages[i++] = id | ||
pages[i++] = id | ||
pages[i++] = id | ||
}) | ||
return pages | ||
} | ||
function getQuadUVs(glyphs, texWidth, texHeight, flipY) { | ||
var uvs = new Float32Array(glyphs.length * 4 * 2) | ||
var i = 0 | ||
glyphs.forEach(function(glyph) { | ||
var bitmap = glyph.data | ||
var bw = (bitmap.x+bitmap.width) | ||
var bh = (bitmap.y+bitmap.height) | ||
//top left position | ||
var u0 = bitmap.x / texWidth | ||
var v1 = bitmap.y / texHeight | ||
var u1 = bw / texWidth | ||
var v0 = bh / texHeight | ||
if (flipY) { | ||
v1 = (texHeight-bitmap.y) / texHeight | ||
v0 = (texHeight-bh) / texHeight | ||
} | ||
//BL | ||
uvs[i++] = u0 | ||
uvs[i++] = v1 | ||
//TL | ||
uvs[i++] = u0 | ||
uvs[i++] = v0 | ||
//TR | ||
uvs[i++] = u1 | ||
uvs[i++] = v0 | ||
//BR | ||
uvs[i++] = u1 | ||
uvs[i++] = v1 | ||
}) | ||
return uvs | ||
} | ||
function getQuadPositions(glyphs, layout) { | ||
var positions = new Float32Array(glyphs.length * 4 * 2) | ||
var i = 0 | ||
glyphs.forEach(function(glyph) { | ||
var bitmap = glyph.data | ||
//bottom left position | ||
var x = glyph.position[0] + bitmap.xoffset | ||
var y = glyph.position[1] + bitmap.yoffset | ||
//quad size | ||
var w = bitmap.width | ||
var h = bitmap.height | ||
//BL | ||
positions[i++] = x | ||
positions[i++] = y | ||
//TL | ||
positions[i++] = x | ||
positions[i++] = y + h | ||
//TR | ||
positions[i++] = x + w | ||
positions[i++] = y + h | ||
//BR | ||
positions[i++] = x + w | ||
positions[i++] = y | ||
}) | ||
return positions | ||
} |
var itemSize = 2 | ||
var box = { min: [0, 0], max: [0, 0] } | ||
function bounds(positions) { | ||
function bounds (positions) { | ||
var count = positions.length / itemSize | ||
@@ -11,3 +11,3 @@ box.min[0] = positions[0] | ||
for (var i=0; i<count; i++) { | ||
for (var i = 0; i < count; i++) { | ||
var x = positions[i * itemSize + 0] | ||
@@ -22,18 +22,19 @@ var y = positions[i * itemSize + 1] | ||
module.exports.computeBox = function(positions, output) { | ||
module.exports.computeBox = function (positions, output) { | ||
bounds(positions) | ||
output.min.set(box.min[0], box.min[1], 0) | ||
output.min.set(box.min[0], box.min[1], 0) | ||
output.max.set(box.max[0], box.max[1], 0) | ||
} | ||
module.exports.computeSphere = function(positions, output) { | ||
module.exports.computeSphere = function (positions, output) { | ||
bounds(positions) | ||
var minX = box.min[0], minY = box.min[1], | ||
maxX = box.max[0], maxY = box.max[1], | ||
width = maxX - minX, | ||
height = maxY - minY, | ||
length = Math.sqrt(width*width + height*height) | ||
output.center.set(minX + width/2, minY + height/2, 0) | ||
output.radius = length/2 | ||
var minX = box.min[0] | ||
var minY = box.min[1] | ||
var maxX = box.max[0] | ||
var maxY = box.max[1] | ||
var width = maxX - minX | ||
var height = maxY - minY | ||
var length = Math.sqrt(width * width + height * height) | ||
output.center.set(minX + width / 2, minY + height / 2, 0) | ||
output.radius = length / 2 | ||
} |
{ | ||
"name": "three-bmfont-text", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "renders BMFont files in ThreeJS with word-wrapping", | ||
@@ -12,24 +12,31 @@ "main": "index.js", | ||
}, | ||
"standard": { | ||
"globals": [ | ||
"THREE" | ||
] | ||
}, | ||
"dependencies": { | ||
"inherits": "^2.0.1", | ||
"layout-bmfont-text": "^1.2.0", | ||
"object-assign": "^4.0.1", | ||
"quad-indices": "^2.0.1", | ||
"xtend": "^4.0.0" | ||
"three-buffer-vertex-data": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"bluebird": "^2.9.14", | ||
"browserify": "^9.0.3", | ||
"budo": "^1.2.2", | ||
"garnish": "^2.1.0", | ||
"browserify": "^12.0.1", | ||
"budo": "^7.0.2", | ||
"load-bmfont": "^1.0.0", | ||
"standard": "^5.4.1", | ||
"three": "^0.70.0", | ||
"three-orbit-viewer": "^69.2.9", | ||
"uglify-js": "^2.4.17", | ||
"watchify": "^2.4.0" | ||
"uglify-js": "^2.4.17" | ||
}, | ||
"scripts": { | ||
"build": "browserify test/test-3d.js | uglifyjs -cm > test/bundle.js", | ||
"test-2d": "budo test/test-2d.js -o bundle.js --dir test --live -d | garnish -v", | ||
"test-3d": "budo test/test-3d.js -o bundle.js --dir test --live -d | garnish -v", | ||
"test-multi": "budo test/test-multi.js -o bundle.js --dir test --live -d | garnish -v" | ||
"start": "budo test/test-line.js:bundle.js --dir test --live", | ||
"test-2d": "budo test/test-2d.js:bundle.js --dir test --live", | ||
"test-3d": "budo test/test-3d.js:bundle.js --dir test --live", | ||
"test-multi": "budo test/test-multi.js:bundle.js --dir test --live", | ||
"test": "standard" | ||
}, | ||
@@ -36,0 +43,0 @@ "keywords": [ |
@@ -9,4 +9,6 @@ # three-bmfont-text | ||
Bitmap font rendering for ThreeJS, batching glyphs into a single BufferGeometry. Supports word-wrapping, letter spacing, kerning, signed distance fields, multi-texture fonts, and more. About 8kb after minification. | ||
Bitmap font rendering for ThreeJS, batching glyphs into a single BufferGeometry. Supports word-wrapping, letter spacing, kerning, signed distance fields with standard derivatives, multi-texture fonts, and more. About 12kb after minification. | ||
Works on Three r69-73, and possibly more. | ||
Below is an example that uses [load-bmfont](https://www.npmjs.com/package/load-bmfont) to parse BMFont files on the fly with XHR: | ||
@@ -19,6 +21,5 @@ | ||
loadFont('fonts/Arial.fnt', function(err, font) { | ||
//create a geometry of packed bitmap glyphs, | ||
//word wrapped to 300px and right-aligned | ||
// create a geometry of packed bitmap glyphs, | ||
// word wrapped to 300px and right-aligned | ||
var geometry = createGeometry({ | ||
text: 'Lorem ipsum\nDolor sit amet.', | ||
width: 300, | ||
@@ -28,11 +29,16 @@ align: 'right', | ||
}) | ||
// change text and other options as desired | ||
// the options sepcified in constructor will | ||
// be used as defaults | ||
geometry.update('Lorem ipsum\nDolor sit amet.') | ||
//the resulting layout has metrics and bounds | ||
// the resulting layout has metrics and bounds | ||
console.log(geometry.layout.height) | ||
console.log(geometry.layout.descender) | ||
//the texture atlas containing our glyphs | ||
// the texture atlas containing our glyphs | ||
var texture = THREE.ImageUtils.loadTexture('fonts/Arial.png') | ||
//We can use plain old bitmap materials | ||
// we can use a simple ThreeJS material | ||
var material = new THREE.MeshBasicMaterial({ | ||
@@ -44,3 +50,3 @@ map: texture, | ||
//now do something with our text mesh ! | ||
// now do something with our mesh! | ||
var mesh = new THREE.Mesh(geometry, material) | ||
@@ -58,4 +64,10 @@ }) | ||
Returns a new BufferGeometry with the given options. The ThreeJS-specific options: | ||
Returns a new BufferGeometry with the given options. | ||
**Note:** The options set in the constructor become the defaults for any subsequent calls to `update()`. | ||
`opt` can be an options object, or a String – equivalent to `{ text: str }`. | ||
Options specific to ThreeJS: | ||
- `flipY` (boolean) whether the texture will be Y-flipped (default true) | ||
@@ -79,6 +91,12 @@ - `multipage` (boolean) whether to construct this geometry with an extra buffer containing page IDs. This is necessary for multi-texture fonts (default false) | ||
Re-builds the geometry using the given options. All options are the same as in the constructor, except for `multipage` which must be specified during construction-time. | ||
Re-builds the geometry using the given options. Any options not specified here will default to those set in the constructor. | ||
This method will recompute the text layout and rebuild the WebGL buffers. | ||
`opt` can be a string, which is equivalent to: | ||
```js | ||
geometry.update({ text: 'new text' }) | ||
``` | ||
#### `geometry.layout` | ||
@@ -92,3 +110,3 @@ | ||
This is an array of `{ line, position, index, data }` objects, [see here](https://github.com/Jam3/layout-bmfont-text#layoutglyphs). For example, this could be used to add a new BufferAttribuet for `line` offset. | ||
This is an array of `{ line, position, index, data }` objects, [see here](https://github.com/Jam3/layout-bmfont-text#layoutglyphs). For example, this could be used to add a new BufferAttribute for `line` offset. | ||
@@ -139,4 +157,17 @@ ## Demos | ||
## Change Log | ||
- `2.0.0` | ||
- now uses [three-buffer-vertex-data](https://github.com/Jam3/three-buffer-vertex-data) to handle some ThreeJS version differences; this may lead to a slight memory increase | ||
- constructor holds default options for subsequent calls to `update()` | ||
- `update()` and constructor can take string, treated as `{ text: str }` | ||
- changed to `RawShaderMaterial` for proper ThreeJS support across versions | ||
- SDF shader now uses standard derivatives by default for better anti-aliasing, with a fall back using `gl_FragCoord.w` | ||
- SDF shader `smooth` option has been removed for less API surface area | ||
- `1.x` | ||
- uses `ShaderMaterial`, only really supports r69 | ||
- must call `update()` with *all* options desired | ||
## License | ||
MIT, see [LICENSE.md](http://github.com/Jam3/three-bmfont-text/blob/master/LICENSE.md) for details. |
@@ -1,6 +0,8 @@ | ||
var xtend = require('xtend') | ||
var assign = require('object-assign') | ||
module.exports = function(opt) { | ||
opt = opt||{} | ||
module.exports = function (opt) { | ||
opt = opt || {} | ||
var opacity = typeof opt.opacity === 'number' ? opt.opacity : 1 | ||
var precision = opt.precision || 'highp' | ||
var alphaTest = typeof opt.alphaTest === 'number' ? opt.alphaTest : 0.0001 | ||
@@ -11,5 +13,5 @@ var textures = opt.textures || [] | ||
var baseUniforms = {} | ||
textures.forEach(function(tex, i) { | ||
baseUniforms['texture' + i] = { | ||
type: 't', | ||
textures.forEach(function (tex, i) { | ||
baseUniforms['texture' + i] = { | ||
type: 't', | ||
value: tex | ||
@@ -19,49 +21,68 @@ } | ||
var samplers = textures.map(function(tex, i) { | ||
return 'uniform sampler2D texture'+i+';' | ||
var samplers = textures.map(function (tex, i) { | ||
return 'uniform sampler2D texture' + i + ';' | ||
}).join('\n') | ||
var body = textures.map(function(tex, i) { | ||
var cond = i===0 ? 'if' : 'else if' | ||
var body = textures.map(function (tex, i) { | ||
var cond = i === 0 ? 'if' : 'else if' | ||
return [ | ||
cond+" (vPage == "+i+".0) {", | ||
"sampleColor = texture2D(texture"+i+", vUv);", | ||
"}" | ||
cond + ' (vPage == ' + i + '.0) {', | ||
'sampleColor = texture2D(texture' + i + ', vUv);', | ||
'}' | ||
].join('\n') | ||
}).join('\n') | ||
return xtend({ | ||
uniforms: xtend(baseUniforms, { | ||
var color = opt.color | ||
// remove to satisfy r73 | ||
delete opt.textures | ||
delete opt.color | ||
delete opt.precision | ||
delete opt.opacity | ||
var attributes = { | ||
attributes: { page: { type: 'f', value: 0 } } | ||
} | ||
var threeVers = (parseInt(THREE.REVISION, 10) || 0) | 0 | ||
if (threeVers >= 72) { | ||
attributes = undefined | ||
} | ||
return assign({ | ||
uniforms: assign({}, baseUniforms, { | ||
opacity: { type: 'f', value: opacity }, | ||
color: { type: 'c', value: new THREE.Color(opt.color) } | ||
color: { type: 'c', value: new THREE.Color(color) } | ||
}), | ||
attributes: { | ||
page: { type: 'f', value: 0 } | ||
}, | ||
vertexShader: [ | ||
"attribute float page;", | ||
"varying vec2 vUv;", | ||
"varying float vPage;", | ||
"void main() {", | ||
"vUv = uv;", | ||
"vPage = page;", | ||
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position.xyz, 1.0 );", | ||
"}" | ||
].join("\n"), | ||
fragmentShader: [ | ||
"uniform float opacity;", | ||
"uniform vec3 color;", | ||
'attribute vec4 position;', | ||
'attribute vec2 uv;', | ||
'attribute float page;', | ||
'uniform mat4 projectionMatrix;', | ||
'uniform mat4 modelViewMatrix;', | ||
'varying vec2 vUv;', | ||
'varying float vPage;', | ||
'void main() {', | ||
'vUv = uv;', | ||
'vPage = page;', | ||
'gl_Position = projectionMatrix * modelViewMatrix * position;', | ||
'}' | ||
].join('\n'), | ||
fragmentShader: [ | ||
'precision ' + precision + ' float;', | ||
'uniform float opacity;', | ||
'uniform vec3 color;', | ||
samplers, | ||
"varying float vPage;", | ||
"varying vec2 vUv;", | ||
"void main() {", | ||
"vec4 sampleColor = vec4(0.0);", | ||
body, | ||
"gl_FragColor = sampleColor * vec4(color, opacity);", | ||
"}" | ||
].join("\n"), | ||
defines: { | ||
"USE_MAP": "" | ||
} | ||
}, opt) | ||
} | ||
'varying float vPage;', | ||
'varying vec2 vUv;', | ||
'void main() {', | ||
'vec4 sampleColor = vec4(0.0);', | ||
body, | ||
'gl_FragColor = sampleColor * vec4(color, opacity);', | ||
alphaTest === 0 | ||
? '' | ||
: ' if (gl_FragColor.a < ' + alphaTest + ') discard;', | ||
'}' | ||
].join('\n') | ||
}, attributes, opt) | ||
} |
@@ -1,49 +0,63 @@ | ||
var xtend = require('xtend') | ||
var assign = require('object-assign') | ||
module.exports = function(opt) { | ||
opt = opt||{} | ||
module.exports = function (opt) { | ||
opt = opt || {} | ||
var opacity = typeof opt.opacity === 'number' ? opt.opacity : 1 | ||
var alphaTest = typeof opt.alphaTest === 'number' ? opt.alphaTest : 0.06 | ||
var smooth = typeof opt.smooth === 'number' ? opt.smooth : 1/16 | ||
return xtend({ | ||
var alphaTest = typeof opt.alphaTest === 'number' ? opt.alphaTest : 0.0001 | ||
var precision = opt.precision || 'highp' | ||
var color = opt.color | ||
var map = opt.map | ||
// remove to satisfy r73 | ||
delete opt.map | ||
delete opt.color | ||
delete opt.precision | ||
delete opt.opacity | ||
return assign({ | ||
uniforms: { | ||
opacity: { type: 'f', value: opacity }, | ||
smooth: { type: 'f', value: smooth }, | ||
map: { type: 't', value: opt.map || new THREE.Texture() }, | ||
color: { type: 'c', value: new THREE.Color(opt.color) } | ||
map: { type: 't', value: map || new THREE.Texture() }, | ||
color: { type: 'c', value: new THREE.Color(color) } | ||
}, | ||
vertexShader: [ | ||
"attribute float page;", | ||
"varying vec2 vUv;", | ||
"varying float vPage;", | ||
"void main() {", | ||
"vUv = uv;", | ||
"vPage = page;", | ||
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position.xyz, 1.0 );", | ||
"}" | ||
].join("\n"), | ||
fragmentShader: [ | ||
'attribute vec2 uv;', | ||
'attribute vec4 position;', | ||
'uniform mat4 projectionMatrix;', | ||
'uniform mat4 modelViewMatrix;', | ||
'varying vec2 vUv;', | ||
'void main() {', | ||
'vUv = uv;', | ||
'gl_Position = projectionMatrix * modelViewMatrix * position;', | ||
'}' | ||
].join('\n'), | ||
fragmentShader: [ | ||
'#ifdef GL_OES_standard_derivatives', | ||
'#extension GL_OES_standard_derivatives : enable', | ||
'#endif', | ||
'precision ' + precision + ' float;', | ||
'uniform float opacity;', | ||
'uniform vec3 color;', | ||
'uniform sampler2D map;', | ||
'varying vec2 vUv;', | ||
"#define SQRT2 1.4142135623730951", | ||
"uniform float opacity;", | ||
"uniform vec3 color;", | ||
"uniform sampler2D map;", | ||
"uniform float smooth;", | ||
"varying float vPage;", | ||
"varying vec2 vUv;", | ||
"void main() {", | ||
"vec4 texColor = texture2D(map, vUv);", | ||
"float dst = texColor.a;", | ||
"float afwidth = smooth * SQRT2 / (2.0 * gl_FragCoord.w);", | ||
"float alpha = smoothstep(0.5 - afwidth, 0.5 + afwidth, dst);", | ||
'float aastep(float value) {', | ||
' #ifdef GL_OES_standard_derivatives', | ||
' float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;', | ||
' #else', | ||
' float afwidth = (1.0 / 32.0) * (1.4142135623730951 / (2.0 * gl_FragCoord.w));', | ||
' #endif', | ||
' return smoothstep(0.5 - afwidth, 0.5 + afwidth, value);', | ||
'}', | ||
"gl_FragColor = vec4(color, opacity * alpha);", | ||
THREE.ShaderChunk["alphatest_fragment"], | ||
"}" | ||
].join("\n"), | ||
defines: { | ||
"USE_MAP": "", | ||
"ALPHATEST": Number(alphaTest || 0).toFixed(1) | ||
} | ||
'void main() {', | ||
' vec4 texColor = texture2D(map, vUv);', | ||
' float alpha = aastep(texColor.a);', | ||
' gl_FragColor = vec4(color, opacity * alpha);', | ||
alphaTest === 0 | ||
? '' | ||
: ' if (gl_FragColor.a < ' + alphaTest + ') discard;', | ||
'}' | ||
].join('\n') | ||
}, opt) | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
19302
8
8
337
166
5
1
+ Addedobject-assign@^4.0.1
+ Addedflatten-vertex-data@1.0.2(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedthree-buffer-vertex-data@1.1.0(transitive)
- Removedxtend@^4.0.0