一、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-hant/n/247457.html
微信掃一掃
支付寶掃一掃