一、gl_fragcoord的概念和作用
在對OpenGL ES進行著色器編程時,gl_fragcoord常常被用來完成一些自由變換。gl_fragcoord指的是一個四維向量,其分量分別為(x, y, z, 1),其中z代表深度值,可用於深度測試。而x和y則表示屏幕上對應像素的坐標。
在頂點著色器中,gl_Position是一個四維向量,其分量表示頂點變換後的位置,而在片段著色器中,gl_fragcoord則表示當前片元在屏幕上的位置。這個位置不是標準的笛卡爾坐標系,而是用像素坐標表示的。
因此,利用gl_fragcoord我們可以輕鬆實現屏幕上各種自由變換效果,例如水波紋、扭曲等等。
二、利用gl_fragcoord進行自由變換
下面我們以一個簡單的例子來說明如何利用gl_fragcoord進行自由變換。
precision mediump float; uniform float time; void main() { vec2 uv = gl_FragCoord.xy / vec2(640.0, 480.0); uv -= 0.5; uv *= 10.0; float amount = length(uv); vec2 offset = uv * sin(amount * 10.0 + time) / 10.0; gl_FragColor = texture2D(u_texture, uv + offset); }
在上面的片段著色器代碼中,我們首先將屏幕坐標系轉化為uv坐標系。然後將坐標繫上的值都*10,使其放大10倍。
接著,我們根據坐標的長度算出一個amount變數,然後利用amount和時間、uv坐標繫上的值來算出一個偏移量,用這個偏移量來採樣紋理。這樣就完成了一個簡單的水波紋效果。通過改變坐標繫上的值,我們就可以獲得各種自由變換的效果。
三、利用gl_fragcoord實現扭曲效果
下面我們來看一個應用到實際場景中的例子,即如何利用gl_fragcoord實現扭曲效果。
precision mediump float; uniform vec2 u_resolution; uniform float u_time; uniform sampler2D u_texture; void main() { vec2 p = gl_FragCoord.xy/u_resolution.xy - 0.5; p.x *= u_resolution.x / u_resolution.y; float offset = texture2D(u_texture, vec2(p.x * 0.2 + u_time/5.0, p.y * 0.85)).r; float fx = sin(p.y * 15.0 * offset + u_time) * 0.5; float fy = sin(p.x * 15.0 * offset + u_time) * 0.5; vec4 pixel = texture2D(u_texture, vec2(p.x + fx, p.y + fy)); gl_FragColor = pixel; }
在這個例子中,我們首先將屏幕坐標系轉換為uv坐標系,然後將x軸進行了拉伸,以適應不同寬高比的屏幕。接著,我們利用gl_fragcoord採樣一張紋理,並利用p.x * 0.2 + u_time/5.0和p.y * 0.85這兩個值來確定紋理採樣的位置。
接下來,我們根據採樣到的紋理值計算出一個偏移值,並將其用於sin函數計算。最後,我們將偏移值應用到uv坐標繫上,並採樣出像素。這樣,就完成了一個簡單的扭曲效果。
四、總結
gl_fragcoord是一個非常有用的變數,通過它我們可以輕鬆實現各種自由變換效果。以上代碼均可在OpenGL ES中使用,如果想要嘗試更多有趣的自由變換效果,可以利用gl_fragcoord進行實現。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/247457.html