SceneKit fast lighting and radiation texture effect

I am developing a solar system application. I am trying to turn off the texture of radiation, where light hits the surface of the planet. But the problem is that the default radiation texture always shows the emission points regardless of the absence or presence of light.

My request in a nutshell: (I want to hide the emission points, in places where light hits the surface) enter image description here

override func viewDidLoad() {
    super.viewDidLoad()

    let scene = SCNScene()

    let earth = SCNSphere(radius: 1)
    let earthNode = SCNNode()
    let earthMaterial = SCNMaterial()
    earthMaterial.diffuse.contents = UIImage(named: "earth.jpg")
    earthMaterial.emission.contents = UIImage(named: "earthEmission.jpg")
    earth.materials = [earthMaterial]
    earthNode.geometry = earth
    scene.rootNode.addChildNode(earthNode)

    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light?.type = .omni
    lightNode.position = SCNVector3(x: 0, y: 10, z: 5)
    scene.rootNode.addChildNode(lightNode)

    sceneView.scene = scene


}
+4
source share
1 answer

SceneKit shader modifiers are ideal for this kind of task.

You can see the frames of the final result here .

Fragment Shader Modifier

visual representation of _lightingContribution.diffuse and the final result of the shader modifier

_lightingContribution.diffuse (RGB (vec3), , ), ( - ), , .

, , . , ( GLSL, Metal , )

uniform sampler2D emissionTexture;

vec3 light = _lightingContribution.diffuse;
float lum = max(0.0, 1 - (0.2126*light.r + 0.7152*light.g + 0.0722*light.b)); // 1
vec4 emission = texture2D(emissionTexture, _surface.diffuseTexcoord) * lum; // 2, 3
_output.color += emission; // 4
  • ( ) _lightingContribution.diffuse ( )
  • , " "
  • UV- ( , )
  • ( , )

, Swift.


emission.contents , SCNMaterialProperty

let emissionTexture = UIImage(named: "earthEmission.jpg")!
let emission = SCNMaterialProperty(contents: emissionTexture)

, setValue(_:forKey:)

earthMaterial.setValue(emission, forKey: "emissionTexture")

- , . , setValue .

, , :

let shaderModifier =
"""
uniform sampler2D emissionTexture;

vec3 light = _lightingContribution.diffuse;
float lum = max(0.0, 1 - (0.2126*light.r + 0.7152*light.g + 0.0722*light.b));
vec4 emission = texture2D(emissionTexture, _surface.diffuseTexcoord) * lum;
_output.color += emission;
"""
earthMaterial.shaderModifiers = [.fragment: shaderModifier]

footage .

, , "". lightNode.light?.intensity 2000 , , . , , .


, , _lightingContribution - , , ambient specular ( Metal):

struct SCNShaderLightingContribution {
    float3 ambient;
    float3 diffuse;
    float3 specular;
} _lightingContribution;
+4

Source: https://habr.com/ru/post/1690745/


All Articles