Variety of hues present on the mesh surface facing the plane

I am facing a challenge in coloring a face that is looking towards a plane.

I have considered two different approaches:

  • One option is to position a light source below the plane (which is only one-sided) so that the underside of the object receives a lighter color. However, I am limited by the fact that I can only control the light in PointLight, and my plane is rectangular. Although RectArea light seems like a good alternative, it does not work with my materials. Additionally, I need the light to only impact certain objects, not all of them.

  • Another approach would be to calculate face normals for each object during every update, compare them to the plane normal, and color them using vertex/face colors if they meet the criteria. I would also need to revert every other object to the default color. However, I am concerned that this method may be too CPU-intensive.

Are there any better solutions to this problem?

Answer №1

According to the insights provided by @Mugen87, the most effective method to achieve this is through the utilization of custom shaders.

Although it may seem complex at first, there are myriad resources available to delve into this subject extensively. The Book of Shaders is a great starting point.


By computing the dot product between a surface's normal and the inverse view direction, valuable information about the degree to which a specific surface is facing towards the camera can be obtained.

Utilizing this data, we can blend two colors and utilize that as the definitive color displayed on the screen.

<html>

<head>

<title> view-based color </title>

<style>
body { margin: 0; position: fixed;}
canvas { width: 100%; height: 100%; display: block;}
</style>

<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

</head>
<body>

<script>

var shader_vert = `

varying vec3 vNormal;

void main() {

vNormal = normalize( modelMatrix * vec4( normal, 1.0 ) ).xyz;

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}

`;

var shader_frag = `

uniform vec3 viewDirection;

varying vec3 vNormal;

void main() {

vec3 red = vec3( 1.0, 0.0, 0.0 );
vec3 pink = vec3( 1.0, 0.8, 0.8 );

float q = clamp( dot( vNormal, -viewDirection ), 0.0, 1.0 );

vec3 color = mix( red, pink, q );

gl_FragColor = vec4( color, 1.0 );


}

`;

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

var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

camera.position.set( 0, 2, 5 );
camera.lookAt( new THREE.Vector3() );


// plane
var geometry = new THREE.BoxBufferGeometry( 2, 2, 2 );

// custom shader
var material = new THREE.ShaderMaterial( {
uniforms: {
viewDirection: { value: new THREE.Vector3() }
},
vertexShader: shader_vert,
fragmentShader: shader_frag,
} );
var plane = new THREE.Mesh( geometry, material );
scene.add( plane );


window.addEventListener( 'resize', onResize );


function animate() {

requestAnimationFrame( animate );

plane.rotation.y += 0.01;
plane.rotation.x += 0.01;

camera.getWorldDirection( material.uniforms.viewDirection.value );

renderer.render( scene, camera );

};

function onResize() {

var w = window.innerWidth;
var h = window.innerHeight;

camera.aspect = w / h;
camera.updateProjectionMatrix();

renderer.setSize( w, h );

}

animate();

</script>

</body>

</html>

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

Quick fix for obtaining only one response

I'm facing a dilemma where I need to redirect the user to the dashboard page after they log in, but also send their JSON details to my client-side JavaScript. While I know that there can only be one res.send/end/json in a response and dynamic data can ...

Learn how to showcase video information in a vue.js template

I am having difficulty displaying a saved media (video) file on another page after collecting it using the ckeditor5 media option. The data is stored along with HTML tags generated by ckeditor, so I'm using v-html to display other content like <p&g ...

What methods can be used to center a Google map on a specific location?

I am facing an issue with three map canvases on different divs. Despite setting the center to the same position in all three of them using JavaScript, the second and third maps do not seem to reflect that center. Does anyone have any insights on what cou ...

Focus on all of the individual items except for the one that was just selected

Within the function thirdNavFunction, I am seeking a way to specifically target all instances of the .third-nav classes, excluding the one that has been clicked on. This must be accomplished without utilizing jQuery. How can I achieve this? var thirdNav = ...

I am looking to customize the color of my Material UI switch

I am having difficulty changing the color of my Material UI switch based on my preference. I have tried several ways, but have not achieved the desired outcome. const useStyles = makeStyles((theme) => ({ toggle: { '& .Mui-checked': ...

When does the frustum culling take place for THREE.Lines in Three.js?

While drawing a few lines in my project using THREE.Line, I've noticed that sometimes the line disappears from the screen under certain conditions. One common scenario is when one endpoint of the line is outside of the camera's field of view whil ...

Angular 7: Finding the variance between array elements

How can I subtract the values from the first 3 rows of the table? The formula is TVA Collectée - TVA Déductible - TVA Déductible/immo If the result is positive, it should be displayed in the box labeled TVA à Payer. If it's negative, it should g ...

Querying a Database to Toggle a Boolean Value with Jquery, Ajax, and Laravel 5.4

I am facing an issue with a button I created to approve a row in a table. It seems that everything is working fine when clicking the button, but there is no change happening in the MySQL database Boolean column. Here is the code for my button: <td> ...

`How can I dynamically hide a collapsible Bootstrap navbar with a click event in a React.js application?`

Hey there! I've managed to create a collapsible navbar with Bootstrap 5 that is working smoothly, but now I want it to automatically close when the user clicks on a link. Is there a way to achieve this in React? Thanks in advance! React.JS navbar : ...

Separate each item in the list and display them across multiple pages within a table

I'm looking to display a list of 37 items across four separate pages within a table. Can anyone suggest a way to split these items and showcase them in four different pages using either javascript or vue.js? ...

Error: Attempting to access 'map' property from undefined object while making API call

Can someone please help me with a coding problem? When I run the code below, I encounter the error message "TypeError: Cannot read properties of undefined (reading 'map')." Upon logging the "items" variable, I observe 2 results, the first of whi ...

The alignment of the point on the Highchart line appears to be off

I've encountered a minor issue while using Highstock type Highchart for my statistics. I am utilizing the angular version of highchart. Take a look at the screenshot below: https://i.sstatic.net/HPCkw.png As evident from the image, the point is not ...

The limit of update depth when using useState with an array generated from a map operation

I'm working on a component where I'm creating a list from an array using map. Each li element in the list has a ref attached to it to capture the getBoundingClientRect().x and getBoundingClientRect().y coordinates, which are then stored in a refs ...

Generate HTML content based on the permissions from a REST API

I have a frontend that renders based on user permissions from a REST API. These permissions could include deleting users, creating users, adding users to workflows, and more. Most of these permissions are managed by an administrator. So my question is: H ...

Destructuring part of an object within function parameters in JavaScript

Is it possible to selectively destructure specific object properties in function arguments, while keeping the rest accessible within the object? Let's explore this concept with a React example. (Although React is used here, the question pertains to J ...

The perplexity regarding asynchronous functions and return statements

I'm attempting to send a request to a Web API and then return true from a function if the input is valid, or false if it's not. I need the request to be asynchronous so that the function doesn't return before the request is verified. While t ...

Inquiries regarding scopes, node.js, and express

I struggle with understanding scopes and similar concepts in various programming languages. Currently, I am working on an express application where I take user input, query an arbitrary API, and display the results in the console. To interact with the REST ...

Error: The prop type validation failed because a `value` prop was provided to a form field in React-Bootstrap-Typehead component

I am currently using the bootstrap-typehead package from https://github.com/ericgio/react-bootstrap-typeahead and struggling to understand why it's causing issues. Could someone help me identify what's wrong with this code that's triggering ...

What is the method for getting js_xlsx to include all empty headers while saving the file?

In the midst of developing a Meteor App, I've incorporated the Node.js package known as "js_xlsx" from "SheetJS", produced by "SheetJSDev". This tool enables me to convert an Excel sheet uploaded into JSON on the backend. The intention is to store thi ...

Ending a connection to MS SQL server in node.js with mssql library

In my journey to write a node.js script for querying an MSSQL database, I find myself navigating the realm of JavaScript, node.js, and VSCode with limited SQL knowledge. While I have managed to piece together working code, the issue lies in the connection ...