DirectX11 学习笔记8 - 最简单的光照
在上一个列子的基础上加了一个地面。这个地面是光照效果生成的。
看图:
先说明:
光照 须要重写一个 lightshader 就是光照的渲染器
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
你会发现之前的第二行是Color而不是如今的Normal 。 由于光照的颜色是有外界 环境光 透射光 漫反射光 形成的。
这些光的计算所有写在一个效果文件lightShader.fx里面
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer ConstantBuffer
{
matrix World;
matrix View;
matrix Projection;
};
cbuffer LightBuffer
{
float3 cameraPosition;
float padding;
};
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 Pos : POSITION;
float3 Normal : NORMAL;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
}; //--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input )
{
VS_OUTPUT output = (VS_OUTPUT)0;
float4 worldPosition;
// 改变顶点为四个分量其次坐标.
input.Pos.w = 1.0f;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
// 世界坐标系中的顶点法向.
float3 N = mul(input.Normal, (float3x3)World);
N = normalize(N);
//世界坐标系顶点位置
float3 P = output.Pos.xyz; //自发射颜色
float3 emissive = float3(0.0, 0.0, 0.0); //计算环境光
float3 ambient = float3(0.3, 0.3, 0.3); //计算漫反射光
float3 L = normalize(float3(-1.0, -1.0, 1.0));
float diffuseLight = max(dot(N, L), 0);
float3 diffuse = diffuseLight; //计算高光
float3 V = normalize(cameraPosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), 5.0); if (diffuseLight <= 0)
specularLight = 0;
float3 specular = specularLight; output.Color.xyz = emissive + ambient + diffuse + specular;
// float3 tt = float3(1.0, 0.0, 0.0);
// output.color.xyz = float3(1.0, 0.0, 0.0);
output.Color.w = 1.0f; return output;
} //--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_OUTPUT input ) : SV_Target
{
return input.Color;
}
主要就是顶点输入进行复杂的光照计算,龙书上有。还多了一个缓冲区
cbuffer LightBuffer
{
float3 cameraPosition;
float padding;
};
眼下仅仅存了光照的颜色 主要 要为4的倍数 对齐float地址
//create the light buffer
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(LightBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = device->CreateBuffer( &bd, NULL, &m_lightmaterialBuffer );
if( FAILED( hr ) )
return hr;
光照渲染文件中面的缓冲区创建
//
// Update variables
//
ConstantBuffer cb;
cb.mWorld = XMMatrixTranspose( worldMatrix);
cb.mView = XMMatrixTranspose( viewMatrix );
cb.mProjection = XMMatrixTranspose( projectionMatrix );
deviceContext->UpdateSubresource( m_matrixBuffer, 0, NULL, &cb, 0, 0 );
deviceContext->VSSetConstantBuffers( 0, 1, &m_matrixBuffer );
LightBuffer lb;
lb.cameraPosition=cameraPos;
deviceContext->UpdateSubresource( m_lightmaterialBuffer, 0, NULL, &lb, 0, 0 );
deviceContext->VSSetConstantBuffers( 1, 1, &m_matrixBuffer );
比曾经多了一个缓冲区更新。
有了光照效果文件 光照渲染器 还差一个承载物
这里是一个四边形,作为大地吧
PlaneModel.h
#pragma once
#include "XComm.h"
class PlaneModel
{
protected:
struct SimpleVertexN
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
};
public://顶点缓冲和顶点索引缓冲
ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
int m_vertexCount, m_indexCount;
public:
PlaneModel():m_vertexCount(0),m_indexCount(0){};
bool init(ID3D11Device*);
void close();
void render(ID3D11DeviceContext*);
};
基本跟之前立方体的方法是一摸一样的 仅仅只是把color颜色换成了法向normal
PlaneModel.cpp
#include "PlaneModel.h"
bool PlaneModel::init(ID3D11Device* device)
{
SimpleVertexN* vertices;
unsigned long* indices;
D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
HRESULT result; //首先,我们创建2个暂时缓冲存放顶点和索引数据,以便后面使用。. // 设置顶点缓冲大小为4,一个平面.
m_vertexCount = 4; // 设置索引缓冲大小.,两个三角形
m_indexCount = 6; // 创建顶点暂时缓冲.
vertices = new SimpleVertexN[m_vertexCount];
if(!vertices)
{
return false;
} // 创建索引缓冲.
indices = new unsigned long[m_indexCount];
if(!indices)
{
return false;
}
//创建顺时针方向的三角形,左手规则
// 设置顶点数据.
vertices[0].Pos = XMFLOAT3(-50.0f, -3.0f, -50.0f);
vertices[0].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f); vertices[1].Pos = XMFLOAT3(-50.0f,-3.0f, 50.0f);
vertices[1].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f); vertices[2].Pos = XMFLOAT3(50.0f, -3.0f, 50.0f);
vertices[2].Normal= XMFLOAT3(0.0f, 1.0f, 0.0f); vertices[3].Pos = XMFLOAT3(50.0f, -3.0f, -50.0f);
vertices[3].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f); // 设置索引缓冲数据.
indices[0] = 0; // 前面
indices[1] = 1;
indices[2] = 2;
indices[3] = 0;
indices[4] = 2;
indices[5] = 3; // 设置顶点缓冲描写叙述
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(SimpleVertexN) * m_vertexCount;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0; // 指向保存顶点数据的暂时缓冲.
vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0; // 创建顶点缓冲.
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
if(FAILED(result))
{
HR(result);
return false;
} // 设置索引缓冲描写叙述.
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0; // 指向存暂时索引缓冲.
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0; // 创建索引缓冲.
result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
if(FAILED(result))
{
HR(result);
return false;
} // 释放暂时缓冲.
delete [] vertices;
vertices = 0; delete [] indices;
indices = 0;
}
void PlaneModel::close()
{
// 释放顶点缓冲.
if(m_indexBuffer)
{
m_indexBuffer->Release();
m_indexBuffer = 0;
} // 释放索引缓冲
if(m_vertexBuffer)
{
m_vertexBuffer->Release();
m_vertexBuffer = 0;
}
}
void PlaneModel::render(ID3D11DeviceContext* deviceContext)
{
unsigned int stride;
unsigned int offset; // 设置顶点缓冲跨度和偏移.
stride = sizeof(SimpleVertexN);
offset = 0; //在input assemberl阶段绑定顶点缓冲,以便可以被渲染
deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); //在input assemberl阶段绑定索引缓冲。以便可以被渲染
deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); // 设置体元语义,渲染三角形列表.
//注意这里和XModel不一样
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
DirectX11 学习笔记8 - 最简单的光照的更多相关文章
- Directx11学习笔记【一】 最简单的windows程序HelloWin
声明:本系列教程代码有部分来自dx11龙书及dx11游戏编程入门两本书,后面不再说明 首先,在vs2013中创建一个空的解决方案Dx11Demo,以后的工程都会放在这个解决方案下面.然后创建一个win ...
- Directx11学习笔记【二十二】 用高度图实现地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第八章:光照
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第八章:光照 代码工程地址: https://github.com/j ...
- Directx11学习笔记【二十一】 封装键盘鼠标响应类
原文:Directx11学习笔记[二十一] 封装键盘鼠标响应类 摘要: 本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/ ...
- Directx11学习笔记【二】 将HelloWin封装成类
我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...
- Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息
</pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...
- Spring MVC 学习笔记9 —— 实现简单的用户管理(4)用户登录显示局部异常信息
Spring MVC 学习笔记9 -- 实现简单的用户管理(4.2)用户登录--显示局部异常信息 第二部分:显示局部异常信息,而不是500错误页 1. 写一个方法,把UserException传进来. ...
- Spring MVC 学习笔记8 —— 实现简单的用户管理(4)用户登录
Spring MVC 学习笔记8 -- 实现简单的用户管理(4)用户登录 增删改查,login 1. login.jsp,写在外面,及跟WEB-INF同一级目录,如:ls Webcontent; &g ...
- Directx11学习笔记【九】 3D渲染管线
原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...
随机推荐
- 从flappy bird中论优化
前两天刚刚做完2014年noipD1T3飞扬的小鸟 其实这道题本身并不是一道很难的DP 状态容易想到,转移也容易想到 但是出于我的基础较差,还是出了较大的偏差 Problem: Flappy Bird ...
- debug时红点消失
问题描述:debug时红色断点和黄色小箭头不见,而用行代码高亮的形式时. 解决办法:可以用设置 工具 => 选项 => 文本编辑器 => 指示器边距 勾上选项
- Java——Spring介绍
spring 是一个开源框架,是为了解决企业应用程序开发. 功能如下:1.目的:解决企业应用开发的复杂性.2.功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能.3.范围:任何Ja ...
- Ajax——php基础知识(三)
上传文件 1.get是传不了文件的,只能用post 2.enctype需要重新设置,默认是application/x-www-form-urlencoded,会在发送到服务器之前,所有字符都会进行编码 ...
- SSH整合框架+mysql简单的实现
SSH整合框架+mysql简单的实现 1. 框架整合原理: struts2整合Spring 两种: 一种struts2自己创建Action,自动装配Service : 一种 将Action交给Spri ...
- Android ExpandableListView的使用详解
ExpandableListView(可扩展的ListView) ExpandableListVivew是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组 ...
- O-理解共享池
我们可以通过show sga命令查看共享池的整体组成部分: ....待截图.... 一.SGA内存结构 Oracle中SGA主要包括: 1.固定数据结构部分(FIXED Size) 2.数据块缓冲区( ...
- 2016.01.07 DOM笔记(二) DOM节点
node节点属性 nodeName属性 oneBox= document.getElementsById('box');var s = oneBox.nodeName; //nodeName与tag ...
- js的replace, 高亮
";console.log(str.replace(/\,/g, "")); //输出 123 ";console.log(str);//输出123 " ...
- echarts图表初始大小问题及echarts随窗口变化自适应
最近在做一个轮播图,使用的是element的Carousel走马灯,每一个走马灯里是eachrts图,开始页面加载的时候发现echarts图并不能自适应,开始以为是走马灯的问题,后来发现不是 不知道大 ...