Public Group

# Distance in HLSL problem

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

## Recommended Posts

I subdivided some spheres. With distance they change. In between the changes, i see glitchs and holes in the sphere like,

Here is my distance function

float distance(VertexOut gin[1])
{
GeoOut pin;

float4x4 gWorlds;
?	?//identity matrix
gWorlds[0][0] = 1;gWorlds[0][1] = 0;gWorlds[0][2] = 0;gWorlds[0][3] = 0;gWorlds[1][0] = 0;gWorlds[1][1]= 1;gWorlds[1][2] = 0;gWorlds[1][3] = 0;
gWorlds[2][0] = 0;gWorlds[2][1] = 0;gWorlds[2][2] = 1;gWorlds[2][3] = 0;gWorlds[3][0] = 0;gWorlds[3][1] = 0;gWorlds[3][2] = 0;gWorlds[3][3] = 0;

// Transform to World Space
pin.PosW = mul(float4(gin[0].PosL, 1.0f),  gWorlds).xyz;

// The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW;
// Cache the distance to the eye from this surface point.
float distToEye = length(toEye);

return distToEye;
}


And

[maxvertexcount(50)]
void GS(triangle VertexOut gin[3], inout TriangleStream<GeoOut> stream)
{

if(distance(gin[0]) < 10.0f)
{
VertexOut v[15];
Subdivide2(gin, v);
OutputSubdivision2(v,stream);

}
else if(distance(gin[0]) >= 10.0f)
{
VertexOut v[6];
Subdivide(gin, v);
OutputSubdivision(v,stream);

}
}


##### Share on other sites
I bet the problem is that different triangles will have different distances, so they may not fit right. Why don't you try to make a single distance parameter per mesh? Wouldn't that make more sense?

PS: Also, use tessellation. Geometry shaders aren't as efficient.

##### Share on other sites

Ive been trying all sorts of stuff for 2 days and i still cant figure this out. Need some help.

cbuffer cbPerFrame
{
DirectionalLight gDirLights[3];
float3 gEyePosW;

float  gFogStart;
float  gFogRange;
float4 gFogColor;
};

cbuffer cbPerObject
{

float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
float4x4 gTexTransform;

Material gMaterial;
};

struct VertexIn
{
float3 PosL		  : POSITION;
float3 NormalL	  : NORMAL;
float2 Tex		  : TEXCOORD;
};

struct VertexOut
{
float3 PosL		: POSITION;
float3 NormalL	: NORMAL;
float2 Tex		: TEXCOORD;
};

struct GeoOut
{
float4 PosH		: SV_POSITION;
float3 PosW		: POSITION;
float3 NormalW	: NORMAL;

};

SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4;

};

Texture2D gDiffuseMap;

VertexOut VS(VertexIn vin)
{
VertexOut vout;

// Transform to world space space.
vout.PosL    = mul(float4(vin.PosL, 1.0f), gWorldInvTranspose).xyz;
vout.NormalL = mul(vin.NormalL, (float3x3)gWorldInvTranspose);

return vout;
}
float distance(VertexOut gin)
{
GeoOut pin;

float4x4 gWorlds;
gWorlds[0][0] = 1;gWorlds[0][1] = 0;gWorlds[0][2] = 0;gWorlds[0][3] = 0;gWorlds[1][0] = 0;gWorlds[1][1]= 1;gWorlds[1][2] = 0;gWorlds[1][3] = 0;
gWorlds[2][0] = 0;gWorlds[2][1] = 0;gWorlds[2][2] = 1;gWorlds[2][3] = 0;gWorlds[3][0] = 0;gWorlds[3][1] = 0;gWorlds[3][2] = 0;gWorlds[3][3] = 0;

// Transform to World Space
pin.PosW = mul(float4(gin.PosL, 1.0f),  gWorlds).xyz;

// The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW;
// Cache the distance to the eye from this surface point.
float distToEye = length(toEye);

return distToEye;
}

void Subdivide(VertexOut inVerts[3], out VertexOut outVerts[6])
{
//			1
//			*
//		   / \
//		  /   \
//	   m0*-----*m1
//	    / \	  /	\
//     /   \ /   \
//    *-----*-----*
//   0     m2     2

VertexOut m[3];

// compute edge midpoints
m[0].PosL = 0.5f * (inVerts[0].PosL + inVerts[1].PosL);
m[1].PosL = 0.5f * (inVerts[1].PosL + inVerts[2].PosL);
m[2].PosL = 0.5f * (inVerts[2].PosL + inVerts[0].PosL);
m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL);

// derive normals
m[0].NormalL = m[0].PosL;
m[1].NormalL = m[1].PosL;
m[2].NormalL = m[2].PosL;

// interpolate texture coordinates

outVerts[0] = inVerts[0];
outVerts[1] = m[0];
outVerts[2] = m[2];
outVerts[3] = m[1];
outVerts[4] = inVerts[2];
outVerts[5] = inVerts[1];
}

void OutputSubdivision(VertexOut v[6], inout TriangleStream<GeoOut> stream)
{
GeoOut gout[6];

[unroll]
for(int i = 0; i < 6; ++i)
{
// Transform to World Space
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose);

// Transform to homogeneous clip space
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj);

}

//			1
//			*
//		   / \
//		  /   \
//	   m0*-----*m1
//	    / \	  /	\
//     /   \ /   \
//    *-----*-----*
//   0     m2     2

// We can draw the subdivision in two strips:
// strip 1: bottom three triangles
// strip 2: top triangle

[unroll]
for(int j = 0; j < 5; ++j)
{
stream.Append(gout[j]);
}
stream.RestartStrip();

stream.Append(gout[1]);
stream.Append(gout[5]);
stream.Append(gout[3]);

}

void Subdivide2(VertexIn inVerts[3], out VertexOut outVerts[15])
{
//			1
//			*
//		   / \
//		  /   \
//	   m0*-----*m1
//	    / \	  /	\
//     /   \ /   \
//    *-----*-----*
//   0     m2     2

VertexOut m[3];
VertexOut n[15];

// compute edge midpoints
m[0].PosL = 0.5f * (inVerts[0].PosL + inVerts[1].PosL);
m[1].PosL = 0.5f * (inVerts[1].PosL + inVerts[2].PosL);
m[2].PosL = 0.5f * (inVerts[2].PosL + inVerts[0].PosL);
n[0].PosL = 0.5f * (inVerts[0].PosL + m[0].PosL);
n[1].PosL = 0.5f * (inVerts[0].PosL + m[2].PosL);
n[2].PosL = 0.5f * (m[0].PosL + m[2].PosL);
n[3].PosL = m[2].PosL;
n[4].PosL = 0.5f * (m[2].PosL + m[1].PosL);
n[5].PosL = 0.5f * (inVerts[2].PosL + m[2].PosL);
n[6].PosL = 0.5f * (inVerts[2].PosL + m[1].PosL);
n[7].PosL = 0.5f * (m[0].PosL + m[1].PosL);
n[8].PosL = 0.5f * (m[0].PosL + inVerts[1].PosL);
n[9].PosL = 0.5f * (m[1].PosL + inVerts[1].PosL);

n[0].PosL = normalize(n[0].PosL);
n[1].PosL = normalize(n[1].PosL);
n[2].PosL = normalize(n[2].PosL);
n[3].PosL = normalize(n[3].PosL);
n[4].PosL = normalize(n[4].PosL);
n[5].PosL = normalize(n[5].PosL);
n[6].PosL = normalize(n[6].PosL);
n[7].PosL = normalize(n[7].PosL);
n[8].PosL = normalize(n[8].PosL);
n[9].PosL = normalize(n[9].PosL);

m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL);

// derive normals
m[0].NormalL = m[0].PosL;
m[1].NormalL = m[1].PosL;
m[2].NormalL = m[2].PosL;
n[0].NormalL = n[0].PosL;
n[1].NormalL = n[1].PosL;
n[2].NormalL = n[2].PosL;
n[3].NormalL = n[3].PosL;
n[4].NormalL = n[4].PosL;
n[5].NormalL = n[5].PosL;
n[6].NormalL = n[6].PosL;
n[7].NormalL = n[7].PosL;
n[8].NormalL = n[8].PosL;
n[9].NormalL = n[9].PosL;

outVerts[0] = inVerts[0];
outVerts[1] = n[0];
outVerts[2] = n[1];
outVerts[3] = n[2];
outVerts[4] = n[3];
outVerts[5] = n[4];
outVerts[6] = n[5];
outVerts[7] = n[6];
outVerts[8] = inVerts[2];
outVerts[9] = m[0];
outVerts[10] = n[7];
outVerts[11] = m[1];
outVerts[12] = n[8];
outVerts[13] = n[9];
outVerts[14] = inVerts[1];

}

void OutputSubdivision2(VertexOut v[15], inout TriangleStream<GeoOut> stream)
{
GeoOut gout[15];

[unroll]
for(int i = 0; i < 15; ++i)
{
// Transform to World Space
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose);

// Transform to homogeneous clip space
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj);

}

//			1
//			*
//		   / \
//		  /   \
//	   m0*-----*m1
//	    / \	  /	\
//     /   \ /   \
//    *-----*-----*
//   0     m2     2

// We can draw the subdivision in two strips:
// strip 1: bottom three triangles
// strip 2: top triangle

[unroll]
for(int j = 0; j < 9; j++)
{
stream.Append(gout[j]);
}
stream.RestartStrip();

stream.Append(gout[1]);
stream.Append(gout[9]);
stream.Append(gout[3]);
stream.Append(gout[10]);
stream.Append(gout[5]);
stream.Append(gout[11]);
stream.Append(gout[7]);

stream.RestartStrip();

stream.Append(gout[9]);
stream.Append(gout[12]);
stream.Append(gout[10]);
stream.Append(gout[13]);
stream.Append(gout[11]);
stream.RestartStrip();

stream.Append(gout[12]);
stream.Append(gout[14]);
stream.Append(gout[13]);

}

[maxvertexcount(50)]
void GS(triangle VertexOut gin[3], inout TriangleStream<GeoOut> stream)
{

if(distance(gin[0]) < 10.0f)
{
VertexOut v[15];
Subdivide2(gin, v);
OutputSubdivision2(v,stream);

}
else if(distance(gin[0]) >= 10.0f && distance(gin[1]) >= 10.0f && distance(gin[2]) >= 10.0f)
{
VertexOut v[6];
Subdivide(gin, v);
OutputSubdivision(v,stream);

}
}

float4 PS(GeoOut pin, uniform int gLightCount, uniform bool gUseTexure, uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{

// Interpolating normal can unnormalize it, so normalize it.
pin.NormalW = normalize(pin.NormalW);

// The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW;

// Cache the distance to the eye from this surface point.

float distToEye = length(toEye);

// Normalize.
toEye /= distToEye;

// Default to multiplicative identity.
float4 texColor = float4(1, 1, 1, 1);

//
// Lighting.
//

float4 litColor = texColor;
if( gLightCount > 0  )
{
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec    = float4(0.0f, 0.0f, 0.0f, 0.0f);

// Sum the light contribution from each light source.
[unroll]
for(int i = 0; i < gLightCount; ++i)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLights[i], pin.NormalW, toEye, A, D, S);

ambient += A;
diffuse += D;
spec    += S;
}

litColor = texColor * (ambient + diffuse) + spec;
}
//	float4 litColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
//	litColor += float4(0.1f,0.05f,0.05f,0.1f);

//
// Fogging
//

if( gFogEnabled )
{
float fogLerp = saturate( (distToEye - gFogStart) / gFogRange );

// Blend the fog color and the lit color.
litColor = lerp(litColor, gFogColor, fogLerp);
}

// Common to take alpha from diffuse material and texture.
litColor.a *= texColor.a;

return litColor;

}



##### Share on other sites

First the sphere subdivided twice

When the distance starts right at 10

then it turns into the sphere divided only once

To LHLaurini and others, how do I make a distance for the whole mesh in the geometry shader if it getting fed only 3 vertices at a time?

Edited by terryeverlast

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 11
• 13
• 9
• 9
• ### Forum Statistics

• Total Topics
634081
• Total Posts
3015386
×