带有阴影的 GLSL 框在其角附近有“十字”效果

问题描述 投票:0回答:1

以下 GLSL 代码:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    vec2 windowSize = iResolution.xy;
    float border = 50.0;

    vec2 pixelPos = uv * windowSize;

    vec2 v = windowSize - pixelPos;
    vec2 n = normalize(vec2(1.0, -1.0));

    float col = 1.0;

    if (dot(v, n) < 0.0) {
        col = clamp(windowSize.x - pixelPos.x, 0.0, border) / border;
    } else {
        col = clamp(windowSize.y - pixelPos.y, 0.0, border) / border;
    }

    fragColor = vec4(vec3(col), 1.0);
}

产生以下图像:

拐角处有一条明显较亮的线 - 右侧和顶部渐变相交的地方。 我真的不明白为什么会发生这种情况。当点位于对角线右侧时,该值应该与对角线附近的值相同。为了说明我的观点,请考虑以下 python 代码:

import numpy as np
from numpy.linalg import norm


def clamp(x, min_val, max_val):
    return np.minimum(np.maximum(x, min_val), max_val)


def normalize(x):
    return x / norm(x)


def vec2(x, y):
    return np.array([x, y])


windowSize = vec2(200, 100)
border = 50.0


def calculate(pixelPos):
    v = windowSize - pixelPos
    n = normalize(vec2(1.0, -1.0))

    col = 1.0

    if np.dot(v, n) < 0.0:
        col = clamp(windowSize[0] - pixelPos[0], 0.0, border) / border
    else:
        col = clamp(windowSize[1] - pixelPos[1], 0.0, border) / border

    return col


print(10 / border)  # expected value

pixelPos = np.array([190, 90])  # right on the diagonal
print(pixelPos, calculate(pixelPos))

pixelPos = np.array([189, 90])  # slightly above
print(pixelPos, calculate(pixelPos))

pixelPos = np.array([190, 89])  # slightly below
print(pixelPos, calculate(pixelPos))

它输出:

0.2
[190  90] 0.2
[189  90] 0.2
[190  89] 0.2

如上面的代码所示,对角线处的值与其左侧和下方的值相同。那么如果值相同,为什么 OpenGL 会在拐角处显示这条光线?

glsl gradient fragment-shader
1个回答
0
投票

正如我所指出的,事实证明这是一个众所周知的视错觉,并且在 Stack Overflow 上也有人提出了类似的问题:

这是一个小的Python脚本,可以更清晰地可视化它:

import numpy as np
from numpy.linalg import norm
import matplotlib.pyplot as plt


def clamp(x, min_val, max_val):
    return np.minimum(np.maximum(x, min_val), max_val)


def normalize(x):
    return x / norm(x)


def vec2(x, y):
    return np.array([x, y])


windowSize = vec2(200, 100)
border = 50.0


def calculate(pixelPos):
    v = windowSize - pixelPos
    n = normalize(vec2(1.0, -1.0))

    col = 1.0

    if np.dot(v, n) < 0.0:
        col = clamp(windowSize[0] - pixelPos[0], 0.0, border) / border
    else:
        col = clamp(windowSize[1] - pixelPos[1], 0.0, border) / border

    return col


pixels = [[0.0 for _ in range(windowSize[0])] for _ in range(windowSize[1])]
for i in range(windowSize[1]):
    for j in range(windowSize[0]):
        x = j
        y = windowSize[1] - i
        pixels[i][j] = calculate(vec2(x, y))

plt.imshow(pixels)
plt.show()

© www.soinside.com 2019 - 2024. All rights reserved.