我不是編譯器專家,但如果GLSL編譯器不做簡單的常量摺疊,我會感到非常驚訝。因此,我認爲它應該是安全的假設,在下列情況下,不斷的劃分得到在編譯時評價:
vec2 x = y * (1.0/256.0);
第二種情況實際上是更有趣:
vec2 x = y/256.0;
如果這是C或C++代碼,我的理解是,一個編譯器將而不是默認情況下乘以一個乘法。原因是由於舍入不同,無法保證結果與最後一位相同。作爲參考,請參閱Optimizing a floating point division and conversion operation中的答案,其中一個答案確認例如gcc不會執行替換,除非使用-freciprocal-math
編譯器選項。
但是,GLSL是另一種情況。了OpenGL ES GLSL規範特別允許此類型的轉換:
C++標準要求表達式必須在由操作的優先級指定的順序進行評估,並可以僅重新分組如果結果是相同的或結果未定義。沒有其他變換可能會影響操作的結果。 GLSL ES在以下方面放寬了這些要求:
...
浮點除法可以通過互惠和乘法來代替。
有趣的是,這是在充滿不部分(即非ES)GLSL規格。它確實有精確度要求,即分部的誤差最多可以是2.5 ULP(最後的單位)。我解釋這一點的方式是,如果用乘法替代一個分割符合精度要求,則替換將是合法的。但要確保您的代碼儘可能高效,在可能的情況下使用乘法而不是分割似乎更安全。
我特別選擇256,因爲在任何一種情況下舍入都是相同的。 –
這個答案寫得很好,但不幸的是,它並沒有真正回答這個問題,即是否有理由相信你的GLSL編譯器可能不支持強度降低或不斷摺疊。 –
@DietrichEpp依賴於驅動程序,並且大多數開發者無論如何都會在謹慎的方面犯錯。 –