add custom animate prints.

Custom Code

Demo

https://flowcode.com/p/Z6ovqdUqE

Shader Loader

  1. Add this code to your 3D object custom code on the scene
  2. Copy JSON link of any shaders bellow and change link inside loadShader function, OR upload your own JSON and insert link ( important: if you want to use other shaders from ShaderFrog keep in mind that some of ShaderFrog shaders don’t work because of three.js updates )
// Check Model Placed event (after click on Tap To Place icon)
this.activeSceneModel.$parent.emitter.addListener("geenee-model-placed", () => {
  const runtime = new ShaderRuntime();
  const clock = new THREE.Clock();
  let mesh;
  this.object3D.visible = false;
  this.object3D.traverse((children) => {
    if (mesh) return;
    if (children.type === "Mesh") mesh = children;
  });
  const loadShader = (shaderPath) => {
    runtime.load(shaderPath, (shaderData) => {
      // Get the Three.js material you can assign to your objects
      const material = runtime.get(shaderData.name);
      // Assign it to your objects
      mesh.material = material;
      this.object3D.visible = true;
    });
  };

  const onUpdate = () => {
    runtime?.updateShaders(clock.getElapsedTime());
  };

  loadShader("<https://dl.dropbox.com/s/n3toyx2w6vzt3jn/customSphere.json>");
  this.activeSceneModel.userCallbacks.onRender = onUpdate;
});

Shader Frog Library

  1. Place this code outside of the scene to the custom code section inside the projects panel
let defaultThreeUniforms=["normalMatrix","viewMatrix","projectionMatrix","position","normal","modelViewMatrix","uv","uv2","modelMatrix"];function ShaderRuntime(){}ShaderRuntime.prototype={mainCamera:null,cubeCameras:{},reserved:{time:null,cameraPosition:null},umap:{float:{type:"f",value:0},int:{type:"i",value:0},vec2:{type:"v2",value(){return new THREE.Vector2()},},vec3:{type:"v3",value(){return new THREE.Vector3()},},vec4:{type:"v4",value(){return new THREE.Vector4()},},samplerCube:{type:"t"},sampler2D:{type:"t"},},getUmap(type){let value=this.umap[type].value;return typeof value==="function"?value():value},load(sourceOrSources,callback){let sources=sourceOrSources,onlyOneSource=typeof sourceOrSources==="string";if(onlyOneSource){sources=[sourceOrSources]}let loadedShaders=new Array(sources.length),itemsLoaded=0;let loadSource=(index,source)=>{let loader=new THREE.FileLoader();loader.load(source,(json)=>{let parsed;let parsedId;try{parsed=JSON.parse(json);parsedId=parsed.id;delete parsed.id}catch(e){throw new Error("Could not parse shader"+source+"! Please verify the URL is correct.");}parsed.name=parsed.name+":"+parsedId;this.add(parsed.name,parsed);loadedShaders[index]=parsed;if(++itemsLoaded===sources.length){callback(onlyOneSource?loadedShaders[0]:loadedShaders)}})};for(let x=0;x<sources.length;x++){loadSource(x,sources[x])}},registerCamera(camera){if(!(camera instanceof THREE.Camera)){throw new Error("Cannot register a non-camera as a camera!");}this.mainCamera=camera},registerCubeCamera(name,camera){if(!camera.renderTarget){throw new Error("Cannot register a non-camera as a camera!");}this.cubeCameras[name]=camera},unregisterCamera(name){if(name in this.cubeCameras){delete this.cubeCameras[name]}else if(name===this.mainCamera){delete this.mainCamera}else{throw new Error("You never registered camera "+name);}},updateSource(identifier,config,findBy){findBy=findBy||"name";if(!this.shaderTypes[identifier]){throw new Error("Runtime Error: Cannot update shader "+identifier+" because it has not been added.");}let newShaderData=this.add(identifier,config),shader,x;for(x=0;(shader=this.runningShaders[x++]);){if(shader[findBy]===identifier){extend(shader.material,omit(newShaderData,"id"));shader.material.needsUpdate=true}}},renameShader(oldName,newName){let x,shader;if(!(oldName in this.shaderTypes)){throw new Error("Could not rename shader "+oldName+" to "+newName+". It does not exist.");}this.shaderTypes[newName]=this.shaderTypes[oldName];delete this.shaderTypes[oldName];for(x=0;(shader=this.runningShaders[x++]);){if(shader.name===oldName){shader.name=newName}}},get(identifier){let shaderType=this.shaderTypes[identifier];if(!shaderType.initted){this.create(identifier)}return shaderType.material},add(shaderName,config){let newData=clone(config),uniform;newData.fragmentShader=config.fragment;newData.vertexShader=config.vertex;delete newData.fragment;delete newData.vertex;for(var uniformName in newData.uniforms){uniform=newData.uniforms[uniformName];if(uniform.value===null){newData.uniforms[uniformName].value=this.getUmap(uniform.glslType)}}if(shaderName in this.shaderTypes){extend(this.shaderTypes[shaderName],newData)}else{this.shaderTypes[shaderName]=newData}return newData},create(identifier){let shaderType=this.shaderTypes[identifier];let keys=Object.keys(shaderType);let withoutId={};for(let i=0;i<keys.length;i++){if(keys[i]!=="id"){withoutId[keys[i]]=shaderType[keys[i]]}}shaderType.material=new THREE.RawShaderMaterial(withoutId);this.runningShaders.push(shaderType);shaderType.init&&shaderType.init(shaderType.material);shaderType.material.needsUpdate=true;shaderType.initted=true;return shaderType.material},updateRuntime(identifier,data,findBy){findBy=findBy||"name";let shader,x,uniformName,uniform;for(x=0;(shader=this.runningShaders[x++]);){if(shader[findBy]===identifier){for(uniformName in data.uniforms){if(uniformName in this.reserved){continue}if(uniformName in shader.material.uniforms){uniform=data.uniforms[uniformName];if(uniform.type==="t"&&typeof uniform.value==="string"){uniform.value=this.cubeCameras[uniform.value].renderTarget}shader.material.uniforms[uniformName].value=data.uniforms[uniformName].value}}}}},updateShaders(time,obj){let shader,x;obj=obj||{};for(x=0;(shader=this.runningShaders[x++]);){for(let uniform in obj.uniforms){if(uniform in shader.material.uniforms){shader.material.uniforms[uniform].value=obj.uniforms[uniform]}}if("cameraPosition"in shader.material.uniforms&&this.mainCamera){shader.material.uniforms.cameraPosition.value=this.mainCamera.position.clone()}if("viewMatrix"in shader.material.uniforms&&this.mainCamera){shader.material.uniforms.viewMatrix.value=this.mainCamera.matrixWorldInverse}if("time"in shader.material.uniforms){shader.material.uniforms.time.value=time}}},shaderTypes:{},runningShaders:[],};function extend(){let length=arguments.length,obj=arguments[0];if(length<2){return obj}for(let index=1;index<length;index++){let source=arguments[index],keys=Object.keys(source||{}),l=keys.length;for(let i=0;i<l;i++){let key=keys[i];obj[key]=source[key]}}return obj}function clone(obj){return extend({},obj)}function omit(obj,...keys){let cloned=clone(obj),x,key;for(x=0;(key=keys[x++]);){delete cloned[key]}return cloned}

Shaders

Amazing Universe

amazing_universe.mp4

JSON: https://dl.dropbox.com/s/glyn1rulp7s98yk/amazing_universe.json

Source: https://shaderfrog.com/app/view/5599

Blomine

blomine.mp4