Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

troika-three-utils

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

troika-three-utils - npm Package Compare versions

Comparing version 0.37.0 to 0.38.0

0

__tests__/ShaderFloatArray.test.js

@@ -0,0 +0,0 @@ import { encodeFloatToFourInts, decodeFloatFromFourInts } from '../src/ShaderFloatArray.js'

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [0.38.0](https://github.com/protectwise/troika/compare/v0.37.0...v0.38.0) (2021-01-24)
### Features
* move InstancedUniformsMesh to its own three-instanced-uniforms-mesh package ([f623b1f](https://github.com/protectwise/troika/commit/f623b1f2307b0db094912246ee4cf4bef54ffd85))
# [0.37.0](https://github.com/protectwise/troika/compare/v0.36.1...v0.37.0) (2021-01-18)

@@ -8,0 +19,0 @@

190

dist/troika-three-utils.esm.js

@@ -1,2 +0,2 @@

import { ShaderChunk, MathUtils, UniformsUtils, MeshDepthMaterial, RGBADepthPacking, MeshDistanceMaterial, ShaderLib, MeshBasicMaterial, InstancedMesh, InstancedBufferAttribute, Vector3, Mesh, CylinderBufferGeometry, Vector2, MeshStandardMaterial, DoubleSide } from 'three';
import { ShaderChunk, MathUtils, UniformsUtils, MeshDepthMaterial, RGBADepthPacking, MeshDistanceMaterial, ShaderLib, Vector3, Mesh, CylinderBufferGeometry, Vector2, MeshStandardMaterial, DoubleSide } from 'three';

@@ -469,188 +469,2 @@ /**

const precededByUniformRE = /\buniform\s+(int|float|vec[234])\s+$/;
const attrRefReplacer = (name, index, str) => (precededByUniformRE.test(str.substr(0, index)) ? name : `troika_${name}`);
const varyingRefReplacer = (name, index, str) => (precededByUniformRE.test(str.substr(0, index)) ? name : `troika_vary_${name}`);
function createInstancedUniformsDerivedMaterial (baseMaterial, uniformNames) {
const derived = createDerivedMaterial(baseMaterial, {
defines: {
TROIKA_INSTANCED_UNIFORMS: uniformNames.sort().join('|')
},
customRewriter ({ vertexShader, fragmentShader }) {
let vertexDeclarations = [];
let vertexAssignments = [];
let fragmentDeclarations = [];
// Find what uniforms are declared in which shader and their types
let vertexUniforms = getShaderUniformTypes(vertexShader);
let fragmentUniforms = getShaderUniformTypes(fragmentShader);
// Add attributes and varyings for, and rewrite references to, instanceUniforms
uniformNames.forEach((name) => {
let vertType = vertexUniforms[name];
let fragType = fragmentUniforms[name];
if (vertType || fragType) {
let finder = new RegExp(`\\b${name}\\b`, 'g');
vertexDeclarations.push(`attribute ${vertType || fragType} troika_attr_${name};`);
if (vertType) {
vertexShader = vertexShader.replace(finder, attrRefReplacer);
}
if (fragType) {
fragmentShader = fragmentShader.replace(finder, varyingRefReplacer);
let varyingDecl = `varying ${fragType} troika_vary_${name};`;
vertexDeclarations.push(varyingDecl);
fragmentDeclarations.push(varyingDecl);
vertexAssignments.push(`troika_vary_${name} = troika_attr_${name};`);
}
}
});
// Inject vertex shader declarations and assignments
vertexShader = `${vertexDeclarations.join('\n')}\n${vertexShader.replace(voidMainRegExp, `\n$&\n${vertexAssignments.join('\n')}`)}`;
// Inject fragment shader declarations
if (fragmentDeclarations.length) {
fragmentShader = `${fragmentDeclarations.join('\n')}\n${fragmentShader}`;
}
return { vertexShader, fragmentShader }
}
});
derived.isInstancedUniformsMaterial = true;
return derived
}
const defaultMaterial = new MeshBasicMaterial();
class InstancedUniformsMesh extends InstancedMesh {
constructor (geometry, material, count) {
super(geometry, material, count);
this._instancedUniformNames = []; //treated as immutable
}
/*
* Getter/setter for automatically wrapping the user-supplied geometry with one that will
* carry our extra InstancedBufferAttribute(s)
*/
get geometry () {
return this._derivedGeometry
}
set geometry (geometry) {
// Extend the geometry so we can add our instancing attributes but inherit everything else
if (geometry) {
geometry = Object.create(geometry);
geometry.attributes = Object.create(geometry.attributes);
}
this._derivedGeometry = geometry;
}
/*
* Getter/setter for automatically wrapping the user-supplied material with our upgrades. We do the
* wrapping lazily on _read_ rather than write to avoid unnecessary wrapping on transient values.
*/
get material () {
let derivedMaterial = this._derivedMaterial;
const baseMaterial = this._baseMaterial || this._defaultMaterial || (this._defaultMaterial = defaultMaterial.clone());
const uniformNames = this._instancedUniformNames;
if (!derivedMaterial || derivedMaterial.baseMaterial !== baseMaterial || derivedMaterial._instancedUniformNames !== uniformNames) {
derivedMaterial = this._derivedMaterial = createInstancedUniformsDerivedMaterial(baseMaterial, uniformNames);
derivedMaterial._instancedUniformNames = uniformNames;
// dispose the derived material when its base material is disposed:
baseMaterial.addEventListener('dispose', function onDispose () {
baseMaterial.removeEventListener('dispose', onDispose);
derivedMaterial.dispose();
});
}
return derivedMaterial
}
set material (baseMaterial) {
if (Array.isArray(baseMaterial)) {
throw new Error('InstancedUniformsMesh does not support multiple materials')
}
// Unwrap already-derived materials
while (baseMaterial && baseMaterial.isInstancedUniformsMaterial) {
baseMaterial = baseMaterial.baseMaterial;
}
this._baseMaterial = baseMaterial;
}
get customDepthMaterial () {
return this.material.getDepthMaterial()
}
get customDistanceMaterial () {
return this.material.getDistanceMaterial()
}
/**
* Set the value of a shader uniform for a single instance.
* @param {string} name - the name of the shader uniform
* @param {number} index - the index of the instance to set the value for
* @param {number|Vector2|Vector3|Vector4|Color|Array} value - the uniform value for this instance
*/
setUniformAt (name, index, value) {
const attrs = this.geometry.attributes;
const attrName = `troika_attr_${name}`;
let attr = attrs[attrName];
if (!attr) {
const defaultValue = getDefaultUniformValue(this._baseMaterial, name);
const itemSize = getItemSizeForValue(defaultValue);
attr = attrs[attrName] = new InstancedBufferAttribute(new Float32Array(itemSize * this.count), itemSize);
// Fill with default value:
if (defaultValue !== null) {
for (let i = 0; i < this.count; i++) {
setAttributeValue(attr, i, defaultValue);
}
}
this._instancedUniformNames = [...this._instancedUniformNames, name];
}
setAttributeValue(attr, index, value);
attr.needsUpdate = true;
}
}
function setAttributeValue (attr, index, value) {
let size = attr.itemSize;
if (size === 1) {
attr.setX(index, value);
} else if (size === 2) {
attr.setXY(index, value.x, value.y);
} else if (size === 3) {
if (value.isColor) {
attr.setXYZ(index, value.r, value.g, value.b);
} else {
attr.setXYZ(index, value.x, value.y, value.z);
}
} else if (size === 4) {
attr.setXYZW(index, value.x, value.y, value.z, value.w);
}
}
function getDefaultUniformValue (material, name) {
// Try uniforms on the material itself, then try the builtin material shaders
let uniforms = material.uniforms;
if (uniforms && uniforms[name]) {
return uniforms[name].value
}
uniforms = getShadersForMaterial(material).uniforms;
if (uniforms && uniforms[name]) {
return uniforms[name].value
}
return null
}
function getItemSizeForValue (value) {
return value == null ? 0
: typeof value === 'number' ? 1
: value.isVector2 ? 2
: value.isVector3 || value.isColor ? 3
: value.isVector4 ? 4
: Array.isArray(value) ? value.length
: 0
}
/*

@@ -865,2 +679,2 @@ Input geometry is a cylinder with r=1, height in y dimension from 0 to 1,

export { BezierMesh, InstancedUniformsMesh, createDerivedMaterial, expandShaderIncludes, getShaderUniformTypes, getShadersForMaterial, voidMainRegExp };
export { BezierMesh, createDerivedMaterial, expandShaderIncludes, getShaderUniformTypes, getShadersForMaterial, voidMainRegExp };

@@ -458,201 +458,2 @@ (function (global, factory) {

var precededByUniformRE = /\buniform\s+(int|float|vec[234])\s+$/;
var attrRefReplacer = function (name, index, str) { return (precededByUniformRE.test(str.substr(0, index)) ? name : ("troika_" + name)); };
var varyingRefReplacer = function (name, index, str) { return (precededByUniformRE.test(str.substr(0, index)) ? name : ("troika_vary_" + name)); };
function createInstancedUniformsDerivedMaterial (baseMaterial, uniformNames) {
var derived = createDerivedMaterial(baseMaterial, {
defines: {
TROIKA_INSTANCED_UNIFORMS: uniformNames.sort().join('|')
},
customRewriter: function customRewriter (ref) {
var vertexShader = ref.vertexShader;
var fragmentShader = ref.fragmentShader;
var vertexDeclarations = [];
var vertexAssignments = [];
var fragmentDeclarations = [];
// Find what uniforms are declared in which shader and their types
var vertexUniforms = getShaderUniformTypes(vertexShader);
var fragmentUniforms = getShaderUniformTypes(fragmentShader);
// Add attributes and varyings for, and rewrite references to, instanceUniforms
uniformNames.forEach(function (name) {
var vertType = vertexUniforms[name];
var fragType = fragmentUniforms[name];
if (vertType || fragType) {
var finder = new RegExp(("\\b" + name + "\\b"), 'g');
vertexDeclarations.push(("attribute " + (vertType || fragType) + " troika_attr_" + name + ";"));
if (vertType) {
vertexShader = vertexShader.replace(finder, attrRefReplacer);
}
if (fragType) {
fragmentShader = fragmentShader.replace(finder, varyingRefReplacer);
var varyingDecl = "varying " + fragType + " troika_vary_" + name + ";";
vertexDeclarations.push(varyingDecl);
fragmentDeclarations.push(varyingDecl);
vertexAssignments.push(("troika_vary_" + name + " = troika_attr_" + name + ";"));
}
}
});
// Inject vertex shader declarations and assignments
vertexShader = (vertexDeclarations.join('\n')) + "\n" + (vertexShader.replace(voidMainRegExp, ("\n$&\n" + (vertexAssignments.join('\n')))));
// Inject fragment shader declarations
if (fragmentDeclarations.length) {
fragmentShader = (fragmentDeclarations.join('\n')) + "\n" + fragmentShader;
}
return { vertexShader: vertexShader, fragmentShader: fragmentShader }
}
});
derived.isInstancedUniformsMaterial = true;
return derived
}
var defaultMaterial = new three.MeshBasicMaterial();
var InstancedUniformsMesh = /*@__PURE__*/(function (InstancedMesh) {
function InstancedUniformsMesh (geometry, material, count) {
InstancedMesh.call(this, geometry, material, count);
this._instancedUniformNames = []; //treated as immutable
}
if ( InstancedMesh ) InstancedUniformsMesh.__proto__ = InstancedMesh;
InstancedUniformsMesh.prototype = Object.create( InstancedMesh && InstancedMesh.prototype );
InstancedUniformsMesh.prototype.constructor = InstancedUniformsMesh;
var prototypeAccessors = { geometry: { configurable: true },material: { configurable: true },customDepthMaterial: { configurable: true },customDistanceMaterial: { configurable: true } };
/*
* Getter/setter for automatically wrapping the user-supplied geometry with one that will
* carry our extra InstancedBufferAttribute(s)
*/
prototypeAccessors.geometry.get = function () {
return this._derivedGeometry
};
prototypeAccessors.geometry.set = function (geometry) {
// Extend the geometry so we can add our instancing attributes but inherit everything else
if (geometry) {
geometry = Object.create(geometry);
geometry.attributes = Object.create(geometry.attributes);
}
this._derivedGeometry = geometry;
};
/*
* Getter/setter for automatically wrapping the user-supplied material with our upgrades. We do the
* wrapping lazily on _read_ rather than write to avoid unnecessary wrapping on transient values.
*/
prototypeAccessors.material.get = function () {
var derivedMaterial = this._derivedMaterial;
var baseMaterial = this._baseMaterial || this._defaultMaterial || (this._defaultMaterial = defaultMaterial.clone());
var uniformNames = this._instancedUniformNames;
if (!derivedMaterial || derivedMaterial.baseMaterial !== baseMaterial || derivedMaterial._instancedUniformNames !== uniformNames) {
derivedMaterial = this._derivedMaterial = createInstancedUniformsDerivedMaterial(baseMaterial, uniformNames);
derivedMaterial._instancedUniformNames = uniformNames;
// dispose the derived material when its base material is disposed:
baseMaterial.addEventListener('dispose', function onDispose () {
baseMaterial.removeEventListener('dispose', onDispose);
derivedMaterial.dispose();
});
}
return derivedMaterial
};
prototypeAccessors.material.set = function (baseMaterial) {
if (Array.isArray(baseMaterial)) {
throw new Error('InstancedUniformsMesh does not support multiple materials')
}
// Unwrap already-derived materials
while (baseMaterial && baseMaterial.isInstancedUniformsMaterial) {
baseMaterial = baseMaterial.baseMaterial;
}
this._baseMaterial = baseMaterial;
};
prototypeAccessors.customDepthMaterial.get = function () {
return this.material.getDepthMaterial()
};
prototypeAccessors.customDistanceMaterial.get = function () {
return this.material.getDistanceMaterial()
};
/**
* Set the value of a shader uniform for a single instance.
* @param {string} name - the name of the shader uniform
* @param {number} index - the index of the instance to set the value for
* @param {number|Vector2|Vector3|Vector4|Color|Array} value - the uniform value for this instance
*/
InstancedUniformsMesh.prototype.setUniformAt = function setUniformAt (name, index, value) {
var attrs = this.geometry.attributes;
var attrName = "troika_attr_" + name;
var attr = attrs[attrName];
if (!attr) {
var defaultValue = getDefaultUniformValue(this._baseMaterial, name);
var itemSize = getItemSizeForValue(defaultValue);
attr = attrs[attrName] = new three.InstancedBufferAttribute(new Float32Array(itemSize * this.count), itemSize);
// Fill with default value:
if (defaultValue !== null) {
for (var i = 0; i < this.count; i++) {
setAttributeValue(attr, i, defaultValue);
}
}
this._instancedUniformNames = ( this._instancedUniformNames ).concat( [name]);
}
setAttributeValue(attr, index, value);
attr.needsUpdate = true;
};
Object.defineProperties( InstancedUniformsMesh.prototype, prototypeAccessors );
return InstancedUniformsMesh;
}(three.InstancedMesh));
function setAttributeValue (attr, index, value) {
var size = attr.itemSize;
if (size === 1) {
attr.setX(index, value);
} else if (size === 2) {
attr.setXY(index, value.x, value.y);
} else if (size === 3) {
if (value.isColor) {
attr.setXYZ(index, value.r, value.g, value.b);
} else {
attr.setXYZ(index, value.x, value.y, value.z);
}
} else if (size === 4) {
attr.setXYZW(index, value.x, value.y, value.z, value.w);
}
}
function getDefaultUniformValue (material, name) {
// Try uniforms on the material itself, then try the builtin material shaders
var uniforms = material.uniforms;
if (uniforms && uniforms[name]) {
return uniforms[name].value
}
uniforms = getShadersForMaterial(material).uniforms;
if (uniforms && uniforms[name]) {
return uniforms[name].value
}
return null
}
function getItemSizeForValue (value) {
return value == null ? 0
: typeof value === 'number' ? 1
: value.isVector2 ? 2
: value.isVector3 || value.isColor ? 3
: value.isVector4 ? 4
: Array.isArray(value) ? value.length
: 0
}
/*

@@ -826,3 +627,2 @@ Input geometry is a cylinder with r=1, height in y dimension from 0 to 1,

exports.BezierMesh = BezierMesh;
exports.InstancedUniformsMesh = InstancedUniformsMesh;
exports.createDerivedMaterial = createDerivedMaterial;

@@ -829,0 +629,0 @@ exports.expandShaderIncludes = expandShaderIncludes;

@@ -1,22 +0,16 @@

'use strict';(function(h,f){"object"===typeof exports&&"undefined"!==typeof module?f(exports,require("three")):"function"===typeof define&&define.amd?define(["exports","three"],f):(h=h||self,f(h.troika_three_utils={},h.THREE))})(this,function(h,f){function r(b){return b.replace(/^[ \t]*#include +<([\w\d./]+)>/gm,function(b,d){return(d=f.ShaderChunk[d])?r(d):b})}function q(b,c){var d=G(c),a=x.get(b);a||x.set(b,a=Object.create(null));if(a[d])return new a[d];var e="_onBeforeCompile"+d,t=function(a){b.onBeforeCompile.call(this,
a);var m=d+"|||"+a.vertexShader+"|||"+a.fragmentShader,g=y[m];g||(g=H(a,c,d),g=y[m]=g);a.vertexShader=g.vertexShader;a.fragmentShader=g.fragmentShader;l(a.uniforms,this.uniforms);c.timeUniform&&(a.uniforms[c.timeUniform]={get value(){return Date.now()-I}});if(this[e])this[e](a)},k=function(){return n(c.chained?b:b.clone())},n=function(a){var e=Object.create(a,g);Object.defineProperty(e,"baseMaterial",{value:b});Object.defineProperty(e,"id",{value:J++});e.uuid=f.MathUtils.generateUUID();e.uniforms=
l({},a.uniforms,c.uniforms);e.defines=l({},a.defines,c.defines);e.defines["TROIKA_DERIVED_MATERIAL_"+d]="";e.extensions=l({},a.extensions,c.extensions);e._listeners=void 0;return e},g={constructor:{value:k},isDerivedMaterial:{value:!0},customProgramCacheKey:{value:function(){return d}},onBeforeCompile:{get:function(){return t},set:function(a){this[e]=a}},copy:{writable:!0,configurable:!0,value:function(a){b.copy.call(this,a);b.isShaderMaterial||b.isDerivedMaterial||(l(this.extensions,a.extensions),
l(this.defines,a.defines),l(this.uniforms,f.UniformsUtils.clone(a.uniforms)));return this}},clone:{writable:!0,configurable:!0,value:function(){var a=new b.constructor;return n(a).copy(this)}},getDepthMaterial:{writable:!0,configurable:!0,value:function(){var a=this._depthMaterial;a||(a=this._depthMaterial=q(b.isDerivedMaterial?b.getDepthMaterial():new f.MeshDepthMaterial({depthPacking:f.RGBADepthPacking}),c),a.defines.IS_DEPTH_MATERIAL="",a.uniforms=this.uniforms);return a}},getDistanceMaterial:{writable:!0,
configurable:!0,value:function(){var a=this._distanceMaterial;a||(a=this._distanceMaterial=q(b.isDerivedMaterial?b.getDistanceMaterial():new f.MeshDistanceMaterial,c),a.defines.IS_DISTANCE_MATERIAL="",a.uniforms=this.uniforms);return a}},dispose:{writable:!0,configurable:!0,value:function(){var a=this._depthMaterial,c=this._distanceMaterial;a&&a.dispose();c&&c.dispose();b.dispose.call(this)}}};a[d]=k;return new k}function H(b,c,d){var a=b.vertexShader,e=b.fragmentShader;b=c.vertexDefs;var f=c.vertexMainIntro,
k=c.vertexMainOutro,n=c.vertexTransform,g=c.fragmentDefs,m=c.fragmentMainIntro,h=c.fragmentMainOutro,p=c.fragmentColorTransform,u=c.customRewriter;c=c.timeUniform;b=b||"";f=f||"";k=k||"";g=g||"";m=m||"";h=h||"";if(n||u)a=r(a);if(p||u)e=e.replace(/^[ \t]*#include <((?:tonemapping|encodings|fog|premultiplied_alpha|dithering)_fragment)>/gm,"\n//!BEGIN_POST_CHUNK $1\n$&\n//!END_POST_CHUNK\n"),e=r(e);u&&(e=u({vertexShader:a,fragmentShader:e}),a=e.vertexShader,e=e.fragmentShader);if(p){var l=[];e=e.replace(/^\/\/!BEGIN_POST_CHUNK[^]+?^\/\/!END_POST_CHUNK/gm,
function(a){l.push(a);return""});h=p+"\n"+l.join("\n")+"\n"+h}c&&(p="\nuniform float "+c+";\n",b=p+b,g=p+g);n&&(b=b+"\nvec3 troika_position_"+d+";\nvec3 troika_normal_"+d+";\nvec2 troika_uv_"+d+";\nvoid troikaVertexTransform"+d+"(inout vec3 position, inout vec3 normal, inout vec2 uv) {\n "+n+"\n}\n",f="\ntroika_position_"+d+" = vec3(position);\ntroika_normal_"+d+" = vec3(normal);\ntroika_uv_"+d+" = vec2(uv);\ntroikaVertexTransform"+d+"(troika_position_"+d+", troika_normal_"+d+", troika_uv_"+d+");\n"+
f+"\n",a=a.replace(/\b(position|normal|uv)\b/g,function(a,b,c,e){return/\battribute\s+vec[23]\s+$/.test(e.substr(0,c))?b:"troika_"+b+"_"+d}));a=z(a,d,b,f,k);e=z(e,d,g,m,h);return{vertexShader:a,fragmentShader:e}}function z(b,c,d,a,e){if(a||e||d)b=b.replace(v,"\n"+d+"\nvoid troikaOrigMain"+c+"() {"),b+="\nvoid main() {\n "+a+"\n troikaOrigMain"+c+"();\n "+e+"\n}";return b}function K(b,c){return"uniforms"===b?void 0:"function"===typeof c?c.toString():c}function G(b){b=JSON.stringify(b,K);var c=A.get(b);
null==c&&A.set(b,c=++L);return c}function B(b){var c=M[b.type];return c?f.ShaderLib[c]:b}function w(b){for(var c=/\buniform\s+(int|float|vec[234])\s+([A-Za-z_][\w]*)/g,d=Object.create(null),a;null!==(a=c.exec(b));)d[a[2]]=a[1];return d}function N(b,c){b=q(b,{defines:{TROIKA_INSTANCED_UNIFORMS:c.sort().join("|")},customRewriter:function(b){var a=b.vertexShader,d=b.fragmentShader,f=[],k=[],h=[],g=w(a),m=w(d);c.forEach(function(b){var c=g[b],e=m[b];if(c||e){var t=new RegExp("\\b"+b+"\\b","g");f.push("attribute "+
(c||e)+" troika_attr_"+b+";");c&&(a=a.replace(t,O));e&&(d=d.replace(t,P),c="varying "+e+" troika_vary_"+b+";",f.push(c),h.push(c),k.push("troika_vary_"+b+" = troika_attr_"+b+";"))}});a=f.join("\n")+"\n"+a.replace(v,"\n$&\n"+k.join("\n"));h.length&&(d=h.join("\n")+"\n"+d);return{vertexShader:a,fragmentShader:d}}});b.isInstancedUniformsMaterial=!0;return b}function C(b,c,d){var a=b.itemSize;1===a?b.setX(c,d):2===a?b.setXY(c,d.x,d.y):3===a?d.isColor?b.setXYZ(c,d.r,d.g,d.b):b.setXYZ(c,d.x,d.y,d.z):4===
a&&b.setXYZW(c,d.x,d.y,d.z,d.w)}var v=/\bvoid\s+main\s*\(\s*\)\s*{/g,l=Object.assign||function(){for(var b=arguments,c=arguments[0],d=1,a=arguments.length;d<a;d++){var e=b[d];if(e)for(var f in e)e.hasOwnProperty(f)&&(c[f]=e[f])}return c},I=Date.now(),x=new WeakMap,y=new Map,J=1E10,L=0,A=new Map,M={MeshDepthMaterial:"depth",MeshDistanceMaterial:"distanceRGBA",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"toon",MeshStandardMaterial:"physical",
MeshPhysicalMaterial:"physical",MeshMatcapMaterial:"matcap",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points",ShadowMaterial:"shadow",SpriteMaterial:"sprite"},D=/\buniform\s+(int|float|vec[234])\s+$/,O=function(b,c,d){return D.test(d.substr(0,c))?b:"troika_"+b},P=function(b,c,d){return D.test(d.substr(0,c))?b:"troika_vary_"+b},Q=new f.MeshBasicMaterial,R=function(b){function c(a,c,d){b.call(this,a,c,d);this._instancedUniformNames=[]}b&&(c.__proto__=b);c.prototype=Object.create(b&&
b.prototype);c.prototype.constructor=c;var d={geometry:{configurable:!0},material:{configurable:!0},customDepthMaterial:{configurable:!0},customDistanceMaterial:{configurable:!0}};d.geometry.get=function(){return this._derivedGeometry};d.geometry.set=function(a){a&&(a=Object.create(a),a.attributes=Object.create(a.attributes));this._derivedGeometry=a};d.material.get=function(){var a=this._derivedMaterial,b=this._baseMaterial||this._defaultMaterial||(this._defaultMaterial=Q.clone()),c=this._instancedUniformNames;
a&&a.baseMaterial===b&&a._instancedUniformNames===c||(a=this._derivedMaterial=N(b,c),a._instancedUniformNames=c,b.addEventListener("dispose",function n(){b.removeEventListener("dispose",n);a.dispose()}));return a};d.material.set=function(a){if(Array.isArray(a))throw Error("InstancedUniformsMesh does not support multiple materials");for(;a&&a.isInstancedUniformsMaterial;)a=a.baseMaterial;this._baseMaterial=a};d.customDepthMaterial.get=function(){return this.material.getDepthMaterial()};d.customDistanceMaterial.get=
function(){return this.material.getDistanceMaterial()};c.prototype.setUniformAt=function(a,b,c){var d=this.geometry.attributes,e="troika_attr_"+a,g=d[e];if(!g){var h=this._baseMaterial;h=(g=h.uniforms)&&g[a]?g[a].value:(g=B(h).uniforms)&&g[a]?g[a].value:null;g=h;g=null==g?0:"number"===typeof g?1:g.isVector2?2:g.isVector3||g.isColor?3:g.isVector4?4:Array.isArray(g)?g.length:0;g=d[e]=new f.InstancedBufferAttribute(new Float32Array(g*this.count),g);if(null!==h)for(d=0;d<this.count;d++)C(g,d,h);this._instancedUniformNames=
this._instancedUniformNames.concat([a])}C(g,b,c);g.needsUpdate=!0};Object.defineProperties(c.prototype,d);return c}(f.InstancedMesh),E=null,F=new f.MeshStandardMaterial({color:16777215,side:f.DoubleSide}),S=function(b){function c(){b.call(this,c.getGeometry(),F);this.pointA=new f.Vector3;this.controlA=new f.Vector3;this.controlB=new f.Vector3;this.pointB=new f.Vector3;this.radius=.01;this.dashArray=new f.Vector2;this.dashOffset=0;this.frustumCulled=!1}b&&(c.__proto__=b);c.prototype=Object.create(b&&
b.prototype);c.prototype.constructor=c;var d={material:{configurable:!0},customDepthMaterial:{configurable:!0},customDistanceMaterial:{configurable:!0}};c.getGeometry=function(){return E||(E=(new f.CylinderBufferGeometry(1,1,1,6,64)).translate(0,.5,0))};d.material.get=function(){var a=this._derivedMaterial,b=this._baseMaterial||this._defaultMaterial||(this._defaultMaterial=F.clone());a&&a.baseMaterial===b||(a=this._derivedMaterial=q(b,{chained:!0,uniforms:{pointA:{value:new f.Vector3},controlA:{value:new f.Vector3},
controlB:{value:new f.Vector3},pointB:{value:new f.Vector3},radius:{value:.01},dashing:{value:new f.Vector3}},vertexDefs:"\nuniform vec3 pointA;\nuniform vec3 controlA;\nuniform vec3 controlB;\nuniform vec3 pointB;\nuniform float radius;\nvarying float bezierT;\n\nvec3 cubicBezier(vec3 p1, vec3 c1, vec3 c2, vec3 p2, float t) {\n float t2 = 1.0 - t;\n float b0 = t2 * t2 * t2;\n float b1 = 3.0 * t * t2 * t2;\n float b2 = 3.0 * t * t * t2;\n float b3 = t * t * t;\n return b0 * p1 + b1 * c1 + b2 * c2 + b3 * p2;\n}\n\nvec3 cubicBezierDerivative(vec3 p1, vec3 c1, vec3 c2, vec3 p2, float t) {\n float t2 = 1.0 - t;\n return -3.0 * p1 * t2 * t2 +\n c1 * (3.0 * t2 * t2 - 6.0 * t2 * t) +\n c2 * (6.0 * t2 * t - 3.0 * t * t) +\n 3.0 * p2 * t * t;\n}\n",
'use strict';(function(f,c){"object"===typeof exports&&"undefined"!==typeof module?c(exports,require("three")):"function"===typeof define&&define.amd?define(["exports","three"],c):(f=f||self,c(f.troika_three_utils={},f.THREE))})(this,function(f,c){function r(b){return b.replace(/^[ \t]*#include +<([\w\d./]+)>/gm,function(a,b){return(b=c.ShaderChunk[b])?r(b):a})}function l(b,a){var e=z(a),d=q.get(b);d||q.set(b,d=Object.create(null));if(d[e])return new d[e];var g="_onBeforeCompile"+e,C=function(h){b.onBeforeCompile.call(this,
h);var d=e+"|||"+h.vertexShader+"|||"+h.fragmentShader,c=t[d];c||(c=A(h,a,e),c=t[d]=c);h.vertexShader=c.vertexShader;h.fragmentShader=c.fragmentShader;k(h.uniforms,this.uniforms);a.timeUniform&&(h.uniforms[a.timeUniform]={get value(){return Date.now()-B}});if(this[g])this[g](h)},f=function(){return p(a.chained?b:b.clone())},p=function(d){var h=Object.create(d,m);Object.defineProperty(h,"baseMaterial",{value:b});Object.defineProperty(h,"id",{value:E++});h.uuid=c.MathUtils.generateUUID();h.uniforms=
k({},d.uniforms,a.uniforms);h.defines=k({},d.defines,a.defines);h.defines["TROIKA_DERIVED_MATERIAL_"+e]="";h.extensions=k({},d.extensions,a.extensions);h._listeners=void 0;return h},m={constructor:{value:f},isDerivedMaterial:{value:!0},customProgramCacheKey:{value:function(){return e}},onBeforeCompile:{get:function(){return C},set:function(b){this[g]=b}},copy:{writable:!0,configurable:!0,value:function(a){b.copy.call(this,a);b.isShaderMaterial||b.isDerivedMaterial||(k(this.extensions,a.extensions),
k(this.defines,a.defines),k(this.uniforms,c.UniformsUtils.clone(a.uniforms)));return this}},clone:{writable:!0,configurable:!0,value:function(){var a=new b.constructor;return p(a).copy(this)}},getDepthMaterial:{writable:!0,configurable:!0,value:function(){var d=this._depthMaterial;d||(d=this._depthMaterial=l(b.isDerivedMaterial?b.getDepthMaterial():new c.MeshDepthMaterial({depthPacking:c.RGBADepthPacking}),a),d.defines.IS_DEPTH_MATERIAL="",d.uniforms=this.uniforms);return d}},getDistanceMaterial:{writable:!0,
configurable:!0,value:function(){var d=this._distanceMaterial;d||(d=this._distanceMaterial=l(b.isDerivedMaterial?b.getDistanceMaterial():new c.MeshDistanceMaterial,a),d.defines.IS_DISTANCE_MATERIAL="",d.uniforms=this.uniforms);return d}},dispose:{writable:!0,configurable:!0,value:function(){var a=this._depthMaterial,d=this._distanceMaterial;a&&a.dispose();d&&d.dispose();b.dispose.call(this)}}};d[e]=f;return new f}function A(b,a,e){var d=b.vertexShader,g=b.fragmentShader;b=a.vertexDefs;var c=a.vertexMainIntro,
f=a.vertexMainOutro,p=a.vertexTransform,m=a.fragmentDefs,h=a.fragmentMainIntro,k=a.fragmentMainOutro,n=a.fragmentColorTransform,l=a.customRewriter;a=a.timeUniform;b=b||"";c=c||"";f=f||"";m=m||"";h=h||"";k=k||"";if(p||l)d=r(d);if(n||l)g=g.replace(/^[ \t]*#include <((?:tonemapping|encodings|fog|premultiplied_alpha|dithering)_fragment)>/gm,"\n//!BEGIN_POST_CHUNK $1\n$&\n//!END_POST_CHUNK\n"),g=r(g);l&&(g=l({vertexShader:d,fragmentShader:g}),d=g.vertexShader,g=g.fragmentShader);if(n){var q=[];g=g.replace(/^\/\/!BEGIN_POST_CHUNK[^]+?^\/\/!END_POST_CHUNK/gm,
function(a){q.push(a);return""});k=n+"\n"+q.join("\n")+"\n"+k}a&&(n="\nuniform float "+a+";\n",b=n+b,m=n+m);p&&(b=b+"\nvec3 troika_position_"+e+";\nvec3 troika_normal_"+e+";\nvec2 troika_uv_"+e+";\nvoid troikaVertexTransform"+e+"(inout vec3 position, inout vec3 normal, inout vec2 uv) {\n "+p+"\n}\n",c="\ntroika_position_"+e+" = vec3(position);\ntroika_normal_"+e+" = vec3(normal);\ntroika_uv_"+e+" = vec2(uv);\ntroikaVertexTransform"+e+"(troika_position_"+e+", troika_normal_"+e+", troika_uv_"+e+");\n"+
c+"\n",d=d.replace(/\b(position|normal|uv)\b/g,function(a,d,b,c){return/\battribute\s+vec[23]\s+$/.test(c.substr(0,b))?d:"troika_"+d+"_"+e}));d=u(d,e,b,c,f);g=u(g,e,m,h,k);return{vertexShader:d,fragmentShader:g}}function u(b,a,c,d,g){if(d||g||c)b=b.replace(v,"\n"+c+"\nvoid troikaOrigMain"+a+"() {"),b+="\nvoid main() {\n "+d+"\n troikaOrigMain"+a+"();\n "+g+"\n}";return b}function F(b,a){return"uniforms"===b?void 0:"function"===typeof a?a.toString():a}function z(b){b=JSON.stringify(b,F);var a=w.get(b);
null==a&&w.set(b,a=++G);return a}var v=/\bvoid\s+main\s*\(\s*\)\s*{/g,k=Object.assign||function(){for(var b=arguments,a=arguments[0],c=1,d=arguments.length;c<d;c++){var g=b[c];if(g)for(var f in g)g.hasOwnProperty(f)&&(a[f]=g[f])}return a},B=Date.now(),q=new WeakMap,t=new Map,E=1E10,G=0,w=new Map,H={MeshDepthMaterial:"depth",MeshDistanceMaterial:"distanceRGBA",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"toon",MeshStandardMaterial:"physical",
MeshPhysicalMaterial:"physical",MeshMatcapMaterial:"matcap",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points",ShadowMaterial:"shadow",SpriteMaterial:"sprite"},x=null,y=new c.MeshStandardMaterial({color:16777215,side:c.DoubleSide}),I=function(b){function a(){b.call(this,a.getGeometry(),y);this.pointA=new c.Vector3;this.controlA=new c.Vector3;this.controlB=new c.Vector3;this.pointB=new c.Vector3;this.radius=.01;this.dashArray=new c.Vector2;this.dashOffset=0;this.frustumCulled=
!1}b&&(a.__proto__=b);a.prototype=Object.create(b&&b.prototype);a.prototype.constructor=a;var e={material:{configurable:!0},customDepthMaterial:{configurable:!0},customDistanceMaterial:{configurable:!0}};a.getGeometry=function(){return x||(x=(new c.CylinderBufferGeometry(1,1,1,6,64)).translate(0,.5,0))};e.material.get=function(){var a=this._derivedMaterial,b=this._baseMaterial||this._defaultMaterial||(this._defaultMaterial=y.clone());a&&a.baseMaterial===b||(a=this._derivedMaterial=l(b,{chained:!0,
uniforms:{pointA:{value:new c.Vector3},controlA:{value:new c.Vector3},controlB:{value:new c.Vector3},pointB:{value:new c.Vector3},radius:{value:.01},dashing:{value:new c.Vector3}},vertexDefs:"\nuniform vec3 pointA;\nuniform vec3 controlA;\nuniform vec3 controlB;\nuniform vec3 pointB;\nuniform float radius;\nvarying float bezierT;\n\nvec3 cubicBezier(vec3 p1, vec3 c1, vec3 c2, vec3 p2, float t) {\n float t2 = 1.0 - t;\n float b0 = t2 * t2 * t2;\n float b1 = 3.0 * t * t2 * t2;\n float b2 = 3.0 * t * t * t2;\n float b3 = t * t * t;\n return b0 * p1 + b1 * c1 + b2 * c2 + b3 * p2;\n}\n\nvec3 cubicBezierDerivative(vec3 p1, vec3 c1, vec3 c2, vec3 p2, float t) {\n float t2 = 1.0 - t;\n return -3.0 * p1 * t2 * t2 +\n c1 * (3.0 * t2 * t2 - 6.0 * t2 * t) +\n c2 * (6.0 * t2 * t - 3.0 * t * t) +\n 3.0 * p2 * t * t;\n}\n",
vertexTransform:'\nfloat t = position.y;\nbezierT = t;\nvec3 bezierCenterPos = cubicBezier(pointA, controlA, controlB, pointB, t);\nvec3 bezierDir = normalize(cubicBezierDerivative(pointA, controlA, controlB, pointB, t));\n\n// Make "sideways" always perpendicular to the camera ray; this ensures that any twists\n// in the cylinder occur where you won\'t see them: \nvec3 viewDirection = normalMatrix * vec3(0.0, 0.0, 1.0);\nif (bezierDir == viewDirection) {\n bezierDir = normalize(cubicBezierDerivative(pointA, controlA, controlB, pointB, t == 1.0 ? t - 0.0001 : t + 0.0001));\n}\nvec3 sideways = normalize(cross(bezierDir, viewDirection));\nvec3 upish = normalize(cross(sideways, bezierDir));\n\n// Build a matrix for transforming this disc in the cylinder:\nmat4 discTx;\ndiscTx[0].xyz = sideways * radius;\ndiscTx[1].xyz = bezierDir * radius;\ndiscTx[2].xyz = upish * radius;\ndiscTx[3].xyz = bezierCenterPos;\ndiscTx[3][3] = 1.0;\n\n// Apply transform, ignoring original y\nposition = (discTx * vec4(position.x, 0.0, position.z, 1.0)).xyz;\nnormal = normalize(mat3(discTx) * normal);\n',
fragmentDefs:"\nuniform vec3 dashing;\nvarying float bezierT;\n",fragmentMainIntro:"\nif (dashing.x + dashing.y > 0.0) {\n float dashFrac = mod(bezierT - dashing.z, dashing.x + dashing.y);\n if (dashFrac > dashing.x) {\n discard;\n }\n}\n"}),b.addEventListener("dispose",function k(){b.removeEventListener("dispose",k);a.dispose()}));return a};d.material.set=function(a){this._baseMaterial=a};d.customDepthMaterial.get=function(){return this.material.getDepthMaterial()};d.customDistanceMaterial.get=
function(){return this.material.getDistanceMaterial()};c.prototype.onBeforeRender=function(a){a=this.material.uniforms;var b=this.controlA,c=this.controlB,d=this.pointB,f=this.radius,g=this.dashArray,h=this.dashOffset;a.pointA.value.copy(this.pointA);a.controlA.value.copy(b);a.controlB.value.copy(c);a.pointB.value.copy(d);a.radius.value=f;a.dashing.value.set(g.x,g.y,h||0)};c.prototype.raycast=function(a,b){};Object.defineProperties(c.prototype,d);return c}(f.Mesh);h.BezierMesh=S;h.InstancedUniformsMesh=
R;h.createDerivedMaterial=q;h.expandShaderIncludes=r;h.getShaderUniformTypes=w;h.getShadersForMaterial=B;h.voidMainRegExp=v;Object.defineProperty(h,"__esModule",{value:!0})})
fragmentDefs:"\nuniform vec3 dashing;\nvarying float bezierT;\n",fragmentMainIntro:"\nif (dashing.x + dashing.y > 0.0) {\n float dashFrac = mod(bezierT - dashing.z, dashing.x + dashing.y);\n if (dashFrac > dashing.x) {\n discard;\n }\n}\n"}),b.addEventListener("dispose",function D(){b.removeEventListener("dispose",D);a.dispose()}));return a};e.material.set=function(a){this._baseMaterial=a};e.customDepthMaterial.get=function(){return this.material.getDepthMaterial()};e.customDistanceMaterial.get=
function(){return this.material.getDistanceMaterial()};a.prototype.onBeforeRender=function(a){a=this.material.uniforms;var b=this.controlA,d=this.controlB,c=this.pointB,e=this.radius,f=this.dashArray,h=this.dashOffset;a.pointA.value.copy(this.pointA);a.controlA.value.copy(b);a.controlB.value.copy(d);a.pointB.value.copy(c);a.radius.value=e;a.dashing.value.set(f.x,f.y,h||0)};a.prototype.raycast=function(a,b){};Object.defineProperties(a.prototype,e);return a}(c.Mesh);f.BezierMesh=I;f.createDerivedMaterial=
l;f.expandShaderIncludes=r;f.getShaderUniformTypes=function(b){for(var a=/\buniform\s+(int|float|vec[234])\s+([A-Za-z_][\w]*)/g,c=Object.create(null),d;null!==(d=a.exec(b));)c[d[2]]=d[1];return c};f.getShadersForMaterial=function(b){var a=H[b.type];return a?c.ShaderLib[a]:b};f.voidMainRegExp=v;Object.defineProperty(f,"__esModule",{value:!0})})
{
"name": "troika-three-utils",
"version": "0.37.0",
"version": "0.38.0",
"description": "Various utilities related to Three.js",

@@ -19,3 +19,3 @@ "author": "Jason Johnston <jason.johnston@protectwise.com>",

},
"gitHead": "f2c9c725b22a88ca3275c39150d75f6894ea3503"
"gitHead": "d48144bf99a2eaf2089c0cd2a8065506161dfdf4"
}

@@ -65,41 +65,7 @@ # Troika Three.js Utilities

### InstancedUniformsMesh
[Source code](./src/InstancedUniformsMesh.js)
This extends Three.js's [`InstancedMesh`](https://threejs.org/docs/#api/en/objects/InstancedMesh) to allow any of its material's shader uniforms to be set individually per instance. It behaves just like `InstancedMesh` but exposes a new `setUniformAt(uniformName, instanceIndex, value)` method.
When you call `setUniformAt`, the geometry and the material shaders will be automatically upgraded behind the scenes to turn that uniform into an instanced buffer attribute, filling in the other indices with the uniform's default value. You can do this for any uniform of type `float`, `vec2`, `vec3`, or `vec4`. It works both for built-in Three.js materials and also for any custom ShaderMaterial.
For example, here is how you could set random `emissive` and `metalness` values for each instance using a `MeshStandardMaterial`:
```js
import { InstancedUniformsMesh } from 'troika-three-utils'
const count = 100
const mesh = new InstancedUniformsMesh(
someGeometry,
new MeshStandardMaterial(),
count
)
const color = new Color()
for (let i = 0; i < count; i++) {
mesh.setUniformAt('metalness', i, Math.random())
mesh.setUniformAt('emissive', i, color.set(Math.random() * 0xffffff))
}
```
The type of the `value` argument should match the type of the uniform defined in the material's shader:
| For uniform type: | Pass a value of this type: |
| ----------------- | ----------------------------------------- |
| float | Number |
| vec2 | `Vector2` or Array w/ length=2 |
| vec3 | `Vector3` or `Color` or Array w/ length=3 |
| vec4 | `Vector4` or Array w/ length=4 |
### BezierMesh
_[Source code with JSDoc](./src/BezierMesh.js)_ | _[Online example](https://troika-examples.netlify.com/#bezier3d)_
_[Source code with JSDoc](./src/BezierMesh.js)_
_[Online example](https://troika-examples.netlify.com/#bezier3d)_
_[Online example using InstancedUniformsMesh](https://ibyou.csb.app/)_

@@ -120,1 +86,5 @@ This creates a cylindrical mesh and bends it along a 3D cubic bezier path between two points, in a custom derived vertex shader. This is useful for visually connecting objects in 3D space with a line that has thickness to it.

### InstancedUniformsMesh
> NOTE: InstancedUniformsMesh has been moved to [its own `three-instanced-uniforms-mesh` package](https://github.com/protectwise/troika/tree/master/packages/three-instanced-uniforms-mesh).

@@ -0,0 +0,0 @@ import { CylinderBufferGeometry, DoubleSide, Mesh, MeshStandardMaterial, Vector2, Vector3 } from 'three'

@@ -0,0 +0,0 @@ import { createDerivedMaterial } from './DerivedMaterial.js'

@@ -0,0 +0,0 @@ import { voidMainRegExp } from './voidMainRegExp.js'

@@ -0,0 +0,0 @@ import { ShaderChunk } from 'three'

@@ -0,0 +0,0 @@ import { ShaderLib } from 'three'

@@ -0,0 +0,0 @@ /**

@@ -8,3 +8,2 @@ // Troika Three.js Utilities exports

export { voidMainRegExp } from './voidMainRegExp.js'
export { InstancedUniformsMesh } from './InstancedUniformsMesh.js'
export { BezierMesh } from './BezierMesh.js'

@@ -0,0 +0,0 @@ import {

@@ -0,0 +0,0 @@ /**

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc