视差映射 - GLSL-OpenGL

时间:2014-08-20 00:32:20

标签: c++ opengl 3d glsl parallax

在过去的几天里,我一直试图在我的引擎中实现视差映射,但它似乎不起作用,我至少看过15个例子,而我仍然无法获得它工作

这是一张图片:enter image description here

如您所见,您只能看到基色,高度图不存在

以下是我的着色器:

Fragment Shader

#version 330 core
uniform sampler2D DiffuseTextureSampler;
uniform sampler2D HeightTextureSampler;
vec2 scaleBias = vec2(0.5,0.5); 
in vec3 EyeDirection_tangentspace;
in vec2 UV;
void main() 
{ 
 float height = texture2D(HeightTextureSampler, vec2 (UV.x, -UV.y)).r; 
 //Our heightmap only has one color channel.
 float v = height * scaleBias.r - scaleBias.g; 
 vec3 eye = EyeDirection_tangentspace; 
 vec2 newCoords = UV + (eye.xy * v); 

 vec3 rgb = texture2D(DiffuseTextureSampler,  vec2 (newCoords.x, -newCoords.y)).rgb; 
 gl_FragColor = vec4(rgb, 1.0); 
}






Vertex Shader

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal_modelspace;
layout(location = 3) in vec3 vertexTangent_modelspace;
layout(location = 4) in vec3 vertexBitangent_modelspace;

// Output data ; will be interpolated for each fragment.
out vec2 UV;
out vec3 Position_worldspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;

out vec3 LightDirection_tangentspace;
out vec3 EyeDirection_tangentspace;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;
uniform mat4 V;
uniform mat4 M;
uniform mat3 MV3x3;
uniform vec3 LightPosition_worldspace;

void main() 
{ 
 gl_Position = MVP * vec4(vertexPosition_modelspace,1);

Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz;

    // Vector that goes from the vertex to the camera, in camera space.
    // In camera space, the camera is at the origin (0,0,0).
    vec3 vertexPosition_cameraspace = ( V * M * vec4(vertexPosition_modelspace,1)).xyz;
    EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;


 UV = vertexUV;
 vec3 vertexTangent_cameraspace = MV3x3 * vertexTangent_modelspace;
    vec3 vertexBitangent_cameraspace = MV3x3 * vertexBitangent_modelspace;
    vec3 vertexNormal_cameraspace = MV3x3 * vertexNormal_modelspace;

 mat3 TBNMatrix = transpose(mat3(vertexTangent_cameraspace, vertexBitangent_cameraspace, vertexNormal_cameraspace)); 
 EyeDirection_tangentspace = Position_worldspace - vertexPosition_modelspace.xyz; 
 EyeDirection_tangentspace *= TBNMatrix; 
}

1 个答案:

答案 0 :(得分:1)

一些事情

  1. 将您的比例设置为1.如果你根本看不到你的高度,那么没有任何意义。

  2. (您的当前问题)您将使用-UV.y获得纹理坐标.Outngl没有负纹理坐标。获得否定将从纹理中拉出任何东西,或者如果你有平铺,则更糟糕的是镜像纹理。

  3. (您的下一个问题)在计算片段中的新坐标之前规范化您的眼睛向量。如果你没有标准化,矢量的XY坐标将会很大,所以你的新纹理坐标是大量偏移。

  4. 尝试这些着色器。它们很简单而且很有效。你必须在视差工作后添加光照

    顶点着色器

    attribute vec3 tangent;
    attribute vec3 binormal;
    uniform vec3 CAMERA_POSITION;
    varying vec3 eyeVec;
    void main()
    {
        gl_Position = ftransform();
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
    
        mat3 TBNMatrix = mat3(tangent, binormal, gl_Normal);
        eyeVec = CAMERA_POSITION - gl_Vertex.xyz;
        eyeVec *= TBNMatrix;
    }
    

    片段着色器

    uniform sampler2D basetex;
    uniform sampler2D heightMap;
    uniform vec2 scaleBias;
    varying vec3 eyeVec;
    void main()
    {
        float height = texture2D(heightMap, gl_TexCoord[0].st).r;
    
        float v = height * scaleBias.r - scaleBias.g;
        vec3 eye = normalize(eyeVec);
        vec2 newCoords = texCoord + (eye.xy * v);
    
        vec3 rgb = texture2D(basetex, newCoords).rgb;
        gl_FragColor = vec4(rgb, 1.0);
    }