GLSL着色器可提供纹理“烟熏”效果

0x新浪

我环顾四周,没有发现任何相关内容。我打算创建一个着色器,以提供如下所示的纹理烟雾效果动画:

例子

没有要求完整/完整的解决方案(尽管那会很棒),但是没有任何指向我可以开始实现此效果的指针。我是否需要图纸的顶点,或者如果仅具有纹理,这可能吗?

Badweasel

在上图的示例中,看起来好像它们具有顶点。可能记录了花朵形状的“绘画”,然后连续播放。然后,效果会根据绘制时的时间偏移量命中顶点。那里的效果似乎主要是运动模糊。

因此,要复制此效果,您将需要顶点。看到花朵的顶部如何开始在底部之前消失?如果仔细观察,您会发现模糊效果的计时实际上是沿着花朵的逆时针方向移动的。即使在gif的第一帧,您也可以看到花朵形状的末端比开始处的黄色更亮。

运动模糊的角度也似乎随着时间的变化而从更左定向变为更向上定向。

分段的亮度也随着时间的变化而变化,从淡黄色开始,以黑色或透明结束。

我无法确定的是效果是否是累加的,这意味着他们是将效果应用到整个帧,然后将效果应用到每个帧,或者是否正在重新创建每个帧。如果重新创建每一帧,您将可以反向执行效果并显示图像。

如果您希望这种效果对位图纹理而不是对线对象也可行,尽管方法会有所不同。

让我们从线对象开始,并假设您具有顶点。我要采用的方法是,将一定百分比的衰减作为属性添加到顶点数据中。然后,您渲染的每个帧都将首先基于该顶点的时间来更新衰减百分比。稍微交错一下。

然后,着色器将使用运动模糊着色器绘制线段,其中运动模糊的量,模糊的角度和线段的颜色由衰减属性指定的可变变量控制。我尚未测试此着色器。像伪代码一样对待它。但是我会用这种方式来处理...顶点着色器:

 uniform mat4 u_modelViewProjectionMatrix;
 uniform float maxBlurSizeConstant;  // experiment with value and it will be based on the scale of the render

 attribute vec3 a_vertexPosition;
 attribute vec2 a_vertexTexCoord0;
 attribute float a_decay;

 varying float v_decay;
 varying vec2 v_fragmentTexCoord0;
 varying vec2 v_texCoord1;
 varying vec2 v_texCoord2;
 varying vec2 v_texCoord3;
 varying vec2 v_texCoord4;
 varying vec2 v_texCoordM1;
 varying vec2 v_texCoordM2;
 varying vec2 v_texCoordM3;
 varying vec2 v_texCoordM4;

 void main()
 {
    gl_Position = u_modelViewProjectionMatrix * vec4(a_vertexPosition,1.0);

    v_decay = a_decay;

    float angle = 2.8 - a_decay * 0.8;  // just an example of angles

    vec2 tOffset = vec2(cos(angle),sin(angle)) * maxBlurSizeConstant * a_decay;

    v_fragmentTexCoord0 = a_vertexTexCoord0;

    v_texCoordM1 = a_vertexTexCoord0 - tOffset;
    v_texCoordM2 = a_vertexTexCoord0 - 2.0 * tOffset;
    v_texCoordM3 = a_vertexTexCoord0 - 3.0 * tOffset;
    v_texCoordM4 = a_vertexTexCoord0 - 4.0 * tOffset;
    v_texCoord1 = a_vertexTexCoord0 + tOffset;
    v_texCoord2 = a_vertexTexCoord0 + 2.0 * tOffset;
    v_texCoord3 = a_vertexTexCoord0 + 3.0 * tOffset;
    v_texCoord4 = a_vertexTexCoord0 + 4.0 * tOffset;
 }

片段着色器:

 uniform sampler2D u_textureSampler;

 varying float v_decay;
 varying vec2 v_fragmentTexCoord0;
 varying vec2 v_texCoord1;
 varying vec2 v_texCoord2;
 varying vec2 v_texCoord3;
 varying vec2 v_texCoord4;
 varying vec2 v_texCoordM1;
 varying vec2 v_texCoordM2;
 varying vec2 v_texCoordM3;
 varying vec2 v_texCoordM4;

 void main()
 {
     lowp vec4 fragmentColor = texture2D(u_textureSampler, v_fragmentTexCoord0) * 0.18;

     fragmentColor += texture2D(u_textureSampler, v_texCoordM1) * 0.15;
     fragmentColor += texture2D(u_textureSampler, v_texCoordM2) * 0.12;
     fragmentColor += texture2D(u_textureSampler, v_texCoordM3) * 0.09;
     fragmentColor += texture2D(u_textureSampler, v_texCoordM4) * 0.05;
     fragmentColor += texture2D(u_textureSampler, v_texCoord1) * 0.15;
     fragmentColor += texture2D(u_textureSampler, v_texCoord2) * 0.12;
     fragmentColor += texture2D(u_textureSampler, v_texCoord3) * 0.09;
     fragmentColor += texture2D(u_textureSampler, v_texCoord4) * 0.05;

     gl_FragColor = vec4(fragmentColor.rgb, fragmentColor.a * v_decay);
 }

当然,诀窍在于根据时间的微小偏移量来改变每个顶点的衰减量。

如果要对子图执行相同的操作,则将执行非常相似的操作,除了每个顶点的衰减之间的差异必须正确处理(因为只有4个顶点)。

对不起-编辑

抱歉...上面的着色器模糊了传入的纹理。它不一定会模糊所绘制线条的颜色。这可能是您想要做的,也可能不是。但是,又一次又不知道您实际上试图完成什么,很难给您一个完美的答案。我觉得您还是宁愿在精灵上执行此操作,也不愿基于线顶点的对象执行此操作。因此,您不能按原样复制此着色器并将其粘贴到您的代码中。但这显示了您将如何做自己想做的事情的概念。尤其是在纹理上而不是在基于顶点的直线上进行处理时。

另外,上面的着色器还不完整。例如,它不会扩展以允许模糊超出纹理范围。它从子画面中子画面所在区域的外部获取纹理信息。要解决此问题,您必须从大于精灵的边界框开始,然后将顶点中的精灵缩小为正确的大小。而且,您不必从Sprite工作表中获取超出Sprite边界的文本框。有一些方法可以做到,而不必在Sprite工作表中的Sprite周围包含一堆空白。

更新

从第二方面看,它可能是基于粒子的。如果是的话,它们再次具有所有顶点,但作为粒子位置。我比较喜欢线段,因为我看不到任何间隙。因此,如果是颗粒,则存在很多并且它们被紧紧地放置。粒子仍在从顶部花瓣到最后一个花瓣的级联衰减。即使是线段,您也可以将顶点视为施加风和重力的粒子。

至于烟雾效果是如何工作的,请通过71平方查看此助手应用程序:https : //71squared.com/particledesigner

它的工作方式是购买Mac应用程序以用于设计和保存粒子。然后,转到他们的github并获取iOS代码。但是这个特定的代码创建了一个粒子发射器。用粒子做形状将是不同的代码。但是粒子的演化是相同的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

GLSL着色器可提供纹理“烟熏”效果

来自分类Dev

GLSL片段着色器可智能地平铺纹理

来自分类Dev

glsl片段着色器计算纹理位置

来自分类Dev

在 glsl 着色器中访问矩阵作为纹理

来自分类Dev

GLSL着色器-2D边框照明效果

来自分类Dev

在GLSL着色器中使用多个纹理时,纹理被覆盖

来自分类Dev

GLSL着色器问题

来自分类Dev

GLSL着色器闪烁

来自分类Dev

GLSL着色器折旧

来自分类Dev

GLSL HSV着色器

来自分类Dev

GLSL着色器问题

来自分类Dev

GLSL着色器:在两个以上的纹理之间插值

来自分类Dev

如何在GLSL片段着色器纹理中访问自动mipmap级别?

来自分类Dev

将纹理传递给GLSL着色器而不使用统一?

来自分类Dev

使用GLSL计算着色器渲染纹理时遇到麻烦

来自分类Dev

仅使用顶点着色器对象的glsl会丢失颜色/纹理

来自分类Dev

将float数组作为3D纹理传递给GLSL片段着色器

来自分类Dev

通过GLSL着色器对cessna.osg进行纹理映射

来自分类Dev

GLSL着色器-片段着色器无法编译

来自分类Dev

在使用片段着色器应用波浪效果时,防止在WebGL中出现纹理边界扭曲

来自分类Dev

在片段着色器中的OpenGL中更改纹理的颜色效果不佳

来自分类Dev

OpenGL 3.3 GLSL片段着色器雾效果不起作用

来自分类Dev

计算着色器写入纹理

来自分类Dev

着色器产生弯曲的纹理

来自分类Dev

在OpenGL着色器中渲染纹理

来自分类Dev

片段着色器忽略纹理坐标

来自分类Dev

Unity中的多层纹理着色器

来自分类Dev

始终面对相机的着色器纹理

来自分类Dev

在OpenGL着色器中渲染纹理