博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DirectX 10 学习笔记5:漫射光
阅读量:6091 次
发布时间:2019-06-20

本文共 6482 字,大约阅读时间需要 21 分钟。

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

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

加入光照后的shader:

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

 
// 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;
}
负责加载shader的LightShaderClass:
调用shader的类(上一篇笔记中的TextureShaderClass)没有发生太多变化,由于shader中增加了描述光照的两个全局变量,所以在该类中需要添加两个指针成员,用来指向那两个成员变量:
ID3D10EffectVectorVariable* m_lightDirectionPtr;
ID3D10EffectVectorVariable* m_diffuseColorPtr;
由于顶点格式发生了变化(增加了法向量),所以在该类的初始化函数中,需要对layout进行相应的调整:
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;

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

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

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

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;
}

ModelClass的变化:

顶点格式:

struct VertexType
{
D3DXVECTOR3 position;
D3DXVECTOR2 texture;
D3DXVECTOR3 normal;
};

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

// 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);

新增加的光照类:

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

 
// Filename: lightclass.h
 
#ifndef _LIGHTCLASS_H_
#define _LIGHTCLASS_H_
 
 
//
// INCLUDES //
//
#include 
 
 
 
// 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
实现:
 
// 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;
}

视图类的变化:

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

LightClass* m_Light;

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

// 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);

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

m_LightShader->Render(m_device, pmesh->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, pmesh->GetTexture(),
m_Light->GetDirection(), m_Light->GetDiffuseColor());

转载于:https://www.cnblogs.com/youthlion/archive/2012/12/15/2819835.html

你可能感兴趣的文章
Java编程常见问题汇总(四)
查看>>
Hadoop 学习系列(四)之 MapReduce 原理讲解
查看>>
函数throttle、debounce介绍
查看>>
源码阅读:SDWebImage(三)——NSData+ImageContentType
查看>>
十六、类的真正形态
查看>>
spring-cloud Sleuth
查看>>
Python 进阶之路 (十一) 再立Flag, 社区最全的itertools深度解析(下)
查看>>
微信分享,二次分享(移动web端)
查看>>
蚂蚁金服智能推荐引擎解决方案与实践
查看>>
PC比电脑好玩的秘密是什么?答案就是因为有这些神奇的网站!
查看>>
30秒的PHP代码片段(2)数学 - Math
查看>>
助力中文文字识别突破,美团公开首个真实场景招牌图像数据集
查看>>
IOS常用框架集合
查看>>
Laravel 深入核心系列教程
查看>>
webpack 性能提速
查看>>
一次下载多个文件的解决思路-JS
查看>>
记录使用Vue相关API开发项目时遇到的问题难点整理(不定时更新)
查看>>
《Java8实战》-第五章读书笔记(使用流Stream-02)
查看>>
vue轮播图插件之vue-awesome-swiper
查看>>
Cabloy.js:基于EggBorn.js开发的一款顶级Javascript全栈业务开发框架
查看>>