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

Debugging 形状取决于点光源顶点或片段着色器中的视角,debugging,opengl,glsl,lighting,Debugging,Opengl,Glsl,Lighting,在把基本教程弄得一团糟之后,我将尝试通过顶点或片段着色器实现OpenGL照明。问题是,根据摄影机的视角,背景中有一个形状,而结果并不取决于我是否在顶点或片段中执行此操作: 根据视角的不同,它在前面看起来有点像一个秋千,在右边,它只在几乎看不见的情况下显示亮起的表面(不知怎么的,在平截头体上让我想起了一点) 现在我对点光源的理解是,它不同于聚光灯,它照亮任何方向的所有东西,不应该依赖于相机 我现在主要关注这个教程:或者说这是第二个教程 请不要奇怪,我现在正在将几乎所有的东西都传递给片段,这只是为

在把基本教程弄得一团糟之后,我将尝试通过顶点或片段着色器实现OpenGL照明。问题是,根据摄影机的视角,背景中有一个形状,而结果并不取决于我是否在顶点或片段中执行此操作:

根据视角的不同,它在前面看起来有点像一个秋千,在右边,它只在几乎看不见的情况下显示亮起的表面(不知怎么的,在平截头体上让我想起了一点)

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

我现在主要关注这个教程:或者说这是第二个教程

请不要奇怪,我现在正在将几乎所有的东西都传递给片段,这只是为了进行实验,正如前面所说的,如果不将任何东西传递给片段着色器,除了漫反射颜色,并且像第一个教程中那样在顶点中做所有事情,它也会这样做。还要注意的是,我还添加了一个纹理,它似乎可以很好地处理coords。光的位置目前在世界空间,但也尝试在眼睛空间。在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;

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);             
}
我现在也省略了衰减来简化它,但是衰减也不起作用。将其设置为平行光,看起来很好左侧的墙被完全照亮,并且灯光位置在球体上看起来是正确的。 然而,LightSource的位置似乎是罪魁祸首,但由于LightLocation是修复的,所以它必须是vv_coord,我还尝试了任何可用矩阵的任何可想象的转换版本,无论它是否有意义,只是为了看看它的行为,因为我在这里读到一些问题,将向量作为颜色可以帮助调试,但我想不出来。vnormal的modelviewMat的逆转置应该是什么样子的?但无论如何,它似乎并不关心视角

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


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

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


稍后编辑,对于寻找一些调试提示的任何人:

片段着色器的
vv_-coord
似乎在对象空间中。光在物体空间中的位置也是吗?(听起来不太可能)无法说出我尝试了多少种不同的转换,因此目前这可能是错误的,但似乎对这个特定问题没有任何影响:(Core GLSL不提供常规调试的方法。有一些调试器,但它们是特定于供应商的;查看您的视频卡供应商开发人员网站,您可能会找到一个。至于颜色-它是线性RGB[0;1],其中1是最大颜色,0是黑色。通过重新缩放数字/向量,您可以看到这个范围(并从屏幕缓冲区读取)结果值。然后您可以将此颜色重新映射回向量(除法,可能还有减法)顺便说一句,在您忽略了我提到的明显问题之后,.PS停止在给定代码中查找错误。我想调试确实是您需要习惯的事情。对于颜色调试,这个想法是显而易见的,但是,我觉得目前为止还无法从输出中读取某些内容,因此我想知道是否有一些详细的信息信息,甚至可能是学习如何理解它的例子。猜一猜你也需要有经验的东西(尽管有点矛盾,因为这正是我需要的)。无论如何,谢谢你的帮助;)我不知道清楚的解释方法。首先,看一看,它包含法线看起来像什么的图像(重新缩放到[0;1]范围);其次,它描述了重新映射公式。我建议将不同的值转储到颜色中并查看结果;如果需要,获取屏幕截图并在gimp/photoshop/等中检查像素的颜色。例如,您的
点(法线方向,lightDirection)
实际上是这些向量之间角度的余弦(根据
dot
函数的数学定义,以及向量已经归一化的事实)-因此,您可以从中获取角度。了解角度(使用arccos),您可以在任何3D编辑器中查看场景(甚至只是在纸上绘制)然后知道它应该是什么角度。把它和你们得到的结果进行比较。若你们看到显著的不同,那个么有些东西是不一样的
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);             
}