Hello,
I'm working parallell on my tower pc and my notebook. Yesterday I finally implemented my deferred rendering-system, which works fine on the tower. When cloning my repo on the notebook however, nothing shows up. Those are the steps I already took to debug (in PIX):
- I made sure that the cube actually gets rendered and transformed correctly.
- The g-buffer render-targets are set correctly.
- There is no output to the 3 g-buffer rts. "Debug this pixel" shows that the pixel is black, then it gets cleared to black (before the rendering), and then nothing.
- All rendertargets, camera etc... are correctly sized to the backbuffer (my app takes care of that automatically).
So uhm... since my notebook has an Ati graphics card I cannot use NVPerfStudio to debug it in detail like I normally would. GpuPerfStudio 1.2 seems to lack a d3d-server, so thats out of the question too. Let me give you a quick insight on my two effect files I use to render.
The effect used to render my cube:
/*
% Base shader for rendering 3D models
% Renders to a g-buffer
keywords: material classic
date: 120129
*/
float4x4 World : World;
shared float4x4 ViewProj;
texture2D Material;
texture2D Bump;
sampler MaterialSampler = sampler_state
{
Texture = <Material>;
MagFilter = Linear;
MinFilter = Anisotropic;
MipFilter = Linear;
MaxAnisotropy = 16;
};
sampler BumpSampler = sampler_state
{
Texture = <Bump>;
MagFilter = Linear;
MinFilter = Linear;
MipFilter = Linear;
};
struct VS_INPUT
{
float4 vPos : POSITION0;
float2 vTex0 : TEXCOORD0;
float3 vNrm : NORMAL0;
float3 vTan : TANGENT0;
float3 vBin : BINORMAL0;
};
struct VS_OUTPUT
{
float4 vPos : POSITION0;
float4 vPos1 : POSITION1;
float2 vTex0 : TEXCOORD0;
float3x3 mTBN : TEXCOORD1;
};
struct PS_OUTPUT
{
float4 vMat : COLOR0;
float4 vPos : COLOR1;
float4 vNrm :COLOR2;
};
VS_OUTPUT mainVS(VS_INPUT i)
{
VS_OUTPUT o;
float4x4 WorldViewProj = mul(World,ViewProj);
o.vPos = mul(i.vPos, WorldViewProj);
o.vPos1 = mul(i.vPos, World);
o.vTex0 = i.vTex0;
float3 N = normalize(mul(i.vNrm, World));
float3 T = normalize(mul(i.vTan, World));
float3 B = normalize(mul(i.vBin, World));
o.mTBN = float3x3(T, B, N);
return o;
}
PS_OUTPUT mainPS(VS_OUTPUT i)
{
PS_OUTPUT o;
o.vMat = tex2D(MaterialSampler,i.vTex0);
o.vPos = i.vPos1;
o.vNrm = tex2D(BumpSampler, i.vTex0);
o.vNrm.rgb = 2.0* o.vNrm.rgb - 1.0;
o.vNrm.rgb = mul(o.vNrm.rgb, i.mTBN);
o.vNrm.rgb = normalize(o.vNrm.rgb);
o.vNrm.rgb = 0.5 * o.vNrm.rgb + 0.5;
o.vNrm.a = 1.0f;
return o;
}
technique technique0 {
pass p0 {
CullMode = Ccw;
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
}
The effect for the lights:
/*
% Shader for performing deferred lighting
% Renders: ambient
keywords: light deferred
date: 120202
*/
/*
Ambient Paramters
*/
float3 cAmbientColor;
shared texture2D cMaterial;
sampler cMaterialSampler = sampler_state
{
Texture = <cMaterial>;
MagFilter = Point;
MinFilter = Point;
MipFilter = Point;
};
/*
Directional Paramters
*/
float3 cLightDirection;
float3 cCameraPos;
float3 cDiffuseColor;
float3 cSpecularColor;
shared texture2D cNormal;
sampler cNormalSampler = sampler_state
{
Texture = <cNormal>;
MagFilter = Point;
MinFilter = Point;
MipFilter = Point;
};
shared texture2D cPosition;
sampler cPositionSampler = sampler_state
{
Texture = <cPosition>;
MagFilter = Point;
MinFilter = Point;
MipFilter = Point;
};
/*
Primitive Vertex Shader
*/
struct VS_INPUT
{
float3 vPos : POSITION0;
float2 vTex0 : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 vPos : POSITION0;
float2 vTex0 : TEXCOORD0;
};
struct PS_OUTPUT
{
float4 vMat : COLOR0;
float4 vPos : COLOR1;
float4 vNrm :COLOR2;
};
VS_OUTPUT vsQuad(VS_INPUT i)
{
VS_OUTPUT o;
o.vPos = float4(i.vPos,1.0);
o.vTex0 = i.vTex0;
return o;
}
/*
Ambient Lighting
*/
float4 psAmbient(VS_OUTPUT i) : COLOR0
{
float4 vDiffuseMaterial;
vDiffuseMaterial.rgb = tex2D(cMaterialSampler, i.vTex0).rgb;
vDiffuseMaterial.rgb *= cAmbientColor;
vDiffuseMaterial.a = 1.0;
return vDiffuseMaterial;
};
technique Ambient {
pass p0 {
CullMode = None;
ZEnable = false;
AlphaBlendEnable = true;
Srcblend = One;
Destblend = One;
VertexShader = compile vs_3_0 vsQuad();
PixelShader = compile ps_3_0 psAmbient();
}
}
/*
Directional Lighting
*/
float4 psDirectional(VS_OUTPUT i) : COLOR0
{
float3 vDiffuseMaterial;
vDiffuseMaterial.rgb = tex2D(cMaterialSampler, i.vTex0).rgb;
float4 vWorldNrm = tex2D(cNormalSampler, i.vTex0);
vWorldNrm.rgb = 2.0 * vWorldNrm.rgb - 1.0;
float3 vWorldPos = tex2D(cPositionSampler, i.vTex0).rgb;
float3 vCameraDir = cCameraPos - vWorldPos;
float3 vLightDir = normalize(cLightDirection);
float3 vDiffuseIntensity = max(0, dot(vLightDir, vWorldNrm));
float3 Reflect = normalize(2 * -vDiffuseIntensity * vWorldNrm - vLightDir);
float shadow = saturate(4* vDiffuseIntensity);
float4 specular = max(pow(dot(Reflect, normalize(-vCameraDir)), 32), 0); // R.V^n
float4 color;
color.rgb = shadow * (vDiffuseIntensity * cDiffuseColor.xyz * vDiffuseMaterial.rgb + specular * cSpecularColor.xyz);
color.a = 1.0;
return color;
};
technique Directional {
pass p0 {
CullMode = None;
ZEnable = false;
AlphaBlendEnable = true;
Srcblend = One;
Destblend = One;
VertexShader = compile vs_3_0 vsQuad();
PixelShader = compile ps_3_0 psDirectional();
}
}
Then, let me show you my (temporary) code for rendering the cube and my lights:
#pragma once
#include "SystemManager.h"
#include "Components.h"
class DeferredRenderSystem : public EntitySystem<DeferredRenderSystem>
{
public:
DeferredRenderSystem(Gfx3D& gfx3D): m_pGfx3D(&gfx3D) {};
void Update(EntityManager& entityManager)
{
//todo: HUGE cleanup
EntityManager::entityVector* vEntities = entityManager.EntitiesWithComponents<ModelComponent, PositionComponent>();
Camera camera;
D3DXMATRIX matrix;
D3DXMatrixIdentity(&matrix);
Effect* effect;
Model* model;
Material* material;
// set g-buffer
//todo: implement "ClearAllBound"
m_pGfx3D->Clear3DRenderTarget(RenderTargets::DEFERRED_POSITION);
m_pGfx3D->Clear3DRenderTarget(RenderTargets::DEFERRED_MATERIAL);
m_pGfx3D->Clear3DRenderTarget(RenderTargets::DEFERRED_NORMAL);
m_pGfx3D->Set3DRenderTarget(0, RenderTargets::DEFERRED_MATERIAL);
m_pGfx3D->Set3DRenderTarget(1, RenderTargets::DEFERRED_POSITION);
m_pGfx3D->Set3DRenderTarget(2, RenderTargets::DEFERRED_NORMAL);
for(auto entity : *vEntities)
{
PositionComponent* pos = entity->GetComponent<PositionComponent>();
ModelComponent* mod = entity->GetComponent<ModelComponent>();
effect = m_pGfx3D->GetEffect(mod->m_effect);
model = m_pGfx3D->GetModel(mod->m_model);
material = m_pGfx3D->GetMaterial(mod->m_material);
effect->SetMatrix("ViewProj", camera.GetViewProjectionMatrix());
effect->SetTexture("Material", material->GetTexture());
effect->SetTexture("Bump", material->GetBumpMap());
D3DXMatrixTranslation(&matrix, pos->m_x, pos->m_y, pos->m_z);
effect->SetMatrix("World", matrix);
effect->Begin();
model->Render();
effect->End();
}
delete vEntities;
//unbind g-buffer
m_pGfx3D->Set3DRenderTarget(0, RenderTargets::BACKBUFFER);
m_pGfx3D->Set3DRenderTarget(1, RenderTargets::BACKBUFFER);
m_pGfx3D->Set3DRenderTarget(2, RenderTargets::BACKBUFFER);
}
private:
Gfx3D* m_pGfx3D;
};
class DeferredLightSystem : public EntitySystem<DeferredLightSystem>
{
public:
DeferredLightSystem(Gfx3D& gfx3D): m_pGfx3D(&gfx3D) {};
void Update(EntityManager& entityManager)
{
m_pGfx3D->Clear3DRenderTarget(RenderTargets::FINAL_SCENE);
m_pGfx3D->Set3DRenderTarget(0, RenderTargets::FINAL_SCENE);
//ambient
EntityManager::entityVector* vEntities = entityManager.EntitiesWithComponents<AmbientComponent>();
Effect* pEffect = m_pGfx3D->GetEffect(L"Light.fx");
if(vEntities->size() != 0)
{
pEffect->SetTechnique("Ambient");
for(auto entity: *vEntities)
{
AmbientComponent* pComponent = entity->GetComponent<AmbientComponent>();
FColor color = pComponent->m_ambient;
pEffect->SetFloat3("cAmbientColor", color.r, color.g, color.b);
pEffect->SetTexture("cMaterial", m_pGfx3D->Get3DRenderTarget(RenderTargets::DEFERRED_MATERIAL));
pEffect->Begin();
m_pGfx3D->RenderScreen();
pEffect->End();
}
}
delete vEntities;
//directional
vEntities = entityManager.EntitiesWithComponents<DirectionComponent, DiffuseComponent, SpecularComponent>();
pEffect = m_pGfx3D->GetEffect(L"Light.fx");
if(vEntities->size() != 0)
{
pEffect->SetTechnique("Directional");
//todo: real camera
pEffect->SetFloat3("cCameraPos", 10.0f, 0.0f, 0.0f);
for(auto entity: *vEntities)
{
DirectionComponent* pDirection = entity->GetComponent<DirectionComponent>();
pEffect->SetFloat3("cLightDirection", pDirection->m_x, pDirection->m_y, pDirection->m_z);
//diffuse component
FColor color = entity->GetComponent<DiffuseComponent>()->m_diffuse;
pEffect->SetFloat3("cDiffuseColor", color.r, color.g, color.b);
//specular component
FColor specularColor = entity->GetComponent<SpecularComponent>()->m_specular;
pEffect->SetFloat3("cSpecularColor", specularColor.r, specularColor.g, specularColor.b);
//set g-buffer
pEffect->SetTexture("cMaterial", m_pGfx3D->Get3DRenderTarget(RenderTargets::DEFERRED_MATERIAL));
pEffect->SetTexture("cPosition", m_pGfx3D->Get3DRenderTarget(RenderTargets::DEFERRED_POSITION));
pEffect->SetTexture("cNormal", m_pGfx3D->Get3DRenderTarget(RenderTargets::DEFERRED_NORMAL));
//render
pEffect->Begin();
m_pGfx3D->RenderScreen();
pEffect->End();
}
}
delete vEntities;
//unbind g-buffer
m_pGfx3D->Set3DRenderTarget(0, RenderTargets::BACKBUFFER);
pEffect->SetTexture("cMaterial", NULL);
pEffect->SetTexture("cNormal", NULL);
pEffect->SetTexture("cPosition", NULL);
};
private:
Gfx3D* m_pGfx3D;
};
Other than that, no device render states etc... are set. The backbuffer and z-buffer is cleared afterwards, begin() and end() is applied correctly, as my gui using the LPD3DXSPRITE is working properly (see attachment).
So, I know this is probably even harder to tell than for me, but do you have any other idea what could be failing here? Using PIX I determined that almost everything is correct, there just is no output to my g-buffers... I'm pretty desperate after 3 hours of successless debugging, so any idea would be highly appreciated!