OpenGL 定向光着色器

2024-03-17

我想使用 OpenGL 和 GLSL 将定向光添加到我的场景中。问题在于,理论上正确的方法会产生错误的结果。

在顶点着色器中我执行以下操作:

光线的方向以世界坐标给出,并使用 viewMatrix 转换为相机坐标。使用法线矩阵将顶点的法线转换为相机坐标。

void main () {
    vary_textureCoord = attribute_textureCoord;
    vary_normal = mat3(normalMatrix) * attribute_normal;

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0);

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0);
}

因此两个向量都位于相机坐标中并传递给片段着色器。片段着色器使用光线的法线和方向来计算光线强度。

void main () {
    vec3 normalizedNormal = normalize(vary_normal);
    vec4 color = texture(tex, vary_textureCoord);

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz)));

    out_color =  color * directionalLightIntensity;
}

这个着色器导致的结果是光线不是静态的而是随着相机移动。使用此行更改顶点着色器:

vary_directionalLight_direction = transpose(inverse(viewMatrix)) * vec4(lightDir, 1.0);

得到了想要的结果。 那么我到底做错了什么或者哪里有误解呢?

这里是完整的着色器代码:

顶点着色器:

# version 330

layout(location = 0) in vec3 attribute_position;
layout(location = 2) in vec2 attribute_textureCoord;
layout(location = 3) in vec3 attribute_normal;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
uniform vec3 lightDir;

out vec2 vary_textureCoord;
out vec3 vary_normal;
out vec4 vary_directionalLight_direction;

void main () {
    vary_textureCoord = attribute_textureCoord;
    vary_normal = mat3(normalMatrix) * attribute_normal;

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0);

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0);
}

片段着色器:

# version 330

in vec2 vary_textureCoord;
in vec3 vary_normal;
in vec4 vary_directionalLight_direction;

uniform sampler2D tex;

out vec4 out_color;

void main () {
    vec3 normalizedNormal = normalize(vary_normal);
    vec4 color = texture(tex, vary_textureCoord);

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz)));

    out_color =  color * directionalLightIntensity;
}

变换矩阵如下所示:

( X-axis.x, X-axis.y, X-axis.z, 0 )
( Y-axis.x, Y-axis.y, Y-axis.z, 0 )
( Z-axis.x, Z-axis.y, Z-axis.z, 0 )
( trans.x,  trans.y,  trans.z,  1 ) 

如果你想变换一个位置,那么你必须将完整的变换矩阵应用到该位置。

mat4 viewMatrix;
vec3 pos;
vec4 viewPos = viewMatrix * vec4(pos, 1.0);

这将视图的方向和位置应用到位置pos.

但方向没有起源。方向只有方向。这意味着,如果你想通过视图变换方向向量,那么你必须将它乘以 4*4 的左上角 3*3 部分viewMatrix:

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

OpenGL 定向光着色器 的相关文章

  • OpenGL什么时候完成函数中指针的处理?

    OpenGL有多项功能 http www opengl org wiki GLAPI glTexSubImage2D直接获取指针 他们中有一些从这些指针读取数据 http www opengl org wiki GLAPI glBuffer
  • GLSL聚光投影体积

    在我的开源项目中 我使用 Qt3D 设置了延迟渲染管道 到目前为止一切顺利 但现在我想通过添加聚光灯投影量来继续前进 例如场景中好像有烟雾 像这样 我正在使用的片段着色器位于问题的末尾 我读过 对于每个片段 我应该从光位置进行光线行进并找到
  • 渲染缓冲区大于窗口大小 - OpenGL

    我正在尝试绘制大于屏幕尺寸 即 320x480 的渲染缓冲区 512x512 执行 glReadPixels 后 图像看起来是正确的 除非图像的尺寸超过了屏幕尺寸 在本例中 超过了水平 320 和垂直 480 是什么原因导致这种异常现象呢
  • 按像素值偏移 gl_Position 或 gl_Vertex

    我的属性包含像素值 我想用这个属性值来偏移我的 gl vertex 问题是我的 gl vertex 以世界单位为单位 而 offset attribute 以像素为单位 如果我将屏幕尺寸作为统一发送 然后将像素转换为 1 到 1 值 并将其
  • matplotlib:渲染到缓冲区/访问像素数据

    我想使用 matplotlib 生成的图作为 OpenGL 中的纹理 到目前为止 我遇到的 matplotlib 的 OpenGL 后端要么不成熟 要么已经停止使用 所以我想避免使用它们 我当前的方法是将图形保存到临时 png 文件中 并从
  • 具有交错缓冲区的 openGL glDrawElements

    到目前为止 我只使用了 glDrawArrays 并希望转向使用索引缓冲区和索引三角形 我正在绘制一个有点复杂的对象 其中包含纹理坐标 法线和顶点坐标 所有这些数据都收集到一个交错的顶点缓冲区中 并使用类似于以下的调用进行绘制 假设所有血清
  • Three.js、自定义着色器和具有透明度的 png 纹理

    我有一个非常简单的 PNG 纹理 一个带有透明背景的灰色圆圈 我用它作为制服map for a THREE ShaderMaterial var uniforms THREE UniformsUtils merge basicShader
  • OpenSceneGraph 将相机设置在初始位置

    我是第一次使用 OpenSceneGraph 我有点迷失 因为文档确实不太清楚 所以 我有这段代码加载一个带有房子的 obj 文件 并且我在我想要的 人 所在的地方淹没了一个小盒子 所以现在 我不想把那个盒子放在那里 而是想把相机放在那里
  • 使用 gl_FragColor 与 vec4 颜色?

    似乎有很多不明确的地方gl FragColor被弃用 例如 它缺失在GLSL 4 40 规范 https www khronos org registry OpenGL specs gl GLSLangSpec 4 40 pdf 但它包含在
  • 为贝塞尔曲线中的每个点绘制切线

    我设法绘制了一条贝塞尔曲线 如下所示 glColor3f 0 1 0 glBegin GL LINE STRIP for int i 3 i lt nPt i 3 glColor3f 0 0 0 for float k 0 k lt NLI
  • 无法在 Linux 的 NetBeans 中编译 C++ 和 OpenGL (GLFW) 的简单源代码

    我开始学习 OpenGL glfw 我从教程中复制源代码并尝试编译它 但出现了错误 我想我已经正确安装了所有头文件 glm glfw 等 这是我的来源 我没有在头文件中使用这些字符 include iostream include stdi
  • 使用 OpenGL 渲染 QImage

    与我相关的其他问题 https stackoverflow com questions 20126354 render qimage from sooffscreenrenderer in qglwidget 我认为更核心的问题是 如何渲染
  • OpenGL 缓冲区、glFlush 和 glutSwapBuffers()

    使用之间有什么区别吗 glutInitDisplayMode GLUT SINGLE GLUT RGB with glFlush and glutInitDisplayMode GLUT DOUBLE GLUT RGB with glutS
  • 如何创建自己的 openGL 上下文并将其绑定到 GLCanvas?

    所以当我开始掌握java时 paint Graphics g 我继续创建自己的渲染方法 但我必须了解缓冲区策略以及如何 获取 图形 所以现在我在学习openGL 我必须掌握方法 Override public void display GL
  • sRGB 纹理。它是否正确?

    我最近阅读了一些有关 sRGB 格式以及它们如何允许硬件自动对典型显示器执行色彩校正的文章 作为我阅读的一部分 我发现您可以使用普通纹理和返回结果上的 pow 函数来模拟此步骤 无论如何 我想问两个问题 因为我以前从未使用过此功能 首先 有
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前
  • Three.js 中的自定义纹理着色器

    我只是想创建一个非常简单的片段着色器 将指定的纹理绘制到网格上 我研究了一些实现相同功能的自定义片段着色器 并构建了我自己的着色器并围绕它支持 JS 代码 然而 它就是行不通 这是我尝试运行的代码的工作抽象 顶点着色器
  • Raspberry PI 上的 JavaFX:加载库存着色器时出错

    目前我正在尝试部署我的 JavaFX 应用程序 该应用程序可以在 Windows 上的 Raspberry Model B v1 2 上顺利运行 由于 JavaFX 不能直接在 Raspi 上使用 我已经按照此处所述使用 Gluon 进行了
  • 光照不适用于 gluSphere

    这是一个简单的问题 我有点羞于寻求帮助 我正在对 gluSphere 进行简单调用来渲染球体 但是 即使我很确定我正确添加了法线和照明 它也无法正确照亮 但是 如果我添加纹理 模型会正常点亮 但它似乎总是平滑的 并且我无法将其更改为平面 这

随机推荐