6
\$\begingroup\$

I'm looking for a simple algorithm for LOD, for changing geometry vertexes and decreasing frame time. I've created an octree, but now I want model or terrain vertex modify algorithm, not for increase (looking on tessellation later) but for decrease.

I want something like this:

LOD

Questions:

  • Can the same algorithm apply to both model and terrain correctly?
  • Do indexes need to be modified?
  • Must I use octree or simple check distance between camera and object for desired effect?
  • Is a new value of indexcount for the DrawIndexed function needed?

Code:

     //m_LOD == 10 in the beginning
     //m_RawVerts - array of 3d Vector filled with values from vertex buffer.

     void DecreaseLOD()
     {
         m_LOD--;
         if(m_LOD<1)m_LOD=1;
         RebuildGeometry();
     }

     void IncreaseLOD()
     {
         m_LOD++;
         if(m_LOD>10)m_LOD=10;
         RebuildGeometry();
     }

     void RebuildGeometry()
     {    
         void* vertexRawData = new byte[m_VertexBufferSize];        
         void* indexRawData = new DWORD[m_IndexCount];
         auto context = mp_D3D->mp_Context;     

         D3D11_MAPPED_SUBRESOURCE data; 
         ZeroMemory(&data,sizeof(D3D11_MAPPED_SUBRESOURCE));

         context->Map(mp_VertexBuffer->mp_buffer,0,D3D11_MAP_READ,0,&data);
         memcpy(vertexRawData,data.pData,m_VertexBufferSize);
         context->Unmap(mp_VertexBuffer->mp_buffer,0);             

         context->Map(mp_IndexBuffer->mp_buffer,0,D3D11_MAP_READ,0,&data);
         memcpy(indexRawData,data.pData,m_IndexBufferSize);
         context->Unmap(mp_IndexBuffer->mp_buffer,0); 

         DWORD* dwI = (DWORD*)indexRawData;

         int sz = (m_VertexStride/sizeof(float));//size of vertex element

         //algorithm must be here.
         std::vector<Vector3d> vertices;
         int i = 0;
         for(int j = 0; j < m_VertexCount; j++)
         { 
             float x1 = (((float*)vertexRawData)[0+i]);
             float y1 = (((float*)vertexRawData)[1+i]);
             float z1 = (((float*)vertexRawData)[2+i]);
             Vector3d lv = Vector3d(x1,y1,z1);            

             //my useless attempts
             if(j+m_LOD+1<m_RawVerts.size())
             {
                 float v1 = VECTORHELPER::Distance(m_RawVerts[dwI[j]],m_RawVerts[dwI[j+m_LOD]]);
                 float v2 = VECTORHELPER::Distance(m_RawVerts[dwI[j]],m_RawVerts[dwI[j+m_LOD+1]]);   

                 if(v1>v2)
                     lv = m_RawVerts[dwI[j+1]];
                 else
                     if(v2<v1)
                         lv = m_RawVerts[dwI[j+2]];
             }     

             (((float*)vertexRawData)[0+i]) = lv.x;
             (((float*)vertexRawData)[1+i]) = lv.y;
             (((float*)vertexRawData)[2+i]) = lv.z;

             i+=sz;//pass others vertex format values without change     
         }  

         for(int j = 0; j < m_IndexCount; j++)
         {
             //indices ?
         }

         //set vertexes to device
         UpdateVertexes(vertexRawData,mp_VertexBuffer->getSize());             

         delete[] vertexRawData;
         delete[] indexRawData;
     }    
\$\endgroup\$
3
  • \$\begingroup\$ What shader model are you targeting? You might have a look at hull/geometry shaders. \$\endgroup\$
    – 3Dave
    Jul 8, 2012 at 17:14
  • \$\begingroup\$ hull&geometry ? 4.0/5.0 anyway - they for create geometry, and Im want decrease level of detail. \$\endgroup\$
    – ChaosDev
    Jul 8, 2012 at 17:28
  • \$\begingroup\$ See the link in my answers. Hull shaders are primarily for handling tessellation (ie, varying level of detail). \$\endgroup\$
    – 3Dave
    Jul 8, 2012 at 18:22

1 Answer 1

1
\$\begingroup\$

Hull shaders perform tessellation on the GPU, which makes handling variable level-of-detail pretty straightforward.

See this MSDN article for more information.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .