How can I apply a texture to a 3D rectangle in THREE.js?

I am attempting to create a 3D box in THREE.js that represents a box made up of 2x4 Legos, measuring 24 pieces wide by 48 pieces long and an unspecified number of pieces tall. I have created a texture displaying this pattern using random colors:

https://i.sstatic.net/sFuRN.png

I want to display two sides of this cube while ensuring that the textures align so that the edge pieces match in color, similar to what is shown in this Blender-generated image:

https://i.sstatic.net/eUP8T.jpg

I would prefer not to create six separate images for a CubeTexture, especially since four would be unnecessary. Is there a way to flip the texture on one side to create the appearance of alignment? (This is purely for visual effect.)

Furthermore, not all 3D rectangles will be cubes, but I am struggling to determine how to set the texture.repeat.x and texture.repeat.y properties so that the width scales correctly while maintaining the same vertical scale, stopping when it reaches the object's height, like in this example:

https://i.sstatic.net/ZTtZs.png

Thank you!

Answer №1

To create a mirror effect on an image, you can achieve this by flipping the UVs.

It's important to identify which UVs correspond to the specific face you want to mirror and determine the correct direction for the flip based on your geometry structure.

Below is an example illustrating how to use a simple BoxBufferGeometry and adjust its uv attribute to achieve a mirrored effect through UV flipping. (The right face demonstrates the result of UV flipping)

var textureURL = "https://upload.wikimedia.org/wikipedia/commons/0/02/Triangular_hebesphenorotunda.png";
// attribution and license here: https://commons.wikimedia.org/wiki/File:Triangular_hebesphenorotunda.png

var renderer = new THREE.WebGLRenderer({antialias:true});
document.body.appendChild(renderer.domElement);
renderer.setSize(500, 500);

var textureLoader = new THREE.TextureLoader();

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(28, 1, 1, 1000);
camera.position.set(50, 25, 50);
camera.lookAt(scene.position);
scene.add(camera);

camera.add(new THREE.PointLight(0xffffff, 1, Infinity));

var cubeGeo = new THREE.BoxBufferGeometry(20, 20, 20);
var uvs = cubeGeo.attributes.uv;
// originally:
// [0] = 0,1
// [1] = 1,1
// [2] = 0,0
// [3] = 1,0
// convert to:
// [0] = 1,1
// [1] = 0,1
// [2] = 1,0
// [3] = 0.0
uvs.setX(0, 1);
uvs.setY(0, 1);
uvs.setX(1, 0);
uvs.setY(1, 1);
uvs.setX(2, 1);
uvs.setY(2, 0);
uvs.setX(3, 0);
uvs.setY(3, 0);
uvs.needsUpdate = true;

var mat = new THREE.MeshLambertMaterial({
  color: "white",
  map: textureLoader.load(textureURL, function(){
    animate();
  })
});
var mesh = new THREE.Mesh(cubeGeo, mat);
scene.add(mesh);

function render() {
  renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>

Answer №2

To construct a cube, you may generate six instances of PlaneBufferGeometries, apply the same material to each, and arrange them accordingly. Incrementally rotate the planes by 90 degrees until achieving the intended outcome. To optimize performance, consolidating these geometries into a single entity using BufferGeometry is advisable.

Answer №3

To bring your creation from Blender into the digital realm, you have a few export options at your disposal. Utilize the THREE.js json exporter or choose a format like OBJ or GLTF for a seamless transition into loading and rendering.

Your focus on maintaining the UV layout as it appears in Blender suggests a need for precision control. In this case, simply importing the model may prove more efficient than attempting to recreate it from scratch.

When utilizing either the three.js .json or .gltf formats, consider embedding textures directly during export. While this may streamline the process, keep in mind that it could lead to slightly less space-efficient storage.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

User-generated JSON Object with Date Information

I have created an API using Node.js/Express that receives input from a form including a date option in the request body. Currently, I am sending dates in the format YYYY-mm-dd, and I have also attempted using dd/mm/YYYY. However, when testing in Postman, ...

The attempt to run 'setProperty' on 'CSSStyleDeclaration' was unsuccessful as these styles are precalculated, rendering the 'opacity' property unchangeable

I am attempting to change the value of a property in my pseudo element CSS class using a JavaScript file. Unfortunately, I keep encountering the error mentioned in the title. Is there any other method that can be used to achieve this? CSS Code: .list { ...

Reacting with Node.js: Capturing a selected option from a dropdown menu and storing it in the database

On my React frontend, I have a select dropdown like this: <select name="level" value={level} onChange={this.handleChange} className="form-control"> <option>Begineer</option> <option>Intermediate</option> <option> ...

Experiencing difficulties with executing numerous NodeJs queries

Could someone assist with rendering multiple queries in a Nodejs view? The console shows Promise {pending} and I can't figure out what's causing the issue. I'd appreciate any help or guidance on how to fix this problem. router.get('/ ...

Utilize CSS to vertically align buttons

One of my current projects involves creating a panel with buttons organized in columns side by side, similar to the layout shown below: https://i.sstatic.net/ObAqw.png However, I am struggling to achieve this desired arrangement. Below is the code I hav ...

I am encountering an issue where the object I am sending with Next.js is appearing as undefined on the receiving page

When transferring data from my question screen to a result screen, I am using an object called footprintsData. Here is the code snippet for sending the data: const footprintsData = { carFootprint: roundedCarFootprint, electricityFootprint: roundedElect ...

Developing a Fresh Settings Tab and Vue Module in Laravel Spark

When working with Laravel Spark, you'll find that most settings panels come with a corresponding Vue JS component that is called upon using a custom tab. <spark-create-tests :user="user" inline-template> <div> </div> </sp ...

Execute a JavaScript function when a form is submitted

Seeking to reacquaint myself with Javascript, encountering difficulties with this fundamental issue. https://jsfiddle.net/gfitzpatrick2/aw27toyv/3/ var name = document.getElementById("name"); function validate() { alert("Your name is " +name); } < ...

Ways to verify if an array contains two identical object values?

I am in search of a way to determine whether my array contains duplicate object values or not. Let's say I have the following array of objects: const array = [ { id: "id1", quantity: 3, variation: "red", ...

Optimizing the management of optional post fields in an Express.js application

When creating an endpoint with Express that includes both mandatory and non-mandatory fields in the post request, what is the optimal strategy for handling this? Would it be best to use something like if (field exists in req.body) { set variable } else { ...

Setting the maximum width for a JavaScript pop-up box

Below is the html code that creates a link reading "sacola de compras" <div> <script type="text/javascript" src="https://app.ecwid.com/script.js?4549118"></script> <script type="text/javascript"> xMinicart("style=","layout=Mini") ...

Populate modal form with database information without using Bootstrap

As I work on populating a form with data from an sqlite database, I've come across a stumbling block. My code is available for reference on JSFiddle: https://jsfiddle.net/daikini/e71mvg7n/ One important note: Bootstrap isn't being utilized in t ...

Managing JSON responses from a server using Javascript

I have encountered various similar issues, but none of them have provided a solution for my specific question. On my server, I generate a JSON string and place it in the response: List<String> list = getSomeList(); JSONArray jsArray = new JSONArray( ...

The display of options in React Bootstrap typeahead is not functioning properly

When I try to implement React Bootstrap Typeahead, the options do not appear in the Typeahead component upon page load. Here is a snippet of my code: const React = require('react'); ... (code continues) The options are generated as follows: [ ...

Developing a slideshow with PHP and JQuery

Attempting to create a simple manual slideshow where the user clicks "next" to advance to the next slide. I have over 50 images and want to display them in batches of 8. For example, the first batch of 8 will be shown initially, then the user can click "ne ...

"Trouble with props: List items not showing up after refreshing the page

I am facing an issue with my "Event Selector" component where it is not displaying the list items as expected. The component is supposed to create a button for each item in the 'lists' passed via props. Strangely, the items do not show up upon re ...

Traversing JSON data structures regardless of missing keys

Here is a JSON containing some data: { "results":[ { "name":"Sydney Showboats", "photos":[ { "photo_reference":"Pic062" } ] }, ...

Issue with VueJS compilation: JSON data import causing failure

I'm attempting to bring in a static .json file within the <script> section of a .Vue file using the code snippet import Test from '@assets/test.json' From what I've gathered about webpack, this should work effortlessly. I have ev ...

Ways to designate a parent element in Vue Draggable when the element is lacking a child

I'm currently incorporating vue-draggable into my project from the following GitHub repository: https://github.com/SortableJS/Vue.Draggable Below is my ElementsList component: <div> <draggable v-model="newElement" :move ...

Efficiently styling table Spans with styled components in React

Can anyone help me with a frustrating CSS problem I'm facing? I am trying to render these tags as spans, but they are not separating properly as shown in the image below. They appear stuck together and I can't figure out why. I am using styled co ...