簡體   English   中英

隧道着色器(從WebGL轉換為OpenGL) - 紋理坐標不匹配?

[英]Tunnel shader (converted from WebGL to OpenGL) - texture coords do not match?

我試過上周將來自不同WebGL示例的經典隧道演示效果轉換為openFrameroks(使用OpenGL GLSL着色器)。 經過大量的研究,試驗和錯誤,主要是在閱讀[本綜合教程] [1]和[這一個] [2]后,我仍然不明白為什么轉換后的着色器不起作用。 它至少是我認為紋理坐標的問題。

就我對原理的理解而言,你可以通過計算距離中心的角度和距離來獲得紋理的像素值,並將它們作為輸出傳遞。 但結果卻截然不同。 這是來自我開始嘗試的代碼的[ShaderToy示例] [3]和[這里是示例] [4]的結果。 以下是我在openFrameworks中得到的內容:![在此處輸入圖像描述] [5]將紋理傳遞給着色器:![在此處輸入圖像描述] [6]看起來這個着色器只是通過像素的頂行暫停一段時間,屏幕保持一種顏色(就像到達隧道的盡頭)。 我嘗試使用紋理只是顏色噪聲作為像素,顏色最后階段正好是黃色,作為頂行的最后一個像素。 奇怪。 希望有人可以告訴我問題出在哪里。

這是testApp.cpp

void testApp::setup(){

    texture.loadImage("koalaSQ.jpg"); // 512x512px
    tunnel.load("tunnel.vert", "tunnel.frag");
    projection.set(640, 480);
    projection.setPosition(320, 240, 0);
    projection.setResolution(2,2);
    projection.mapTexCoordsFromTexture(texture.getTextureReference());  

 }

void testApp::draw(){
ofSetColor(255);

if (ofGetKeyPressed('g')) // used just for testing texture
{

    ofBackground(0, 0, 0);
    texture.bind();
    projection.draw();
    texture.unbind();

}else
{
    ofBackground(0, 0, 0);
    tunnel.begin();
    tunnel.setUniform1f("timeE", time/1000);
    tunnel.setUniform2f("resolution", 512,512);
    tunnel.setUniformTexture("tex", texture.getTextureReference(), 0);
    projection.draw();

    tunnel.end();


}

time = ofGetElapsedTimeMillis();

}

這是着色器:

 // vertex shader - simple pass-though with texcoodrs as output for fragent shader
#version 150
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 texC;

void main()
{   
    gl_Position = modelViewProjectionMatrix * position;
    texC = texcoord;
}
// ------------------------Fragent shader----------------------
#version 150
precision highp float;
uniform sampler2DRect tex;
uniform float timeE;
uniform vec2 resolution;
in vec2 texC;
out vec4 output;

void main(){

vec2 position = 2.0 * texC.xy / resolution.xy -1.0;
position.x *= resolution.x / resolution.y;

float a = atan(position.y, position.x);
float r = length(position);

vec2 uv = vec2(1/ r + (timeE*5), a/3.1416);
  vec3 texSample = texture(tex, uv).xyz;
 output = vec4(vec3(texSample), 1);
}

您沒有說明許多細節(即您使用texcoord的值)。 但是,我想我仍然可以解釋為什么你的代碼只導致訪問底行(當你使用從上到下的圖像數組作為glTexImage()的圖像數據時,你可能會認為它是頂行,但從技術上講,它將是最底行。)

在獲取紋理時,您使用uv作為坐標。 你將uv.y定義為atan(position.y, position.x)/3.1415 由於atan()將在[-pi, pi]返回一個vlue,因此將coord大致標准化為區間[-1,1] 經典的OpenGL紋理空間為[0,1] ,其中0表示底行,1表示頂行。 但是,您使用的是sampler2DRect ,因此您使用的是矩形紋理 在這種情況下,tex坐標不是標准化的,而是水平方向上的像素坐標[0,width]和垂直方向上的[0,height]

實際上,您的texcoords確實只在兩個紋素的范圍內變化。 根據您所設置的包裝(和過濾器)模式下,你應該只用clapming,或additionaly(兩兩行之間或過濾)頂部一行訪問底排(或過濾betwenn兩個底部行) GL_REPEAT為消極的部分。

暫無
暫無

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

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