Jump to content
  • Advertisement
Sign in to follow this  
nickyc95

DX11 DirectX11 Shader issue (DX11, HLSL, C++)

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

RESOLVED: Constant buffers were set for VS and not for PS

 

 

 

I am currently having issues with HLSL shaders. I am trying to implement point lights but I am getting unusual data when debugging the shader in Visual Studio.

I have read on several sites that say that the data stored in CBuffers should be aligned to 4 bytes, thus I added padding where it was needed (is this correct?).

 

When I set the data in c++, some of it comes through alright but other data is not. For example the color comes through alright but the range is being displayed as NaN or just zeros in the VS graphics debugger.

 

Is there something wrong with the code below? (All structs are the same as those in c++ structs)

Please ask if there is anything else you would like to see code wise. Thanks!

 

All the code is stored in a file called buffers.hlsl which is included by the separate shaders i.e. poingLight.vs/.ps include it and make a call to calcPointLight passing in there normal calculations etc... 

 

Lighting Shader:

//Structs

struct BaseLight
{
	float4 color;
	float intensity;

	float3 padding3; //TEST
};

struct DirectionalLight
{
	BaseLight base;
	float3 direction;
};


struct Attenuation
{
	float constantAtten;
	float linearAtten;
	float exponentAtten;

	float padding;
};

struct PointLight
{
	BaseLight base;
	float3 atten;
	float3 pos;
	float range;
};

struct SpotLight
{
	PointLight pointLight;
	float3 direction;
	float cutoff;

	float padding;
};


cbuffer MatrixBuffer : register(b0)
{
	matrix worldMatrix;
	matrix viewMatrix;
	matrix projectionMatrix;
};


cbuffer LightingBuffer : register(b1)
{
	float4 ambient;

	float specularPower;
	float3 padding3;

	PointLight pointLight;
	//DirectionalLight light;

};


cbuffer CameraBuffer : register(b2)
{
	float4 cameraPos;
};


struct VertexInputType
{
	float4 position : POSITION;
	float4 color : COLOR;
	float2 texCoords : TEXCOORD0;
	float3 normal : NORMAL;
	float3 tangent : TANGENT;
	float3 biTangent : BINORMAL;
};

struct PixelInputType
{
	float4 position : SV_POSITION;
	float4 color : COLOR;
	float3 normal : NORMAL;
	float2 texCoords : TEXCOORD0;
	float3 worldPos : TEXCOORD1;
	float3 tangent : TANGENT;
	float3 biTangent : BINORMAL;
};






//Methods
float4 calcLight(BaseLight base, float3 direction, float3 normal, float3 worldPos0, float4 specularMap)
{
	float diffuseFactor = (dot(normal, -direction));

		float4 diffuseColor = float4(0, 0, 0, 0);
		float4 specularColor = float4(0, 0, 0, 0);

		if (diffuseFactor > 0.0f)
		{
			diffuseColor = base.color * base.intensity * diffuseFactor;
			diffuseColor = saturate(diffuseColor);

			float3 directionToEye = normalize(cameraPos - worldPos0);
			float3 reflectDirection = normalize(reflect(direction, normal));

			float specularFactor = dot(directionToEye, reflectDirection);
			specularFactor = pow(specularFactor, specularPower);

			if (specularFactor > 0)
			{
#if 0
				specularColor = float4(1, 0, 0, 1) * specularFactor; //Debug Specular
#else
				specularColor = base.color * 1.0f * specularFactor; //Normal Specular
#endif

			}
			if (specularMap.a > 0.0f)
				specularColor = specularColor * specularMap;
		}


	return ambient + diffuseColor + specularColor;


}

float4 calcDirectionalLight(DirectionalLight directionalLight, float3 normal, float3 worldPos0, float4 specularMap)
{
	return calcLight(directionalLight.base, -directionalLight.direction, normal, worldPos0, specularMap);
}

float4 calcPointLight(PointLight pointLight, float3 normal, float3 worldPos0, float4 specularMap, float4 diffuseTex)
{
	float3 lightDirection = worldPos0 - pointLight.pos;
	float distanceToPoint = length(lightDirection);

	//	if (distanceToPoint > pointLight.range)
	//	return float4(0, 0, 0, 0);

	lightDirection = normalize(lightDirection);

	float4 color = calcLight(pointLight.base, lightDirection, normal, worldPos0, specularMap);

		float attenuation = pointLight.atten[0] +
		pointLight.atten[1] * distanceToPoint +
		pointLight.atten[2] * distanceToPoint * distanceToPoint +
		0.0001;

	return color / attenuation;
}

 

 

The main problem that I have found is caused by the specular calculations in calcLight. The specular seems to be having some kind of odd effect for example in my current build it leaves like a "tail" / "trail" on the point light which just plain looks wrong.

 

When I inspect it via the VS debugger the cameraPos is showing as float4(0,0,0, Nan) which is clearly incorrect. 

Edited by nickyc95

Share this post


Link to post
Share on other sites
Advertisement

Can you show the code where you fill your constant buffers on the CPU side?  For example, when you actually put your camera position into the buffer, are you certain that you copy a value for all four elements?

Share this post


Link to post
Share on other sites

Can you show the code where you fill your constant buffers on the CPU side?  For example, when you actually put your camera position into the buffer, are you certain that you copy a value for all four elements?

 

C++ code is below

bool LightingShader::SetLightingShaderParameters(ID3D11DeviceContext* deviceContext, const Matrix4f& worldMatrix, CameraClass& camera,
	const Material* material, Vector3f lightDirection, Vector4f ambientColor, Vector4f diffuseColor) const
{
	HRESULT result;
	D3D11_MAPPED_SUBRESOURCE mappedResource;
	D3D11_MAPPED_SUBRESOURCE mappedLightResource;
	D3D11_MAPPED_SUBRESOURCE mappedCameraResource;

	MatrixBufferType* matrixBuffer;
	perLightBuffer* lightingBuffer;
	CameraBufferType* cameraBuffer;

	/* MATRIX BUFFER */
	// Lock the constant buffer so it can be written to.
	result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
	if (FAILED(result))
	{
		return false;
	}

	// Get a pointer to the data in the constant buffer.
	matrixBuffer = (MatrixBufferType*)mappedResource.pData;

	// Copy the matrices into the constant buffer.
	matrixBuffer->world = worldMatrix.Transpose();
	matrixBuffer->view = camera.GetViewMatrix().Transpose();
	matrixBuffer->projection = camera.GetProjectionMatrix().Transpose();
	// Unlock the constant buffer.
	deviceContext->Unmap(m_matrixBuffer, 0);
	deviceContext->VSSetConstantBuffers(MATRIX_BUFFER, 1, &m_matrixBuffer);


	/*!!!! CAMERA BUFFER !!!!*/
	result = deviceContext->Map(m_cameraBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedCameraResource);
	if (FAILED(result))
		return false;


	Vector3f camPos = camera.getTransform().GetTransformedPos();

	cameraBuffer = (CameraBufferType*)mappedCameraResource.pData;
	cameraBuffer->cameraPos = Vector4f(camPos.GetX(), camPos.GetY(), camPos.GetZ(), 1);
	//cameraBuffer->padding = 1.0f;

	deviceContext->Unmap(m_cameraBuffer, 0);
	deviceContext->VSSetConstantBuffers(CAMERA_BUFFER, 1, &m_cameraBuffer);



	/*LIGHTING BUFFER*/
	result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedLightResource);

	if (FAILED(result))
	{
		return false;
	}
	// Get a pointer to the data in the constant buffer.
	lightingBuffer = (perLightBuffer*)mappedLightResource.pData;

	lightingBuffer->ambientLight = Vector4f(0.2f, 0.2f, 0.2f, 1.0f);

	lightingBuffer->specularPower = m_specularPower;
	lightingBuffer->padding = Vector3f(0, 0, 0);

	//Point Light
	lightPos = t.GetTransformedPos();
	lightingBuffer->pointLight.pos = Vector3f(lightPos.GetX(), lightPos.GetY(), lightPos.GetZ()); // camera.getTransform().GetTransformedPos();
	lightingBuffer->pointLight.range = 10.0f;
	lightingBuffer->pointLight.atten = Vector3f(0.0f, 0.2f, 0.0f);
	lightingBuffer->pointLight.base.color= Vector4f(0.0f, 1.0f, 0.0f, 1.0f);
	lightingBuffer->pointLight.base.intensity = 100.0f;


	//TODO: Change so that specular is actually from the model material not the material that is passed in....
	//Possibly within a game object per model? Or something...
	
	deviceContext->Unmap(m_lightBuffer, 0);
	deviceContext->PSSetConstantBuffers(LIGHTING_BUFFER, 1, &m_lightBuffer);

	
	return true;
}

 

Edited by nickyc95

Share this post


Link to post
Share on other sites

It's a bit hard to tell. You don't show the C++ side structs and even if, different compiler options can produce a different layout. Better be sure about it and check it with sizeof and the offsetof macro. Looking at a shader compiler assembly dump (or using the shader reflection system) also tells you the offsets on shader side.

 

Neither do we see actual shaders, just functions. One guess though: since cameraPos is used as a lighting parameter, that constant buffer should probably be bound to the pixel shader stage, not vertex shader.

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!