Я снова пытаюсь портировать шейдерный шейдер кеинга для использования с p5. js. Примеры шейдерной передачи также передают фоновое изображение шейдеру для смешивания с передним планом в качестве текстуры. Но я не хочу использовать фоновое изображение с шейдером кеинга, потому что мой фон - это другой объект (сфера skydome) внутри трехмерного пространства для анимации камеры и параллакса. Я использую веб-камеру в качестве изображения для передачи в шейдер. Мне нужна помощь в понимании последнего фрагмента кода фрагмента шейдера, когда я пытаюсь игнорировать зеленый цвет от кеинга. Я изменил исходную линию шейдера
color = mix(color, bg, incrustation);
на
color = max(color, incrustation);
Мой фрагментный шейдер:
#ifdef GL_ES
precision mediump float;
#endif
// our texture coming from p5
uniform sampler2D tex0;
//uniform sampler2D tex1;
uniform vec2 iResolution;
vec3 rgb2hsv(vec3 rgb)
{
float Cmax = max(rgb.r, max(rgb.g, rgb.b));
float Cmin = min(rgb.r, min(rgb.g, rgb.b));
float delta = Cmax - Cmin;
vec3 hsv = vec3(0., 0., Cmax);
if (Cmax > Cmin)
{
hsv.y = delta / Cmax;
if (rgb.r == Cmax)
hsv.x = (rgb.g - rgb.b) / delta;
else
{
if (rgb.g == Cmax)
hsv.x = 2. + (rgb.b - rgb.r) / delta;
else
hsv.x = 4. + (rgb.r - rgb.g) / delta;
}
hsv.x = fract(hsv.x / 6.);
}
return hsv;
}
float chromaKey(vec3 color)
{
vec3 backgroundColor = vec3(0.157, 0.576, 0.129);
vec3 weights = vec3(4., 1., 2.);
vec3 hsv = rgb2hsv(color);
vec3 target = rgb2hsv(backgroundColor);
float dist = length(weights * (target - hsv));
return 1. - clamp(3. * dist - 1.5, 0., 1.);
}
vec3 changeSaturation(vec3 color, float saturation)
{
float luma = dot(vec3(0.213, 0.715, 0.072) * color, vec3(1.));
return mix(vec3(luma), color, saturation);
}
void main()
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec3 color = texture(tex0, uv).rgb;
float incrustation = chromaKey(color);
color = changeSaturation(color, 0.5);
color = max(color, incrustation);
// Output to screen
//gl_FragColor = vec4(color, 1.);
if (vec4(color, 1.).a > 0.0) {
gl_FragColor = vec4(color, 1.);
} else {
discard;
}
}
Вершинный шейдер:
// our vertex data
attribute vec3 aPosition;
void main() {
// 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;
}
P5. js функция рисования эскиза:
function draw() {
orbitControl();
background(0,40, 200);
ambientLight(255);
push();
translate(-35, 0, -250);
normalMaterial();
texture(imgSky);
sphere(1200);
pop();
shaderTexture.shader(theShader);
theShader.setUniform('tex0', cam);
theShader.setUniform('iResolution', [width, height]);
shaderTexture.rect(0, 0, width, height);
texture(shaderTexture);
plane(width, height);
pop();
}
Оригинальный шейдерный шейдер
Мой пример на Glitch
Портирование кода Shadertoy на p5. js Руководство по шейдерам