我在shader toy里读到一个二维灯光着色器,可以用来创建二维(点)灯光。https:/www.shadertoy.comview4dfXDn
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:
// 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);
}
我使用了类似的代码 如何在GLSL中实现2D光线投射光效 作为起点,因此变量的名称略有不同。
这个想法是计算碎片到你的光形的所有边缘的垂直距离,并选择最大的一个,因为其他的都是朝向错误的一面。
这个 lpolygon[n]
是指光相对于光的位置的形状 t0
和 t1
是碎片位置。它必须是在CCW绕组,否则你将需要否定正常的计算(我的视图是翻转的,所以它可能看起来它的CW,但它不是)。我用的是范围 <0,1>
因为你可以直接用它作为纹理坐标......。
这里是截图。
这里有一些解释
对于分析形状,你需要使用分析距离计算... ...