我在我的网络项目中使用curves.js。 我告诉你这个是因为我试图在关于这个主题的 stackoverflow 上找到类似的问题,但由于窗帘的制作方式,我无法重现答案。窗帘.js 对 html 的 DOM 中的对象非常具体。 考虑到这一点,我想提出以下问题:
有没有办法让我的代码更漂亮?目前我有这个:
export default [...]
varying vec2 vTextureCoord;
varying vec2 vDisplacedTextureCoord;
varying vec2 vDistortionEffect;
// custom uniforms
uniform float uDisplacementStrength;
uniform float uVideoQueue;
// our textures samplers
uniform sampler2D displacementTexture2;
uniform sampler2D sourceVideo0;
uniform sampler2D sourceVideo1;
uniform sampler2D sourceVideo2;
uniform sampler2D sourceVideo3;
uniform sampler2D sourceVideo4;
uniform sampler2D sourceVideo5;
uniform sampler2D sourceVideo6;
uniform sampler2D sourceVideo7;
uniform sampler2D sourceVideo8;
uniform sampler2D sourceVideo9;
uniform sampler2D canvasTexture;
void main (void) {
vec2 textureCoords = vTextureCoord;
vec4 mouseEffect = texture2D(canvasTexture, textureCoords);
vec4 mapEffect = texture2D(displacementTexture2, textureCoords);
vec4 colorEffect = texture2D(sourceVideo0, textureCoords);
vec4 finalColor = texture2D(sourceVideo0, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
if (uVideoQueue == 1.0) {
colorEffect = texture2D(sourceVideo1, textureCoords);
finalColor = texture2D(sourceVideo1, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 2.0) {
colorEffect = texture2D(sourceVideo2, textureCoords);
finalColor = texture2D(sourceVideo2, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 3.0) {
colorEffect = texture2D(sourceVideo3, textureCoords);
finalColor = texture2D(sourceVideo3, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 4.0) {
colorEffect = texture2D(sourceVideo4, textureCoords);
finalColor = texture2D(sourceVideo4, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 5.0) {
colorEffect = texture2D(sourceVideo5, textureCoords);
finalColor = texture2D(sourceVideo5, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 6.0) {
colorEffect = texture2D(sourceVideo6, textureCoords);
finalColor = texture2D(sourceVideo6, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 7.0) {
colorEffect = texture2D(sourceVideo7, textureCoords);
finalColor = texture2D(sourceVideo7, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 8.0) {
colorEffect = texture2D(sourceVideo8, textureCoords);
finalColor = texture2D(sourceVideo8, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
} else if (uVideoQueue == 9.0) {
colorEffect = texture2D(sourceVideo9, textureCoords);
finalColor = texture2D(sourceVideo9, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r, 0.0));
}
gl_FragColor = finalColor;
[...]
在我的主脚本中有一个uniform,它不断更新以告诉着色器它应该用于输出的纹理(uVideoQueue),范围从0-9(当前数字是特定视频的编号)>
sampler2D uniforms(0-9)是DOM中需要绘制的视频。
正如您在代码中看到的,在着色器中每次绘制调用时,该函数都必须检查它需要添加片段着色器的 sourceVideo sampler2D 统一变量。
如您所见:每个 if/else if 代码行都与顶部的相同,但只有 sampler2D 统一的名称不同。一定有办法拥有这样的东西
vec4 colorEffect = texture2D(sourceVideo **+ i**, textureCoords);
vec4 finalColor = texture2D(sourceVideo **+ i**, [...]);
其中 i 是 uVideoQueue 的编号。
代码工作正常,但我认为与只需要 2 行代码的更优雅的解决方案相比,所有 if/else if 语句的处理器强度更高......
谢谢!
答案 0 :(得分:1)
根据官方文档 slideshow example code,您应该使用额外的 activeTexture
纹理并随时更新其来源。
然后您的片段着色器将变得更容易编写,只需使用统一的 uActiveTexture
采样器。
这是一个演示该概念的最小代码和框:https://codepen.io/martinlaxenaire/pen/YzpVYLE
干杯,
答案 1 :(得分:0)
感谢您的回复!
这是我的新 FS:
void main (void) {
vec2 textureCoords = vTextureCoord;
vec4 mouseEffect = texture2D(canvasTexture, vDisplacedTextureCoord);
vec4 mapEffect = texture2D(displacementTexture2, vDisplacedTextureCoord);
vec4 colorEffect = texture2D(activeVideo, vDisplacedTextureCoord);
vec4 finalColor = texture2D(activeVideo, vDisplacedTextureCoord + vec2(mapEffect.r * mouseEffect.r * colorEffect.r * 0.2, 0.0));
gl_FragColor = finalColor;
在我的主脚本中,我创建了一个新纹理:
welcomeobj.mouseEffect.activeTexture = welcomeobj.mouseEffect.curtains.planes[0].createTexture({
sampler: "activeVideo",
});
当上一个视频结束时,主脚本会为纹理设置一个新源:
welcomeobj.mouseEffect.activeTexture.setSource(loaderobj.xhrarray[m].video);