Jump to content
  • Advertisement
Sign in to follow this  
Toastmastern

Set vertex position in Domain Shader with Height Map texture

This topic is 737 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

Since I introduced Tessellation in my sphere game I want to move my height map calculation into the Domain shader to handle all the vertices
and not just the ones I start out with.

Here is my HullOutputType that is sent to the Domain Shader:
struct HullOutputType
{
	float3 position : POSITION;
	float4 color : COLOR;
	float3 sphereNormal : NORMAL;
	float2 heightMapCoord : TEXCOORD0;
};
as you can see I send the sphere normal(the vector in which direction the height is going to be applied) I also send the coordinates which is calculated
in the main code
 
mPlanetMesh.vertices[i].heightMapCoord.x = ((longitude + 180) * (8192 / 360) / 8192);
mPlanetMesh.vertices[i].heightMapCoord.y = ((latitude + 90) * (4096 / 180) / 4096);
The calculation could be made much easier I can see that but for now this will do. I take the longitude and pick a pixel, this pixel is then normalized to get a value
between 0 and 1(The texture is 8192x4096).

I have a .tga file that is inserted with some code:
deviceContext->DSSetShaderResources(0, 1, &texture);
deviceContext->DSSetSamplers(0, 1, &mSampleState);
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

result = device->CreateSamplerState(&samplerDesc, &mSampleState);
if (FAILED(result))
{
	return false;
}
Here is main Domain Shader code:
float3 vertexPosition;
float2 patchHeightMapCoord;
float4 heightMapColor;
PixelInputType output;

patchHeightMapCoord = patch[0].heightMapCoord * uvwCoord.x + patch[1].heightMapCoord * uvwCoord.y + patch[2].heightMapCoord * uvwCoord.z;

heightMapColor = heightMapTexture.SampleLevel(sampleType, patchHeightMapCoord, 0);

vertexPosition = uvwCoord.x * patch[0].position + uvwCoord.y * patch[1].position + uvwCoord.z * patch[2].position;

vertexPosition.x = vertexPosition.x + ((patch[0].sphereNormal.x * (heightMapColor.x * (29429.0f / 255.0f))) - 8200);
vertexPosition.y = vertexPosition.y + ((patch[0].sphereNormal.y * (heightMapColor.x * (29429.0f / 255.0f))) - 8200);
vertexPosition.z = vertexPosition.z + ((patch[0].sphereNormal.z * (heightMapColor.x * (29429.0f / 255.0f))) - 8200);

output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

output.color = patch[0].color;

return output;
(29429.0f / 255.0f))) - 8200 in this part 29429 is the max height and -8200 is the offset since the lowest point is -8200 below see level.

What happens is that this changes nothing, I get a perfect round sphere but no height differences. I have a hard time seeing if any part of the code is wrong since
I don't really know how to debug a HLSL file.

Maybe this part should be done in the Pixel Shader and not in the Domain shader?

Thanks in advance
Toastmastern Edited by Toastmastern

Share this post


Link to post
Share on other sites
Advertisement

You definitely want to do this in the domain shader, not the pixel shader. Have you tried using a debugging tool like RenderDoc to make sure that you've correctly bound the height map texture to the domain shader stage? RenderDoc also supports shader debugging (although not for tessellation shaders unfortunately), which you may find useful.

Edited by MJP

Share this post


Link to post
Share on other sites

You definitely want to do this in the domain shader, not the pixel shader. Have you tried using a debugging tool like RenderDoc to make sure that you've correctly bound the height map texture to the domain shader stage? RenderDoc also supports shader debugging (although not for tessellation shaders unfortunately), which you may find useful.


Thanks for the idea, this is what I came up with after working with RenderDoc for a while, might be to tired for this now but it looks like the texture is inside the domain shader
 

http://imgur.com/BK7wamY

 

http://imgur.com/VtZHRNx

 

But when comparing the font texture the height map texture seems to be unbound for some reason. Will have to google that. 

 

Thanks again MJP now I have something to work on tomorrow :)

 

Edit:

Here is the latest image when the font/text is not rendered. looks okey to me, is there a way to  check the values inside the shader? To see what I get out for values in the different calculations?

http://imgur.com/yq8b6rI

 

//Toastmastern

Edited by Toastmastern

Share this post


Link to post
Share on other sites

Ah well I guess the unbound Domain and Hull shader is because when I render the text I set them to null. The texture seems to be in the correct shader atleast

Share this post


Link to post
Share on other sites

After a good night of sleep I'm going at it again.

 

I can confirm that I get correct colors from the texture. I took the output from the SampleLevel function and used that color to render the sphere. That is one point to take of the list of possible errors then.

 

//Toastmastern

Share this post


Link to post
Share on other sites
After even more debugging this is my current status, first off the code that has been reworked somef or debugging purpose:

float3 vertexPosition;
float3 normal;
float2 heightMapCoord;
PixelInputType output;
float4 heightMapColor;
float3 height;

heightMapCoord = uvwCoord.x * patch[0].heightMapCoord + uvwCoord.y * patch[1].heightMapCoord + uvwCoord.z * patch[2].heightMapCoord;
vertexPosition = uvwCoord.x * patch[0].position + uvwCoord.y * patch[1].position + uvwCoord.z * patch[2].position;
//normal = uvwCoord.x * patch[0].sphereNormal + uvwCoord.y * patch[1].sphereNormal + uvwCoord.z * patch[2].sphereNormal;

heightMapColor = heightMapTexture.SampleLevel(sampleType, heightMapCoord, 0);

height.x = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;
height.y = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;
height.z = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;

vertexPosition.x = vertexPosition.x + height.x; //(patch[0].sphereNormal.x * height.x);
vertexPosition.y = vertexPosition.y + height.x; //(patch[0].sphereNormal.y * height.y);
vertexPosition.z = vertexPosition.z + height.x; //(patch[0].sphereNormal.z * height.z);

output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

output.color = heightMapColor;//patch[0].color;

return output;
height.x = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;
height.y = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;
height.z = (heightMapColor.x * (29429.0f / 255.0f));// - 8200.0f;

If I add the -8200 that is not active at the moment the whole sphere gets -8200 * 2 pixels smaller. I can see that with my altitude that the "ground"
changes with that amount. This means that this part: (heightMapColor.x * (29429.0f / 255.0f))
most equal to 0. We know for a fact that (29429.0f / 255.0f) is not 0(it's actually ~115.4) which in means that heightMapColor.x most be 0 for the height.x to become
-8200. But I also know that this is not the case since I get the color value which I add instead of just pure white color. Am I picking the color in the wrong way? Is there
a heightMapColor.rgb or something like that?

Right now I'm at a dead end. I feel that my code is telling me different things.

Appreciate any help I can get

//Toastmastern

Share this post


Link to post
Share on other sites
It is done :D

It turned out that HLSL works with color values between 0.0f - 1.0f and not 0-255 as I thought. The final code:

float3 vertexPosition;
float2 heightMapCoord;
PixelInputType output;
float4 heightMapColor;

heightMapCoord = uvwCoord.x * patch[0].heightMapCoord + uvwCoord.y * patch[1].heightMapCoord + uvwCoord.z * patch[2].heightMapCoord;
vertexPosition = uvwCoord.x * patch[0].position + uvwCoord.y * patch[1].position + uvwCoord.z * patch[2].position;

heightMapColor = heightMapTexture.SampleLevel(sampleType, heightMapCoord, 0);

vertexPosition.x = vertexPosition.x + (patch[0].sphereNormal.x * ((heightMapColor.x * 29429.0f) - 8200.0f));
vertexPosition.y = vertexPosition.y + (patch[0].sphereNormal.y * ((heightMapColor.x * 29429.0f) - 8200.0f));
vertexPosition.z = vertexPosition.z + (patch[0].sphereNormal.z * ((heightMapColor.x * 29429.0f) - 8200.0f));

output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

output.color = heightMapColor;

return output;
//Toastmastern

Share this post


Link to post
Share on other sites

How the GPU interprets the texture data depends on the DXGI format used for the shader resource view. Specifically, the suffix at the end of the format (UNORM, FLOAT, etc.). You can see a full list and a description for each towards the end of this page (scroll down to "Format Modifiers"). In your case you were likely creating your texture with a UNORM format, which means that the GPU will interpret the 0-255 integer data as a 0.0-1.0 floating point value. 

Share this post


Link to post
Share on other sites

How the GPU interprets the texture data depends on the DXGI format used for the shader resource view. Specifically, the suffix at the end of the format (UNORM, FLOAT, etc.). You can see a full list and a description for each towards the end of this page (scroll down to "Format Modifiers"). In your case you were likely creating your texture with a UNORM format, which means that the GPU will interpret the 0-255 integer data as a 0.0-1.0 floating point value. 

 

Thanks for the explanation :)

 

//Toastmastern

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!