Java 延迟渲染管道无法在笔记本电脑图形卡上工作,以及奇数“;“模型重影”;问题(glBlendFunc)
编辑:更改片段着色器,使每次运行只能使用一个灯光,从而解决了我的第一个问题。我的第二个问题仍然存在 提前感谢您提供的任何帮助。我已经为我的LWJGL渲染引擎做了几个星期的延迟着色管道。我想我已经设法让一切都如我所期望的那样运作起来了,但是在把程序分发给我认识的几个人之后,我开始遇到问题。我会尽量把这个简短些。谢谢你陪我 我将从标题中的两个问题中的第一个开始。在我的机器(AMD Phenom II 965和Nvidia GTX 480)上,我的渲染器的最终产品完全符合预期。(我本来打算发布一个图像链接,但由于我是一个新用户,所以我无法发布超过3个超链接。但可以说,它看起来应该是这样的。) 这正是我想要的,所以我认为渲染器工作得很好。我把它寄给了一个朋友(他正在使用GT440),他们得到了相同的结果 不久之后,我给了我的一个朋友一个引擎的构建,他有一台笔记本电脑(GT540M)。这就是渲染器产生的结果(忽略FPS计数器,它不起作用): 显然,这根本不是我所期望的结果。我在其他所有能够测试的移动图形卡上都体验到了相同的结果。在一周多的时间里,我的头撞到了我的桌子上,我终于把问题缩小到了照明通道上,那里叫glBlendFunc。我的代码如下:Java 延迟渲染管道无法在笔记本电脑图形卡上工作,以及奇数“;“模型重影”;问题(glBlendFunc),java,opengl,lwjgl,glblendfunc,deferred-rendering,Java,Opengl,Lwjgl,Glblendfunc,Deferred Rendering,编辑:更改片段着色器,使每次运行只能使用一个灯光,从而解决了我的第一个问题。我的第二个问题仍然存在 提前感谢您提供的任何帮助。我已经为我的LWJGL渲染引擎做了几个星期的延迟着色管道。我想我已经设法让一切都如我所期望的那样运作起来了,但是在把程序分发给我认识的几个人之后,我开始遇到问题。我会尽量把这个简短些。谢谢你陪我 我将从标题中的两个问题中的第一个开始。在我的机器(AMD Phenom II 965和Nvidia GTX 480)上,我的渲染器的最终产品完全符合预期。(我本来打算发布一个图像
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
List<Float[]>[] listArray = LightData.getInstance().updateLights();
List<Float[]> lightsColor = listArray[1];
List<Float[]> lightsPos = listArray[0];
viewMatrix.setViewMatrix(camera.getTranslation(), camera.getRotation());
glDisable(GL_DEPTH_TEST);
glUseProgram(0);
glCallList(quadList);
FBO.useShader();
FBO.passTextures(); //Just sets the shader uniform values to the correct textures
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glLoadIdentity();
glBlendFunc(GL_ONE, GL_ONE) ; //using GL_ONE and GL_ONE_MINUS_SRC_ALPHA have the same effect
for (int i = 0; i < lightsPos.size(); i++) {
glClear(GL_DEPTH_BUFFER_BIT);
int uniformLightPosition = glGetUniformLocation(FBO.getShaderID(), "uniformLightPosition");
int uniformLightColor = glGetUniformLocation(FBO.getShaderID(), "uniformLightColor");
int uniformViewMatrix = glGetUniformLocation(FBO.getShaderID(), "uniformViewMatrix");
int uniformAmbient = glGetUniformLocation(FBO.getShaderID(), "uniformAmbient");
glUniform1(uniformLightPosition, Tools.asFloatBuffer(lightsPos.get(i)));
glUniform1(uniformLightColor, Tools.asFloatBuffer(lightsColor.get(i)));
glUniform1f(uniformAmbient, 0.01f);
glUniformMatrix4(uniformViewMatrix, true, viewMatrix.asFloatBuffer());
glCallList(quadList); //is just a display list for a fullscreen quad (using GL_QUADS)
}
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
据我所知,这段代码应该什么都不做。但是,当我删除四边形的图形时,窗口会显示以下内容:
除了“鬼影”,我不知道该怎么称呼它,因为它就像一个鬼影(至少在我看来是这样)。当我旋转MV矩阵时,它在我旋转的方向上扭曲,第一组灯光(我使用7个阵列)照亮它,但其余灯光照亮实际模型。我无法解释为什么会发生这种情况,因为生成此图像的代码与上面没有glCallList(quadList)的代码完全相同代码>这意味着深度和颜色缓冲区在我进入循环之前仍然被清除。我根本无法解释这个问题。有没有人知道什么地方出了问题以及如何修复,或者至少知道什么地方出了问题
编辑我发现这只发生在具有纹理坐标的模型上。我不知道为什么
编辑看起来,当我将每个着色器中允许的灯光数量限制为1时,重影变得不那么明显,但仍然存在,因此我假设这意味着一次片段着色器运行会导致这些重影
非常感谢任何人在这两个问题上给予的帮助,非常感谢。如果你有任何问题要问我,尽管我可能需要一些时间才能回复你,但我会尽快回复
编辑对不起,我忘了我的着色器代码:
几何体类顶点:
uniform sampler2D tex;
varying vec3 surfaceNormal;
varying vec3 varyingVertex;
void main() {
vec4 color = vec4(texture2D(tex, gl_TexCoord[1].st));
gl_FragColor = color;
}
几何虫碎片:
uniform sampler2D tex;
varying vec3 surfaceNormal;
varying vec3 varyingVertex;
uniform float materialValue;
uniform float specValue;
void main() {
vec4 color = vec4(texture2D(tex, gl_TexCoord[1].st)) ;//vec4(0.25,0.25,0.25,1);
vec4 vertex = vec4(varyingVertex, materialValue);
vec4 normal = vec4(surfaceNormal, specValue);
gl_FragData[0] = color;
gl_FragData[1] = vertex;
gl_FragData[2] = normal;
}
LightPass Phong顶点:
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewMatrix * gl_Vertex;
}
光通Phong片段
uniform sampler2D location;
uniform sampler2D normal;
uniform sampler2D color;
uniform float uniformLightPosition[21];
uniform mat4 uniformViewMatrix;
uniform float uniformLightColor[28];
void main() {
vec4 color = texture2D(color, gl_TexCoord[0].st);
vec4 locationAndMat = texture2D(location, gl_TexCoord[0].st);
vec4 normalAndSpec = texture2D(normal, gl_TexCoord[0].st);
vec3 vertexPosition = locationAndMat.xyz;
vec3 surfaceNormal = normalAndSpec.xyz;
float spec = normalAndSpec.a;
float specA = locationAndMat.a;
vec4 lightColor[7];
int iterator = 0;
for (int i = 0; i<28; i = i+4) {
lightColor[iterator] = vec4(uniformLightColor[i], uniformLightColor[i+1], uniformLightColor[i+2], uniformLightColor[i+3]);
iterator = iterator + 1;
}
vec3 lightPos[7];
iterator = 0;
for (int i = 0; i<21; i = i+3) {
lightPos[iterator] = vec3(uniformLightPosition[i], uniformLightPosition[i+1], uniformLightPosition[i+2]);
lightPos[iterator] = (uniformViewMatrix * vec4(lightPos[iterator],1)).xyz ;
iterator = iterator + 1;
}
vec4 fragData[7];
vec4 endColor;
for (int i = 0; i<7 ; i++) {
if (lightColor[i] != vec4(0,0,0,0) && color != vec4(0,0,0,0)) {
vec3 lightDistance = lightPos[i]-vertexPosition;
float distance = pow((pow(lightDistance.x, 2) + pow(lightDistance.y, 2) + pow(lightDistance.z, 2)), 0.5);
if (distance < lightColor[i].a) {
float att = 1/((-3/800*(lightColor[i].a) + 0.225)*pow(distance, 2));
vec3 lightDirection = normalize(lightDistance);
float diffuseLightIntensity = max(0.0, dot(surfaceNormal, lightDirection));
fragData[i] += (vec4(diffuseLightIntensity,diffuseLightIntensity,diffuseLightIntensity,1));
vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));
float specular = max(0.0, dot(reflectionDirection, -normalize(vertexPosition)));
if (diffuseLightIntensity != 0) {
float fspecular = pow(specular, spec);
vec4 fspec = vec4(fspecular*specA, fspecular*specA, fspecular*specA,1);
fragData[i] += fspec;
}
fragData[i] *= lightColor[i];
fragData[i] *= 0.1;
fragData[i].a = 0;
fragData[i] *= att;
endColor += fragData[i];
}
}
}
gl_FragData[0] = endColor * color;
}
统一取样器二维定位;
均匀二维法线;
颜色均匀;
均匀浮动均匀灯光位置[21];
均匀mat4均匀矩阵;
均匀浮动均匀灯光颜色[28];
void main(){
vec4 color=texture2D(颜色,gl_TexCoord[0].st);
vec4 locationAndMat=texture2D(位置,gl_TexCoord[0].st);
vec4 normalAndSpec=texture2D(normal,gl_TexCoord[0].st);
vec3=位置和材料xyz;
vec3 surfaceNormal=法线和规格xyz;
浮动等级=普通等级和等级a;
浮子规格a=位置和材料a;
vec4-lightColor[7];
int迭代器=0;
for(int i=0;i我解决了主要问题!这对我来说已经足够好了。我遇到的问题似乎是每个片段着色器需要很多指令(因为for循环)。当我将着色器调整为只允许一个灯光时,它按预期工作!我只是像以前一样使用混合来处理所有事情,但运行着色器的次数更多。缺点是它需要更多的过滤,但优点是它可以在较旧的硬件和笔记本电脑上工作
我仍然无法找出造成重影的原因,但这对我来说不太重要,因为我对此的修复很差。我解决了主要问题!这对我来说已经足够好了。我遇到的问题似乎是每个片段着色器都有很多指令(因为for循环)。当我将着色器调整为只允许一个灯光时,它按预期工作!我只是像以前一样使用混合来处理所有事情,但运行着色器的次数更多。缺点是它需要更多的过滤,但优点是它可以在较旧的硬件和笔记本电脑上工作
我仍然无法找出造成重影的原因,但这对我来说不太重要,因为我对此的修复很差。看起来我解决了第一个问题!看起来我解决了第一个问题!
uniform sampler2D location;
uniform sampler2D normal;
uniform sampler2D color;
uniform float uniformLightPosition[21];
uniform mat4 uniformViewMatrix;
uniform float uniformLightColor[28];
void main() {
vec4 color = texture2D(color, gl_TexCoord[0].st);
vec4 locationAndMat = texture2D(location, gl_TexCoord[0].st);
vec4 normalAndSpec = texture2D(normal, gl_TexCoord[0].st);
vec3 vertexPosition = locationAndMat.xyz;
vec3 surfaceNormal = normalAndSpec.xyz;
float spec = normalAndSpec.a;
float specA = locationAndMat.a;
vec4 lightColor[7];
int iterator = 0;
for (int i = 0; i<28; i = i+4) {
lightColor[iterator] = vec4(uniformLightColor[i], uniformLightColor[i+1], uniformLightColor[i+2], uniformLightColor[i+3]);
iterator = iterator + 1;
}
vec3 lightPos[7];
iterator = 0;
for (int i = 0; i<21; i = i+3) {
lightPos[iterator] = vec3(uniformLightPosition[i], uniformLightPosition[i+1], uniformLightPosition[i+2]);
lightPos[iterator] = (uniformViewMatrix * vec4(lightPos[iterator],1)).xyz ;
iterator = iterator + 1;
}
vec4 fragData[7];
vec4 endColor;
for (int i = 0; i<7 ; i++) {
if (lightColor[i] != vec4(0,0,0,0) && color != vec4(0,0,0,0)) {
vec3 lightDistance = lightPos[i]-vertexPosition;
float distance = pow((pow(lightDistance.x, 2) + pow(lightDistance.y, 2) + pow(lightDistance.z, 2)), 0.5);
if (distance < lightColor[i].a) {
float att = 1/((-3/800*(lightColor[i].a) + 0.225)*pow(distance, 2));
vec3 lightDirection = normalize(lightDistance);
float diffuseLightIntensity = max(0.0, dot(surfaceNormal, lightDirection));
fragData[i] += (vec4(diffuseLightIntensity,diffuseLightIntensity,diffuseLightIntensity,1));
vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));
float specular = max(0.0, dot(reflectionDirection, -normalize(vertexPosition)));
if (diffuseLightIntensity != 0) {
float fspecular = pow(specular, spec);
vec4 fspec = vec4(fspecular*specA, fspecular*specA, fspecular*specA,1);
fragData[i] += fspec;
}
fragData[i] *= lightColor[i];
fragData[i] *= 0.1;
fragData[i].a = 0;
fragData[i] *= att;
endColor += fragData[i];
}
}
}
gl_FragData[0] = endColor * color;
}