{"__v":0,"_id":"58f7a4c9cbd001190056cc37","category":{"version":"58f7a4c8cbd001190056cbf8","project":"578c4badbd223d2000cc1441","_id":"58f7a4c8cbd001190056cbfc","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-07-18T21:08:45.730Z","from_sync":false,"order":3,"slug":"develop","title":"Develop"},"parentDoc":null,"project":"578c4badbd223d2000cc1441","user":"578c4a62bd223d2000cc143e","version":{"__v":1,"_id":"58f7a4c8cbd001190056cbf8","project":"578c4badbd223d2000cc1441","createdAt":"2017-04-19T17:56:24.172Z","releaseDate":"2017-04-19T17:56:24.172Z","categories":["58f7a4c8cbd001190056cbf9","58f7a4c8cbd001190056cbfa","58f7a4c8cbd001190056cbfb","58f7a4c8cbd001190056cbfc","58f7a4c8cbd001190056cbfd","58f7a4c8cbd001190056cbfe"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.1.0","version":"1.1.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-07-18T19:33:45.498Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":8,"body":"You illuminate scenes in Viro by adding lights to your ```<ViroNode>``` objects. For example, in the scene below, a grey spotlight and a blue ambient light illuminate a 3D object.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroScene>\\n  <ViroOrbitCamera position={[0, 0, -0]} focalPoint={[0, 0, -1.15]} />\\n  <ViroSpotLight position={[0, -0.25, 0]}\\n                 color=\\\"#777777\\\"\\n                 direction={[0, 0, -1]}\\n                 attenuationStartDistance={5}\\n                 attenuationEndDistance={10}\\n                 innerAngle={5}\\n                 outerAngle={20}/>\\n\\n  <ViroAmbientLight color=\\\"#FF0000\\\" />\\n\\n  <Viro3DObject source={require('./res/heart.obj')}\\n                position={[-0.0, -5.5, -1.15]}\\n                materials={[\\\"heart\\\"]} />\\n</ViroScene>\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe impact of a light's illumination on a component is determined by two things: the light's properties, and the component's materials. This guide covers both [lights](#light-types) and [materials](#materials). \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Constant Lighting\"\n}\n[/block]\nFor basic scenes with only UI elements and a background (```<Viro360Image>``` or ```<ViroSkybox>```), lights can effectively be ignored. By default, all elements use *Constant* lighting. Components with Constant lighting ignore the lights in the scene altogether; they are displayed in full color.\n\nTo apply lighting, one or more [lights](#light-types) must be added to the scene, *and* the [lighting models](#lighting-models) of the components you want to respond to light must be set. The next few sections go into more detail.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Materials\"\n}\n[/block]\nFor more advanced scenes, we use lights and materials to control the illumination of objects.\n\nMaterials are the set of shading attributes that define the appearance of a geometry's surface when rendered. Each object in a scene can be assigned one or more materials. All UI elements, and most basic 3D models, utilize only one material. Complex 3D objects, represented by ```<Viro3DObject>```, can have multiple materials, one for each defined mesh surface in the 3D object.\n\nMaterials are assigned via the object's ```materials``` property. The following is a simple example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<Viro3DObject source={require('./res/heart.obj')}\\n                      position={[-0.0, -5.5, -1.15]}\\n                      materials={[\\\"heart\\\"]} />\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe material itself is then defined as follows:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ViroMaterials.createMaterials({\\n  heart: {\\n     lightingModel: \\\"Blinn\\\",\\n     diffuseTexture: require('./res/Heart_D3.jpg'),\\n     specularTexture: require('./res/Heart_S2.jpg'),\\n   },\\n});\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThe following material properties determine how a material is rendered in light:\n\n* ```diffuseTexture``` and ```diffuseColor```: describe the color of light reflected equally in all directions from the material’s surface. The diffuse property of a pixel is independent of the point of view, so it can be thought of as a material’s “base” color or texture. The diffuse property be set as a texture (via ```diffuseTexture```), and/or as a uniform color (via ```diffuseColor```). If both are set, the two will be multiplied together at each pixel.\n\n* ```specularTexture```: describes the color of light reflected by the material directly toward the viewer. The specular color forms a bright highlight on the surface, simulating a glossy or shiny appearance. \n\n* ```shininess```: describes the sharpness of specular highlights. Ranges from 0 to 1.\n\n* ```lightingModel```: defines how material properties and the lights in the scene are combined to create the color for each pixel on the material's surface. Set to one of ```Constant```, ```Lambert```, ```Phong```, or ```Blinn```. See the next section for details.\n\n* ```normalTexture```: defines the orientation of the surface at each point for use in lighting. Viro treats the R, G, and B components of each pixel in the normal map as the X, Y, and Z components of a surface normal vector. Normal maps are often used to simulate rough surfaces or to add details to otherwise smooth surfaces.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Lighting Models\"\n}\n[/block]\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/678338b-viro_lighting_models.jpg\",\n        \"viro_lighting_models.jpg\",\n        754,\n        201,\n        \"#93086f\"\n      ]\n    }\n  ]\n}\n[/block]\nViro supports four traditional lighting models: ```Constant```, ```Lambert```, ```Phong```, or ```Blinn```. Each of these lighting models defines a formula for combining a material’s diffuse and specular properties with the lights in the scene and the point of view, to create the color of each rendered pixel.\n\nIn the examples below, ```diffuseMaterial``` refers to either the material's ```diffuseTexture``` or ```diffuseColor```, whichever is defined. If both are defined it refers to the material's ```diffuseTexture``` multiplied by its ```diffuseColor```.\n\n## Constant\n\nThe ```diffuseMaterial``` wholly determines the color of the surface. Lights are ignored.\n\n```color = diffuseMaterial```\n\n## Lambert\n\nLambert’s Law of diffuse reflectance determines the color of the surface. The formula is as follows:\n\n```color = (∑ambientLight + ∑diffuseLight) * diffuseMaterial```\n\n```∑ambientLight```: the sum of all ambient lights in the scene, as contributed by ```ViroAmbientLight``` objects\n\n```∑diffuseLight```: the sum of each non-ambient light's diffuse contribution. Each light's contribution is defined as follows\n\n```diffuseLight = max(0, dot(N, L))```\n\nwhere N is the surface normal vector at the point being shaded, and L is the normalized vector from the point being shaded to the light source.\n\n## Phong\n\nThe Phong approximation of real-world reflectance adds a specular contribution to the calculation:\n\n```color = (∑ambientLight + ∑diffuseLight) * diffuseMaterial + ∑specularLight * specularTexture```\n\n```∑specularLight```: the sum of each non-ambient light's specular contribution. Each light's specular contribution is defined as follows\n\n```specularLight = pow(max(0, dot(R, E)), shininess)```\n\nwhere E is the normalized vector from the point being shaded to the viewer, R is the reflection of the light vector L across the normal vector N, and shininess is the value of the material's shininess property.\n\n## Blinn\n\nThe Blinn-Phong approximation of real-world reflectance is similar to Phong, but uses a different formula for the specular contribution\n\n```specularLight = pow(max(0, dot(H, N)), shininess)```\n\nwhere H is the vector halfway between the light vector L and the eye vector E, and shininess is the value of the material's shininess property.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Light Types\"\n}\n[/block]\nThe lighting models above determine how a set of lights impact a surface. The influence of a given light is also determined by the properties of the lights *themselves.* Light properties determine things like the directionality of the light, the color of the light, and how the light impacts objects over a distance. Viro supports four light types.\n\n# Ambient Light\n```<ViroAmbientLight>``` illuminates all objects in the view (and its subviews) with equal intensity from all directions. Only the ```color``` of am ambient light needs to be set.\n\n# Directional Light\n```<ViroDirectionalLight>``` represents a light source with uniform direction and constant intensity. The sun is a canonical example of a directional light. Directional lights have a ```color``` property and a ```direction``` property.\n\n# Omni Light\n```<ViroOmniLight>``` is a light source that casts light in all directions from a given position. Omni lights have a ```color``` property and a ```position``` property. Additionally, the illumination of an omni light can attenuate over distance. This attenuation is controlled by the ```attenuationStartDistance``` and ```attenuationEndDistance``` properties.\n\n# Spot Light\n```<ViroSpotLight>``` is a light source that illuminates a cone-shaped area determined by its ```position``` and ```direction```. The color of the spot light is determined by its ```color``` property. The edges of the cone are controlled by ```innerAngle```, the angle at which the cone begins to fade, and ```outerAngle```, the angle at which the cone has faded completely. Additionally, spot lights, like omni lights, can also attenuate with distance. This is controlled via the ```attenuationStartDistance``` and ```attenuationEndDistance``` properties.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Light Cascading\"\n}\n[/block]\nLights cascade down a scene: each light illuminates not only the objects in its view, but also the objects in its view's subviews. In the example below, the ```ViroSpotlight``` illuminates both 3D objects, while the ```ViroOmniLight``` illuminates only the second 3D object.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<ViroScene>\\n  <ViroSpotLight position={[0, -0.25, 0]}\\n                 color=\\\"#777777\\\"\\n                 direction={[0, 0, -1]}\\n                 attenuationStartDistance={5}\\n                 attenuationEndDistance={10}\\n                 innerAngle={5}\\n                 outerAngle={20}/>\\n \\n  <Viro3DObject source={require('./res/heart.obj')}\\n                position={[-0.0, -5.5, -1.15]}\\n                materials={[\\\"heart\\\"]} />\\n                \\n  <ViroNode>\\n    <ViroOmniLight color=\\\"#FF0000\\\"\\n                   position={[0, 0, 0]}\\n                   attenuationStartDistance={5}\\n                   attenuationEndDistance={10} /> \\n       \\n    <Viro3DObject source={require('./res/brain.obj')}\\n                  position={[-0.0, 0, -1.15]}\\n                  materials={[\\\"brain\\\"]} />\\n  </ViroNode>\\n</ViroScene>\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]","excerpt":"Illuminating Scenes","slug":"3d-scene-lighting","type":"basic","title":"Lighting and Materials"}

Lighting and Materials

Illuminating Scenes

You illuminate scenes in Viro by adding lights to your ```<ViroNode>``` objects. For example, in the scene below, a grey spotlight and a blue ambient light illuminate a 3D object. [block:code] { "codes": [ { "code": "<ViroScene>\n <ViroOrbitCamera position={[0, 0, -0]} focalPoint={[0, 0, -1.15]} />\n <ViroSpotLight position={[0, -0.25, 0]}\n color=\"#777777\"\n direction={[0, 0, -1]}\n attenuationStartDistance={5}\n attenuationEndDistance={10}\n innerAngle={5}\n outerAngle={20}/>\n\n <ViroAmbientLight color=\"#FF0000\" />\n\n <Viro3DObject source={require('./res/heart.obj')}\n position={[-0.0, -5.5, -1.15]}\n materials={[\"heart\"]} />\n</ViroScene>", "language": "javascript" } ] } [/block] The impact of a light's illumination on a component is determined by two things: the light's properties, and the component's materials. This guide covers both [lights](#light-types) and [materials](#materials). [block:api-header] { "type": "basic", "title": "Constant Lighting" } [/block] For basic scenes with only UI elements and a background (```<Viro360Image>``` or ```<ViroSkybox>```), lights can effectively be ignored. By default, all elements use *Constant* lighting. Components with Constant lighting ignore the lights in the scene altogether; they are displayed in full color. To apply lighting, one or more [lights](#light-types) must be added to the scene, *and* the [lighting models](#lighting-models) of the components you want to respond to light must be set. The next few sections go into more detail. [block:api-header] { "type": "basic", "title": "Materials" } [/block] For more advanced scenes, we use lights and materials to control the illumination of objects. Materials are the set of shading attributes that define the appearance of a geometry's surface when rendered. Each object in a scene can be assigned one or more materials. All UI elements, and most basic 3D models, utilize only one material. Complex 3D objects, represented by ```<Viro3DObject>```, can have multiple materials, one for each defined mesh surface in the 3D object. Materials are assigned via the object's ```materials``` property. The following is a simple example: [block:code] { "codes": [ { "code": "<Viro3DObject source={require('./res/heart.obj')}\n position={[-0.0, -5.5, -1.15]}\n materials={[\"heart\"]} />", "language": "javascript" } ] } [/block] The material itself is then defined as follows: [block:code] { "codes": [ { "code": "ViroMaterials.createMaterials({\n heart: {\n lightingModel: \"Blinn\",\n diffuseTexture: require('./res/Heart_D3.jpg'),\n specularTexture: require('./res/Heart_S2.jpg'),\n },\n});", "language": "javascript" } ] } [/block] The following material properties determine how a material is rendered in light: * ```diffuseTexture``` and ```diffuseColor```: describe the color of light reflected equally in all directions from the material’s surface. The diffuse property of a pixel is independent of the point of view, so it can be thought of as a material’s “base” color or texture. The diffuse property be set as a texture (via ```diffuseTexture```), and/or as a uniform color (via ```diffuseColor```). If both are set, the two will be multiplied together at each pixel. * ```specularTexture```: describes the color of light reflected by the material directly toward the viewer. The specular color forms a bright highlight on the surface, simulating a glossy or shiny appearance. * ```shininess```: describes the sharpness of specular highlights. Ranges from 0 to 1. * ```lightingModel```: defines how material properties and the lights in the scene are combined to create the color for each pixel on the material's surface. Set to one of ```Constant```, ```Lambert```, ```Phong```, or ```Blinn```. See the next section for details. * ```normalTexture```: defines the orientation of the surface at each point for use in lighting. Viro treats the R, G, and B components of each pixel in the normal map as the X, Y, and Z components of a surface normal vector. Normal maps are often used to simulate rough surfaces or to add details to otherwise smooth surfaces. [block:api-header] { "type": "basic", "title": "Lighting Models" } [/block] [block:image] { "images": [ { "image": [ "https://files.readme.io/678338b-viro_lighting_models.jpg", "viro_lighting_models.jpg", 754, 201, "#93086f" ] } ] } [/block] Viro supports four traditional lighting models: ```Constant```, ```Lambert```, ```Phong```, or ```Blinn```. Each of these lighting models defines a formula for combining a material’s diffuse and specular properties with the lights in the scene and the point of view, to create the color of each rendered pixel. In the examples below, ```diffuseMaterial``` refers to either the material's ```diffuseTexture``` or ```diffuseColor```, whichever is defined. If both are defined it refers to the material's ```diffuseTexture``` multiplied by its ```diffuseColor```. ## Constant The ```diffuseMaterial``` wholly determines the color of the surface. Lights are ignored. ```color = diffuseMaterial``` ## Lambert Lambert’s Law of diffuse reflectance determines the color of the surface. The formula is as follows: ```color = (∑ambientLight + ∑diffuseLight) * diffuseMaterial``` ```∑ambientLight```: the sum of all ambient lights in the scene, as contributed by ```ViroAmbientLight``` objects ```∑diffuseLight```: the sum of each non-ambient light's diffuse contribution. Each light's contribution is defined as follows ```diffuseLight = max(0, dot(N, L))``` where N is the surface normal vector at the point being shaded, and L is the normalized vector from the point being shaded to the light source. ## Phong The Phong approximation of real-world reflectance adds a specular contribution to the calculation: ```color = (∑ambientLight + ∑diffuseLight) * diffuseMaterial + ∑specularLight * specularTexture``` ```∑specularLight```: the sum of each non-ambient light's specular contribution. Each light's specular contribution is defined as follows ```specularLight = pow(max(0, dot(R, E)), shininess)``` where E is the normalized vector from the point being shaded to the viewer, R is the reflection of the light vector L across the normal vector N, and shininess is the value of the material's shininess property. ## Blinn The Blinn-Phong approximation of real-world reflectance is similar to Phong, but uses a different formula for the specular contribution ```specularLight = pow(max(0, dot(H, N)), shininess)``` where H is the vector halfway between the light vector L and the eye vector E, and shininess is the value of the material's shininess property. [block:api-header] { "type": "basic", "title": "Light Types" } [/block] The lighting models above determine how a set of lights impact a surface. The influence of a given light is also determined by the properties of the lights *themselves.* Light properties determine things like the directionality of the light, the color of the light, and how the light impacts objects over a distance. Viro supports four light types. # Ambient Light ```<ViroAmbientLight>``` illuminates all objects in the view (and its subviews) with equal intensity from all directions. Only the ```color``` of am ambient light needs to be set. # Directional Light ```<ViroDirectionalLight>``` represents a light source with uniform direction and constant intensity. The sun is a canonical example of a directional light. Directional lights have a ```color``` property and a ```direction``` property. # Omni Light ```<ViroOmniLight>``` is a light source that casts light in all directions from a given position. Omni lights have a ```color``` property and a ```position``` property. Additionally, the illumination of an omni light can attenuate over distance. This attenuation is controlled by the ```attenuationStartDistance``` and ```attenuationEndDistance``` properties. # Spot Light ```<ViroSpotLight>``` is a light source that illuminates a cone-shaped area determined by its ```position``` and ```direction```. The color of the spot light is determined by its ```color``` property. The edges of the cone are controlled by ```innerAngle```, the angle at which the cone begins to fade, and ```outerAngle```, the angle at which the cone has faded completely. Additionally, spot lights, like omni lights, can also attenuate with distance. This is controlled via the ```attenuationStartDistance``` and ```attenuationEndDistance``` properties. [block:api-header] { "type": "basic", "title": "Light Cascading" } [/block] Lights cascade down a scene: each light illuminates not only the objects in its view, but also the objects in its view's subviews. In the example below, the ```ViroSpotlight``` illuminates both 3D objects, while the ```ViroOmniLight``` illuminates only the second 3D object. [block:code] { "codes": [ { "code": "<ViroScene>\n <ViroSpotLight position={[0, -0.25, 0]}\n color=\"#777777\"\n direction={[0, 0, -1]}\n attenuationStartDistance={5}\n attenuationEndDistance={10}\n innerAngle={5}\n outerAngle={20}/>\n \n <Viro3DObject source={require('./res/heart.obj')}\n position={[-0.0, -5.5, -1.15]}\n materials={[\"heart\"]} />\n \n <ViroNode>\n <ViroOmniLight color=\"#FF0000\"\n position={[0, 0, 0]}\n attenuationStartDistance={5}\n attenuationEndDistance={10} /> \n \n <Viro3DObject source={require('./res/brain.obj')}\n position={[-0.0, 0, -1.15]}\n materials={[\"brain\"]} />\n </ViroNode>\n</ViroScene>", "language": "javascript" } ] } [/block]