Shader之旅2:四宮格畫面實現
阿新 • • 發佈:2018-12-18
書寫本文的初衷是為了自我反省記錄。如有表達不當,請批評指正
首先貼出shader程式碼。這段程式碼是實現相機拍攝畫面四宮格的實現。分別傳入不同的channel 0 1 2 3。然後將UV進行切割分為四塊填入四個channel
uniform float selected_ratio; uniform float selected; #include "res/shaders/BlendMode.frag" //建立新uv vec2 newImage(vec2 uv, float ratio, vec2 padding){ uv -= padding; uv /= ratio; return uv; } //------------------------------------------ //void mainImage(out vec4 fragColor, in vec2 fragCoord)是一個二次封裝的著色器入口函式用過shadertoy都知道此函式 //------------------------------------------ void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = (fragCoord.xy / iResolution.xy);//iResolution是一個螢幕適應的變數將coord延展到當前螢幕 vec4 color; vec4 channelColor; vec2 selectedUv = uv; bool flag_u = false; bool flag_v = false; //-------------------------------------- //切割UV //-------------------------------------- if(uv.x>0.5){ flag_u = true; uv.x -= 0.5; } if(uv.y>0.5){ flag_v = true; uv.y -= 0.5; } uv = (uv * vec2(2.0,2.0)); if (flag_u && flag_v) // 右上角 { color = texture(iChannel1, uv); fragColor = color; } else if (flag_u && !flag_v) // 右下角 { color = texture(iChannel3, uv); fragColor = color; } else if (!flag_u && flag_v) // 左上角 { color = texture(iChannel0, uv); fragColor = color; } else if (!flag_u && !flag_v) // 左下角 { color = texture(iChannel2, uv); fragColor = color; } //-------------------------------------- //此段程式碼是實現點選四個宮格,對應的宮格放大佔滿螢幕 //-------------------------------------- if (selected == 1.0){ if (selectedUv.x < selected_ratio && selectedUv.y > (1.0 - selected_ratio)){ selectedUv = newImage(selectedUv, selected_ratio, vec2(0.0, 1.0 - selected_ratio)); fragColor = texture(iChannel0, selectedUv); } }else if(selected == 2.0){ if (selectedUv.x > (1.0 - selected_ratio) && selectedUv.y > (1.0 - selected_ratio)){ selectedUv = newImage(selectedUv, selected_ratio, vec2(1.0 - selected_ratio, 1.0 - selected_ratio)); fragColor = texture(iChannel1, selectedUv); } }else if(selected == 3.0){ if (selectedUv.x < selected_ratio && selectedUv.y < selected_ratio){ selectedUv = newImage(selectedUv, selected_ratio, vec2(0.0)); fragColor = texture(iChannel2, selectedUv); } }else if(selected == 4.0){ if (selectedUv.x > (1.0 - selected_ratio) && selectedUv.y < selected_ratio){ selectedUv = newImage(selectedUv, selected_ratio, vec2(1.0 - selected_ratio, 0.0)); fragColor = texture(iChannel3, selectedUv); } } }
這裡關於入口函式在多說一下。我們都知道shader的入口函式為main函式而上述程式碼中為一個二次封裝的入口函式,與shadertoy中一樣。下面進行一下說明。
上述shader可以寫成如下形式,以下程式碼是在OpenGL es3.0下書寫的shader
- 首先宣告版本
- 說明精度
- 將mainImage()中的fragcoord替換為gl_FragCoord內建函式
- fragColor作為輸出宣告在開頭
#version 300 es precision mediump float; uniform float selected_ratio; uniform float selected; out vec4 fragColor; #include "res/shaders/BlendMode.frag" //建立新uv vec2 newImage(vec2 uv, float ratio, vec2 padding){ ............ } void main() { vec2 uv = (gl_FragCoord.xy / iResolution.xy);//iResolution是一個螢幕適應的變數將coord延展到當前螢幕 ............. }
下面是將程式碼放置到shadertoy上的效果