回答
嗯,這很有趣。 :)
一個WebGL的演示,請訪問:http://boblycat.org/~knute/webgl/tunnel/
主要算法是在片段着色器。基本思想是for循環遍歷黑圈/圓圈,從大到小,同時偏移中心以產生隧道效應。
給定任何像素,我們可以檢查像素是否足夠接近環以成爲黑色像素的候選者。如果它在環之外,則打破環路以避免在較大的環上看到較小的環。
當環接近時,與前一個(外)圓的距離用於「擠壓」圖案,這有助於創建3D表面的幻覺。
每個環的波浪圖案當然是一條正弦曲線。像素的角度(與圓心相比)與均勻的時間參數相結合,爲每個環形的波浪圖案製作動畫。
最後,有很多實驗用不同的參數和轉換函數,例如pow()來獲得接近目標動畫的結果。這並不完美,但非常接近。
片段着色器代碼:
#ifdef GL_ES
precision highp float;
#endif
const float PI = 3.14159265358979323846264;
const float TWOPI = PI*2.0;
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec2 CENTER = vec2(0.0, 0.0);
const int MAX_RINGS = 30;
const float RING_DISTANCE = 0.05;
const float WAVE_COUNT = 60.0;
const float WAVE_DEPTH = 0.04;
uniform float uTime;
varying vec2 vPosition;
void main(void) {
float rot = mod(uTime*0.0006, TWOPI);
float x = vPosition.x;
float y = vPosition.y;
bool black = false;
float prevRingDist = RING_DISTANCE;
for (int i = 0; i < MAX_RINGS; i++) {
vec2 center = vec2(0.0, 0.7 - RING_DISTANCE * float(i)*1.2);
float radius = 0.5 + RING_DISTANCE/(pow(float(i+5), 1.1)*0.006);
float dist = distance(center, vPosition);
dist = pow(dist, 0.3);
float ringDist = abs(dist-radius);
if (ringDist < RING_DISTANCE*prevRingDist*7.0) {
float angle = atan(y - center.y, x - center.x);
float thickness = 1.1 * abs(dist - radius)/prevRingDist;
float depthFactor = WAVE_DEPTH * sin((angle+rot*radius) * WAVE_COUNT);
if (dist > radius) {
black = (thickness < RING_DISTANCE * 5.0 - depthFactor * 2.0);
}
else {
black = (thickness < RING_DISTANCE * 5.0 + depthFactor);
}
break;
}
if (dist > radius) break;
prevRingDist = ringDist;
}
gl_FragColor = black ? BLACK : WHITE;
}
看起來真棒!不錯的工作。 – Qcom 2011-04-05 23:13:03
在我的低端系統上使用Firefox進行測試時:着色器鏈接錯誤:C:\ util \ firefox-3.7a5pre.en-US.win32 \ firefox \ memory(98,16):警告X3206:向量類型C的隱式截斷:\ util \ firefox-3.7a5pre.en-US.win32 \ firefox \ memory(33,5):錯誤X3511:無法展開循環,循環顯示不及時終止(17次迭代),請使用[ unroll(n)]屬性強制執行一個確切的更高數字 – zproxy 2011-04-08 05:45:52
MAX_RINGS = 10:着色器鏈接錯誤:C:\ util \ firefox-3.7a5pre.en-US.win32 \ firefox \ memory(98,16):warning X3206:隱式截斷向量類型C:\ util \ firefox-3.7a5pre.en-US.win32 \ firefox \ memory(74,4):錯誤X5608:編譯着色器代碼使用太多算術指令槽(733)。最大。目標(ps_2_0)允許的值爲64.(1,1):錯誤X5609:編譯的着色器代碼使用太多的指令槽(733)。最大。目標(ps_2_0)允許的值爲96. – zproxy 2011-04-08 05:50:06
- 1. 如何實現像「陰霾」這樣的動畫
- 2. 如何實現像UIActivityIndicatorView一樣的自動動畫視圖?
- 3. 這個動畫是如何實現的
- 4. 如何用Spritekit實現這個動畫?
- 5. 如何實現這個動畫?
- 6. 在C#中實現SSL隧道#
- 7. 如何像IFTTT一樣實現動畫介紹屏幕?
- 8. 雙棧vs隧道IPV6的實現,這很容易實現?
- 9. 如何在android中實現facebook像動畫一樣的反應彈出窗口?
- 10. 如何實現像這樣的曲線?
- 11. 如何實現像AppStore這樣的AppStore
- 12. 如何實現這樣一個滾動div與改變CSS?
- 13. 如何實現這樣的滾動?
- 14. 在PowerPoint中嵌入webgl或從webgl呈現動畫gif
- 15. 在PhoneApplicationPage中實現像Pivot頁一樣的滑動動畫windows phone 8
- 16. 如何在WebGL中實現這種旋轉螺旋?
- 17. 如何在Facebook Messenger API中像這樣發送動畫GIF?
- 18. 是否可以使用CSS像這個圖像一樣動畫?
- 19. 如何在zepto中實現像slideDown()這樣的jquery
- 20. 如何在twitter中實現像urls這樣的短url?
- 21. 如何編程一個http隧道
- 22. 實現像UITableView這樣的頭像
- 23. 如何在JFrame中實現動畫
- 24. 如何在android中實現這種動畫?
- 25. 如何在Android SDK中實現這種類型的動畫?
- 26. 如何刪除現有的IP隧道
- 27. 如何在webgl中移動攝像頭?
- 28. 實現這樣一個迭代器?
- 29. WPF隧道一個Button_Click
(看30秒後拋出了) – Blender 2011-03-27 18:39:28
嘗試使用展示在牆上它的投影機;) – zproxy 2011-03-27 20:43:53
雖然這有一個公認的答案,我們的社會是不是要用於爲您提供個人便利的代碼工廠。 – Kev 2011-11-08 12:39:19