Texture Projection

Hi, community!

I was curious about how to project a texture, for example, on a plane, like a video projector does.
As usual, I’ve invented my own bicycle from the scratch with THREE.ShaderMaterial() and 5 vertices. (Robot Bender.jpg) :smile:

http://jsfiddle.net/prisoner849/461bvhoc/

This is a very rought concept, but it’s working as expected. Maybe somebody has/knows about a better approach. If so, I’d like to look at it (if it’s not classified top-secret :wink: )

From my point of view, this solution can be used in these forum threads:

7 Likes

Related: https://github.com/mrdoob/three.js/pull/13057

1 Like

@Mugen87

Thanks for the link, Michael.
During creation of the fiddle, I have a thought, that it would be cool to have a type of a light source (a separated one or extension of an existing one), which works like a real video projector, using a texture.

1 Like

Thats very good, i’ve been waiting for more projector like features to become available, definitely a step in the right direction.

Reworked Example

I’ve updated the original example to use projector’s pre-computed viewMatrix and projectionMatrix. It might help people understand what’s happening inside the shader without having to understand each step of the projection.

It’s also 30% more performant on my machine.

4 Likes

@prisoner849 @sciecode

Great examples. I’m trying to achieve projection mapping, and this is working fantastic. However I’d like the initial projection to ‘stick’ to the meshes. This illustrates the concept, see the 2nd slide: https://www.instagram.com/p/B2b71Z1i73o/

See my fiddle here: http://jsfiddle.net/gcpuj1zk/5/. Basically, as screen moves, the image should distort, not keep the projection. Any idea, or point in the right direction, how I can achieve this? Much appreciated it.

Just don’t move the projector?

1 Like

The projector is already not moving. So, while the object is moving, the projected image remains the same.

My goal is to have the INITIAL projected image ‘painted’ onto the object, so as the object is rotated/moved, the texture moves with it.

Then you can attach the projector (or a copy thereof) to the object that you want to rotate. :wink:

1 Like

Would it be possible to dynamically merge this projection method into the standard shader using onBeforeCompile?

Hi!
Could you explain what you mean with this?

From what i can find, people are using the OnBeforeCompile method to modify shaders at run-time. just trying to determine a way to use this projection method with the already very featured Standard Material.

1 Like

Thanks a lot for your code. I updated the code to three.js 121 (ES module + replace GLSL texture2d by texture) in an Observable notebook : https://observablehq.com/@severo/texture-projection

4 Likes

three-projected-material :point_down: :eyes:

@donmccurdy Hello, I’d like to project a texture onto an object with a physical material, and it seems the old way would be to inject code into the physical material for MeshPhysicalMaterial in inBeforeRender or similar, which is hacky.

I have a hunch that we can do this composition with node materials more cleanly. Is this in fact the case?

What inputs/outputs do you need to use from MeshPhysicalMaterial when injecting code? I would guess this can be done with node materials if the projection works with these inputs:

  • input: uv, local, or world coordinates, and original base color
  • output: new base color

I’m not sure yet, but what I do know is that patching shader code is not so fun. :slight_smile:

Seems like I would need to fork MeshStandardNodeMaterial for example, and insert a property for the decal node.

It’s a little inflexible the current way, it seems. I think a better system would be that all primitives stay separated (not grouped by higher level baked-in classes like MeshStandardNodeMaterial), then a node component system would group them into higher-level groups (like standard material) that can be modified easily (add/remove nodes and modify input/output connections, which requires all aspects of a node to be modifiable, but right now constructor args are not something that can be modified after the fact, which is where inflexibility comes from). The node editor sort of does this, but it does it on top of the inflexible MeshStandardNodeMaterial, for example, IIUC. That’s gonna be a big refactor…