关于在集成显卡下使用OpenGL碰到的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29523119/article/details/77018958


集成显卡(Intel)驱动问题导致片元缺失

刚开始在公司入职的时候,办公电脑的只有集成显卡,并且集成显卡的驱动版本低,导致我渲染的第一个红色的三角形部分片元显示为黑色(部分片元无法光栅化出来),像噪点一样,刚开始检查了很久还以为自己写的程序问题(其实写图形渲染程序也有一段时间了,从没遇到这种问题),后面更新集成显卡驱动才解决问题。




将法向量从模型空间(ModelSpace)变换到相机空间(ViewSpace)

法向量从一个空间变换到另外一个空间,要乘以相应变化矩阵的逆矩阵的转置矩阵,也就是transpose(invense(Matrix)),
那么法向量从模型空间变换到相机空间,可以写作:


第一种写法的VertexShader

CubeShader.setMat4("TransposeInverseModelMarix", transpose(inverse(cubeModelMatrix)));
CubeShader.setMat4("TransposeInverseViewMarix", transpose(inverse(viewMatrix)));



#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;



uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjMatrix;
uniform mat4 TransposeInverseModelMarix;
uniform mat4 TransposeInverseViewMarix;

out vec3 fragViewSpaceNormal;
out vec3 fragViewSpacePos;



//这次是变化到ViewSpace进行Phong着色,其实只要片元的法向量,片元的位置,灯光的位置,相机的位置都位于同一个空间,那么Phong着色(Ambient,Diffuse,Specular)就是正确的
//在相机空间,相机的位置为(0,0,0)
void main()
{

    gl_Position = ProjMatrix*ViewMatrix*ModelMatrix*vec4(vPosition,1.0f);
	fragViewSpaceNormal=(TransposeInverseViewMarix*TransposeInverseModelMarix*vec4(vNormal,0.0f)).xyz;
	fragViewSpacePos=(ViewMatrix*ModelMatrix*vec4(vPosition,1.0f)).xyz;
}



第二种写法的VertexShader


CubeShader.setMat4("TransposeInverseModelToViewMarix", transpose(inverse(viewMatrix*cubeModelMatrix)));


#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;



uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjMatrix;
uniform mat4 TransposeInverseModelToViewMarix;


out vec3 fragViewSpaceNormal;
out vec3 fragViewSpacePos;



//这次是变化到ViewSpace进行Phong着色,其实只要片元的法向量,片元的位置,灯光的位置,相机的位置都位于同一个空间,那么Phong着色(Ambient,Diffuse,Specular)就是正确的
//在相机空间,相机的位置为(0,0,0)
void main()
{

    gl_Position = ProjMatrix*ViewMatrix*ModelMatrix*vec4(vPosition,1.0f);
	fragViewSpaceNormal=(TransposeInverseModelToViewMarix*vec4(vNormal,0.0f)).xyz;
	fragViewSpacePos=(ViewMatrix*ModelMatrix*vec4(vPosition,1.0f)).xyz;
}


我实现的是在相机空间的PhongShading, 随便放出FragmentShader的代码:

FragmentShader
#version 330 core


uniform vec3 lightColor;
uniform vec3 objectColor;
uniform vec3 cameraViewSpacePos;
uniform int specularPower;
uniform float specularStrength;
uniform float ambientStrength;
uniform vec3 lightViewSpacePos;

in vec3 fragViewSpaceNormal;
in vec3 fragViewSpacePos;

out vec4 fColor;


void main()
{

   vec3 ambientLight;
   vec3 diffuseLight;
   vec3 specularLight;

   //规格化片元法向量
   vec3 fViewSpaceNormal=normalize(fragViewSpaceNormal);

   //计算环境光
   ambientLight=ambientStrength*lightColor;

   //计算漫反射光
   //1,计算入射光线方向
   vec3 lightDir=normalize(fragViewSpacePos-lightViewSpacePos);
   //2,计算漫反射值
  float diffuse=max(dot(-lightDir,fViewSpaceNormal),0.0f);

   diffuseLight=diffuse*lightColor;

   //计算镜面光
   //1,计算反射光方向(入射光尽量用规格化向量,并且反射函数的第一个参数为入射光)
   vec3 reflectLightDir=reflect(lightDir,fViewSpaceNormal);
   reflectLightDir=normalize(reflectLightDir);

   //2,计算片元的视角向量
   vec3 viewDir=normalize(cameraViewSpacePos-fragViewSpacePos);

   //3,计算镜面光参数
   float specular=pow(max(dot(reflectLightDir,viewDir),0.0f),specularPower);
   specularLight=specular*specularStrength*lightColor;


   vec3 result= (ambientLight+diffuseLight+ specularLight)*objectColor;

   fColor =vec4(result,1.0f);

} 




按原理来说,两种写法是一样的,我也尝试在控制台(Console)输出过结果,矩阵参数确实是一样的。但实际上第一种写法和第二种写法在我的有独立显卡(N卡)的笔记本上都是跑出正确的效果,而第一种写法在公司只有集成显卡的电脑上就出问题了。法向量从模型空间变换到相机空间建议用第一种写法,毕竟适应各种情况。



猜你喜欢

转载自blog.csdn.net/qq_29523119/article/details/77018958