Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/marcofugaro/three-projected-material
📽 Three.js Material which lets you do Texture Projection on a 3d Model
https://github.com/marcofugaro/three-projected-material
texture-mapping texture-projection threejs threejs-example
Last synced: 21 days ago
JSON representation
📽 Three.js Material which lets you do Texture Projection on a 3d Model
- Host: GitHub
- URL: https://github.com/marcofugaro/three-projected-material
- Owner: marcofugaro
- License: mit
- Created: 2019-12-12T16:12:55.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-07-04T15:05:59.000Z (4 months ago)
- Last Synced: 2024-10-12T22:06:39.412Z (27 days ago)
- Topics: texture-mapping, texture-projection, threejs, threejs-example
- Language: JavaScript
- Homepage: https://marcofugaro.github.io/three-projected-material/
- Size: 18.3 MB
- Stars: 674
- Watchers: 16
- Forks: 58
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-game-engine-dev - three-projected-material - Texture projection in Three.js. (Libraries / JavaScript)
README
# three-projected-material
> Three.js Material which lets you do [Texture Projection](https://en.wikipedia.org/wiki/Projective_texture_mapping) on a 3d Model.
## Installation
After having installed three.js, install it from npm with:
```
npm install three-projected-material
```or
```
yarn add three-projected-material
```You can also use it from the CDN, just make sure to use the three.js import map:
```html
{
"imports": {
"three": "https://unpkg.com/three/build/three.module.js"
}
}import ProjectedMaterial from 'https://unpkg.com/three-projected-material/build/ProjectedMaterial.module.js'
// ...```
## Getting started
You can import it like this
```js
import ProjectedMaterial from 'three-projected-material'
```or, if you're using CommonJS
```js
const ProjectedMaterial = require('three-projected-material').default
```Then, you can use it like this:
```js
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new ProjectedMaterial({
camera, // the camera that acts as a projector
texture, // the texture being projected
textureScale: 0.8, // scale down the texture a bit
textureOffset: new THREE.Vector2(0.1, 0.1), // you can translate the texture if you want
cover: true, // enable background-size: cover behaviour, by default it's like background-size: contain
color: '#ccc', // the color of the object if it's not projected on
roughness: 0.3, // you can pass any other option that belongs to MeshPhysicalMaterial
})
const box = new THREE.Mesh(geometry, material)
webgl.scene.add(box)// move the mesh any way you want!
box.rotation.y = -Math.PI / 4// and when you're ready project the texture on the box!
material.project(box)
```ProjectedMaterial also supports **instanced meshes** via three.js' [InstancedMesh](https://threejs.org/docs/index.html#api/en/objects/InstancedMesh), and even **multiple projections**. Check out the examples below for a detailed guide!
## [Examples](https://marcofugaro.github.io/three-projected-material/)
## API Reference
### new ProjectedMaterial({ camera, texture, ...others })
Create a new material to later use for a mesh.
| Option | Default | Description |
| ------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `camera` | | The [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera) the texture will be projected from. |
| `texture` | | The [Texture](https://threejs.org/docs/#api/en/textures/Texture) being projected. |
| `textureScale` | 1 | Make the texture bigger or smaller. |
| `textureOffset` | `new THREE.Vector2()` | Offset the texture in a x or y direction. The unit system goes from 0 to 1, from the bottom left corner to the top right corner of the projector camera frustum. |
| `cover` | false | Wheter the texture should act like [`background-size: cover`](https://css-tricks.com/almanac/properties/b/background-size/) on the projector frustum. By default it works like [`background-size: contain`](https://css-tricks.com/almanac/properties/b/background-size/). |
| `backgroundOpacity` | 1 | The opacity of the part of the mesh which is not covered by the projected texture. You can set this to 0 if you don't want the non-projected part of the mesh to be shown. |
| `...options` | | Other options you pass to any three.js material like `color`, `opacity`, `envMap` and so on. The material is built from a [MeshPhysicalMaterial](https://threejs.org/docs/index.html#api/en/materials/MeshPhysicalMaterial), so you can pass any property of that material and of its parent [MeshStandardMaterial](https://threejs.org/docs/index.html#api/en/materials/MeshStandardMaterial). |These properties are exposed as properties of the material, so you can change them later.
For example, to update the material texture and change its scale:
```js
material.texture = newTexture
material.textureScale = 0.8
```### material.project(mesh)
Project the texture from the camera on the mesh. With this method we "take a snaphot" of the current mesh and camera position in space. The
After calling this method, you can move the mesh or the camera freely.| Option | Description |
| ------ | ---------------------------------------------------- |
| `mesh` | The mesh that has a `ProjectedMaterial` as material. |### allocateProjectionData(geometry, instancesCount)
Allocate the data that will be used when projecting on an [InstancedMesh](https://threejs.org/docs/#api/en/objects/InstancedMesh). Use this on the geometry that will be used in pair with a `ProjectedMaterial` when initializing `InstancedMesh`.
This needs to be called before `.projectInstanceAt()`.
| Option | Description |
| ---------------- | ----------------------------------------------------------------------------- |
| `geometry` | The geometry that will be passed to the `InstancedMesh`. |
| `instancesCount` | The number of instances, the same that will be passed to the `InstancedMesh`. |### material.projectInstanceAt(index, instancedMesh, matrix)
Do the projection for an [InstancedMesh](https://threejs.org/docs/#api/en/objects/InstancedMesh). Don't forget to call `updateMatrix()` like you do before calling `InstancedMesh.setMatrixAt()`.
To do projection an an instanced mesh, the geometry needs to be prepared with `allocateProjectionData()` beforehand.
```js
dummy.updateMatrix()
projectInstanceAt(i, instancedMesh, dummy.matrix)
```[Link to the full example about instancing](https://marcofugaro.github.io/three-projected-material/instancing).
| Option | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `index` | The index of the instanced element to project. |
| `instancedMesh` | The [InstancedMesh](https://threejs.org/docs/#api/en/objects/InstancedMesh) with a projected material. |
| `matrix` | The `matrix` of the dummy you used to position the instanced mesh element. Be sure to call `.updateMatrix()` beforehand. |