gpt4 book ai didi

opengl - 如何渲染带纹理的四边形,以便淡化不同的角落?

转载 作者:行者123 更新时间:2023-12-04 09:33:03 24 4
gpt4 key购买 nike

我在 2D 环境中将纹理四边形绘制到屏幕上。四边形用作瓦片 map 。为了将一些瓷砖“混合”在一起,我有这样的想法:

  • 在泥土上绘制的单个“草”瓷砖会将其渲染为褪色的草圈;可能从四分之一点开始消失。
  • 如果有更大面积的草方块,那么边缘会从草边缘的四分之一点逐渐消失。

  • 因此,如果要淡化四边形的整个左边缘,则左边缘的不透明度为 0,然后四边形宽度的四分之一处为完全不透明度。右边缘淡入淡出将在四分之三的宽度处具有完全不透明度,并在最右侧边缘淡化至 0 不透明度。
    我认为将 4 个角设置为“开”或“关”就足以让片段着色器解决这个问题。但是,我无法解决。
    corner0分别是 0四边形的结果应该是这样的:
    enter image description here
    如果两者都 corner0corner1分别是 0那么它看起来像这样:
    enter image description here
    这是我到目前为止:
    #version 330

    layout(location=0) in vec3 inVertexPosition;
    layout(location=1) in vec2 inTexelCoords;
    layout(location=2) in vec2 inElementPosition;
    layout(location=3) in vec2 inElementSize;
    layout(location=4) in uint inCorner0;
    layout(location=5) in uint inCorner1;
    layout(location=6) in uint inCorner2;
    layout(location=7) in uint inCorner3;

    smooth out vec2 texelCoords;
    flat out vec2 elementPosition;
    flat out vec2 elementSize;
    flat out uint corner0;
    flat out uint corner1;
    flat out uint corner2;
    flat out uint corner3;

    void main()
    {
    gl_Position = vec4(inVertexPosition.x,
    -inVertexPosition.y,
    inVertexPosition.z, 1.0);

    texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);

    elementPosition.x = (inElementPosition.x + 1.0) / 2.0;
    elementPosition.y = -((inElementPosition.y + 1.0) / 2.0);
    elementSize.x = (inElementSize.x) / 2.0;
    elementSize.y = -((inElementSize.y) / 2.0);
    corner0 = inCorner0;
    corner1 = inCorner1;
    corner2 = inCorner2;
    corner3 = inCorner3;
    }
    元素位置在 [-1,1]范围内提供, corner变量都是 0 或 1。这些是基于实例提供的,而顶点位置和 texelcoords 是针对每个顶点提供的。顶点 y 坐标是倒置的,因为我反向工作,只是为了方便翻转它。 ElementSize 的规模为 [0,2] ,所以我只是将它转换为 [0,1]范围。
    UV 坐标可以是任何值,不一定是 [0,1] .
    这是碎片着色器
    #version 330

    precision highp float;

    layout(location=0) out vec4 frag_colour;

    smooth in vec2 texelCoords;
    flat in vec2 elementPosition;
    flat in vec2 elementSize;
    flat in uint corner0;
    flat in uint corner1;
    flat in uint corner2;
    flat in uint corner3;

    uniform sampler2D uTexture;

    const vec2 uScreenDimensions = vec2(600,600);

    void main()
    {
    vec2 uv = texelCoords;

    vec4 c = texture(uTexture,uv);

    frag_colour = c;

    vec2 fragPos = gl_FragCoord.xy / uScreenDimensions;

    // What can I do using the fragPos, elementPos??
    }
    基本上,我不确定使用 fragPos 能做什么和 elementPosition如果该角为 0,则将像素淡入该角而不是 1 .我有点理解它应该基于碎片与角落位置的距离......但我无法解决。我加了 elementSize因为我认为需要确定给定碎片离角落多远......

    最佳答案

    要实现褪色效果,您必须使用 Blending .您必须根据 scale 设置片段颜色的 Alpha channel :

    frag_colour = vec4(c.rgb, c.a * scale);
    scale必须根据纹理坐标( uv )计算。如果坐标在 [0.0, 0.25] 或 [0.75, 1.0] 范围内,则必须根据相应的cornerX 变量对纹理进行淡化。在下面的变量 uv假定为二维向量,范围为 [0, 1]。
    计算左侧、右侧、底部和顶部的线性梯度,取决于 uv :
    float gradL = min(1.0, uv.x * 4.0);
    float gradR = min(1.0, (1.0 - uv.x) * 4.0);
    float gradT = min(1.0, uv.y * 4.0);
    float gradB = min(1.0, (1.0 - uv.y) * 4.0);
    或者使用 smoothstep 计算 Hermite 梯度:
    float gradL = smoothstep(0.0, 0.25, uv.x);
    float gradR = 1.0 - smoothstep(0.75, 1.0, uv.x);
    float gradT = smoothstep(0.0, 0.25, uv.y);
    float gradB = 1.0 - smoothstep(0.75, 1.0, uv.y);
    计算依赖于 gradL 的 4 个角和 4 个边的淡化因子, gradR , gradT , gradB和相应的cornerX变量。最后计算最大衰减因子:
    float fade0 = float(corner0) * max(0.0, 1.0 - dot(vec2(0.707), vec2(gradL, gradT)));
    float fade1 = float(corner1) * max(0.0, 1.0 - dot(vec2(0.707), vec2(gradL, gradB)));
    float fade2 = float(corner2) * max(0.0, 1.0 - dot(vec2(0.707), vec2(gradR, gradB)));
    float fade3 = float(corner3) * max(0.0, 1.0 - dot(vec2(0.707), vec2(gradR, gradT)));

    float fadeL = float(corner0) * float(corner1) * (1.0 - gradL);
    float fadeB = float(corner1) * float(corner2) * (1.0 - gradB);
    float fadeR = float(corner2) * float(corner3) * (1.0 - gradR);
    float fadeT = float(corner3) * float(corner0) * (1.0 - gradT);

    float fade = max(
    max(max(fade0, fade1), max(fade2, fade3)),
    max(max(fadeL, fadeR), max(fadeB, fadeT)));
    最后计算比例并设置片段颜色:
    float scale = 1.0 - fade; 
    frag_colour = vec4(c.rgb, c.a * scale);

    关于opengl - 如何渲染带纹理的四边形,以便淡化不同的角落?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62736718/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com