gpt4 book ai didi

debugging - 形状取决于点光源顶点或片段着色器中的视角

转载 作者:行者123 更新时间:2023-12-02 03:37:29 32 4
gpt4 key购买 nike

在学习了很多基础教程之后,我将尝试通过顶点或片段着色器实现 OpenGL 光照。问题是,根据相机视角,背景中有一个形状,而结果不取决于我是在顶点还是在片段中:

enter image description here

根据视角,它看起来有点像前方的空中飞人,而在右侧,如果几乎看不到它,它只会显示出被照亮的表面(不知何故让我想起了一个截锥体)。

现在我对点光源的理解是,与聚光灯不同,它可以照亮任何方向的所有东西,并且不应该也依赖于相机。

我目前主要在学习本教程:http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Diffuse_Reflectionhttp://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Smooth_Specular_Highlights而现在这是第二个。

请不要怀疑我现在将几乎所有的东西都传递给片段,这只是为了试验它,如前所述,如果不将任何东西传递给片段着色器,除了漫反射颜色并在像第一个教程中那样的顶点。另请注意,我还添加了一个纹理,它似乎可以很好地处理坐标。 Light position目前在worldspace,但也试过在eye space。我在 C++ 中使用 GLM 对矩阵进行的大部分数学运算,并且只将其传递过来。

FLOAT ViewMatrix[16]  =
{
1.f, 0.f, 0.f, 0.f,
0.f, -1.f, 0.f, 0.f,
0.f, 0.f, -1.f, 0.f,
0.f, 0.f, 0.f, 1.f
};
viewMat = glm::make_mat4(ViewMatrix);

// Identity
modelMat = glm::mat4(1.0f);

//gl_NormalMatrix ?
modelviewMat=modelMat*viewMat;
m_3x3_inv_transp = glm::inverseTranspose(glm::mat3(modelviewMat));

//viewMat inverted
viewMatinv = glm::inverse(viewMat);

projMat = glm::frustum(-RProjZ, +RProjZ, -Aspect*RProjZ, +Aspect*RProjZ, 1.0f, 32768.0);

我当前的顶点着色器看起来像这样(目前没有任何环境光或镜面反射):

uniform sampler2D Texture0;
layout (location = 0) in vec3 v_coord; // == gl_Vertex
layout (location = 1) in vec3 v_normal;


uniform mat3 m_3x3_inv_transp; // == gl_NormalMatrix inverse transpose of modelviewMat
uniform mat4 projMat;
uniform mat4 viewMat;
uniform mat4 modelMat;
uniform mat4 modelviewMat;
uniform mat4 modelviewprojMat; // == gl_ModelViewProjectionMatrix == projMat*viewMat*modelMat;
uniform mat4 viewMatinv; // == ViewMatrix inverse

out vec2 vTexCoords;
out vec3 vv_coord;
out vec3 vv_normal;
out vec3 vNormalDirection;

out mat3 vm_3x3_inv_transp;
out mat4 vprojMat;
out mat4 vviewMat;
out mat4 vmodelMat;
out mat4 vmodelviewMat;
out mat4 vmodelviewprojMat;
out mat4 vviewMatinv;

void main(void)
{
//pass matrices also to fragment shader
vprojMat = projMat;
vviewMat = viewMat;
vmodelMat = modelMat;
vmodelviewMat = modelviewMat;
vmodelviewprojMat = modelviewprojMat;
vm_3x3_inv_transp = m_3x3_inv_transp;
vviewMatinv = viewMatinv;
vv_coord = v_coord;
vv_normal = v_normal;

//Texture UV to fragment
vTexCoords=TexCoords;

//Texture UV Lightmap to fragment
vLightTexCoords = LightTexCoords;

vNormalDirection = m_3x3_inv_transp * v_normal;
gl_Position = modelviewprojMat * vec4(v_coord, 1.0);
}

虽然片段着色器目前看起来像这样:

uniform sampler2D Texture0;

in vec2 vTexCoords;
in vec2 vLightTexCoords;
in vec3 vv_coord;
in vec3 vv_normal;
in vec3 vNormalDirection;

in mat3 vm_3x3_inv_transp;
in mat4 vprojMat;
in mat4 vviewMat;
in mat4 vmodelMat;
in mat4 vmodelviewMat;
in mat4 vmodelviewprojMat;
in mat4 vviewMatinv;

struct LightInfo
{
vec4 LightLocation;
vec3 DiffuseLightColor;
vec3 AmbientLightColor;
vec3 SpecularLightColor;
vec3 spotDirection;
float AmbientLightIntensity;
float SpecularLightIntensity;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
float spotCutoff;
float spotExponent;
};
uniform LightInfo gLight;


struct material
{
vec4 diffuse;
};
material mymaterial = material(vec4(1.0, 0.8, 0.8, 1.0));


out vec4 FragColor;

void main (void)
{
vec4 color = texture2D(Texture0, vTexCoords);

vec3 normalDirection = normalize(vNormalDirection);
vec3 lightDirection;
float attenuation;
vec3 positionToLightSource;

if (gLight.LightLocation.w == 0.0) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(gLight.LightLocation));
}
else // point light or spotlight (or other kind of light)
{
positionToLightSource = vec3(gLight.LightLocation - vec4(vv_coord,1.0));
}
vec3 diffuseReflection = vec3(gLight.DiffuseLightColor) * max(0.0, dot(normalDirection, lightDirection));

FragColor = color*vec4(diffuseReflection,1.0);
}

我目前还省略了衰减以简化它,但是有了衰减它也不起作用。将它设置为定向光,看起来左边的墙完全被照亮了,而且光的位置似乎是正确的,在球体上很明显。然而 positionToLightSource 似乎是罪魁祸首,但由于 LightLocation 是固定的,它必须是 vv_coord 并且我还尝试了任何可用矩阵的任何可以想象的转换版本,无论它是否有意义只是为了看看它的行为方式,因为我在这里阅读了一些问题将矢量作为颜色可以帮助调试,但我无法弄清楚。 vnormal 的 modelviewMat 的逆转置应该是什么样子的?但无论如何它似乎并不关心视角......

我的猜测是,并非所有东西都在同一个空间中(这很愚蠢,但我会感到惊讶,因为它用作定向光),或者出于某种原因 f.e. normalDirection/vnormals 是不对的 - 我不完全确定它,因为我从一个旧游戏引擎中获取值,它应该可以在某一天工作并且简单地遵循一些教程和示例代码它可以完美地工作。

现在做一个总结,这不仅仅是关于当前的问题,这里可能没有解决方案,因为它的来源可能超出了这些着色器的范围,尽管我仍然希望即使是这样也有人有想法,但也有如何正确调试这样的事情。我也尝试过 glsldevil,但没有经验,在没有任何 printf 或其他东西的情况下进行调试时,我仍然感到非常无助。将向量输出为颜色也很酷,但如前所述,我不知道什么是“应该看起来正确”——是否有某种“有效调试输出”的存档?请仅对 OpenGL3 或更新版本提出建议 :)

最佳答案

似乎是我获取法线信息的引擎需要先对屏幕坐标进行一些转换,所以绝对不是着色器的问题。在将 vv_coords 和 LightLocation 与 modMat 相乘后,将其放在正确的空间中,一切看起来都像预期的那样。尽管如此,如果 glsl 内部有一些这种“按颜色调试”的文件或文档,我仍然会感兴趣。无论如何谢谢 ;)

稍后编辑,对于任何寻找调试提示的人:http://antongerdelan.net/opengl/debugshaders.html

关于debugging - 形状取决于点光源顶点或片段着色器中的视角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22485506/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com