Billboard problem

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Billboard problem

Beitrag von exploid »

Hallo liebe ZFX-Community

Es wird versucht eine Szene zu zeichnen. Dabei werden 2 Modelle dargestellt die jeweils u.a. ein Billboard verwenden, also eine rechteckige Fläche die eine Bitmap enthält, das sich immer auf die Kamera ausrichtet. Die Billboards haben eine Bitmap die einen Alphawert verwendet für die Transparenz. Dabei entsteht folgender Darstellungsfehler.

Bild

Der Fehler kann behoben werden indem die Modelle vor dem Zeichnen sortiert werden in der Weise, daß die Billboards die in der Szene am weitesten von der Kamera entfernt sind zuerst gezeichnet werden.

Bild

Sollte dieses Sortieren nicht vom Z-Buffer geschehen? Ich bin verwirrt und weiss mir nicht weiter zu helfen. o.O

Code: Alles auswählen

/**
 * -> IN: HWND      - handle of application window
 */
HRESULT Graphics::Init(HWND hWnd, BOOL bDialog){

	m_hWndMain = hWnd;
    // Suboptimal
    //TO DO Enumeration
    HRESULT  hr = _FAIL;
    UINT createDeviceFlags = 0;
    ID3D10Texture2D* pBackBuffer;

    #ifdef _DEBUG
	   createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
    #endif
    RECT Rect;
    int width, height;
    GetWindowRect(hWnd, &Rect);
    width = Rect.right-Rect.left;
    height = Rect.bottom - Rect.top;
	if (bDialog) {
		m_pEnum = new GraEnum(m_pLog);
		if(!m_pEnum) {
			Log("new GraEnum -> Out of memory!");
		}
		// start enumeration dialog
		DialogBox(m_hDLL, TEXT("ENUMERATION"), hWnd, DlgProcWrap);
		if(!m_bOkWasPressed) {
			Log("Dialogbox cancel");
			return _CANCELED;
		}
		// create device
		if( FAILED( D3D10CreateDevice(	m_Adapter.pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags,
			D3D10_SDK_VERSION, &m_pDevice)) ) {
				Log("D3D10CreateDevice failed!");
				return _FAIL;
		}
		IDXGIDevice * pDXGIDevice;
		hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
		IDXGIAdapter * pDXGIAdapter;
		hr += pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
		IDXGIFactory * pIDXGIFactory;
		hr += pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pIDXGIFactory);
		if FAILED(hr) {
			Log("QueryInterface failed!");
			return _FAIL;
		}
		// create swapchain
		DXGI_SWAP_CHAIN_DESC swapChainDesc;
		ZeroMemory( &swapChainDesc, sizeof(swapChainDesc) );	
		swapChainDesc.BufferDesc.Width = m_DescResolution.Width;
		swapChainDesc.BufferDesc.Height = m_DescResolution.Height;
		swapChainDesc.BufferDesc.Format = m_DescResolution.Format;
		swapChainDesc.BufferDesc.ScanlineOrdering = m_DescResolution.ScanlineOrdering;
		swapChainDesc.BufferDesc.Scaling = m_DescResolution.Scaling;
		swapChainDesc.BufferDesc.RefreshRate.Numerator = m_DescResolution.RefreshRate.Numerator;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = m_DescResolution.RefreshRate.Denominator;
		swapChainDesc.SampleDesc.Count = 1;//
		swapChainDesc.SampleDesc.Quality = 0;
		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;//
		swapChainDesc.BufferCount = 1;//
		swapChainDesc.OutputWindow = hWnd;//
		swapChainDesc.Windowed = m_bWindowed;
		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;//
		swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;


		hr = pIDXGIFactory->CreateSwapChain(m_pDevice, &swapChainDesc, &m_pSwapChain);

		
	}
	else {
		DXGI_SWAP_CHAIN_DESC swapChainDesc;
		ZeroMemory( &swapChainDesc, sizeof(swapChainDesc) );
		swapChainDesc.BufferCount = 1;//
		swapChainDesc.BufferDesc.Width = width;
		swapChainDesc.BufferDesc.Height = height;
		swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//
		swapChainDesc.BufferDesc.RefreshRate.Numerator = 60000;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = 1000;
		swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;//
		swapChainDesc.OutputWindow = hWnd;//
		swapChainDesc.SampleDesc.Count = 1;//
		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;//
		swapChainDesc.SampleDesc.Quality = 0;
		swapChainDesc.Windowed = m_bWindowed = false;//
	    
		if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, 
			D3D10_DRIVER_TYPE_HARDWARE, NULL, 
			createDeviceFlags, D3D10_SDK_VERSION, &swapChainDesc, 
			&m_pSwapChain, &m_pDevice ) ) )
		{
			Log("D3D10CreateDeviceAndSwapChain => D3D10_DRIVER_TYPE_HARDWARE failed now trying D3D10_DRIVER_TYPE_REFERENCE");
			// if D3D10_DRIVER_TYPE_HARDWARE fails try D3D10_DRIVER_TYPE_REFERENCE
			if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, 
				D3D10_DRIVER_TYPE_REFERENCE, NULL, 
				0, D3D10_SDK_VERSION, &swapChainDesc, 
				&m_pSwapChain, &m_pDevice ) ) )
			{            
				Log("Failed to create device and swap chain");
				return hr;
			}
		}
	}
    if( FAILED( m_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), 
              (LPVOID*)&pBackBuffer ) ) )
    {
		Log("Failed to create back buffer");
        return hr;
    }

    if(FAILED( m_pDevice->CreateRenderTargetView( pBackBuffer, 
               NULL, &m_pRenderTargetView )))
    {        
		Log("Failed to create render target view");
        return hr;
    }
    pBackBuffer->Release();

    //Create the depth-stencil buffer using a texture resource.

    D3D10_TEXTURE2D_DESC descDepth;
    descDepth.Width = width;
    descDepth.Height = height;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D32_FLOAT;
    descDepth.SampleDesc.Count = 1;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D10_USAGE_DEFAULT;
    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = 0;
    descDepth.MiscFlags = 0;
    hr=m_pDevice->CreateTexture2D(&descDepth, NULL, &m_pDepthStencil);
    if(FAILED(hr)) 
		return hr;
    // The depth-stencil state tells the output-merger stage how to perform the depth-stencil test.
    // The depth-stencil test determines whether or not a given pixel should be drawn.
    D3D10_DEPTH_STENCIL_DESC dsDesc;

    // Depth test parameters
    dsDesc.DepthEnable = true;
    dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
    dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
    // Stencil test parameters
    dsDesc.StencilEnable = true;
    dsDesc.StencilReadMask = 0xFF;
    dsDesc.StencilWriteMask = 0xFF;
    // Stencil operations if pixel is front-facing
    dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
    dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
    // Stencil operations if pixel is back-facing
    dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
    dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
    // Create depth stencil state
    m_pDevice->CreateDepthStencilState(&dsDesc, &m_pDSState);
    // Bind depth stencil state
    m_pDevice->OMSetDepthStencilState(m_pDSState, 1);

    //Bind the depth-stencil resource using a view.
    D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
    hr = m_pDevice->CreateDepthStencilView(m_pDepthStencil, &descDSV, &m_pDepthStencilView);
    if(FAILED(hr))
	   return hr;

    // Bind the depth stencil view
    m_pDevice->OMSetRenderTargets(	1,          		// One rendertarget view
					&m_pRenderTargetView,   // Render target view, created earlier
					m_pDepthStencilView );  // Depth stencil view for the render target


    D3D10_VIEWPORT vp = {0, 0, width, height, 0, 1};
	
    m_pDevice->RSSetViewports( 1, &vp );
	
    m_dwWidth         = width;
    m_dwHeight        = height;

    D3D10_BLEND_DESC desc;
    ZeroMemory(&desc,sizeof(D3D10_BLEND_DESC));
    desc.AlphaToCoverageEnable=FALSE;
    desc.BlendEnable[0]=TRUE;
	desc.BlendEnable[1]=TRUE;
    desc.SrcBlend=D3D10_BLEND_SRC_ALPHA;
    desc.DestBlend=D3D10_BLEND_INV_SRC_ALPHA;
    desc.BlendOp=D3D10_BLEND_OP_ADD;
    desc.SrcBlendAlpha=D3D10_BLEND_ZERO;
    desc.DestBlendAlpha=D3D10_BLEND_ZERO;
    desc.BlendOpAlpha=D3D10_BLEND_OP_ADD;
    desc.RenderTargetWriteMask[0]=0xf;
    m_pDevice->CreateBlendState(&desc, &m_pFontBlendState);
	

    m_bRunning	= true;
    Log("D3D::InitWindowed returned _OK");

    return OneTimeInit();
}
/*----------------------------------------------------------------*/
Blendstates wurden so gesetzt.

Code: Alles auswählen

//--------------------------------------------------------------------------------------
// File: phong.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D tTexture;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

matrix World;
matrix View;
matrix Projection;
 
float4 vLightDir[3];
float4 vLightColor[3];
float4 vOutputColor;

float fSpecularIntensity;
float fDiffuseIntensity;
float fAmbientIntensity;

float4 vAmbientColor;
float4 vDiffuseColor;
float4 vSpecularColor;

float3 CameraPosition : CameraPosition;

/*BlendState SrcAlphaBlendingAdd
{
	BlendEnable[0] = TRUE;
	SrcBlend = SRC_ALPHA;
	DestBlend = INV_SRC_ALPHA;
	BlendOp = ADD;
	SrcBlendAlpha = ZERO;
	DestBlendAlpha = ZERO;
	BlendOpAlpha = ADD;
	RenderTargetWriteMask[0] = 0x0F;
};*/


//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 position : POSITION;	// Vertex position in object space
    float3 normal : NORMAL;		// Vertex normal in object space
    float2 texCoord : TEXCOORD;	// Vertex texture in object space
};

struct VS_OUTPUT
{
    float4 position : SV_POSITION; // Pixel position in clip space
    float3 light : TEXCOORD0;	// Pixel texture coordinates
    float3 normal : TEXCOORD1;	// Pixel normal vector
    float3 camview: TEXCOORD2;		// Pixel view vector
    float2 texCoord : TEXCOORD3; // Texture
   
};

#define PS_INPUT VS_OUTPUT		// what comes out of VS goes into PS

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    // Basic transformation of untransformed vertex into clip-space
    output.position = mul( input.position, World );
    output.position = mul( output.position, View );
    output.position = mul( output.position, Projection );
    // basic texture stuff
    output.light = vLightDir[0];//LightDirection;
    // calculate the normal vector
    output.normal = mul( input.normal, World );
    // calcutlate the view vector
    output.camview = CameraPosition - mul(input.position, World);
    // Texture
    output.texCoord = input.texCoord;
    
    
    return output;
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    float4 finalColor = 0;
    float3 Norm = normalize(input.normal);
    float3 LightDir = normalize(input.light);
    // Get ambient light
    vAmbientColor *= fAmbientIntensity;
    // Get diffuse light
    vDiffuseColor = (fDiffuseIntensity * vDiffuseColor) * saturate(dot(LightDir, Norm));
    float3 Half = normalize(LightDir + normalize(input.camview));
    float specular = pow(saturate(dot(Norm,Half)),25);

    finalColor = (vAmbientColor + vDiffuseColor + ((vSpecularColor * fSpecularIntensity) * specular) ) 
	* tTexture.Sample( samLinear, input.texCoord ); 
   // finalColor.a -= 0.5; // transparency
    return finalColor;
}


//--------------------------------------------------------------------------------------
// Pixel Shader 2 ambient + diffuse + texture color
//--------------------------------------------------------------------------------------
float4 PSSolid( PS_INPUT input) : SV_Target
{
	float4 finalColor = 0;
    //float3 Norm = normalize(input.normal);
    //float3 LightDir = normalize(input.light);
    // Get ambient light
    vAmbientColor *= fAmbientIntensity;
    // Get diffuse light
    vDiffuseColor *= fDiffuseIntensity;
    
    finalColor = (vAmbientColor + vDiffuseColor) * tTexture.Sample( samLinear, input.texCoord ); 
    //finalColor.a = 1;
    return finalColor;
}


//--------------------------------------------------------------------------------------
technique10 DotProduct
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}


//--------------------------------------------------------------------------------------
technique10 RenderSolid
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSSolid() ) );

		//SetBlendState( SrcAlphaBlendingAdd, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF );
    }
}
GPU-Programm (Shader) sieht so aus.

Hat hier jemand Erfahrung mit derlei Probleme? Hilfe wäre geschätzt. :)
All your base are belong to us! Justice
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Billboard problem

Beitrag von dot »

Wie genau sollte der Z-Buffer denn deiner Meinung nach das Problem hier lösen? ;)

Ich könnte mir aber vorstellen, dass du in deinem Fall sowieso kein "normales" Alphablending haben willst, sondern eher additives Blending. Dann hast du Glück, denn das ist kommutativ und dann brauchst du nix sortieren, sondern einfach nur die Depth Buffer Writes abschalten...
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Hallo dot

Danke für die schnelle Hilfe. Hab das sofort ausprobiert, provisorisch,

Code: Alles auswählen

// Depth test parameters
    dsDesc.DepthEnable = false; //true; <= HIER
    dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
    dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
    // Stencil test parameters
    dsDesc.StencilEnable = true;
    dsDesc.StencilReadMask = 0xFF;
    dsDesc.StencilWriteMask = 0xFF;
    // Stencil operations if pixel is front-facing
    dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
    dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
    // Stencil operations if pixel is back-facing
    dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
    dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
    dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
    // Create depth stencil state
    m_pDevice->CreateDepthStencilState(&dsDesc, &m_pDSState);
und auf einmal werden die Billboards richtig gezeichnet allerdings sind dann die Modelle fehlerhaft. Muss das in den solid pass für die Billboards einbauen und dort den depth stencil ausschalten und im phong shader wieder anschalten. :) Okay danke nochmal für den Hinweis.
All your base are belong to us! Justice
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Billboard problem

Beitrag von dot »

Wundert mich, dass das "funktioniert". Render zuerst alle soliden Objekte ganz normal. Danach renderst du die Billboards und setzt dafür die Write Mark auf ZERO, lasst den Depth Test selbst aber eingeschaltet.

Btw: Wofür verwendest du denn den Stencil Buffer?
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Ich weiß nicht wo die "Write Mark" gesetzt wird. o.O Hilfe!
All your base are belong to us! Justice
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Billboard problem

Beitrag von dot »

In dem Fall darf ich deine Aufmerksamkeit auf deinen eigenen Code aus deinem Letzten Posting Zeile zwei lenken... ;)
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Ach so, verstanden :), hm

das wurde versucht aber es funktioniert nicht :(

Code: Alles auswählen

//--------------------------------------------------------------------------------------
// Depth/Stencil States
//--------------------------------------------------------------------------------------
DepthStencilState DepthEnableOff
{
    DepthEnable = false;
    DepthWriteMask = ZERO;
    DepthFunc = Less;
    
    // Setup stencil states
    StencilEnable = true;
    StencilReadMask = 0xFF;
    StencilWriteMask = 0xFF;
    
    FrontFaceStencilFunc = Not_Equal;
    FrontFaceStencilPass = Keep;
    FrontFaceStencilFail = Zero;
    
    BackFaceStencilFunc = Not_Equal;
    BackFaceStencilPass = Keep;
    BackFaceStencilFail = Zero;
};

DepthStencilState DepthEnableOn
{
    DepthEnable = true;
    DepthWriteMask = 1;
    DepthFunc = Less;
    
    // Setup stencil states
    StencilEnable = true;
    StencilReadMask = 0xFF;
    StencilWriteMask = 0xFF;
    
    FrontFaceStencilFunc = Always;// Not_Equal;
    FrontFaceStencilPass = Keep;
    FrontFaceStencilFail = Keep;
    
    BackFaceStencilFunc = Not_Equal;
    BackFaceStencilPass = Keep;
    BackFaceStencilFail = Zero;
};

//--------------------------------------------------------------------------------------
technique10 DotProduct
{
    pass P0
    {
		
        
	       SetVertexShader( CompileShader( vs_4_0, VS() ) );
               SetGeometryShader( NULL );
               SetPixelShader( CompileShader( ps_4_0, PS() ) );
               SetDepthStencilState( DepthEnableOn, 0 );

		
    }
}


//--------------------------------------------------------------------------------------
technique10 RenderSolid
{
    pass P0
    {
		

        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSSolid() ) );
	SetDepthStencilState( DepthEnableOff, 0 );
			
		//SetBlendState( SrcAlphaBlendingAdd, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF );
    }
}
Die Modelle werden mit der "DotProdukt-technique" gezeichnet und die Billboards mit der "RenderSolid-technique".
Als Problemlösung wollte ich den Depthbuffer umschalten. => klappt nicht, *heul*
All your base are belong to us! Justice
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Eine mögliche Problemlösung wäre alle Objekte hinsichtlich der Entfernung zur Kamera sortieren und dann beginnend beim Entferntesten zu zeichnen. Dann wär der Fehler weg.
All your base are belong to us! Justice
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Bild

Die Billboard alpha Werte werden aber richtig gezeichnet wenn auch alles andere falsch ist. :)
All your base are belong to us! Justice
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Problem gelöst dank dem Hinweis von Dot. Ich dreh eben einen kleinen Film und dokumentiere woran es gelegen hat.
All your base are belong to us! Justice
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Billboard problem

Beitrag von exploid »

Hallo :)

Wie bereits gesagt wurde ist es bei Billboards, die Transparenz verwenden durch Alpha-Werte, wie das bei "dds-Texturen" der Fall ist, notwendig den "depht stencil" zu verändern. Das ist möglich durch einen DepthStencilState zur Laufzeit im HLSL-Shader mit:

Code: Alles auswählen

//--------------------------------------------------------------------------------------
// Depth/Stencil States
//--------------------------------------------------------------------------------------
DepthStencilState DepthEnableBillboard
{
    DepthWriteMask = ZERO;
};

Dieser wird in den "Pass" der "Technique" eingebaut mit

technique10 RenderBillboard
{
    pass P0
    {
		

        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSSolid() ) );
		
	SetDepthStencilState( DepthEnableBillboard, 0 );		
		
    }
}
Der wichtige Eintrag ist die DepthWriteMask. Der Sinn und Zweck war mir vorher für DirektX 10 nicht bekannt und daher wurden Informationen gesucht. Die Dokumentation sagt:

D3D10_DEPTH_WRITE_MASK
A member of the D3D10_DEPTH_WRITE_MASK enumerated type that identifies a portion of the depth-stencil
buffer that can be modified by depth data. The default value is D3D10_DEPTH_WRITE_MASK_ALL.

Das bedeutet wenn wir die DephtWriteMask auf 0 setzen werden keine Werte in den z-Buffer geschrieben also dem
Depth buffer was das selbe bezeichnet mit anderen Ausdrücken. Der Tiefentest wird damit ausgeschaltet.
Die Texeldaten der Billboards werden dadurch einfach addiert und zum Output Merger geschickt.
Das ist aber noch nicht alles. Damit im nächsten "Pass" die Scene nicht weiter so behandelt wird, erzeugt übrigens
einen lustigen Effekt, muss der ursprünglicher DepthStencilState widerhergestellt werden. Das erreichen wir mit

Code: Alles auswählen

DepthStencilState DepthEnableRestore
{
    DepthWriteMask = All;
};

Das schaltet den "Tiefentest" wieder ein. 

und in den Pass einbauen:

technique10 DotProduct
{
    pass P0
    {
		      
	SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );

	SetDepthStencilState( DepthEnableRestore, 0 );
    }
}
http://www.youtube.com/watch?v=EVzwfzHA ... e=youtu.be
All your base are belong to us! Justice
Antworten