Jump to content
  • Advertisement
Sign in to follow this  
markypooch

DX11 Bump Mapping....almost

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

Hello all,

 

I'm quite close to getting normal mapping to work with a quad. Using the calculations for the binormals and tangents (which I received from an awesome tutorial) it would appear that I am getting back valid normalized values. However I see nothing on the screen :\

 

There is a lot of code in this question, so I will recommend not to read all of it since I believe the problem lies in the .fx file, i.e. my shaders. So I thought I would bring it to you guys and you can show me the errors of my ways

 

Below is a snippet of code from the function LoadContent:

 

void Tesellator::LoadContent()
{
    //Init the light for the scene
    light.pos = XMFLOAT3(0.0f, 0.0f, 1.0f);
    light.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
    light.ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 0.5f);
 
    //add the inital vertices for my quad
    calcInitVerts();
 
    //calculate the normals, binormals and tangents for my quad
    calcModelVectors();
 
 
    finalVerts verts[6];
 
    //fill in the array of structures to be sent to the vertexBuffer
    for (int i = 0; i <= 5; i++)
    {
        verts[i].pos.x = vertices[i].pos.x;
        verts[i].pos.y = vertices[i].pos.y;
        verts[i].pos.z = vertices[i].pos.z;

        verts[i].tex.x = vertices[i].tex.x;
        verts[i].tex.y = vertices[i].tex.y;
        
        verts[i].norm.x = model[i].norm.x;
        verts[i].norm.y = model[i].norm.y;
        verts[i].norm.z = model[i].norm.z;

        verts[i].tang.x = model[i].tang.x;
        verts[i].tang.y = model[i].tang.y;
        verts[i].tang.z = model[i].tang.z;

        verts[i].binorm.x = model[i].binorm.x;
        verts[i].binorm.y = model[i].binorm.y;
        verts[i].binorm.z = model[i].binorm.z;
    }

    D3D11_BUFFER_DESC vertexDesc;
    ZeroMemory(&vertexDesc, sizeof(D3D11_BUFFER_DESC));
    vertexDesc.BindFlags                        = D3D11_BIND_VERTEX_BUFFER;
    vertexDesc.Usage                            = D3D11_USAGE_DEFAULT;
    vertexDesc.ByteWidth                        = sizeof(finalVerts) * 6;

    D3D11_SUBRESOURCE_DATA resource;
    ZeroMemory(&resource, sizeof(D3D11_SUBRESOURCE_DATA));
    resource.pSysMem                            = verts;

    dev->CreateBuffer(&vertexDesc, &resource, &vertexBuffer);

    WORD indices[] =
    {
        0, 1, 2, 3, 4, 5,
    };

    D3D11_BUFFER_DESC indicesDesc;
    ZeroMemory(&indicesDesc, sizeof(D3D11_BUFFER_DESC));
    indicesDesc.BindFlags                    = D3D11_BIND_INDEX_BUFFER;
    indicesDesc.Usage                        = D3D11_USAGE_DEFAULT;
    indicesDesc.ByteWidth                    = sizeof(WORD) * 6;
    indicesDesc.CPUAccessFlags               = 0;
    resource.pSysMem                         = indices;

    dev->CreateBuffer(&indicesDesc, &resource, &indexBuffer);

    D3D11_BUFFER_DESC constDesc;
    ZeroMemory(&constDesc, sizeof(D3D11_BUFFER_DESC));
    constDesc.BindFlags                     = D3D11_BIND_CONSTANT_BUFFER;
    constDesc.Usage                         = D3D11_USAGE_DEFAULT;
    constDesc.ByteWidth                     = sizeof(XMMATRIX);

    dev->CreateBuffer(&constDesc, 0, &worldCB);
    dev->CreateBuffer(&constDesc, 0, &viewCB);
    dev->CreateBuffer(&constDesc, 0, &projCB);

    constDesc.ByteWidth                    = sizeof(cbPerFrame);
    dev->CreateBuffer(&constDesc, 0, &LightCB);

    projMat = XMMatrixPerspectiveFovLH(XM_PIDIV4, 850.0f / 650.0f, 0.1f, 100.0f);
    projMat = XMMatrixTranspose( projMat );

    D3DX11CreateShaderResourceViewFromFile(dev, L"1.png", NULL, NULL, &colorMap[0], NULL);
    D3DX11CreateShaderResourceViewFromFile(dev, L"2.png", NULL, NULL, &colorMap[1], NULL);
}
 
//Fill out the initial vertices for my quad
void Tesellator::calcInitVerts()
{
    vertices[0].pos  = XMFLOAT3(-1.0f, -1.0f, 0.0f);
    vertices[0].tex  = XMFLOAT2( 0.0f,  1.0f);
    vertices[0].norm = XMFLOAT3(-1.0f, -1.0f, -1.0f);
    vertices[1].pos  = XMFLOAT3(-1.0f, 1.0f, 0.0f);
    vertices[1].tex  = XMFLOAT2(0.0f, 0.0f);
    vertices[1].norm = XMFLOAT3(-1.0f, 1.0f, -1.0f);
    vertices[2].pos  = XMFLOAT3(1.0f, 1.0f, 0.0f);
    vertices[2].tex  = XMFLOAT2(1.0f, 0.0f);
    vertices[2].norm = XMFLOAT3(1.0f, 1.0f, -1.0f);
    vertices[3].pos  = XMFLOAT3(1.0f, 1.0f, 0.0f);
    vertices[3].tex  = XMFLOAT2(1.0f, 0.0f);
    vertices[3].norm = XMFLOAT3(1.0f, 1.0f, -1.0f);
    vertices[4].pos  = XMFLOAT3(1.0f, -1.0f, 0.0f);
    vertices[4].tex  = XMFLOAT2(1.0f, 1.0f);
    vertices[4].norm = XMFLOAT3(1.0f, -1.0f, -1.0f);
    vertices[5].pos  = XMFLOAT3(-1.0f, -1.0f, 0.0f);
    vertices[5].tex  = XMFLOAT2(0.0f, 1.0f);
    vertices[5].norm = XMFLOAT3(-1.0f, -1.0f, -1.0f);
}
 
Now as I said It would APPEAR that I am getting valid normalized values back from the preceding function calls, so I'm not to sure those are the roots of my problem, in fact I think it's the shader which is the code I will show next
 
[code]
 

/////////////
// GLOBALS //
/////////////
Texture2D shaderTextures[2]  : register(t0);
SamplerState SampleType      : register(s0);          

struct Light
{
    float3 dir;
    float4 diffuse;
    float4 ambient;
};

cbuffer LightBuffer     : register(b0)
{
    Light light;
};

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

cbuffer MatrixBuffer2   : register(b1)
{
    matrix viewMatrix;
};

cbuffer MatrixBuffer3  : register(b2)
{
    matrix projectionMatrix;
};



//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
       float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
};

struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 binormal : BINORMAL;
};

PixelInputType BumpMapVertexShader(VertexInputType input)
{
    PixelInputType output;
    

    // Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);
    
    // Store the texture coordinates for the pixel shader.
    output.tex = input.tex;
    
    // Calculate the normal vector against the world matrix only and then normalize the final value.
    output.normal = mul(input.normal, viewMatrix);
    output.normal = normalize(output.normal);

    // Calculate the tangent vector against the world matrix only and then normalize the final value.
    output.tangent = mul(input.tangent, worldMatrix);
    output.tangent = normalize(output.tangent);

    // Calculate the binormal vector against the world matrix only and then normalize the final value.
    output.binormal = mul(input.binormal, worldMatrix);
    output.binormal = normalize(output.binormal);

    return output;
}

////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 BumpMapPixelShader(PixelInputType input) : SV_TARGET
{
    float4 textureColor;
    float4 bumpMap;
    float3 bumpNormal;
    float3 lightDir;
    float lightIntensity;
    float4 color;


    // Sample the texture pixel at this location.
    textureColor = shaderTextures[0].Sample(SampleType, input.tex);
    
    // Sample the pixel in the bump map.
    bumpMap = shaderTextures[1].Sample(SampleType, input.tex);

    // Expand the range of the normal value from (0, +1) to (-1, +1).
    bumpMap = (bumpMap * 2.0f) - 1.0f;
    
    // Calculate the normal from the data in the bump map.
    bumpNormal = input.normal + bumpMap.x * input.tangent + bumpMap.y * input.binormal;
    
    // Normalize the resulting bump normal.
    bumpNormal = normalize(bumpNormal);

    // Calculate the amount of light on this pixel based on the bump map normal value.
    lightIntensity = saturate(dot(bumpNormal, -light.dir));

    // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
    color = saturate(light.diffuse * lightIntensity);

    // Combine the final bump light color with the texture color.
    color = color * textureColor;
    
    return color;
}
 
[/code]
 
Notice in the top of the .fx file I am setting a Texture2D array of 2 elements, one for the image and the normal map of said image.
 
and last but not least the "SetShaders" Function where I bind the structures to Constant Buffers and Set the Shaders.
 
[code]
 
float clearColor[] = {0.0f, 0.0f, 1.0f, 0.0f};
    devcon->ClearRenderTargetView(backBuffer, clearColor);
    devcon->ClearDepthStencilView(depthStencil, D3D11_CLEAR_DEPTH, 1.0f, 0);
 
    //InputAssembler:
    ////////////////////////////////////////
    devcon->IASetInputLayout(inputL);
    devcon->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, offset);
    devcon->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
    devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    devcon->VSSetShader(vsColor, 0, 0);
    devcon->PSSetShader(psColor, 0, 0);
    devcon->PSSetShaderResources(0, 2, colorMap);
    devcon->PSSetSamplers(0, 1, &colorSampler);
    //////////////////////////////////////

    cbPer.light = light;
    devcon->PSSetConstantBuffers(0, 1, &LightCB);
    devcon->UpdateSubresource(LightCB, 0, 0, &cbPer, 0, 0);

    worldMat = XMMatrixIdentity();
    worldMat = XMMatrixTranspose( worldMat );

    rotationMat = XMMatrixRotationRollPitchYaw(0.0f, 0.0f, 0.0f);
    translationMat = XMMatrixTranslation(0.0f, 0.0f, 3.0f);

    viewMat = rotationMat * translationMat;
    viewMat = XMMatrixTranspose( viewMat );

    devcon->VSSetConstantBuffers(0, 1, &worldCB);
    devcon->VSSetConstantBuffers(1, 1, &viewCB);
    devcon->VSSetConstantBuffers(2, 1, &projCB);

    devcon->UpdateSubresource(worldCB, 0, 0, &worldMat, 0, 0);
    devcon->UpdateSubresource(viewCB,  0, 0, &viewMat, 0, 0);
    devcon->UpdateSubresource(projCB,  0, 0, &projMat, 0, 0);
   
    //Draw the quad

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

 

I personally think the root of my problems lies in the shaders but I've been wrong before. As I said I emitted the code where I actually do the calculations for the tangent and binormals since Im getting back what would APPEAR to be valid normalized values.

 

So in conclusion I just would like to know what is it that I am overlooking that is giving me nothing on the screen.

 

-Marcus

Share this post


Link to post
Share on other sites
Advertisement

Nevermind I figured it out :D

 

turns out I wasn't setting the right stride in the IA call for the vertexBuffer

 

Thanks anyways!

 

-Marcus = Extremely Happy

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!