首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将ShaderToy Chromakey示例移植到P5.js上

将ShaderToy Chromakey示例移植到P5.js上
EN

Stack Overflow用户
提问于 2020-02-03 19:11:31
回答 1查看 862关注 0票数 1

我正在尝试移植着色玩具色度的例子到p5与摄像头作为视频来源。经过多次阅读文档的着色器,我的代码似乎不工作。我需要些帮助。

我遵循这个指南来移植p5的代码

片段着色代码:

代码语言:javascript
复制
#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D tex0;
uniform sampler2D tex1;

mat4 RGBtoYUV = mat4(0.257,  0.439, -0.148, 0.0,
                     0.504, -0.368, -0.291, 0.0,
                     0.098, -0.071,  0.439, 0.0,
                     0.0625, 0.500,  0.500, 1.0 );


vec4 chromaKey = vec4(0.05, 0.63, 0.14, 1);

vec2 maskRange = vec2(0.005, 0.26);


float colorclose(vec3 yuv, vec3 keyYuv, vec2 tol)
{
    float tmp = sqrt(pow(keyYuv.g - yuv.g, 2.0) + pow(keyYuv.b - yuv.b, 2.0));
    if (tmp < tol.x)
      return 0.0;
    else if (tmp < tol.y)
      return (tmp - tol.x)/(tol.y - tol.x);
    else
      return 1.0;
}


void main()
{
    vec2 fragPos =  gl_FragCoord.xy / iResolution.xy;
    vec4 texColor0 = texture(text0, fragPos);
    vec4 texColor1 = texture(text1, fragPos);

    vec4 keyYUV =  RGBtoYUV * chromaKey;
    vec4 yuv = RGBtoYUV * texColor0;

    float mask = 1.0 - colorclose(yuv.rgb, keyYUV.rgb, maskRange);
    gl_FragColor = max(texColor0 - mask * chromaKey, 0.0) + texColor1 * mask;
}

P5草图代码:

代码语言:javascript
复制
let theShader;
let cam;

let img;

function preload(){

  theShader = loadShader('webcam.vert', 'webcam.frag');

  img = loadImage('http://www.quadrochave.com/wp-content/uploads/elementor/thumbs/nodulo_bannersite_ptodu%C3%A7%C3%A3o2-mpe2nvmu8s8o2uqcd7b2oh3mnuv9up05ubby33shz4.png');
}

function setup() {
  pixelDensity(1);

  createCanvas(windowWidth, windowHeight, WEBGL);
  noStroke();

  cam = createCapture(VIDEO);
  cam.size(windowWidth, windowHeight);

  cam.hide();
}

function draw() {
  // shader() sets the active shader with our shader
  shader(theShader);

  // passing cam as a texture
  theShader.setUniform('tex0', cam);
  theShader.setUniform('tex1', img);

  // rect gives us some geometry on the screen
  theShader.rect(0,0,width,height);

}

小故障试验

着色玩具原始碎片着色器

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-03 22:21:36

市长的问题是,您没有指定和设置统一变量iResolution。但是在着色代码中还有更多的问题(tex0tex1,而不是text0text1)。

碎片着色器:

代码语言:javascript
复制
precision mediump float;

uniform sampler2D tex0;
uniform sampler2D tex1;
uniform vec2 iResolution;

mat4 RGBtoYUV = mat4(0.257,  0.439, -0.148, 0.0,
                        0.504, -0.368, -0.291, 0.0,
                        0.098, -0.071,  0.439, 0.0,
                        0.0625, 0.500,  0.500, 1.0 );


vec4 chromaKey = vec4(0.05, 0.63, 0.14, 1);

vec2 maskRange = vec2(0.005, 0.26);

float colorclose(vec3 yuv, vec3 keyYuv, vec2 tol)
{
    float tmp = sqrt(pow(keyYuv.g - yuv.g, 2.0) + pow(keyYuv.b - yuv.b, 2.0));
    if (tmp < tol.x)
        return 0.0;
    else if (tmp < tol.y)
        return (tmp - tol.x)/(tol.y - tol.x);
    else
        return 1.0;
}

void main()
{
    vec2 fragPos =  gl_FragCoord.xy / iResolution.xy;
    vec4 texColor0 = texture2D(tex0, fragPos);
    vec4 texColor1 = texture2D(tex1, fragPos);

    vec4 keyYUV =  RGBtoYUV * chromaKey;
    vec4 yuv = RGBtoYUV * texColor0;

    float mask = 1.0 - colorclose(yuv.rgb, keyYUV.rgb, maskRange);
    gl_FragColor = max(texColor0 - mask * chromaKey, 0.0) + texColor1 * mask;
}

剧本:

代码语言:javascript
复制
let theShader;
let cam;
let img;

function setup() {
    createCanvas(windowWidth, windowHeight, WEBGL);

    theShader = loadShader('webcam.vert', 'webcam.frag');
    img = loadImage('http://www.quadrochave.com/wp-content/uploads/elementor/thumbs/nodulo_bannersite_ptodu%C3%A7%C3%A3o2-mpe2nvmu8s8o2uqcd7b2oh3mnuv9up05ubby33shz4.png');

    pixelDensity(1);
    noStroke();

    cam = createCapture(VIDEO);
    cam.size(windowWidth, windowHeight);

    cam.hide();
}

function draw() {
    // shader() sets the active shader with our shader
    shader(theShader);

    // passing cam as a texture
    theShader.setUniform('tex0', cam);
    theShader.setUniform('tex1', img);
    theShader.setUniform('iResolution', [width, height]);

    // rect gives us some geometry on the screen
    rect(0,0,width,height);
}

如果顶点着色器提供纹理,则坐标:

代码语言:javascript
复制
// our vertex data
attribute vec3 aPosition;
attribute vec2 aTexCoord;

// lets get texcoords just for fun! 
varying vec2 vTexCoord;

void main() {
    // copy the texcoords
    vTexCoord = aTexCoord;

    // copy the position data into a vec4, using 1.0 as the w component
    vec4 positionVec4 = vec4(aPosition, 1.0);
    positionVec4.xy = positionVec4.xy * 2.0 - 1.0;

    // send the vertex information on to the fragment shader
    gl_Position = positionVec4;
}

然后您可以使用这个坐标而不是gl_FragCoord.xy / iResolution.xy

代码语言:javascript
复制
varying vec2 vTexCoord;

// [...]

void main() {
    vec2 fragPos = vTexCoord.xy;

    // [...]
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60045681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档