Bump Mapping....almost

Started by
1 comment, last by markypooch 10 years, 9 months ago

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

Advertisement

I apologize it would appear I misused the

tags :p

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

This topic is closed to new replies.

Advertisement