我一直在尝试为地形着色器实现高度贴图,但地形仍然平坦。纹理已正确加载到顶点着色器中,我尝试使用基于网格uvs的纹理灰度值来调整顶点高度:
//DIFFUSE VERTEX SHADER
#version 330
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec3 vertex;
in vec3 normal;
in vec2 uv;
uniform sampler2D heightmap;
out vec2 texCoord;
void main( void ){
vec3 _vertex = vertex;
_vertex.y = texture(heightmap, uv).r * 2.f;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(_vertex, 1.f);
texCoord = uv;
}
片段:(飞溅图工作,所以忽略它)
uniform sampler2D splatmap;
uniform sampler2D diffuse1;
uniform sampler2D diffuse2;
uniform sampler2D diffuse3;
uniform sampler2D diffuse4;
in vec2 texCoord;
out vec4 fragment_color;
void main( void ) {
///Loading the splatmap and the diffuse textures
vec4 splatTexture = texture2D(splatmap, texCoord);
vec4 diffuseTexture1 = texture2D(diffuse1, texCoord);
vec4 diffuseTexture2 = texture2D(diffuse2, texCoord);
vec4 diffuseTexture3 = texture2D(diffuse3, texCoord);
vec4 diffuseTexture4 = texture2D(diffuse4, texCoord);
//Interpolate between the different textures using the splatmap's rgb values (works)
diffuseTexture1 *= splatTexture.r;
diffuseTexture2 = mix (diffuseTexture1, diffuseTexture2, splatTexture.g);
diffuseTexture3 = mix (diffuseTexture2,diffuseTexture3, splatTexture.b);
vec4 outcolor = mix (diffuseTexture3, diffuseTexture4, splatTexture.a);
fragment_color = outcolor;
}
一些附加信息:所有纹理都像这样加载到我的地形材质中,并传递到着色器(正常工作):
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, heightMap->getId());
glUniform1i (_shader->getUniformLocation("heightMap"),0);
...
平面网格uvs映射如下:
(0,1)(1,1)
(0,0)(1,0)
我想我做错了什么,但我不知道是什么。感谢您的帮助!
你写这个吗:
平面网格uvs映射如下:
(0,1)(1,1)
(0,0)(1,0)
…意味着您的网格仅由4个顶点组成?如果是这样的话,那么这就是你的问题所在:"顶点"着色器无法神奇地创建"新"顶点,因此你的高度贴图纹理只在4个点采样(中间没有采样)。
因为你以整数值和纹理坐标对纹理坐标进行采样,并且分别为0和1,所以你实际上是在对相同的纹理坐标进行取样,所以你会看到所有四个顶点都有相同的位移。
解决方案:对基础网格进行Tesselate,以便实际存在可用于置换的顶点。镶嵌着色器非常适合。
编辑:
顺便说一句,你可以简单地修改你的顶点着色器:对于属性,使其成为
in vec2 vertex;
这只需要vec3的2/3空间,因为您无论如何都没有使用z组件。
float y = texture(heightmap, uv).r * 2.f;
gl_Position =
projectionMatrix
* viewMatrix
* modelMatrix
* vec4(vertex.x, y, vertex.y, 1.f);