this is my first post for this forum so I hope that this questions wouldn't be too stupid I have decided that I would like try to do water simulation according to this paper. And because I like some challenge I would like to extend it to flowing river simulation. For 3D rendering I am using DirectX 11.
1) Heightfield question [SOLVED]:
On page 3 you can find some equations for flowfiled texture. Start point is to create heightfield texture based on the terrain mesh of the river. Everywhere I looked I found only tutorials on generating terrain from height maps but not vica versa. My current solution in HLSL shader looks like this (code bellow). I take my Camera class and set position and rotation so I look perpendicular to the terrain I'm rendering. Then I multiply all matrices and set position to depth variable (for precision). In pixel shader I do logarithmic calculation of depth value that ranges from 0.0f (near plane) to 1.0f (far plane) so I have more range for depth values (most of them is between 0.95f and 0.99f). And by some trial-error process I found two values minRange and maxRange where my model is visible. Then I scale values from 0.0 to 1.0 to indicate how much hight is there. When I asked my friend what he thinks about this solution he replied that it's kinda weird and I should reconsider it. So question number one is: Is there any other elegant and intuitive way to create heightfiled map?
SOLUTION: There is much easier way to do this. Just take distance from camera to vertex and send it to pixel shader, then depending on maximum height you set for 1.0f value compute right color value.
float4 position : POSITION;
float4 texCoords : TEXCOORD0;
float3 normal : NORMAL;
float4 position : SV_POSITION;
float distance : TEXCOORD0;
PixelInputType main(VertexInputType input)
//Change the position vector to 4 units for proper matrix calculations
input.position.w = 1.0f;
//Calculate the position
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
//Get distance from camera
output.distance = output.position.z;
output.position = mul(output.position, projectionMatrix);
float4 position : VS_POSITION;
float distance : TEXCOORD0;
float4 main(PixelInputType input) : SV_TARGET
float rangeValue = 1.0f / maximumHeight;
float height = cameraPosition.y - input.distance;
float colorValue = rangeValue * height;
float4 color = float4(colorValue, colorValue, colorValue, 1.0f);
2) Gradient question:
Next step is to compute gradient from heightmap texture. This part is little fuzzy for me. From mathematical description I know that gradient is derivation in horizontal and vertical direction. When I searched on the internet I found 2 possible solutions. One mentioned that gradient equals Sobel edge detection. I don't think this one is right. Other one was mathematical with this equation (found here):
(f(x+h) - f(x-h)) / 2h = f'(x) + O(h[sup]2[/sup])
Question here is:
Is this the right way to calculate gradient? If so am I understanding it right that I take samples that lies left/right for X or up/down for Y part of vector from current sample position and then divide it by 2. Final gradient should be computed as square root from sum of X and Y gradient. Another thing that's bugging me is value representation inside texture. Image channel values are in positive range but when I am going down the values should be negative. How this should be done?
3) River height [SOLVED]:
Most water simulations expects that ocean / pond / etc. have flat surface. So you just need to set some constant for water level to find out if you are above or inside water volume. That doesn't need to be true in river. You can have quickly flowing stream from some hill that ends in little pond and from the edge of the pond is waterfall. If I want to add some rigid objects to flowfield map for splashing effects I first need to know how hight is actual water level at any position. I thought I could render riverbed with heightmap shader and add some constant that would indicate where and how hight water is before adding visible part of rigid objects to calculation. But this would be bad idea if somewhere in the terrain could be found ocal extreme (pond) because here should be flat surface. Any ideas how to achieve this?
SOLUTION: This is no easy task to do. Party my solution was correct. You are adding some constant for initialization over terrain height so you are building water heightmap. To create lakes, waterfalls and etc. you have to edit this heightmap according to preassure between surrounding cells. More on this topic in this paper.
Thank you for your ideas / suggestions / solutions. They will be deeply appreciated.