沿矩形框的边缘纹理化
Texturing along the edges of a rectangular box
从这个答案开始 我正在尝试将带有一些透明部分 (png) 的纹理仅应用到我的直角棱镜的边缘。
我的第一次尝试(左图)是使用线性过滤的 4x4 纹理。这是代码:
// Normal direction branching
// M: coordinates, MN: normals of the model, sX,sY,sZ. size of the box
if( (abs(MN.x) > abs(MN.y)) && (abs(MN.x) > abs(MN.z)) ) {
// X axis
texCoords = M.yz / vec2(sY, sZ);
} else if( (abs(MN.z) > abs(MN.x)) && (abs(MN.z) > abs(MN.y)) ) {
// Z axis
texCoords = M.xy / vec2(sX, sY);
} else {
// Y axis
texCoords = M.xz / vec2(sX, sZ);
}
texCoords += vec2(0.5);
我对这个结果不满意,因为盒子两侧有清晰可见的伪影。
之后,我尝试使用距离函数和 2x2 纹理(中心图片),但我无法参数化映射纹理与我的框边缘的距离。这是我第二次尝试的代码:
float squared(vec2 pos) {
float at = (atan(pos.x, pos.y) + PI) / (2.0 * PI);
float st = floor(at * 4.0 + 0.5) / 4.0;
float dist = length(pos) * cos((at - st) * 2.0 * PI);
return smoothstep(0.3, 1.0, dist);
}
// Here goes the same direction branching as above
texCoords *= squared(texCoords);
texCoords += vec2(0.5);
我正在尝试获得如右图所示的结果,其中我的纹理应用于我的盒子的所有面,模拟边缘的漂亮方形阴影。
我现在正在研究距离函数,所以我不确定这里应该使用什么方法,我想知道这是否是我正在尝试做的事情的正确方法。
如何将纹理坐标映射到我的盒子的表面,直到离边缘一定距离?
这个问题有一个点赞,所以我在这里发布我的成果。
这是我的最终结果:
float borderSize = 0.5;
vec2 edgeDist;
float insideDist;
float outsideDist;
float dist;
if( (abs(MN.x) > abs(MN.y)) && (abs(MN.x) > abs(MN.z)) ) {
// X major axis
edgeDist = abs(M.zy) - 0.5 * vec2(sZ, sY);
} else if( (abs(MN.z) > abs(MN.x)) && (abs(MN.z) > abs(MN.y)) ) {
// Z major axis
edgeDist = abs(M.xy) - 0.5 * vec2(sX, sY);
} else {
// Y major axis
edgeDist = abs(M.zx) - 0.5 * vec2(sZ, sX);
}
insideDist = max(edgeDist.x, edgeDist.y);
outsideDist = max(insideDist, borderSize);
dist = (outsideDist - insideDist) / (2.0 * borderSize);
eCoords = vec2(smoothstep(0.1, 1.0, dist));
我仍然需要了解是否可以避免轴分支,但至少,我对这个结果很满意:
顺便说一句:
这张图片的第一个例子使用了我问题中提到的2x2纹理,而第二个例子使用了垂直翻转的相同纹理,blueish是material 穿透纹理透明部分的颜色。
从这个答案开始
我的第一次尝试(左图)是使用线性过滤的 4x4 纹理。这是代码:
// Normal direction branching
// M: coordinates, MN: normals of the model, sX,sY,sZ. size of the box
if( (abs(MN.x) > abs(MN.y)) && (abs(MN.x) > abs(MN.z)) ) {
// X axis
texCoords = M.yz / vec2(sY, sZ);
} else if( (abs(MN.z) > abs(MN.x)) && (abs(MN.z) > abs(MN.y)) ) {
// Z axis
texCoords = M.xy / vec2(sX, sY);
} else {
// Y axis
texCoords = M.xz / vec2(sX, sZ);
}
texCoords += vec2(0.5);
我对这个结果不满意,因为盒子两侧有清晰可见的伪影。 之后,我尝试使用距离函数和 2x2 纹理(中心图片),但我无法参数化映射纹理与我的框边缘的距离。这是我第二次尝试的代码:
float squared(vec2 pos) {
float at = (atan(pos.x, pos.y) + PI) / (2.0 * PI);
float st = floor(at * 4.0 + 0.5) / 4.0;
float dist = length(pos) * cos((at - st) * 2.0 * PI);
return smoothstep(0.3, 1.0, dist);
}
// Here goes the same direction branching as above
texCoords *= squared(texCoords);
texCoords += vec2(0.5);
我正在尝试获得如右图所示的结果,其中我的纹理应用于我的盒子的所有面,模拟边缘的漂亮方形阴影。
我现在正在研究距离函数,所以我不确定这里应该使用什么方法,我想知道这是否是我正在尝试做的事情的正确方法。
如何将纹理坐标映射到我的盒子的表面,直到离边缘一定距离?
这个问题有一个点赞,所以我在这里发布我的成果。
这是我的最终结果:
float borderSize = 0.5;
vec2 edgeDist;
float insideDist;
float outsideDist;
float dist;
if( (abs(MN.x) > abs(MN.y)) && (abs(MN.x) > abs(MN.z)) ) {
// X major axis
edgeDist = abs(M.zy) - 0.5 * vec2(sZ, sY);
} else if( (abs(MN.z) > abs(MN.x)) && (abs(MN.z) > abs(MN.y)) ) {
// Z major axis
edgeDist = abs(M.xy) - 0.5 * vec2(sX, sY);
} else {
// Y major axis
edgeDist = abs(M.zx) - 0.5 * vec2(sZ, sX);
}
insideDist = max(edgeDist.x, edgeDist.y);
outsideDist = max(insideDist, borderSize);
dist = (outsideDist - insideDist) / (2.0 * borderSize);
eCoords = vec2(smoothstep(0.1, 1.0, dist));
我仍然需要了解是否可以避免轴分支,但至少,我对这个结果很满意:
顺便说一句:
这张图片的第一个例子使用了我问题中提到的2x2纹理,而第二个例子使用了垂直翻转的相同纹理,blueish是material 穿透纹理透明部分的颜色。