Jump to content
  • Advertisement
Sign in to follow this  
terryeverlast

Distance in HLSL problem

This topic is 892 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

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

6ycbqb.png

 

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
Share on other sites

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

 

Here is my shader code.

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;

	AddressU = WRAP;
	AddressV = WRAP;
};

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  )
	{  
		// Start with a sum of zero. 
		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;
		}

		// Modulate with late add.
		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 this post


Link to post
Share on other sites

First the sphere subdivided twice

55h6hj.png

 

When the distance starts right at 10

 

kb4m77.png

 

then it turns into the sphere divided only once

29gmqmr.png

 

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

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!