反射模型在使用 glColor3f 的 OpenGl 中无法正常工作
Reflection model does not work correctly in OpenGl using glColor3f
我有一张 480x640 二维双阵列深度图。我使用 glBegin(GL_TRIANGLES) 使用 openGL 将其可视化。
这是我的代码,它工作正常:
int main(int argc, char** argv){
ifstream ifs("D:\DepthMaps1-20\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3f(189.0/255.0, 140.0 / 255.0, 194.0 / 255.0);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j+1] != 0)
{
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;}
所以现在我需要使用数学公式为反射模型添加光照。想法是 - 照明被视为具有相同强度的平行(单向)光束,光源的大小不受限制。照明由方向 L [Lx Ly Lz] 设置。
这是我的 Lambert 反射模型代码,它可以工作,但我想要更好的结果。
float coord = -1.0f;
float coord1 = -1.0f;
float coord2 = -0.0f;
float coord4 = -1.0f;
float coord5 = -2.0f;
float coord6 = -1.0f;
int main(int argc, char** argv)
{
ifstream ifs("D:\DepthMaps1-20\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
vector<vector<int>> brightness(height, vector<int>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(tippangle, 1, 0, 0);
glRotatef(viewangle, 0, 1, 0);
glScalef(scaleF, scaleF, scaleF);
//x
glRasterPos3f(1.1, 0.0, 0.0);
//y
glRasterPos3f(0.0, 1.1, 0.0);
//z
glRasterPos3f(0.0, 0.0, 1.1);
glTranslatef(d[0], d[1], d[2]);
glBegin(GL_TRIANGLES);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j + 1] != 0)
{
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
glm::vec3 normal = glm::normalize(glm::cross(left, right));
glm::vec3 Position_Light = glm::vec3(coord + 0, coord1+ 0, coord2 + 0); //Light source
glm::vec3 Position_View = glm::vec3(coord4, coord5, coord6); //observer
glm::vec3 Position_Point = glm::vec3(x[i][j], y[i][j], z[i][j]);
//Directions
glm::vec3 Light_Direction = glm::normalize(Position_Light - Position_Point); //To source
glm::vec3 View_Direction = glm::normalize(Position_View - Position_Point); // To the observer
glm::vec3 HalfWay_Direction = glm::normalize(Light_Direction + View_Direction); //Median vector (halfway)
double kd = 1;//diffuse reflectance for the Lambert model
double I = 0; //variable brightness
I = kd * glm::dot(Light_Direction, normal);
glColor3f(I, I, I);
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;
}
这是我的结果。
我想要这个结果。
第二个结果是这项工作的示例,但使用的是 c#。源代码在这里:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
double[,] depth;
int[,] brightness;
bool glConrerolIsLoaded;
float coord = 501.5f;
float coord1 = -17.5f;
float coord2 = -2979.5f;
float coord4 = -73.0f;
float coord5 = 1269.0f;
float coord6 = 413.5f;
int resNum = 0;
private void glControl1_Load(object sender, EventArgs e)
{
glConrerolIsLoaded = true;
GL.ClearColor(Color.Black);
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown3_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
Matrix4 perspectiveMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), glControl1.Width / glControl1.Height, 1.0f, 100.0f);
GL.LoadMatrix(ref perspectiveMatrix);
GL.MatrixMode(MatrixMode.Modelview);
GL.Translate(-25.0, -9.0, -45.0);
GL.Scale(0.04, 0.04, 0.04);
GL.Begin(BeginMode.Points);
for (int i = 0; i < depth.GetLength(0) - 1 ; i++)
{
for (int j = 0; j < depth.GetLength(1) - 1 ; j++)
{
if (depth[i, j] != 0 && depth[i + 1, j] != 0 && /*depth[i + 1, j + 1] != 0 &&*/ depth[i, j + 1] != 0)
{
Vector3 left = new Vector3(0, 1, Convert.ToSingle(depth[i, j + 1]) - Convert.ToSingle(depth[i, j]));
Vector3 right = new Vector3(1, 0, Convert.ToSingle(depth[i + 1, j]) - Convert.ToSingle(depth[i, j]));
Vector3 Normal = Vector3.Normalize(Vector3.Cross(left, right));
Vector3 Position_Light = new Vector3(coord + Convert.ToSingle(numericUpDown1.Value), coord1
+ Convert.ToSingle(numericUpDown2.Value), coord2 + Convert.ToSingle(numericUpDown3.Value));
Vector3 Position_View = new Vector3(coord4, coord5, coord6);
Vector3 Position_Point = new Vector3(i, j, Convert.ToSingle(depth[i, j]));
Vector3 Light_Direction = Vector3.Normalize(Position_Light - Position_Point);
Vector3 View_Direction = Vector3.Normalize(Position_View - Position_Point);
Vector3 HalfWay_Direction = Vector3.Normalize(Light_Direction + View_Direction);
double kd = 1;
double I = 0;
I = kd * Vector3.Dot(Light_Direction, Normal);
GL.Color3(I, I, I);
GL.Vertex3(i, j, depth[i, j]);
}
}
GL.End();
glControl1.SwapBuffers();
}
private void Form1_Load(object sender, EventArgs e)//Считывание карты глубины
{
string path = @"DepthMap_1.dat";
BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open));
double Height1 = reader.ReadDouble();
double Width1 = reader.ReadDouble();
depth = new double[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
brightness = new int[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
for (int i = 0; i < depth.GetLength(0); i++)
{
for (int j = 0; j < depth.GetLength(1); j++)
{
depth[i, j] = reader.ReadDouble();
}
}
reader.BaseStream.Close();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
}
}
所以我的问题是我的代码有什么不正确的地方?如果灯位置不好请帮我修一下
颜色由环境光+漫反射+镜面反射组成。镜面反射分量会增加反射,我认为这是您所期望的。您正在为颜色
进行的计算
I_diffuse = kd * glm::dot(Light_Direction, normal);
只是漫反射分量。
所以你需要的是
I_total = I_diffuse + I_specular;
你已经有I_diffuse,你可以得到I_specular如下,
vec3 viewDir = normalize(viewPos - pointPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 I_specular = specularStrength * spec * Ks;
specularStrength 可用于控制反射强度。
注意:
您正在使用的代码看起来像是在一个固定功能的管道中,它已被弃用。如果可能,请将其移至带有着色器的可编程管线。
您可以关注:https://learnopengl.com/Lighting/Basic-Lighting
我找到了答案,我在这里弄错了:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
应该是这样的:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i][j]));
我有一张 480x640 二维双阵列深度图。我使用 glBegin(GL_TRIANGLES) 使用 openGL 将其可视化。 这是我的代码,它工作正常:
int main(int argc, char** argv){
ifstream ifs("D:\DepthMaps1-20\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3f(189.0/255.0, 140.0 / 255.0, 194.0 / 255.0);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j+1] != 0)
{
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;}
所以现在我需要使用数学公式为反射模型添加光照。想法是 - 照明被视为具有相同强度的平行(单向)光束,光源的大小不受限制。照明由方向 L [Lx Ly Lz] 设置。 这是我的 Lambert 反射模型代码,它可以工作,但我想要更好的结果。
float coord = -1.0f;
float coord1 = -1.0f;
float coord2 = -0.0f;
float coord4 = -1.0f;
float coord5 = -2.0f;
float coord6 = -1.0f;
int main(int argc, char** argv)
{
ifstream ifs("D:\DepthMaps1-20\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
vector<vector<int>> brightness(height, vector<int>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(tippangle, 1, 0, 0);
glRotatef(viewangle, 0, 1, 0);
glScalef(scaleF, scaleF, scaleF);
//x
glRasterPos3f(1.1, 0.0, 0.0);
//y
glRasterPos3f(0.0, 1.1, 0.0);
//z
glRasterPos3f(0.0, 0.0, 1.1);
glTranslatef(d[0], d[1], d[2]);
glBegin(GL_TRIANGLES);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j + 1] != 0)
{
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
glm::vec3 normal = glm::normalize(glm::cross(left, right));
glm::vec3 Position_Light = glm::vec3(coord + 0, coord1+ 0, coord2 + 0); //Light source
glm::vec3 Position_View = glm::vec3(coord4, coord5, coord6); //observer
glm::vec3 Position_Point = glm::vec3(x[i][j], y[i][j], z[i][j]);
//Directions
glm::vec3 Light_Direction = glm::normalize(Position_Light - Position_Point); //To source
glm::vec3 View_Direction = glm::normalize(Position_View - Position_Point); // To the observer
glm::vec3 HalfWay_Direction = glm::normalize(Light_Direction + View_Direction); //Median vector (halfway)
double kd = 1;//diffuse reflectance for the Lambert model
double I = 0; //variable brightness
I = kd * glm::dot(Light_Direction, normal);
glColor3f(I, I, I);
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;
}
这是我的结果。
我想要这个结果。
第二个结果是这项工作的示例,但使用的是 c#。源代码在这里:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
double[,] depth;
int[,] brightness;
bool glConrerolIsLoaded;
float coord = 501.5f;
float coord1 = -17.5f;
float coord2 = -2979.5f;
float coord4 = -73.0f;
float coord5 = 1269.0f;
float coord6 = 413.5f;
int resNum = 0;
private void glControl1_Load(object sender, EventArgs e)
{
glConrerolIsLoaded = true;
GL.ClearColor(Color.Black);
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown3_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
Matrix4 perspectiveMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), glControl1.Width / glControl1.Height, 1.0f, 100.0f);
GL.LoadMatrix(ref perspectiveMatrix);
GL.MatrixMode(MatrixMode.Modelview);
GL.Translate(-25.0, -9.0, -45.0);
GL.Scale(0.04, 0.04, 0.04);
GL.Begin(BeginMode.Points);
for (int i = 0; i < depth.GetLength(0) - 1 ; i++)
{
for (int j = 0; j < depth.GetLength(1) - 1 ; j++)
{
if (depth[i, j] != 0 && depth[i + 1, j] != 0 && /*depth[i + 1, j + 1] != 0 &&*/ depth[i, j + 1] != 0)
{
Vector3 left = new Vector3(0, 1, Convert.ToSingle(depth[i, j + 1]) - Convert.ToSingle(depth[i, j]));
Vector3 right = new Vector3(1, 0, Convert.ToSingle(depth[i + 1, j]) - Convert.ToSingle(depth[i, j]));
Vector3 Normal = Vector3.Normalize(Vector3.Cross(left, right));
Vector3 Position_Light = new Vector3(coord + Convert.ToSingle(numericUpDown1.Value), coord1
+ Convert.ToSingle(numericUpDown2.Value), coord2 + Convert.ToSingle(numericUpDown3.Value));
Vector3 Position_View = new Vector3(coord4, coord5, coord6);
Vector3 Position_Point = new Vector3(i, j, Convert.ToSingle(depth[i, j]));
Vector3 Light_Direction = Vector3.Normalize(Position_Light - Position_Point);
Vector3 View_Direction = Vector3.Normalize(Position_View - Position_Point);
Vector3 HalfWay_Direction = Vector3.Normalize(Light_Direction + View_Direction);
double kd = 1;
double I = 0;
I = kd * Vector3.Dot(Light_Direction, Normal);
GL.Color3(I, I, I);
GL.Vertex3(i, j, depth[i, j]);
}
}
GL.End();
glControl1.SwapBuffers();
}
private void Form1_Load(object sender, EventArgs e)//Считывание карты глубины
{
string path = @"DepthMap_1.dat";
BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open));
double Height1 = reader.ReadDouble();
double Width1 = reader.ReadDouble();
depth = new double[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
brightness = new int[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
for (int i = 0; i < depth.GetLength(0); i++)
{
for (int j = 0; j < depth.GetLength(1); j++)
{
depth[i, j] = reader.ReadDouble();
}
}
reader.BaseStream.Close();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
}
}
所以我的问题是我的代码有什么不正确的地方?如果灯位置不好请帮我修一下
颜色由环境光+漫反射+镜面反射组成。镜面反射分量会增加反射,我认为这是您所期望的。您正在为颜色
进行的计算I_diffuse = kd * glm::dot(Light_Direction, normal);
只是漫反射分量。 所以你需要的是
I_total = I_diffuse + I_specular;
你已经有I_diffuse,你可以得到I_specular如下,
vec3 viewDir = normalize(viewPos - pointPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 I_specular = specularStrength * spec * Ks;
specularStrength 可用于控制反射强度。
注意: 您正在使用的代码看起来像是在一个固定功能的管道中,它已被弃用。如果可能,请将其移至带有着色器的可编程管线。 您可以关注:https://learnopengl.com/Lighting/Basic-Lighting
我找到了答案,我在这里弄错了:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
应该是这样的:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i][j]));