troika-three-text
Advanced tools
Comparing version 0.50.3 to 0.51.0
@@ -6,2 +6,20 @@ # Change Log | ||
# [0.51.0](https://github.com/protectwise/troika/compare/v0.50.3...v0.51.0) (2024-11-10) | ||
### Bug Fixes | ||
* **BatchedText:** Fix texel read for taller data texture ([57f3b0b](https://github.com/protectwise/troika/commit/57f3b0bfa6f13d7311d51e1cb4c3b0e1caf17458)) | ||
* **troika-three-text:** Fix error when first character is whitespace [#313](https://github.com/protectwise/troika/issues/313) ([f71679e](https://github.com/protectwise/troika/commit/f71679e97a3850057ff85054d10326c8100c5328)) | ||
### Features | ||
* **BatchedText:** support fillOpacity, and color now sets the `diffuse` uniform ([8f83424](https://github.com/protectwise/troika/commit/8f8342447f3fe4a31420cf46fdb191ddc0afb929)) | ||
* **troika-three-text:** Add config to disable web worker ([86023ec](https://github.com/protectwise/troika/commit/86023ecd1ce00cebc3094088f935de5c129d5201)), closes [#337](https://github.com/protectwise/troika/issues/337) | ||
## [0.50.3](https://github.com/protectwise/troika/compare/v0.50.2...v0.50.3) (2024-11-01) | ||
@@ -8,0 +26,0 @@ |
{ | ||
"name": "troika-three-text", | ||
"version": "0.50.3", | ||
"version": "0.51.0", | ||
"description": "SDF-based text rendering for Three.js", | ||
@@ -18,4 +18,4 @@ "author": "Jason Johnston <jason.johnston@protectwise.com>", | ||
"bidi-js": "^1.0.2", | ||
"troika-three-utils": "^0.50.3", | ||
"troika-worker-utils": "^0.50.0", | ||
"troika-three-utils": "^0.51.0", | ||
"troika-worker-utils": "^0.51.0", | ||
"webgl-sdf-generator": "1.1.1" | ||
@@ -37,3 +37,3 @@ }, | ||
}, | ||
"gitHead": "afcf40d9063b5dd0cb3c495f2f14ff0b1a9dc668" | ||
"gitHead": "9c214c7b2c85d14b886ef3542d5313b32a7cc8f2" | ||
} |
@@ -368,3 +368,14 @@ # Troika Text for Three.js | ||
### Disabling web worker | ||
Some environments don't allow evaluating JS strings for security reasons, like those with a restrictive [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), which blocks how troika-three-text creates its web worker. Or you may want to avoid using a worker for some other reason. You can force it to run on the main thread instead (although still asynchronously) by configuring it prior to creating any Text instances: | ||
```js | ||
import {configureTextBuilder} from 'troika-three-text' | ||
configureTextBuilder({ | ||
useWorker: false | ||
}) | ||
``` | ||
## Preloading | ||
@@ -371,0 +382,0 @@ |
@@ -13,2 +13,3 @@ import { Text } from "./Text.js"; | ||
// 16: color | ||
// 17: fillOpacity | ||
// TODO: | ||
@@ -18,5 +19,4 @@ // total bounds for uv | ||
// strokeWidth/Color/Opacity | ||
// fillOpacity | ||
// clipRect | ||
let floatsPerMember = 17; | ||
let floatsPerMember = 18; | ||
floatsPerMember = Math.ceil(floatsPerMember / 4) * 4; // whole texels | ||
@@ -168,3 +168,3 @@ | ||
// Color | ||
// Color + opacity | ||
let color = text.color; | ||
@@ -175,2 +175,3 @@ if (color == null) color = this.color; | ||
setTexData(startIndex + 16, tempColor.set(color).getHex()); | ||
setTexData(startIndex + 17, text.fillOpacity == null ? 1 : text.fillOpacity) | ||
@@ -289,4 +290,10 @@ // TODO: | ||
const texSizeUniformName = "uTroikaMatricesTextureSize"; | ||
const colorVaryingName = "vTroikaTextColor"; | ||
const batchMaterial = createDerivedMaterial(baseMaterial, { | ||
const fillOpacityVaryingName = "vTroikaFillOpacity"; | ||
// Due to how vertexTransform gets injected, the matrix transforms must happen | ||
// in the base material of TextDerivedMaterial, but other transforms to its | ||
// shader must come after, so we sandwich it between two derivations. | ||
// Transform the vertex position | ||
let batchMaterial = createDerivedMaterial(baseMaterial, { | ||
chained: true, | ||
@@ -302,40 +309,61 @@ uniforms: { | ||
attribute float ${memberIndexAttrName}; | ||
varying vec3 ${colorVaryingName}; | ||
vec4 troikaGetTexel(float i) { | ||
vec4 troikaBatchTexel(float offset) { | ||
offset += ${memberIndexAttrName} * ${floatsPerMember.toFixed(1)} / 4.0; | ||
float w = ${texSizeUniformName}.x; | ||
vec2 uv = (vec2(mod(i, w), floor(i / w)) + 0.5) / w; | ||
vec2 uv = (vec2(mod(offset, w), floor(offset / w)) + 0.5) / ${texSizeUniformName}; | ||
return texture2D(${texUniformName}, uv); | ||
} | ||
vec3 troikaFloatToColor(float v) { | ||
return mod(floor(vec3(v / 65536.0, v / 256.0, v)), 256.0) / 256.0; | ||
} | ||
`, | ||
// language=GLSL prefix="void main() {" suffix="}" | ||
vertexTransform: ` | ||
float i = ${memberIndexAttrName} * ${floatsPerMember.toFixed(1)} / 4.0; | ||
mat4 matrix = mat4( | ||
troikaGetTexel(i), | ||
troikaGetTexel(i + 1.0), | ||
troikaGetTexel(i + 2.0), | ||
troikaGetTexel(i + 3.0) | ||
troikaBatchTexel(0.0), | ||
troikaBatchTexel(1.0), | ||
troikaBatchTexel(2.0), | ||
troikaBatchTexel(3.0) | ||
); | ||
position.xyz = (matrix * vec4(position, 1.0)).xyz; | ||
`, | ||
}); | ||
float packedColor = troikaGetTexel(i + 4.0).r; | ||
${colorVaryingName} = troikaFloatToColor(packedColor); | ||
`, | ||
// Add the text shaders | ||
batchMaterial = createTextDerivedMaterial(batchMaterial); | ||
// Now make other changes to the derived text shader code | ||
batchMaterial = createDerivedMaterial(batchMaterial, { | ||
chained: true, | ||
customRewriter({vertexShader, fragmentShader}) { | ||
// Convert some text shader uniforms to varyings | ||
function uniformToVarying(shader, uniformName, varyingName) { | ||
return shader.replace( | ||
new RegExp(`(uniform\\s+(float|vec[234])\\s+)?\\b${uniformName}\\b`, 'g'), | ||
(_, isDeclaration, type) => { | ||
return (isDeclaration ? `varying ${type} ` : '') + varyingName | ||
} | ||
); | ||
} | ||
fragmentShader = uniformToVarying(fragmentShader, 'uTroikaFillOpacity', fillOpacityVaryingName); | ||
// Strip out diffuse uniform from the vertex shader, if it was added by | ||
// TextDerivedMaterial, and replace with a writeable var | ||
vertexShader = 'vec3 diffuse;\n' + vertexShader.replace(/uniform vec3 diffuse;/, '') | ||
return {vertexShader, fragmentShader} | ||
}, | ||
// language=GLSL | ||
fragmentDefs: ` | ||
varying vec3 ${colorVaryingName}; | ||
vertexDefs: ` | ||
varying float ${fillOpacityVaryingName}; | ||
vec3 troikaFloatToColor(float v) { | ||
return mod(floor(vec3(v / 65536.0, v / 256.0, v)), 256.0) / 256.0; | ||
} | ||
`, | ||
// language=GLSL prefix="void main() {" suffix="}" | ||
fragmentColorTransform: ` | ||
gl_FragColor.rgb = ${colorVaryingName}; | ||
` | ||
// TODO: If the base shader has a diffuse color modify that rather than gl_FragColor | ||
// customRewriter({vertexShader, fragmentShader}) { | ||
// return {vertexShader, fragmentShader} | ||
// }, | ||
vertexMainIntro: ` | ||
vec4 colorData = troikaBatchTexel(4.0); | ||
diffuse = troikaFloatToColor(colorData.r); | ||
${fillOpacityVaryingName} = colorData.g; | ||
`, | ||
}); | ||
batchMaterial.setMatrixTexture = (texture) => { | ||
@@ -345,4 +373,4 @@ batchMaterial.uniforms[texUniformName].value = texture; | ||
}; | ||
return createTextDerivedMaterial(batchMaterial); | ||
return batchMaterial; | ||
} | ||
@@ -150,3 +150,3 @@ import fontParser from "./FontParser.js"; | ||
(prevCharResult === RESOLVED && fontResolutions[charResolutions[i - 1]].supportsCodePoint(codePoint)) || | ||
/\s/.test(text[i]) | ||
(i > 0 && /\s/.test(text[i])) | ||
) { | ||
@@ -157,3 +157,3 @@ charResolutions[i] = charResolutions[i - 1] | ||
} | ||
} else { | ||
} else { | ||
for (let j = charResolutions[i], jLen = userFonts.length; j <= jLen; j++) { | ||
@@ -160,0 +160,0 @@ if (j === jLen) { |
@@ -16,2 +16,3 @@ import { Color, Texture, LinearFilter } from 'three' | ||
textureWidth: 2048, | ||
useWorker: true, | ||
} | ||
@@ -55,2 +56,3 @@ const tempColor = /*#__PURE__*/new Color() | ||
* increase the glyph size and/or have an extraordinary number of glyphs. | ||
* @param {Boolean} config.useWorker - Whether to run typesetting in a web worker. Defaults to true. | ||
*/ | ||
@@ -194,3 +196,4 @@ function configureTextBuilder(config) { | ||
// Issue request to the typesetting engine in the worker | ||
typesetInWorker(args).then(result => { | ||
const typeset = CONFIG.useWorker ? typesetInWorker : typesetOnMainThread | ||
typeset(args).then(result => { | ||
const {glyphIds, glyphFontIndices, fontData, glyphPositions, fontSize, timings} = result | ||
@@ -482,2 +485,4 @@ const neededSDFs = [] | ||
const typesetOnMainThread = typesetInWorker.onMainThread | ||
function dumpSDFTextures() { | ||
@@ -484,0 +489,0 @@ Object.keys(atlases).forEach(size => { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
728575
11801
440
+ Addedtroika-three-utils@0.51.0(transitive)
+ Addedtroika-worker-utils@0.51.1(transitive)
- Removedtroika-three-utils@0.50.3(transitive)
- Removedtroika-worker-utils@0.50.0(transitive)
Updatedtroika-three-utils@^0.51.0
Updatedtroika-worker-utils@^0.51.0