WebGL片元着色器:求含给定点的直角三角形直角顶点C
实现WebGL片元着色器的getAngleC函数
要解决这个问题,核心是利用直角三角形的平铺规律——整个UV空间可被划分为acLength × bcLength的矩形网格,每个矩形被一条斜边分割为两个目标直角三角形,分别以矩形的两个对角为直角顶点C。具体实现步骤如下:
关键逻辑
- 坐标偏移计算:以已知的
c0为基准点,计算输入点p相对于c0的偏移量。 - 网格单元定位:将偏移量按矩形网格的尺寸(
acLength和bcLength)取整,确定p所在的网格单元。 - 三角形区域判断:通过斜边方程判断
p位于网格单元内的哪个三角形,进而确定对应的直角顶点C。
斜边方程推导:以网格单元左下角为直角顶点C时,两条直角边分别沿x轴(长度acLength)和y轴(长度bcLength)延伸,斜边连接(acLength, 0)和(0, bcLength),方程为y = bcLength - (bcLength/acLength) * x。
GLSL实现代码
vec2 getAngleC(vec2 p) { // 定义已知常量 const float acLength = 0.25; const float bcLength = 1.0 / 6.0; const vec2 c0 = vec2(0.5, 0.5); // 计算点p相对于c0的偏移 vec2 delta = p - c0; // 确定p所在的网格单元坐标(整数) vec2 grid = floor(delta / vec2(acLength, bcLength)); // 计算p在网格单元内的局部坐标 vec2 local = delta - grid * vec2(acLength, bcLength); // 判断p属于哪个三角形:斜边下方的区域对应左下角的C点,上方对应右上角的C点 bool isLowerTriangle = local.y <= bcLength - (bcLength / acLength) * local.x; // 返回对应的直角顶点C坐标 return isLowerTriangle ? c0 + grid * vec2(acLength, bcLength) : c0 + (grid + vec2(1.0, 1.0)) * vec2(acLength, bcLength); }
补充说明
- 如果UV空间是周期性的(如纹理重复采样),可在计算
delta前对p取模,确保坐标落在[0,1]×[0,1]范围内:vec2 normalizedP = fract(p); vec2 delta = normalizedP - c0; - 当点
p刚好落在斜边上时,两个三角形的判定结果均可,不会影响视觉效果(单个片元的误差可忽略)。
内容的提问来源于stack exchange,提问作者Roberto Ferrero
相关产品推荐
相关产品推荐

