WebGL alpha 取决于与原点的距离
WebGL alpha depending on distance from origin
我有以下设置:
平面网格由线组成,线相交处有较亮的点。我想在整个场景中引入一个 alpha 渐变,当前的 alpha (0.2) 在最中心,在边缘线性淡化到 0.0。我在网上能找到的唯一示例最终除了根据 near/far 值将背景更改为随机颜色外什么也没做。
我正在寻找这样的东西:https://i.stack.imgur.com/92LEU.png
我怎样才能做到这一点?这是网格着色器:
顶点:
precision mediump float;
attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;
int scale = 1;
void main()
{
vUv = uv;
gl_Position = projection * view * model * position * vec4(scale, scale, scale, 1);
}
片段:
precision mediump float;
vec2 spacing = vec2(32, 32);
varying vec2 vUv;
int scale = 1;
void main()
{
float scaleFactor = 32.0 * 8.0 * float(scale);
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
int remX = int(mod(offX, spacing[0]));
int remY = int(mod(offY, spacing[1]));
if (remX == 0 || remY == 0)
{
if (remX == remY)
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.2);
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.05);
}
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
立方体使用不同的基本着色器 - 我还希望它们受到雾的影响。我是否只需要将雾逻辑复制到该着色器并以相同的方式操作 gl_FragColor 的 alpha?
非常感谢
根据距中心的距离设置 alpha 通道。中心的 vUv
坐标为 (0.5, 0.5)。计算 Euclidean distance using the length
函数并将 alpha 通道设置为此距离的函数:
void main()
{
// [...]
if (remX == 0 || remY == 0)
{
float dist = length(vUv - vec2(0.5));
float alpha = (1.0 - 2.0*dist) * 0.2;
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
}
else
{
// [...]
}
}
感谢接受的答案解决了 - 我修改了距离 -> alpha 映射以允许任何 min/max alpha。
看起来像这样:
precision mediump float;
vec2 spacing = vec2(32, 32);
varying vec2 vUv;
int scale = 32;
// fog scale describes the amount of space where the fog's opacity is affected by the linear interpolation. larger fog scale = larger gradient
int fog_scale = 2;
float map(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float get_distance_alpha(float min, float max)
{
float dist = length(vUv - vec2(0.5)) * float(scale) / float(fog_scale);
return map(dist, 0.0, 0.5, max, min); // at origin: max; at edge: min
}
void main()
{
float scaleFactor = 32.0 * 8.0 * float(scale);
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
int remX = int(mod(offX, spacing[0]));
int remY = int(mod(offY, spacing[1]));
if (remX == 0 || remY == 0)
{
if (remX == remY)
{
// gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.5));
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.2));
}
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
我有以下设置:
平面网格由线组成,线相交处有较亮的点。我想在整个场景中引入一个 alpha 渐变,当前的 alpha (0.2) 在最中心,在边缘线性淡化到 0.0。我在网上能找到的唯一示例最终除了根据 near/far 值将背景更改为随机颜色外什么也没做。
我正在寻找这样的东西:https://i.stack.imgur.com/92LEU.png
我怎样才能做到这一点?这是网格着色器:
顶点:
precision mediump float;
attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;
int scale = 1;
void main()
{
vUv = uv;
gl_Position = projection * view * model * position * vec4(scale, scale, scale, 1);
}
片段:
precision mediump float;
vec2 spacing = vec2(32, 32);
varying vec2 vUv;
int scale = 1;
void main()
{
float scaleFactor = 32.0 * 8.0 * float(scale);
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
int remX = int(mod(offX, spacing[0]));
int remY = int(mod(offY, spacing[1]));
if (remX == 0 || remY == 0)
{
if (remX == remY)
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.2);
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.05);
}
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
立方体使用不同的基本着色器 - 我还希望它们受到雾的影响。我是否只需要将雾逻辑复制到该着色器并以相同的方式操作 gl_FragColor 的 alpha?
非常感谢
根据距中心的距离设置 alpha 通道。中心的 vUv
坐标为 (0.5, 0.5)。计算 Euclidean distance using the length
函数并将 alpha 通道设置为此距离的函数:
void main()
{
// [...]
if (remX == 0 || remY == 0)
{
float dist = length(vUv - vec2(0.5));
float alpha = (1.0 - 2.0*dist) * 0.2;
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
}
else
{
// [...]
}
}
感谢接受的答案解决了 - 我修改了距离 -> alpha 映射以允许任何 min/max alpha。
看起来像这样:
precision mediump float;
vec2 spacing = vec2(32, 32);
varying vec2 vUv;
int scale = 32;
// fog scale describes the amount of space where the fog's opacity is affected by the linear interpolation. larger fog scale = larger gradient
int fog_scale = 2;
float map(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float get_distance_alpha(float min, float max)
{
float dist = length(vUv - vec2(0.5)) * float(scale) / float(fog_scale);
return map(dist, 0.0, 0.5, max, min); // at origin: max; at edge: min
}
void main()
{
float scaleFactor = 32.0 * 8.0 * float(scale);
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
int remX = int(mod(offX, spacing[0]));
int remY = int(mod(offY, spacing[1]));
if (remX == 0 || remY == 0)
{
if (remX == remY)
{
// gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.5));
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.2));
}
}
else
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}