Bloodpass Warband Map Editor

Users who are viewing this thread

Update - slight learning curve with the new engine, as is to be expected, I'm using but I'm getting over it nicely so far.  I think I promised a time estimate once I felt I had an idea of one, so I'm hoping to have a new version some time this weekend, assuming no surprises and that I don't get too distracted with further research to work on implementation.  Not gonna promise a new version ready for testing just yet though.  :razz:  Still a lot to do!
 
Below: Rendering via a new engine, still Java/OpenGL based, but more modern and popular!
(Functionality and UI still not done in this version, so this is just for show/fun.)
image.jpg


Yeah, I realize rivers look like rubbish (and there are some other issues including lack of shading, mountain snow, etc), but we're still a work in progress here.  Point here is, shaders are finally blending textures, so I'm happy for now.

Still, probably have a ways to go before coming close to the game's look, but it's getting there.  Ironically having the M&B shaders to "help" wasn't really any help--unless I just have no clue about HLSL, M&B just seems to be doing multitexturing completely outside the shader code.  (Maybe a megatexture technique?) 

Anyways, going to back see if I can't get some of the visual quirks ironed out.  Check out that ridiculous framerate - heh.. quite a difference from the old version so far.
 
Niiiiice, that was rather speedy Bloodpass & Congrats on what appears to be a very positive result.
 
It was pretty fast wasn't it?  Still using Java though!  Actually the engine's similar to J3D since it's just an OpenGL wrapper (this is how Java gets around not being able to access hardware directly-just interface with native libs), just much better documented and supported.  I wish I had known about it all along, oh well.
 
Looking good man. The blending river and ocean textures are a result of doing only one pass for all of the textures. You shouldn't take much of a hit for doing multiple passes. The game after all does quite a few passes.

As far as how the game does its blending, I'm still struggling with that myself. You'll probably notice that in the Rodok area of the map, some of the mountain passes do not match the in game view at all. The pass will look like its made out of the mountain material instead of grass. I just can't figure out how to replicate the in game view in my editor :/ Looking at the ps_main_map pixel shader, it appears that what they are doing is almost too simple. Just a single texture lookup and 12 passes for the terrain.
Code:
float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);
That line right there is the only texture lookup being done.

Actually as I type this I'm looking and it appears that the mountains are being rendered on a separate pass as well. that would explain the discrepancies that I'm noticing. You may want to look at ps_map_mountain for an idea on that.
 
Yup, texture bits of the shaders are trivial.  I did notice the mountain shaders (didn't analyze) but figured they'd be doing similar.

I *think* what M&B is doing is a technique called "megatexture" if I had to guess.  Unfortunately I'm not sure how we'd implement that (could be easy, could be a lot more work) and it means the shaders are little help, on texturing.

I'll look at the mountain shaders briefly just to confirm but yea, we're probably on our own.
 
Decided to stop hoarding the latest implementation and put it out for others to test for stability and performance.  Still need to implement any basic features but "the framework" to do so is now there.

This is an entirely new engine (still Java/OpenGL though), so forget any past issues with the former version, most of the code is completely different now and my confidence in the new engine has reached the "no turning back" point.

One thing does have me a little stumped though - mountain ridges.  I feel like they should be a little sharper, but without arbitrarily messing with the geometry of the map, for some reason that just isn't showing up as well as I'd like.

That stupid key repeat delay is gone now, too...yay.
 
Looks good bud. A few shader issues however. For one thing, it looks like you are splitting the river, bridge, and ocean triangles into their own buffer, the bridge tris however should be in the "land" buffer if you will. holding space shows that the bridge texture is technically flowing with the water. Also it appears that you are drawing the ocean textures across every single triangle in the water buffer, and then going back and drawing the river textures only on the river tris. Problem with this is that I know you're aiming for accuracy and this does not to the best of my knowledge occur in game (makes a cool wave effect however that I really like :p). That said, I'm still stumped on how to get the rivers to blend with the ocean at the river deltas. Also I noticed that you are using a mountain snow texture did you give up on trying to apply the texture like they do?
 
Bioxx said:
Looks good bud. A few shader issues however. For one thing, it looks like you are splitting the river, bridge, and ocean triangles into their own buffer, the bridge tris however should be in the "land" buffer if you will. holding space shows that the bridge texture is technically flowing with the water. Also it appears that you are drawing the ocean textures across every single triangle in the water buffer, and then going back and drawing the river textures only on the river tris. Problem with this is that I know you're aiming for accuracy and this does not to the best of my knowledge occur in game (makes a cool wave effect however that I really like :p). That said, I'm still stumped on how to get the rivers to blend with the ocean at the river deltas. Also I noticed that you are using a mountain snow texture did you give up on trying to apply the texture like they do?

That's a good point about the bridge textures, easy enough to fix if I just pick a terrain or texture type for bridge/ford, but I'm not sure what to use.  The game usually has bridges there, but what I'm doing now "looks" more like a ford to me.  I'm not sure what the game does when there isn't a bridge placed.

Yes I am splitting the water into another vbuffer. :smile:
I'm aware of the ocean textures within the rivers, but as you said since it looks better than the game (hehe) I just kinda said whatever and left it in for now.

I didn't give up on duplicating the snow effect (which I guess is in the shaders), just felt that the quick fix was "good enough" for now so I could concentrate on other areas.  I think we're both going to be doing some work on shaders for that and shadows, for some time.  But that's cool, I'd like to learn that stuff in detail and this is a good opportunity.

There's also the beach areas in game, not sure how the game does it but it seems like it may be blending the desert texture with the coastlines.  Once we get some solid editing features working, we should be able to start throwing together entirely different maps (which may or may not render similarly in game), which will be useful for determining how the game reacts to different things.

Getting an accurate look (consistent with all maps and not just the default) is going to be a challenge however we approach it.

For the river deltas maybe you can do something like what I've done?  I'm combining various textures (depending on a weighted terrain type assigned to each vertex, calculated from adjacent face terrain types) based on a varying (interpolated) alpha weight.  But I see you're blending land textures fine, is there some reason you can't use the same technique with river/ocean?  Is it because you're using separate buffers/meshes for river and ocean tris?  I'm using the same "mesh/geometry" (in my engine's language) for all water with faces sharing vertices (thus the free alpha blending), tex animation is done in the shaders. (Which you're free to look at, excuse the hacky-ness.  :razz: )
 
Actually my implementation is nearly identical to yours. My water mesh exists in a separate vbuffer from the land mesh. In fact this is my water pixel shader here:
Code:
MBPSOutput MBTexturedBlendedPS(MBPSInput PSIn)
{
    MBPSOutput Output = (MBPSOutput)0;

    float lightingFactor = 1;
    if (xEnableLighting)
        lightingFactor = saturate(saturate(dot(PSIn.Normal, PSIn.LightDirection)) + xAmbient);
        
    float4 farColor = (0,0,0,0);

	if(PSIn.TextureWeights0.x > 0)
	{
		PSIn.TextureCoords.y += xOffset0; 
		farColor = tex2D(TextureSampler0, PSIn.TextureCoords / xScale0); //Ocean
	}
	else if(PSIn.TextureWeights2.x > 0)
	{
		PSIn.TextureCoords.y += xOffset1; 
		farColor = tex2D(TextureSampler8, PSIn.TextureCoords / xScale1); //River
	}

	Output.Color = farColor * lightingFactor;

    return Output;
}

PSIn.TextureWeights0.x is the weight of the ocean texture and PSIn.TextureWeights2.x is the river texture. The problem with my implementation is that the triangles must be either river OR ocean but NOT both. I'm sure its something stupid that I'm overlooking but alas I just don't see it. One of these days I'll actually take a really close look at the MB shader file, as it is I'm just burnt out of late.
 
I'm assuming a few things here, but what if TextureWeights0.x and TextureWeights2.x are both > 0?  If your ocean/river faces share vertices, the weights should be interpolated between them. 

Assuming that's a possible condition (I think it should be), you could use lerp() http://msdn.microsoft.com/en-us/library/bb509618(v=vs.85).aspx to combine the two according to their relative weights in your pixel shader right?  This is basically what I'm doing using glsl's mix() function (same as hlsl lerp() I think).

float4 farColor = (0, 0, 0, 0);

float4 oceanColor = tex2D(TextureSampler0, PSIn.TextureCoords / xScale0); //Ocean
farColor = lerp (farColor, oceanColor, PSInTextureWeights0.x);
float4 riverColor = tex2D(TextureSampler8, PSIn.TextureCoords / xScale1); //River
farColor = lerp (farColor, riverColor, PSInTextureWeights2.x);

Output.Color = farColor * lightingFactor;
return Output;

Actually with that would you even need the if/else bits?  Since the tex weights for the ocean/river should be == 0, lerp() shouldn't have any effect at all if it behaves the same as mix().
 
oh yes trust me, I've tried to lerp it but that introduces a whole host of issues for me, such as where the water meets the land verts. For instance in the case of where the water and land verts meet, I get the black water issue along the coast because my program assigns a weight of 0.5 for the water and 0.5 for the snow lets say. Because of this, you get a black effect along the coast. I've solved this on the water side of the seam, but not on the land side yet. Basically I have one Vertex Buffer and 2 Index Buffers (this changes to 16 Index Buffers for simple mode non blending).

I actually misspoke earlier as I keep my terrain in a single vbuffer. I'm sure if I could get around that, things may work better in some ways. However there would be a performance drop due to how terrain painting works. Every time you release the lmb while painting, the program must reconstruct every single index buffer and vbuffer as well, and that would add more overhead if I were to implement that. The other issue I have is that its a hell of a lot easier to modify terrain that exists in a single vbuffer. For instance how do I move a vertex along a coastline if there are technically 2 vertices there? One for the ocean mesh and one for the land mesh.

Edit: After all that, i got the water/ocean blending using lerp haha. Something I overlooked and voila. Also I have made some headway with the snowcapped mountains, but the spotted snow effect is still eluding me and the mb.fx file only mentions snow in one place, and that area is commented out, So I'm not sure where to look for that.
 
This is good!
Yeah I was going to say (maybe this wasn't the issue), when I'm rendering a water (or land) mesh and there are texture alphas of the other mesh's terrain type, I drop the "wrong" terrain weights and rescale all the weights until their total == 1 (just the same as normalizing vertex coords only with more components).  So even vertices on the edges of the meshes are fully shaded.

Yep I'm not looking forward to complex land/water edits but I have a few ideas and I still think it's do-able.  First try is going to be running off the map 'metadata' I'm storing which basically is a copy of the "real" map data, referencing the rendered map data (2 meshes) via face and vertex indices.  Seems to work so far, and doing similar worked in the version with the older engine, so we'll see.  I think one good thing about my (seemingly more complex?) approach is that I think I'm really only doing one pass (not counting shadows which I'm guessing they do another), so performance is pretty good.  If I don't lock down a max FPS, it claims to be getting 200-300 FPS with shadows.  Once I redo shadows using a more "M&B" type method I expect that "true" FPS to go a little higher.

Yeah, if you're able to figure out how to do this snow (or shadows/shading accurately), I'd be interested. :razz:
 
With the snow , what I'm attempting to make it right is to use the mountain texture and turn it into a greyscale image, then if the texel is > 0.8 in a 0 to 1 clamped range, I draw the snow texture on the mountain, may actually work, I need to tweak and build into the shader, we'll see. As far as the edits go, I'm also referencing the metadata and manipulating it in my technique, so that's probably our best bet. I just need to figure out how to do vertex picking, as it is, I've only managed Triangle picking :/
 
That sounds pretty similar to what I'm doing - all I did for the "extra" snow texture was copy the mountain texture and make it brighter, increase gamma (I forget exactly), and then that gets blended in based on the z (altitude) value which controls the blending alpha.

The map shaders and mountain shaders are so similar, it's probably just a matter of comparing the two and decoding what the mountain-specific shaders are doing differently.
Ex in the vertex shaders, the only differences are these two extra lines in the mountain vs:

float3 P = mul(matWorldView, vPosition); //position in view space
Out.Tex0.z = /*saturate*/(0.7f * (vWorldPos.z - 1.5f));  //This looks an awful lot like it's snow related, factoring the z position like that

The "pixel" shader (OpenGL calls it fragment shader) is slightly more different, but not much:

Mountain:
tex_col.rgb += saturate(In.Tex0.z * (tex_col.a) - 1.5f);
tex_col.a = 1.0f;

if ((PcfMode != PCF_NONE))
{
float sun_amount = GetSunAmount(PcfMode, In.ShadowTexCoord, In.ShadowTexelPos);
// sun_amount *= sun_amount;
Output.RGBColor =  saturate(tex_col) * ((In.Color + In.SunLight * sun_amount));
}
else
{
Output.RGBColor = saturate(tex_col) * (In.Color + In.SunLight);
}

{
float fresnel = 1-(saturate(dot( In.ViewDir, In.WorldNormal)));
// fresnel *= fresnel;
Output.RGBColor.rgb *= max(0.6,fresnel+0.1);
}

Regular shader:
float sun_amount = 1;
if ((PcfMode != PCF_NONE))
{
sun_amount = GetSunAmount(PcfMode, In.ShadowTexCoord, In.ShadowTexelPos);
}
Output.RGBColor =  tex_col * ((In.Color + In.SunLight * sun_amount));


//add fresnel term
{
float fresnel = 1-(saturate(dot( normalize(In.ViewDir), normalize(In.WorldNormal))));
fresnel *= fresnel;
Output.RGBColor.rgb *= max(0.6,fresnel+0.1);
}

And the lines before/after are the same!  But I think the mountain "bump shaders" are a big factor (haven't looked too much at those yet).

It's funny how different 3d engines can be- in most of the ones I've used triangle picking is the tougher part, and nearest vertex is what you typically get without much work.
 
Interesting find, however that is not the z position that it is looking at. You can't read the position values within the pixel shader (I've tried it throws an error). What that is doing, is reading a texture weight value that is stored in a float4. Weirdly enough, in hlsl you can read the values of a float4 as either rgba or xyzw. So In.Tex0.z is more likely how much to possibly blend in the snow texture if that is in fact what its doing at that point. Perhaps the vertex shader will shed more like on how In.Tex0.z is getting its value.

As far as the vertex picking goes, I'm sure its just my noobness really and having never seen a tutorial on the subject :p

Edit: nvm the above I completely missed the part where you went into the vertex shader haha
 
I've made some more headway and yet I'm thinking that I'll need to tear apart the way I'm doing things and figure out how to break my rendering up into 14 passes and maintain the blending (that's the hard part) :/ Anyways, I was taking the snippets you pointed out and am trying to place them into my editor and I've gotten this so far:
http://s80.photobucket.com/albums/j200/Deadrik/?action=view&current=mbxnasnowcap.jpg
You'll have to slide the image over, I didn't feel like cutting out the left monitor in a photo editor. Anyways you'll notice that the areas that aren't black, are only the areas where the snow caps appear in game. So that is most certainly related to the snow. I just can't seem to figure out how to get that snow to draw yet :/ And not only that but my terrain won't like it due to the 1 pass with 12 blends that I'm using now.
Anyways just thought you'd wanna know that we're barking up the right tree here.
 
mb122.jpg


Just a random terrain painting experiment.  Took some tweaking (apparently the mountain texture is not weighted very strong at all), but with the exception of shadows I guess it's looking pretty close at this point--check the mountain texture repeat rate, blending w/plains, etc.  (Above is just a flat area I painted with the mountain terrain type... the Swadians were pretty pissed off.)

Anyway, I'm still trying to decide if I should continue with terrain editing and painting, or leave that to Bioxx.  If I change direction, it would let me look into settlement editing features (move, delete villages, rename settlements, change ownership, etc whatever) or something else instead...
 
Back
Top Bottom