【发布时间】:2021-02-16 15:37:48
【问题描述】:
我正在为我的网络项目使用窗帘.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;
[...]
在我的主脚本中有一个不断更新的制服,以告诉着色器它应该使用哪个纹理用于输出(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 语句的处理器强度更高...
谢谢!
【问题讨论】:
-
既然这个制服只在draw call之间改变,你就不能改变绑定的纹理吗?
-
使用数组,将uVideoQueue转为int,然后从数组中得到你需要的。
-
@ZachSaucier GLSL 1.0 不允许使用非常数索引到数组中。
标签: fragment glsl shader webgl curtains.js