BSP lightmap

Software: Away3D 4.x

kerike, Newbie
Posted: 29 July 2011 09:47 AM   Total Posts: 7

Hi,

I’m doing a bsp loader in away3d, and I have some troubles with the lightmaps stored in the bsp file.

In openGL you can use multitextures, and load the texture and lightmap in one pass. I searched the away3d library and I didn’t find something that is close to multitexturing.

Can you give me an idea on how to do this, or will this feature be added to the library? Maybe it is allready there and I didn’t see it. :)

Thank you very much.

   

Avatar
David Lenaerts, Administrator
Posted: 29 July 2011 05:56 PM   Total Posts: 80   [ # 1 ]

Hi,

The way “multitexturing” used to be done in OpenGL is a bit of a thing of the past. Since shader programs became standard (and the only option in Molehill) over the fixed function pipeline, everything happens in the fragment shader code. To add things to the shader, code, we use shader “methods”, which provide their own pieces of code to the materials. However, for light mapping, there is no method yet. There are secondary uv sets on the SubGeometry objects, though, which were supposed to be used for this. So if you feel up to it, you could try and create your own method.
Check out existing methods in the away3d.materials.methods package.
I would do it myself, but I’ve got my hands tied this week-end :(

Cheers,
David

 

   

kerike, Newbie
Posted: 30 July 2011 05:35 AM   Total Posts: 7   [ # 2 ]

Thanks for the reply. I will check it out, and get back to you.

 

   

kerike, Newbie
Posted: 05 August 2011 07:52 PM   Total Posts: 7   [ # 3 ]

Hi guys,

I have a small question. I’ve written a LightMap method, but the register pool overflowes. This is the code:

public class LightMapMethod extends ShadingMethodBase
 {
  
private var _texture Texture3DProxy;
    
  private var 
_textureIndex:uint;
  private var 
_uvIndex:uint;
 
  public function 
LightMapMethod(bmp:BitmapData null)
  
{
   super
(truefalsefalse);
   
_texture = new Texture3DProxy(bmp);
  
}
  
  arcane override 
function activate(stage3DProxy Stage3DProxy) : void
  {
   super
.activate(stage3DProxy);
   
   
stage3DProxy.setTextureAt(_textureIndex_texture.getTextureForStage3D(stage3DProxy));
  
}
  
  arcane override 
function deactivate(stage3DProxy Stage3DProxy) : void
  {
   super
.deactivate(stage3DProxy);
   
stage3DProxy.setTextureAt(_textureIndexnull);
  
}
  
  arcane override 
function setRenderState(renderable IRenderablestage3DProxy Stage3DProxycamera Camera3Dlights Vector.<LightBase>) : void
  {
   
var subMesh:SubMesh renderable as SubMesh;
   
stage3DProxy.setSimpleVertexBuffer(_uvIndexsubMesh.getSecondaryUVBuffer(stage3DProxy), Context3DVertexBufferFormat.FLOAT_2);
  
}
  
  arcane override 
function getFragmentPostLightingCode(regCache ShaderRegisterCachetargetReg ShaderRegisterElement) : String
  {
   
var code String "";
   
   var 
textureReg ShaderRegisterElement regCache.getFreeTextureReg();
   var 
uvReg ShaderRegisterElement regCache.getFreeFragmentVectorTemp();
   var 
temp ShaderRegisterElement regCache.getFreeFragmentVectorTemp();
   
   
code += "tex " temp ", " uvReg ", " textureReg " <2d,clamp,linear> \n";
   
code += "mul " targetReg ", " targetReg ", " temp " \n";

   
_textureIndex textureReg.index;
   
_uvIndex uvReg.index;
   
   return 
code;
  
}
 } 

And this would be the code were I add the metod to the material:

var lmesh:Mesh _mesh[i];
lmesh.subMeshes[0].material BitmapMaterial(mBitmapArray[id]);
mat BitmapMaterial(lmesh.subMeshes[0].material);
mat.bothSides true;
mat.ambientColor 0xFFFFFF;
mat.addMethod(mLightMapArray[_lightMaterial[i]]); 

There is only one method in the array and it is created prior, but I wrote the code so i could add more methods.
When I tried to debug the algorithm it calls “getFragmentPostLightingCode” until the rergister pool overflowes.
Could you give me some ideas were is the problem?

Thank you.

 

   

Avatar
David Lenaerts, Administrator
Posted: 08 August 2011 09:54 AM   Total Posts: 80   [ # 4 ]

Hey,

Can you check which array is overflowing? I’m guessing it’s the texture one, and your creation code causes many light map methods to be added to a single material. It’s probably better to just use 1 method, and add several textures to it linked to SubMesh instances (fe keeping a Dictionary and activating the Texture in setRenderState instead of in activate.

Code-wise, there’s some mistakes. The secondary uv coordinates would have to be read from the stream and passed on to a varying register in the vertex shader code. This is in fact something that should still be added into the “core” shader compilation code, and then passed on to the methods similar to the primary uv coords, but that’s not yet added at this point, so it’d have to be coded manually in the method until I can fix it.

Also, you call regCache.getFreeFragmentVectorTemp twice in a row to get two registers. However, a temporary register will remain “free” until you reserve it for usage. So until you do, getFreeFragmentVectorTemp will return the same register. You’d need to insert regCache.addFragmentTempUsages(register, 1); before you request a new one, and (important!) call regCache.removeFragmentTempUsage(register); to free it up again. This is only the case for temporary registers.
However, with the previous point, if you use a varying register for the uv coords, you wouldn’t need two temporary registers, so you’ll probably be able to ignore reserving them.

Finally, please don’t create Texture3DProxy instances using “new”, but use BitmapDataTextureCache.getInstance().getTexture(bmd); and freeTexture(texture) in the method’s dispose(). This will allow Away3D to manage your Texture objects more efficiently.

It all may seem a bit overwhelming, but you stepped into one of the darker parts of the Away3D forest wink Gotta add the subject to an already long list of due blog posts…

Oh, and I added the getSecondaryUVBuffer to the IRenderable interface, so there’s no need for that ugly cast anymore smile

 

   

kerike, Newbie
Posted: 08 August 2011 05:52 PM   Total Posts: 7   [ # 5 ]

Hi David,

today I figured out some of the problems, like the one that I need to pass the uv to a varying register and from there to the fragment register.

You are right, the texture buffer is the one overflowing.

Thank you very much for clarifying the use of addFragmentTempUsages and removeFragmentTempUsage, I will do the modifications tonight.

Meanwhile i will leave a screen-shot of my work, I hope after I will finish the modifications it will look better.

Thanks David for everything.

 

   

kerike, Newbie
Posted: 08 August 2011 07:16 PM   Total Posts: 7   [ # 6 ]

Hey,

it’s me again. I just wanted to tell you that I managed to get it working for a small map with only 1 lightmap. I will attach screen shot from it. I think that it is pretty close.

Tomorrow I will try it on the big map, with 15 lightmaps.

 

   

kerike, Newbie
Posted: 17 August 2011 09:33 AM   Total Posts: 7   [ # 7 ]

Hi guys,

this will probably be a noob question, but I can’t figure out how to work this lightmap material for big maps. As you can see it work very nice on a small map with only one lightmap material. I took your advice and made a Dictionary with the submeshes and the materials, and it is not working for the big map. It only sets the lightmap material for a few triangles. As you can see on the snapshot there is a lightmap on the eye, and no lightmaps surrounding the eye.

This is my algorithm in big lines. I create a mesh for every face, so I can the use the PVS algorithm to just add and remove the visible faces. Every mesh has one bitmap material and one lightmap material assigned to it’s submesh[0].

If I assign a shader method to every mesh.submesh[0] then I have that error that I talked about in my other post. If I assign the method to only one of them it is working for the small map, but it isn’t working with the big one.

Can a shader method be assigned like a global method? From the source code I saw that you need a material to assign it to. I am a little bit confused. Any idea would help. smile
I will attach the source code of the shader, and a snapshot.

public class LightMapMethod extends ShadingMethodBase
 {
  
private var _textureIndex:int;
  private var 
_uvIndex:int;
  private var 
_varIndex:ShaderRegisterElement;
  private var 
mDictionary:Dictionary;
  
  public function 
LightMapMethod(dict:Dictionary null)
  
{
   super
(truefalsefalse);
   
mDictionary = new Dictionary();
   
   for (var 
k:Object in dict)
   
{
    
var bmp:BitmapData dict[k];
    
mDictionary[k] BitmapDataTextureCache.getInstance().getTexture(bmp);
   
}
  }
  
  override 
public function dispose(deep Boolean) : void
  {
   
for each(var txt:Texture3DProxy in mDictionary)
    
BitmapDataTextureCache.getInstance().freeTexture(txt);
  
}
  
  arcane override 
function activate(stage3DProxy Stage3DProxy) : void
  {
   super
.activate(stage3DProxy);
  
}
  
  arcane override 
function setRenderState(renderable IRenderablestage3DProxy Stage3DProxycamera Camera3Dlights Vector.<LightBase>) : void
  {
   
var subMesh:SubMesh renderable as SubMesh;
   
stage3DProxy.setTextureAt(_textureIndexmDictionary[subMesh].getTextureForStage3D(stage3DProxy));
   
stage3DProxy._context3D.setVertexBufferAt(_uvIndexsubMesh.getSecondaryUVBuffer(stage3DProxy), 0Context3DVertexBufferFormat.FLOAT_2);
  
}
  
  arcane override 
function getVertexCode(regCache ShaderRegisterCache) : String
  {
   
var code String "";
   var 
uvReg ShaderRegisterElement regCache.getFreeVertexAttribute();
   
   
_varIndex regCache.getFreeVarying();
   
   
code += "mov " _varIndex ", " uvReg "\n";
   
   
_uvIndex uvReg.index;
   return 
code;
  
}
  
  arcane override 
function getFragmentPostLightingCode(regCache ShaderRegisterCachetargetReg ShaderRegisterElement) : String
  {
   
var code String "";
   
   var 
textureReg ShaderRegisterElement regCache.getFreeTextureReg();
   var 
temp ShaderRegisterElement regCache.getFreeFragmentVectorTemp();
   
regCache.addFragmentTempUsages(temp1);
   var 
locReg ShaderRegisterElement regCache.getFreeFragmentVectorTemp();
   
   
code += "mov " locReg ", " _varIndex "\n";
   
code += "tex " temp ", " locReg ", " textureReg " <2d,clamp,linear> \n";
   
code += "mul " targetReg ", " targetReg ", " temp " \n";
   
regCache.removeFragmentTempUsage(temp);
   
_textureIndex textureReg.index;
   
   return 
code;
  
}
 } 

 

   

Avatar
Apprentice, Jr. Member
Posted: 01 September 2011 07:59 AM   Total Posts: 45   [ # 8 ]

I’m also interested in adding light maps to my game. I’d prefer to use official Away 3D code, but if this feature is not planned to come out in the coming few weeks I’d be very interested in your work kerike. You’ve done some nice work already smile

—Apprentice

 

   

kerike, Newbie
Posted: 01 September 2011 11:26 AM   Total Posts: 7   [ # 9 ]

Hi Apprentice,

the only new thing added to the basic away3d library is that “LightMapMethod” that I’ve posted in the earlier post. The rest of the project is based on reading the bsp file, and creating the whole world correctly.I still haven’t solved the problem on loading multiple lightmaps.

I was busy working on some other projects, but I hope to get back to this project, and hopefully finish it soon.

All the best,
Istvan.

 

   

cbrown, Jr. Member
Posted: 10 September 2011 03:50 PM   Total Posts: 39   [ # 10 ]

I have a question in all of this.  Is BSP still necessary now that flash has hardware acceleration?  I only created a BSP map for the Quake II engine way back in the late 90’s so I’m not a BSP expert.  But I thought it was mostly for guaranteeing fast rendering on non-hardware accelerated systems.  It’s no good for scenes with large outdoor spaces, correct?  Don’t BSP maps have to be fully-enclosed spaces?

Also, is BSP absolutely necessary for good collision detection on hardware accelerated systems?  For example, would a scene like this…

http://www.alternativaplatform.com/en/demos/crash/

or this (image below)

...be using BSP?

Thanks for helping me clear up my confusion :/

 

 Signature 
signature_image

whatever is good to know is difficult to learn

   

kerike, Newbie
Posted: 10 September 2011 06:01 PM   Total Posts: 7   [ # 11 ]

Hi,

in hungarian there is a saying. Two things are necessary, or a must. To die and to go to the bathroom when you have diarrhea.

So you don’t have to use bsp maps if you don’t want to. There are collision detection algorithms out there, there are algorithms that help you pick out which objects to show and so on.

Bsp has it all in one, and the best thing - from my perspective- it works. From my experience, there are a lot of algorithms on the net, that are buggy, and it is a good thing to start with something that works.

I just want to tell you, if I didn’t use the culling algorithm from the bsp file, and rendered all the triangles, the whole thing cracked. But you are right, bsp can be used only for closed scenes.

Best regards,
Istvan.

 

   

carl.looper, Newbie
Posted: 19 May 2012 10:10 PM   Total Posts: 8   [ # 12 ]
David Lenaerts - 08 August 2011 09:54 AM

It all may seem a bit overwhelming, but you stepped into one of the darker parts of the Away3D forest wink Gotta add the subject to an already long list of due blog posts…

I look forward to a tutorial on how one goes about properly integrating AGAL code into a simple Away3D material shader. Reverse engineering how Away3D otherwise integrates AGAL is quite arduous.

Carl

 

   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X