java - Java:OpenGl ES 2.0着色器光

原文 标签 java android shader opengl-es-2.0

我需要一个着色器,该着色器可以创建仅受法线和光源之间的角度影响的漫射光。我当前受距离和角度影响的着色器如下所示:

private final String vertexShaderCode2 =
        "uniform mat4 uMVPMatrix;" +
        "uniform mat4 uMVMatrix;" +
        "uniform vec3 uLightPos;" +
        "attribute vec4 vPosition;" +
        "attribute vec4 aColor;" +
        "attribute vec3 aNormal;" +

        "varying vec4 vColor;" +
        "void main() {" +
        "   vec3 modelViewVertex = vec3(uMVMatrix * vPosition); " +
        "   vec3 modelViewNormal = vec3(uMVMatrix * vec4(aNormal, 0.0));" +
        "   float distance = length(uLightPos - modelViewVertex);" +
        "   vec3 lightVector = normalize(uLightPos - modelViewVertex);" +
        "   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);" +
        "   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));" +
        "   vColor = aColor * diffuse;" +

        "  gl_Position = uMVPMatrix * vPosition;" +

        "}";

private final String fragmentShaderCode =
        "precision mediump float;" +
        "varying vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";


以下是用于填充着色器的代码:

    // Calculate position of the light.
    Matrix.setIdentityM(mLightModelMatrix, 0);
    Matrix.rotateM(mLightModelMatrix, 0, LightAngleInDegrees, 0.0f, 1.0f, 1.0f);
    Matrix.translateM(mLightModelMatrix, 0, 0.0f, 100.0f, -10.0f);
    Matrix.multiplyMV(mLightPosInWorldSpace, 0, mLightModelMatrix, 0, mLightPosInModelSpace, 0);
    Matrix.multiplyMV(mLightPosInEyeSpace, 0, mViewMatrix, 0, mLightPosInWorldSpace, 0);

    // Player
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, py, px, pz);
    Matrix.rotateM(mModelMatrix, 0, mAngle, 0, 0, 1.0f);
    Matrix.scaleM(mModelMatrix, 0, scalef, scalef, scalef * 2);
    Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);
    cube.draw(mMVPMatrix, mMVMatrix, mLightPosInWorldSpace);


最后,cube.draw方法:

public void draw(float[] mvpMatrix, float[] mvMatrix, float[] mLightPosInWorldSpace) {
    ...
    // Pass in the light position in eye space.
    GLES20.glUniform3f(LightPosHandle, mLightPosInWorldSpace[0], mLightPosInWorldSpace[1], mLightPosInWorldSpace[2]);
    ...
}


如果我将以下行留在着色器之外:

diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));


然后,不考虑距离,但是副作用是旋转立方体不会影响立方体侧面的颜色,就像光源跟随立方体在周围一样。 LightAngleInDegrees(light)和mAngle(cube)是两个单独的变量。

最佳答案

漫射计算的光照位置需要在世界空间中完成。这意味着您需要传递mLightPosInWorldSpace,而不是mLightPosInEyeSpace

public void draw(float[] mvpMatrix, float[] mvMatrix, float[] mLightPosInEyeSpace) {
    ...
    // Pass in the light position in world space.
    GLES20.glUniform3f(LightPosHandle, mLightPosInWorldSpace[0], mLightPosInWorldSpace[1], mLightPosInWorldSpace[2]);
    ...
}


好东西让您清楚地命名了变量,否则我不会发现它。

关于java - Java:OpenGl ES 2.0着色器光,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35349651/

相关文章:

android - 无法获取 'https://jitpack.io/com/google/android/gms/play-services-basement/maven-metadata.xml' 。从服务器 : Forbidden 收到状态代码 403

android - 如何使用清除按钮制作可重复使用的 EditText?

C++着色器问题

opengl - 如何将大型四边形基元数组转换为三角形基元?

java - session 超时 Spring

java - 复制不同类型的HashMap

java - 每当我尝试将文本放入日志文件时,Java Logger都会覆盖

java - 将相同的布局添加到一个容器android

java - Android 6.0 文件写入权限被拒绝