首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLSL在所需位置混合基础纹理和贴花纹理

GLSL在所需位置混合基础纹理和贴花纹理
EN

Stack Overflow用户
提问于 2012-04-02 16:57:06
回答 2查看 4.5K关注 0票数 0

让我们假设我们纹理四边形(两个三角形)。我认为这个问题类似于下一个例子中的纹理溅射。

代码语言:javascript
复制
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”(这是浮动吗?)可变和混合基础纹理和贴花纹理与它。

代码语言:javascript
复制
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个不同的贴花在四边形,但将是缓慢的频繁更新(例如机枪击中墙壁)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-03 02:45:13

是的,正如您所描述的,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的模糊边缘,你可以玩。祝好运!

票数 1
EN

Stack Overflow用户

发布于 2012-04-03 02:43:39

float decal_layer = /*somehow根据decal_position获取decal_layer */

好吧,这取决于你,你如何解释decal_position。我认为一个简单的距离度量就足够了。但这也需要四边形的大小。让我们假设您通过一个额外的统一decal_radius提供了这一点。然后我们就可以使用

代码语言:javascript
复制
decal_layer = clamp(length(decal_position - vec2(0.5, 0.5)) / decal_radius, 0., 1.);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9973466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档