当前位置: 首页 > 知识库问答 >
问题:

OpenGL片段着色器不点亮场景

公良渝
2023-03-14

我对OpenGL有点生疏,我已经实现了一个场景的照明,场景中有小行星围绕行星旋转的实例。出于某种原因,我得到的唯一输出似乎是场景的环境照明。我无法使漫反射或镜面反射工作。

这是现场的一张照片(很难看到…)仅限环境

片段着色器代码如下所示。FragPos、Normal和TexCoords都是你所期待的。纹理_diffuse1是行星/小行星纹理,具体取决于使用的着色器。LightPos可以移动,它由图像中较小的行星表示(位于中心行星正上方),而viewPos是相机的位置。

需要更多信息,请告诉我,但剩下的代码非常简单(顶点着色器非常标准,场景中绘制了ASIMP加载的模型,小行星实例化了200000次)。

谢了乔恩

片段着色器:

`

#version 330 core
out vec4 fragColor;

in VS_OUT{
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
} fs_in;

uniform sampler2D texture_diffuse1;
uniform vec3 lightPos;
uniform vec3 viewPos;

void main()
{
    vec3 color = texture(texture_diffuse1, fs_in.TexCoords).rgb;

    //Ambient
    vec3 ambient = 0.05f * color;

    //Diffuse
    vec3 lightDir = normalize(lightPos - fs_in.FragPos);
    vec3 normal = normalize(fs_in.Normal);
    float diff = max(dot(lightDir, normal), 0.0);
    vec3 diffuse = diff * color;

    //Specular

    vec3 viewDir = normalize(viewPos - fs_in.FragPos);  

    float spec = 0.0f;
    vec3 halfwayDir = normalize(lightDir + viewDir);
    spec = pow(max(dot(normal, halfwayDir), 0.0), 32.0f);

    vec3 specular = vec3(0.3f) * spec * color;

    float distance = length(lightPos - fs_in.FragPos);
    float attenuation = 1.0f/distance;

    //fragColor = vec4(ambient + (diffuse + specular), 1.0f);
    fragColor = vec4( pow(ambient + attenuation * (diffuse + specular),vec3(1.0f/2.2f)), 1.0f);
}

`

共有1个答案

农永宁
2023-03-14

看来闪电的方向是错的。而不是中的lightPos-fs_。FragPosfs_in。需要FragPos-lightPos。我将在这里提供我的代码链接,使其更加可见,也许它也会帮助其他人:https://github.com/aromanro/SolarSystem

编辑

JonCain:结果还表明,法线矩阵在从顶点着色器传递之前没有正确应用。

 类似资料:
  • 我真的不明白片段着色器是如何工作的。 我知道 顶点着色器每个顶点运行一次 片段着色器对每个片段运行一次 由于片段着色器不是按顶点而是按片段工作,它如何将数据发送到片段着色器?顶点的数量和片段的数量不相等。 它如何决定哪个碎片属于哪个顶点?

  • 我希望在2D OpenGL应用程序上实现着色器。我的计划是将场景渲染到帧缓冲区对象,然后使用着色器将该帧缓冲区对象渲染到屏幕。 这是我绘制到帧缓冲区对象的场景,然后从那里绘制到屏幕。使用箭头键可以让月亮四处移动(我很自豪!) 但是,当我尝试使用着色器程序将帧缓冲区对象渲染到屏幕上时,我得到以下结果: 这是非常可悲的。这个片段着色器是我从一个教程中得到的,我相信问题一定是统一变量。 以下是片段着色器

  • WebGL的着色器代码分为顶点着色器代码和片元着色器代码两部分,顶点着色器代码会在GPU的顶点着色器单元执行,片元着色器代码会在GPU的片元着色器单元执行,在WebGL渲染管线流程中,或者说GPU的渲染流程中,顶点着色器代码先执行处理顶点,得到一系列片元,然后再执行片元着色器代码处理片元。 main()函数 顶点着色器和片元着色器代码都有一个唯一的主函数main(),attribute、varyi

  • OpenGL的渲染管线分为几个步骤。一个简单的OpenGL渲染管线将包含一个顶点着色器和一个片段着色器。 顶点着色器接收顶点数据,并且在程序最后赋值给gl_Position。然后,顶点将会被裁剪,转换和栅格化后作为像素输出。 片段(像素)进入片段着色器,进一步对片段操作并将结果的颜色赋值给gl_FragColor。顶点着色器调用多边形每个角的点(顶点=3D中的点),负责这些点的3D处理。片段(片度

  • 在一个简单的hello world OpenGL程序中,它只是在窗口上绘制一个静态三角形,当我将三角形的3个顶点设置为红色、绿色和蓝色时,三角形将填充渐变。 但是当我使用这样的着色器时: 顶点着色器: 其中属性和来自顶点缓冲区,通过的调用传递。 片段着色器: 三角形仍然充满了梯度,问题来了: 如果顶点着色器是按顶点计算的,则应为的每个实例指定顶点的颜色。顶点颜色应为红色、绿色或蓝色,如顶点缓冲区中