您的位置:首页 > 其它

DirectX 10 学习笔记5:漫射光

2012-12-15 21:52 330 查看
这一节在渲染中加入了光照影响。由于引入了光照,所以所以框架会继续扩展,要加入一个光照类。目前的框架大概可以粗略画成这样:





另外光照的渲染与多边形以及顶点的法线方向关系密切,所以顶点格式也要发生变化:添加一个法线向量。这样调用shader的类中顶点layout、模型类中顶点各成员的赋值也要随之修改。

加入光照后的shader:

加入光照后,shader中的顶点结构改变,增加了法向量,vertex shader和pixel shader的代码都要发生变化,此外光的属性(方向、颜色)是在LightClass对象中设定的,在shader渲染的时候需要知道这两个属性,所以要在shader中添加两个对应的全局变量,technique保持不变:

[code] [code]////////////////////////////////////////////////////////////////////////////////


// Filename: light.fx


////////////////////////////////////////////////////////////////////////////////


 


 


/////////////


// GLOBALS //


/////////////


matrix worldMatrix;


matrix viewMatrix;


matrix projectionMatrix;


Texture2D shaderTexture;


 


float4 diffuseColor;


float3 lightDirection;


 


 


///////////////////


// SAMPLE STATES //


///////////////////


SamplerState SampleType


{


Filter = MIN_MAG_MIP_LINEAR;


AddressU = Wrap;


AddressV = Wrap;


};


 


//////////////


// TYPEDEFS //


//////////////


struct VertexInputType


{


float4 position : POSITION;


float2 tex : TEXCOORD0;


float3 normal : NORMAL;


};


 


struct PixelInputType


{


float4 position : SV_POSITION;


float2 tex : TEXCOORD0;


float3 normal : NORMAL;


};


 


////////////////////////////////////////////////////////////////////////////////


// Vertex Shader


////////////////////////////////////////////////////////////////////////////////


PixelInputType LightVertexShader(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.


output.normal = mul(input.normal, (float3x3)worldMatrix);




// Normalize the normal vector.


output.normal = normalize(output.normal);


 


return output;


}


 


////////////////////////////////////////////////////////////////////////////////


// Pixel Shader


////////////////////////////////////////////////////////////////////////////////


float4 LightPixelShader(PixelInputType input) : SV_Target


{


float4 textureColor;


float3 lightDir;


float lightIntensity;


float4 color;


 


 


// Sample the pixel color from the texture using the sampler at this texture coordinate location.


textureColor = shaderTexture.Sample(SampleType, input.tex);


 


// Invert the light direction for calculations.


lightDir = -lightDirection;


 


// Calculate the amount of light on this pixel.


lightIntensity = saturate(dot(input.normal, lightDir));


 


// Determine the final amount of diffuse color based on the diffuse color combined with the light intensity.


color = saturate(diffuseColor * lightIntensity);


 


// Multiply the texture pixel and the final diffuse color to get the final pixel color result.


color = color * textureColor;


 


return color;


}

[/code]
[/code]

[code]ID3D10EffectVectorVariable* m_lightDirectionPtr;


ID3D10EffectVectorVariable* m_diffuseColorPtr;

[/code]
[/code]

[code]polygonLayout[2].SemanticName = "NORMAL";


polygonLayout[2].SemanticIndex = 0;


polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;


polygonLayout[2].InputSlot = 0;


polygonLayout[2].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;


polygonLayout[2].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;


polygonLayout[2].InstanceDataStepRate = 0;

[/code]
[/code]

此外在初始化的时候还需要获得shader中分别代表光的颜色和方向的全局变量的指针:

[code]
[code]m_lightDirectionPtr = m_effect->GetVariableByName("lightDirection")->AsVector();


m_diffuseColorPtr = m_effect->GetVariableByName("diffuseColor")->AsVector();

[/code]
[/code]

同样,SetShaderParameters函数也要考虑这两个新加入的变量,该函数又增加了两个参数,以及相应的set代码:

[code]
[code]void LightShaderClass::SetShaderParameters(D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix,


ID3D10ShaderResourceView* texture, D3DXVECTOR3 lightDirection, D3DXVECTOR4 diffuseColor)


{


// Set the world matrix variable inside the shader.


m_worldMatrixPtr->SetMatrix((float*)&worldMatrix);


 


// Set the view matrix variable inside the shader.


m_viewMatrixPtr->SetMatrix((float*)&viewMatrix);


 


// Set the projection matrix variable inside the shader.


m_projectionMatrixPtr->SetMatrix((float*)&projectionMatrix);


 


// Bind the texture.


m_texturePtr->SetResource(texture);


 


// Set the direction of the light inside the shader.


m_lightDirectionPtr->SetFloatVector((float*)&lightDirection);


 


// Set the diffuse color of the light inside the shader.


m_diffuseColorPtr->SetFloatVector((float*)&diffuseColor);


 


return;


}

[/code]
[/code]

ModelClass的变化:

顶点格式:

[code]
[code]struct VertexType


{


D3DXVECTOR3 position;


D3DXVECTOR2 texture;


D3DXVECTOR3 normal;


};

[/code]
[/code]

设置vertex array现在也要考虑到法向量:

[code]
[code]// Load the vertex array with data.


vertices[0].position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);  // Bottom left.


vertices[0].texture = D3DXVECTOR2(0.0f, 1.0f);


vertices[0].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);


 


vertices[1].position = D3DXVECTOR3(0.0f, 1.0f, 0.0f);  // Top middle.


vertices[1].texture = D3DXVECTOR2(0.5f, 0.0f);


vertices[1].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);


 


vertices[2].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);  // Bottom right.


vertices[2].texture = D3DXVECTOR2(1.0f, 1.0f);


vertices[2].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);

[/code]
[/code]

新增加的光照类:

目前只考虑光照的颜色和方向,所以这个类比较简单:

[code]
[code]////////////////////////////////////////////////////////////////////////////////


// Filename: lightclass.h


////////////////////////////////////////////////////////////////////////////////


#ifndef _LIGHTCLASS_H_


#define _LIGHTCLASS_H_


 


 


//////////////


// INCLUDES //


//////////////


#include <d3dx10math.h>


 


 


////////////////////////////////////////////////////////////////////////////////


// Class name: LightClass


////////////////////////////////////////////////////////////////////////////////


class LightClass


{


public:


LightClass();


LightClass(const LightClass&);


~LightClass();


 


void SetDiffuseColor(float, float, float, float);


void SetDirection(float, float, float);


 


D3DXVECTOR4 GetDiffuseColor();


D3DXVECTOR3 GetDirection();


 


private:


D3DXVECTOR4 m_diffuseColor;


D3DXVECTOR3 m_direction;


};


 


#endif

[/code]
实现:[/code]

[code]
[code]////////////////////////////////////////////////////////////////////////////////


// Filename: lightclass.cpp


////////////////////////////////////////////////////////////////////////////////


#include "lightclass.h"


 


 


LightClass::LightClass()


{


}


 


 


LightClass::LightClass(const LightClass& other)


{


}


 


 


LightClass::~LightClass()


{


}


 


 


void LightClass::SetDiffuseColor(float red, float green, float blue, float alpha)


{


m_diffuseColor = D3DXVECTOR4(red, green, blue, alpha);


return;


}


 


 


void LightClass::SetDirection(float x, float y, float z)


{


m_direction = D3DXVECTOR3(x, y, z);


return;


}


 


 


D3DXVECTOR4 LightClass::GetDiffuseColor()


{


return m_diffuseColor;


}


 


 


D3DXVECTOR3 LightClass::GetDirection()


{


return m_direction;


}

[/code]
[/code]

视图类的变化:

在视图类中添加了LightClass指针成员,用于设置光照:

[code]
[code]LightClass* m_Light;

[/code]
[/code]

在InitializeShader中创建光照对象,并设置颜色和照明方向:

[code]
[code]// Create the light object.


m_Light = new LightClass;


if(!m_Light)


{


return false;


}


// Initialize the light object.


m_Light->SetDiffuseColor(1.0f, 0.0f, 1.0f, 1.0f);


m_Light->SetDirection(0.0f, 0.0f, 1.0f);

[/code]
[/code]

最后,OnPaint函数中调用LightShaderClass的Render函数进行绘制:

[code]
[code]m_LightShader->Render(m_device, pmesh->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, pmesh->GetTexture(),


m_Light->GetDirection(), m_Light->GetDiffuseColor());

[/code]
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: