android - 阴影贴图在 Android 上的 OpenGL ES 3.0 中不起作用

标签 android opengl-es glsl opengl-es-3.0

我尝试在我的项目中实现阴影贴图近一周了,但似乎没有一种方法有效。深度图纹理似乎是空的。

我一直在挖掘整个互联网,但没有任何帮助。也许我的代码中遗漏了一些东西。

这里我首先创建 FBO 和深度图纹理:

//  create depthMap
int[] depthMapPtr = new int[1];
GLES30.glGenTextures(1, depthMapPtr, 0);
depthMap = depthMapPtr[0];

//  use depthMap
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, depthMap);

GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT16, size, size, 
    0, GLES30.GL_DEPTH_COMPONENT, GLES30.GL_UNSIGNED_SHORT, null);

GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT);

//  create fbo
int[] fboPtr = new int[1];
GLES30.glGenFramebuffers(1, fboPtr, 0);
fbo = fboPtr[0];

//  use fbo
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fbo);
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, 
    GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_TEXTURE_2D, depthMap, 0);

//  draw/read buffers
int[] buffer = {GLES30.GL_NONE};
GLES30.glDrawBuffers(1, buffer, 0);
GLES30.glReadBuffer(GLES30.GL_NONE);

然后我定义深度着色器来渲染我的场景:

深度顶点着色器:

#version 300 es

layout (location = 0) in vec3 vPos;

uniform mat4 mLightSpace;
uniform mat4 mModel;

void main()
{
    gl_Position = mLightSpace * mModel * vec4(vPos, 1.0);
}

深度 fragment 着色器:

#version 300 es


//out float fragDepth;

void main()
{
    //fragDepth = gl_FragCoord.z;
}

(注释没有改变,结果是一样的)。

在从阴影角度渲染场景之前,我使用这段代码更改viewPort,清除深度缓冲区,绑定(bind)FBO:

GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);

//  clear the depth
GLES30.glClear(GLES30.GL_DEPTH_BUFFER_BIT);

GLES30.glViewport(0, 0, size, size);
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fbo);


//  use the shader program for the shadows
useProgramShadow();

完成深度渲染后,我准备好一切以通常的方式渲染场景:

GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);

GLES30.glViewport(0, 0, GLWindow.width, GLWindow.height);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);

GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, depthMap);


useProgram();

然后我从光的角度传递所有制服+ View /投影矩阵,然后渲染场景。

我用这些线从顶点着色器中的光线角度找到 fragment 位置:

const mat4 tMat = mat4(
    0.5, 0.0, 0.0, 0.0,
    0.0, 0.5, 0.0, 0.0,
    0.0, 0.0, 0.5, 0.0,
    0.5, 0.5, 0.5, 1.0
);

/* ... */

vFragPosLight = tMat * mLightSpace * mModel * vec4(vPosition, 1.0);

然后获取vFragPosLightdepthMap纹理

in vec4 vFragPosLight;
uniform sampler2DShadow depthMap;

...在 fragment 着色器中并使用此行计算阴影:

textureProj(depthMap, vFragPosLight);

...始终返回 0!

着色器编译没有错误,没有纹理到帧缓冲区绑定(bind)错误,一切似乎都正常工作,但深度图是空的。

非常感谢您的帮助,也感谢您花时间阅读!

最佳答案

我仍然不知道确切的问题是什么,但我已经阅读并使用了this book about OpenGL ES 3.0中的阴影贴图部分。这有效。

我可能必须禁用所有颜色渲染组件并将 glColorMask 设置为 False。

关于android - 阴影贴图在 Android 上的 OpenGL ES 3.0 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54226353/

相关文章:

android - 在android map 上的两个指定之间查找路线?

android - (Android) 如果我只将图像文件放在 drawable-xxhdpi 文件夹中,它是否适用于具有不同密度的所有设备

iphone - 应用商店 : blocking the game for 3G- devices

opengl - 英特尔和 GLSL - 无法编译片段着色器

glsl - webgl2.0我如何获得除uniformBuffer项目之外的所有制服

c++ - 如何更新 GLSL 中的统一变量

android - RxJava2, Android -> 这个单元测试有什么问题

android - 如何在 Android MVVM ViewModel 中获取上下文

android - OPENGL ES 不工作 : no Current context

iphone - 适用于iOS的OpenGL ES 2.0-多次调用glDrawElements导致EXC_BAD_ACCESS