OpenGL片段着色器不照亮场景
Posted
技术标签:
【中文标题】OpenGL片段着色器不照亮场景【英文标题】:OpenGL fragment shader not lighting the scene 【发布时间】:2016-06-30 11:09:38 【问题描述】:我是 OpenGL 的一个新手,我已经为一个场景实现了光照,其中实例化的小行星环绕着一个行星。出于某种原因,我得到的唯一输出似乎是场景的环境照明。我无法让漫反射或镜面反射工作。
这是现场的图像(很难看到...)ambient only
片段着色器代码如下。 FragPos、Normal 和 TexCoords 如您所料。 texture_diffuse1 是行星/小行星纹理,取决于使用的着色器。 LightPos 可以移动,它由图像中较小的行星表示(因此直接在中心行星上方),viewPos 是相机位置。
如果需要更多信息,请告诉我,但其余代码非常简单(顶点着色器非常标准,场景中绘制的 assimp 加载模型,小行星实例化 200,000 次)。
谢谢 乔恩
片段着色器:
`
#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);
`
【问题讨论】:
如果你的光源和你的星球相距 300 单位,你的星球只会受到 1/300~0,003 的光的影响。这是故意的吗? 这是关于衰减与伽马校正混合的教程的一部分。我确实删除了它,但它没有任何区别。 我有一个实现太阳能系统的程序。那里没有实例,但有闪电(也有阴影)。你可以看看对比一下,也许你会发现哪里出了问题。代码在这里:github.com/aromanro/SolarSystem 啊,传奇人物阿德里安,谢谢,我的光线方向弄错了!这是 Frag - lightpos,我有 lightpos - frag!!如果您希望得到答案,那么非常乐意为您提供答案,请将其添加到答案中 嘿,原来我错了......再次,但我确实发现使用你的着色器实际上是错误的顶点着色器,我没有计算法向量关于在将模型矩阵传递给片段着色器之前!但是再次感谢,如果没有你的例子,我永远找不到它。 【参考方案1】:看来闪电的方向错了。需要fs_in.FragPos - lightPos
而不是lightPos - fs_in.FragPos
。我将在此处提供我的代码的链接,以使其更加可见,也许它也会对其他人有所帮助:https://github.com/aromanro/SolarSystem
编辑
JonCain:还发现在从顶点着色器传递之前,法线的矩阵没有被正确应用。
【讨论】:
以上是关于OpenGL片段着色器不照亮场景的主要内容,如果未能解决你的问题,请参考以下文章