2014-11-24 117 views
2

我希望能夠(在片段着色器中)添加一個紋理到另一個。現在我有投影紋理,並希望擴大。寫入紋理GLSL

這是我到目前爲止有:

林還繪製沿着藍色/灰色測試圖像投射到是在不斷旋轉的幾何viewfrustum。

我的頂點着色器:

ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; 

我的片段着色器:

vec4 diffuse = texture(texture1, vs_st); 
vec4 projTexColor = textureProj(texture2, ProjTexCoord); 
vec4 shaded = diffuse; // max(intensity * diffuse, ambient); -- no shadows for now 
    if (ProjTexCoord[0] > 0.0 || 
     ProjTexCoord[1] > 0.0 || 
     ProjTexCoord[0] < ProjTexCoord[2] || 
     ProjTexCoord[1] < ProjTexCoord[2]){ 
     diffuse = shaded; 
    }else if(dot(n, projector_aim) < 0){ 
     diffuse = projTexColor; 
    }else{ 
     diffuse = shaded; 
    } 

我想實現:

時 - 例如用戶按下按鈕,我想要藍色/灰色紋理爲寫入球體上的灰色紋理,並用它轉動。試想一下,將其作爲「拍攝照片」或繪畫在球體頂部,以便在按下按鈕之後藍色/灰色紋理與球體一起旋轉。

由於片段着色器在每個像素上運行,因此應該可以將像素逐像素從一個紋理複製到另一個紋理,但我不知道如何,我可能會用錯誤的東西搜索。

我怎樣才能實現這一技術?什麼方法是最通用的?建議非常感謝,請讓我知道如果更多的代碼是必要的。

+0

是沿着你想要的東西的行幀緩衝區對象? http://www.songho.ca/opengl/gl_fbo.html – BlamKiwi 2014-11-24 22:37:38

+0

@MorphingDragon我從來沒有使用過FBO的。那麼這個想法是FBO成爲球體的最終輸出紋理?有點像我經常修改的緩存紋理? – mike 2014-11-24 22:54:23

+0

非常。無論如何,這只是GPU的唯一路線。 – BlamKiwi 2014-11-24 23:09:13

回答

2

爲了清楚起見,您希望將貼花烤成球體的灰色紋理。

在繪製另一個對象時寫入灰色紋理的麻煩是它不是一對一的。您可能會將兩次或更多次寫入相同的紋理元素,或者單個片段可能需要在灰色紋理中寫入許多紋理元素。這聽起來很有吸引力,因爲你已經擁有一個地方的所有座標,但我不會這樣做。

我首先創建一個紋理,其中包含灰色紋理中每個紋理元素的對象空間位置。這是關鍵,所以當你點擊你可以渲染你的灰色紋理(使用FBO),並知道每個紋素在你當前視圖或投影紋理視圖中的位置。可能存在邊緣情況,其中在多個三角形上出現相同的紋理位。您可以通過使用紋理座標作爲頂點位置將您的球體渲染爲灰色紋理來實現此目的。你可能需要一個浮點紋理,下面的圖像可能不是球體的紋理映射,但它可以用於演示:P。

enter image description here

所以,當你點擊,您呈現一個全屏幕的四到您的灰色紋理alpha混合功能。使用灰色紋理對象空間位置,每個片段計算藍色紋理投影內的圖像空間位置。丟棄紋理之外的碎片,並在裏面的碎片中進行採樣/混合。

enter image description here

+0

我已經在CPU上實現了這個功能,結果如下:[鏈接到結果](http://imgur.com/yxnPGZF) - 我需要很長時間才能在GPU上實現它。 **問題:**我該怎麼做呢?我的意思是:我以前從來沒有和FBO合作過,並且發現很難理解這個概念 - 我是否爲渲染到FBO創建了一個完整的獨立vert/frag着色器管道?我所擁有的是標準glUseProgram(「myShader」);/*傳遞制服等*/glUseProgram(0); imageProject()。我在代碼中的哪裏(如何)做FBO渲染? – mike 2014-12-17 16:18:10

+0

哦,還有,因爲我不能弄清楚FBO渲染,所以我嘗試通過計算着色器(目前似乎不起作用):[Other Stack-question](http://stackoverflow.com/q /2579996分之27494768) – mike 2014-12-17 16:21:40

0

我認爲你是過於複雜的事情。

  • 寫入經典着色器中的紋理(即不是計算着色器)僅適用於最新的硬件和最新的OpenGL版本和擴展。
  • 如果使用錯誤,速度可能非常慢。引入流水線延遲和CPU-GPU同步點非常容易
  • 像素着色器可能會變得非常緩慢而難以維護的分支和紋理提取。
  • 而這一切的混亂會爲每一個像素來完成每一個幀

解決方法:KISS

  • 只需更新您的CPU側質感。
  • 寫入紋理,用所需的內容替換部分紋理
  • 更新只需要進行一次,並且只在需要時進行。數據仍然存在,直到你把它改寫(甚至不是每幀一次,但每次變更請求只有一次)
  • 像素着色器是死的大腦簡單:沒有分支,一個紋理
  • 要獲得目標像素,實現射線採摘(你會無論如何對於任何非平凡的交​​互式3D圖形程序都需要它)

PS 「一切都應該儘可能簡單,但並不簡單。」艾爾伯特愛因斯坦。

+0

自OpenGL3以來,紋理寫入已經得到支持,幾乎不是最新的版本和擴展。我建議更新您的答案以達到事實準確性。 – BlamKiwi 2014-11-24 23:10:56

+0

@Drop:其實我只限於核心配置文件440以上,所以我不太關心後向能力。但是,在CPU端做這件事有點麻煩吧?在我看來,我將不得不做投影CPU端,然後更新紋理?我以前從來沒有聽說過採光,但不好意思看它。謝謝 – mike 2014-11-24 23:18:55

+0

@mike爲什麼你不試一試。對於混合GPU和CPU數據以及僅GPU編程而言,放鬆是3D程序員的一大優勢。 – BlamKiwi 2014-11-24 23:24:45