I am loading a BM3 file which contains definitions of (geometry and) material information as below:
{
type: "Phong",
opacity: 1,
name: "",
diffuseMap: 0,
color: [
0.254902,
0.2,
0.129412,
],
transparent: false,
specularMap: 1,
specular: [
0.811765,
0.811765,
0.811765,
],
shininessInSpecMap: true,
shininess: 174,
refractionRatioMap: 2,
refractionRatio: 3.35294,
normalMap: 3,
LUTPublications: [
"pot",
],
lightMap: 4,
}
I then am using ThreeJS to create a Mesh object and MeshPhongMaterial.
Below are maps in this order: diffuseMap, normalMap, specularMap, refrationRatioMap, lightMap. The MeshPhongMaterial is created using above maps except the lightMap.
If I load this mesh I get below dark image:
If I change the color property to (1,1,1) instead. I get just a brighter orange color, but the pot is still dark.
However if I load this object in another application it looks like this:
The pot looks bright. It looks to me as if the metal/steel side of the material is not handled correctly, as this is the case with any other model I tried which has a part that looks like steel. Any idea why the material is rendered dark (while it should be rendered differently/brighter)?
Your normal map is likely reversed, which is causing light to reflect away from the camera. In the software where you're generating the normal map, look for a setting like Y+, Y-up, bottom-up, or OpenGL.
Related
I recently started learning about shaders and three.js. I tried to display a shader with a texture but it displays all black.
Here's the codepen: https://codepen.io/LDB95/pen/MxmWNq
These are my uniforms:
uniforms: {
tDiffuse: { value: null },
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
iChannel0: { type: 't', value: new THREE.TextureLoader().load('https://naqyr37xcg93tizq734pqsx1-wpengine.netdna-ssl.com/wp-content/uploads/2017/11/10-Things-We-Can-Learn-From-the-Incredible-Steve-Jobs.jpg')},
iChannel1: { type: 't', value: new THREE.TextureLoader().load('https://gobelmont.ca/Portals/0/xBlog/uploads/2018/8/30/white%20noise.jpg')},
},
I just can't seem to find the fix. Would be really awesome if someone could help me out here :)
Thanks!
I'm afraid your codepen is full of mistakes. It seems you are trying to port a shader from shadertoy to three.js, right?
I have removed all errors here but the effect still looks broken: https://codepen.io/anon/pen/XGRVew
Anyway, here are a few things to keep in mind:
You have to assign the textures to the uniforms after you have created the shader pass. Uniforms are cloned for the internal material of ShaderPass. That means textures are cloned, too. The respective needsUpdate flag is not set correctly if you load the texture before the material creation.
As mentioned by #Marquizzo, your texture are blocked for security reasons. I've added some textures from the three.js repo for test purposes.
The following line of code is not necessary since uv coordinates are provided with the geometry. It's not necessary to compute them on-the-fly like shadertoy does. Just use the varying vUv in the fragment shader.
vec2 uv = gl_FragCoord.xy / resolution.xy;
For such simple one-pass shaders, it's not necessary to use EffectComposer. Try to use an approach similar to this official example.
You always have to ensure that the example files like ShaderPass or EffectComposer match the three.js version in your code. I've changed this in the codepen in order to remove all deprecation warnings.
I'm attempting to get a basic THREE.js example to work and modify it from there on out but it just keeps outputting a torus, no matter what I change.
I've copied the exact code from the docs page into a JSFiddle and again I get a torus.
Here is the docs page example:
CylinderGeometry
And here is the jsfiddle with the torus: https://jsfiddle.net/ded9grxn/
I've tried adding the code from the docs page to the example like so:
var geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 );
var material = new THREE.MeshPhongMaterial(
{
color: 0x156289,
emissive: 0x072534,
side: THREE.DoubleSide,
shading: THREE.FlatShading
});
mesh.add(
new THREE.Mesh(
geometry,
material
)
);
But to no avail. Any help is appreciated!
The reason you fiddle does not work is that the script you invoke (https://threejs.org/docs/scenes/js/geometry.js) looks at the hash in the URL of the window to select the object.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html#CylinderGeometry
you get the cylinder.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html
you get the default, which is a torus.
For the reason why your modification does not work, we need more information about how you performed the modif (what did you remove, where did you add).
(Edit) in the fiddle, after doing your modification, do not forget to remove the line
var options = chooseFromHash( mesh );
this is where your script invokes the function in geometry.js that will set the mesh according to the hash in the URL
I am trying to apply a decal to the outside of a mesh object using DecalGeometry. However, the decal appears on the inside of the mesh. I've tried rotation and position settings within the DecalGeometry, but can't seem to affect which side of the mesh the decal appears on. FWIW, the mesh is a custom OBJ model. My code is a bit extensive to post here, but you can view the issue here. I have red BoundingBoxHelpers to help visualize the placement.
The materials object has a parameter which allows you to designate the side(s) of the mesh on which it will display (thanks #j-t for posting this question Prevent decal from showing on inside of mesh. My working code looks like this...
var decalMaterial = new THREE.MeshPhongMaterial( {
map: decalNormal,
transparent: true,
depthTest: true,
depthWrite: false,
polygonOffset: true,
polygonOffsetFactor: - 4,
side: THREE.DoubleSide
});
I am very new to three.js. In my project you can move through a series of planes with cross section images of an object. The problem is that the material doesn't load right away and moving up and down too quickly causes some of the planes to display black. I need to change this behavior. Is there a way to either
change some property so the plane is transparent - but the image should still be opaque when loaded
or don't display/render the plane at all until the texture is loaded?
I'm not at all sure I am on the right track, and I am hoping someone more experienced can suggest a specific fix.
Thanks!
Not sure if you already cleared this up but I made a handy little function to take care of this by modifying the opacity setting, the basic of which are:
function loadTexture( path ){
var mat = new THREE.MeshBasicMaterial({
map: new THREE.ImageUtils.loadTexture( path, null, function() {
mat.opacity = 1;
} ),
opacity: 0
});
return mat;
}
How can we create glossy effects on materials with three.js like the one on this link?
I am not interested in path tracing (yet :) )
WebGL Path Tracing
Glossy refers to the ability of a material to reflect light in the specular direction.
In three.js, you can use THREE.MeshPhongMaterial to do that. For example:
new THREE.MeshPhongMaterial( {
color: 0x996633,
envMap: envMap, // optional environment map
specular: 0x050505,
shininess: 100
} )
You can also use MeshStandardMaterial with an environment map.
three.js r.97