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

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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 : 210
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  

+ 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