【问题标题】:How can I texture with vertex position coordinates? openGL,c++如何使用顶点位置坐标进行纹理处理? openGL,c++
【发布时间】:2016-09-18 12:30:36
【问题描述】:

我想在没有预先确定的纹理坐标的情况下对我的地形进行纹理处理。我想使用顶点位置坐标确定顶点或碎片着色器中的坐标。我现在使用位置“xz”坐标(up=(0,1,0)),但是如果我有一个与地面成 90 度的墙,那么纹理将是这样的:

如何将这些坐标转换为这个位置才能正常工作?

这是我的顶点着色器:

#version 430

in layout(location=0) vec3 position;
in layout(location=1) vec2 textCoord;
in layout(location=2) vec3 normal;

out vec3 pos;
out vec2 text;
out vec3 norm;


uniform mat4 transformation;

void main()
{   
    gl_Position = transformation * vec4(position, 1.0);
    norm = normal;
    pos = position;
    text = position.xz;

}

这是我的碎片着色器:

#version 430

in vec3 pos;
in vec2 text;
in vec3 norm;

//uniform sampler2D textures[3];

layout(binding=3) uniform sampler2D texture_1;
layout(binding=4) uniform sampler2D texture_2;
layout(binding=5) uniform sampler2D texture_3;

vec3 lightPosition = vec3(-200, 700, 50);
vec3 lightAmbient = vec3(0,0,0);
vec3 lightDiffuse = vec3(1,1,1);
vec3 lightSpecular = vec3(1,1,1);

out vec4 fragColor;
vec4 theColor;



void main()
{
    vec3 unNormPos = pos;
    vec3 lightVector = normalize(lightPosition) - normalize(pos);
    //lightVector = normalize(lightVector);

    float cosTheta = clamp(dot(normalize(lightVector), normalize(norm)), 0.5, 1.0);

    if(pos.y <= 120){
        fragColor = texture2D(texture_2, text*0.05) * cosTheta;
    }
    if(pos.y > 120 && pos.y  <  150){
        fragColor = (texture2D(texture_2, text*0.05) * (1 - (pos.y-120)/29) +  texture2D(texture_3, text*0.05) * ((pos.y-120)/29))*cosTheta;
    }
    if(pos.y >= 150)
    {
        fragColor = texture2D(texture_3, text*0.05) * cosTheta;
    }   
}

编辑:(Fons)

text = 0.05 * (position.xz + vec2(0,position.y)); 

text = 0.05 * (position.xz + vec2(position.y,position.y)); 

现在墙可以工作,但地形不行。

【问题讨论】:

    标签: c++ opengl textures fragment-shader texture2d


    【解决方案1】:

    这个问题实际上是一个非常困难的问题,因为你无法设计一个公式来正确显示垂直墙壁的纹理坐标,只使用 xyz 坐标。

    为了形象化这一点,请想象一块平坦土地旁边的一座小山。由于经过山丘的路径比经过平坦土地的路径更长,因此纹理应该在山丘上包裹更多次,而不是在平坦土地上。在下图中,纹理在山丘上包裹 5 次,在平板上包裹 4 次。

    如果纹理坐标是左边的(0,0),那么它们应该是右边的(4,0)还是(5,0)?由于两个答案都是有效的,这证明没有函数可以纯粹根据 xyz 坐标计算正确的纹理坐标。 :(

    但是,您的问题可能会通过不同的方法得到解决:

    • 可以通过独立于地形生成墙壁并为其分配正确的纹理坐标来校正墙壁。实际上,不将它们合并到您的地形中更有意义。
    • 您可以使用法线贴图、更高分辨率的纹理或不同纹理的组合为陡峭山坡的侧面添加更多细节。可能有更好的解决方案,我不知道。

    编辑:Triplanar mapping 将解决您的问题!

    【讨论】:

    • 三平面映射解决了我的问题。非常感谢:)
    【解决方案2】:

    试试:

    text = position.xz + vec2(0,y);
    

    另外,我建议在顶点着色器而不是片段着色器中设置*0.05 比例因子。最终代码是:

    text = 0.05 * (position.xz + vec2(0,y));
    

    【讨论】:

    • "+ vec2(0,y)" 你的意思是 "vec2(0,position.y)" 吗?它看起来不错,但还不完美。我用新的截图编辑了帖子。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多