书写本文的初衷是为了自我反省记录。如有表达不当,请批评指正
首先贴出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上的效果