Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
The Cheshire Cat
Jun 10, 2008

Fun Shoe

roomforthetuna posted:

Given that you're apparently wanting it to be possible for an object to be halfway pushed through a portal, how do you intend to resolve the gravity for that object? Just switching as its center of mass goes through, or would it have gravity acting in two directions on it such that it might start spinning?

Edit: It sounds like could still do it with a rendertexture, you'd just have to render two of an object whenever the object is part way through a portal, and do extra tests for hitscans when the line hits a portal.

Just a center of mass switch - my concept doesn't require that something will be pulled in two separate directions simultaneously by gravity. Think of it more as you start on the floor, walk through a portal, and now you're walking on the ceiling. To the player it should seem as if they just walked through a door, so having gravity apply conflicting forces would actually break that feeling.

I'm not sure I understand entirely what you mean - have the game create a second object on the other side of the portal if one is in the process of passing through but hasn't actually "teleported", so that it will appear on the other side as it intersects the rendertexture, or is there some way to get the engine to actually render an object simultaneously in two places? If the latter works that would be ideal.

One solution I've been thinking about is to have a mobile "transition" room that sits at each doorway. It would have a rendertexture on the far wall of the small room that would display the other side of the portal, and instead of having the player pass into the portal to teleport, the transition room and everything in it will swap positions with another transition room to deposit the player at the actual location the rendertexture depicts, with the transition room spun around so that the area the player is viewing is now the actual main room, and the rendertexture is displayed behind them, showing the area they just came from. The main reason the whole room is moved rather than just the objects in it is because this would allow objects the player is pushing along to transition more smoothly, since the room would only move when the PLAYER crosses the threshold. Presumably this implies that the room would have to be large enough that an object fits neatly in the room as the player enters (the rendertexture on the far wall could also teleport objects and projectiles if they collide with it and the player has not entered the transition room, since the teleporting would be less noticeable when the player is farther away).

It would be a smoother transition, but it would require every doorway to be unusually deep in order to fit the player, and it might cause issues with any physics objects that are straddling the edge of the room when it moves. I would still prefer a solution that allows for smooth portal behaviour without having to kludge it together.

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

The Cheshire Cat posted:

I'm not sure I understand entirely what you mean - have the game create a second object on the other side of the portal if one is in the process of passing through but hasn't actually "teleported", so that it will appear on the other side as it intersects the rendertexture, or is there some way to get the engine to actually render an object simultaneously in two places? If the latter works that would be ideal.
I'm not sure how the engine handles it exactly, but if you're in control of the rendertexture part then you could move the object to the "far side" of the portal before making that render, then to the "near side" before the regular render, to get it rendering "simultaneously" in two places.

But yes, making it into two objects while it passes through a portal was also an option I was thinking of when suggesting that, if the engine can't do it any other way.

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!
This is all to recreate the final scene out of Labyrinth, isn't it?

To stay on the game dev topic, any people here familiar enough with flixel to give me some help on how to do things like pixel perfect terrain collisions and different types of terrain (like water for swimming)?

FlyingDodo
Jan 22, 2005
Not Extinct
I have a rather puzzling problem relating to constructing an AABB tree and its peformance, it seems to be far too slow. Firstly some information about the tree. It is a binary tree and built by inserting element one at a time. Data is only stored in leaf nodes, all other nodes just bounding boxes.

When inserting an element, if the current node is not a leaf node, the current nodes bounding box is enlarged so it is big enough to contain the element being inserted. Then one of the two child nodes is chosen by checking if the inserted element is inside the bounding box of one of the two child nodes, if it is it gets sent down the respective node. If it is not inside either but it is intersecting then it chooses the one it intersects. If it does not intersect either of the nodes then it calculates the manhattan distance between the centre of the child nodes bounding box and the centre of element to be inserted bounding box. If the distance is greater it chooses the node with the greater manhattan distance. For whatever reason this seems to give better performance than checking if it is less.

The performance does not seem to be very good overall. There is, up until around 14000 elements in the tree, better performance simply by comparing a given AABB against every other AABB. Even then it is only a ~100ms difference of ~700ms vs ~800ms.

I am assuming there is something wrong with how I insert things into the tree. Anything I can find on building AABB trees is either how to build them if you already have all elements in advance (not in this case), or the algorithm given is similar to what I already do, but chooses the child node based on some mysterious unexplained cost function. One suggests manhattan distance but as I have said it strangely gives better performance choosing the further node. Thoughts anyone?


edit: found and fixed a bug to do with the manhattan distance check, which (sort of) explained why at the time choosing the further distance made it faster. Now it is checking which is closer instead of further away, which is obviously correct. The time is now down to ~400ms vs 800ms. I still think it could be faster. It seems that having a good cost function is key to performance.

FlyingDodo fucked around with this message at 18:37 on Jun 27, 2011

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
Have you tried outputting any data on the tree? You want to have a look at how deep it is, and how many entities each leaf node contains. Generally you want to have your entities spread fairly evenly throughout the leaves, since your tree does very little good if 90% of your entities are all in the same leaf. Also, if you have a malfunction building the tree, you may end up with a tree thousands of layers deep (also bad).

dereekb
Nov 7, 2010

What do you mean "error"?
I've recently come across this problem:





(Please ignore the temporary textures, ty :v:)

The back/lower side of the mountain is "clipping through" for what I think is culling or the Z-buffer are getting thrown off. I recently added the skybox, but I've turned it off/on just to check, but no go. Even while it was on, the old terrain never clipped through itself.


I actually glue'd in my previous terrain generation/vertex creation code and it still didn't work.


So, I'm looking for suggestions and ideas on whats up. (Coded with XNA)


I swear I had this problem before, but forgot what I did to fix it then...

dereekb fucked around with this message at 01:49 on Jun 28, 2011

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!
It looks like alternate triangle strips are having issues. Are you using the same windings throughout? It's hard because the shots are so dim, but maybe you are reversing the normals every row somehow?

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.
e: nevermind, I can't read apparently.

PDP-1 fucked around with this message at 03:09 on Jun 28, 2011

dereekb
Nov 7, 2010

What do you mean "error"?
Er, yea, sorry about the bad lighting. The attached file should be easier to see.


Apparently it's called Z-fighting, but I've done what was recommended and no change. Luckily I have an entire copy of the project from last week saved, so I'll have to go through it and see what I changed.

At this point I'm thinking it has something to do with the camera, but then again its possible that I enabled/disabled something when calling draw().

Only registered members can see post attachments!

dereekb fucked around with this message at 05:58 on Jun 28, 2011

dereekb
Nov 7, 2010

What do you mean "error"?
Well, actually... My Backups now throw graphics errors when trying to play them.

:negative:

quote:

Direct3D9: (ERROR) :Unsupported mag filter.

Direct3D9: (ERROR) :Invalid texture sampler state value. SetSamplerState failed.

Seems like part of the puzzle though. I was "unplugging" the DirectX SDK from my project so, maybe there were some side effects... Or they're unrelated. v:shobon:v



Edit:
Got everything back to working, although the original cause is still unknown... To get the quoted error to go away, I removed the magfilter from the shader (no change in looks, so...), and had to impliment the following code in the HLSL file the terrain uses:

quote:

ZEnable = True;
ZWriteEnable = True;

dereekb fucked around with this message at 06:12 on Jun 28, 2011

FlyingDodo
Jan 22, 2005
Not Extinct

Gerblyn posted:

Have you tried outputting any data on the tree? You want to have a look at how deep it is, and how many entities each leaf node contains. Generally you want to have your entities spread fairly evenly throughout the leaves, since your tree does very little good if 90% of your entities are all in the same leaf. Also, if you have a malfunction building the tree, you may end up with a tree thousands of layers deep (also bad).

By design each leaf contains only one element, and for the ~14,000 element test the maximum depth was 65. It's not excessively deep but still seems a bit too deep for the number of elements in it.

edit: average (mean) depth for ~14,000 element test is around 25.

FlyingDodo fucked around with this message at 06:53 on Jun 28, 2011

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

FlyingDodo posted:

By design each leaf contains only one element, and for the ~14,000 element test the maximum depth was 65. It's not excessively deep but still seems a bit too deep for the number of elements in it.

edit: average (mean) depth for ~14,000 element test is around 25.

I guess what's happening then is that the nodes in the graph are overlapping too much, so when you check an AABB against the tree it ends up checking a few thousand nodes instead of the 50 or so it would in perfect conditions? Looking at the algorithm you describe for building the tree, I can see why that would happen and I'm not really sure there's a way of fixing it; it sounds as if the type of binary tree you're using simply isn't suited to the task, due to either having too many elements, having the elements too densely packed together or both. Have you tried letting the system put more than one element in each leaf? That would simplify the tree structure and may cut down on unnecessary AABB checks.

Failing that, you might have more luck with a quad tree, like the one described on this page. He's using 1 element per node, but considering the number of test elements you have I'd have 5-10.

Edit: Now that I think about it, with either of these tree structures a leaf should be able to store at least as many elements as a node can store children. i.e. With your binary tree it's better to have a leaf containing two elements than a node containing two leaves, each of which contains one element. The leaf with two elements gets 2 AABB checks (one for each element), where the node with two leaves gets 2-4 (2 to check each leaf and up to 2 to check the elements in the leaves). Similarly a quad tree leaf should be able to store at least 4 elements before splitting.

Gerblyn fucked around with this message at 09:43 on Jun 28, 2011

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

dereekb posted:

Apparently it's called Z-fighting, but I've done what was recommended and no change.
In a case like this (where the surfaces aren't close), it's probably happening because your depth range is too large for the Z-buffer resolution.

Try to keep the far plane at a sane distance and don't use ridiculously low near plane distances. Depth values scale hyperbolically so as your near plane starts approaching zero, the depth range reserved for near values goes through the roof and everything else suffers.

FlyingDodo
Jan 22, 2005
Not Extinct

Gerblyn posted:

I guess what's happening then is that the nodes in the graph are overlapping too much, so when you check an AABB against the tree it ends up checking a few thousand nodes instead of the 50 or so it would in perfect conditions? Looking at the algorithm you describe for building the tree, I can see why that would happen and I'm not really sure there's a way of fixing it; it sounds as if the type of binary tree you're using simply isn't suited to the task, due to either having too many elements, having the elements too densely packed together or both. Have you tried letting the system put more than one element in each leaf? That would simplify the tree structure and may cut down on unnecessary AABB checks.

Failing that, you might have more luck with a quad tree, like the one described on this page. He's using 1 element per node, but considering the number of test elements you have I'd have 5-10.

Edit: Now that I think about it, with either of these tree structures a leaf should be able to store at least as many elements as a node can store children. i.e. With your binary tree it's better to have a leaf containing two elements than a node containing two leaves, each of which contains one element. The leaf with two elements gets 2 AABB checks (one for each element), where the node with two leaves gets 2-4 (2 to check each leaf and up to 2 to check the elements in the leaves). Similarly a quad tree leaf should be able to store at least 4 elements before splitting.

I think I will stick to an AABB tree for now, but I will try different numbers of elements stored in each leaf. You said that you can see why the algorithm I'm using for building tree is a problem, is there a better way of building the tree? Or a better way to choose which child node to send an inserted element down?

Hopefully increasing the number of elements stored in a leaf will help, perhaps have no limit but instead limit the depth of the tree. Only one way to find out.

dereekb
Nov 7, 2010

What do you mean "error"?

OneEightHundred posted:

In a case like this (where the surfaces aren't close), it's probably happening because your depth range is too large for the Z-buffer resolution.

Try to keep the far plane at a sane distance and don't use ridiculously low near plane distances. Depth values scale hyperbolically so as your near plane starts approaching zero, the depth range reserved for near values goes through the roof and everything else suffers.

My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh.

I did play with those settings just to check again though, but even a far plane of ~1000 or so still had the fighting.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

FlyingDodo posted:

I think I will stick to an AABB tree for now, but I will try different numbers of elements stored in each leaf. You said that you can see why the algorithm I'm using for building tree is a problem, is there a better way of building the tree? Or a better way to choose which child node to send an inserted element down?

Hopefully increasing the number of elements stored in a leaf will help, perhaps have no limit but instead limit the depth of the tree. Only one way to find out.

I believe part of the problem comes from the fact that the algorithm is growing the AABB of a node when an element is placed into it, to make sure the element completely fits. This is causing the nodes to overlap with their siblings, which increases the chance that an AABB check have to search down both siblings, rather than just one of them. This is just speculation on my part, but given what you've said so far it's the only thing I can think of that makes sense.

One possible solution is to have the root node encompass the entirely game world. Then, instead of dynamically shaping the child nodes, you just split a parent node in half, guaranteeing that sibling nodes never overlap. If an element intersects both child nodes, you add it to a list of elements in the parent, rather than trying to re-size one of the children so it fits. Essentially, you do what they guys does in the page I linked in my previous post, except you use a binary tree instead of a quad tree. This should lead to a more balanced tree, and should make your check search the tree more efficiently. The downside is that your elements won't be as evenly distributed between leaves, so if you have elements that are very clustered up around each other, it might actually make things worse (though having lots of elements clumped up together is going to gently caress up most spatial partitioning algorithms anyway).

First though, I think limiting the depth and allowing multiple elements per node is definitely a good place to start, it may fix the issue outright.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I recall awhile back asking about collision detection for a character doing something like a melee attack. One suggestion was to generate a bounding sphere in front of the attacking character at a certain point. I'm trying to figure out how to do that right now. I can set things up so that during a certain frame range I have some stuff active, but I can't figure out between Irrlicht and Bullet how to create an invisible volume that can report back to with what it collided.

I assumed Bullet would have some capability for this. The problem is that the volume has effect on the surrounding objects no matter what. So it's knocking stuff around while it's active, and everything tries hard to keep from occupying each other's spaces. However I want this to be a space that could be occupied--that is really the whole goal. Does anybody using Bullet for physics have an idea on how to set it up to do these kinds of tests?

Edit: I guess what I need are Bullet's "ghost objects." The wrapper I'm using doesn't support them so I'm trying to write a wrapper for them.

Rocko Bonaparte fucked around with this message at 15:30 on Jun 29, 2011

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

dereekb posted:

My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh.
In that case you probably had Z test off.

FlyingDodo
Jan 22, 2005
Not Extinct

Gerblyn posted:

I believe part of the problem comes from the fact that the algorithm is growing the AABB of a node when an element is placed into it, to make sure the element completely fits. This is causing the nodes to overlap with their siblings, which increases the chance that an AABB check have to search down both siblings, rather than just one of them. This is just speculation on my part, but given what you've said so far it's the only thing I can think of that makes sense.

One possible solution is to have the root node encompass the entirely game world. Then, instead of dynamically shaping the child nodes, you just split a parent node in half, guaranteeing that sibling nodes never overlap. If an element intersects both child nodes, you add it to a list of elements in the parent, rather than trying to re-size one of the children so it fits. Essentially, you do what they guys does in the page I linked in my previous post, except you use a binary tree instead of a quad tree. This should lead to a more balanced tree, and should make your check search the tree more efficiently. The downside is that your elements won't be as evenly distributed between leaves, so if you have elements that are very clustered up around each other, it might actually make things worse (though having lots of elements clumped up together is going to gently caress up most spatial partitioning algorithms anyway).

First though, I think limiting the depth and allowing multiple elements per node is definitely a good place to start, it may fix the issue outright.


I thought about too many nodes being visited, the 14,000 element test visited ~350 nodes on average. Too many? Maybe it is time to throw out the code I have and re-write it from the start, taking into account thing you've said.

Seabert
Apr 13, 2008

dereekb posted:

My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh.

Not sure on this, but did you add anything involving a spritebatch? When used, it switches renderstates and disables your z-buffer.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

FlyingDodo posted:

I thought about too many nodes being visited, the 14,000 element test visited ~350 nodes on average. Too many? Maybe it is time to throw out the code I have and re-write it from the start, taking into account thing you've said.

It's hard to say really, it does sound like a lot, but you need to take into account the size of the AABB that you're checking with. If you're saying something like:

1) I have a 1000x1000m field
2) I have 14,000 elements in that field, each 1m squared in area
3) I'm searching for all elements in a 100x100 meter box

Then having the system check 350 nodes (assuming that includes leaves, and you have only 1 or 2 elements per leaf) sounds pretty good. If your check box is only 10x10, however, then that sounds like too many.

How long does the check take? Also, I assume when you wrote 800ms earlier, you meant microseconds, not millisends, right?

As a general opinion, assuming you have the patience and time, it's never a bad idea to rewrite an algorithm like this to try out a new approach or to implement ideas you thought of while writing the new one. It's not like you have to throw away the old code if your rewrite sucks, and the chances are your second attempt will be much better than your first (not just because of my advice, more because you have a clearer idea of what you're doing).

Before you get too disheartened with what you have though, these kinds of algorithms are very fiddly, and you may find changing certain parameters, such as max elements per node and maximum tree depth have big effects. Also, 14,000 elements IS a lot, I'm guessing this is a stress test and when the system is in use, you'll usually have far fewer elements? Just because the tree performs badly with 14,000 elements doesn't mean it'll be bad with only 1000.

Gerblyn fucked around with this message at 23:09 on Jun 29, 2011

Paniolo
Oct 9, 2007

Heads will roll.
Out of curiosity, how are you allocating your nodes when you build the tree?

FlyingDodo
Jan 22, 2005
Not Extinct
Just using new. However I don't think this is relevant to the speed of querying the tree as nothing is allocated/deallocated when searching. The only allocation that might happen is a re-sizing of an std::vector which collects the results.

edit: for more information; the test data is ~14,000 brushes from a quake3 level. The tree is created from those then each one is sent through the tree to find any brushes bounding boxes that touch the bounding box of the test brush. All 14,000 brushes are tested in this way. Checking all 14,000 with the tree takes ~300-400 milliseconds. Testing without the tree takes ~700-800 milliseconds. So one query using the tree takes on average ~0.021-0.028 milliseconds per query. Without the tree it is about double the time.

FlyingDodo fucked around with this message at 16:33 on Jun 30, 2011

Paniolo
Oct 9, 2007

Heads will roll.

FlyingDodo posted:

Just using new. However I don't think this is relevant to the speed of querying the tree as nothing is allocated/deallocated when searching. The only allocation that might happen is a re-sizing of an std::vector which collects the results.

It's not allocation overhead I'm thinking about, it's cache thrashing. I'd try allocating the nodes from a pool of contiguous memory and see how that affects performance; it may not end up being a big deal, but it could help a lot. If nothing else you'll save a lot of memory.

Also, if you're using STL containers at any point in the querying, make sure you're either building in release mode or disabling checked iterators because those can add a pretty enormous performance penalty.

Paniolo fucked around with this message at 16:40 on Jun 30, 2011

FlyingDodo
Jan 22, 2005
Not Extinct
It is compiled in release mode and I don't think it has to do with std::vector, if I comment out anything to do with it and just traverse the tree during search without collecting the results it still takes just as long. Point noted about memory allocation, something possible add to do in a re-write. However I'm thinking it's just a bad data structure/algorithm. I supposed I better get to work on something new rather than screwing around with what I have.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

FlyingDodo posted:

It is compiled in release mode and I don't think it has to do with std::vector, if I comment out anything to do with it and just traverse the tree during search without collecting the results it still takes just as long. Point noted about memory allocation, something possible add to do in a re-write. However I'm thinking it's just a bad data structure/algorithm. I supposed I better get to work on something new rather than screwing around with what I have.

Yeah, I think that a binary tree is really not the right kind of algorithm to use in this case. The differing sizes of the brushes, how they're arranged and how densely they're packed, are all absolutely horrible for the algorithm you've chosen. It's almost guaranteed to make a tree with lots of overlapping nodes that will really hurt performance.

You want to use an octree for this (i.e. a quadtree in 3D).

PiCroft
Jun 11, 2010

I'm sorry, did I break all your shit? I didn't know it was yours

Hi guys, first time posting in Cavern of COBOL,

I'm working on shaders for a game, and I need to implement a bump-mapping shader that reads in the texture, a normal map and use the alpha channel of the normal map as a specular map.

So far, it seems to work okayish:




You might notice the specular effect is banded in lines across the surface in an unusual manner. This is deliberate and reflects the specular map we are using at the moment (its a grid to make it more obvious when it works).

However, I am getting unusual weirdness: the light seems to swim across the surface in a bizarre manner, and can be seen clearly when the demo is running: the sphere rotates on the spot and thus, the specular should always stay in the same location as the sphere turns. It doesn't however, and travels in a weird manner that I can't quite describe.

I have the vertex and fragment shaders at hand, if you would be kind enough to examine it and see where I am going wrong. I apologise in advance for poor quality code, I am still coming to grips with shaders.

Vertex:
code:
void main(	in float4 position : POSITION,	
		in float2 texCoords : TEXCOORD0, 		
		in float3 vTangent : TANGENT,			
		in float3 vNormal : NORMAL,			

		out float4 positionOUT : POSITION,		// Send the transformed vertex position on to the fragment shader
		out float2 texCoordsOUT : TEXCOORD0,		// Send the texture map's texcoords to the fragment shader
		out float2 normalCoordsOUT : TEXCOORD1,		// Send the normal map's texcoords to the fragment shader
		out float3 vLightVector : TEXCOORD2, 		// Send the transformed light vector to the fragment shader
		out float3 positionPassed : TEXCOORD3,
		out float3 normal : TEXCOORD4,

		const uniform float4x4 ModelViewProj,	// The concatenated modelview and projection matrix
		const uniform float4 lightPositionOS) 		// The light sphere's position in object space
{
	// Calculate the light vector
	vLightVector = lightPositionOS - position.xyz;

	// Transform the light vector from object space into tangent space
	float3 binormal = cross(vTangent,vNormal);
	float3x3 T = float3x3(vTangent, binormal, vNormal);
	
	//float3x3 TBNMatrix = float3x3(vTangent, vBinormal, vNormal);
	//vLightVector.xyz = mul(TBNMatrix, vLightVector);
	vLightVector.xyz = mul(T, (lightPositionOS.xyz - position.xyz * lightPositionOS.w));
	
	// Transform the current vertex from object space to clip space, since OpenGL isn't doing it for us
	// as long we're using a vertex shader
	positionOUT = mul(ModelViewProj, position);
	
	// Send the texture map coords and normal map coords to the fragment shader
	texCoordsOUT = texCoords;
	normalCoordsOUT = texCoords;
	positionPassed = position;
	normal = vNormal;
}
fragment:

code:
void main(	in float4 colorIN : COLOR0,
		in float2 texCoords : TEXCOORD0,		// The texture map's texcoords
		in float2 normalCoords : TEXCOORD1,		// The normal map's texcoords
		in float3 vLightVector : TEXCOORD2,		// The transformed light vector (in tangent space)
		in float3 position : TEXCOORD3,
		in float3 normal : TEXCOORD4,

		out float4 colorOUT : COLOR0,			// The final color of the current pixel

		uniform sampler2D baseTexture : TEXUNIT0,	// The whole rock texture map
		uniform sampler2D normalTexture : TEXUNIT1,	// The whole normal map
		uniform float3 lightcolor,
		uniform float3 eyePositionOS,
		uniform float3 lightPositionOS)		// The diffuse color of the light source
{
	// We must remember to normalize the light vector as it's linearly interpolated across the surface,
	// which in turn means the length of the vector will change as we interpolate
	vLightVector = normalize(vLightVector);

	// Since the normals in the normal map are in the (color) range [0, 1] we need to uncompress them
	// to "real" normal (vector) directions.
	// Decompress vector ([0, 1] -> [-1, 1])
	float3 vNormal = 2.0f * (tex2D(normalTexture, normalCoords).rgb - 0.5f);
	
	float4 normMap = tex2D(normalTexture, normalCoords);
	
	float shininess = 16.0f;
	
	half3 L = normalize(lightPositionOS - position);	// Vertex to light
	half3 V = normalize(eyePositionOS - position);		// Vertex to eye
	half3 N = normalize(vNormal);						// Normal
	//half3 N = normalize(normal);
	half3 H = normalize(L + V);							// Half angle vector
	 
	float NdotL = dot(N, L);
	float NdotH = dot(N, H);
	 
	 half4 lighting = lit(NdotL, NdotH, shininess);
	 
	 //lighting.y = lighting.y + 0.5;
	 lighting.z = lighting.z * normMap.w;
	 
	// Calculate the diffuse component and store it as the final color in 'colorOUT'
	// The diffuse component is defined as: I = Dl * Dm * clamp(L.N, 0, 1)
	// saturate() works just like clamp() except that it implies a clamping between [0;1] normMap.w * lighting.y
	colorOUT.rgb =lightcolor * (tex2D(baseTexture, texCoords).rgb * saturate(dot(vLightVector, vNormal)) + lighting.z);
	//colorOUT.rgb = lightcolor * (lighting.y * (half3)tex2D(baseTexture, texCoords).rgb + lighting.z); // * saturate(dot(vLightVector, vNormal));
}
If you need me to clarify anything, let me know, I am struggling to understand what the problem is.

PiCroft fucked around with this message at 18:11 on Jun 30, 2011

Vinlaen
Feb 19, 2008

What's the fastest way to prototype some simple 2D games?

I'm using C# as my primary language (it's what we use at work, etc) so I know I could use XNA but even that requires a bit of work to display sprites, menus, etc.

Ideally I'd like something extremely high level (for .NET?) that I can create menus and then move some sprites around, etc. (Maybe my best bet is Windows Forms and GDI?)

Paniolo
Oct 9, 2007

Heads will roll.
Use something like Stencyl, Game Maker, or Unity for prototyping.

Shameproof
Mar 23, 2011

What's the best way to make a birds-eye 2D isometric game, like RollerCoaster Tycoon, SimCity, or Ceasar?

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
I can't speak for SimCity, but I'm pretty sure the best way to write RollerCoaster Tycoon is x86 assembly.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Internet Janitor posted:

I can't speak for SimCity, but I'm pretty sure the best way to write RollerCoaster Tycoon is x86 assembly.
Pfh, then you're only making it for crappy x86 systems. You should use ARM assembly, or 68000.

For an actual answer, most games of that nature were done using sprites that are just drawn in positions so as to look isometric, by positioning them on a hexagonal/triangular grid (moving half a square across and half a square down with each row, rather than one square down as you would for a flat view). You can also move one square up for vertical positioning if your isometric game is having a third dimension.

The advantage of doing it that way is it's pretty easy to code, you can make the graphics with Paint, and everything's on a grid so all collision detection and stuff is a piece of cake.

The disadvantage is that you have to draw many things twice or four times (if a thing can face any direction then drawing twice gives you northwest and southwest, then you can mirror it for northeast and southeast. If the thing can face any direction and isn't symmetrical then you can't mirror it and must draw it four times.)

So the way that sort of thing is frequently done now is to use 3D rendering and just have an isometric view/projection. Advantage, only make things once. Disadvantage, it's harder to make 3D things and you can't make things pixel-perfect. Additional advantage: you can also make things face directions that aren't cardinal directions without making any extra art.

Another way isometric things have been done is using 3D rendering with lots of anti-aliasing and even manual touching up, while making the game, to make the sprites, which you then render the old-school way in-game. You get the "make things once" advantage and the "pixel perfect" advantage, you still lose the "face arbitrary directions" and "make the art easily" abilities.

So the actual answer to the question is "there isn't an inherently best way, what's best depends on your goals and abilities." (And all this is assuming the question was about this low-level stuff rather than "what language/libraries should you use?")

Shameproof
Mar 23, 2011

roomforthetuna posted:

(And all this is assuming the question was about this low-level stuff rather than "what language/libraries should you use?")

Oh... that's actually what I wanted to know. Is FIFE (http://www.fifengine.de/) a good choice??

Shameproof fucked around with this message at 00:27 on Jul 2, 2011

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Shameproof posted:

Which was an incorrect assumption... that's actually what I wanted to know. Is FIFE (http://www.fifengine.de/) a good choice??

I don't think that snidely dismissing the person who actually took the time to try and help you is going to win you many friends here.

Maybe you could explain what exactly you need from an engine, and what kind of experience you have with making games?

Shameproof
Mar 23, 2011

Gerblyn posted:

I don't think that snidely dismissing the person who actually took the time to try and help you is going to win you many friends here.

Maybe you could explain what exactly you need from an engine, and what kind of experience you have with making games?

Sorry, didn't mean to come off that way.

I'd like an engine where I can import my sprites and have them get drawn in the proper order in a 2D plane. Tile-based... I don't have very much experience with games but I know the basics of how they work.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
The FIFE engine looks like a good place to start, it has the features you want and is apparently geared towards making isometric games. It looks like you'd be writing all the game logic in PYTHON, with the engine handling most of the fiddly stuff for you, which is very handy if you don't have much experience.

If you want something even higher level, you could try out things like GameMaker and RPGMaker.

Spatial
Nov 15, 2007

What's the best way to clamp an angle within an arc, snapping to the closest arc edge if out of bounds?

This is the best method I've come up with so far. It works fine but I'm wondering if there's a more elegant or efficient solution. My math skills are subpar at best.

code:
float ddir_clamp ( float angle, float axis, float arc )
{
    // Clamp angle within axis+-(arc/2), snapping to nearest arc edge if outside.
    float arc2,amin,amax,diff;
    
    arc2 = arc / 2.0f;
    amin = fmod( axis - arc2, 360.0f );
    amax = fmod( axis + arc2, 360.0f );
    diff = ddir_diff( angle, axis );

    if (abs( diff ) <= arc2)
    { return angle; }

    if (diff < 0.0f)
    {
         if (ddir_diff( angle, amin ) <= 0.0f)
              { return amin; }
         else { return amax; }
    }
    else 
    {
         if (ddir_diff( angle, amax ) >= 0.0f)
              { return amax; }
         else { return amin; }
    }
}
ddir_diff() computes the difference between angles accounting for wraparound.
code:
float  ddir_diff ( float a, float b )
{
    // Angular difference, -180 to 180 degrees.
    return fmod( fmod( a - b, 360.0f ) + 540.0f, 360.0f ) - 180.0f;
}

Spatial fucked around with this message at 03:48 on Jul 4, 2011

shrughes
Oct 11, 2008

(call/cc call/cc)

Spatial posted:

What's the best way to clamp an angle within an arc, snapping to the closest arc edge if out of bounds?

This looks shorter.
code:
float ddir_clamp(float angle, float axis, float arc) {
    double rel = fmod(360.0 + fmod(angle - axis + 180.0, 360.0), 360) - 180;
    return (rel < -arc ? -arc : rel > arc ? arc : rel) + axis;
}
Edit: But this might be faster:
code:
float ddir_clamp(float angle, float axis, float arc) {
    double x = fmod(angle - axis + 180, 360.0);
    double rel = (x < 0 ? x + 360 : x) - 180;
    return (rel < -arc ? -arc : rel > arc ? arc : rel) + axis;
}
Edit: Uh, what's with your dividing arc by 2 and using arc2? That doesn't meet the spec.

shrughes fucked around with this message at 03:33 on Jul 4, 2011

Spatial
Nov 15, 2007

Thanks for the help, I'll try those out.

quote:

Edit: Uh, what's with your dividing arc by 2 and using arc2? That doesn't meet the spec.
Whoops. I meant to write "+-arc/2" in that comment. The arc is supposed to be centred around the axis angle.


Edit: Gave it a whirl. On average your first function is 1.5x faster than mine, and your second is more than twice as fast. Thanks again. :)

Spatial fucked around with this message at 04:36 on Jul 4, 2011

Adbot
ADBOT LOVES YOU

FlyingDodo
Jan 22, 2005
Not Extinct
I re-wrote my bounding volume hierachy, so it is more like a kd-tree now. There is the ability to put limits on tree depth and the number of elements in a node.

So the algorithm/data structure is now as follow. Each internal node has an axis aligned splitting plane. When something is inserted into the tree if the node is internal and the inserted element spans the splitting plane it stays at that node.

If it's in front, goes to the front child node, if back goes to the back child node. This repeats until it either spans the plane and stays in the internal node or hits a leaf node. If the node is a leaf node the element is inserted into that node.

If the number of elements in a leaf node reach a set limit the node is split by a plane at the centre of the bounding box of that node. The plane is axis aligned, the axis chosen by mod 3 of the depth. Leaf nodes can go over the limit of number of elements if max depth has been reached, and internal nodes don't have a limit because all elements stored in an internal node cannot be split as they span the splitting plane.

Despite this re-write it actually seems to be slower than my previous attempt, even though there can't be any overlap of nodes and there is a limit on depth and allowing for multiple elements per node. It seems like both ways I have tried only reduce the number of bounding box checks by about 60%, still leaving a huge amount.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply