2017-06-27 4 views
-2

J'essaye d'implémenter le mappage d'ombre dans ma scène, mais tout ce que je reçois est des zéros dans mon fragment shader quand j'appelle texture() (je l'ai testé avec == 0.0). Ma question: est-ce que j'envoie la texture de profondeur au shader correctement?Envoyer la carte d'ombre à shader dans OpenGL

Voici mon code shader fragment:

bool getShadow() { 
    vec4 lightProjPositionScaled = lightProjPosition/lightProjPosition.w; 
    vec2 texCoords = lightProjPositionScaled.xy*0.5 + 0.5; // bias 
    return lightProjPositionScaled.z + 0.0005 > texture(shadowMap, texCoords).x; 
} 

Voici mon code Java correspondant
Init (modifié en raison du commentaire BDL)

gl.glEnable(GL2.GL_TEXTURE_2D); 

// generate stuff 
IntBuffer ib = IntBuffer.allocate(1); 
gl.glGenFramebuffers(1, ib); 
frameBuffer = ib.get(0); 

ib = IntBuffer.allocate(1); 
gl.glGenTextures(1, ib); 
shadowMap = ib.get(0); 

gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer); 
gl.glBindTexture(GL2.GL_TEXTURE, shadowMap); 
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null); 
gl.glDrawBuffer(GL2.GL_NONE); 
gl.glReadBuffer(GL2.GL_NONE); 
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); 


// prevents 'shadow acne' 
gl.glPolygonOffset(2.5f, 0); 
// prevents multiple shadows 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE); 
// prevents (or expects!!!) pixel-y textures 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST); 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST); 
// store one value in all four components of pixel 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY); 

Affichage (1er passage, pour les ombres):

// render shadows 
gl.glUseProgram(shadowProgram); 

gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0); // yep (haha change viewMatrix -> lightMatrix) 
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0); 

gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, sha.frameBuffer); 

gl.glViewport(0, 0, 1024, 1024); 
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT); 
renderScene(gl, sunMatrix); 
gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0); 
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); 

Affichage (2ème passage, pour le rendu de la scène):

// render display (regular) 
gl.glUseProgram(displayProgram); 
gl.glDrawBuffer(GL2.GL_FRONT); 
gl.glReadBuffer(GL2.GL_FRONT); 

gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0); 
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0); 
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0); 
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0); // send sun's position to shader 
gl.glUniform1f(sunBrightnessLoc, sunBrightness); 
gl.glUniform1i(shadowMapLoc, 0); 

gl.glViewport(0, 0, screenWidth, screenHeight); 
// day-night cycle 
float[] color = SkyManager.getSkyColor(time); 
gl.glClearColor(color[0], color[1], color[2], 1); 
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 
gl.glActiveTexture(GL2.GL_TEXTURE0); 
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.shadowMap); 
renderScene(gl, sunMatrix); 

Un autre résultat est étrange que des fragments sur le z=0 plan par rapport à la matrice de lumière (en rotation est la lumière, et le plan tourne avec lui) sont allumés Tous les autres fragments, derrière et devant la lumière, sont ombrés.

+1

Vérifiez-vous quelque part les erreurs OpenGL? Je vois de la première vue au moins deux d'entre eux qui se passe. 'GL_RENDERBUFFER' n'est pas une cible supportée par' glBindTexture'. Vous n'attachez jamais la texture au framebuffer ('glFramebufferTexture2D'), donc il ne sera probablement pas complet. Vérifiez 'glCheckFramebufferStatus'. – BDL

+0

Ah, je suis passé à l'aide d'un tampon de rendu, puis je suis revenu à l'utilisation d'une texture. Lorsque j'utilise 'glCheckFramebufferStatus', j'obtiens' GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'. – clabe45

+0

Oui, car vous n'attachez jamais la texture de profondeur ... Et vous devrez appeler 'glDrawBuffer (GL_NONE)' avant de vérifier, sinon une pièce jointe en couleur est requise. – BDL

Répondre

0

Un problème était avec la ligne gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);

je lient la texture à GL_TEXTURE au lieu de GL_TEXTURE_2D.