Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 具有数组和条件的奇怪GLSL行为_Opengl_Glsl_Shader_Fragment Shader_Vertex Shader - Fatal编程技术网

Opengl 具有数组和条件的奇怪GLSL行为

Opengl 具有数组和条件的奇怪GLSL行为,opengl,glsl,shader,fragment-shader,vertex-shader,Opengl,Glsl,Shader,Fragment Shader,Vertex Shader,我正在开发一个小型OpenGL引擎,目前遇到以下GLSL问题: 我试图为多个灯光实现一个着色器,它会生成正确的结果,但前提是我将漫反射灯光的计算放在一个(完全无用的)if语句中。specultar灯光组件始终正确渲染 作品: for( int i = 0; i < uNumLights; ++i ) { //... if( <anything> == <something> ) { lDiffuseLight += vAmbientDiff

我正在开发一个小型OpenGL引擎,目前遇到以下GLSL问题:

我试图为多个灯光实现一个着色器,它会生成正确的结果,但前提是我将漫反射灯光的计算放在一个(完全无用的)if语句中。specultar灯光组件始终正确渲染

作品:

for( int i = 0; i < uNumLights; ++i ) {
   //...
   if( <anything> == <something> ) {
      lDiffuseLight  += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
   }
}
for(int i=0;i
不起作用:

for( int i = 0; i < uNumLights; ++i ) {
   //...
   lDiffuseLight  += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
for(int i=0;i
此外,如果我在循环条件中使用常数而不是统一值,则没有任何效果

为什么带if的代码可以工作而不带if?如果没有愚蠢的if语句,如何使着色器工作

完整着色器代码:

顶点着色器:

#version 330
const int MAX_LIGHTS = 4;

in vec3 iVertex;
in vec3 iNormals;

uniform mat4 uModelView;
uniform mat4 uMVP;
uniform mat3 uNormal;

smooth out vec3 vPosition;
smooth out vec3 vModelView;
smooth out vec3 vNormals;

// Colors...

smooth out vec3 vAmbientDiffuseMaterial; // Make some colors...
smooth out vec3 vAmbientLight;
smooth out vec3 vLightDirection[MAX_LIGHTS];

uniform vec3 uAmbientColor;

uniform int uNumLights;

uniform struct Light {
   vec3 color;
   vec3 position;
} uLights[MAX_LIGHTS];

void main(void) {
   vAmbientDiffuseMaterial = clamp(iVertex, 0.0, 1.0);

   vAmbientLight = vAmbientDiffuseMaterial * uAmbientColor;

   gl_Position = uMVP * vec4( iVertex.xyz, 1.0 );

   vPosition  = gl_Position.xyz;
   vNormals   = normalize( uNormal    * iNormals );
   vModelView = ( uModelView * vec4( iVertex , 1 )).xyz;

   for( int i = 0; i < uNumLights; ++i ) {
      vLightDirection[i] = normalize( uLights[i].position - vModelView );
   }
}
#版本330
const int MAX_LIGHTS=4;
在vec3-iVertex中;
在vec3非正常情况下;
统一mat4 uModelView;
统一mat4 uMVP;
统一mat3非正常;
平滑vec3位置;
平滑vec3-vModelView;
平滑vec3异常;
//颜色。。。
平滑vec3 vAmbientDiffuseMaterial;//做一些颜色。。。
平滑vec3 vAmbientLight;
平滑vec3灯光方向[最大灯光];
均匀的vec3颜色;
均匀照明;
均匀结构光{
vec3颜色;
vec3位置;
}uLights[MAX_LIGHTS];
真空总管(真空){
vAmbientDiffuseMaterial=夹具(iVertex,0.0,1.0);
vAmbientLight=vAmbientDiffuseMaterial*uAmbientColor;
gl_位置=uMVP*vec4(iVertex.xyz,1.0);
vPosition=gl_Position.xyz;
vNormals=正常化(非正常*非正常);
vModelView=(uModelView*vec4(iVertex,1)).xyz;
对于(int i=0;i
片段着色器:

#version 330

const int MAX_LIGHTS = 4;

uniform mat4 uModelView;

out vec4 oFinalColor;

smooth in vec3 vPosition;
smooth in vec3 vModelView;
smooth in vec3 vNormals;

smooth in vec3 vAmbientDiffuseMaterial;
smooth in vec3 vAmbientLight;
smooth in vec3 vLightDirection[MAX_LIGHTS];

// Light stuff

uniform int uNumLights;

uniform struct Light {
   vec3 color;
   vec3 position;
} uLights[MAX_LIGHTS];

const vec3 cSpecularMaterial = vec3( 0.9, 0.9, 0.9 );
const float cShininess       = 30.0;


void main(void) {
   vec3 lReflection, lSpecularLight = vec3( 0 ), lDiffuseLight = vec3( 0 );
   float lIntensity;

   // Specular Light
   for( int i = 0; i < uNumLights; ++i ) {
      lReflection     = normalize( reflect( -vLightDirection[i], vNormals) );
      lIntensity      = max( 0.0, dot( -normalize(vModelView), lReflection ) );

      lSpecularLight += cSpecularMaterial * uLights[i].color * pow( lIntensity, cShininess );

      // Diffuse Light
      lIntensity      = max( 0, dot( vNormals, vLightDirection[i] ) );

      // Here is the strange if part:
      // Only with the if lDiffuseLight is what it is supposed to be.
      if( uLights[i].color != vec3( 0, 0, 0 ) ) {
         lDiffuseLight  += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
      }
   }

   oFinalColor = vec4( vAmbientLight + lDiffuseLight + lSpecularLight, 1 );
}
#版本330
const int MAX_LIGHTS=4;
统一mat4 uModelView;
脱色vec4;
vec3位置平滑;
在vec3 vModelView中平滑;
在vec3 vNormals中平滑;
在vec3真空扩散材料中光滑;
在vec3 vAmbientLight中平滑;
在vec3灯光方向平滑[最大灯光];
//轻质材料
均匀照明;
均匀结构光{
vec3颜色;
vec3位置;
}uLights[MAX_LIGHTS];
常数vec3 cSpecularMaterial=vec3(0.9,0.9,0.9);
常数浮点数cshiness=30.0;
真空总管(真空){
vec3 lReflection,lSpecularLight=vec3(0),lDiffuseLight=vec3(0);
浮感;
//镜面反射光
对于(int i=0;i

我已经测试了所有制服,它们在着色器中的设置都是正确的。

@waaitt有什么错误?(特别是“很多”部分——只有3个地方可能是错误的,而事实并非如此)。我觉得不错。同样可以使用
cgc
编译。您是否考虑过尝试在例如shadertoy上重现问题?它不应该像你描述的那样,如果不是一些奇怪的NaN或完全无关的事情发生的话。使用Intel GPU和免费的nouveau驱动程序以及专有的NVidia驱动程序进行了更多的测试:该错误只发生在具有专有NVidia驱动程序的机器上。所有其他配置都正常工作。请尝试清除着色器缓存(
~/.nv/GLCache
对于*nix,
%USERPROFILE%\AppData\Local\Temp\NVIDIA Corporation\nv\u cache
对于windows)。如果问题仍然存在,请考虑将其移动到独立的示例中,并可能提交bug报告。清除缓存没有帮助。我将创建一个bug报告