为什么灯光出现在对面?

2024-03-30

我正在尝试使用构建照明this https://learnopengl.com/Lighting/Basic-Lighting教程。但是,灯光出现在人体物体的错误一侧,我不知道为什么。

法线是按三角形创建的。三角形的顶点基本上具有相同的法线:

glm::vec3 calculateNormal(glm::vec3 vertice_1, glm::vec3 vertice_2, glm::vec3 vertice_3)
{
    glm::vec3 vector_1 = vertice_2 - vertice_1;
    glm::vec3 vector_2 = vertice_3 - vertice_1;
    return glm::normalize(glm::cross(vector_1, vector_2));
}

这是顶点着色器的代码:

#version 330 core

layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
out vec4 vert_color;
out vec3 Normal;
out vec3 FragPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 transform;
uniform vec4 color;

void main()
{
    vert_color = color;
    gl_Position = projection * view * model * transform * vec4(pos.x, pos.y, pos.z, 1.0);
    FragPos = vec3(model * transform *  vec4(pos, 1.0));
    Normal = normal;
}

片段着色器:

#version 330 core

uniform vec3 cameraPos;
uniform vec3 lightPos;
uniform vec3 lightColor;

in vec4 vert_color;
in vec3 FragPos;
in vec3 Normal;
out vec4 frag_color;

void main()
{
    float ambientStrength = 0.1;
    float specularStrength = 0.5;
    vec3 ambient = ambientStrength * lightColor;

    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(Normal, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    vec3 viewDir = normalize(cameraPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, Normal);

    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor; 

    vec3 result = (ambient + diffuse + specular) * vec3(vert_color.x, vert_color.y, vert_color.z);
    frag_color = vec4(result, vert_color.w);
}

主循环:

    wxGLCanvas::SetCurrent(*glContext);
    glClearDepth(1.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glm::mat4 model, view, projection;
    model = glm::translate(model, modelPos); // modelPos is 
    view = fpsCamera->getViewMatrix();
    projection = fpsCamera->getProjectionMatrix(windowWidth, windowHeight);
    color = glm::vec4(0.310f, 0.747f, 0.185f, 1.0f);
    glm::vec3 lightPos = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::vec3 lightColor = glm::vec3(1.0f, 1.0f, 1.0f);

    glm::mat4 phantomtTransformation;
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() , glm::vec3(0.0f, 0.0f, 1.0f));
    
    ShaderProgram shaderProgram;
    shaderProgram.loadShaders("Shaders/phantom.vert", "Shaders/phantom.frag");

    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    shaderProgram.use();
    shaderProgram.setUniform("transform", phantomtTransformation);
    shaderProgram.setUniform("model", model);
    shaderProgram.setUniform("view", view);
    shaderProgram.setUniform("projection", projection);
    shaderProgram.setUniform("color", color);
    shaderProgram.setUniform("lightColor", lightColor);
    shaderProgram.setUniform("lightPos", lightPos);
    shaderProgram.setUniform("cameraPos", fpsCamera->getPosition());

    
    glStencilMask(0xFF); // Write to stencil buffer
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0

    glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to object ID
    m_pantomMesh->draw();
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0        // no need for testing

    glFlush();
    wxGLCanvas::SwapBuffers();

从物体正面观察:

从物体背面看:

EDIT:为了调试,我从主循环中删除了对象旋转矩阵:

 glm::mat4 phantomtTransformation;
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() , glm::vec3(0.0f, 0.0f, 1.0f));
 
shaderProgram.setUniform("transform", phantomtTransformation);

并将片段着色器中的行更改为

frag_color = vec4(result, vert_color.w);

to

frag_color = vec4(Normal, vert_color.w);

为了可视化正常值。结果我注意到,当相机改变位置时,幻影也会改变颜色,这意味着正常值也会改变。


我认为问题的原因是您没有将模型转换应用于法向量。由于您绝对不想倾斜它们,因此您必须为法线创建一个特殊的矩阵。

正如您提到的教程中进一步解释的那样,可以像这样构造矩阵

Normal = mat3(transpose(inverse(model))) * aNormal;

在你的顶点着色器中。However,我强烈建议您在应用程序代码中计算矩阵,因为您将在上面的示例中计算每个顶点。 由于您使用的是 glm 库,因此它看起来像这样:

glm::mat3 model_normal = glm::mat3(glm::transpose(glm::inverse(model)));

然后您可以加载新的model_normal矩阵作为着色器uniform mat3.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么灯光出现在对面? 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s

随机推荐

  • 关闭连接后继续处理[重复]

    这个问题在这里已经有答案了 PHP 有没有办法关闭连接 本质上告诉浏览器没有更多数据 但继续处理 我想到的具体情况是 我想要提供缓存数据 那么如果缓存已过期 我仍然会提供缓存数据以获得快速响应 关闭连接 但继续处理以重新生成并缓存新数据数据
  • R-如何使用两种不同的调查设计进行双样本 t 检验

    我想对两个均值的相等性进行双样本 韦尔奇 t 检验 其中之一是使用简单随机抽样获得的 srsmean 另一个是使用调查包的调查权重计算得出的 mean weighted 我还进行了 t 检验mean weighted以及在调查设计中同时实施
  • Orion 的 Freeboard 数据源与 Context Broker 之间没有连接

    我一直在尝试连接 Freeboard 以可视化来自 OCB 的上下文信息 但是遇到了一些困难 导致我无法从那里接收任何数据 我的想法是 将Freeboard连接到OCB有问题 因为在OCB的订阅列表中没有任何新条目 并且Freeboard中
  • Visual Studio 2020 如何阻止选项卡中的文件名被缩短

    在 Visual Studio 对我来说是 2020 中 打开文件的文件名写在屏幕顶部的选项卡中 如果文件名太长 它会自动缩短 即代替真正的长文件名 cs它会说真的L lename cs 我想要显示整个文件名 我意识到我可以将鼠标悬停在选项
  • 使用退格控制字符擦除

    我正在尝试使用退格控制字符 b 删除行尾的尾随逗号 尽管它在没有其他输出的情况下有效stdout 如果之后有另一个输出 b 它变得毫无用处 这是一个例子 include
  • OpenCV2 薄板样条应用变换不起作用?

    我正在使用 Python OpenCV2 实现薄板变压器并遇到一些问题 当我执行 WarpImage 时 图像会正确扭曲 但是当我使用一些手动输入的点的estimateTransformation 时 这些点无法正确映射 相反 所有点最终都
  • Python 将列重塑为多列 - 交替行

    任何人都可以建议一种有效的方法 将一列 在 python pandas 数据框中 重塑为多列 并交替进行列分配 我可以用循环来做到这一点 但想知道是否有更优雅的方法 例如 请考虑以下示例 Added 有没有人有一个解决方案 可以将单列中的每
  • 如何比较两个日期?

    我有三个日期 1 上一个日期 2 当前日期 3 下一个日期 我想检查 currentDate 是否晚于前一个日期且早于 nextDate 我怎么做 NSDateFormatter df NSDateFormatter alloc init
  • Haskell 函数 :: [名称] -> [[(Name, Bool)]]

    鉴于以下情况 type Name String envs Name gt Name Bool 我必须实现 envs 以便给定名称列表 它返回名称和布尔值的所有可能组合 我的尝试没有返回所有可能的组合 这是我的代码 envs xxs x xs
  • 如何确保 Jest 在“unhandledRejection”上失败?

    我们的单元测试在持续交付管道的容器中运行 有时 我们不会在单元测试中处理拒绝 但是 我认为这是不正确的 并且在我看来管道应该失败 我怎样才能确保当我执行时jest并且在测试期间unhandledRejection事件发生 jest 会错误退
  • 提示工具包和提示工具包有什么区别

    我最近运行了一个 conda 列表 我发现我有两个不同的软件包 分别称为prompt toolkit 3 0 4 和prompt toolkit 3 0 4 我试图用谷歌搜索它们之间的区别 基本上使用我的问题标题的确切措辞 而出现的只是pr
  • 在javascript中获取鼠标光标的大小

    我需要确定网页上当前使用的鼠标光标的宽度和高度 我需要在光标正下方显示一个 div 也可能在其右侧 所以我需要确定 div 相对于确切指针位置的偏移量 这样光标就不会覆盖 div 该机制将用于Intranet系统 因此它可以是仅firefo
  • Terraform 中使用多个 user_data 文件

    我正在尝试为常见任务 例如文件夹创建和某些包安装 提供一个通用的 user data 文件 并为应用程序特定的配置提供一个单独的 user data 文件 我正在尝试以下 user data data template file userd
  • MacOS,如何删除键盘快捷键中未使用的服务项

    我是 Mac OS 的新手 正在学习 Automator 我发现它很有用 但不太可控 我在服务中创建了快捷方式 但不知道如何删除它 突出显示的项目是我要删除的项目 我想我应该用 Automator 来做 但我不知道如何做 任何帮助将不胜感激
  • javascript闭包立即评估[重复]

    这个问题在这里已经有答案了 考虑以下 JavaScript 代码 var a var f function for var i 0 i lt 3 i a push function alert i for var j 0 j lt 3 j
  • 如何使用 Haskell Aeson 解析数组

    我有一个 JSON 文档 如下所示 series 1 2 2 3 3 4 我想将其解析为一组数据类型 data Series Series DataPoint data DataPoint DataPoint Int Int x and y
  • 为什么我的 MongoDB $or 查询不起作用?

    我正在尝试执行 or 搜索来匹配两个正则表达式 如下所示 metadata text or regex hello regex world 我正在使用 mlab com 并收到以下错误 MongoDB error Command faile
  • 使用twig变量动态调用导入的宏子函数

    我正在尝试是否使用变量来调用特定的宏名称 我有一个正在导入的宏文件 import form elements html twig as forms 现在该文件中包含所有表单元素宏 文本 文本区域 选择 单选等 我有一个传入的数组变量 其中包
  • Groovy 相对于 Jython 或 Jruby 的优势?

    当我可以使用 Jython 或 Jruby 时 为什么我要选择使用 Groovy 该语言是否提供了任何固有的优势来弥补 Jython 和 Jruby 技能适用于 JVM 之外的其父语言的事实 请记住 我故意保持这个问题的通用性 但如果特定领
  • 为什么灯光出现在对面?

    我正在尝试使用构建照明this https learnopengl com Lighting Basic Lighting教程 但是 灯光出现在人体物体的错误一侧 我不知道为什么 法线是按三角形创建的 三角形的顶点基本上具有相同的法线 gl