2012-11-23 53 views
6

我的着色器經常分享許多相同的功能。例如計算漫反射/鏡面光照。我想寫一遍,然後在不同的着色器中重用代碼。如何編寫可重用的glsl代碼?

Glsl不知道文件,也不支持類似c的#include預處理器指令。

我知道glsl支持從多個cstrings編譯源代碼,但是如何知道包含哪些cstrings?你是否實現了你自己的include版本?或者你爲每個着色器創建一些圖元文件?

回答

4

在大型項目中,着色器通常在第一次運行時(或圖形選項發生更改時)組裝,因此它們將包含所有供應商特定的功能,並針對用戶機器和設置進行了優化。而且不僅着色,還有渲染管線的一些階段。
您可以將GLSL視爲PHP腳本爲響應請求而吐出的HTML \ CSS \ JavaSript代碼。您可以使用與採樣相同的工藝,在循環中進行代碼注入(例如紋理查找量)。這對平面設計師來說也很好,因爲他們通過參數化 - 支票簿,輸入字段等簡單控制着色器源,並且可以爲獨特的情況提供獨特的着色器。

1

我有一個基於http://blackpixel.com/blog/494/xcode-using-includes-in-opengl-shaders/ [404現在]的自定義解決方案。基本上它說你可以使用m4工具預處理這些文件。

在GLSL源文件只包括要重複使用所需的片段:

include(Utils.glsl) 
include(Colors.glsl) 

... 

void main (void) { 
    ... 
} 

在Xcode中,添加所有glsl文件「複製包資源」。

添加「運行腳本」階段這個shell腳本:

#!/bin/sh 

cd ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME} 
find . -name "*.fsh" | while read file; do 
    echo Preprocess $file 
    m4 "$file" > "$file.tmp" 
    mv "$file.tmp" "$file" 
done 

exit 0 

腳本假設你的着色器有.fsh擴展。修改它以匹配着色器擴展是微不足道的。

被警告:幾乎任何人都可以輕鬆訪問着色器。您可以使用它進行開發,並在釋放它們之前將它們轉換爲字符串(除非您加密它,否則不是真正的保護)。另外,如果着色器之間沒有太多的共享,最終會出現大量未使用的代碼。我猜着色器編譯器會照顧它,但我不能100%確定是否存在性能損失。