Merge ~mrluzeiro/kicad:improve_anti_aliasing into ~kicad-product-committers/kicad:master

Proposed by Mario Luzeiro
Status: Merged
Merge reported by: Seth Hillbrand
Merged at revision: 98fa0a57127e47d93e8807c07dde5145aefd9be9
Proposed branch: ~mrluzeiro/kicad:improve_anti_aliasing
Merge into: ~kicad-product-committers/kicad:master
Diff against target: 1697 lines (+563/-702)
7 files modified
3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h (+1/-1)
3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp (+371/-649)
3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h (+14/-1)
3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp (+78/-14)
3d-viewer/3d_rendering/3d_render_raytracing/raypacket.h (+15/-0)
3d-viewer/3d_rendering/ccamera.cpp (+76/-37)
3d-viewer/3d_rendering/ccamera.h (+8/-0)
Reviewer Review Type Date Requested Status
Wayne Stambaugh Approve
Review via email: mp+309090@code.launchpad.net

Description of the change

improve anti-aliasing

+re-implement anti-aliasing, making it more accurate, not blured, better
and much faster (using much less lines of code)
+rewrite some function on camera and raypacket.
+small improvements on raytracing realtime, remove useless ifs

To post a comment you must log in.
Revision history for this message
Mario Luzeiro (mrluzeiro) wrote :
Revision history for this message
Wayne Stambaugh (stambaughw) wrote :

I merged this patch into the product master branch. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h
2index 050a9eb..798e1a4 100644
3--- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h
4+++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h
5@@ -120,7 +120,7 @@ public:
6 // Imported from CGENERICACCELERATOR
7 bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const override;
8 bool Intersect( const RAY &aRay, HITINFO &aHitInfo, unsigned int aAccNodeInfo ) const override;
9- bool Intersect(const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const override;
10+ bool Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const override;
11 bool IntersectP( const RAY &aRay, float aMaxDistance ) const override;
12
13 private:
14diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp
15index 89cccb5..f09fe9f 100644
16--- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp
17+++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp
18@@ -466,6 +466,176 @@ void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO,
19 ptrPBO[3] = 255;
20 }
21
22+
23+static void HITINFO_PACKET_init( HITINFO_PACKET *aHitPacket )
24+{
25+ // Initialize hitPacket with a "not hit" information
26+ for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
27+ {
28+ aHitPacket[i].m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
29+ aHitPacket[i].m_HitInfo.m_acc_node_info = 0;
30+ aHitPacket[i].m_hitresult = false;
31+ aHitPacket[i].m_HitInfo.m_HitNormal = SFVEC3F();
32+ aHitPacket[i].m_HitInfo.m_ShadowFactor = 1.0f;
33+ }
34+}
35+
36+
37+void C3D_RENDER_RAYTRACING::rt_shades_packet(const SFVEC3F *bgColorY,
38+ const RAY *aRayPkt,
39+ HITINFO_PACKET *aHitPacket,
40+ bool is_testShadow,
41+ SFVEC3F *aOutHitColor )
42+{
43+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
44+ {
45+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
46+ {
47+ if( aHitPacket[i].m_hitresult == true )
48+ {
49+ aOutHitColor[i] = shadeHit( bgColorY[y],
50+ aRayPkt[i],
51+ aHitPacket[i].m_HitInfo,
52+ false,
53+ 0,
54+ is_testShadow );
55+ }
56+ else
57+ {
58+ aOutHitColor[i] = bgColorY[y];
59+ }
60+ }
61+ }
62+}
63+
64+
65+void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
66+ const HITINFO_PACKET *aHitPck_X0Y0,
67+ const HITINFO_PACKET *aHitPck_AA_X1Y1,
68+ const RAY *aRayPck,
69+ SFVEC3F *aOutHitColor )
70+{
71+ // If post processing is using, do not calculate shadows as they will not be
72+ // used for futher post processing.
73+ const bool is_testShadow = m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) &&
74+ !m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
75+
76+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
77+ {
78+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
79+ {
80+ const RAY &rayAA = aRayPck[i];
81+
82+ HITINFO hitAA;
83+ hitAA.m_tHit = std::numeric_limits<float>::infinity();
84+ hitAA.m_acc_node_info = 0;
85+
86+ bool hitted = false;
87+
88+ const unsigned int idx0y1 = ( x + 0 ) + RAYPACKET_DIM * ( y + 1 );
89+ const unsigned int idx1y1 = ( x + 1 ) + RAYPACKET_DIM * ( y + 1 );
90+
91+ // Gets the node info from the hit.
92+ const unsigned int nodex0y0 = aHitPck_X0Y0[ i ].m_HitInfo.m_acc_node_info;
93+ const unsigned int node_AA_x0y0 = aHitPck_AA_X1Y1[ i ].m_HitInfo.m_acc_node_info;
94+
95+ unsigned int nodex1y0 = 0;
96+
97+ if( x < (RAYPACKET_DIM - 1) )
98+ nodex1y0 = aHitPck_X0Y0[ i + 1 ].m_HitInfo.m_acc_node_info;
99+
100+ unsigned int nodex0y1 = 0;
101+
102+ if( y < (RAYPACKET_DIM - 1) )
103+ nodex0y1 = aHitPck_X0Y0[ idx0y1 ].m_HitInfo.m_acc_node_info;
104+
105+ unsigned int nodex1y1 = 0;
106+
107+ if( ((x < (RAYPACKET_DIM - 1)) &&
108+ (y < (RAYPACKET_DIM - 1))) )
109+ nodex1y1 = aHitPck_X0Y0[ idx1y1 ].m_HitInfo.m_acc_node_info;
110+
111+
112+ if( (nodex0y0 == nodex1y0) && // If all notes are equal we assume there was no change on the object hits
113+ (nodex0y0 == nodex0y1) &&
114+ (nodex0y0 == nodex1y1) &&
115+ (nodex0y0 == node_AA_x0y0) )
116+ {
117+ // Option 1
118+ // This option will give a very good quality on reflections (slow)
119+ /*
120+ if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
121+ {
122+ aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
123+ }
124+ else
125+ {
126+ if( m_accelerator->Intersect( rayAA, hitAA ) )
127+ aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
128+ else
129+ aOutHitColor[i] += hitColor[i];
130+ }
131+ */
132+
133+ // Option 2
134+ // Trace again with the same node,
135+ // then if miss just give the same color as before
136+ //if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
137+ // aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
138+
139+ }
140+ else
141+ {
142+ // Try to intersect the different nodes
143+ // It tests the possible combination of hitted or not hitted points
144+ // This will try to get the best hit for this ray
145+
146+ if( nodex0y0 != 0 )
147+ hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
148+
149+ if( ( nodex1y0 != 0 ) &&
150+ ( nodex0y0 != nodex1y0 ) )
151+ hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
152+
153+ if( ( nodex0y1 != 0 ) &&
154+ ( nodex0y0 != nodex0y1 ) &&
155+ ( nodex1y0 != nodex0y1 ) )
156+ hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
157+
158+ if( (nodex1y1 != 0 ) &&
159+ ( nodex0y0 != nodex1y1 ) &&
160+ ( nodex0y1 != nodex1y1 ) &&
161+ ( nodex1y0 != nodex1y1 ) )
162+ hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y1 );
163+
164+ if( (node_AA_x0y0 != 0 ) &&
165+ ( nodex0y0 != node_AA_x0y0 ) &&
166+ ( nodex0y1 != node_AA_x0y0 ) &&
167+ ( nodex1y0 != node_AA_x0y0 ) &&
168+ ( nodex1y1 != node_AA_x0y0 ) )
169+ hitted |= m_accelerator->Intersect( rayAA, hitAA, node_AA_x0y0 );
170+
171+ if( hitted )
172+ {
173+ // If we got any result, shade it
174+ aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow );
175+ }
176+ else
177+ {
178+ // Note: There are very few cases that will end on this situation
179+ // so it is not so expensive to trace a single ray from the beginning
180+
181+ // It was missed the 'last nodes' so, trace a ray from the beginning
182+ if( m_accelerator->Intersect( rayAA, hitAA ) )
183+ aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow );
184+ }
185+ }
186+ }
187+ }
188+}
189+
190+#define DISP_FACTOR 0.075f
191+
192 void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
193 signed int iBlock )
194 {
195@@ -475,19 +645,14 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
196 const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset,
197 blockPos.y + m_yoffset );
198
199- RAYPACKET blockPacket( m_settings.CameraGet(), blockPosI );
200+ RAYPACKET blockPacket( m_settings.CameraGet(),
201+ (SFVEC2F)blockPosI + SFVEC2F(DISP_FACTOR, DISP_FACTOR),
202+ SFVEC2F(DISP_FACTOR, DISP_FACTOR) // Displacement random factor
203+ );
204
205- HITINFO_PACKET hitPacket[RAYPACKET_RAYS_PER_PACKET];
206+ HITINFO_PACKET hitPacket_X0Y0[RAYPACKET_RAYS_PER_PACKET];
207
208- // Initialize hitPacket with a "not hit" information
209- for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
210- {
211- hitPacket[i].m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
212- hitPacket[i].m_HitInfo.m_acc_node_info = 0;
213- hitPacket[i].m_hitresult = false;
214- hitPacket[i].m_HitInfo.m_HitNormal = SFVEC3F();
215- hitPacket[i].m_HitInfo.m_ShadowFactor = 1.0f;
216- }
217+ HITINFO_PACKET_init( hitPacket_X0Y0 );
218
219 // Calculate background gradient color
220 // /////////////////////////////////////////////////////////////////////////
221@@ -503,7 +668,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
222
223 // Intersect ray packets (calculate the intersection with rays and objects)
224 // /////////////////////////////////////////////////////////////////////////
225- if( !m_accelerator->Intersect( blockPacket, hitPacket ) )
226+ if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
227 {
228
229 // If block is empty then set shades and continue
230@@ -556,597 +721,147 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
231 }
232
233
234- // Shade hits ("paint" the intersected objects)
235- // /////////////////////////////////////////////////////////////////////////
236-
237- SFVEC3F hitColor[RAYPACKET_RAYS_PER_PACKET];
238+ SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET];
239
240- for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
241- {
242- for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
243- {
244- if( hitPacket[i].m_hitresult == true )
245- {
246- hitColor[i] = shadeHit( bgColor[y],
247- blockPacket.m_ray[i],
248- hitPacket[i].m_HitInfo,
249- false,
250- 0 );
251- }
252- else
253- {
254- hitColor[i] = bgColor[y];
255- }
256- }
257- }
258-
259-
260- // This code was a tentative to retrace the block but using small changes
261- // on ray direction (to work as a random anti-aliasing)
262- // but it was not producing good results with low passes,
263- // parked for future use / to be implemented
264+ // Shade original (0, 0) hits ("paint" the intersected objects)
265 // /////////////////////////////////////////////////////////////////////////
266-
267- /*
268- //if( m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
269- if(0)
270- {
271- SFVEC3F absDirDiff;
272- absDirDiff.x = glm::abs( blockPacket.m_ray[ 1].m_Dir.x - blockPacket.m_ray[0].m_Dir.x ) * 0.45f;
273- absDirDiff.y = glm::abs( blockPacket.m_ray[RAYPACKET_DIM + 0].m_Dir.y - blockPacket.m_ray[0].m_Dir.y ) * 0.45f;
274- absDirDiff.z = glm::abs( blockPacket.m_ray[RAYPACKET_DIM + 1].m_Dir.z - blockPacket.m_ray[0].m_Dir.z ) * 0.45f;
275-
276- const unsigned int number_of_passes = 16;
277-
278- for( unsigned int aaPasses = 0; aaPasses < number_of_passes; ++aaPasses )
279- {
280-
281- HITINFO_PACKET hitPacketAA[RAYPACKET_RAYS_PER_PACKET];
282-
283- // Initialize hitPacket with a "not hit" information
284- for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
285- {
286- hitPacketAA[i].m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
287- hitPacketAA[i].m_HitInfo.m_acc_node_info = 0;
288- hitPacketAA[i].m_hitresult = false;
289- hitPacketAA[i].m_HitInfo.m_HitNormal = SFVEC3F();
290- hitPacketAA[i].m_HitInfo.m_ShadowFactor = 1.0f;
291- }
292-
293- RAYPACKET blockPacketAA( m_settings.CameraGet(), blockPosI, absDirDiff );
294-
295- if( m_accelerator->Intersect( blockPacketAA, hitPacketAA ) )
296- {
297- for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
298- {
299- for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
300- {
301- if( hitPacketAA[i].m_hitresult == true )
302- {
303- hitColor[i] += shadeHit( bgColor[y],
304- blockPacketAA.m_ray[i],
305- hitPacketAA[i].m_HitInfo,
306- false,
307- 0 );
308- }
309- else
310- {
311- hitColor[i] += bgColor[y];
312- }
313- }
314- }
315- }
316- }
317-
318- const float aaPasses_inv = 1.0f / (float)(number_of_passes + 1);
319-
320- for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
321- hitColor[i] *= aaPasses_inv;
322- }
323- */
324-
325- // If anti-aliasing is enabled, trace a new random rays over the hits
326- // already calculated.
327- // On this pass it will calculate pixels near the hitted ray,
328- // so it will reuse the nodes found on that hits
329- // /////////////////////////////////////////////////////////////////////
330+ rt_shades_packet( bgColor,
331+ blockPacket.m_ray,
332+ hitPacket_X0Y0,
333+ m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ),
334+ hitColor_X0Y0 );
335
336 if( m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
337 {
338+ SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
339
340- SFVEC3F hitColorAA[RAYPACKET_RAYS_PER_PACKET];
341-
342- for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
343- hitColorAA[i] = SFVEC3F(0.0f);
344-
345- // This just get some difference between two pixels
346- // There is not logic on this approach, it trys to guess the xyz increments
347- SFVEC3F absDirDiff;
348- absDirDiff.x = glm::abs( blockPacket.m_ray[RAYPACKET_DIM + 0].m_Dir.x -
349- blockPacket.m_ray[0].m_Dir.x ) * 0.55f;
350-
351- absDirDiff.y = glm::abs( blockPacket.m_ray[RAYPACKET_DIM + 0].m_Dir.y -
352- blockPacket.m_ray[0].m_Dir.y ) * 0.55f;
353
354- absDirDiff.z = glm::abs( blockPacket.m_ray[RAYPACKET_DIM + 0].m_Dir.z -
355- blockPacket.m_ray[0].m_Dir.z ) * 0.55f;
356+ // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation
357+ // /////////////////////////////////////////////////////////////////////////
358+ HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
359+ HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
360
361- const unsigned int number_of_passes = 3;
362+ RAYPACKET blockPacket_AA_X1Y1( m_settings.CameraGet(),
363+ (SFVEC2F)blockPosI + SFVEC2F(0.5f, 0.5f),
364+ SFVEC2F(DISP_FACTOR, DISP_FACTOR) // Displacement random factor
365+ );
366
367- for( unsigned int aaPasses = 0; aaPasses < number_of_passes; ++aaPasses )
368+ if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
369 {
370+ // Missed all the package
371 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
372 {
373+ const SFVEC3F &outColor = bgColor[y];
374+
375 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
376 {
377- if( hitPacket[i].m_hitresult == true )
378- {
379- const SFVEC3F randVector = SFVEC3F( Fast_RandFloat() * absDirDiff.x,
380- Fast_RandFloat() * absDirDiff.y,
381- Fast_RandFloat() * absDirDiff.z );
382-
383- RAY rayAA;
384- rayAA.Init( blockPacket.m_ray[i].m_Origin,
385- glm::normalize( blockPacket.m_ray[i].m_Dir +
386- randVector ) );
387-
388- HITINFO hitAA;
389- hitAA.m_tHit = std::numeric_limits<float>::infinity();
390- hitAA.m_acc_node_info = 0;
391- hitAA.m_ShadowFactor = 1.0f;
392-
393- bool hitted = false;
394-
395- const unsigned int idx0y1 = ( x + 0 ) + RAYPACKET_DIM * ( y + 1 );
396- const unsigned int idx1y1 = ( x + 1 ) + RAYPACKET_DIM * ( y + 1 );
397-
398- // Gets the node info from the hit. If there was no hit, return 0
399- const unsigned int nodex0y0 = (hitPacket[ i ].m_hitresult == false)?0:
400- hitPacket[ i ].m_HitInfo.m_acc_node_info;
401-
402- unsigned int nodex1y0 = 0;
403-
404- if( x < (RAYPACKET_DIM - 1) )
405- nodex1y0 = (hitPacket[ i + 1 ].m_hitresult == false)?0:
406- hitPacket[ i + 1 ].m_HitInfo.m_acc_node_info;
407-
408- unsigned int nodex0y1 = 0;
409-
410- if( y < (RAYPACKET_DIM - 1) )
411- nodex0y1 = (hitPacket[ idx0y1 ].m_hitresult == false)?0:
412- hitPacket[ idx0y1 ].m_HitInfo.m_acc_node_info;
413-
414- unsigned int nodex1y1 = 0;
415-
416- if( ((x < (RAYPACKET_DIM - 1)) &&
417- (y < (RAYPACKET_DIM - 1))) )
418- nodex1y1 = (hitPacket[ idx1y1 ].m_hitresult == false)?0:
419- hitPacket[ idx1y1 ].m_HitInfo.m_acc_node_info;
420-
421-
422- if( (nodex0y0 == nodex1y0) && //
423- (nodex0y0 == nodex0y1) &&
424- (nodex0y0 == nodex1y1) )
425- {
426- // Option 1
427- // This option will give a very good quality on reflections (slow)
428- /*
429- if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
430- {
431- hitColorAA[i] += shadeHit( bgColor[y], rayAA, hitAA, false, 0 );
432- }
433- else
434- {
435- if( m_accelerator->Intersect( rayAA, hitAA ) )
436- hitColorAA[i] += shadeHit( bgColor[y], rayAA, hitAA, false, 0 );
437- else
438- hitColorAA[i] += hitColor[i];
439- }
440- */
441-
442- // Option 2
443- // Trace again with the same node,
444- // then if miss just give the same color as before
445- //if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
446- // hitColorAA[i] += shadeHit( bgColor[y], rayAA, hitAA, false, 0 );
447- //else
448- // This option will give the same color as the hit before (faster)
449- hitColorAA[i] += hitColor[i];
450- }
451- else
452- {
453- // Try to intersect the different nodes
454- // It tests the possible combination of hitted or not hitted points
455- // This will try to get the best hit for this ray
456-
457- if( nodex0y0 != 0 )
458- hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
459-
460- if( nodex1y0 != 0 )
461- if( ( nodex0y0 != nodex1y0 ) || ( nodex0y0 == 0 ) )
462- hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
463-
464- if( nodex0y1 != 0 )
465- if( ( ( nodex0y0 != nodex0y1 ) || ( nodex0y0 == 0 ) ) &&
466- ( ( nodex1y0 != nodex0y1 ) || ( nodex1y0 == 0 ) ) )
467- hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
468-
469- if( nodex1y1 != 0 )
470- if( ( ( nodex0y0 != nodex1y1 ) || ( nodex0y0 == 0 ) ) &&
471- ( ( nodex0y1 != nodex1y1 ) || ( nodex0y1 == 0 ) ) &&
472- ( ( nodex1y0 != nodex1y1 ) || ( nodex1y0 == 0 ) ) )
473- hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y1 );
474-
475- if( hitted )
476- {
477- // If he got any result, shade it
478- hitColorAA[i] += shadeHit( bgColor[y], rayAA, hitAA, false, 0 );
479- }
480- else
481- {
482- // It was missed the 'last nodes' so, trace a ray from the beginning
483- if( m_accelerator->Intersect( rayAA, hitAA ) )
484- hitColorAA[i] += shadeHit( bgColor[y], rayAA, hitAA, false, 0 );
485- else
486- hitColorAA[i] += hitColor[i];
487- }
488- }
489- }
490- else
491- {
492- hitColorAA[i] += hitColor[i];
493- }
494+ hitColor_AA_X1Y1[i] = outColor;
495 }
496 }
497 }
498+ else
499+ {
500+ rt_shades_packet( bgColor,
501+ blockPacket_AA_X1Y1.m_ray,
502+ hitPacket_AA_X1Y1,
503+ m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) &&
504+ (!m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING )),
505+ hitColor_AA_X1Y1
506+ );
507+ }
508
509- const float aaPasses_inv = 1.0f / (float)number_of_passes;
510+ SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
511+ SFVEC3F hitColor_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
512+ SFVEC3F hitColor_AA_X0Y1_half[RAYPACKET_RAYS_PER_PACKET];
513
514 for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
515- hitColor[i] = hitColor[i] * 0.40f + (hitColorAA[i] * aaPasses_inv) * 0.60f;
516- }
517-
518-
519- // Trace adaptative anti-aliasing middle pixels
520- // /////////////////////////////////////////////////////////////////////
521-
522- HITINFO_PACKET hitPacketAA[ (RAYPACKET_DIM-1) * (RAYPACKET_DIM-1) ];
523- RAY raysAA[ (RAYPACKET_DIM-1) * (RAYPACKET_DIM-1) ];
524- SFVEC3F hitColorAA[ (RAYPACKET_DIM-1) * (RAYPACKET_DIM-1) ];
525- bool hittedAA[ (RAYPACKET_DIM-1) * (RAYPACKET_DIM-1) ];
526-
527- if( m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
528- {
529- for( unsigned int y = 0, i = 0; y < (RAYPACKET_DIM - 1); ++y )
530 {
531- for( unsigned int x = 0; x < (RAYPACKET_DIM - 1); ++x, ++i )
532- {
533- hitColorAA[i] = bgColor[y];
534- hittedAA[i] = false;
535+ const SFVEC3F color_average = ( hitColor_X0Y0[i] +
536+ hitColor_AA_X1Y1[i] ) * SFVEC3F(0.5f);
537
538- const unsigned int idx0y0 = (x + 0) + RAYPACKET_DIM * (y + 0);
539- const unsigned int idx1y0 = (x + 1) + RAYPACKET_DIM * (y + 0);
540- const unsigned int idx0y1 = (x + 0) + RAYPACKET_DIM * (y + 1);
541- const unsigned int idx1y1 = (x + 1) + RAYPACKET_DIM * (y + 1);
542-
543- // Evaluate if we can skip the pixel from trace if the adjacent
544- // pixels are similar (hitted, similar color and normal)
545-
546- if( hitPacket[ idx0y0 ].m_hitresult &&
547- hitPacket[ idx1y0 ].m_hitresult &&
548- hitPacket[ idx0y1 ].m_hitresult &&
549- hitPacket[ idx1y1 ].m_hitresult )
550- {
551- // Calc the average gray scale
552-
553- // Average
554- /*
555- const float gray_idx0y0 =
556- (hitColor[idx0y0].r + hitColor[idx0y0].g + hitColor[idx0y0].b ) / 3.0f;
557- const float gray_idx1y0 =
558- (hitColor[idx1y0].r + hitColor[idx1y0].g + hitColor[idx1y0].b ) / 3.0f;
559- const float gray_idx0y1 =
560- (hitColor[idx0y1].r + hitColor[idx0y1].g + hitColor[idx0y1].b ) / 3.0f;
561- const float gray_idx1y1 =
562- (hitColor[idx1y1].r + hitColor[idx1y1].g + hitColor[idx1y1].b ) / 3.0f;
563- */
564-
565-
566- // Luminance
567- const float gray_idx0y0 = (hitColor[idx0y0].r * 0.2126f +
568- hitColor[idx0y0].g * 0.7152f +
569- hitColor[idx0y0].b * 0.0722f);
570-
571- const float gray_idx1y0 = (hitColor[idx1y0].r * 0.2126f +
572- hitColor[idx1y0].g * 0.7152f +
573- hitColor[idx1y0].b * 0.0722f);
574-
575- const float gray_idx0y1 = (hitColor[idx0y1].r * 0.2126f +
576- hitColor[idx0y1].g * 0.7152f +
577- hitColor[idx0y1].b * 0.0722f);
578-
579- const float gray_idx1y1 = (hitColor[idx1y1].r * 0.2126f +
580- hitColor[idx1y1].g * 0.7152f +
581- hitColor[idx1y1].b * 0.0722f);
582-
583- const float threshould_color = 0.070f;
584-
585- // Check if there are no big difference, if not,
586- // it will continue and not process anti-aliasing
587- if( ( glm::abs( gray_idx0y0 - gray_idx1y0) < threshould_color ) &&
588- ( glm::abs( gray_idx0y0 - gray_idx0y1) < threshould_color ) &&
589- ( glm::abs( gray_idx0y1 - gray_idx1y1) < threshould_color ) &&
590- ( glm::abs( gray_idx1y1 - gray_idx1y0) < threshould_color ) )
591- {
592- continue;
593- }
594- }
595-
596-
597- // Use this code if you want to see (debug) the pixels that are interpolated
598- // hitColorAA[i] = SFVEC3F(1.0f, 0.0f, 1.0f);
599- // hittedAA[i] = true;
600- // continue;
601-
602-
603-
604- // Initialize a ray that is in the middle of the 4 pixeis and
605- // have an average direction of the 4 pixels
606- raysAA[i].Init( ( blockPacket.m_ray[idx0y0].m_Origin +
607- blockPacket.m_ray[idx1y0].m_Origin +
608- blockPacket.m_ray[idx0y1].m_Origin +
609- blockPacket.m_ray[idx1y1].m_Origin ) / 4.0f,
610- glm::normalize( ( blockPacket.m_ray[idx0y0].m_Dir +
611- blockPacket.m_ray[idx1y0].m_Dir +
612- blockPacket.m_ray[idx0y1].m_Dir +
613- blockPacket.m_ray[idx1y1].m_Dir ) ) );
614-
615- hitPacketAA[i].m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
616- hitPacketAA[i].m_HitInfo.m_acc_node_info = 0;
617- hitPacketAA[i].m_HitInfo.m_ShadowFactor = 1.0f;
618- hitPacketAA[i].m_hitresult = false;
619-
620- bool hitted = false;
621-
622- // Gets the node info from the hit. If there was no hit, return 0
623- const unsigned int nodex0y0 = (hitPacket[ idx0y0 ].m_hitresult == false)?0:
624- hitPacket[ idx0y0 ].m_HitInfo.m_acc_node_info;
625-
626- const unsigned int nodex1y0 = (hitPacket[ idx1y0 ].m_hitresult == false)?0:
627- hitPacket[ idx1y0 ].m_HitInfo.m_acc_node_info;
628-
629- const unsigned int nodex0y1 = (hitPacket[ idx0y1 ].m_hitresult == false)?0:
630- hitPacket[ idx0y1 ].m_HitInfo.m_acc_node_info;
631-
632- const unsigned int nodex1y1 = (hitPacket[ idx1y1 ].m_hitresult == false)?0:
633- hitPacket[ idx1y1 ].m_HitInfo.m_acc_node_info;
634-
635- // Try to intersect the different nodes
636- // It tests the possible combination of hitted or not hitted points
637- // This will try to get the best hit for this ray
638-
639- if( nodex0y0 != 0 )
640- hitted |= m_accelerator->Intersect( raysAA[i],
641- hitPacketAA[i].m_HitInfo,
642- nodex0y0 );
643-
644- if( nodex1y0 != 0 )
645- if( ( nodex0y0 != nodex1y0 ) || ( nodex0y0 == 0 ) )
646- hitted |= m_accelerator->Intersect( raysAA[i],
647- hitPacketAA[i].m_HitInfo,
648- nodex1y0 );
649-
650- if( nodex0y1 != 0 )
651- if( ( ( nodex0y0 != nodex0y1 ) || ( nodex0y0 == 0 ) ) &&
652- ( ( nodex1y0 != nodex0y1 ) || ( nodex1y0 == 0 ) ) )
653- hitted |= m_accelerator->Intersect( raysAA[i],
654- hitPacketAA[i].m_HitInfo,
655- nodex0y1 );
656-
657- if( nodex1y1 != 0 )
658- if( ( ( nodex0y0 != nodex1y1 ) || ( nodex0y0 == 0 ) ) &&
659- ( ( nodex0y1 != nodex1y1 ) || ( nodex0y1 == 0 ) ) &&
660- ( ( nodex1y0 != nodex1y1 ) || ( nodex1y0 == 0 ) ) )
661- hitted |= m_accelerator->Intersect( raysAA[i],
662- hitPacketAA[i].m_HitInfo,
663- nodex1y1 );
664-
665- if( hitted )
666- {
667- // If he got any result, shade it
668- hitColorAA[i] = shadeHit( bgColor[y],
669- raysAA[i],
670- hitPacketAA[i].m_HitInfo,
671- false,
672- 0 );
673- }
674- else
675- {
676- // It was missed the 'last nodes' so,
677- // trace a ray from the beginning
678- if( m_accelerator->Intersect( raysAA[i], hitPacketAA[i].m_HitInfo ) )
679- hitColorAA[i] = shadeHit( bgColor[y],
680- raysAA[i],
681- hitPacketAA[i].m_HitInfo,
682- false,
683- 0 );
684- }
685+ hitColor_AA_X1Y0[i] = color_average;
686+ hitColor_AA_X0Y1[i] = color_average;
687+ hitColor_AA_X0Y1_half[i] = color_average;
688+ }
689
690- hittedAA[i] = true;
691- }
692+ RAY blockRayPck_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
693+ RAY blockRayPck_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
694+ RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
695+
696+ RAYPACKET_InitRays_with2DDisplacement( m_settings.CameraGet(),
697+ (SFVEC2F)blockPosI + SFVEC2F(0.5f - DISP_FACTOR, DISP_FACTOR),
698+ SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
699+ blockRayPck_AA_X1Y0 );
700+
701+ RAYPACKET_InitRays_with2DDisplacement( m_settings.CameraGet(),
702+ (SFVEC2F)blockPosI + SFVEC2F(DISP_FACTOR, 0.5f - DISP_FACTOR),
703+ SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
704+ blockRayPck_AA_X0Y1 );
705+
706+ RAYPACKET_InitRays_with2DDisplacement( m_settings.CameraGet(),
707+ (SFVEC2F)blockPosI + SFVEC2F(0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR),
708+ SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
709+ blockRayPck_AA_X1Y1_half );
710+
711+ rt_trace_AA_packet( bgColor,
712+ hitPacket_X0Y0, hitPacket_AA_X1Y1,
713+ blockRayPck_AA_X1Y0,
714+ hitColor_AA_X1Y0 );
715+
716+ rt_trace_AA_packet( bgColor,
717+ hitPacket_X0Y0, hitPacket_AA_X1Y1,
718+ blockRayPck_AA_X0Y1,
719+ hitColor_AA_X0Y1 );
720+
721+ rt_trace_AA_packet( bgColor,
722+ hitPacket_X0Y0, hitPacket_AA_X1Y1,
723+ blockRayPck_AA_X1Y1_half,
724+ hitColor_AA_X0Y1_half );
725+
726+ // Average the result
727+ for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
728+ {
729+ hitColor_X0Y0[i] = ( hitColor_X0Y0[i] +
730+ hitColor_AA_X1Y1[i] +
731+ hitColor_AA_X1Y0[i] +
732+ hitColor_AA_X0Y1[i] +
733+ hitColor_AA_X0Y1_half[i]
734+ ) * SFVEC3F(1.0f / 5.0f);
735 }
736 }
737
738
739- // Blend original hitted pixels with anti-alised pixels
740+ // Copy results to the next stage
741 // /////////////////////////////////////////////////////////////////////
742- for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
743- {
744- for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
745- {
746- SFVEC3F hColor = hitColor[i];
747
748- if( m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
749- {
750- SFVEC3F aaColor = bgColor[y];
751+ GLubyte *ptr = &ptrPBO[ ( blockPos.x +
752+ (blockPos.y * m_realBufferSize.x) ) * 4 ];
753
754- if( (x > 0) &&
755- (y > 0) &&
756- ( x < (RAYPACKET_DIM - 1) ) &&
757- ( y < (RAYPACKET_DIM - 1) ) )
758- {
759- // It makes a blur of the hitColor
760- const SFVEC3F averageHitColor =
761- hitColor[ (x - 1) + RAYPACKET_DIM * (y - 1) ] * 0.0625f +
762- hitColor[ (x + 0) + RAYPACKET_DIM * (y - 1) ] * 0.1250f +
763- hitColor[ (x + 1) + RAYPACKET_DIM * (y - 1) ] * 0.0625f +
764- hitColor[ (x - 1) + RAYPACKET_DIM * (y + 0) ] * 0.1250f +
765- hitColor[ (x + 0) + RAYPACKET_DIM * (y + 0) ] * 0.2500f +
766- hitColor[ (x + 1) + RAYPACKET_DIM * (y + 0) ] * 0.1250f +
767- hitColor[ (x - 1) + RAYPACKET_DIM * (y + 1) ] * 0.0625f +
768- hitColor[ (x + 0) + RAYPACKET_DIM * (y + 1) ] * 0.1250f +
769- hitColor[ (x + 1) + RAYPACKET_DIM * (y + 1) ] * 0.0625f;
770-
771-
772- const unsigned x0y0 = (x - 1) + (RAYPACKET_DIM - 1) * (y - 1);
773- const unsigned x1y0 = (x - 0) + (RAYPACKET_DIM - 1) * (y - 1);
774- const unsigned x0y1 = (x - 1) + (RAYPACKET_DIM - 1) * (y - 0);
775- const unsigned x1y1 = (x - 0) + (RAYPACKET_DIM - 1) * (y - 0);
776-
777- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: averageHitColor) +
778- (hittedAA[ x1y0 ]? hitColorAA[ x1y0 ]: averageHitColor) +
779- (hittedAA[ x0y1 ]? hitColorAA[ x0y1 ]: averageHitColor) +
780- (hittedAA[ x1y1 ]? hitColorAA[ x1y1 ]: averageHitColor);
781-
782- aaColor /= 4.0f;
783- }
784- else
785- {
786- if( (x == 0) && (y == 0) )
787- {
788- const unsigned x0y0 = (x - 0) + (RAYPACKET_DIM - 1) * (y - 0);
789- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: hColor);
790- }
791- else
792- {
793- if( (x == (RAYPACKET_DIM - 1)) && (y == (RAYPACKET_DIM - 1)) )
794- {
795- const unsigned x0y0 = (x - 1) + (RAYPACKET_DIM - 1) * (y - 1);
796- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: hColor);
797- }
798- else
799- {
800- if( (x == (RAYPACKET_DIM - 1)) && (y == 0) )
801- {
802- const unsigned x0y0 = (x - 1) + (RAYPACKET_DIM - 1) * (y - 0);
803- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: hColor);
804- }
805- else
806- {
807- if( (x == 0) && (y == (RAYPACKET_DIM - 1)) )
808- {
809- const unsigned x0y0 = (x - 0) + (RAYPACKET_DIM - 1) * (y - 1);
810- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: hColor);
811- }
812- else
813- {
814- if( ( y == 0 ) && ( x < (RAYPACKET_DIM - 1) ) )
815- {
816- const unsigned x0y0 = (x - 1) + (RAYPACKET_DIM - 1) *
817- (y - 0);
818- const unsigned x1y0 = (x - 0) + (RAYPACKET_DIM - 1) *
819- (y - 0);
820-
821- aaColor = (hittedAA[ x0y0 ]? hitColorAA[ x0y0 ]: hColor) +
822- (hittedAA[ x1y0 ]? hitColorAA[ x1y0 ]: hColor);
823-
824- aaColor = aaColor / 2.0f;
825- }
826- else
827- {
828- if( ( y == (RAYPACKET_DIM - 1) ) &&
829- ( x < (RAYPACKET_DIM - 1) ) )
830- {
831- const unsigned x0y0 = (x - 1) + (RAYPACKET_DIM - 1) *
832- (y - 1);
833- const unsigned x1y0 = (x - 0) + (RAYPACKET_DIM - 1) *
834- (y - 1);
835-
836- aaColor = (hittedAA[ x0y0 ]?hitColorAA[ x0y0 ]:hColor) +
837- (hittedAA[ x1y0 ]?hitColorAA[ x1y0 ]:hColor);
838-
839- aaColor = aaColor / 2.0f;
840- }
841- else
842- {
843- if( ( x == 0 ) && ( y < (RAYPACKET_DIM - 1) ) )
844- {
845- const unsigned x0y0 = (x - 0) +
846- (RAYPACKET_DIM - 1) * (y - 1);
847- const unsigned x0y1 = (x - 0) +
848- (RAYPACKET_DIM - 1) * (y - 0);
849-
850- aaColor = (hittedAA[x0y0]?hitColorAA[x0y0]:hColor) +
851- (hittedAA[x0y1]?hitColorAA[x0y1]:hColor);
852-
853- aaColor = aaColor / 2.0f;
854- }
855- else
856- {
857- if( ( x == (RAYPACKET_DIM - 1) ) &&
858- ( y < (RAYPACKET_DIM - 1) ) )
859- {
860- const unsigned x0y0 = (x - 1) +
861- (RAYPACKET_DIM - 1) *
862- (y - 1);
863-
864- const unsigned x0y1 = (x - 1) +
865- (RAYPACKET_DIM - 1) *
866- (y - 0);
867-
868- aaColor =
869- (hittedAA[x0y0]?hitColorAA[x0y0]:hColor) +
870- (hittedAA[x0y1]?hitColorAA[x0y1]:hColor);
871-
872- aaColor = aaColor / 2.0f;
873- }
874- else
875- {
876- aaColor = SFVEC3F(1.0f, 0.0f, 1.0f ); // Invalid
877- }
878- }
879- }
880- }
881- }
882- }
883- }
884- }
885- }
886+ const uint32_t ptrInc = (m_realBufferSize.x - RAYPACKET_DIM) * 4;
887
888- // Calculate the final blend color. It gives more importance
889- // to the original color
890- hColor = hColor * 0.60f + aaColor * 0.40f;
891- }
892+ if( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
893+ {
894+ SFVEC2I bPos;
895+ bPos.y = blockPos.y;
896
897- // This will set the output color to be displayed
898- // If post processing is enabled, it will not reflect the final result
899- // (as the final color will be computed on post processing)
900- // but it is used for report progress
901- GLubyte *ptr = &ptrPBO[ ( blockPos.x + x +
902- ((y + blockPos.y) * m_realBufferSize.x) ) * 4 ];
903+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
904+ {
905+ bPos.x = blockPos.x;
906
907- if( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
908+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
909 {
910- if( hitPacket[i].m_hitresult == true )
911- m_postshader_ssao.SetPixelData( blockPos.x + x, blockPos.y + y,
912- hitPacket[i].m_HitInfo.m_HitNormal,
913+ const SFVEC3F &hColor = hitColor_X0Y0[i];
914+
915+ if( hitPacket_X0Y0[i].m_hitresult == true )
916+ m_postshader_ssao.SetPixelData( bPos.x, bPos.y,
917+ hitPacket_X0Y0[i].m_HitInfo.m_HitNormal,
918 hColor,
919 blockPacket.m_ray[i].at(
920- hitPacket[i].m_HitInfo.m_tHit ),
921- hitPacket[i].m_HitInfo.m_tHit,
922- hitPacket[i].m_HitInfo.m_ShadowFactor );
923+ hitPacket_X0Y0[i].m_HitInfo.m_tHit ),
924+ hitPacket_X0Y0[i].m_HitInfo.m_tHit,
925+ hitPacket_X0Y0[i].m_HitInfo.m_ShadowFactor );
926 else
927- m_postshader_ssao.SetPixelData( blockPos.x + x, blockPos.y + y,
928+ m_postshader_ssao.SetPixelData( bPos.x, bPos.y,
929 SFVEC3F(),
930 hColor,
931 SFVEC3F(),
932@@ -1154,11 +869,26 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
933 1.0f );
934
935 rt_final_color( ptr, hColor, false );
936+
937+ bPos.x++;
938+ ptr += 4;
939 }
940- else
941+
942+ ptr += ptrInc;
943+ bPos.y++;
944+ }
945+ }
946+ else
947+ {
948+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
949+ {
950+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
951 {
952- rt_final_color( ptr, hColor, true );
953+ rt_final_color( ptr, hitColor_X0Y0[i], true );
954+ ptr += 4;
955 }
956+
957+ ptr += ptrInc;
958 }
959 }
960 }
961@@ -1399,7 +1129,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
962
963 for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
964 {
965- const SFVEC3F bhColorY = bgColor[i/RAYPACKET_DIM];
966+ const SFVEC3F bhColorY = bgColor[i / RAYPACKET_DIM];
967
968 if( hitPacket[i].m_hitresult == true )
969 {
970@@ -1407,7 +1137,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
971 blockPacket.m_ray[i],
972 hitPacket[i].m_HitInfo,
973 false,
974- 0 );
975+ 0,
976+ false );
977
978 hitColorShading[i] = CCOLORRGB( hitColor );
979 }
980@@ -1485,38 +1216,31 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
981 RAY centerRay;
982 centerRay.Init( oriC, dirC );
983
984- const unsigned int nodeLT = (hitPacket[ iLT ].m_hitresult == false)?0:
985- hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
986-
987- const unsigned int nodeRT = (hitPacket[ iRT ].m_hitresult == false)?0:
988- hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
989-
990- const unsigned int nodeLB = (hitPacket[ iLB ].m_hitresult == false)?0:
991- hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
992-
993- const unsigned int nodeRB = (hitPacket[ iRB ].m_hitresult == false)?0:
994- hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
995+ const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
996+ const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
997+ const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
998+ const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
999
1000 if( nodeLT != 0 )
1001 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLT );
1002
1003- if( nodeRT != 0 )
1004- if( ( nodeRT != nodeLT ) || ( nodeLT == 0 ) )
1005- hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRT );
1006+ if( ( nodeRT != 0 ) &&
1007+ ( nodeRT != nodeLT ) )
1008+ hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRT );
1009
1010- if( nodeLB != 0 )
1011- if( ( ( nodeLB != nodeLT ) || ( nodeLT == 0 ) ) &&
1012- ( ( nodeLB != nodeRT ) || ( nodeRT == 0 ) ) )
1013+ if( ( nodeLB != 0 ) &&
1014+ ( nodeLB != nodeLT ) &&
1015+ ( nodeLB != nodeRT ) )
1016 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLB );
1017
1018- if( nodeRB != 0 )
1019- if( ( ( nodeRB != nodeLB ) || ( nodeLB == 0 ) ) &&
1020- ( ( nodeRB != nodeLT ) || ( nodeLT == 0 ) ) &&
1021- ( ( nodeRB != nodeRT ) || ( nodeRT == 0 ) ) )
1022+ if( ( nodeRB != 0 ) &&
1023+ ( nodeRB != nodeLB ) &&
1024+ ( nodeRB != nodeLT ) &&
1025+ ( nodeRB != nodeRT ) )
1026 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRB );
1027
1028 if( hittedC )
1029- cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, false, 0 ) );
1030+ cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, false, 0, false ) );
1031 else
1032 {
1033 centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
1034@@ -1527,7 +1251,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1035 centerRay,
1036 centerHitInfo,
1037 false,
1038- 0 ) );
1039+ 0,
1040+ false ) );
1041 }
1042 }
1043
1044@@ -1559,7 +1284,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1045 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1046 hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f );
1047
1048- cLRT = CCOLORRGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, false, 0 ) );
1049+ cLRT = CCOLORRGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, false, 0, false ) );
1050 cLRT = BlendColor( cLRT, BlendColor( cLT, cRT) );
1051 }
1052 else
1053@@ -1567,29 +1292,27 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1054 if( hitPacket[ iLT ].m_hitresult ||
1055 hitPacket[ iRT ].m_hitresult ) // If any hits
1056 {
1057- const unsigned int nodeLT = (hitPacket[ iLT ].m_hitresult == false)?0:
1058- hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1059-
1060- const unsigned int nodeRT = (hitPacket[ iRT ].m_hitresult == false)?0:
1061- hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1062+ const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1063+ const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1064
1065 bool hittedLRT = false;
1066
1067 if( nodeLT != 0 )
1068 hittedLRT |= m_accelerator->Intersect( rayLRT, hitInfoLRT, nodeLT );
1069
1070- if( nodeRT != 0 )
1071- if( ( nodeRT != nodeLT ) || ( nodeLT == 0 ) )
1072- hittedLRT |= m_accelerator->Intersect( rayLRT,
1073- hitInfoLRT,
1074- nodeRT );
1075+ if( ( nodeRT != 0 ) &&
1076+ ( nodeRT != nodeLT ) )
1077+ hittedLRT |= m_accelerator->Intersect( rayLRT,
1078+ hitInfoLRT,
1079+ nodeRT );
1080
1081 if( hittedLRT )
1082 cLRT = CCOLORRGB( shadeHit( bgColorY,
1083 rayLRT,
1084 hitInfoLRT,
1085 false,
1086- 0 ) );
1087+ 0,
1088+ false ) );
1089 else
1090 {
1091 hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
1092@@ -1599,7 +1322,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1093 rayLRT,
1094 hitInfoLRT,
1095 false,
1096- 0 ) );
1097+ 0,
1098+ false ) );
1099 }
1100 }
1101 }
1102@@ -1636,7 +1360,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1103 hitInfoLTB.m_HitNormal =
1104 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1105 hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f );
1106- cLTB = CCOLORRGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, 0 ) );
1107+ cLTB = CCOLORRGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, 0, false ) );
1108 cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) );
1109 }
1110 else
1111@@ -1644,11 +1368,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1112 if( hitPacket[ iLT ].m_hitresult ||
1113 hitPacket[ iLB ].m_hitresult ) // If any hits
1114 {
1115- const unsigned int nodeLT = (hitPacket[ iLT ].m_hitresult == false)?0:
1116- hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1117-
1118- const unsigned int nodeLB = (hitPacket[ iLB ].m_hitresult == false)?0:
1119- hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1120+ const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1121+ const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1122
1123 bool hittedLTB = false;
1124
1125@@ -1657,18 +1378,19 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1126 hitInfoLTB,
1127 nodeLT );
1128
1129- if( nodeLB != 0 )
1130- if( ( nodeLB != nodeLT ) || ( nodeLT == 0 ) )
1131- hittedLTB |= m_accelerator->Intersect( rayLTB,
1132- hitInfoLTB,
1133- nodeLB );
1134+ if( ( nodeLB != 0 ) &&
1135+ ( nodeLB != nodeLT ) )
1136+ hittedLTB |= m_accelerator->Intersect( rayLTB,
1137+ hitInfoLTB,
1138+ nodeLB );
1139
1140 if( hittedLTB )
1141 cLTB = CCOLORRGB( shadeHit( bgColorY,
1142 rayLTB,
1143 hitInfoLTB,
1144 false,
1145- 0 ) );
1146+ 0,
1147+ false ) );
1148 else
1149 {
1150 hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
1151@@ -1678,7 +1400,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1152 rayLTB,
1153 hitInfoLTB,
1154 false,
1155- 0 ) );
1156+ 0,
1157+ false ) );
1158 }
1159 }
1160 }
1161@@ -1713,7 +1436,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1162 glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
1163 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1164
1165- cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0 ) );
1166+ cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, false ) );
1167 cRTB = BlendColor( cRTB, BlendColor( cRT, cRB) );
1168 }
1169 else
1170@@ -1721,26 +1444,25 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1171 if( hitPacket[ iRT ].m_hitresult ||
1172 hitPacket[ iRB ].m_hitresult ) // If any hits
1173 {
1174- const unsigned int nodeRT = (hitPacket[ iRT ].m_hitresult == false)?0:
1175- hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1176- const unsigned int nodeRB = (hitPacket[ iRB ].m_hitresult == false)?0:
1177- hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1178+ const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1179+ const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1180
1181 bool hittedRTB = false;
1182
1183 if( nodeRT != 0 )
1184 hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRT );
1185
1186- if( nodeRB != 0 )
1187- if( ( nodeRB != nodeRT ) || ( nodeRT == 0 ) )
1188- hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRB );
1189+ if( ( nodeRB != 0 ) &&
1190+ ( nodeRB != nodeRT ) )
1191+ hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRB );
1192
1193 if( hittedRTB )
1194 cRTB = CCOLORRGB( shadeHit( bgColorY,
1195 rayRTB,
1196 hitInfoRTB,
1197 false,
1198- 0 ) );
1199+ 0,
1200+ false) );
1201 else
1202 {
1203 hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
1204@@ -1750,7 +1472,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1205 rayRTB,
1206 hitInfoRTB,
1207 false,
1208- 0 ) );
1209+ 0,
1210+ false ) );
1211 }
1212 }
1213 }
1214@@ -1787,7 +1510,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1215 glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
1216 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1217
1218- cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0 ) );
1219+ cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) );
1220 cLRB = BlendColor( cLRB, BlendColor( cLB, cRB) );
1221 }
1222 else
1223@@ -1795,22 +1518,20 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1224 if( hitPacket[ iLB ].m_hitresult ||
1225 hitPacket[ iRB ].m_hitresult ) // If any hits
1226 {
1227- const unsigned int nodeLB = (hitPacket[ iLB ].m_hitresult == false)?0:
1228- hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1229- const unsigned int nodeRB = (hitPacket[ iRB ].m_hitresult == false)?0:
1230- hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1231+ const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1232+ const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1233
1234 bool hittedLRB = false;
1235
1236 if( nodeLB != 0 )
1237 hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeLB );
1238
1239- if( nodeRB != 0 )
1240- if( ( nodeRB != nodeLB ) || ( nodeLB == 0 ) )
1241- hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeRB );
1242+ if( ( nodeRB != 0 ) &&
1243+ ( nodeRB != nodeLB ) )
1244+ hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeRB );
1245
1246 if( hittedLRB )
1247- cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0 ) );
1248+ cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) );
1249 else
1250 {
1251 hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
1252@@ -1820,7 +1541,8 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1253 rayLRB,
1254 hitInfoLRB,
1255 false,
1256- 0 ) );
1257+ 0,
1258+ false ) );
1259 }
1260 }
1261 }
1262@@ -1852,7 +1574,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1263 hitInfoLTC );
1264
1265 if( hitted )
1266- cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, 0 ) );
1267+ cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, 0, false ) );
1268 }
1269
1270
1271@@ -1880,7 +1602,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1272 hitInfoRTC );
1273
1274 if( hitted )
1275- cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, 0 ) );
1276+ cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, 0, false ) );
1277 }
1278
1279
1280@@ -1908,7 +1630,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1281 hitInfoLBC );
1282
1283 if( hitted )
1284- cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, 0 ) );
1285+ cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, 0, false ) );
1286 }
1287
1288
1289@@ -1936,7 +1658,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
1290 hitInfoRBC );
1291
1292 if( hitted )
1293- cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, 0 ) );
1294+ cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, 0, false ) );
1295 }
1296
1297
1298@@ -1983,7 +1705,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
1299 const RAY &aRay,
1300 HITINFO &aHitInfo,
1301 bool aIsInsideObject,
1302- unsigned int aRecursiveLevel ) const
1303+ unsigned int aRecursiveLevel,
1304+ bool is_testShadow ) const
1305 {
1306 if( aRecursiveLevel > 2 )
1307 return SFVEC3F( 0.0f );
1308@@ -2004,9 +1727,6 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
1309
1310 const LIST_LIGHT &lightList = m_lights.GetList();
1311
1312- const bool is_testShadow = m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) &&
1313- (!m_isPreview);
1314-
1315 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1316 const bool is_aa_enabled = m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
1317 (!m_isPreview);
1318@@ -2185,7 +1905,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
1319 reflectedRay,
1320 reflectedHit,
1321 false,
1322- aRecursiveLevel + 1 ) *
1323+ aRecursiveLevel + 1,
1324+ is_testShadow ) *
1325 (1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit *
1326 reflectedHit.m_tHit) ); // Falloff factor
1327 }
1328@@ -2241,7 +1962,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
1329 refractedRay,
1330 refractedHit,
1331 true,
1332- aRecursiveLevel + 1 );
1333+ aRecursiveLevel + 1,
1334+ is_testShadow );
1335
1336 const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
1337 (1.0f - objTransparency ) *
1338diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h
1339index e3493bd..085a760 100644
1340--- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h
1341+++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h
1342@@ -83,6 +83,18 @@ private:
1343 void rt_render_trace_block( GLubyte *ptrPBO , signed int iBlock );
1344 void rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion );
1345
1346+ void rt_shades_packet( const SFVEC3F *bgColorY,
1347+ const RAY *aRayPkt,
1348+ HITINFO_PACKET *aHitPacket,
1349+ bool is_testShadow,
1350+ SFVEC3F *aOutHitColor );
1351+
1352+ void rt_trace_AA_packet( const SFVEC3F *aBgColorY,
1353+ const HITINFO_PACKET *aHitPck_X0Y0,
1354+ const HITINFO_PACKET *aHitPck_AA_X1Y1,
1355+ const RAY *aRayPck,
1356+ SFVEC3F *aOutHitColor );
1357+
1358 // Materials
1359 void setupMaterials();
1360
1361@@ -109,7 +121,8 @@ private:
1362 const RAY &aRay,
1363 HITINFO &aHitInfo,
1364 bool aIsInsideObject,
1365- unsigned int aRecursiveLevel ) const;
1366+ unsigned int aRecursiveLevel,
1367+ bool is_testShadow ) const;
1368
1369 /// State used on quality render
1370 RT_RENDER_STATE m_rt_render_state;
1371diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp
1372index cf7f66e..bc8d14d 100644
1373--- a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp
1374+++ b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp
1375@@ -32,6 +32,16 @@
1376 #include <wx/debug.h>
1377
1378
1379+static void RAYPACKET_GenerateFrustum( CFRUSTUM *m_Frustum, RAY *m_ray )
1380+{
1381+ m_Frustum->GenerateFrustum(
1382+ m_ray[ 0 * RAYPACKET_DIM + 0 ],
1383+ m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
1384+ m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
1385+ m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
1386+}
1387+
1388+
1389 RAYPACKET::RAYPACKET( const CCAMERA &aCamera, const SFVEC2I &aWindowsPosition )
1390 {
1391 unsigned int i = 0;
1392@@ -55,12 +65,29 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera, const SFVEC2I &aWindowsPosition )
1393
1394 wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
1395
1396- m_Frustum.GenerateFrustum(
1397- m_ray[ 0 * RAYPACKET_DIM + 0 ],
1398- m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
1399- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
1400- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
1401+ RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
1402+}
1403
1404+
1405+RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
1406+ const SFVEC2F &aWindowsPosition )
1407+{
1408+ RAYPACKET_InitRays( aCamera, aWindowsPosition, m_ray );
1409+
1410+ RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
1411+}
1412+
1413+
1414+RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
1415+ const SFVEC2F &aWindowsPosition,
1416+ const SFVEC2F &a2DWindowsPosDisplacementFactor )
1417+{
1418+ RAYPACKET_InitRays_with2DDisplacement( aCamera,
1419+ aWindowsPosition,
1420+ a2DWindowsPosDisplacementFactor,
1421+ m_ray );
1422+
1423+ RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
1424 }
1425
1426
1427@@ -91,11 +118,7 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
1428
1429 wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
1430
1431- m_Frustum.GenerateFrustum( m_ray[ 0 * RAYPACKET_DIM + 0 ],
1432- m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
1433- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
1434- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
1435-
1436+ RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
1437 }
1438
1439
1440@@ -124,8 +147,49 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
1441
1442 wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
1443
1444- m_Frustum.GenerateFrustum( m_ray[ 0 * RAYPACKET_DIM + 0 ],
1445- m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
1446- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
1447- m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
1448+ RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
1449+}
1450+
1451+
1452+void RAYPACKET_InitRays( const CCAMERA &aCamera,
1453+ const SFVEC2F &aWindowsPosition,
1454+ RAY *aRayPck )
1455+{
1456+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
1457+ {
1458+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
1459+ {
1460+ SFVEC3F rayOrigin;
1461+ SFVEC3F rayDir;
1462+
1463+ aCamera.MakeRay( SFVEC2F( aWindowsPosition.x + (float)x,
1464+ aWindowsPosition.y + (float)y ),
1465+ rayOrigin, rayDir );
1466+
1467+ aRayPck[i].Init( rayOrigin, rayDir );
1468+ }
1469+ }
1470+}
1471+
1472+void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera,
1473+ const SFVEC2F &aWindowsPosition,
1474+ const SFVEC2F &a2DWindowsPosDisplacementFactor,
1475+ RAY *aRayPck )
1476+{
1477+ for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
1478+ {
1479+ for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
1480+ {
1481+ SFVEC3F rayOrigin;
1482+ SFVEC3F rayDir;
1483+
1484+ aCamera.MakeRay( SFVEC2F( aWindowsPosition.x +(float)x +
1485+ Fast_RandFloat() * a2DWindowsPosDisplacementFactor.x,
1486+ aWindowsPosition.y + (float)y +
1487+ Fast_RandFloat() * a2DWindowsPosDisplacementFactor.y ),
1488+ rayOrigin, rayDir );
1489+
1490+ aRayPck[i].Init( rayOrigin, rayDir );
1491+ }
1492+ }
1493 }
1494diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.h b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.h
1495index 410a76a..70fa5ff 100644
1496--- a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.h
1497+++ b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.h
1498@@ -55,7 +55,22 @@ struct RAYPACKET
1499 RAYPACKET( const CCAMERA &aCamera,
1500 const SFVEC2I &aWindowsPosition,
1501 unsigned int aPixelMultiple );
1502+
1503+ RAYPACKET( const CCAMERA &aCamera,
1504+ const SFVEC2F &aWindowsPosition );
1505+
1506+ RAYPACKET( const CCAMERA &aCamera,
1507+ const SFVEC2F &aWindowsPosition,
1508+ const SFVEC2F &a2DWindowsPosDisplacementFactor );
1509 };
1510
1511+void RAYPACKET_InitRays( const CCAMERA &aCamera,
1512+ const SFVEC2F &aWindowsPosition,
1513+ RAY *aRayPck );
1514+
1515+void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera,
1516+ const SFVEC2F &aWindowsPosition,
1517+ const SFVEC2F &a2DWindowsPosDisplacementFactor,
1518+ RAY *aRayPck );
1519
1520 #endif // _RAYPACKET_H_
1521diff --git a/3d-viewer/3d_rendering/ccamera.cpp b/3d-viewer/3d_rendering/ccamera.cpp
1522index 3124757..55ed918 100644
1523--- a/3d-viewer/3d_rendering/ccamera.cpp
1524+++ b/3d-viewer/3d_rendering/ccamera.cpp
1525@@ -197,32 +197,36 @@ void CCAMERA::rebuildProjection()
1526 break;
1527 }
1528
1529- m_scr_nX.resize( m_windowSize.x );
1530- m_scr_nY.resize( m_windowSize.y );
1531-
1532- // Precalc X values for camera -> ray generation
1533- for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
1534+ if ( (m_windowSize.x > 0) &&
1535+ (m_windowSize.y > 0) )
1536 {
1537- // Converts 0.0 .. 1.0
1538- const float xNormalizedDeviceCoordinates = ( ( (float)x + 0.5f ) /
1539- (m_windowSize.x - 0.0f) );
1540+ m_scr_nX.resize( m_windowSize.x + 1 );
1541+ m_scr_nY.resize( m_windowSize.y + 1 );
1542
1543- // Converts -1.0 .. 1.0
1544- m_scr_nX[x] = 2.0f * xNormalizedDeviceCoordinates - 1.0f;
1545- }
1546+ // Precalc X values for camera -> ray generation
1547+ for( unsigned int x = 0; x < (unsigned int)m_windowSize.x + 1; ++x )
1548+ {
1549+ // Converts 0.0 .. 1.0
1550+ const float xNormalizedDeviceCoordinates = ( ( (float)x + 0.5f ) /
1551+ (m_windowSize.x - 0.0f) );
1552
1553- // Precalc Y values for camera -> ray generation
1554- for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
1555- {
1556- // Converts 0.0 .. 1.0
1557- const float yNormalizedDeviceCoordinates = ( ( (float)y + 0.5f ) /
1558- (m_windowSize.y - 0.0f) );
1559+ // Converts -1.0 .. 1.0
1560+ m_scr_nX[x] = 2.0f * xNormalizedDeviceCoordinates - 1.0f;
1561+ }
1562
1563- // Converts -1.0 .. 1.0
1564- m_scr_nY[y] = 2.0f * yNormalizedDeviceCoordinates - 1.0f;
1565- }
1566+ // Precalc Y values for camera -> ray generation
1567+ for( unsigned int y = 0; y < (unsigned int)m_windowSize.y + 1 ; ++y )
1568+ {
1569+ // Converts 0.0 .. 1.0
1570+ const float yNormalizedDeviceCoordinates = ( ( (float)y + 0.5f ) /
1571+ (m_windowSize.y - 0.0f) );
1572
1573- updateFrustum();
1574+ // Converts -1.0 .. 1.0
1575+ m_scr_nY[y] = 2.0f * yNormalizedDeviceCoordinates - 1.0f;
1576+ }
1577+
1578+ updateFrustum();
1579+ }
1580 }
1581
1582
1583@@ -264,21 +268,25 @@ void CCAMERA::updateFrustum()
1584 m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
1585 m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;
1586
1587- // Reserve size for precalc values
1588- m_right_nX.resize( m_windowSize.x );
1589- m_up_nY.resize( m_windowSize.y );
1590+ if ( (m_windowSize.x > 0) &&
1591+ (m_windowSize.y > 0) )
1592+ {
1593+ // Reserve size for precalc values
1594+ m_right_nX.resize( m_windowSize.x + 1 );
1595+ m_up_nY.resize( m_windowSize.y + 1 );
1596
1597- // Precalc X values for camera -> ray generation
1598- const SFVEC3F right_nw = m_right * m_frustum.nw;
1599+ // Precalc X values for camera -> ray generation
1600+ const SFVEC3F right_nw = m_right * m_frustum.nw;
1601
1602- for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
1603- m_right_nX[x] = right_nw * m_scr_nX[x];
1604+ for( unsigned int x = 0; x < ((unsigned int)m_windowSize.x + 1); ++x )
1605+ m_right_nX[x] = right_nw * m_scr_nX[x];
1606
1607- // Precalc Y values for camera -> ray generation
1608- const SFVEC3F up_nh = m_up * m_frustum.nh;
1609+ // Precalc Y values for camera -> ray generation
1610+ const SFVEC3F up_nh = m_up * m_frustum.nh;
1611
1612- for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
1613- m_up_nY[y] = up_nh * m_scr_nY[y];
1614+ for( unsigned int y = 0; y < ((unsigned int)m_windowSize.y + 1); ++y )
1615+ m_up_nY[y] = up_nh * m_scr_nY[y];
1616+ }
1617 }
1618
1619
1620@@ -286,22 +294,53 @@ void CCAMERA::MakeRay( const SFVEC2I &aWindowPos,
1621 SFVEC3F &aOutOrigin,
1622 SFVEC3F &aOutDirection ) const
1623 {
1624- //const SFVEC2I minWindowsPos = glm::min( aWindowPos, m_windowSize );
1625 wxASSERT( aWindowPos.x < m_windowSize.x );
1626 wxASSERT( aWindowPos.y < m_windowSize.y );
1627- const SFVEC2I &minWindowsPos = aWindowPos;
1628+
1629+ const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] +
1630+ m_right_nX[aWindowPos.x];
1631+
1632+ switch( m_projectionType )
1633+ {
1634+ default:
1635+ case PROJECTION_PERSPECTIVE:
1636+ aOutOrigin = up_plus_right + m_frustum.nc;
1637+ aOutDirection = glm::normalize( aOutOrigin - m_pos );
1638+ break;
1639+
1640+ case PROJECTION_ORTHO:
1641+ aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
1642+ aOutDirection = -m_dir;
1643+ break;
1644+ }
1645+}
1646+
1647+
1648+void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const
1649+{
1650+ wxASSERT( aWindowPos.x < (float)m_windowSize.x );
1651+ wxASSERT( aWindowPos.y < (float)m_windowSize.y );
1652+
1653+ const SFVEC2F floorWinPos_f = glm::floor( aWindowPos );
1654+ const SFVEC2I floorWinPos_i = (SFVEC2I)floorWinPos_f;
1655+ const SFVEC2F relativeWinPos = aWindowPos - floorWinPos_f;
1656+
1657+ // Note: size of vectors m_up and m_right are m_windowSize + 1
1658+ const SFVEC3F up_plus_right = m_up_nY[floorWinPos_i.y] * (1.0f - relativeWinPos.y) +
1659+ m_up_nY[floorWinPos_i.y + 1] * relativeWinPos.y +
1660+ m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
1661+ m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
1662
1663 switch( m_projectionType )
1664 {
1665 default:
1666 case PROJECTION_PERSPECTIVE:
1667- aOutOrigin = m_up_nY[minWindowsPos.y] + m_right_nX[minWindowsPos.x] + m_frustum.nc;
1668+ aOutOrigin = up_plus_right + m_frustum.nc;
1669 aOutDirection = glm::normalize( aOutOrigin - m_pos );
1670 break;
1671
1672 case PROJECTION_ORTHO:
1673- aOutOrigin = (m_up_nY[minWindowsPos.y] + m_right_nX[minWindowsPos.x]) * 0.5f +
1674- m_frustum.nc;
1675+ aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
1676 aOutDirection = -m_dir;
1677 break;
1678 }
1679diff --git a/3d-viewer/3d_rendering/ccamera.h b/3d-viewer/3d_rendering/ccamera.h
1680index 363fcbd..aa8c2d5 100644
1681--- a/3d-viewer/3d_rendering/ccamera.h
1682+++ b/3d-viewer/3d_rendering/ccamera.h
1683@@ -227,6 +227,14 @@ class CCAMERA
1684 void MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
1685
1686 /**
1687+ * @brief MakeRay - Make a ray based on a windows screen position, it will interpolate based on the float aWindowPos
1688+ * @param aWindowPos: the windows buffer position (float value)
1689+ * @param aOutOrigin: out origin position of the ray
1690+ * @param aOutDirection: out direction
1691+ */
1692+ void MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
1693+
1694+ /**
1695 * @brief MakeRayAtCurrrentMousePosition - Make a ray based on the latest mouse position
1696 * @param aOutOrigin: out origin position of the ray
1697 * @param aOutDirection: out direction

Subscribers

People subscribed via source and target branches

to status/vote changes: