Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lightmap] Add “lightmap” component #279

Open
donmccurdy opened this issue Nov 13, 2018 · 11 comments
Open

[lightmap] Add “lightmap” component #279

donmccurdy opened this issue Nov 13, 2018 · 11 comments

Comments

@donmccurdy
Copy link
Collaborator

Lightmap could be added through a separate component, like envMap. Adding directly to “material” doesn’t make sense, since it can’t be applied to models with existing materials.

@donmccurdy donmccurdy changed the title Add “lightmap” component [lightmap] Add “lightmap” component Nov 22, 2018
@biomorphica
Copy link

biomorphica commented Jul 11, 2019

Some reasons to add light maps directly to the material 1) avoid pixelation from overly dense map packing. If you had to use a single texture atlas for all objects in the scene, it would surely get crowded and lead to a pixellation problem 2) scene organization: keep lights maps associated with other textures. They are generated in 3d apps (max maya blender etc), on a per material basis, in a process called Render To Texture (aka 'baked lighting'). It makes sense to keep them in the material as they are composited over other textures (normal, roughness, etc). The problem is that light maps must use a second uv map channel as the baking fragments the texture.
Light maps are a bit different that AO, which could get away with using a single map for the entire scene as detail is not so relevant. Light maps have the base color textures with lighting added in, so detail is crucial. Part of the art of light mapping is generating high resolultion maps where needed (areas of game play focus) and low res for peripheral objects.
The 'problem' is accessing the second map channel. Not sure if gltf exports multiple uv map channels, but if it doesn't, it should (I think it does). THREE.js enforces lightmaps and AO to use map chan 2, and all others map chan 1. This would be ideal. It is simply a matter of AFrame parsing the glb, understanding which texture is the light map, and assigning and reading map chan 2. I suggest using the emissive slot in gltf as the light channel.
Of course one can use lightmaps now without any new changes, by placing the renderToTexture (ie the lightmap) in the baseColor or emissive map slot. The problems is that this light map can't be used with other textures, because it requires another uv set. So really all we need is the ability to use 2 uv sets.
Light maps are standard fare for Unity and Unreal, and are really important for building realism or sophisticated looks through texturing. Ultimately you'd want to harness the power of pbr in addition to light maps, so that you could have normal maps, roughness, metallic (and all the power of substance designer) in addition to baked lighting. Obviously you don't want light maps for objects that move, but for static object, it really transforms the flat look to something complex and emotional. I think light maps are important tool for any game designer, and a big step to take AFrame beyond the "webgl look" and bring it up to the shading sophistication of Unity.

@biomorphica
Copy link

@biomorphica
Copy link

biomorphica commented Jul 19, 2019

Here is a brilliant example of blending light maps with the complexity of shaders. Not sure if this was done with AFrame, but this is what we need. (would love to have ;)
https://showroom.littleworkshop.fr/

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Jul 20, 2019

Light maps have the base color textures with lighting added in, so detail is crucial.

I don't follow this – lightmaps are independent of the base color texture, I think?

Part of the art of light mapping is generating high resolultion maps where needed (areas of game play focus) and low res for peripheral objects.

Quality is, in the end, a matter of UV space. Like with AO, you can allocate more or less UV space to a region, regardless of the number and size of textures involved. This is why both AO and Lightmaps often use a second UV channel, distinct from the UV channel used for the base color texture and normals.

Not sure if gltf exports multiple uv map channels...

It does, yes.

I suggest using the emissive slot in gltf as the light channel...

Even though glTF does not have a lightmap feature yet, once it is parsed to a threejs or a-frame material, the .lightMap texture slot is available. The proposal in this PR is to add a new component that allows a lightmap to be added to a glTF model, rather than bundled into it. I don't want to treat an emissive map as a lightmap in a shared library, although users applications are free to do things like that.

For example:

<a-entity gltf-model="src: scene.glb"
  lightmap="src: lightmap.png"></a-entity>

This should be a fairly simple component to create, but would perhaps not handle (or at least not handle easily) cases where the model requires multiple lightmaps. That can be avoided by packing them in the texturing application, but in the end the best workflow would be for glTF to support lightmaps itself. This has been proposed, and feedback/encouragement on KhronosGroup/glTF#1017 would be welcome.

@biomorphica
Copy link

biomorphica commented Jul 20, 2019 via email

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Jul 20, 2019

Note that this issue is for the creation of an A-Frame component that would let you load a lightmap from a texture file, or perhaps multiple lightmaps, that is separate from your glTF model. Having lightmaps embedded in glTF models would require the glTF specification to support this, tracked elsewhere, and not in scope for A-Frame Extras to solve. Best-case scenario, then, you'd need to know the name of each primitive to assign the lightmap:

<a-entity gltf-model="src: scene.glb"
  lightmap_top="src: lightmap_top.png"
  lightmap_base="src: lightmap_base.png"></a-entity>

^This would imply that primitives named "top" and "base" exist in the GLB file.

@biomorphica
Copy link

biomorphica commented Jul 20, 2019 via email

@biomorphica
Copy link

biomorphica commented Jul 20, 2019 via email

@colinfizgig
Copy link

I’ve written a light map component. It’s here...
https://github.com/colinfizgig/aframe_Components

The only downside right now was that I was having trouble targeting preexisting Second UV sets. So currently it just duplicates the first UV set. If the light map matches the UVs it works. This isn’t optimal, since the lightmap could me optimized for packing. Donmccurdy do you know of a way to target the second map? It may be that the second UVs are not exported with GLTF?

Either way hopefully this component helps.

@donmccurdy
Copy link
Collaborator Author

A glTF file might or might not include a second UV set. While threejs and A-Frame require it for AO and lightmaps, glTF does not. If you just have one UV set in Blender, and export to glTF, you'll just have one UV set in the resulting file. You can duplicate the UVs in Blender first, or duplicate them after loading in your component:

if ( material.lightMap
    && geometry.attributes.uv2 === undefined
    && geometry.attributes.uv !== undefined ) {

  geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );

}

@biomorphica
Copy link

biomorphica commented Oct 3, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants