demo
PBR直接光源
- 顾名思义:直接光源指有光源直接照射到点p 的辐射强度,由于一个光源只会有一个光线wi影响点p,所以和之前的计算没什么差异
- 对于影响p的光源,并不需要积分计算半球形辐照度,遍历每个影响点p的光源计算辐射率(单一方向的影响),再将所有光源求和计算,
- 最后考虑BRDF来缩放辐射率
- 但这次需要按照PBR的方程,计算出基于物理模型的渲染图元
F0
,被称为0°入射角的基础反射率,会随着与平面法线的夹角增加而增大
球体(顶点数据):
//4096个顶点,绘制整个球体,按照经度半圈半圈,自上到下绘制,最后所有经度线都离散的绘制了
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)//纬度有64个顶点
{
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)//每个经度半圈有64个顶点
{
float xSegment = (float)x / (float)X_SEGMENTS;//分隔绕y轴的角度
float ySegment = (float)y / (float)Y_SEGMENTS;//分隔绕x或z的角度,
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);//弧度制
float yPos = std::cos(ySegment * PI);//
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);//
s_SphereData.positions.push_back(glm::vec3(xPos, yPos, zPos));
s_SphereData.uv.push_back(glm::vec2(xSegment, ySegment));
s_SphereData.normals.push_back(glm::vec3(xPos, yPos, zPos));
}
}
//上面仅仅是绘制了平面的4个顶点,实则需要6个顶点,
for (int i = 0; i < Y_SEGMENTS; i++)//第0个顶点和第65个顶点对齐,相邻的维度,绘制3角形
{
for (int j = 0; j < X_SEGMENTS; j++)
{
s_SphereData.indices.push_back(i * (X_SEGMENTS + 1) + j);
s_SphereData.indices.push_back((i + 1) * (X_SEGMENTS + 1) + j);
s_SphereData.indices.push_back((i + 1) * (X_SEGMENTS + 1) + j + 1);
s_SphereData.indices.push_back(i * (X_SEGMENTS + 1) + j);
s_SphereData.indices.push_back((i + 1) * (X_SEGMENTS + 1) + j + 1);
s_SphereData.indices.push_back(i * (X_SEGMENTS + 1) + j + 1);
}
}
s_SphereData.indexCount = static_cast<unsigned int>(s_SphereData.indices.size());
//data将每个顶点的三个数据和为一个-》最终每个顶点的数据
for (unsigned int i = 0; i < s_SphereData.positions.size(); ++i)
{
s_SphereData.data.push_back( s_SphereData.positions[i].x);
s_SphereData.data.push_back( s_SphereData.positions[i].y);
s_SphereData.data.push_back( s_SphereData.positions[i].z);
if (s_SphereData.normals.size() > 0)
{
s_SphereData.data.push_back( s_SphereData.normals[i].x);
s_SphereData.data.push_back( s_SphereData.normals[i].y);
s_SphereData.data.push_back( s_SphereData.normals[i].z);
}
if (s_SphereData.uv.size() > 0)
{
s_SphereData.data.push_back( s_SphereData.uv[i].x);
s_SphereData.data.push_back( s_SphereData.uv[i].y);
}
}