2016-07-28 4 views
0

J'utilise OpenGL 4.3 sous GeForce GTX 750 pour créer Shadow Map. En ce moment, l'effet de base, montré ci-dessous, semble être correct: enter image description here Pour effacer l'effet de block, j'ai essayé de faire un PCF 2x2 manuellement dans le shader. Pour l'accélération, je veux utiliser le bénéfice apporté par la carte graphique, qui donne le filtre linéaire du résultat de la comparaison avec un aller chercher. Mais l'effet était différent de celui ci-dessus. Il est plus comme OpenGL filtre le rendu de l'ombre linéaire, mais pas les filtres sur la carte Ombre: enter image description here Voici c'est comment je fais le PCF matériel: J'ai remarqué que les deux choses de base qui doivent être fait en pour utiliser le PCF matériel, qui sont:Matériel PCF pour Shadow Map en utilisant OpenGL

  1. l'aide d'un échantillonneur de type shadow, qui dans mon cas, est samplerCubeShadow (j'utilise un type de carte de cube depuis que je suis en train de créer une scène lumière ponctuelle) .
  2. Définissez le type de mode de comparaison et de filtrage, qui dans mon cas, est fait par le code suivant:

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 
    

Après cela, j'utiliser la fonction texture dans le shader comme celui-ci (la raison que j'utilise texture mais pas textureProj est parce que ce dernier ne semble pas soutenir la texture d'ombre carte cube car il aura besoin d'un type vec5 qui est évidemment pas encore pris en charge):

vec4 posInLight4D = positionsInLight/positionsInLight.w; // divided by the 4-th component) 
vec3 texCoord = GetCubeMapTexCoord(posInLight4D.xy); // get the texture coordinate in cube map texture. This can be assumed correct 
float lightness = texture(shadowMapHardware, vec4(texCoord, posInLight4D.z)); 

Mais malheureusement, cela donne le résultat montré dans la troisième image.

Pour autant que je le comprends, le réglage du mode et filtre linéaire, la carte graphique comparaison va faire la comparaison dans une région 2x2 à proximité et interpoler linéairement les résultats et lui donne retour à travers la fonction texture. Je pense avoir fait toutes les parties nécessaires, mais je n'arrive toujours pas à obtenir le résultat exact de la deuxième photo.

Quelqu'un peut-il me donner des suggestions sur les endroits où je pourrais me tromper? Merci beaucoup.

ps: La chose intéressante est: J'ai essayé la fonction textureGather, qui renvoie uniquement les résultats de la comparaison, mais ne pas le filtrage, et il donne le résultat exact comme indiqué sur la 2ème image. Mais il manque une procédure de filtrage automatique et évidemment ce n'est pas la version complète du matériel PCF.

Répondre

2

Pour effacer l'effet de bloc, j'ai essayé de faire un PCF 2x2 manuellement dans le shader. Il conduit au résultat suivant, qui semble également être correct:

La spécification OpenGL ne dicte pas l'algorithme spécifique à utiliser lors de l'interpolation linéaire des comparaisons de profondeur.Cependant, il décrit généralement comme:

Les détails de cette mise en œuvre dépendent de la, mais r devrait être une valeur dans l'intervalle [0,1] qui est proportionnelle au nombre de comparaison passes ou des échecs .

Ce n'est pas très contraignant, et il ne nécessite certainement pas la sortie que vous voyez comme "correcte".

En effet, actual PCF diffère beaucoup de ce que vous suggérez que vous voulez. Ce que vous semblez vouloir est encore très bloquant; ce n'est pas binaire blocs. Votre algorithme n'a pas interpolé linéairement entre les résultats de la comparaison; vous venez de faire les 4 comparaisons les plus proches et les moyenné ensemble.

Qu'est-ce que NVIDIA vous donne est ce que la CPD est en fait censé ressembler à: interpolation linéaire entre les résultats de la comparaison, en fonction du point de vous échantillonnage.

Vos attentes sont donc mauvaises, pas NVIDIA.

+0

Donc, en faisant la moyenne des résultats de la comparaison, je ne fais pas le "interpolation linéaire" que NVIDIA effectue , droite? J'ai vérifié le matériel que vous avez fourni auparavant, mais il ne dit rien sur la façon dont cette interpolation est faite. Pouvez-vous me dire plus de détails à ce sujet? THX. – Narusaki

+1

@Narusaki: C'est une interpolation linéaire. Cela fonctionne exactement comme ce serait le cas pour les cas de non-comparaison, mais seulement pour l'interpolation sur les valeurs de post-comparaison. –

+1

Oh, je pense avoir compris ce que vous voulez dire: l'interpolation linéaire devrait utiliser la distance entre la "coordonnée centrale" et les quatre "coordonnées d'angle" comme le "poids", non seulement la moyenne des quatre valeurs sur la Dans ce cas, le poids est de 0,25. Est-ce exact? – Narusaki

0

Par la réponse de @Nicol, je pense que j'ai mal compris la signification de l'interpolation. Voici ma mise en œuvre d'une interpolation de niveau shader, qui ressemble exactement à la deuxième image de la question: enter image description here