Opengl es OpenGL ES 2.0-如何设置光源&x27;s颜色与颜色;强度
我一直在玩凯文·博洛塔勒的第4课“学习OpenGLES2.0” 下面是它的片段着色器:Opengl es OpenGL ES 2.0-如何设置光源&x27;s颜色与颜色;强度,opengl-es,fragment-shader,vertex-shader,light,Opengl Es,Fragment Shader,Vertex Shader,Light,我一直在玩凯文·博洛塔勒的第4课“学习OpenGLES2.0” 下面是它的片段着色器: precision mediump float; // Set the default precision to medium. We don't need as high of a // precision in the fragment shader. uniform vec3 u_LightPos; // The po
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform vec3 u_LightPos; // The position of the light in eye space.
uniform sampler2D u_Texture; // The input texture.
varying vec3 v_Position; // Interpolated position for this fragment.
varying vec4 v_Color; // This is the color from the vertex shader interpolated across the
// triangle per fragment.
varying vec3 v_Normal; // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
// The entry point for our fragment shader.
void main()
{
// Will be used for attenuation.
float distance = length(u_LightPos - v_Position);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - v_Position);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(v_Normal, lightVector), 0.0);
// Add attenuation.
diffuse = diffuse * (1.0 / (1.0 + (0.10 * distance)));
// Add ambient lighting
diffuse = diffuse + 0.3;
// Multiply the color by the diffuse illumination level and texture value to get final output color.
//===================== original
gl_FragColor = (v_Color * diffuse * texture2D(u_Texture, v_TexCoordinate));
//=====================
}
我看到灯光的位置已定义并传递到着色器中,但我没有看到灯光的颜色/强度在源代码中的任何位置被定义
如何定义灯光的颜色/强度并使其影响片段着色器的输出gl_FragColor
我看不到源代码中任何地方定义的灯光颜色/强度,但该程序显示由移动光源照亮的立方体。如果仔细观察,该着色器使用2个“魔法”数字:
diffuse = diffuse * (1.0 / (1.0 + (0.10 * distance)));
.10
将根据距离作为一个线性因素发挥作用。此值可能是您第一个转换为统一的值,以便您可以从应用程序本身设置它
diffuse = diffuse + 0.3;
0.3
是环境照明,因此场景中最暗的角落仍亮起30%。也可以将其转换为制服
除此之外,还有一系列的1和0可以影响光的强度。例如,漫反射
可以在添加环境光之前乘以直接光强度。此值不需要在[0,1]的范围内
照明本身实际上很难生成,最终使用的值几乎没有意义(如果有的话):
如果你看物理,那么你可以指定一个特定的值J
,它代表聚光灯的强度。你看到的是从表面反射的光。因此,您需要做的第一件事是通过应用与灯光和曲面的距离来降低影响曲面的灯光强度,该值会降低平方距离=J/(距离*距离)
(注意*)。接下来,重要的是要包括曲面的旋转方式,这是由法线定义的,如果法线和从曲面中的点到灯光中心的路径(光向量
)朝向相同的方向,您将获得最大的灯光照射。如果此角度为90度或更大,它将完全没有照明。该因子可以通过着色器中使用的点积实现。使用这种方法,您可能只有一个影响光强度的因素,即J
。这里的问题是,这种照明将只存在于一个完全的真空中,周围没有其他物体,甚至物体的形状也必须使其不会将光线反射到自身(一个球体就可以了)
这就是说,标准的物理程序看起来不太自然,需要一些额外的补充来模拟自然光。最常见的是在距离效应中加入不同的幂,然后是平方。对于这些参数,您应该搜索一些好的结果,或者自己进行实验
我之所以要告诉你们所有这些,是因为你们有无限的方法来定义光的性质和强度,所以最好是你们在网上进行实验或寻找其他解决方案,知道它们都不是最好的或正确的,因为你们的计算能力太小,无法在一个特定的环境中创建真正的光源计算机场景
(注意*)为了清楚地了解J/(距离*距离)
:一个真正的公式也会添加一个常数,因为球面面积定义为J'=J/(4*Phi*r*r)
,但该常数可以删除并添加到光强度或距离单位中
还注意到,还有一些其他的光效应,你可能需要考虑到后来的SUCH作为光反射(像镜子),已经使用的环境光和最吸引人的绘制阴影的艺术。