B
Bastendorf
Guest
First things first, I looked all over and found nothing on this topic anywhere, so if there was already a topic like this started, I apologize.
Now, I understand that what I'm asking is quite advanced, and could be out of the scope of GameMaker all together, so this is something I'm already expecting to be unable to pull off, or for there to be no one with any ideas to get this done. Just wanted to put that out there.
On to the question: Is it possible to use normal maps on/with tiles? I spent 4 to 5 days painstakingly making a bunch of normal map tiles for all the tiles in my first room, so I already have the normal maps. Right now, the plan was to use them by having a tileset background of the diffuse map tiles and a tileset background of the normal map tiles, with the corresponding tiles setup to share the exact same coordinates.
Uh... What I mean with my rambling there is, I have two tilesets, they're both identical, but one is normals the other is diffuse, so if you laid them over top of each other, the normals would line up perfectly with the diffuse. But I can't figure out how to use it that way. (It might not even be possible).
I'm already using the Sprite Lamp shaders, but in order for that to work, the sprite with the normal map has to be an object, which means either each tile has to be an object (the problems with this are self evident) or I would have to get an object to add all of the tiles, which means breaking my back to make the script draw the world, and the world isn't going to be a simple, repeating backdrop (think RPG). This sounds nightmare-ish, so I'd rather not have to do that.
What I'm hoping for is a way to do this:
Which comes from the Sprite Lamp tutorial, but do it with tiles instead. Which I am unable to do because it requires me to run it from a draw event, and I'm not sure how to do that with tiles placed down in the room editor. I'll be perfectly honest, I'm not much of a coder. I can quite competently work on my own until I run into something advanced, like this. I usually use tutorials to rescue me, but there are very few shader-based lighting tutorials, and fewer that use normal maps.
I'm sure there are other ways, I just spent 2 months setting up my game to rely on normal map shaders only to realize, after doing a bunch of work, that using it with tiles isn't as straight forward, and would hate to have to scrap all that mind-numbing work I did.
But I wouldn't mind having to set the normal maps up a different way if the method I thought I was going to be able to use won't work.
And lastly, yes, normal maps are a must. I don't want to use the fake-looking alpha lighting engine, and although GlareEngine is cool, it doesn't give the same atmosphere that a normal map would have, and that normal map atmosphere is what I've been banking on since the start of the project.
Now, I understand that what I'm asking is quite advanced, and could be out of the scope of GameMaker all together, so this is something I'm already expecting to be unable to pull off, or for there to be no one with any ideas to get this done. Just wanted to put that out there.
On to the question: Is it possible to use normal maps on/with tiles? I spent 4 to 5 days painstakingly making a bunch of normal map tiles for all the tiles in my first room, so I already have the normal maps. Right now, the plan was to use them by having a tileset background of the diffuse map tiles and a tileset background of the normal map tiles, with the corresponding tiles setup to share the exact same coordinates.
Uh... What I mean with my rambling there is, I have two tilesets, they're both identical, but one is normals the other is diffuse, so if you laid them over top of each other, the normals would line up perfectly with the diffuse. But I can't figure out how to use it that way. (It might not even be possible).
I'm already using the Sprite Lamp shaders, but in order for that to work, the sprite with the normal map has to be an object, which means either each tile has to be an object (the problems with this are self evident) or I would have to get an object to add all of the tiles, which means breaking my back to make the script draw the world, and the world isn't going to be a simple, repeating backdrop (think RPG). This sounds nightmare-ish, so I'd rather not have to do that.
What I'm hoping for is a way to do this:
shader_set(SpriteLampShader);
shader_set_uniform_f(u_SpriteAngle, image_angle * pi / 180.0);
shader_set_uniform_f(u_TextureRes, textureWidth, textureHeight);
var lightPosArray;
var lightColourArray;
if(numLights >= 1)
{
lightPosArray[0] = lightSource1.cameraSpacePosX;
lightPosArray[1] = lightSource1.cameraSpacePosY;
lightPosArray[2] = lightSource1.zPosition;
lightColourArray[0] = lightSource1.colourRed;
lightColourArray[1] = lightSource1.colourGreen;
lightColourArray[2] = lightSource1.colourBlue;
}
if(numLights >= 2)
{
lightPosArray[3] = lightSource2.cameraSpacePosX;
lightPosArray[4] = lightSource2.cameraSpacePosY;
lightPosArray[5] = lightSource2.zPosition;
lightColourArray[3] = lightSource2.colourRed;
lightColourArray[4] = lightSource2.colourGreen;
lightColourArray[5] = lightSource2.colourBlue;
}
if(numLights >= 3)
{
lightPosArray[6] = lightSource3.cameraSpacePosX;
lightPosArray[7] = lightSource3.cameraSpacePosY;
lightPosArray[8] = lightSource3.zPosition;
lightColourArray[6] = lightSource3.colourRed;
lightColourArray[7] = lightSource3.colourGreen;
lightColourArray[8] = lightSource3.colourBlue;
}
if(numLights >= 4)
{
lightPosArray[9] = lightSource4.cameraSpacePosX;
lightPosArray[10] = lightSource4.cameraSpacePosY;
lightPosArray[11] = lightSource4.zPosition;
lightColourArray[9] = lightSource4.colourRed;
lightColourArray[10] = lightSource4.colourGreen;
lightColourArray[11] = lightSource4.colourBlue;
}
shader_set_uniform_f_array(u_LightPosArray, lightPosArray);
shader_set_uniform_f_array(u_LightColourArray, lightColourArray);
texture_set_stage(u_NormalDepthMap, normalDepthTexture);
texture_set_stage(u_SpecGlossMap, specGlossMap);
texture_set_stage(u_AOMap, aoMap);
texture_set_stage(u_EmissiveMap, emissiveMap);
shader_set_uniform_f(u_CelLevel, celLevel);
shader_set_uniform_f(u_Shininess, shininess);
shader_set_uniform_f(u_WrapAroundLevel, wrapAroundLevel);
shader_set_uniform_f(u_AOStrength, aoStrength);
shader_set_uniform_f(u_EmissiveStrength, emissiveStrength);
shader_set_uniform_f(u_AmplifyDepth, amplifyDepth);
shader_set_uniform_f(u_UpperAmbientColour,
upperAmbient_Red, upperAmbient_Green, upperAmbient_Blue);
shader_set_uniform_f(u_LowerAmbientColour,
lowerAmbient_Red, lowerAmbient_Green, lowerAmbient_Blue);
shader_set_uniform_f(u_numLights, numLights);
// must check each frame
spritelamp_updatelights();
draw_self();
shader_reset();
shader_set_uniform_f(u_SpriteAngle, image_angle * pi / 180.0);
shader_set_uniform_f(u_TextureRes, textureWidth, textureHeight);
var lightPosArray;
var lightColourArray;
if(numLights >= 1)
{
lightPosArray[0] = lightSource1.cameraSpacePosX;
lightPosArray[1] = lightSource1.cameraSpacePosY;
lightPosArray[2] = lightSource1.zPosition;
lightColourArray[0] = lightSource1.colourRed;
lightColourArray[1] = lightSource1.colourGreen;
lightColourArray[2] = lightSource1.colourBlue;
}
if(numLights >= 2)
{
lightPosArray[3] = lightSource2.cameraSpacePosX;
lightPosArray[4] = lightSource2.cameraSpacePosY;
lightPosArray[5] = lightSource2.zPosition;
lightColourArray[3] = lightSource2.colourRed;
lightColourArray[4] = lightSource2.colourGreen;
lightColourArray[5] = lightSource2.colourBlue;
}
if(numLights >= 3)
{
lightPosArray[6] = lightSource3.cameraSpacePosX;
lightPosArray[7] = lightSource3.cameraSpacePosY;
lightPosArray[8] = lightSource3.zPosition;
lightColourArray[6] = lightSource3.colourRed;
lightColourArray[7] = lightSource3.colourGreen;
lightColourArray[8] = lightSource3.colourBlue;
}
if(numLights >= 4)
{
lightPosArray[9] = lightSource4.cameraSpacePosX;
lightPosArray[10] = lightSource4.cameraSpacePosY;
lightPosArray[11] = lightSource4.zPosition;
lightColourArray[9] = lightSource4.colourRed;
lightColourArray[10] = lightSource4.colourGreen;
lightColourArray[11] = lightSource4.colourBlue;
}
shader_set_uniform_f_array(u_LightPosArray, lightPosArray);
shader_set_uniform_f_array(u_LightColourArray, lightColourArray);
texture_set_stage(u_NormalDepthMap, normalDepthTexture);
texture_set_stage(u_SpecGlossMap, specGlossMap);
texture_set_stage(u_AOMap, aoMap);
texture_set_stage(u_EmissiveMap, emissiveMap);
shader_set_uniform_f(u_CelLevel, celLevel);
shader_set_uniform_f(u_Shininess, shininess);
shader_set_uniform_f(u_WrapAroundLevel, wrapAroundLevel);
shader_set_uniform_f(u_AOStrength, aoStrength);
shader_set_uniform_f(u_EmissiveStrength, emissiveStrength);
shader_set_uniform_f(u_AmplifyDepth, amplifyDepth);
shader_set_uniform_f(u_UpperAmbientColour,
upperAmbient_Red, upperAmbient_Green, upperAmbient_Blue);
shader_set_uniform_f(u_LowerAmbientColour,
lowerAmbient_Red, lowerAmbient_Green, lowerAmbient_Blue);
shader_set_uniform_f(u_numLights, numLights);
// must check each frame
spritelamp_updatelights();
draw_self();
shader_reset();
I'm sure there are other ways, I just spent 2 months setting up my game to rely on normal map shaders only to realize, after doing a bunch of work, that using it with tiles isn't as straight forward, and would hate to have to scrap all that mind-numbing work I did.
But I wouldn't mind having to set the normal maps up a different way if the method I thought I was going to be able to use won't work.
And lastly, yes, normal maps are a must. I don't want to use the fake-looking alpha lighting engine, and although GlareEngine is cool, it doesn't give the same atmosphere that a normal map would have, and that normal map atmosphere is what I've been banking on since the start of the project.