Make SceneKit light only cast shadows without lighting the scene - scenekit

I'm using physically based lighting to light my scene in ARKit, however, I also want to add shadows to make it more realistic. I tried adding a directional light and setting the intensity as low as possible but I still am not able to reach my desired effect. I basically want a light to only cast shadows and have no effect on the lighting in the scene.
Is there any way I can achieve this effect?

You should use correct SCNShadowMode property.
From the apple's documentation:
Each shadow mode may have a positive or negative effect on rendering performance, depending on the contents of the scene. Test your app to determine which shadow mode provides the best balance between performance and quality for the scenes you want to render.
case forward:
SceneKit renders shadows during lighting computations.
case deferred:
SceneKit renders shadows in a post-processing pass.
case modulated:
SceneKit renders shadows by projecting the light’s gobo image. The light does not illuminate the scene.
So your desired option is should be modulated.
I hope it helped!
P.S. If this answer is useful to you, don't forget to press up arrow and mark it as a correct. Best of luck!
Update.
Lights source:
Directional:
- Intensity - 1000.
- Mode - dynamic.
- Color #000000 (rgb(0, 0, 0)).
- Shadow Mode: modulated.

Related

Scenekit - add red tint to camera

Is it possible to add a red tint to a given camera in SceneKit? I would like to accomplish this without the (what I consider to be) hacky solution of just trying to shove a red object with < 1 opacity in front of the camera. That could be a solution but I haven't had great success in SceneKit showing an object right in front of the camera.
Also, ideally, I could fade the red tint in and out using SCNAction or some other way.
Finally, a perfect solution would work in ARKit, and give a red tint to the whole world around you. So it would have to be something more than a red scenekit light.
SCNCamera's colorGrading property can do that (that would be the most efficient option).
Using a SCNTechnique to apply a custom post process would work too but it requires an additional pass.
Both options would be faster than a blended node in front of the camera, or a red-ish spritekit overlay or a UIView on top of the SCNView.
Instead of adding a red-tinted SCNNode into the scene, you could just add a tinted UIView in front of the ARSCNView in the storyboard. With an outlet to that view fading it in and out would be easy.

How to change color of dark spots in SceneKit?

How to change color of the area where light doesn't reach?
By default it's black, so how can I make it white for example? I couldn't find it, if its duplicate, please let me know how to form my question in order to find correct answer!
Thank you in advance
The "color of the are where light doesn't reach" demonstrates your problem, you have no light influencing your scene at this point. In any space/place where light doesn't reach, there is no colour, only blackness.
Here are the common ways of addressing 3D lighting:
1. Add more lights to places that create your ideal lighting
This is an artistic process, time consuming and arduous to get "just so". But it gets the best effects and the best atmosphere, generally speaking.
or...
2. Use an ambient light in your scene to light everything
When starting out, in 3D, there's so much to master that simply throwing in an ambient light and getting on with other work towards your goal is probably a good workflow. Work on artistic light last, use ambient lighting until then: https://developer.apple.com/reference/scenekit/scnlight.lighttype/1522769-ambient
Caveat:
Ambient lights will likely solve your problem of the dark edges, but will also wash out a lot of your existing shadows.
SCNLight has a property for changing the color of shadows. Here's a link to the page for more info. If you have any other questions, let me know, hopefully this helps.
SCNLight.shadowColor Link
You can also set the shading mode to Constant if you don't want a node to be affected by shading (making it therefore dark):

Shadow not being cast with ThreeJS in react-three-renderer

I'm having trouble casting a shadow in my scene. Steps I've taken:
shadowMapEnabled attribute added to the React3 element
the directional light in my scene has verbatim the properties I see here in the react-three-renderer example
all three meshes (one cube and two planes) in the scene have castShadow and receiveShadow
I have a black cube in the image below to show where the directional light is eminating from.
Here's a gist of my code. (abbreviated)
Try reducing the shadow camera's near value, it looks too high. If you can provide a full example it may be easier to diagnose what's happening
Additionally try to place a different object at the "lookAt" target for the light, this should help identify in which direction it will face

What projection matrix does SceneKit use for directional light shadows?

I'm trying to prevent shadow swimming when moving the directional light around to cover only the visible part of my scene. Despite rounding the translation components in light space, they swimming artifacts are still there.
I even tried pointing the light directly down (with a scale of 2 and shadow map size of 32) and translated the directional light along the world x-axis by -1 and +1. The shadows still changed. I can only assume they aren't using normal orthographic projection. The shadows seem to move more when near the edge too.
Has anyone had luck preventing shadow swimming in SceneKit, or knows what projection matrix is being used for the directional light shadows?

Zoom in and out of a scene?

What is the correct way to zoom in and out of a scene in SceneKit?
So when I enable the standard camera control in a scene and pinch in and out the scene gets bigger and smaller. What is that pinch really doing?
Is it changing the scale of the whole scene? Is it moving the camera closer?
I want to implement the same effect but programmatically.
What should I do to obtain the same effect?
When you pinch it's the field of view (xFox and yFov properties) of your camera that's changed. Changing the field of view is not the best way to zoom because it can dramatically change the perspective.
Moving the camera closer to your object is a good solution.
Also note that the "free camera" behavior is suitable for 3D viewers (such as Preview.app) but will rapidly become frustrating in any other app. At this point you might want to implement your own camera controller.
At any given point the camera has a position in space, it has a rotation for each of its own axis compared to each of the world axis, to have a zoom in and zoom out, you have to move the camera in the +z/-z axis direction.
Along the Cameras own Z/-Z axis.
For those on OSX, I used this in my SCNView subclass:
override func scrollWheel(theEvent: NSEvent) {
let cam = pointOfView!.camera
cam!.xFov = cam!.xFov - Double(theEvent.deltaY)
cam!.yFov = cam!.yFov - Double(theEvent.deltaY)
}
There are two (minor) problems that could be addressed with a little extra code. One is that the values can go negative, at which point the image is flipped inside-out. The other is that mouse acceleration can cause the zoom level to go too fast if you really spin the wheel. Limits on both of these would be a good idea, but in my app the behaviour was fine as it is above.

Resources