Opengl 具有数组和条件的奇怪GLSL行为
我正在开发一个小型OpenGL引擎,目前遇到以下GLSL问题: 我试图为多个灯光实现一个着色器,它会生成正确的结果,但前提是我将漫反射灯光的计算放在一个(完全无用的)if语句中。specultar灯光组件始终正确渲染 作品: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
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报告