以下 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 会在拐角处显示这条光线?
正如我所指出的,事实证明这是一个众所周知的视错觉,并且在 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()