Shader之旅2:四宫格画面实现

书写本文的初衷是为了自我反省记录。如有表达不当,请批评指正

首先贴出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上的效果

Shader之旅2:四宫格画面实现_第1张图片

你可能感兴趣的:(Shader之旅)