Add fake quad lighting (multisampling)
This commit is contained in:
		
							parent
							
								
									fdc84a0d81
								
							
						
					
					
						commit
						ba31c21b0d
					
				|  | @ -10,6 +10,7 @@ public class Light | ||||||
|     public float InnerRadius; |     public float InnerRadius; | ||||||
|     public float Radius; |     public float Radius; | ||||||
|     public float R2; |     public float R2; | ||||||
|  |     public bool QuadLit; | ||||||
| 
 | 
 | ||||||
|     public bool Spotlight; |     public bool Spotlight; | ||||||
|     public Vector3 SpotlightDir; |     public Vector3 SpotlightDir; | ||||||
|  |  | ||||||
|  | @ -232,6 +232,11 @@ class Program | ||||||
| 
 | 
 | ||||||
|         if (propLight != null) |         if (propLight != null) | ||||||
|         { |         { | ||||||
|  |             if (propLight.QuadLit) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Quadlit light wowzer"); | ||||||
|  |             } | ||||||
|  |              | ||||||
|             var light = new Light |             var light = new Light | ||||||
|             { |             { | ||||||
|                 Position = baseLight.Position + propLight.Offset, |                 Position = baseLight.Position + propLight.Offset, | ||||||
|  | @ -239,6 +244,7 @@ class Program | ||||||
|                 InnerRadius = propLight.InnerRadius, |                 InnerRadius = propLight.InnerRadius, | ||||||
|                 Radius = propLight.Radius, |                 Radius = propLight.Radius, | ||||||
|                 R2 = propLight.Radius * propLight.Radius, |                 R2 = propLight.Radius * propLight.Radius, | ||||||
|  |                 QuadLit = propLight.QuadLit, | ||||||
|                 Spotlight = baseLight.Spotlight, |                 Spotlight = baseLight.Spotlight, | ||||||
|                 SpotlightDir = baseLight.SpotlightDir, |                 SpotlightDir = baseLight.SpotlightDir, | ||||||
|                 SpotlightInnerAngle = baseLight.SpotlightInnerAngle, |                 SpotlightInnerAngle = baseLight.SpotlightInnerAngle, | ||||||
|  | @ -267,6 +273,7 @@ class Program | ||||||
|                 InnerRadius = propAnimLight.InnerRadius, |                 InnerRadius = propAnimLight.InnerRadius, | ||||||
|                 Radius = propAnimLight.Radius, |                 Radius = propAnimLight.Radius, | ||||||
|                 R2 = propAnimLight.Radius * propAnimLight.Radius, |                 R2 = propAnimLight.Radius * propAnimLight.Radius, | ||||||
|  |                 QuadLit = propAnimLight.QuadLit, | ||||||
|                 Spotlight = baseLight.Spotlight, |                 Spotlight = baseLight.Spotlight, | ||||||
|                 SpotlightDir = baseLight.SpotlightDir, |                 SpotlightDir = baseLight.SpotlightDir, | ||||||
|                 SpotlightInnerAngle = baseLight.SpotlightInnerAngle, |                 SpotlightInnerAngle = baseLight.SpotlightInnerAngle, | ||||||
|  | @ -449,44 +456,26 @@ class Program | ||||||
|                             var pos = topLeft; |                             var pos = topLeft; | ||||||
|                             pos += x * 0.25f * renderPoly.TextureVectors.Item1; |                             pos += x * 0.25f * renderPoly.TextureVectors.Item1; | ||||||
|                             pos += y * 0.25f * renderPoly.TextureVectors.Item2; |                             pos += y * 0.25f * renderPoly.TextureVectors.Item2; | ||||||
|                              | 
 | ||||||
|                             // Embree has robustness issues when hitting poly edges which |                             var hit = false; | ||||||
|                             // results in false misses. To alleviate this we pre-push everything |                             var strength = 0f; | ||||||
|                             // slightly towards the center of the poly. | 
 | ||||||
|                             var centerOffset = renderPoly.Center - pos; |                             // TODO: THIS IS ACTUALLY MULTISAMPLING NOT QUAD LIGHTING | ||||||
|                             if (centerOffset.LengthSquared() > MathUtils.Epsilon) |                             if (light.QuadLit) | ||||||
|                             { |                             { | ||||||
|                                 pos += Vector3.Normalize(centerOffset) * MathUtils.Epsilon; |                                 var xOffset = 0.25f * 0.25f * renderPoly.TextureVectors.Item1; | ||||||
|  |                                 var yOffset = 0.25f * 0.25f * renderPoly.TextureVectors.Item2; | ||||||
|  |                                 hit |= TracePixel(scene, light, pos - xOffset - yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength); | ||||||
|  |                                 hit |= TracePixel(scene, light, pos + xOffset - yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength); | ||||||
|  |                                 hit |= TracePixel(scene, light, pos - xOffset + yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength); | ||||||
|  |                                 hit |= TracePixel(scene, light, pos + xOffset + yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength); | ||||||
|  |                                 strength /= 4f; | ||||||
|  |                             } | ||||||
|  |                             else | ||||||
|  |                             { | ||||||
|  |                                 hit |= TracePixel(scene, light, pos, renderPoly.Center, plane, planeMapper, v2ds, ref strength); | ||||||
|                             } |                             } | ||||||
|                              |                              | ||||||
|                             // If we can't see our target point from the center of the poly |  | ||||||
|                             // then it's outside the world. We need to clip the point to slightly |  | ||||||
|                             // inside the poly and retrace to avoid three problems: |  | ||||||
|                             // 1. Darkened spots from lightmap pixels whose center is outside |  | ||||||
|                             //    the polygon but is partially contained in the polygon |  | ||||||
|                             // 2. Darkened spots from linear filtering of points outside the |  | ||||||
|                             //    polygon which have missed |  | ||||||
|                             // 3. Darkened spots where centers are on the exact edge of a poly |  | ||||||
|                             //    which can sometimes cause Embree to miss casts |  | ||||||
|                             var inPoly = TraceRay(scene, renderPoly.Center + plane.Normal * 0.25f, pos); |  | ||||||
|                             if (!inPoly) |  | ||||||
|                             { |  | ||||||
|                                 var p2d = planeMapper.MapTo2d(pos); |  | ||||||
|                                 p2d = MathUtils.ClipPointToPoly2d(p2d, v2ds); |  | ||||||
|                                 pos = planeMapper.MapTo3d(p2d); |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             // If we're out of range there's no point casting a ray |  | ||||||
|                             // There's probably a better way to discard the entire lightmap |  | ||||||
|                             // if we're massively out of range |  | ||||||
|                             if ((pos - light.Position).LengthSquared() > light.R2) |  | ||||||
|                             { |  | ||||||
|                                 continue; |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             // We cast from the light to the pixel because the light has |  | ||||||
|                             // no mesh in the scene to hit |  | ||||||
|                             var hit = TraceRay(scene, light.Position, pos); |  | ||||||
|                             if (hit) |                             if (hit) | ||||||
|                             { |                             { | ||||||
|                                 // If we're an anim light there's a lot of stuff we need to update |                                 // If we're an anim light there's a lot of stuff we need to update | ||||||
|  | @ -506,7 +495,6 @@ class Program | ||||||
|                                     info.AnimLightBitmask |= 1u << paletteIdx; |                                     info.AnimLightBitmask |= 1u << paletteIdx; | ||||||
|                                     layer = paletteIdx + 1; |                                     layer = paletteIdx + 1; | ||||||
|                                 } |                                 } | ||||||
|                                 var strength = light.StrengthAtPoint(pos, plane); |  | ||||||
|                                 lightmap.AddLight(layer, x, y, light.Color, strength, hdr); |                                 lightmap.AddLight(layer, x, y, light.Color, strength, hdr); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  | @ -517,6 +505,60 @@ class Program | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     private static bool TracePixel( | ||||||
|  |         Raytracer scene, | ||||||
|  |         Light light, | ||||||
|  |         Vector3 pos, | ||||||
|  |         Vector3 polyCenter, | ||||||
|  |         Plane plane, | ||||||
|  |         MathUtils.PlanePointMapper planeMapper, | ||||||
|  |         Vector2[] v2ds, | ||||||
|  |         ref float strength) | ||||||
|  |     { | ||||||
|  |         // Embree has robustness issues when hitting poly edges which | ||||||
|  |         // results in false misses. To alleviate this we pre-push everything | ||||||
|  |         // slightly towards the center of the poly. | ||||||
|  |         var centerOffset = polyCenter - pos; | ||||||
|  |         if (centerOffset.LengthSquared() > MathUtils.Epsilon) | ||||||
|  |         { | ||||||
|  |             pos += Vector3.Normalize(centerOffset) * MathUtils.Epsilon; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // If we can't see our target point from the center of the poly | ||||||
|  |         // then it's outside the world. We need to clip the point to slightly | ||||||
|  |         // inside the poly and retrace to avoid three problems: | ||||||
|  |         // 1. Darkened spots from lightmap pixels whose center is outside | ||||||
|  |         //    the polygon but is partially contained in the polygon | ||||||
|  |         // 2. Darkened spots from linear filtering of points outside the | ||||||
|  |         //    polygon which have missed | ||||||
|  |         // 3. Darkened spots where centers are on the exact edge of a poly | ||||||
|  |         //    which can sometimes cause Embree to miss casts | ||||||
|  |         var inPoly = TraceRay(scene, polyCenter + plane.Normal * 0.25f, pos); | ||||||
|  |         if (!inPoly) | ||||||
|  |         { | ||||||
|  |             var p2d = planeMapper.MapTo2d(pos); | ||||||
|  |             p2d = MathUtils.ClipPointToPoly2d(p2d, v2ds); | ||||||
|  |             pos = planeMapper.MapTo3d(p2d); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // If we're out of range there's no point casting a ray | ||||||
|  |         // There's probably a better way to discard the entire lightmap | ||||||
|  |         // if we're massively out of range | ||||||
|  |         if ((pos - light.Position).LengthSquared() > light.R2) | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // We cast from the light to the pixel because the light has | ||||||
|  |         // no mesh in the scene to hit | ||||||
|  |         var hit = TraceRay(scene, light.Position, pos); | ||||||
|  |         if (hit) | ||||||
|  |         { | ||||||
|  |             strength += light.StrengthAtPoint(pos, plane); | ||||||
|  |         } | ||||||
|  |         return hit; | ||||||
|  |     } | ||||||
|      |      | ||||||
|     private static bool TraceRay(Raytracer scene, Vector3 origin, Vector3 target) |     private static bool TraceRay(Raytracer scene, Vector3 origin, Vector3 target) | ||||||
|     { |     { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue