让我们假设我们纹理四边形(两个三角形)。我认为这个问题类似于下一个例子中的纹理溅射。
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个不同的贴花在四边形,但将是缓慢的频繁更新(例如机枪击中墙壁)
发布于 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的模糊边缘,你可以玩。祝好运!
发布于 2012-04-03 02:43:39
float decal_layer = /*somehow根据decal_position获取decal_layer */
好吧,这取决于你,你如何解释decal_position。我认为一个简单的距离度量就足够了。但这也需要四边形的大小。让我们假设您通过一个额外的统一decal_radius提供了这一点。然后我们就可以使用
decal_layer = clamp(length(decal_position - vec2(0.5, 0.5)) / decal_radius, 0., 1.);https://stackoverflow.com/questions/9973466
复制相似问题