簡體   English   中英

使用GLSL合成瓷磚的紋理坐標

[英]Composing a tile's texture coordinates using GLSL

前言

考慮以下示例圖像:

Tilesheet示例


請注意以下幾點:

  • 每個圖塊索引從左到右,從上到下遞增
  • 只有28個有效磁貼(可能為32個)
  • 在此示例中,我們知道每個圖塊的像素均為32x32
  • 我們也知道整體圖片尺寸為256x128像素

僅給出上述信息和有效的瓦片索引,我們如何使用頂點着色器構造適當的紋理坐標以用於所需的瓦片,然后將其傳遞給片段着色器進行采樣? 幸運的是,我們可以使用gl_VertexID來確定所需的圖像“拐角” ...但是由於我們正在使用歸一化的Textels(而不只是像素),因此需要某種方式將尺寸縮小到0到如圖1所示,這進一步使算法復雜化。

這是我到目前為止的內容,盡管它似乎只顯示圖像中的純色

#version 330 core

layout(location=0) in vec3 in_pos;
out vec2 out_texCoord;

void main()
{
    // These will eventually be uniforms/attributes, and are
    //  only used here for more immediate debugging purposes
    int tileNum = 1;        // Desired tile index
    int tileCount = 28;     // Maximum # of tiles
    float tileWidth = 32;   // Width of each tile in pixels
    float tileHeight = 32;  // Height of each tile in pixels
    float imgWidth = 256;   // Overall width of image in pixels
    float imgHeight = 128;  // Overall height of image in pixels

    // Attempt to calculate the correct texture coordinates
    //  for the desired tile, given only the above info...
    int tileIndex = tileNum % tileCount;
    int columnCount = int(imgWidth / tileWidth);
    int rowCount = int(imgHeight / tileHeight);
    int tileX = tileIndex % columnCount;
    int tileY = int(float(tileIndex) / float(columnCount));

    float startX = float(tileX) * tileWidth;
    float startY = float(tileY) * tileHeight;
    float endX = 1.0f / (startX + tileWidth);
    float endY = 1.0f / (startY + tileHeight);
    startX = 1.0f / startX;
    startY = 1.0f / startY;

    // Check which corner of the image we are working with
    int vid = gl_VertexID % 4;
    switch(vid) {
        case 0:
            out_texCoord = vec2(startX, endY);
            break;
        case 1:
            out_texCoord = vec2(endX, endY);
            break;
        case 2:
            out_texCoord = vec2(startX, startY);
            break;
        case 3:
            out_texCoord = vec2(endX, startY);
            break;
    }
    gl_Position = vec4(in_pos, 1);
}



放棄

在任何人開始談論缺乏信息/代碼之前,請注意,使用以下代碼確實確實可以按預期正確顯示整個圖像...
實際上,這意味着實際的紋理坐標計算存在問題,
而不是我的應用程序的OpenGL實現:

int vid = gl_VertexID % 4;
switch(vid) {
    case 0:
        out_texCoord = vec2(0, 1);
        break;
    case 1:
        out_texCoord = vec2(1, 1);
        break;
    case 2:
        out_texCoord = vec2(0, 0);
        break;
    case 3:
        out_texCoord = vec2(1, 0);
        break;
}

反轉紋理坐標似乎是在黑暗中的鏡頭。 您只需要按比例縮小:

float endX = (startX + tileWidth) / imgWidth;
float endY = (startY + tileHeight) / imgHeight;
startX = startX / imgWidth;
startY = startY / imgHeight;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM