Libgdx GLSL顶点世界的位置?

时间:2014-07-24 23:40:47

标签: opengl-es libgdx glsl shader

我正在尝试一个支持点和方向灯的简单灯光着色器。定向灯已经完​​成,但我正在与点灯挣扎。如何获得顶点世界位置来计算光线方向? 我使用的是Libgdx和一个sprite batcher,还有一个正交相机。现在我只是做了一个(脏)黑客,将当前精灵的位置传递给片段着色器(中心位置)并使其正常工作。 对于我在glsl中读到的内容,我可以获取模型视图矩阵并将其与当前顶点位置相乘(使用libgdx,我猜这将是" a_position"属性)但我无法做到...

顶点着色器:

attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec3 position;

void main() {
    vTexCoord = a_texCoord0;
    position = a_position.xyz;
    gl_Position =  u_projTrans * a_position;
}

片段着色器:

varying vec2 vTexCoord;
varying vec3 position;

uniform sampler2D u_texture0;   //diffuse map
uniform sampler2D u_texture1;   //normal map
uniform vec4 light_pos[2];
uniform vec4 light_color[2];

//uniform vec3 spritepos; // "Hack" variable with the sprite position...

void main() {
float attenFactor;
vec4 lightAmbientDiffuse= vec4(0.0,0.0,0.0,0.0);
vec4 lightSpecular      = vec4(0.0,0.0,0.0,0.0);
vec3 ambient_light      = vec3(0.1,0.1,0.1);
vec3 eyeDir             = vec3(0.0,0.0,-1.0);
vec3 lightDir;

float shininess = 10.0;

int totalLights = 2;
vec3 normal = normalize((texture2D(u_texture1, vTexCoord.st).rgb * 2.0) - 1.0);

vec3 pos = position;
// pos = spriteposition; //this is what I do that makes it work
for (int i=0; i<totalLights; i++) {
        if (light_pos[i].w != 0.0) {
            float dist = distance(light_pos[i].xyz, pos);
            float constantAttenuation = 0.01;
            float linearAttenuation = 0.2;
            float quadraticAttenuation = 0.5;
            attenFactor = 1.0 / (constantAttenuation + linearAttenuation * dist + quadraticAttenuation * dist * dist );
            lightDir = normalize(light_pos[i].xyz - pos);
        }       
        else { // Directional light
            attenFactor = 1.0;
            lightDir = normalize(light_pos[i].xyz);
        }

        lightAmbientDiffuse += vec4(ambient_light * attenFactor, 0.0);      
        lightAmbientDiffuse += vec4(light_color[i].rgb * max(dot(normal, lightDir), 0.0) * attenFactor, 1.0);

        vec3 r = normalize(reflect(-lightDir, normal));
        lightSpecular += light_color[i] * pow(max(dot(r, -eyeDir), 0.0), shininess) * attenFactor;
    }

    vec4 texColor = texture2D(u_texture0, vTexCoord.st);
    gl_FragColor  = texColor * (lightAmbientDiffuse) + lightSpecular;
 }

pos变量是我从我的应用程序发送的统一。

1 个答案:

答案 0 :(得分:0)

好的,这是怎么回事。 我为你创建了一个libgdx项目,可以在IntelliJ中正常工作 https://dl.dropboxusercontent.com/u/13497625/stackoverflow/StackOverFlow_Pointlights.zip

打开项目,运行build.gradle。 在你的run-configuration中设置你的工作目录到android / assets文件夹。 编辑:哦,也许不要忘记指定你的Android sdk的正确路径!

你的制服传球可能有问题等等。 我稍微改变了你的着色器,因为在顶点着色器中存在片段着色器中缺少一些变化。

另一件事是,你不必在texturecoord-vector的末尾使用.st,因为它已经是vec2而不必被转换为另一个大小。我认为惯例是使用.uv而不是.st无论如何!

命名变量的提示:

v_name for varyings
u_name for uniforms
a_name for attributes
m_name for values in the main function
祝你的项目好运!