[英]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.