gpt4 book ai didi

c++ - OpenGL 中的视差映射故障

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:48:49 25 4
gpt4 key购买 nike

alt text alt text

这是在将切线 vector 传输到顶点着色器后立即反转切线 vector 时的结果:

alt text alt text

“影子”放错地方了。

(并且它仅在我通过 Y 轴旋转它时才起作用,所以最后一张图像似乎呈现出一个很好的视差映射立方体)

我确定这不是切 vector 或纹理坐标问题

因为

我使用了与工作演示中完全相同的切线计算函数完全相同的立方体位置、法线和纹理坐标数据。毕竟,我将带有 position/texcoord/normal/tangent 数据的数组导出到一个 .txt 文件中,我看到了我所期望的(我所期望的是与工作演示中相同的 pos/tex/norm 数据,包括计算出的切线我设法从工作演示中导出)。

下一个论点是,我将我的着色器代码复制到一个工作演示中并且它仍然工作。另一个是,我尝试了多种方法来渲染这个立方体。我尝试了使用 glVertexAttribPointer 的 VBO,我尝试了将切线保存为其他纹理坐标的 VBO(如演示中所示),我尝试了使用 glVertexAttrib4f 的 DisplayList。结果是……完全一样。

高度贴图加载正确,我尝试将其设置为漫反射贴图,看起来还不错。glGetError() 给我没有错误,着色器编译日志也是如此。

这可能与相机或初始化状态有关。

也许发布初始化代码会有帮助。

void CDepthBase::OpenGLSet() {

glEnable( GL_TEXTURE_2D );
glShadeModel( GL_SMOOTH );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClearDepth( 1.0f );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDepthFunc( GL_LEQUAL );
glEnable(GL_DEPTH_TEST);



glBlendFunc( GL_ONE, GL_ONE );
GLfloat ratio;

glViewport(0, 0, ResolutionWidth, ResolutionHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, ResolutionWidth / (float)ResolutionHeight, 0.1f, 900.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

if (GLEW_OK != glewInit()) {
MBX("Failed to init GLEW.", "Error");
}
if (glewIsSupported("GL_ARB_vertex_buffer_object")) {
VBO_supported = true;


} else VBO_supported = false;

glHint( GL_FOG_HINT, GL_DONT_CARE );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glShadeModel(GL_SMOOTH);

glAlphaFunc(GL_ALWAYS, 0);
}

顺便说一下,我正在使用带有扩展的 GL Extension Wrangler。

着色器代码和日志(此导出文件包含直接传递给 glShaderSource 的代码):

Vertex shader was successfully compiled to run on hardware.


Fragment shader was successfully compiled to run on hardware.

Fragment shader(s) linked, vertex shader(s) linked.


------------------------------------------------------------------------------------------


varying vec3 lightDir;
varying vec3 viewDir;
attribute vec4 tangent;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tn = tangent.xyz;
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * tangent.xyz);
vec3 b = cross(t, n) * -tangent.w;
mat3 tbnMatrix = mat3(t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.z, n.z);
lightDir = (gl_LightSource[0].position.xyz - vertexPos) / 100.0;
lightDir = tbnMatrix * lightDir;
viewDir = -vertexPos;
viewDir = tbnMatrix * viewDir;
}

-----------------------------------------------------------------------------------------
varying vec3 lightDir;
varying vec3 viewDir;
uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
uniform sampler2D heightMap;
uniform float scale;
uniform float bias;
void main()
{
vec3 v = normalize(viewDir);
vec2 TexCoord = gl_TexCoord[0].st;
{
float height = texture2D(heightMap, gl_TexCoord[0].st).r;
height = height * scale + bias;
TexCoord = gl_TexCoord[0].st + (height * v.xy);
}
vec3 l = lightDir;
float atten = max(0.0, 1.0 - dot(l, l));
l = normalize(l);
vec3 n = normalize(texture2D(normalMap, TexCoord).rgb * 2.0 - 1.0);
vec3 h = normalize(l + v);
float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
vec4 ambient = gl_FrontLightProduct[0].ambient * atten;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL * atten;
vec4 specular = gl_FrontLightProduct[0].specular * power * atten;
vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;color *= texture2D(diffuseMap,TexCoord);
gl_FragColor = color ;
}

制服工作正常,因为如果我用常量值切换它们,结果是相同的。编译着色器:

void __Shader::import(){
if(imported) __Shader::~__Shader();

v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);


glShaderSource(v, 1, (const GLchar **)&vsrc.cstr,NULL);
glShaderSource(f, 1, (const GLchar **)&fsrc.cstr,NULL);

glCompileShader(v);
glCompileShader(f);

p = glCreateProgram();

glAttachShader(p,v);
glAttachShader(p,f);

if(_flags & NORMAL_MAPPING)
glBindAttribLocation(p, ATTRIB_TANGENT, "tangent");

glLinkProgram(p);

if(_flags & DIFFUSE_MAPPING)
diffuseUni.loc = glGetUniformLocation(p, "diffuseMap");
if(_flags & NORMAL_MAPPING)
normalUni.loc = glGetUniformLocation(p, "normalMap");
if(_flags & PARALLAX_MAPPING)
heightUni.loc = glGetUniformLocation(p, "heightMap");
if(_flags & SPECULAR_MAPPING)
specularUni.loc = glGetUniformLocation(p, "specularMap");

imported = true;
}

在 VBO 中设置属性:

    if(tangents.size() > 0){
buffered |= 3;
glGenBuffers(1, &VBO_tangent);
glBindBuffer(GL_ARRAY_BUFFER, VBO_tangent);
glBufferData(GL_ARRAY_BUFFER, tangents.size()*sizeof(tangent), tangents.get_ptr(), GL_STATIC_DRAW);
}

// and in draw:

if(buffered & 3) {

glBindBuffer(GL_ARRAY_BUFFER, VBO_tangent);
glVertexAttribPointer(__Shader::ATTRIB_TANGENT, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(__Shader::ATTRIB_TANGENT);
}

还有一张小纸条

for(int i = 0; i < responders.size(); ++i)
if(strstr(responders[i].idea, "tangent problem"))
responders[i].please_dont_talk();

请告诉我您对导致这些不良结果的原因的其他想法。

最佳答案

哇...已经解决了。问题是加载纹理文件,即使我没有看到漫反射贴图或什至漫反射+法线贴图有任何紊乱。我使用的是 SDL 的 IMG_Load,也许我用错了它,但它对我不起作用。这可能是法线贴图搞砸了。

错误的纹理导入代码:

if(imported || filenamez.length() < 1) return;
SDL_Surface* surface = 0;


surface = IMG_Load(filenamez.c_str());

if (surface) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
bool endianess = filenamez.substr(filenamez.length()-4) == ".jpg";
glTexImage2D(GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0,
(endianess ? GL_RGB : GL_BGR), GL_UNSIGNED_BYTE, surface->pixels);

}

小心!

我现在正在使用从我正在谈论的 dhpoware 演示中获取的基于 HBITMAP 的纹理加载。而且效果很好。

和平。

经过2-3天的艰苦调试,让我感到了一丝欣喜。

哦,我忘了,最后的结果: alt text

关于c++ - OpenGL 中的视差映射故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4750707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com