Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


eowdaoc

Member Since 24 May 2011
Offline Last Active Dec 19 2012 11:10 PM

Topics I've Started

Pulling my hair out over D3D11 lighting bug

08 December 2012 - 08:03 PM

I have a simple model loaded and a point light source that I am trying to get to work correctly, but it's just not happening. I have probably spent around 12 hours over the past two days trying to figure out what is wrong, and I'm starting to get really frustrated, so I thought I would ask here as a last resort.

I have checked and double checked my lighting equation many times with at least 3 different sources. At the moment I am using constant lighting coefficient so that I know for a fact my object will be lit no matter what the distance. My light is EXPLICITLY fixed at the -30.0 position on the Z-axis, yet my object appears as if it is lit from a different direction. My camera is located at ( 0.0, 0.0, -20.0 ) so that I can verify the model is not swallowing the light, and it is not. The light is plenty far away from my model. I've changed the light/camera distance many times and have gotten the same result.

The entire front side of my object should be lit, instead it is lit from a different angle.

I use the DirectXMath library and I was VERY, VERY careful to store the const buffer matrices correctly and with the right alignment. I also made sure my HLSL byte alignment was correct by using float4. I use the row-major compiler options for HLSL so I do not need to use matrix transpose, and my code reflects that.

Please give my code a look and tell me where I've gone wrong, because I obviously cannot figure it out! Posted Image

Bugged lighting:
Attached File  bug.jpg   20.02KB   47 downloads

Matrix update function:
Attached File  update.jpg   483.45KB   51 downloads

Vertex shader:
Attached File  vs.jpg   131.51KB   56 downloads

Pixel shader:
Attached File  ps.jpg   292.01KB   47 downloads

Parentheses in HLSL cause light attenuation function to not work correctly?

13 September 2012 - 03:10 PM

I have a diffuse+specular equation in my pixel shader, and it works pretty well except for this one issue:

When I change this:
float attenuation = 1.0f / d*d;
To this:
float attenuation = 1.0f / ( d*d );

My model is no longer lit, and is instead the color of my ambient intensity. I find this extremely strange. The reason I want parentheses is so I can use a different attenuation function such as ( 1 + 0.045*d + 0.0075*d*d ).

It also messes up if I try this:
float denominator = d*d;
float attenuation = 1.0f / denominator;


Here is my entire pixel shader. The reason for all of the "tmp_stuff" variables is to make everything "politically correct" since I have no choice but to input them as float4 due to constant buffer alignment properties. I would rather convert everything to temporary float3 rather than risk the chance of something not working right because of float4. Anyways, it shouldn't have anything to do with my current problem. I've doubled, tripled, and quad-checked my lighting equations with four different books, and I'm just baffled with this problem.

void ps( in v2p input, out float4 final_color : SV_TARGET )
{
	float3 ambient_intensity = float3( 0.1f, 0.1f, 0.1f );
	float3 diffuse_color = float3( 0.8f, 0.8f, 0.8f);
	float3 specular_color = float3( 1.0f, 1.0f , 1.0f );

	float3 tmp_light;
	tmp_light.x = light_vector.x;
	tmp_light.y = light_vector.y;
	tmp_light.z = light_vector.z;

	float3 norm_light = normalize( tmp_light );

	float3 tmp_pos;
	tmp_pos.x = input.pos.x;
	tmp_pos.y =  input.pos.y;
	tmp_pos.z = input.pos.z;

	float3 tmp_norm;
	tmp_norm.x = input.norm.x;
	tmp_norm.y = input.norm.y;
	tmp_norm.z = input.norm.z;

	float3 tmp_cam = float3( 0.0f, 0.0f, -20.0f ); // fixed view camera position

	// light intensity
	float d = distance( tmp_pos, tmp_light );
	float attenuation = 1.0f/d*d; // HERE IS THE PROBLEM AREA

	float3 pointlight = attenuation*float3( light_color.x, light_color.y, light_color.z );

	// diffuse lighting
	float diffuse = max( dot( tmp_norm, norm_light) , 0.0f );
	float3 diffuse_final = diffuse_color*ambient_intensity + diffuse_color*pointlight*diffuse;

	// specular lighting
	float3 reflect_vect = 2*dot( tmp_norm, norm_light )*tmp_norm - norm_light;
	float ref_max = max( dot( reflect_vect, normalize(tmp_cam) ), 0.0f );
	float spec_exponent = pow ( ref_max, 50.0f );
	float3 spec_final;

	if( dot( tmp_norm, norm_light ) <= 0 )
	{
	  spec_final = float3( 0.0f, 0.0f, 0.0f );
	}
	if( dot( tmp_norm, norm_light ) > 0 )
	{
	  spec_final = specular_color*pointlight*spec_exponent;
	}
	final_color = float4(  diffuse_final + spec_final, 1.0f );
}

Without parentheses:
Posted Image

With parentheses:
Posted Image

Colors are inverted after creating my own vector class?

18 August 2011 - 01:12 PM

My title says it all. I didn't change my original code at all. I only replaced the D3DXVECTOR3 class with my vec4 class. The colors of my primitives became incorect, and I am at a loss as to why.

Obviously there must be an error in my vec4 class, right? I cannot seem find it, if there is one, so I was wondering if anyone here would like to take a look?

My program displays a simple animated box, but it's supposed to be blue, not red!

I have narrowed the problem down a little and it seems it is happening when I replace "D3DXVECTOR3" in my vertex list with "vec4" for the position. My replacement color vector for D3DXCOLOR works properly.
vec4.h
#ifndef VEC4_H
#define VEC4_H

class vec4
{
	float x, y, z, alpha;
public:
	
	vec4( const float& xCoord, const float& yCoord, const float& zCoord = 0.0f, const float& alphaVal = 1.0f );
	vec4( const vec4& v );
	vec4& operator=( const vec4& v );
	~vec4();

	float getX();
	void setX( const float& xCoord );
	float getY();
	void setY( const float& yCoord );
	float getZ();
	void setZ( const float& zCoord );
	float getAlpha();
	void setAlpha( const float& alphaVal );

	void scalarMult( const float& s );
	vec4 operator+( const vec4& v )const;
};
#endif


vec4.cpp
#ifndef VEC4_CPP
#define VEC4_CPP
#include "vec4.h"


vec4::vec4( const float& xCoord, const float& yCoord, const float& zCoord, const float& alphaVal )
{
	x = xCoord;
	y = yCoord;
	z = zCoord;
	alpha = alphaVal;
}
vec4::vec4( const vec4& v )
{
	x = v.x;
	y = v.y;
	z = v.z;
	alpha = v.alpha;
}
vec4& vec4::operator=( const vec4& v )
{
	x = v.x;
	y = v.y;
	z = v.z;
	alpha = v.alpha;
	return *this;
}
vec4::~vec4()
{

}
float vec4::getX()
{
	return x;
}
void vec4::setX( const float& xCoord )
{
	x = xCoord;
}
float vec4::getY()
{
	return y;
}
void vec4::setY( const float& yCoord )
{
	y = yCoord;
}
float vec4::getZ()
{
	return z;
}
void vec4::setZ( const float& zCoord )
{
	z = zCoord;
}
float vec4::getAlpha()
{
	return alpha;
}
void vec4::setAlpha( const float& alphaVal )
{
	alpha = alphaVal;
}
void vec4::scalarMult( const float& s )
{
	x = x*s;
	y = y*s;
	z = z*s;
}
vec4 vec4::operator+( const vec4& v )const
{
	return vec4( x + v.x, y + v.y, z + v.z );
}


#endif

d3d.h
#ifndef D3D_H
#define D3D_H

#include <D3D10.h>
#include <D3DX10.h>
#include "vec4.h"

#pragma comment (lib, "d3d10.lib")
#pragma comment (lib, "d3dx10.lib")

struct VERTEX
{
      vec4 Position;
      vec4 Color;
};

class D3D
{
	int w, h; // width, height of window
	
	ID3D10Device* dev;
	IDXGISwapChain* sc;
	ID3D10RenderTargetView* rtv;

	ID3D10Buffer* pBuff;
	ID3D10Buffer* pIndexBuff;

	ID3D10Effect* pEff;
	ID3D10EffectTechnique* pTech;
	ID3D10EffectPass* pPass;
	ID3D10InputLayout* pLayout;

	ID3D10EffectScalarVariable* pVariable;

public:
	D3D( int width, int height );

	void init( HWND hwnd );
	void pipe();
	void geo();
	void render_frame();
	void clean();
};

#endif


d3d.cpp
#include "d3d.h"

D3D::D3D( int width, int height )
{
	w = width;
	h = height;
}
//################################################################################################
void D3D::init( HWND hwnd )
{
	DXGI_SWAP_CHAIN_DESC scd;
	scd.BufferCount = 1;
	scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	scd.BufferDesc.Height = h;
	scd.BufferDesc.RefreshRate.Denominator = 1;
	scd.BufferDesc.RefreshRate.Numerator = 60;
	scd.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
	scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
	scd.BufferDesc.Width = w;
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	scd.OutputWindow = hwnd;
	scd.SampleDesc.Count = 1;
	scd.SampleDesc.Quality = 0;
	scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	scd.Windowed = true;

	D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, NULL, D3D10_SDK_VERSION, &scd, &sc, &dev );

	ID3D10Texture2D* pBackBuffer;
	sc->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBackBuffer );
	dev->CreateRenderTargetView( pBackBuffer, NULL, &rtv );
	pBackBuffer->Release();
	dev->OMSetRenderTargets( 1, &rtv, NULL );

	D3D10_VIEWPORT viewport;
	viewport.Height = h;
	viewport.MaxDepth = 0;
	viewport.MinDepth = 0;
	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = w;
	
	dev->RSSetViewports( 1, &viewport );
}
//################################################################################################
void D3D::geo()
{
    VERTEX vvertices[] =
    {
		// position 					// color
		{ vec4( -0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
        { vec4( -0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
        { vec4( 0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },

        { vec4( -0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
		{ vec4( 0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
		{ vec4( 0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) }
			
		
    };

	D3D10_BUFFER_DESC vbd;
	vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	vbd.ByteWidth = sizeof( VERTEX ) * 6;
	vbd.CPUAccessFlags = NULL;
	vbd.MiscFlags = NULL;
	vbd.Usage = D3D10_USAGE_IMMUTABLE;

	D3D10_SUBRESOURCE_DATA vinitData;
	vinitData.pSysMem = vvertices;

	dev->CreateBuffer( &vbd, &vinitData, &pBuff );

	int ivertices[6] = { 
		0, 1, 2, 
		0, 4, 5 
	};

	D3D10_BUFFER_DESC ibd;
	ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
	ibd.ByteWidth = sizeof( int ) * 6;
	ibd.CPUAccessFlags = NULL;
	ibd.MiscFlags = NULL;
	ibd.Usage = D3D10_USAGE_IMMUTABLE;

	D3D10_SUBRESOURCE_DATA iinitData;
	iinitData.pSysMem = ivertices;

	dev->CreateBuffer( &ibd, &iinitData, &pIndexBuff );

	// use if not immutable
	//void* pVoid;
	//pBuff->Map( D3D10_MAP_WRITE_DISCARD, NULL, &pVoid );
	//memcpy( pVoid, vertices, sizeof( vertices ) );
	//pBuff->Unmap();
}
//################################################################################################
void D3D::pipe()
{
	D3D10_PASS_DESC passdesc;

	D3DX10CreateEffectFromFile( "effect.fx", NULL, NULL, "fx_4_0", NULL, NULL, dev, NULL, NULL, &pEff, NULL, NULL );
	pTech = pEff->GetTechniqueByIndex( 0 );
	pPass = pTech->GetPassByIndex( 0 );
	pPass->GetDesc( &passdesc );

	D3D10_INPUT_ELEMENT_DESC layout[2];

	layout[0].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].InputSlot = 0;
	layout[0].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
	layout[0].InstanceDataStepRate = 0;
	layout[0].SemanticIndex = 0;
	layout[0].SemanticName = "POSITION";

	layout[1].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;
	layout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[1].InputSlot = 0;
	layout[1].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
	layout[1].InstanceDataStepRate = 0;
	layout[1].SemanticIndex = 0;
	layout[1].SemanticName = "COLOR";

	dev->CreateInputLayout( layout, 2, passdesc.pIAInputSignature, passdesc.IAInputSignatureSize, &pLayout );

	
	pVariable = pEff->GetVariableByName( "timeVar" )->AsScalar();
}
//################################################################################################
void D3D::render_frame()
{

	FLOAT color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
	dev->ClearRenderTargetView( rtv, color );

	dev->IASetInputLayout( pLayout );
	dev->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	UINT stride = sizeof( VERTEX );
	UINT offset = 0;
	static float time = 0.0f;
	time += 0.0001f;

	dev->IASetVertexBuffers( 0, 1, &pBuff, &stride, & offset );
	dev->IASetIndexBuffer( pIndexBuff, DXGI_FORMAT_R32_UINT, 0 );
	
	pVariable->SetFloat( time );
	pPass->Apply( NULL );

	dev->DrawIndexed( 6, 0, 0 );

	sc->Present( NULL, NULL );
}
//################################################################################################
void D3D::clean()
{

	if( pLayout )
		pLayout->Release();
	if( pEff )
		pEff->Release();
	if( pBuff )
		pBuff->Release();
	if( rtv )
		rtv->Release();
	if( dev )
		dev->Release();
	if( sc )
		sc->Release();
}

effect.fx
float timeVar;

// a struct for the vertex shader return value
struct VSOut
{
    float4 Col : COLOR;    // vertex color
    float4 Pos : SV_POSITION;    // vertex screen coordinates
};

// the vertex shader
VSOut VS(float4 Col : COLOR, float4 Pos : POSITION)
{
    VSOut Output;
    Output.Pos = Pos;    // set the vertex position to the input's position

    Output.Pos.x *= sin( timeVar );    // shrink the vertex on the x-axis
	Output.Pos.y *= sin( timeVar );

    Output.Col = Col;    // set the vertex color to the input's color

    return Output;    // send the modified vertex data to the Rasterizer Stage
}

// the pixel shader
float4 PS(float4 Col : COLOR) : SV_TARGET
{
    return Col;    // set the pixel color to the color passed in by the Rasterizer Stage
}

// the primary technique
technique10 Technique_0
{
    // the primary pass
    pass Pass_0
    {
        SetVertexShader(CompileShader(vs_4_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PS()));
    }
}

Program crash when ppSwapChain->GetBuffer

24 May 2011 - 02:18 PM

#include <windows.h>
#include <d3d11.h>

HWND hwnd;
HINSTANCE hInstance;
D3D_FEATURE_LEVEL pFeatureLevel;
IDXGISwapChain *ppSwapChain;
ID3D11Device *ppDevice;
ID3D11DeviceContext *ppImmediateContext;
ID3D11RenderTargetView *pRenderTargetView;

void InitWindow( HINSTANCE hInstance, int nCmdShow );
void InitDevice();
void Render();

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	InitWindow( hInstance, nCmdShow );
	InitDevice();
	


	MSG msg = {0};
	while( WM_QUIT != msg.message )
	{
		if( PeekMessage( &msg, hwnd, 0, 0, PM_REMOVE ) )
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
			Render();
	}
}

void InitWindow( HINSTANCE hInstance, int nCmdShow )
{
	WNDCLASS wnd;

	wnd.cbClsExtra = 0;
	wnd.cbWndExtra = 0;
	wnd.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wnd.hCursor = LoadCursor( 0, IDC_ARROW );
	wnd.hIcon = LoadIcon( 0, IDI_APPLICATION );
	wnd.hInstance = hInstance;
	wnd.lpfnWndProc = WndProc;
	wnd.lpszClassName = "Default";
	wnd.lpszMenuName = NULL;
	wnd.style = CS_VREDRAW | CS_HREDRAW;

	RegisterClass( &wnd );

	hwnd = CreateWindow( "Default", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, 0, 0, hInstance, 0 );
	ShowWindow( hwnd, nCmdShow );
}

void InitDevice()
{
	// first fill out swap chain desc
	DXGI_SWAP_CHAIN_DESC sd;

	sd.BufferCount = 1;

	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.Width = 400;
	sd.BufferDesc.Height = 400;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.Flags = NULL;
	sd.OutputWindow = hwnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Windowed = true;
	
	
	// now create device and swap chain
	D3D_DRIVER_TYPE DriverType = D3D_DRIVER_TYPE_HARDWARE;

	D3D_FEATURE_LEVEL pFeatureLevels = D3D_FEATURE_LEVEL_11_0;
	if( !D3D11CreateDeviceAndSwapChain( NULL, DriverType, NULL, NULL, &pFeatureLevels, 1, D3D11_SDK_VERSION, &sd, &ppSwapChain, &ppDevice, &pFeatureLevel, &ppImmediateContext ))
		MessageBox( 0, "OOps", "Oops!", 0 );
	
	// now handle the render target views for buffers
	ID3D11Texture2D *pBackBuffer;
	
	ppSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>(&pBackBuffer) );
	MessageBox( 0, "GetBuffer success!", "Success!", 0 );
	ppDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView );
	
	
	D3D11_VIEWPORT vp;
	vp.Width = 400;
	vp.Height = 400;
	vp.MaxDepth = 1.0f;
	vp.MinDepth = 0.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	ppImmediateContext->RSSetViewports( 1, &vp );
}

void Render()
{
    // Just clear the backbuffer
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha
	ppImmediateContext->ClearRenderTargetView( pRenderTargetView, ClearColor );
    ppSwapChain->Present( 0, 0 );
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch( msg )
	{
	case WM_CREATE:
		return 0;
	case WM_KEYDOWN:
		switch( wParam )
		{
		case VK_LEFT:
			SetWindowText( hwnd, "pressed left arrow key!" );
			return 0;
		case VK_RIGHT:
			SetWindowText( hwnd, "pressed right arrow key!" );
			return 0;
		case VK_DOWN:
			SetWindowText( hwnd, "pressed down arrow key!" );
			return 0;
		case VK_UP:
			SetWindowText( hwnd, "pressed up arrow key!" );
			return 0;
		case VK_ESCAPE:
			PostQuitMessage( 0 );
			return 0;
		}
	case WM_KEYUP:
		{
			SetWindowText( hwnd, "Test" );
			return 0;
		}
	case WM_DESTROY:
		{
			PostQuitMessage( 0 );
			return 0;
		}
	}
	return DefWindowProc( hwnd, msg, wParam, lParam );
}

Says I have an access violation when I execute ppSwapChain->GetBuffer.

Any ideas?

PARTNERS