Do we need the intermediate object. (.css3dObject.)

Some years ago I programmed with a not so well known programming language

( from Germany, XProfan for MS-Windows, I used it for teaching back then,
see https://de.wikipedia.org/wiki/Liste_von_Programmiersprachen )

the simulation of an absolutely minimal processor ( 8 bit data and addresses, 256 byte RAM).

Links to the project - mostly German.
https://hofk.de/cpusimulation/
https://xprofan.net/intl/de/anwendungen/8bit-cpu-simulation/
Sourcecode: http://hofk.info/sourcecode/HC680_assembler.xprf

I now transfer the project to JavaScript and add some 3D. I will also transfer it from German to English.

I am currently creating some small test programs to see what is suitable.
There https://hofk.de/main/threejs/ are already some available
in the category -Test- CPU Simulation. (Top of the page after my addons.)

I also want to mix HTML/CSS and WebGl. See MixedHtmlCssWebGl there.

I used the example Is there a way to add gradients or stripes to a material color? from @trusktr as a starting point and simplified it a lot.
I added some elements.


My question:

Do we need the intermediate object (.css3dObject.) if we want the application to do even more complex things?

e.g. button.css3dObject.element.style.border = '2px solid #fa5a85'


I do not need it for my simple test program.

function makeHtmlCssObject( type, width, height ) {

	const element = document.createElement( type );
	obj = new THREE.CSS3DObject( element );
	element.style.width = width + 'px';
	element.style.height = height + 'px';
	return obj;

}	

e.g. button.element.style.border = '1px solid #444444';


CSS3DObject is responsible for integrating CSS objects into the scene graph and thus retrieve a proper world matrix. In this way, you can add CSS objects to other 3D objects like meshes and ensures that it keeps a relative position to its parent.

My simplified function also creates a CSS3DObject.

The more exact question then is, if you should always bind it to a THREE.Object3D like in the original function of @trusktr.

var css3dObject = new THREE.CSS3DObject( element );
    obj.css3dObject = css3dObject
    obj.add(css3dObject)

from

function makeElementObject(type, width, height) {
    const obj = new THREE.Object3D
    const element = document.createElement( type );
    element.style.width = width+'px';
    element.style.height = height+'px';
    element.style.opacity = 0.999;
    element.style.boxSizing = 'border-box'

    var css3dObject = new THREE.CSS3DObject( element );
    obj.css3dObject = css3dObject
    obj.add(css3dObject)

    // make an invisible plane for the DOM element to chop
    // clip a WebGL geometry with it.
    var material = new THREE.MeshPhongMaterial({
        opacity	: 0.15,
        color	: new THREE.Color( 0x111111 ),
        blending: THREE.NoBlending,
        // side	: THREE.DoubleSide,
    });
    var geometry = new THREE.BoxGeometry( width, height, 1 );
    var mesh = new THREE.Mesh( geometry, material );
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    obj.lightShadowMesh = mesh
    obj.add( mesh );

    return obj
}

The reason I did that was because in my example I create both a CSS plane (CSS3DObject) and a WebGL plane (Mesh with a thin BoxGeometry) in order to apply the effect of light and shadow to the CSS planes.

But in your case, if you don’t need the light and shadow effects (CSS doesn’t have that feature) then you’re fine with only the CSS3DObject.

Or in other words, if you want to add the shine and shadows like in my example, then you’d need the WebGL object too. Without it, you will have only CSS effects (background, border, font color, etc) which is similar to MeshBasicMaterial (having no light shading).

And the reason I put both the CSS and WebGL objects under an Object3D in my example was so I could transform them as if they were a single object.

Thank you for the detailed explanation. :slightly_smiling_face:

1 Like