I've been baking textures (and shadows) in Cinema4D, and exporting as GLTF to import into Three.js. However, I'd like to animate some of these objects. Is there an equivalent to baking textures for moving objects, or a best way to do this?
three.js (as of r125) supports three types of lighting that could be pre-baked in Blender:
Diffuse / Base Color (material.map)
Lightmap (material.lightMap)
Ambient Occlusion (material.aoMap)
Of these, only ambient occlusion is usually baked for dynamic objects. This represents the "soft shadows" in corners, holes, and insets that would receive less light from diffuse (widely spread) sources. Directional sources (like THREE.PointLight) can still modify the effect of .aoMap as the object moves: for example, shining a light into a dark corner could hide all ambient occlusion. So this method remains useful for dynamic objects, more so than baked diffuse textures and light maps.
If you need additional "hard shadows" that depend on the direction of the light, those would need to be computed at runtime in three.js.
Related
I am new to three.js and I created a classic sphere, wrapped with a world color map & bump map and an alpha map for clouds, and directional sunlight. How can I now add an earth at night texture only on the shadow side of the globe? The globe is rotating, so I couldn't just create 2 half-spheres.
I tried adding this grayscale mask to the texture, but it is also visible in daytime. I then tried illuminating the map with a different light aimed at the dark side, but couldn't selectively target only one material. I didn't quite understand if I need to use "emissiveMap".
Could I shine a light through a semi-transparent map/mask from the center of the earth to make the cities visible, or is there some type of "black light" to only make selected color/map areas shine in the dark?
I don't need any glowing effects, I just want it to be visible. Will I have to create individual light points or learn to use fragment shaders?
Is it possible to have a custom geometry emit light in Three.js?
There is a similar question from 5 years ago here.
In my particular case, I have created a TorusGeometry. I would like this torus to also give off light. Is that possible?
The only true way to do this is raytracing, in which case your torus becomes an "emitter" of photons and its geometry is used to calculate the initial directions of said photons.
Otherwise, light technically doesn't exist. Only (mathematical) descriptions of lights exist. (Remember, lights aren't visible/aren't rendered unless you're using a LightHelper.) These descriptions are used by material shaders, which use the light descriptions (and other objects in the scene, in the case of shadows) to determine the color the current fragment should contribute to a pixel.
With this in mind, if you could write a shader to handle a torus-shaped light, then all you need to do is provide that light's information to the shader. You can do this by extending a THREE.js light class to make your own TorusLight to add to the scene, then give the objects in your scene your custom shader.
THAT SAID, if you'd be satisfied with simulating the torus light, and want a visible torus, you can always add a PointLight at the position of your torus (or several throughout the body of the torus), and give your torus some kind of glow effect.
I have a large terrain scene with many objects that cast shadows on the terrain. It seems I need multiple light sources to achieve good shadow resolution.
I will probably need to edit the source code to make a particular light affect one object in the scene only so that it only casts shadows from that one light.
How do I edit the shadows SRC in THREE.JS to acheive this?
I needed to refactor my custom mesh creation a bit
from:
create mesh of unified sizes (SIZE,SIZE,SIZE), than scale them as needed (setting scale for each axis)
to:
create mesh with correct size, do not scale later
meshes are custom generated (vertices, faces, normals, uvs), nothing of this process was altered, worked like a charm before
=> resulting meshes are the same size, position, etc.
The whole scene setup stays the same: lights, shadowing, materials, yet when using the second approach the whole lighting is very very bright and super reflective, is that a known issue?
material used is MeshPhongMaterial with map, bumMap, specMap, envMap
using three.js r68, no error/warning in console
before:
https://cloud.githubusercontent.com/assets/3647854/3876053/76b8f260-2158-11e4-9e96-c8de55eaec9a.png
after:
https://cloud.githubusercontent.com/assets/3647854/3876052/76b7fa86-2158-11e4-9393-8f3eece04c0b.png
Did you rescale the normals in the mesh?
The mesh format probably needs normalized normals, in which case, the new normals are now incorrect, but would've been correct, if you hadn't rescaled.
Alternately, you say the lights haven't been changed, maybe they need to be appropriately redirected in the scene. (Assuming you're applying different scaling factors in each axis.)
I am building quite a complex 3D environment in Three.js (FPS-a-like). For this purpose I wanted to structure the loading of textures and materials in an object oriƫnted way. For example; materials.wood.brownplank is a reusable material with a certain texture and other properties. Below is a simplified visualisation of the process where models uses materials and materials uses textures.
loadTextures();
loadMaterials();
loadModels();
//start doing stuff in the scene
I want to use that material on differently sized objects. However, in Three.js you can't (AFAIK) set a certain texture scale. You will have to set the repeat to scale it appropiate to your object. But I don't want to do that for every plane of every object I use.
Here is how it looks now
As you can see, the textures are not uniform in size.
Is there an easy way achieve this? So cloning the texture and/or material every time and setting the repeat according to the geometry won't do :)
I hope someone can help me.
Conclusion:
There is no real easy way to do this. I ended up changing my loading methods, where things like materials.wood.brownplank are now for example getMaterial('wood', 'brownplank') In the function new objects are instantiated
You should be able to do this by modifying your geometry UV coordinates according to the "real" dimensions of each face.
In Three.js, UV coordinates are relative to the face and texture (as in, 0.0 = one edge, 1.0 = other edge), no matter what the actual size of texture or face is. But by modifying the UVs in geometry (multiply them by some factor based on face physical size), you can use the same material and texture in different sizes (and orientations) per face.
You just need to figure out the mapping between UVs, geometry scale and your desired working units (eg. mm or m). Sorry I don't have, or know a ready algorithm to do it, but that's the approach you probably need to take. Should be quite doable with a bit of experimentation and google-fu.