【问题标题】:GLSL mixing base texture with decal texture at needed placeGLSL 在需要的地方混合基础纹理和贴花纹理
【发布时间】:2012-04-02 08:57:05
【问题描述】:

假设我们对四边形(两个三角形)进行纹理处理。我认为这个问题类似于下一个示例中的纹理飞溅

precision lowp float;

uniform sampler2D Terrain;
uniform sampler2D Grass;
uniform sampler2D Stone;
uniform sampler2D Rock;

varying vec2 tex_coord;

void main(void)
{
vec4 terrain = texture2D(Terrain, tex_coord);
vec4 tex0    = texture2D(Grass, tex_coord * 4.0); // Tile
vec4 tex1    = texture2D(Rock,  tex_coord * 4.0); // Tile
vec4 tex2    = texture2D(Stone, tex_coord * 4.0); // Tile

tex0 *= terrain.r; // Red channel - puts grass
tex1 = mix( tex0, tex1, terrain.g ); // Green channel - puts rock and mix with grass 
vec4 outColor = mix( tex1, tex2, terrain.b ); // Blue channel - puts stone and mix with others

gl_FragColor = outColor; //final color
}

但我只想在所需位置的基础四边形纹理上放置 1 个贴花。
算法是一样的,但我认为我们不需要带有 1 个填充层的额外纹理来保存贴花的位置(例如红色层!= 0),我们必须如何生成我们自己的“terrain.r”(这是浮动?)变量并混合基础纹理和贴花纹理。

precision lowp float;

uniform sampler2D base;
uniform sampler2D decal;
uniform vec2 decal_location; //where we want place decal (e.g. 0.5, 0.5 is center of quad)

varying vec2 base_tex_coord;
varying vec2 decal_tex_coord;

void main(void)
{
vec4 v_base = texture2D(base, base_tex_coord);
vec4 v_decal = texture2D(Grass, decal_tex_coord);
float decal_layer = /*somehow get our decal_layer based on decal_position*/

gl_FragColor = mix(v_base, v_decal, decal_layer);
}

如何实现这样的事情?
或者我可能只是在 opengl 端生成 splat 纹理并将其传递给第一个着色器?这将为我提供多达 4 种不同的贴花,但频繁更新会很慢(例如机枪撞墙)

【问题讨论】:

    标签: opengl glsl


    【解决方案1】:
    float decal_layer = /*somehow get our decal_layer based on decal_position*/
    

    嗯,如何解释 decal_position 取决于您。我认为一个简单的距离度量就足够了。但这也需要四边形的 size。假设您通过一个额外的统一贴花半径来提供它。然后我们可以使用

    decal_layer = clamp(length(decal_position - vec2(0.5, 0.5)) / decal_radius, 0., 1.);
    

    【讨论】:

    • 你的也不错,比66多了30.8k,新手需要帮助新手。
    【解决方案2】:

    是的,decal_layer 正如您所描述的那样是一个浮点数。它的范围是 0 到 1。但是您没有足够的信息,在这里您指定了 decal_location 但没有指定贴花的大小。您也不知道该片段在四边形中的位置,如果您想知道该片段相对于正在渲染的四边形的位置,则需要来自顶点着色器的varying vec2 quad_coord; 或类似输入。

    但让我们尝试不同的方法。编辑您的第二个示例的顶部以包含这些制服:

    uniform vec2 decal_location; // Location of decal relative to base_tex_coord uniform float decal_size; // Size of decal relative to base_tex_coord

    现在,在 main() 中,您应该可以使用以下方式计算 decal_layer:

    float decal_layer = 1.0 - smoothstep(decal_size - 0.01, decal_size, max(abs(decal_location.x - base_tex_coord.x), abs(decal_location.y - base_tex_coord.y)));

    基本上,您试图让 decal_layer 在贴花内为 1.0,在贴花外为 0.0。我在边界处添加了一个 0.01 的模糊边缘,您可以使用它。祝你好运!

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 2019-03-12
      • 2021-12-08
      • 2014-02-19
      相关资源
      最近更新 更多