IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Tile Frustum Culling


Sujet :

OpenGL

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Points : 56
    Points
    56
    Par défaut Tile Frustum Culling
    Bonjour,

    J'essaie d'implémenter du frustum culling pour des sources de lumières basé sur des tuiles en utilisant un compute shader.
    L'idée est de générer les normales des plans du frustum dans la view space. Chaque tuile peut donc estimer si une source de lumière
    se situe dans son frustum en calculant la distance (dot product) entre la normale et la position de la lumière.

    Le culling semble bien s'effectuer mais les normales me paraissent anormales. En effet, les lumières situées dans la partie inférieur gauche
    de la tuile ne sont pas prise en compte. Voici une image de la situation:

    Nom : tileculling.jpg
Affichages : 181
Taille : 48,5 Ko

    Voici le compute shader simplifié:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    vec4 unProject(vec4 clipSpace)
    {
    	vec4 homo = inv_camera_projection * clipSpace;
    	homo.xyz /= homo.w;
    	homo.w = 0.0f;
    	return homo;
    }
     
    vec4 createPlaneEquation(vec4 b, vec4 c)
    {
    	vec4 n;
    	n.xyz = normalize(cross(b.xyz, c.xyz));
    	n.w = 0;
     
    	return n;
    }
     
    layout(local_size_x = CULL_TILE_COUNT, local_size_y = CULL_TILE_COUNT, local_size_z = 1) in;
    void main()
    {
        ivec2 globalID = ivec2(gl_GlobalInvocationID.xy);
        ivec2 localID = ivec2(gl_LocalInvocationID.xy);
        ivec2 tileID = ivec2(gl_WorkGroupID.xy);
        ivec2 tileNumber = ivec2(gl_NumWorkGroups.xy);
        uint index = tileID.y * tileNumber.x + tileID.x;
     
        // Initialize shared global values for depth and light count
    	if(gl_LocalInvocationIndex == 0)
    	{
    		screenSize = textureSize(depth_texture, 0);
    		visibleLightCount = 0;
    	}
     
    	barrier();
     
    	if(gl_LocalInvocationIndex == 0)
    	{
    		float minX = ((tileID.x / float(CULL_TILE_COUNT)) * 2.0f) - 1.0f;
    		float minY = ((tileID.y / float(CULL_TILE_COUNT)) * 2.0f) - 1.0f;
    		float maxX = (((tileID.x + 1) / float(CULL_TILE_COUNT)) * 2.0f) - 1.0f;
    		float maxY = (((tileID.y + 1) / float(CULL_TILE_COUNT)) * 2.0f) - 1.0f;
     
    		vec4 corners[4];
    		// 3-------2
    		// |       |
    		// |       |
    		// 0-------1
    		corners[0] = unProject(vec4(minX, minY, 1.0f, 1.0f));
    		corners[1] = unProject(vec4(maxX, minY, 1.0f, 1.0f));
    		corners[2] = unProject(vec4(maxX, maxY, 1.0f, 1.0f));
    		corners[3] = unProject(vec4(minX, maxY, 1.0f, 1.0f));
     
    		vec4 frustum[4];
    		frustum[0] = createPlaneEquation(corners[0], corners[1]); //Bottom
    		frustum[1] = createPlaneEquation(corners[2], corners[3]); //Up
    		frustum[2] = createPlaneEquation(corners[3], corners[1]); //Left
    		frustum[3] = createPlaneEquation(corners[1], corners[2]); //Right
     
    		for(uint i = 0; i < point_light_count; i++)
    		{
    			vec4 position = vec4(point_lights[i].position, 1.0f); //view space
    			float radius = point_lights[i].radius;
     
    			bool inside = true;
    			for(int f = 0; f < 4; f++)
    			{
    				if(dot(frustum[f].xyz, position.xyz) > radius)
    				{
    					inside = false;
    					break;
    				}
    			}
     
    			if(inside)
    			{
    				uint offset = atomicAdd(visibleLightCount, 1);
    				visibleLightIndices[offset] = int(i);
    			}
    		}
    	}
     
    	barrier();
     
    	if(gl_LocalInvocationIndex == 0) 
    	{
    		uint offset = index * POINTLIGHT_CULL_MAX_NUMBER;
    		for(uint i = 0; i < visibleLightCount; i++)
    		{
    			point_lights_cull_indices[offset + i] = visibleLightIndices[i];
    		}
     
    		if(visibleLightCount != POINTLIGHT_CULL_MAX_NUMBER) 
    		{
    			point_lights_cull_indices[offset + visibleLightCount] = -1;
    		}
    	}
    }
    On notera que la profondeur n'est pas prise en compte.

    Merci pour votre aide.
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Pour ma part je n'ai pas compris de quel 'frustum culling' vous parlez parce qu'ils en existent plusieurs :
    -Backface culling : qui se fait coté GPU et automatiquement (avec glEnable(GL_CULL_FACE); par exemple).
    -Viewing frustum culling qui se fait coté CPU avec un box
    -Contribution culling : pareil on regarde juste la taille de la box (et non si elle est hors-champ).
    -Occlusion culling : (élimination des objets cachés) : c'est le fait de déterminer quelles parties d'un objet sont cachées par un autre pour un point de vue donné. , et pour ma part le ZBuffer remplit ce rôle.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Points : 56
    Points
    56
    Par défaut
    Le "tile-based light culling" s'apparente plus à du Viewing Frustum Culling sauf que le clip space originel est réduit à la tuile. C'est pour cela que l'on exécute l'algorithme côté GPU, puisqu'on peut avoir une multitude de tuile.
    Dans mon cas actuel, le frustum n'est composé que des plans haut/bas/gauche/droite.

    Je complète ma réponse avec cette présentation rapide du tile base light culling réalisé par Dimitri Zhdan:
    http://twvideo01.ubm-us.net/o1/vault...lling_MGPU.pdf

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Points : 56
    Points
    56
    Par défaut
    Problème résolu !
    La normale du plan de gauche était incorrect.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frustum[2] = createPlaneEquation(corners[3], corners[1]); //Left
    Doit être:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frustum[2] = createPlaneEquation(corners[3], corners[0]); //Left

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [DirectX 10] Frustum culling et vertex buffer
    Par CrankFlash dans le forum DirectX
    Réponses: 3
    Dernier message: 27/02/2011, 12h44
  2. Frustum culling : problème
    Par casafa dans le forum OpenGL
    Réponses: 17
    Dernier message: 09/11/2007, 08h32
  3. clipping / frustum culling
    Par Elendhil dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 13/06/2007, 21h57
  4. Frustum Culling optimisé
    Par Ingham dans le forum Développement 2D, 3D et Jeux
    Réponses: 12
    Dernier message: 19/05/2007, 17h50
  5. Probleme avec du frustum Culling
    Par zlamouche dans le forum OpenGL
    Réponses: 13
    Dernier message: 18/03/2004, 08h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo