简体   繁体   English

阴影映射在 Android 上的 OpenGL ES 3.0 中不起作用

[英]Shadow mapping not working in OpenGL ES 3.0 on Android

I am trying to implement shadow mapping in my project for almost a week, and none of methods seem to work.我试图在我的项目中实施阴影贴图将近一周,但似乎没有任何方法有效。 The depth map texture seem to be empty.深度图纹理似乎是空的。

I have been digging the whole internet and nothing helped me.我一直在挖掘整个互联网,但没有任何帮助。 Maybe I'm missing something in my code.也许我在我的代码中遗漏了一些东西。

Here I start by creating the FBO and a Depth Map texture :在这里,我首先创建 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);

Then I define the depth shaders to render my scene on :然后我定义深度着色器来渲染我的场景:

VERTEX SHADER FOR DEPTH :深度的顶点着色器:

#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 SHADER FOR DEPTH :深度片段着色器:

#version 300 es


//out float fragDepth;

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

(the comments change nothing, the result is the same). (评论没有改变,结果是一样的)。

Before rendering the scene from the shadow perspective, I use this piece of code to change the viewPort, clear depth buffer, bind the FBO :在从阴影角度渲染场景之前,我使用这段代码来更改viewPort,清除深度缓冲区,绑定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();

After I finish rendering the depth, I prepare everything to render the scene the usual way :完成深度渲染后,我准备一切以通常的方式渲染场景:

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();

Than I pass all the uniforms + the View/Projection matrix from the light perspective, and I render the scene.然后我从光的角度传递所有制服 + 视图/投影矩阵,然后渲染场景。

I find the fragment position from the light perspective in the vertex shader with those lines :我在顶点着色器中从光的角度找到片段位置,其中包含以下几行:

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);

To then get the vFragPosLight and the depthMap texture然后获取vFragPosLightdepthMap纹理

in vec4 vFragPosLight;
uniform sampler2DShadow depthMap;

...in the fragment shader and calculate the shadow with this line : ...在片段着色器中并使用此行计算阴影:

textureProj(depthMap, vFragPosLight);

...which always returns 0! ...它总是返回 0!

There is no errors with the shader compilations, no texture to framebuffer binding error, everything seems to be working find, but the depthMap is empty.着色器编译没有错误,没有纹理到帧缓冲区的绑定错误,一切似乎都可以找到,但 depthMap 是空的。

I really appreciate you for your help and thank you for taking your time to read!我非常感谢您的帮助,并感谢您花时间阅读!

I still don't know what the exact problem was, but I've read and used the Shadow Mapping part in this book about OpenGL ES 3.0 which worked. 我仍然不知道确切的问题是什么,但是我已经阅读并使用了有关OpenGL ES 3.0的本书中的阴影映射部分。

It's possible that I had to disable all the color rendering components with glColorMask set to False. 我可能不得不在glColorMask设置为False的情况下禁用所有颜色渲染组件。

when you create frame buffer, you need to check if the frame buffer is successfully created.创建帧缓冲区时,需要检查帧缓冲区是否创建成功。

glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// set up hardware comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
                GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,
                GL_LEQUAL);
//android use GL_DEPTH_COMPONENT16
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT,
             GL_UNSIGNED_SHORT,
             NULL);
glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &mDepthFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mDepthFbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
glDrawBuffers(1, GL_NONE);
glReadBuffer(GL_NONE);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthTexture);

if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
    LOGI("frame buffer success");
} else {
    LOGI("frame buffer fail");
}

I have the same problem with you, finally I found the reason is framebuffer create failed, so I fixed the GL_DEPTH_COMPONENT to GL_DEPTH_COMPONENT16, framebuffer success and depth map is OK!我和你有同样的问题,最后我找到原因是framebuffer create failed,所以我把GL_DEPTH_COMPONENT固定为GL_DEPTH_COMPONENT16,framebuffer成功,深度图就OK了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM