我在着色器玩具中阅读了一个 2d 光着色器,它可用于创建 2d(点)光。https://www.shadertoy.com/view/4dfXDn
vec4 drawLight(vec2 p, vec2 pos, vec4 color, float range)
{
float ld = length(p - pos);
if (ld > range) return vec4(0.0);
float fall = (range - ld)/range;
fall *= fall;
return (fall) * color;
}
void main() {
vec2 p = gl_FragCoord.xy;
vec2 c = u_resolution.xy / 2.0;
vec4 col = vec4(0.0);
vec2 lightPos = vec2(c);
vec4 lightCol = vec4(1.000,0.25,0.000,1.000);
col += drawLight(p, lightPos, lightCol, 400.0);
gl_FragColor = col;
}
但是,我不知道如何使用它制作另一种“形状”的光?我怎样才能修改drawLight
函数以获得另一个参数,它修改原始灯光,比如 1.0 是一个完整的圆形灯光,而 0.25 是一个四边形灯光?
在你的代码中
float ld = length(p - pos);
在所有方向上均匀地计算您与光的距离(欧几里得距离)。如果你想要不同的阴影改变等式......
例如,您可以像这样计算多边形光的最小垂直距离:
顶点:
// Vertex
#version 420 core
layout(location=0) in vec2 pos; // glVertex2f <-1,+1>
layout(location=8) in vec2 txr; // glTexCoord2f Unit0 <0,1>
out smooth vec2 t1; // fragment position <0,1>
void main()
{
t1=txr;
gl_Position=vec4(pos,0.0,1.0);
}
分段:
// Fragment
#version 420 core
uniform sampler2D txrmap; // texture unit
uniform vec2 t0; // mouse position <0,1>
in smooth vec2 t1; // fragment position <0,1>
out vec4 col;
// light shape
const int n=3;
const float ldepth=0.25; // distance to full disipation of light
const vec2 lpolygon[n]= // vertexes CCW
{
vec2(-0.05,-0.05),
vec2(+0.05,-0.05),
vec2( 0.00,+0.05),
};
void main()
{
int i;
float l;
vec2 p0,p1,p,n01;
// compute perpendicular distance to edges of polygon
for (p1=vec2(lpolygon[n-1]),l=0.0,i=0;i<n;i++)
{
p0=p1; p1=lpolygon[i]; // p0,p1 = edge of polygon
p=p1-p0; // edge direction
n01=normalize(vec2(+p.y,-p.x)); // edge normal CCW
// n01=normalize(vec2(-p.y,+p.x)); // edge normal CW
l=max(dot(n01,t1-t0-p0),l);
}
// convert to light strength
l = max(ldepth-l,0.0)/ldepth;
l=l*l*l;
// render
// col=l*texture2D(txrmap,t1);
col = l*vec4(1.0,1.0,1.0,0.0);
}
我使用了类似的代码How to implement 2D raycasting light effect in GLSL作为起点,因此变量的名称略有不同。
这个想法是计算片段到光形状所有边缘的垂直距离,并选择最大的一个,因为其他人面向错误的一侧。
的lpolygon[n]
是相对于光的位置的光的形状t0
和t1
是片段的位置。它必须在 CCW 绕组中,否则您将需要否定正常计算(我的视图被翻转,因此它可能看起来是 CW,但不是)。我使用范围,<0,1>
因为您可以直接将其用作纹理坐标...
这里截图:
这里有一些解释:
对于分析形状,您需要使用分析距离计算...
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句