1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2013 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, carsten_neumann@gmx.net *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #ifndef _OSGCLUSTERSHADINGSTAGE_H_
40 #define _OSGCLUSTERSHADINGSTAGE_H_
45 #include "OSGClusterShadingStageBase.h"
46 #include "OSGAction.h"
47 #include "OSGClusterShadingStageDataFields.h"
50 #include "OSGImageFields.h"
51 #include "OSGTextureObjChunkFields.h"
52 #include "OSGTextureImageChunkFields.h"
53 #include "OSGShaderStorageBufferObjStdLayoutChunkFields.h"
54 #include "OSGUniformBufferObjStd140ChunkFields.h"
55 #include "OSGAlgorithmComputeElementFields.h"
63 /*! \brief ClusterShadingStage class. See \ref
64 PageContribTechniquesClusterShadingStage for a description.
67 class OSG_CONTRIBTECHNIQUES_DLLMAPPING ClusterShadingStage
: public ClusterShadingStageBase
71 /*========================== PUBLIC =================================*/
75 typedef ClusterShadingStageBase Inherited
;
76 typedef ClusterShadingStage Self
;
78 /*---------------------------------------------------------------------*/
82 virtual void changed(ConstFieldMaskArg whichField
,
87 /*---------------------------------------------------------------------*/
91 virtual void dump( UInt32 uiIndent
= 0,
92 const BitVector bvFlags
= 0) const;
95 /*---------------------------------------------------------------------*/
99 void initData (RenderAction
*pAction
,
105 void updateData(RenderAction
*pAction
,
113 /*---------------------------------------------------------------------*/
114 /*! \name Shader Program Snippets */
117 std::string
getFragmentProgramSnippet () const;
119 std::string
getClusteringProgSnippet (bool is_frag_shader
= true) const;
120 std::string
getFrustumProgSnippet () const;
121 std::string
getLightIndexProgSnippet () const;
124 /*========================= PROTECTED ===============================*/
128 /*---------------------------------------------------------------------*/
129 /*! \name Shader Program Snippets */
132 std::string
getDispatchProgSnippet () const;
136 /*---------------------------------------------------------------------*/
137 /*! \name Helper Types */
141 // simple frustum with only left, right, top and bottom planes.
142 // Front and back planes are calculated differently.
150 // data that are used in the compute shader code
154 DispatchData() : matTransf(), viewport(), numTiles() {}
162 // The clustering data are used in the light culling and in the
163 // fragment shader for the cluster key and z-coord calculation.
164 // Addditional some helper flags are added to this struct.
166 struct ClusteringData
169 : zNear (0.f
), zFar(0.f
) //, D(0.f)
170 , nD (0.f
), lg_nD(0.f
)
171 , a (0.f
), b(0.f
) //, c(0)
172 , c_1 (0), p_v (0,0) //, n_c(0,0,0)
176 Real32 zNear
; // positive near plane distance from eye zNear > 0
177 Real32 zFar
; // positive far plane distance from eye zFar > zNear > 0
178 //Real32 D; // positive near plane offset D >= 0, used only for testing
179 Real32 nD
; // zNear + D : shader optimization
180 Real32 lg_nD
; // log2(nD) : shader optimization
181 Real32 a
; // precalculated factor (c-1)/log2(f/(n+D))
182 Real32 b
; // precalculated factor log2(f/(n+D))/(c-1)
183 //Int32 c; // number of cluster planes used only for testing
184 Int32 c_1
; // number of cluster planes minus one : shader optimization
185 Vec2i p_v
; // viewport corner points
186 //Vec3i n_c; // number of clusters, used only for testing
187 bool enabled
;// enable cluster shading
190 struct LightEyeSpaceData
195 LightEyeSpaceData(void) :
196 position (0.f
, 0.f
, 0.f
),
197 direction(0.f
, 0.f
, 0.f
)
202 typedef std::vector
<Frustum
> VecFrustumsT
;
203 typedef std::pair
<UInt32
, UInt32
> ImageDataT
;
204 typedef std::vector
<ImageDataT
> VecImageDataT
;
205 typedef std::vector
<UInt32
> VecLightIndexT
;
206 typedef std::vector
<LightEyeSpaceData
> VecLightEyeSpaceDataT
;
210 Pnt3f c
; // Center point.
222 Pnt3f T
; // Cone tip.
223 Real32 h
; // Height of the cone.
224 Vec3f d
; // Direction of the cone.
225 Real32 r
; // bottom radius of the cone.
238 // Variables should all be in ClusterShadingStageBase.
240 /*---------------------------------------------------------------------*/
241 /*! \name Constructors */
244 ClusterShadingStage(void);
245 ClusterShadingStage(const ClusterShadingStage
&source
);
248 /*---------------------------------------------------------------------*/
249 /*! \name Destructors */
252 virtual ~ClusterShadingStage(void);
255 /*---------------------------------------------------------------------*/
259 Action::ResultE
renderEnter(Action
*action
);
260 Action::ResultE
renderLeave(Action
*action
);
263 /*---------------------------------------------------------------------*/
267 static void initMethod(InitPhase ePhase
);
270 /*---------------------------------------------------------------------*/
271 /*! \name StageData */
274 void setupStageData (ClusterShadingStageData
* pData
,
281 void updateStageData (ClusterShadingStageData
* pData
,
289 /*---------------------------------------------------------------------*/
290 /*! \name StageData Details */
294 /*---------------------------------------------------------------------*/
295 /*! \name Frustum Details */
298 (ClusterShadingStageData
* pData
,
302 (ClusterShadingStageData
* pData
,
303 const UInt32 idx
) const;
306 (ClusterShadingStageData
* pData
,
308 const Frustum
& frustum
);
310 std::size_t calc_frustum_buffer_size
311 (const VecFrustumsT
& vFrustums
);
313 std::vector
<UInt8
> create_frustum_buffer
314 (const VecFrustumsT
& vFrustums
);
316 ShaderStorageBufferObjStdLayoutChunkTransitPtr
318 (const VecFrustumsT
& vFrustums
);
320 void update_frustum_state
321 (ShaderStorageBufferObjStdLayoutChunk
* ssbo
,
322 const VecFrustumsT
& vFrustums
);
324 std::size_t calc_frustum_buffer_size
325 (ClusterShadingStageData
* pData
);
327 std::vector
<UInt8
> create_frustum_buffer
328 (ClusterShadingStageData
* pData
);
330 ShaderStorageBufferObjStdLayoutChunkTransitPtr
332 (ClusterShadingStageData
* pData
);
334 void update_frustum_state
335 (ShaderStorageBufferObjStdLayoutChunk
* ssbo
,
336 ClusterShadingStageData
* pData
);
338 void update_frustum_state
339 (ClusterShadingStageData
* pData
,
340 const VecFrustumsT
& vFrustums
);
342 bool check_frustum_state
343 (ClusterShadingStageData
* pData
,
344 const Vec4u
& viewport
);
348 const Vec4u
& viewport
,
353 (const Pnt3f
& p_w
, // with z-coord already
354 const Vec4u
& viewport
); // given in ndc coords!
358 const Matrix
& matInvProjection
);
360 bool isOrthographicCamera
365 void calc_ortho_frustums_cpu
366 (const Vec4u
& viewport
,
367 const Matrix
& matInvProjection
,
368 VecFrustumsT
& frustums
);
370 void calc_persp_frustums_cpu
371 (const Vec4u
& viewport
,
372 const Matrix
& matInvProjection
,
373 VecFrustumsT
& frustums
);
375 /*---------------------------------------------------------------------*/
376 /*! \name Image Details */
378 ImageTransitPtr create_image
382 bool allocate_memory
);
389 bool allocate_memory
);
391 void update_image_data
393 const VecImageDataT
& imageData
);
395 void write_image_data
399 const Vec3u
& dimensions
,
400 const ImageDataT
& data
,
401 VecImageDataT
& imageData
);
403 TextureObjChunkTransitPtr
407 void update_texture_state
408 (TextureObjChunk
* texObjChunk
);
410 TextureImageChunkTransitPtr
411 create_texture_image_state
412 (TextureObjChunk
* texObjChunk
,
413 const GLenum access
);
415 void update_light_grid_image
416 (const Vec4u
& viewport
,
418 bool allocate_memory
);
421 /*---------------------------------------------------------------------*/
422 /*! \name Light Index Details */
424 std::size_t calc_light_index_buffer_size
425 (const VecLightIndexT
& vIndexList
);
427 std::vector
<UInt8
> create_light_index_buffer
428 (const VecLightIndexT
& vIndexList
);
430 ShaderStorageBufferObjStdLayoutChunkTransitPtr
432 (const VecLightIndexT
& vIndexList
);
434 ShaderStorageBufferObjStdLayoutChunkTransitPtr
438 void update_index_state
439 (ShaderStorageBufferObjStdLayoutChunk
* ssbo
,
440 const VecLightIndexT
& vIndexList
);
442 void clear_index_state
443 (ShaderStorageBufferObjStdLayoutChunk
* ssbo
,
446 /*---------------------------------------------------------------------*/
447 /*! \name Light Index Counter Details */
449 ShaderStorageBufferObjStdLayoutChunkTransitPtr
450 create_light_index_counter_state();
452 void clear_light_index_counter_state
453 (ShaderStorageBufferObjStdLayoutChunk
* ssbo
);
455 /*---------------------------------------------------------------------*/
456 /*! \name Dispatch Data Details */
458 std::size_t calc_dispatch_data_buffer_size
459 (const DispatchData
& data
);
461 std::vector
<UInt8
> create_dispatch_data_buffer
462 (const DispatchData
& data
);
464 UniformBufferObjStd140ChunkTransitPtr
466 (const DispatchData
& data
);
468 void update_dispatch_data
469 (UniformBufferObjStd140Chunk
* ubo
,
470 const DispatchData
& data
);
472 /*---------------------------------------------------------------------*/
473 /*! \name Clustering Data Details */
475 std::size_t calc_clustering_data_buffer_size
476 (const ClusteringData
& data
);
478 std::vector
<UInt8
> create_clustering_data_buffer
479 (const ClusteringData
& data
);
481 UniformBufferObjStd140ChunkTransitPtr
482 create_clustering_data
483 (const ClusteringData
& data
);
485 void update_clustering_data
486 (UniformBufferObjStd140Chunk
* ubo
,
487 const ClusteringData
& data
);
489 /*---------------------------------------------------------------------*/
490 /*! \name Plane and Frustums Test */
492 bool PointInsidePlane (const Pnt3f
& p
,
495 bool SphereInsidePlane (const Sphere
& sphere
,
498 bool SphereInsideFrustum (const Sphere
& sphere
,
499 const Frustum
& frustum
,
503 bool ConeInsidePlane (const Cone
& cone
,
506 bool ConeInsideFrustum (const Cone
& cone
,
507 const Frustum
& frustum
,
511 /*---------------------------------------------------------------------*/
512 /*! \name Cluster Access */
514 UInt32
cluster_k (Real32 z_e
,
520 Real32
cluster_z (UInt32 k
,
526 UInt32
cluster_k (Real32 z_e
,
533 Real32
cluster_z (UInt32 k
,
540 /*---------------------------------------------------------------------*/
541 /*! \name Compute Shader Programs */
544 std::string
get_persp_frustum_cp_program();
545 std::string
get_ortho_frustum_cp_program();
546 std::string
get_light_culling_cp_program();
547 std::string
get_fragment_cp_program();
550 /*---------------------------------------------------------------------*/
551 /*! \name Computation */
554 void create_computation(ClusterShadingStageData
* pData
);
555 void update_computation(ClusterShadingStageData
* pData
);
558 /*---------------------------------------------------------------------*/
559 /*! \name Frustum Computation */
562 void create_frustum_computation(ClusterShadingStageData
* pData
);
565 /*---------------------------------------------------------------------*/
566 /*! \name Light Culling Computation */
569 void create_light_culling_computation(ClusterShadingStageData
* pData
);
572 /*---------------------------------------------------------------------*/
573 /*! \name Fragment Shader */
576 void create_fragment_shader(ClusterShadingStageData
* pData
);
579 /*---------------------------------------------------------------------*/
580 /*! \name Update Dispatch Configurations */
583 void update_dispatch_config_frustums
584 (ClusterShadingStageData
* pData
,
585 const Vec4u
& viewport
,
586 const Matrix
& matInvProjection
);
588 void update_dispatch_config_cull_lights
589 (ClusterShadingStageData
* pData
,
590 const Vec4u
& viewport
,
591 const Matrix
& matViewing
);
594 /*---------------------------------------------------------------------*/
595 /*! \name Calculate Affected Lights */
598 void calc_affected_lights (const Matrix
& matEyeFromWorld
,
599 FrustumVolume volViewFrustum
,
600 VecLightIndexT
& vecAffectedLights
,
601 VecLightEyeSpaceDataT
& vecEyeSpaceData
);
603 void transform_to_eye_space (Matrix matEyeFromWorld
,
605 const Pnt3f
& position_bs
,
606 const Vec3f
& direction_bs
,
608 Vec3f
& direction_es
);
610 bool point_light_inside_frustum
611 (const Pnt3f
& position_es
,
613 const Frustum
& frustum
,
617 bool spot_light_inside_frustum
618 (const Pnt3f
& position_es
,
619 const Vec3f
& direction_es
,
621 Real32 spotlightAngle
,
622 const Frustum
& frustum
,
627 /*---------------------------------------------------------------------*/
628 /*! \name CPU Light Culling */
631 std::size_t frustum_accessor
634 const Vec3u
& dimensions
);
637 (ClusterShadingStageData
* pData
,
638 const VecLightIndexT
& vecAffectedLights
,
639 const VecLightEyeSpaceDataT
& vecEyeSpaceData
,
640 const Vec3u
& dimensions
,
641 const Matrix
& matEyeFromWorld
,
645 VecImageDataT
& gridData
,
646 VecLightIndexT
& lightIndexList
);
649 /*========================== PRIVATE ================================*/
655 friend class FieldContainer
;
656 friend class ClusterShadingStageBase
;
658 // prohibit default functions (move to 'public' if you need one)
659 void operator =(const ClusterShadingStage
&source
);
662 typedef ClusterShadingStage
*ClusterShadingStageP
;
666 #include "OSGClusterShadingStageBase.inl"
667 #include "OSGClusterShadingStage.inl"
669 #endif /* _OSGCLUSTERSHADINGSTAGE_H_ */