Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[RELEASED] Super Fast Soft Shadows

Discussion in 'Works In Progress - Archive' started by Andy-Korth, Jun 5, 2015.

  1. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @ShadowrunnerEmin Unfortunately no. The lighting system in Unity is not extendable. When you render sprites with normal maps, Unity renders a pass for each light and adds them together. It doesn't have a way to change how the lights work (like using a custom shadow map), and only provides a few hard coded options. There is no way to add new types of lights, or new kinds of shadows to it.

    Because of that SFSS lighting implementation is completely separate, and you can't use both on the same sprite. Since we can't extend Unity's multi-pass lighting, we have to pre-calculate all of the lighting for the scene in a single pass. That means means you can't use normal maps since they change how a surface is lit based on the location of each individual light and object.

    You could mix and match though. Use Unity's multi-pass lighting on your foreground sprites, and SFSS on your backgrounds and atmospheric effects. The sprites wouldn't be able to receive shadows, and the backgrounds wouldn't be able to have normal maps though. You'd also have to add both Unity and SFSS lights to your objects.
     
  2. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    I have bought the Asset and played with him a bit, it works great on PC, but I can't see same effect on my mobiles, neigher Galaxy S3 mini (Android 4.1.2), nor Onda V975m (Android 4.3). Are these devices too old to run GPU lighting/shadows effects? This is how it looks at PC (how it should be):
    E20160508-151033[1].png

    This is how it looks on my androids (how it shouldn't be):

    Screenshot_2016-05-08-15-20-38.png

    I feel like I am doing something wrong. Could you help me please?
     
  3. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Hard to say. It works fine on the half dozen Android devices we have. I think the oldest one we have is 4 years old. Since it looks like the shadow masking is the only part not working, first check the log. Are there any warnings from Unity about a shader failing to load? Next thing to try might be updating Unity if you are on an older version.

    According to Google, both of those devices have Mali GPUs. In the past, the GL ES drivers for those were notoriously buggy. The shadow mask shader might be failing to compile due to driver bugs, or since it's mildly long it might be hitting hardware limits. Unfortunately with GL ES there isn't a way to know if a shader is too long without loading it and seeing if the driver throws an error. Unity probably prints something to the log if that happens.
     
  4. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    Thank you!
    Do you know any ready-to-run software (apk or from Google Play) using your asset which I can install on my android devices and test if the reason in my devices or Unity configuration in my software?
     
  5. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    Hi, slembcke2

    Here is my application log (made by adb logcat). App called "Sliders". I cut out the piece which is from my app start till my app exit.

    The most interesting lines is 833, 859, 865 I guess, but unfortunately I can't understand most of these letters.

    I've tried to find anything about "bad shaders", but found nothing. In opposite, I see some success messages like

    D/Unity ( 8809): PlayerInitEngineNoGraphics OK
    D/Unity ( 8809): GfxDevice: creating device client; threaded=1
    D/Unity ( 8809): [EGL] Request: ES 2.0 RGB16 565 0/0
    D/Unity ( 8809): [EGL] Found: ID[29] ES 2.0 RGB16 565 0/0
    D/Unity ( 8809): ANativeWindow: (800/480) RequestedResolution: (0/0) EGLSurface: (800/480)
    D/Unity ( 8809): Renderer: Mali-400 MP
    D/Unity ( 8809): Vendor: ARM
    D/Unity ( 8809): Version: OpenGL ES 2.0
    D/Unity ( 8809): GLES: 2
    D/Unity ( 8809): GL_EXT_debug_marker GL_OES_texture_npot GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_depth24 GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth_texture GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 GL_EXT_blend_minmax GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_rgb8_rgba8 GL_EXT_multisampled_render_to_texture GL_EXT_discard_framebuffer GL_OES_get_program_binary GL_ARM_mali_program_binary GL_EXT_shader_texture_lod GL_EXT_robustness
    D/Unity ( 8809): ETC2 0
    D/Unity ( 8809): OPENGL LOG: Creating OpenGL ES 2.0 graphics device
    D/Unity ( 8809): InitializeGfxDevice OK
    D/Unity ( 8809): Initialize engine version: 5.3.4f1 (fdbb5133b820)
    ....

    May you take a look at log file please? May we assume your asset's shaders were loaded and ran successfully?
    Thank you again.

    P.S. I am using Unity 5.3.4f1 btw.
     

    Attached Files:

    Last edited: May 9, 2016
  6. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    I don't see any shader errors in the log, though it doesn't necessarily mean that it loaded correctly.

    Do you see shadows in this demo? (tilt to fly, touch to aim the flashlight)
    http://files.slembcke.net/temp/SSFS.apk
     
  7. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    Works very good on both my androids (with shadows)!

    I gonna compile and try your Cave Demo from downloaded version of asset.

    Do you think it can be a reason of another asset version or wrong Unity3d configuration?

    ---UPDATE---

    Cave Scene not work properly from my project. I gonna create new clean project and compile from there.

    ---UPDATE 2---

    Works fine at android with clean installation of asset.
     
    Last edited: May 9, 2016
  8. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    I've compiled your asset with empty new project. It works fine.

    So the reason is my own project configuration, I guess.

    Would you recommend best config to make this asset works on android?

    I will try to set up the same config values from clean project to my main project.
     
  9. Epsiloncool

    Epsiloncool

    Joined:
    Mar 30, 2016
    Posts:
    16
    Thanks, I finally got a reason.


    Here is a screenshot of my Resolution and Presentation. Shown checkbox SHOULD BE "ON". If I check it off, I see wrong image (as above).

    E20160510-020519[1].png

    Here is my other setting page, just to refer. Someone may need for them. The SSFS asset working fine with them.

    E20160510-020757[1].png

    Just want to thank you for help and for great product!

    Thanks!
     
  10. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Oh interesting... I use an RGBA render texture to store the lightmap, and the alpha is where the shadow mask is stored. Apparently if you don't have that checked, Unity will give you a render texture without alpha even if you tell it you need one.
     
  11. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi!

    I am back and I have some great news. I was able to completely rewrite how the lighting works in my game and now it uses SFSS to do all its lighting even when the game is XZ plane based. I have separated lighting into XY plane and tried to keep the SFSS's work pipleline intact.

    I only have one small issue, where when light's radius is not 0, (say 0.1) the light sometimes "leakes" on the corner of the shadow polygon. It happens from time to time and it is only noticeable because I use it to clear fog of war on my game.

    It's hard to explain , but it only happens with radius greater than 0 and only on around corner (say a corner of a room and the light is inside the room) The collider on the corner of the room is good.

    Is this known issue? (perhaps with DX11 issue you have mentioned above?)
     
  12. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Not really sure what you mean. Can you post a screenshot?
     
  13. wjone52

    wjone52

    Joined:
    May 4, 2016
    Posts:
    4
    It seems there is no culling mask for the actual lighting effect. Am I missing something, or is this a limitation of the technique used? I need light A to only affect object A, and light B to only affect object B. Perhaps there is another way to accomplish this?
     
  14. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    I'm curious if it'd be feasible to use this asset to create background scene lighting for a 2D platformer style game.

    What I'm trying to achieve is something along the lines of what the Alto's Adventure guys did. (see this thread: http://forum.unity3d.com/threads/2d-day-night-cycle-and-weather-system-a-la-altos-adventure.377959/)

    Do you think SFSS could be used to achieve something like that or would I be better off doing a custom solution like described in the thread?

    Side question: Do these lights/shadows only work with sprites or can they also be used with Mesh Renderers? (A quad Mesh for example)

    -Jeff
     
  15. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @wjone52 Correct. Unfortunately we have to precompute all of the lighting sort of like how deferred rendering works. Unity's forward renderer is not extendable, nor can we implement our own forward renderer on top of theirs. That means that we only get a single pass to render all of the lighting onto the objects. It's all or nothing.

    As a bit of a hack though, you could set up multiple cameras and shadow renderers though. You'll have to render things in layers though.

    @jeffweber You could, but it's probably a little overkill. Their solution is going to be pretty easy to implement, and if that's the specific effect you want, then it's probably the best way to get it. Also, you can use meshes with SFSS, but since it's strictly a 2D (xy) effect, it doesn't work with perspective cameras.
     
  16. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    I will post about the light leaking soon.

    But I am also wondering about the GC allocation it produces. In my case, I have many tiles that makes up the walls (lots of sfpolys) so my GC for the rendering of light is at 1.8k - 2.5k each frame.

    I know in your previous post that I can pass the null to avoid the allocation, but that is probably out of question because of the performance issue.

    Do you think there is way to get rid of allocation somehow? Even if that means I will have to allocate a big enough buffer in the beginning.
     
  17. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Where is the memory allocation coming from according to the profiler? SFSS reuses arrays when possible, but because of how Unity's mesh API works, you can't reuse an array when the vertex count changes. That happens whenever a poly moves into or out of a visible light source. There is no way to avoid this if it's what is causing the allocations. It should be pretty rare though. Only a small percentage of frames should be need allocations unless you have very fast moving lights or polys. These are arrays of value types, and should be very gentle on the collector and cheap to initialize.

    We also allocate 1 closure per light, per frame, but they are tiny. (~100 bytes or something like that?)

    I know Unity developers are supposed to be mildly terrified of the GC, but I wouldn't really worry about it if it's not an issue. Creating lots of tiny bits of garbage is bad for the CPU cache, and constantly reinitializing complicated objects is expensive, but this is doing neither. If we pooled these temporary arrays it would only serve to inflate the overall memory usage.
     
    Last edited: May 11, 2016
  18. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    The GC is indeed coming from _GetShadowMesh , AllocateArray .

    I have a light source that is moving with the character (ie flash light) and every time I look around or move around it allocates around 98-100k GC per frame. Performance of building shadowmesh themselves are fine, but GC is kicking in with vengeance! And I guess at aroun 2k GC when I am not moving or looking around at all is coming from the 100 bytes per light.
     
  19. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Good news!

    I was able to create a flexible way of resizing the buffer array so that it only increases if it has hit new upper limit. This isn't optimal as far as the memory usage goes, but it is still much better than having 100k GC being created all the time, at least in my case. The static lights will almost be as optimal as it can get as before, but it was really important for the big moving light such as flash light to be able to create as less GC as possible.

    Now, I just need to figure out where that basic 1.8k GC is coming from. Can you let me know where the 100bytes per light GC is allocated at?
     
  20. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    How did you change the mesh generation code? Unity's mesh API requires you to have arrays that are exactly the right size. I don't see how you can leave empty space in the array.

    The only other allocation is from calling SFRenderer.CullObjects with a delegate. (Do a search, it's only called a few times) It can be fixed by copy pasting and specializing some code, but I'd be surprised if it really affected the overall performance.
     
  21. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    The empty spaces are filled by zeros. And it seems to work. This is actually "recommended" way of modifying the mesh at runtime frequently. I looked around for posts and found some and the guy from Unity has recommended to fill the rest of the buffers with zeros. Now I get no GC at least from the mesh generation! I will see what I can do about the delegate call!

    Normally, the 1.8k GC isn't too bad on today's PC but.. for lower end android consoles, and others it can add up causing slight stutter during game play.
     
  22. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Yeap I think I did it.. now only at 64b. I think I can call this good enough, I mean optimization is good, but only do it for the bottlenecks right? Thanks for helping me out to the right direction. I also hope for those of you who potentially have the same issue as mine where you are willing to trade off some performance and memory usage for almost gc free method, I can tell you that it is possible with this asset!
     
  23. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Hmm. I guess I had considered degenerate triangles, though somewhat rejected it since the vertex shader is fairly complicated. I assumed it would get too expensive if most vertexes submitted were degerenate.

    Thinking about it again, your solution with some tweaks is probably better though. Instead of caching an array per light, I could make a pool of scratch buffers that increase in size by a small power (say 25%). That would keep the degenerate vertex overhead low, and the total allocated array space would only be ~4x the space required by the largest light. If you have many lights in a scene, this could considerably lower total allocations. I could probably also avoid caching a mesh per light since they are drawn using Graphics.DrawMeshNow(). Even more memory savings.

    The closure allocation for CullObjects could be avoided by moving the culling into SFLight._GetShadowMesh() without needing to copy paste anything around...

    Bah. I'm still not 100% convinced that it will make much of a performance impact, but I can't not improve something once I'm sure there is a better way to do it. -_-
     
  24. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    i am not sure about the others but for me i found that having 100k gc per frame was just not going to work. stutter from gc collection happened too often for an acceptable experience. but then again my game has shadow casting walls made up by many tile pieces and the main character had field of view vision and a large flash lights causing around 1500 to 2000 segments rebuild per frame. it still renders and draw them fast but just gc was problem. if you think there would be more usage cases like that and there could be improvements then by all means right?
     
  25. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Hmm. I guess that is making more sense the more I think about it. Either way, I implemented the changes I outlined above. There are now zero dynamic allocations. There is a single shared mesh for all shadowmasks, and all lights share a pool of vertex arrays to avoid duplication and avoid too many degenerate vertexes. I'll send you a PM with the changes if you want to help test them.

    Seems to work well, though I haven't tried it on all (5?) of Unity's renderers yet.
     
  26. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Sure! I will be glad to test it out for you!
     
  27. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Ok, after adapting the improved version, it seems to work! I am not sure how much more efficient than my personal attempt but I guess you would know better! So I trust yours to work better than my modification. There are only 64b GC now, but I am fine with it.

    It took me while and put a lots of efforts converting my previous lighting solution to SFSS but at the end, I think it was worth it. Performance is around 2x faster than before on desktop alone, but I am sure it runs much better for android consoles and others.

    There is one thing I added to the existing SFSS ploygon class. There could be multiple 2dPolygon collider attached to the game object for various reasons, so in that case , I modified the code to iterate through colliders to generate more SFPolygon components.
     
  28. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Yeah... When rewriting the mesh building code I saw a comment I had left in there about planning to add multiple polys per SFPolygon component. I guess we never followed through on that. Maybe I'll add that before releasing the allocation improvements. It should be pretty easy.
     
  29. TheLordDave

    TheLordDave

    Joined:
    Mar 2, 2014
    Posts:
    28
    I have a system setup where I generate meshes for a 2d terrain. top down.
    Currently I am using several shaders for elements of the Terrain. Could i use your system without replacing my shaders?
    Applying your shaders to another mesh/plane layer overlaid over the existing geometry and sprites?
    This is how i currently do my lighting but its getting expensive on a per vertex basis. I would like to replace it.
     
  30. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @TheLordDave SFSS calculates a screen space lightmap each frame. That's the complicated part. To render a sprite with the lighting applied, it just has to read from the lightmap texture and multiply against the regular color. It should be pretty easy to modify your existing shaders to do that. We could send you the shader if you'd like to take a look at it.
     
  31. TheLordDave

    TheLordDave

    Joined:
    Mar 2, 2014
    Posts:
    28
    Hi, I bought the asset and am integrating it.

    Just wondered if there is a way to limit the distance of shadows?

    I am setting up a scene where a sun light orbits the camera. Due to this all objects in the view generate shadows..

    I want a way to limit the extrusion of the shadow mesh. In order to simulate height in a 2d topdown game.

    so 'taller' objects can be extruded further than 'shorter' objects

    I presume it is in the _GetShadowMesh function but i am struggling to work out where the extrusion distance is calculated.

    Thanks
    Dave
     
  32. TheLordDave

    TheLordDave

    Joined:
    Mar 2, 2014
    Posts:
    28
    Also I am trying to integrate this into my shaderforge shader with no luck. The I have tried to replicate your shader but i think the matrix multiplication is the part causing me issues.

    what are the basic steps to read from the lightmap?

    I either need to be able to blend multiple textures via R,G,B color values and use the alpha to control opacity. While blending the lightmap into the determined pixel color.

    or

    I need to create an additive shader to sit on a plane above the terrain, that renders the light map.

    Both of which I am guessing would need to do some fancy shader matrix multiplication to account for the lightmap texture not mapping 1:1 with my verticies.
     
  33. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @TheLordDave

    Limiting shadow distance:
    Maybe. I talked with somebody a couple days ago that wanted some custom changes to SFSS for their game. One of which was sun shadows:
    sun-shadows.mp4

    I might try tackling more generic directional light sources in a future version, but for now I can at least give you a few pointers. Almost all of the shadow work is done in the SFShadowMask shader. The C# code is really only responsible for batching, culling, etc. The way the projection distance works is really subtle. Look for the line where "float4 projected" is defined. The w coordinate of that vector controls the projection distance. (1 -> no projection, 0 -> project to infinity) The current implementation only outputs 0 or 1, but if you multiplied the " IN.occluderCoord.y" value by something between 0 and 1 then you could control the projection distance. One problem with this is that it causes the penumbra interpolation to be incorrect, and I don't know why yet. So you'll have to settle for hard shadows. The other tricks are to multiply the opacity by "1 - IN.occluderCoord.y" so it fades out to the end of the shadow, and to flip your shadow polygons inside out.

    I'm not convinced this could be made generic enough to make everybody that would want such an effect happy though. Like I said, I might try adding this in a future version, but I wouldn't make plans based on that.

    Custom Shaders:
    SFSoftShadow is the shader you apply to sprites, meshes, or whatever you want to be lit by SFSS. A lot of the code in it is fluff to make it more generic and have different sampling options. Really all you need to do is turn the projected coordinates for the screen (which have the range [-1, 1]), to be texture coordinates (with the range [0, 1]). That's what the " 0.5*(shadowCoord + shadowCoord.w)" bit does. Where "shadowCoord" should just be the vertex output position. Then in the fragment shader use those texture coordinates to read from one or both of the lightmaps ( _SFLightMap, _SFLightMapWithShadows). I've never used ShaderForge, so I have no idea how to advise you exactly. The vertex shader part sounds hard with GUI programming... The fragment shader part should be easy though. It's just a regular, simple texture lookup with a UV coordinate.
     
  34. feoktistov

    feoktistov

    Joined:
    Feb 12, 2015
    Posts:
    5
    Hi! I have issue with flipping SFLight (using negative scale or Y rotation). SFLight ignore SFPolygons after flipping.
    negative_scale_issue.png
     
  35. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Oh, hrm. I hadn't thought of that. I think it might be easy to test if a transform is flipped just from the sign of the determinant. I'll check into it.
     
  36. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @feoktistov: A workaround for the short term is to reverse the SFPolygon vertex order when you flip the object. If it's done at edit time, there is an editor button to make that easy. If it's done at runtime, you can call SFPolygon._FlipInsideOut(). You will need to track when the polygon gets flipped yourself though.
     
  37. _eternal

    _eternal

    Joined:
    Nov 25, 2014
    Posts:
    302
    I noticed something odd when positioning one of my lights. When I drag the transform vertically, it moves normally, but when I try to drag it horizontally, the motion is choppy. Here's an example: https://gfycat.com/RedExhaustedInchworm

    I tried rotating it 90 degrees, and that made the vertical movement choppy rather than the horizontal. Any idea what's causing this? Even though the transform is static in my game, it looks like it's moving unevenly when the camera pans across it.
     
  38. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    That's due to the resolution of the lightmap. I think the default is to render at a fraction of the screen resolution. (SFRenderer's lightmap scale and shadow map scale properties) The snapping you are seeing is the size of the lightmap pixels. Higher numbers mean larger lightmap pixels, but better performance. Desktop machines can probably handle a scale of 1 without problems, but mobile devices generally don't have the power to push that many extra pixels.

    You can set the scales to 1 and get pixel perfect shadow rendering, but it will use more GPU resources. The better alternative is to soften that hard edge on your light's cookie instead. The aliasing (snapping) effect will go away, and you won't have the hard edge in your light.
     
    _eternal likes this.
  39. feoktistov

    feoktistov

    Joined:
    Feb 12, 2015
    Posts:
    5
    Thank you for suggestion! Workaround will work when only one light is used but if there are two lights (one normal and one flipped) you can't apply workaround.
     
  40. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Oooh. The light is flipped? I also didn't think of that... Makes sense since the polygons are transformed into light space. Bah!

    Edit: Bah. You did say light, though my mind immediately went to flipping the polygons. Reading derp.
     
    Last edited: May 25, 2016
  41. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    @feoktistov The fix wasn't quite as simple as I'd thought. It wasn't just the polygon windings that were the problem after all. I'll send you a build with the fixes shortly so you can test it.
     
  42. _eternal

    _eternal

    Joined:
    Nov 25, 2014
    Posts:
    302
    Just to confirm, I suppose there's no way to apply fog to a small part of the scene?

    The laser beam that I posted just above was created through this plugin's fog system, but thinking about it now, that might have been a bit of a hack. Turning scatterColor up to the max means that I can't use other SF Lights to light background objects without having them light the fog as well.

    Is there a way to achieve the look of that laser beam without using fog in the SF Renderer? Or do you know of another approach entirely? I'm still a bit confused by the difference between lighting an object (i.e. making it look like it an unlit sprite with Color(1, 1, 1)) and creating a big beam of light that gives off its own glow, independent of the light's original sprite. I have yet to find the right way to do the latter.
     
  43. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    It's the same reason you can't make a laser beam effect very well with Unity's lighting system. You get point lights and directional lights (like the sun), but no "beam" lights. Even if it did, Unity still doesn't include very complicated atmospheric lighting effects does it?

    In SFSS, you have different limitations. You still don't have a "beam" light type, but now the lighting is strictly 2D too. In a 3D scene, your laser beam can pass by a surface without intersecting it and only light up the fog. In SFSS, if a light overlaps a sprite, then it lights it up.

    An easy and effective way to draw laser beams is to use a Physics raycast to see how far to draw the beam, and then use a line renderer with an additive blending mode. If your beam is really wide (hard to tell in your video if you are zoomed in or not), you *could* borrow some of the code out of SFRenderer to draw shadow masks for it straight into the regular framebuffer. You'd have to be fairly familiar with writing graphics code for Unity though.
     
  44. _eternal

    _eternal

    Joined:
    Nov 25, 2014
    Posts:
    302
    Thanks for the explanation. It's starting to make more sense to me now. I stumbled onto the line renderer + additive blending solution the other day, and I think I can make that work.
     
  45. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi Slembcke2.

    Getting back to the light leaking issue, I was just setting the Radius of the light to 0 to get rid of this issue for Windows platform, but this trick doesn't seem to work for Xboxone platform.

    Here is image of the problem.

    As you can see there is light leak on the corner.

    Now, the 2dcollider and the shadow mesh generated from it is good. They don't have leak and the corner piece has continuous closed collision for the light. The thickness of the collision is the same for the other walls (as thick as the black part of the wall piece which is very thick )

    setting radius to 0 seems to "fix" or minimize the issue enough to be not noticeable. But it is not the same case for XboxOne. I am not sure what would be different for XboxOne , but I think the under-lying issues are the same for Windows anyway. This is huge issue.. Can you look into this? I will be glad to work with you as before to fix / improve this wonderful lighting solution. thanks.

    Here is another shot taken some time after the above shot, the black area is the fogged area (not discovered) but as you can see there are dots everywhere, which is result of "light pixels ?" leaked out of the shadow collision.



    My initial guess was it happens because of precision error between the shadow collision pieces, but I am not so sure anymore. And ofcourse, the vertices along the shadow collision polygons do match exactly. ( but I guess this can't never be precise enough? ) I am not making the shadow collision manually, but generated from 2dPolygonCollider. (they seems to match up perfectly.) so I don't think it is problem of the collision themselves.

    I am not exactly sure what radius value does (softness?) on the light, but I don't need any softness from shader.. All I need is just exact non leaking version.

    My guess at the moment is that this issue was presented in the plugin all the time, but it may not been so visible because the result is so subtle and the viewing of them was not cumulatively shown as mine.

    Perhaps it is the precision inside the shader that is causing this issue? (hence difference in XboxOne version because of different shader compilation precision issue.)
     
  46. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    In your first image, the light leaking out of the corner is almost definitely caused by floating point precision. It *should* be considerably less noticeable with a non-zero light radius. With a zero light radius, the shadow is either on or off and any error shows up as light leaking. With even a fairly small radius, the error from the floating point precision should be less than the monitor it's displayed on. You are saying you've had the opposite problem, which is a little confusing.

    We've done most of our testing on OpenGL (mobile and Mac), but I don't know of any reason why the DirectX renderer for Windows or XBone would have issues. The XBone GPU might have more precision issues due to cheaper hardware though??

    As for the second image, what exactly am I looking at? Are you accumulating the light buffer over many frames to do the visibility fog? That's the only way that image makes sense to me. You shouldn't be having precision issues anywhere other than at the seams between shadows. Unless you have that many vertexes in your shadow polygons?
     
  47. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Yeah the walls are made up with tiles. And the tiles has its own shadow polygons. So the leak is probably happening on the boundaries of the tiles. The shadow polygons are made so that their vertices are matched up, but then I guess floating point error can still creep in. Funny thing is that on the corner , there is no gap. They are one continuous piece. Even when I try to modify the shadow polygon using the editor (inspector , edit shadow polygon) , they are one looping piece.

    The second image or any other image's error is seen because of accumulated light buffer over many frames.

    I will try the radius value like 0.0001 or something to see if anything improves.
     
  48. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517


    Just trying to make it clear.. The corner shadow polygons are something like this. Where there is no other tiles making it up. This is just one shadow ploygon. And the light leaks through the corners on the shadow polygons.

    Yeah , even on PC, anything radius > 0 the leak eventually is seen over time. Not sure why this isn't the case for Xbox..
     
    Last edited: Jun 2, 2016
  49. slembcke2

    slembcke2

    Joined:
    Jun 26, 2013
    Posts:
    270
    Ok, so it is accumulated, that makes much more sense then. You might be able to get rid of the speckles by changing up your blending mode. Like if it's additive, you could switch it to max instead. Then enable larger radiuses on your lights which should make it look much nicer, and avoid such a large error. Additionally, you could do a 4-tap blur and a threshold or something similar when reading from the lightmap to filter in case there are any remaining artifacts.

    If you *really* don't care about soft shadows, the shader code for basic hard shadows is massively simpler.Paste this into SFShadowMask:

    Code (csharp):
    1.  
    2.             CGPROGRAM
    3.                 #pragma target 3.0
    4.                 #pragma vertex VShader
    5.                 #pragma fragment FShader
    6.  
    7.                 struct VertexInput {
    8.                     float3 properties : POSITION;
    9.                     float4 segmentData : TANGENT;
    10.                     float2 occluderCoord : TEXCOORD0;
    11.                 };
    12.                
    13.                 struct FragmentInput {
    14.                     float4 position : SV_POSITION;
    15.                     float opacity : COLOR;
    16.                 };
    17.                
    18.                 void VShader(VertexInput IN, out FragmentInput OUT){
    19.                     float4 projected = float4(lerp(IN.segmentData.xy, IN.segmentData.zw, IN.occluderCoord.x), 0.0, 1.0 - IN.occluderCoord.y);
    20.                     OUT.position = mul(UNITY_MATRIX_MVP, projected);
    21.                     OUT.opacity = IN.properties[2];
    22.                 }
    23.                
    24.                 half4 FShader(FragmentInput IN) : SV_Target {
    25.                     return half4(0.0, 0.0, 0.0, IN.opacity);
    26.                 }
    27.             ENDCG
    28.  
    29.  
     
  50. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    i will try your shader suggestions. but why would it leak when there is no shadow polygon seams? the corner piece is just on its own so..like you said.. there should be no leak at all? for the first pic leak, it is happening on the corner piece which is not supposed to be shadow polygon seams issue. it has to be some other issue?
     
    Last edited: Jun 2, 2016