# Texture Projection

**URL:** <https://discourse.threejs.org/t/texture-projection/3224>\
**Category:** Resources\
**Tags:** texture-mapping, video-texture, textures\
**Created:** [June 25, 2018, 9:56pm UTC](https://discourse.threejs.org/t/texture-projection/3224 "2018-06-25T21:56:07Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [June 25, 2018, 9:56pm UTC](https://discourse.threejs.org/t/texture-projection/3224/1 "2018-06-25T21:56:07Z")

</div>

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) 😄

> **[Edit fiddle - JSFiddle - Code Playground](https://jsfiddle.net/prisoner849/461bvhoc/)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

 ![VideoTextureProjection](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/e/e24f4352339e2abfb491d08964170113073a9973.png)

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 😉 )

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

> [@Projector the video](https://discourse.threejs.org/t/projector-the-video/2900/10):
>
> Thank you very much, @prisoner849 and @hofk . Actually, I want projector texture or material (video) to the model or scene,like pictures below.[image][image][image]. Is anyway do can doind this ? Thanks verymuch.

> [@Interactive Projection Mapping Calculator](https://discourse.threejs.org/t/interactive-projection-mapping-calculator/3212):
>
> Hello! I’m with a projection mapping hardware / computer vision startup called Lightform ([https://lightform.com](https://lightform.com)). We’re looking for a three.js developer to help us build an interactive projector selection tool so our customers can select an appropriate projector for their scene. The user would provide some basic specifications about their scene (XYZ dimensions, ambient light, etc.) and the tool would recommend a few appropriate projectors. The projector database would be provided by us, initial…

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [June 26, 2018, 8:49am UTC](https://discourse.threejs.org/t/texture-projection/3224/2 "2018-06-26T08:49:59Z")

</div>

Related: [https://github.com/mrdoob/three.js/pull/13057](https://github.com/mrdoob/three.js/pull/13057)

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [June 26, 2018, 9:09am UTC](https://discourse.threejs.org/t/texture-projection/3224/3 "2018-06-26T09:09:29Z")

</div>

@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.

---

<div class="post-metadata">

**Author:** ![EFFalcon](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/effalcon/32/7419_2.png) [@EFFalcon](https://discourse.threejs.org/u/EFFalcon)\
**Post date:** [July 24, 2018, 6:17am UTC](https://discourse.threejs.org/t/texture-projection/3224/4 "2018-07-24T06:17:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![sciecode](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/sciecode/32/5623_2.png) [@sciecode](https://discourse.threejs.org/u/sciecode)\
**Post date:** [June 13, 2019, 1:14pm UTC](https://discourse.threejs.org/t/texture-projection/3224/5 "2019-06-13T13:14:46Z")

</div>

[Reworked Example](http://jsfiddle.net/t2w6bagq/)

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.

---

<div class="post-metadata">

**Author:** ![andrevvm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/andrevvm/32/7220_2.png) [@andrevvm](https://discourse.threejs.org/u/andrevvm)\
**Post date:** [September 18, 2019, 5:19am UTC](https://discourse.threejs.org/t/texture-projection/3224/6 "2019-09-18T05:19:03Z")

</div>

@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/](https://www.instagram.com/p/B2b71Z1i73o/)

See my fiddle here: [http://jsfiddle.net/gcpuj1zk/5/](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.

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [September 18, 2019, 7:50am UTC](https://discourse.threejs.org/t/texture-projection/3224/7 "2019-09-18T07:50:12Z")

</div>

Just don’t move the projector?

---

<div class="post-metadata">

**Author:** ![andrevvm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/andrevvm/32/7220_2.png) [@andrevvm](https://discourse.threejs.org/u/andrevvm)\
**Post date:** [September 18, 2019, 5:35pm UTC](https://discourse.threejs.org/t/texture-projection/3224/8 "2019-09-18T17:35:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [September 18, 2019, 9:06pm UTC](https://discourse.threejs.org/t/texture-projection/3224/9 "2019-09-18T21:06:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![EFFalcon](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/effalcon/32/7419_2.png) [@EFFalcon](https://discourse.threejs.org/u/EFFalcon)\
**Post date:** [September 30, 2019, 1:25am UTC](https://discourse.threejs.org/t/texture-projection/3224/10 "2019-09-30T01:25:57Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 30, 2019, 6:57am UTC](https://discourse.threejs.org/t/texture-projection/3224/11 "2019-09-30T06:57:31Z")

</div>

> [@EFFalcon](#):
>
> dynamically merge

Hi!  
Could you explain what you mean with this?

---

<div class="post-metadata">

**Author:** ![EFFalcon](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/effalcon/32/7419_2.png) [@EFFalcon](https://discourse.threejs.org/u/EFFalcon)\
**Post date:** [September 30, 2019, 7:00am UTC](https://discourse.threejs.org/t/texture-projection/3224/12 "2019-09-30T07:00:22Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![severo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/severo/32/14204_2.png) [@severo](https://discourse.threejs.org/u/severo)\
**Post date:** [October 26, 2020, 6:20pm UTC](https://discourse.threejs.org/t/texture-projection/3224/13 "2020-10-26T18:20:17Z")

</div>

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](https://observablehq.com/@severo/texture-projection)

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trusktr/32/13726_2.png) [@trusktr](https://discourse.threejs.org/u/trusktr)\
**Post date:** [March 13, 2022, 11:19pm UTC](https://discourse.threejs.org/t/texture-projection/3224/14 "2022-03-13T23:19:11Z")

</div>

`three-projected-material` 👇 👀

> **[GitHub - marcofugaro/three-projected-material: 📽 Three.js Material which lets...](https://github.com/marcofugaro/three-projected-material)**
>
> 📽 Three.js Material which lets you do Texture Projection on a 3d Model - GitHub - marcofugaro/three-projected-material: 📽 Three.js Material which lets you do Texture Projection on a 3d Model

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trusktr/32/13726_2.png) [@trusktr](https://discourse.threejs.org/u/trusktr)\
**Post date:** [March 27, 2022, 5:48pm UTC](https://discourse.threejs.org/t/texture-projection/3224/15 "2022-03-27T17:48:43Z")

</div>

@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?

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 28, 2022, 7:03pm UTC](https://discourse.threejs.org/t/texture-projection/3224/16 "2022-03-28T19:03:46Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trusktr/32/13726_2.png) [@trusktr](https://discourse.threejs.org/u/trusktr)\
**Post date:** [April 4, 2022, 4:14am UTC](https://discourse.threejs.org/t/texture-projection/3224/17 "2022-04-04T04:14:48Z")

</div>

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

Seems like I would need to fork [MeshStandardNodeMaterial](https://github.com/mrdoob/three.js/blob/d0dc0801fccabf3d146e98f127e9bb09b3ccc98f/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js) 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…
