当前位置:  开发笔记 > 编程语言 > 正文

如何在GLSL中实现2D光线投射光效果

如何解决《如何在GLSL中实现2D光线投射光效果》经验,为你挑选了1个好方法。

这最初是@sydd 在这里询问的。我对此很好奇,所以我尝试对其进行编码,但是在我回答之前,它已被关闭/删除,所以就在这里。

问题:如何在GLSL中复制/实现这种 2D射线投射照明效果?

效果本身将光线从鼠标位置投射到各个方向,从而累积了背景贴图的alpha和影响像素强度的颜色。

因此输入应为:

滑鼠位置

背景RGBA地图纹理

Spektre.. 5

    背景图

    好的,我创建了一个测试RGBA贴图,它是2张图像,其中一张包含RGB(左侧),第二张包含alpha通道(右侧),因此您可以同时看到它们。粗略地将它们组合以形成单个RGBA纹理。

    我对它们都做了一些模糊处理,以便在边缘上获得更好的视觉效果。

    射线铸造

    因为这应该在GLSL中运行,所以我们需要将射线投射到某个地方。我决定在片段着色器中执行此操作。所以算法是这样的:

      GL侧,着色器需要使用统一的制服这里的鼠标位置是纹理坐标,纹理的最大分辨率和透光强度。

      GL侧面绘制四边形,覆盖整个屏幕,并带有背景纹理(o混合)

      在顶点着色器上,只需传递所需的纹理和片段坐标

      在每个片段的片段着色器上:

      将射线从鼠标位置投射到实际片段位置(在纹理坐标中)

      在光线传播过程中累积/积分光属性

      如果光线强度接近零或达到目标碎片位置,则停止。

顶点着色器

// 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;                 // texture end point <0,1>
void main()
    {
    t1=txr;
    gl_Position=vec4(pos,0.0,1.0);
    }

片段着色器

// Fragment
#version 420 core
uniform float transmit=0.99;// light transmition coeficient <0,1>
uniform int txrsiz=512;     // max texture size [pixels]
uniform sampler2D txrmap;   // texture unit for light map
uniform vec2 t0;            // texture start point (mouse position) <0,1>
in smooth vec2 t1;          // texture end point, direction <0,1>
out vec4 col;
void main()
    {
    int i;
    vec2 t,dt;
    vec4 c0,c1;
    dt=normalize(t1-t0)/float(txrsiz);
    c0=vec4(1.0,1.0,1.0,1.0);   // light ray strength
    t=t0;
    if (dot(t1-t,dt)>0.0)
     for (i=0;i

最后是结果:

动画256色GIF:

由于8位截断,GIF中的颜色略有失真。另外,如果动画停止刷新页面或在下降的gfx查看器中打开。



1> Spektre..:

    背景图

    好的,我创建了一个测试RGBA贴图,它是2张图像,其中一张包含RGB(左侧),第二张包含alpha通道(右侧),因此您可以同时看到它们。粗略地将它们组合以形成单个RGBA纹理。

    我对它们都做了一些模糊处理,以便在边缘上获得更好的视觉效果。

    射线铸造

    因为这应该在GLSL中运行,所以我们需要将射线投射到某个地方。我决定在片段着色器中执行此操作。所以算法是这样的:

      GL侧,着色器需要使用统一的制服这里的鼠标位置是纹理坐标,纹理的最大分辨率和透光强度。

      GL侧面绘制四边形,覆盖整个屏幕,并带有背景纹理(o混合)

      在顶点着色器上,只需传递所需的纹理和片段坐标

      在每个片段的片段着色器上:

      将射线从鼠标位置投射到实际片段位置(在纹理坐标中)

      在光线传播过程中累积/积分光属性

      如果光线强度接近零或达到目标碎片位置,则停止。

顶点着色器

// 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;                 // texture end point <0,1>
void main()
    {
    t1=txr;
    gl_Position=vec4(pos,0.0,1.0);
    }

片段着色器

// Fragment
#version 420 core
uniform float transmit=0.99;// light transmition coeficient <0,1>
uniform int txrsiz=512;     // max texture size [pixels]
uniform sampler2D txrmap;   // texture unit for light map
uniform vec2 t0;            // texture start point (mouse position) <0,1>
in smooth vec2 t1;          // texture end point, direction <0,1>
out vec4 col;
void main()
    {
    int i;
    vec2 t,dt;
    vec4 c0,c1;
    dt=normalize(t1-t0)/float(txrsiz);
    c0=vec4(1.0,1.0,1.0,1.0);   // light ray strength
    t=t0;
    if (dot(t1-t,dt)>0.0)
     for (i=0;i

最后是结果:

动画256色GIF:

由于8位截断,GIF中的颜色略有失真。另外,如果动画停止刷新页面或在下降的gfx查看器中打开。

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有