Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


#ActualMigi0027

Posted 24 July 2013 - 10:32 AM

Hi guys.

 

I've been trying to implement tessellation, and got it implemented, thanks to you.

 

My next goal is to implement terrain tessellation with displacement mapping

 

Questions: (Some I have attempted, shown in the shader code below)

  • The vertices generated on the cpu, do they just represent a plane, or a pre generated grid?
  • How do I decide the height of the displacement mapping, just a constant?
  • How are the normals generated?

My attempt: (If you want to see...)

cbuffer ConstantObjectBuffer : register (b0)
{
	matrix worldMatrix;
};

cbuffer ConstantFrameBuffer : register (b1)
{
	matrix viewMatrix;
	matrix projectionMatrix;

	float3 eyepos;
	float cppad;

	float4 lightvec;
	float4 lightcol;

	float FogStart;
	float FogEnd;
	float2 __space;

	float3 FogColor;
	float shadows;

	float SpecularIntensity;
	float3 pad3;
	float4 SpecularColor;
}


//***************************************************//
//                 VERTEX SHADER                     //
//***************************************************//

struct VOut
{
    float4 position : POSITION;
	float2 texcoord : TEXCOORD;
	float access : ACCESS;

	float tessAmount : TSSAM;
	
	float3 NormalW : NORMWORLD;
	float3 normal : NORM;
	float4 depthPosition : TEXTURE0;
};

struct GlobalIn
{
	float4 position : POSITION;
	float4 normal : NORMAL;
	float2 texcoord : TEXCOORD;
};

Texture2D t_map : register(t0);
SamplerState ss;

VOut VShader(GlobalIn input)
{
    VOut output;

    input.position.w = 1.0f;
	output.texcoord = input.texcoord;

	// Calculate the position of the vertex against the world, view, and projection matrices.
    /*output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);*/

	output.position = mul(input.position, viewMatrix);

	// Get Tesselation amount
	output.tessAmount = (1.0f / output.position.z) * 6.0f;

	output.position = input.position;

    output.NormalW = mul(float4(input.normal.xyz,0), mul(worldMatrix, viewMatrix));

	// Store the position value in a second input value for depth value calculations.
	output.depthPosition.xyz = mul(float4(input.position.xyz,1), mul(worldMatrix, viewMatrix)).xyz;

	// Per Vertex lighting
	float4 norm = normalize(input.normal);
	output.access = saturate(dot(norm, lightvec));

	output.normal = input.normal;
	
    return output;
}

//***************************************************//
//                 HULL SHADER                       //
//***************************************************//

struct HOutput
{
    float edges[3] : SV_TessFactor;
    float inside : SV_InsideTessFactor;
};

#define tessellationAmount 12.0f

HOutput ColorPatchConstantFunction(InputPatch<VOut, 3> inputPatch, uint patchId : SV_PrimitiveID)
{    
    HOutput output;

	float tA = inputPatch[0].tessAmount;
	tA = 12.0f;

    // Set the tessellation factors for the three edges of the triangle.
    output.edges[0] = tA;
    output.edges[1] = tA;
    output.edges[2] = tA;

    // Set the tessellation factor for tessallating inside the triangle.
    output.inside = tA;

    return output;
}

[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ColorPatchConstantFunction")]

VOut HShader(InputPatch<VOut, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
{
    VOut output;

    // Set the x for this control point as the output x.
    output.position = patch[pointId].position;

    output.texcoord = patch[pointId].texcoord;
    output.access = patch[pointId].access;
    output.NormalW = patch[pointId].NormalW;
    output.normal = patch[pointId].normal;
    output.depthPosition = patch[pointId].depthPosition;

    return output;
}

//***************************************************//
//                 DOMAIN SHADER                     //
//***************************************************//

struct DOut
{
    float4 position : SV_Position;
	float2 texcoord : TEXCOORD;
	float access : ACCESS;
	
	float3 NormalW : NORMWORLD;
	float4 depthPosition : TEXTURE0;
};

[domain("tri")]

DOut DShader(HOutput input, float3 uvwCoord : SV_DomainLocation, const OutputPatch<VOut, 3> patch)
{
    DOut output;

	float3 vertexPosition;
    float2 texCoords;
    float3 normal;
    float4 worldPosition;

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

    texCoords = uvwCoord.x * patch[0].texcoord + uvwCoord.y * patch[1].texcoord + uvwCoord.z * patch[2].texcoord;

    normal =  uvwCoord.x * float3(0, 1, 0) + uvwCoord.y * float3(0, 1, 0) + uvwCoord.z * float3(0, 1, 0);
    normal = normalize(normal);

    float vHeight = t_map.SampleLevel(ss, texCoords, 0);
    vertexPosition += float3(0, 1, 0) * (vHeight * 2.0f);

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

    output.texcoord = texCoords;

    output.NormalW = mul(normal,(float3x3)worldMatrix);
    output.NormalW = normalize(output.NormalW);

    return output;
}

//***************************************************//
//                 PIXEL SHADER                      //
//***************************************************//

struct POut
{
	float4 Diffuse  : SV_Target0;
	float4 Depth    : SV_Target1;
	float4 Normals  : SV_Target2;
	float4 Lighting : SV_Target3;
};

POut PShader(VOut input)
{
	POut output;

	// Depth
	output.Depth = float4(input.depthPosition.xyz, 1.0f);

	// Normals
	output.Normals = float4(normalize(input.NormalW), 1);

	output.Diffuse = float4(1, 1, 1, 1);
	output.Lighting = float4(lightcol.rgb * input.access, 1.0f);

	output.Lighting = float4(1, 1, 1, 1);

	return output;
}

I've attempted with the pre generated grid, but this came: (The terrain is repeated over and over again, why?)

 

kcxu6f.png

 

Thank you, as always GameDev.


#1Migi0027

Posted 24 July 2013 - 10:30 AM

Hi guys.

 

I've been trying to implement tessellation, and got it implemented, thanks to you.

 

My next goal is to implement terrain tessellation with displacement mapping

 

Questions: (Some I have attempted, shown in the shader code below)

  • The vertices generated on the cpu, do they just represent a plane, or a pre generated grid?
  • How do I decide the height of the displacement mapping, just a constant?
  • How are the normals generated?

My attempt: (If you want to see...)

cbuffer ConstantObjectBuffer : register (b0)
{
	matrix worldMatrix;
};

cbuffer ConstantFrameBuffer : register (b1)
{
	matrix viewMatrix;
	matrix projectionMatrix;

	float3 eyepos;
	float cppad;

	float4 lightvec;
	float4 lightcol;

	float FogStart;
	float FogEnd;
	float2 __space;

	float3 FogColor;
	float shadows;

	float SpecularIntensity;
	float3 pad3;
	float4 SpecularColor;
}


//***************************************************//
//                 VERTEX SHADER                     //
//***************************************************//

struct VOut
{
    float4 position : POSITION;
	float2 texcoord : TEXCOORD;
	float access : ACCESS;

	float tessAmount : TSSAM;
	
	float3 NormalW : NORMWORLD;
	float3 normal : NORM;
	float4 depthPosition : TEXTURE0;
};

struct GlobalIn
{
	float4 position : POSITION;
	float4 normal : NORMAL;
	float2 texcoord : TEXCOORD;
};

Texture2D t_map : register(t0);
SamplerState ss;

VOut VShader(GlobalIn input)
{
    VOut output;

    input.position.w = 1.0f;
	output.texcoord = input.texcoord;

	// Calculate the position of the vertex against the world, view, and projection matrices.
    /*output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);*/

	output.position = mul(input.position, viewMatrix);

	// Get Tesselation amount
	output.tessAmount = (1.0f / output.position.z) * 6.0f;

	output.position = input.position;

    output.NormalW = mul(float4(input.normal.xyz,0), mul(worldMatrix, viewMatrix));

	// Store the position value in a second input value for depth value calculations.
	output.depthPosition.xyz = mul(float4(input.position.xyz,1), mul(worldMatrix, viewMatrix)).xyz;

	// Per Vertex lighting
	float4 norm = normalize(input.normal);
	output.access = saturate(dot(norm, lightvec));

	output.normal = input.normal;
	
    return output;
}

//***************************************************//
//                 HULL SHADER                       //
//***************************************************//

struct HOutput
{
    float edges[3] : SV_TessFactor;
    float inside : SV_InsideTessFactor;
};

#define tessellationAmount 12.0f

HOutput ColorPatchConstantFunction(InputPatch<VOut, 3> inputPatch, uint patchId : SV_PrimitiveID)
{    
    HOutput output;

	float tA = inputPatch[0].tessAmount;
	tA = 12.0f;

    // Set the tessellation factors for the three edges of the triangle.
    output.edges[0] = tA;
    output.edges[1] = tA;
    output.edges[2] = tA;

    // Set the tessellation factor for tessallating inside the triangle.
    output.inside = tA;

    return output;
}

[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ColorPatchConstantFunction")]

VOut HShader(InputPatch<VOut, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
{
    VOut output;

    // Set the x for this control point as the output x.
    output.position = patch[pointId].position;

    output.texcoord = patch[pointId].texcoord;
    output.access = patch[pointId].access;
    output.NormalW = patch[pointId].NormalW;
    output.normal = patch[pointId].normal;
    output.depthPosition = patch[pointId].depthPosition;

    return output;
}

//***************************************************//
//                 DOMAIN SHADER                     //
//***************************************************//

struct DOut
{
    float4 position : SV_Position;
	float2 texcoord : TEXCOORD;
	float access : ACCESS;
	
	float3 NormalW : NORMWORLD;
	float4 depthPosition : TEXTURE0;
};

[domain("tri")]

DOut DShader(HOutput input, float3 uvwCoord : SV_DomainLocation, const OutputPatch<VOut, 3> patch)
{
    DOut output;

	float3 vertexPosition;
    float2 texCoords;
    float3 normal;
    float4 worldPosition;

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

    texCoords = uvwCoord.x * patch[0].texcoord + uvwCoord.y * patch[1].texcoord + uvwCoord.z * patch[2].texcoord;

    normal =  uvwCoord.x * float3(0, 1, 0) + uvwCoord.y * float3(0, 1, 0) + uvwCoord.z * float3(0, 1, 0);
    normal = normalize(normal);

    float vHeight = t_map.SampleLevel(ss, texCoords, 0);
    vertexPosition += float3(0, 1, 0) * (vHeight * 2.0f);

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

    output.texcoord = texCoords;

    output.NormalW = mul(normal,(float3x3)worldMatrix);
    output.NormalW = normalize(output.NormalW);

    return output;
}

//***************************************************//
//                 PIXEL SHADER                      //
//***************************************************//

struct POut
{
	float4 Diffuse  : SV_Target0;
	float4 Depth    : SV_Target1;
	float4 Normals  : SV_Target2;
	float4 Lighting : SV_Target3;
};

POut PShader(VOut input)
{
	POut output;

	// Depth
	output.Depth = float4(input.depthPosition.xyz, 1.0f);

	// Normals
	output.Normals = float4(normalize(input.NormalW), 1);

	output.Diffuse = float4(1, 1, 1, 1);
	output.Lighting = float4(lightcol.rgb * input.access, 1.0f);

	output.Lighting = float4(1, 1, 1, 1);

	return output;
}

Thank you, as always GameDev.


PARTNERS