RawShaderMaterial on GLTFLoader with camera.position

Hey.

Maybe someone can help me - I want to build something like here in this exapmle three.js examples

I just copy the source and try to add GLTFLoader my Logo what i have build in C4D and export as glb singel object file. So far so good. I see my object and also the shader but I can’t handle the update of the camera.position to the matrial camera positon - without that I don’t have the original effect like in the example. As you see in my added screenshot it does not look like in the example :slight_smile:

Here is my code for loading the 3d model

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';

import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import WebGL from 'three/addons/capabilities/WebGL.js';

if (WebGL.isWebGL2Available() === false) {

	document.body.appendChild(WebGL.getWebGL2ErrorMessage());

}

let renderer, scene, camera;
let mesh;

init();

function init() {
//REST like in example

mesh = new GLTFLoader();
	mesh.load('public/Logo.glb', function (gltf) {

		mesh = gltf.scene;

		mesh.traverse(function (object) {

			object.material = new THREE.RawShaderMaterial({
			  glslVersion: THREE.GLSL3,
			  uniforms: {
			    map: { value: texture },
			    cameraPos: { value: new THREE.Vector3() },
			    threshold: { value: 0.6 },
			    steps: { value: 200 }
			  },
			  vertexShader,
			  fragmentShader,
			  side: THREE.BackSide
			});

			if (object.isMesh) object.castShadow = true;

		});

		mesh.scale.set(0.01, 0.01, 0.01);
		scene.add(mesh);

		animate()
	});

	const parameters = { threshold: 0.6, steps: 200 };

	function update() {
		mesh.traverse(function (object) {
			object.material.uniforms.threshold.value = parameters.threshold;
			object.material.uniforms.steps.value = parameters.steps;
		});
	}

	const gui = new GUI();
	gui.add(parameters, 'threshold', 0, 1, 0.01).onChange(update);
	gui.add(parameters, 'steps', 0, 300, 1).onChange(update);

	window.addEventListener('resize', onWindowResize);

}

Also my animate() - Where i have some test code in it.

function animate() {

	requestAnimationFrame(animate);
	mesh.traverse(function (object) {
		// object.material.uniforms.cameraPos.value.copy(camera.position);
               // with that the model disappear nut no error in the dev tool
	});

	if (mesh.material && mesh.material.uniforms.cameraPos) {
		mesh.material.uniforms.cameraPos.value.copy(camera.position);
	}	

	// mesh.material.uniforms.cameraPos.value.copy(camera.position);
	renderer.render(scene, camera);

}

Hope someone give me a hint :slight_smile:

Oky I got a step closer.

I see the matrial now → But I need to add -100 because it does not fit.

if (mesh.material && mesh.material.uniforms.cameraPos) {
		mesh.traverse(function (object) {
			console.log(object.material.uniforms.cameraPos.value);
			object.material.uniforms.cameraPos.value.copy(new THREE.Vector3(camera.position.x / -100, camera.position.y / -100, camera.position.z / -100));
		});

And after some test there I see now why it is not sowing correct - the fragmentShader use a cube to make the matrial and texture and I need the 3d Model for it - So that leads me to my next question is ther any change insteat of passing a cube to the fragmentShader I can pass the 3d Model?

Bildschirmfoto 2023-12-19 um 14.35.03

It will most likely not work out of the box, volumetric shaders assume you’re passing an (inverted) cube through which they can march (it may work with a 3D mesh, but my wild guess is that they’d fail at bounding box calculations.)

To use a 3D model instead of a cube, you may need to voxelize it and pass as a Data3DTexture.

Ah oky - Yeah i thought that could be some problem :slight_smile:

So at the link you send me →

I use already that example three.js examples

@mjurczyk So if I got your idea right, you mean based on the example I need a second Data3DTexture for the model? → const model = new THREE.Data3DTexture( data, sizeX, sizeY, sizeZ );

And how to I prepare the const data out of the 3d Model? And how I can passe it to the volumetric shader?