Opengl es 移动时对象上的照明不会动态变化
我的webGL应用程序中的光源和对象有问题。在我的“drawScene”函数中,我加载视图端口,清除视图,然后渲染灯光。识别矩阵并渲染VBO后(通过推动和弹出矩阵) 当我加载我的应用程序时,光源是正确的,它位于对象的顶部 然后,我将光源移到左侧,照明将正确地显示在对象上 那么问题就来了。我将对象向左移动,经过光源,但对象上的照明不会移动到对象的右侧 如果将照明一直向左移动,则仅当灯光通过初始起始位置(0,0)时,对象上的照明才会发生变化。 我认为这是一个推送和弹出矩阵的问题,但我已经纠正了代码的架构。首先渲染灯光,然后调用矩阵,然后调用对象。这可能是一个问题,我的着色器,但我不能说。。。以下是我的着色器的外观。有人能帮我吗Opengl es 移动时对象上的照明不会动态变化,opengl-es,glsl,webgl,shader,lighting,Opengl Es,Glsl,Webgl,Shader,Lighting,我的webGL应用程序中的光源和对象有问题。在我的“drawScene”函数中,我加载视图端口,清除视图,然后渲染灯光。识别矩阵并渲染VBO后(通过推动和弹出矩阵) 当我加载我的应用程序时,光源是正确的,它位于对象的顶部 然后,我将光源移到左侧,照明将正确地显示在对象上 那么问题就来了。我将对象向左移动,经过光源,但对象上的照明不会移动到对象的右侧 如果将照明一直向左移动,则仅当灯光通过初始起始位置(0,0)时,对象上的照明才会发生变化。 我认为这是一个推送和弹出矩阵的问题,但我已经纠正了代码的
<script id="shader-fs" type="x-shader/x-fragment"> // Textured, lit, normal mapped frag shader precision mediump float;
// uniforms from app
uniform sampler2D samplerD; // diffuse texture map
uniform sampler2D samplerN; // normal texture map
uniform vec3 uLightColor; // directional light color
uniform vec3 uAmbientColor; // ambient light color
// interpolated values from vertex shader
varying vec2 vTextureCoord;
varying vec3 vLightDir;
void main()
{
// get the color values from the texture and normalmap
vec4 clrDiffuse = texture2D(samplerD, vTextureCoord);
vec3 clrNormal = texture2D(samplerN, vTextureCoord).rgb;
// scale & normalize the normalmap color to get a normal vector for this texel
vec3 normal = normalize(clrNormal * 2.0 - 1.0);
// Calc normal dot lightdir to get directional lighting value for this texel.
// Clamp negative values to 0.
vec3 litDirColor = uLightColor * max(dot(normal, vLightDir), 0.0);
// add ambient light, then multiply result by diffuse tex color for final color
vec3 finalColor = (uAmbientColor + litDirColor) * clrDiffuse.rgb;
// finally apply alpha of texture for the final color to render
gl_FragColor = vec4(finalColor, clrDiffuse.a);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex"> // Textured, lit, normal mapped vert shader precision mediump float;
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord; // Texture & normal map coords
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform vec3 uLightDir; // Application can set desired light direction
varying vec2 vTextureCoord; // Passed through to frag shader
varying vec3 vLightDir; // Compute transformed light dir for frag shader
void main(void)
{
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
vLightDir = uLightDir;
vLightDir = normalize(vLightDir);
}
</script>
这并不奇怪,因为移动对象时没有变换法线。事实上,
uLightDir
不应该是传递给着色器的内容。应在顶点着色器中从其相对于顶点的位置计算灯光方向。您提到移动了光源。在你的代码中,你的光源在哪里?@AndonM.Coleman我忘了提到这只是处理纹理和2D对象。我正在为我的精灵使用法线贴图。我将在哪里变换法线?我不完全了解法线贴图在2d应用程序中的工作原理,但我认为如果法线基于纹理,则没有法线可变换,因为法线贴图始终位于精灵上。@namenamesoseji法线必须位于与灯光方向相同的坐标空间中。因为平移它们是没有意义的,如果在视图空间中进行照明,那么这意味着应用来自视图矩阵的旋转。我必须假设照明是在世界空间中计算的,并且法线贴图也在世界空间中-space@namenamesoseji你现在最大的问题是你的光线方向是恒定的。它需要按顶点计算。
function webGLStart() { ... this.light = new Light(); ...
function Light() { ... this.create(); ...
Light.prototype.create = function() {
gl.uniform3fv(shader.prog.lightDir, new Float32Array([0.0, 0.0, 1.0, 1.0]));
gl.uniform3fv(shader.prog.lightColor, new Float32Array([0.8, 0.8, 0.8]));
gl.uniform3fv(shader.prog.ambientColor, new Float32Array([0.2, 0.2, 0.2]));
}
function drawScene() {
...
this.light.render();
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [-player.getPosition()[0], -
player.getPosition()[1], 0.0]);
mat4.translate(mvMatrix, [0, 0, -20.0]);
this.world.render();
this.player.render();
Light.prototype.render= function() {
gl.uniform3f(shader.prog.lightDir,
this.position[0],this.position[1],this.position[2] );
}