Render to Texture



  • hi,

    ich hab das mit dem 2 oder mehr Shader benutzen, um zum Beispiel Blur effekte zu erzeugen nicht ganz verstanden...
    Ich hab das folgende Beispiel ma zusammen gebaut. Ist kein "fertiger" Code nur um das Problem zu verdeutlichen.

    void LowLevelManager::Render()
    {
    	UpdateAllBuffers();
    	unsigned int stride;
    	unsigned int offset;
    
    	// Set vertex buffer stride and offset.
    	stride = sizeof(Basic2DElement::VertexType);
    	offset = 0;
    	//Set the index buffer to active in the input assembler so it can be rendered.
    	DXCLASSGI.deviceContext->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
    	//Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
    	DXCLASSGI.deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    	// Set the sampler state in the pixel shader.
    	DXCLASSGI.deviceContext->PSSetSamplers(0, 1, SBMGI.getSamplerState());
    
    	for (auto& b : basicElements)
    	{
    		if (b->IsVisible())
    		{
    			// Set the vertex buffer to active in the input assembler so it can be rendered.
    			DXCLASSGI.deviceContext->IASetVertexBuffers(0, 1, b->getVertexBuffer(), &stride, &offset);
    			DXCLASSGI.changeRenderTargetToBackBuffer();
    
    			for (std::size_t i = 0; i < b->shaderList.size();i++)
    			{
    				auto vip = SBMGI.getShaderMatMap()[b->shaderList[i]];
    
    				if (b->getVertexBuffer() == nullptr || b->getTexture() == nullptr || vip.vertexShader == nullptr || vip.inputLayout == nullptr || vip.pixelShader == nullptr)
    				{
    					throw "Evil Shit...";//prevent one source for chrashes...
    				}
    
    				if (b->IsClipped())
    				{
    					b->useClipRect();
    				}
    				else
    				{
    					DXCLASSGI.deviceContext->RSSetScissorRects(1, &windowrect);
    				}
    
    				b->constBufferDataList[b->shaderList[i]].ResetCounters();
    				if (i == 0 && (b->shaderList.size() == 3))
    				{
    					b->constBufferDataList[b->shaderList[i]].SetMatrixBuffer(b->m_orthoMatrix);//spezielle RenderTexture Orthomatrix
    				} 
    				else if (i == 1 && (b->shaderList.size() == 3))
    				{
    					b->constBufferDataList[b->shaderList[i]].SetMatrixBuffer(b->m_orthoMatrix);//spezielle RenderTexture Orthomatrix
    				}
    				else
    				{ 
    					b->constBufferDataList[b->shaderList[i]].SetMatrixBuffer();
    				}
    
    				if (b->constBufferDataList[b->shaderList[i]].setConstantBuffersFunc)
    				{
    					b->constBufferDataList[b->shaderList[i]].setConstantBuffersFunc();
    				}
    
    				DXCLASSGI.deviceContext->IASetInputLayout(vip.inputLayout.Get());
    				DXCLASSGI.deviceContext->VSSetShader(vip.vertexShader.Get(), 0, 0);
    				DXCLASSGI.deviceContext->PSSetShader(vip.pixelShader.Get(), 0, 0);
    
    				if (i == 0 && (b->shaderList.size() == 1))
    				{
    					DXCLASSGI.deviceContext->PSSetShaderResources(0, 1, b->getTexture());
    					DXCLASSGI.deviceContext->DrawIndexed(indexCount, 0, 0);
    				}
    				if ((b->shaderList.size() == 3))
    				{
    					if (i == 0)//horizontalblurshader
    					{
    						b->SetRenderTarget();
    						b->SetViewPort();
    						b->ClearRenderTarget();
    						DXCLASSGI.deviceContext->PSSetShaderResources(0, 1, b->getTexture());
    
    						DXCLASSGI.deviceContext->DrawIndexed(indexCount, 0, 0);//1
    
    					}
    					if (i == 1)//anderer shader
    					{
    						b->SetRenderTarget();
    						b->ClearRenderTarget();
    						DXCLASSGI.deviceContext->PSSetShaderResources(0, 1, &b->m_shaderResourceView);
    
    						DXCLASSGI.deviceContext->DrawIndexed(indexCount, 0, 0);//2
    
    					}
    					if (i == 2)//einfacher shader
    					{
                            DXCLASSGI.changeRenderTargetToBackBuffer();
    						DXCLASSGI.ResetViewport();
    						DXCLASSGI.deviceContext->PSSetShaderResources(0, 1, &b->m_shaderResourceView);
    
    						DXCLASSGI.deviceContext->DrawIndexed(indexCount, 0, 0);//3
    					}
    
    				}
    
    			}
    
    		}
    
    		}
    }
    

    Mit einem Shader funktioniert das ganze Wunderbar,nur wenn ich noch nen 2. bzw 3. einfüege klappts nicht.

    Obere Textur hat ein shader,ergebniss wie erwartet.

    Untere Textur geht nicht... (Das Lila kommt vom clearTarget)

    http://img3.fotos-hochladen.net/uploads/testbildtwsbz7ch1f.png

    Wenn jemand ne Idee hat würd mich das echt freuen. 🙂


  • Mod

    d3d debug gibt keine warnings/fehler aus?

    rtt schrieb:

    Mit einem Shader funktioniert das ganze Wunderbar,nur wenn ich noch nen 2. bzw 3. einfüege klappts nicht.

    und mit nur einem pass?

    Obere Textur hat ein shader,ergebniss wie erwartet.
    Untere Textur geht nicht... (Das Lila kommt vom clearTarget)

    du musst aufpassen dass du eine textur nicht gleichzeitig als rendertarget und textur gebunden hast. aber das wuerde dir d3d debug anmeckern. sonst faellt mir nichts auf anhieb auf.

    du koenntst ein renderdoc capture machen udn schauen ob an jeder stelle das passiert was du erwartest.



  • So,erstma vielen Dank für den Hinweis mit dem Debug Layer, wieder was gelernt!:)

    D3D11 WARNING: ID3D11DeviceContext::PSSetShaderResources: Resource being set to PS shader resource slot 0 is still bound on output! Forcing to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]

    ID3D11RenderTargetView* pNullRTV = NULL;
    DXCLASSGI.deviceContext->OMSetRenderTargets(1, &pNullRTV, NULL);
    

    Google meint das ich sowas brauche?
    Bin mir noch nicht ganz Sicher wo das hin gehört...

    mit renderdoc meinst das hier: http://docs.renderdoc.org/html/f2f4fbfa-6127-4831-84e7-07309bd85908.htm ? Werd ich mir definitiv mal anschauen.


  • Mod

    rtt schrieb:

    D3D11 WARNING: ID3D11DeviceContext::PSSetShaderResources: Resource being set to PS shader resource slot 0 is still bound on output! Forcing to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]

    das ist was ich mit
    "du musst aufpassen dass du eine textur nicht gleichzeitig als rendertarget und textur gebunden hast. aber das wuerde dir d3d debug anmeckern. sonst faellt mir nichts auf anhieb auf."
    meinte.

    also eine textur die du nutzen moechtest ist noch als render target angebunden. du kannst aber nicht aus einer textur lesen und gleichzeitig in sie rendern. der fehler sagt dass du genau das machst. das was du ergooglet hast ist nicht zwingen die loesung. denn damit setzt du nur alle rendertargets auf 0, falls du versehentlich vergessen hast eine textur zu unbinden.
    aber ich hab das gefuehl du machst das mit absicht, weil du es nicht wustest dass du es nicht darfst vielleicht?

    es ist also kein programmierfehler den du fixen musst, sondern vermutlich ein resource management fehler 😉
    pass 0 muss in eine temporaere textur rendern
    pass 1 in eine andere und aus der temporaeren samplen

    (ich sehe in deinem source leider nicht was b->SetRendertarget()) fuer daten hat als grundlage, deswegen alles blanke vermutung aus meiner kristalkugel 😉 )



  • Mit Quellcode kann ich dienen *räusper*

    void Basic2DElement::createRenderTexture()
    	{
    
    		D3D11_TEXTURE2D_DESC textureDesc;
    		HRESULT result;
    		D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
    		D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
    		D3D11_TEXTURE2D_DESC depthBufferDesc;
    		D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
    
    		// Initialize the render target texture description.
    		ZeroMemory(&textureDesc, sizeof(textureDesc));
    
    		// Setup the render target texture description.
    		textureDesc.Width = singleSpriteWidth;
    		textureDesc.Height = singleSpriteHeight;
    		textureDesc.MipLevels = 1;
    		textureDesc.ArraySize = 1;
    		textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    		textureDesc.SampleDesc.Count = 1;
    		textureDesc.Usage = D3D11_USAGE_DEFAULT;
    		textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    		textureDesc.CPUAccessFlags = 0;
    		textureDesc.MiscFlags = 0;
    
    		// Create the render target texture.
    		result = DXCLASSGI.device->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture);
    		if (FAILED(result))
    		{
    			throw "FAIL";
    		}
    
    		// Setup the description of the render target view.
    		renderTargetViewDesc.Format = textureDesc.Format;
    		renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
    		renderTargetViewDesc.Texture2D.MipSlice = 0;
    
    		// Create the render target view.
    		result = DXCLASSGI.device->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView);
    		if (FAILED(result))
    		{
    			throw "FAIL";
    		}
    
    		// Setup the description of the shader resource view.
    		shaderResourceViewDesc.Format = textureDesc.Format;
    		shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    		shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
    		shaderResourceViewDesc.Texture2D.MipLevels = 1;
    
    		// Create the shader resource view.
    		result = DXCLASSGI.device->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView);
    		if (FAILED(result))
    		{
    			throw "FAIL";
    		}
    
    		// Initialize the description of the depth buffer.
    		ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
    
    		// Set up the description of the depth buffer.
    		depthBufferDesc.Width = singleSpriteWidth;
    		depthBufferDesc.Height = singleSpriteHeight;
    		depthBufferDesc.MipLevels = 1;
    		depthBufferDesc.ArraySize = 1;
    		depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    		depthBufferDesc.SampleDesc.Count = 1;
    		depthBufferDesc.SampleDesc.Quality = 0;
    		depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    		depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    		depthBufferDesc.CPUAccessFlags = 0;
    		depthBufferDesc.MiscFlags = 0;
    
    		// Create the texture for the depth buffer using the filled out description.
    		result = DXCLASSGI.device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
    		if (FAILED(result))
    		{
    			throw "FAIL";
    		}
    
    		// Initialize the depth stencil view.
    		ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
    
    		// Set up the depth stencil view description.
    		depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    		depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    		depthStencilViewDesc.Texture2D.MipSlice = 0;
    
    		// Create the depth stencil view.
    		result = DXCLASSGI.device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
    		if (FAILED(result))
    		{
    			throw "FAIL";
    		}
    
    		// Setup the viewport for rendering.
    		m_viewport.Width = (float)singleSpriteWidth;
    		m_viewport.Height = (float)singleSpriteHeight;
    		m_viewport.MinDepth = 0.0f;
    		m_viewport.MaxDepth = 1.0f;
    		m_viewport.TopLeftX = 0.0f;
    		m_viewport.TopLeftY = 0.0f;
    
    		// Create an orthographic projection matrix for 2D rendering.
    		XMStoreFloat4x4(&m_orthoMatrix, XMMatrixOrthographicLH(singleSpriteWidth,singleSpriteHeight, 1.0f, 2.0f));
    	}
    
    void Basic2DElement::SetRenderTarget()
    	{
    		// Bind the render target view and depth stencil buffer to the output render pipeline.
    		DXCLASSGI.deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
    	}
    
    void Basic2DElement::SetViewPort()
    	{
           DXCLASSGI.deviceContext->RSSetViewports(1, &m_viewport);
    	}
    
    void Basic2DElement::ClearRenderTarget()
    	{
    		float color[4];
    
    		// Setup the color to clear the buffer to.
    		color[0] = 1;
    		color[1] = 0;
    		color[2] = 1;
    		color[3] = 1;
    	    // Clear the back buffer.
    		DXCLASSGI.deviceContext->ClearRenderTargetView(m_renderTargetView, color);
    
    		// Clear the depth buffer.
    		DXCLASSGI.deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
    	}
    

    Vermutlich besser als die Kristallkugel 😉 Aber ich denke sie ist sehr zuverlässig!
    Okay werd mich heut Abend nochma ransetzen.
    Bin für Hilfe/Tipps jeder Art dankbar.



  • Ich bins nochmal...
    Warning ist weg.

    RenderDoc gibt mir folgendes :

    http://img3.fotos-hochladen.net/uploads/testbild23xsftqr7d5.png

    http://img3.fotos-hochladen.net/uploads/testbild33j9v4urshc.png

    http://img3.fotos-hochladen.net/uploads/testbild4jrc3gozhms.png

    Das Endergebnis ist ja schon mal nicht komplett falsch.
    Es ist verschwommen und gefärbt.(So wie es sein soll)
    Kann das mit der orthoMatrix zusammenhängen?

    XMStoreFloat4x4(&m_orthoMatrix, XMMatrixOrthographicLH(singleSpriteWidth,singleSpriteHeight, 1.0f, 2.0f));
    

    Wenn ich stattdessen:

    XMStoreFloat4x4(&m_orthoMatrix, XMMatrixOrthographicLH((float)W32WINGI.get_clientWidth(), (float)W32WINGI.get_clientHeight(), 1.0f, 2.0f));
    

    einfüge.
    http://img3.fotos-hochladen.net/uploads/testbild5sq70yg9tzm.png


  • Mod

    wofuer brauchst du eine matrix fuer 2d? du kannst doch die vertices genau an die pixelpositionen setzen die du moechtest.



  • 70% meines "Wissens" über DirectX besteht aus:
    Rastertek.com (dort wird das alles immer mit Matrizen gemacht auch in 2D)

    Rest: msdn und andere Seiten.

    Mein Code nimmt sich das "Prinzip" als Grundlage...
    Und versuch das ganze in mein eigenes Gerüst rein zubauen.
    Momentan sinds RenderToTexture,Blur und Glow, die mich beschäftigen.

    Daher auch die Sache mit der OrthoMatrix...

    Wenn ich die Matrizen komplett rausnehme seh ich nix mehr aufm Bildschirm.
    Bin noch blutiger Anfänger,wie man vllt schon gemerkt hat... 🙄
    Soll alles 2D bleiben. 3D brauch ich nicht.

    Naja, auf jedenfall...
    Hast mir schon gut weiter geholfen.
    Finds super was hier geleistet wird auf freiwilliger Basis!Danke!
    Wenn noch Vermutungen hast... bin etwas ratlos...



  • Wollt kurz bescheid geben es funktioniert.
    Musste den ViewPort anpassen 🙂
    Eine Hürde weniger, freue mich auf die nächste!


  • Mod

    rtt schrieb:

    70% meines "Wissens" über DirectX besteht aus...

    sorry, falls meine zeile unfreundlich klang, ich schreibe mal ne zeile hier waehrend etwas compiliert in der arbeit und dann ist es kurz und nicht diplomatisch.

    eigentlich wollte ich nur darauf hin deuten, dass du ja scheinbar DX11 nutzt und darin alles mit shadern gemacht wird, und du somit im shader irgendwo position*matrix machst, kannst du dir das leben einfacher machen indem du einfach nur out.pos=in.pos; machst und auf cpu die koordinaten festlegst.

    aber hast es ja scheinbar in der zwischenzeit zum laufen bekommen live:

    ja, auf zur naechsten huerde 🙂



  • ach, dann hab ich das falsch aufgenommen...
    Okay, verständlich...
    Ja, werd ich ma überdenken mit den Matrizen, wie das auch ohne geht.
    Grad happy das es funktioniert(ändert sich morgen wieder^^)
    Jup, kann jetzt undendlich viele Shader hintereindander klatschen sieht schön aus;)Also werden automatisch x render pass erstellt 😃

    Das nächste große Prob kommt bestimmt, dann bin ich wieder hier,keine Sorge 😛


Anmelden zum Antworten