使用着色器绘制 2d 灯?
Drawing 2d lights using Shaders?
我想知道如何像这里一样创建 2D 灯光:
https://www.youtube.com/watch?v=mVlYsGOkkyM
这里:
https://www.youtube.com/watch?v=nSf1MpsWKig
阴影目前不符合我的兴趣。
我尝试了一些东西,但它们似乎不起作用。所以我目前只有片段和顶点着色器,里面几乎没有任何东西。
有几种方法可以做到这一点,但可能是最简单的方法,就是使用 LWJGL 提供的内置方法。首先,你需要开启灯光,然后你可以调用方法glLight()
来放置指定的灯光。
例如:
FloatBuffer position = BufferUtils.createFloatBuffer(4);
float[] posArray = {0f, 0f, 0f, 1f};
position.put(posArray);
position.flip();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModel(GL_LIGHT_MODEL_AMBIENT, position));
glLight(GL_LIGHT0, GL_DIFFUSE, position2)); // position2's definition not shown
编辑:忘记添加实际灯光
光照几乎是计算机图形学的主要问题,有几种常用的实现光照的方法:
更简单但有局限性的方法称为 "foward shading",一般的想法是将所有关于光照(环境光、光照位置和颜色等)的信息提供给渲染几何体的着色器和直接在您渲染的每个表面上计算光照。限制是您只能将固定数量的灯光传递给着色器。
另一种方式称为"deferred shading",它在现代游戏引擎中很常用。在渲染几何体时,您无需照亮几何体,而只需收集几何体每个像素的相关数据(位置、颜色、法线等)并将其存储在帧缓冲区中。然后您可以使用数据渲染任意数量的灯光。 OGLdev 有一个很好的延迟着色教程,但如果您是初学者,您可能希望避免使用它,因为它很难设置并且在旧硬件上速度很慢。 http://ogldev.atspace.co.uk/www/tutorial35/tutorial35.html
另外GLSL中的通用光照公式为:
// Vector from the current pixel to the light
vec3 toLight = (lightpos - pixelpos);
// This computes how much is the pixel lit based on where it faces
float brightness = clamp(dot(normalize(toLight), pixelnormal), 0.0, 1.0);
// If it faces towards the light it is lit fully, if it is perpendicular
// to the direction towards the light then it is not lit at all.
// This reduces the brightness based on the distance form the light and the light's radius
brightness *= clamp(1.0 - (length(toLight) / lightradius), 0.0, 1.0);
// The final color of the pixel.
vec3 finalcolor = pixelcolor * lightcolor * brightness;
// If you have multiple lights multiply the pixel's color by the combined color of all lights
// like:
finalcolor = pixelcolor * (lightcolor1 * brightness1 + lightcolor2 * brightness2);
// Note that some things are clamped to avoid going into negative values
我想知道如何像这里一样创建 2D 灯光:
https://www.youtube.com/watch?v=mVlYsGOkkyM
这里:
https://www.youtube.com/watch?v=nSf1MpsWKig
阴影目前不符合我的兴趣。 我尝试了一些东西,但它们似乎不起作用。所以我目前只有片段和顶点着色器,里面几乎没有任何东西。
有几种方法可以做到这一点,但可能是最简单的方法,就是使用 LWJGL 提供的内置方法。首先,你需要开启灯光,然后你可以调用方法glLight()
来放置指定的灯光。
例如:
FloatBuffer position = BufferUtils.createFloatBuffer(4);
float[] posArray = {0f, 0f, 0f, 1f};
position.put(posArray);
position.flip();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModel(GL_LIGHT_MODEL_AMBIENT, position));
glLight(GL_LIGHT0, GL_DIFFUSE, position2)); // position2's definition not shown
编辑:忘记添加实际灯光
光照几乎是计算机图形学的主要问题,有几种常用的实现光照的方法:
更简单但有局限性的方法称为 "foward shading",一般的想法是将所有关于光照(环境光、光照位置和颜色等)的信息提供给渲染几何体的着色器和直接在您渲染的每个表面上计算光照。限制是您只能将固定数量的灯光传递给着色器。
另一种方式称为"deferred shading",它在现代游戏引擎中很常用。在渲染几何体时,您无需照亮几何体,而只需收集几何体每个像素的相关数据(位置、颜色、法线等)并将其存储在帧缓冲区中。然后您可以使用数据渲染任意数量的灯光。 OGLdev 有一个很好的延迟着色教程,但如果您是初学者,您可能希望避免使用它,因为它很难设置并且在旧硬件上速度很慢。 http://ogldev.atspace.co.uk/www/tutorial35/tutorial35.html
另外GLSL中的通用光照公式为:
// Vector from the current pixel to the light
vec3 toLight = (lightpos - pixelpos);
// This computes how much is the pixel lit based on where it faces
float brightness = clamp(dot(normalize(toLight), pixelnormal), 0.0, 1.0);
// If it faces towards the light it is lit fully, if it is perpendicular
// to the direction towards the light then it is not lit at all.
// This reduces the brightness based on the distance form the light and the light's radius
brightness *= clamp(1.0 - (length(toLight) / lightradius), 0.0, 1.0);
// The final color of the pixel.
vec3 finalcolor = pixelcolor * lightcolor * brightness;
// If you have multiple lights multiply the pixel's color by the combined color of all lights
// like:
finalcolor = pixelcolor * (lightcolor1 * brightness1 + lightcolor2 * brightness2);
// Note that some things are clamped to avoid going into negative values