本范例主要介绍如何在AR场景中使用动态光源。使用不同的动态光源可以让您的模型看起来更逼真或更奇幻色彩。
metaio SDK提供三种类型的光源:
- 方向性光源:无衰减,但有方向
- 点光源:从一个点向所有方向发射光线,有光源位置和光线衰减
- 聚光灯:圆锥体光型,由位置、方向、外圆锥半径和衰减度来定义
除了上面提到的特性,这三种光源还能添加环境和漫反射光色。环境光总会存在,而漫反射光是根据光源和其他因素(如光方向和物体的角度)计算出来的。
由于移动平台对于着色器的支持有限,目前我们限定同时使用的最多光源数为4
实现方法
此范例使用API函数IMetaioSDK::createLight()来生成三个metaio::ILight实例,而metaio::ILight即是用户改变光源特性的接口。如前文所述,不是所有特性都适用于每个光源。例如,如果您试图对方向性光源添加衰减,系统会在日志信息中给予警告(warning log message)。
为了便于演示,我们在AR场景中使用三个小球来分别代表三个光源。其中,方向性光源并不是一个实际意义上的光源,因为它没有任何衰减且无限延伸。我们关闭光源对三个小球的作用,在实际使用中,您也可以对不需要动态光源的模型进行同样的设置。
默认情况下,光源的坐标系为COS 0—摄像头坐标系。在此范例中,我们需要光源在立方体周围飘动,并使用相对于立方体的坐标。所以,我们把光源的坐标系设置为COS 1。如果您想更多的了解metaio坐标系设置,请点击查看相关教程。- // Windows
- m_pMetaioSDK->setAmbientLight(metaio::Vector3d(0.05f));
- m_pDirectionalLight = m_pMetaioSDK->createLight();
- m_pDirectionalLight->setType(metaio::ELIGHT_TYPE_DIRECTIONAL);
- m_pDirectionalLight->setAmbientColor(metaio::Vector3d(0, 0.15f, 0)); // slightly green
- m_pDirectionalLight->setDiffuseColor(metaio::Vector3d(0.6f, 0.2f, 0)); // orange
- m_pDirectionalLight->setCoordinateSystemID(1);
- m_pDirectionalLightGeo = createLightGeometry();
- m_pDirectionalLightGeo->setCoordinateSystemID(m_pDirectionalLight->getCoordinateSystemID());
- m_pDirectionalLightGeo->setDynamicLightingEnabled(false);
- m_pPointLight = m_pMetaioSDK->createLight();
- m_pPointLight->setType(metaio::ELIGHT_TYPE_POINT);
- m_pPointLight->setAmbientColor(metaio::Vector3d(0, 0, 0.15f)); // slightly blue ambient
- m_pPointLight->setAttenuation(metaio::Vector3d(0, 0, 40));
- m_pPointLight->setDiffuseColor(metaio::Vector3d(0, 0.8f, 0.05f)); // green-ish
- m_pPointLight->setCoordinateSystemID(1);
- m_pPointLightGeo = createLightGeometry();
- m_pPointLightGeo->setCoordinateSystemID(m_pPointLight->getCoordinateSystemID());
- m_pPointLightGeo->setDynamicLightingEnabled(false);
- m_pSpotLight = m_pMetaioSDK->createLight();
- m_pSpotLight->setAmbientColor(metaio::Vector3d(0.17f, 0, 0)); // slightly red ambient
- m_pSpotLight->setType(metaio::ELIGHT_TYPE_SPOT);
- m_pSpotLight->setRadiusDegrees(10);
- m_pSpotLight->setDiffuseColor(metaio::Vector3d(1, 1, 0)); // yellow
- m_pSpotLight->setCoordinateSystemID(1);
- m_pSpotLightGeo = createLightGeometry();
- m_pSpotLightGeo->setCoordinateSystemID(m_pSpotLight->getCoordinateSystemID());
- m_pSpotLightGeo->setDynamicLightingEnabled(false);
复制代码- // Android
- metaioSDK.setAmbientLight(new Vector3d(0.05f));
-
- mDirectionalLight = metaioSDK.createLight();
- mDirectionalLight.setType(ELIGHT_TYPE.ELIGHT_TYPE_DIRECTIONAL);
- mDirectionalLight.setAmbientColor(new Vector3d(0, 0.15f, 0)); // slightly green
- mDirectionalLight.setDiffuseColor(new Vector3d(0.6f, 0.2f, 0)); // orange
- mDirectionalLight.setCoordinateSystemID(1);
- mDirectionalLightGeo = createLightGeometry();
- mDirectionalLightGeo.setCoordinateSystemID(mDirectionalLight.getCoordinateSystemID());
- mDirectionalLightGeo.setDynamicLightingEnabled(false);
-
- mPointLight = metaioSDK.createLight();
- mPointLight.setType(ELIGHT_TYPE.ELIGHT_TYPE_POINT);
- mPointLight.setAmbientColor(new Vector3d(0, 0, 0.15f)); // slightly blue ambient
- mPointLight.setAttenuation(new Vector3d(0, 0, 40));
- mPointLight.setDiffuseColor(new Vector3d(0, 0.8f, 0.05f)); // green-ish
- mPointLight.setCoordinateSystemID(1);
- mPointLightGeo = createLightGeometry();
- mPointLightGeo.setCoordinateSystemID(mPointLight.getCoordinateSystemID());
- mPointLightGeo.setDynamicLightingEnabled(false);
-
- mSpotLight = metaioSDK.createLight();
- mSpotLight.setAmbientColor(new Vector3d(0.17f, 0, 0)); // slightly red ambient
- mSpotLight.setType(ELIGHT_TYPE.ELIGHT_TYPE_SPOT);
- mSpotLight.setRadiusDegrees(10);
- mSpotLight.setDiffuseColor(new Vector3d(1, 1, 0)); // yellow
- mSpotLight.setCoordinateSystemID(1);
- mSpotLightGeo = createLightGeometry();
- mSpotLightGeo.setCoordinateSystemID(mSpotLight.getCoordinateSystemID());
- mSpotLightGeo.setDynamicLightingEnabled(false);
复制代码- // IOS
- m_metaioSDK->setAmbientLight(metaio::Vector3d(0.05f));
-
- m_pDirectionalLight = m_metaioSDK->createLight();
- m_pDirectionalLight->setType(metaio::ELIGHT_TYPE_DIRECTIONAL);
- m_pDirectionalLight->setAmbientColor(metaio::Vector3d(0, 0.15f, 0)); // slightly green
- m_pDirectionalLight->setDiffuseColor(metaio::Vector3d(0.6f, 0.2f, 0)); // orange
- m_pDirectionalLight->setCoordinateSystemID(1);
- m_pDirectionalLightGeo = [self createLightGeometry];
- m_pDirectionalLightGeo->setCoordinateSystemID(m_pDirectionalLight->getCoordinateSystemID());
- m_pDirectionalLightGeo->setDynamicLightingEnabled(false);
-
- m_pPointLight = m_metaioSDK->createLight();
- m_pPointLight->setType(metaio::ELIGHT_TYPE_POINT);
- m_pPointLight->setAmbientColor(metaio::Vector3d(0, 0, 0.15f)); // slightly blue ambient
- m_pPointLight->setAttenuation(metaio::Vector3d(0, 0, 40));
- m_pPointLight->setDiffuseColor(metaio::Vector3d(0, 0.8f, 0.05f)); // green-ish
- m_pPointLight->setCoordinateSystemID(1);
- m_pPointLightGeo = [self createLightGeometry];
- m_pPointLightGeo->setCoordinateSystemID(m_pPointLight->getCoordinateSystemID());
- m_pPointLightGeo->setDynamicLightingEnabled(false);
-
- m_pSpotLight = m_metaioSDK->createLight();
- m_pSpotLight->setAmbientColor(metaio::Vector3d(0.17f, 0, 0)); // slightly red ambient
- m_pSpotLight->setType(metaio::ELIGHT_TYPE_SPOT);
- m_pSpotLight->setRadiusDegrees(10);
- m_pSpotLight->setDiffuseColor(metaio::Vector3d(1, 1, 0)); // yellow
- m_pSpotLight->setCoordinateSystemID(1);
- m_pSpotLightGeo = [self createLightGeometry];
- m_pSpotLightGeo->setCoordinateSystemID(m_pSpotLight->getCoordinateSystemID());
- m_pSpotLightGeo->setDynamicLightingEnabled(false);
复制代码
设置光源特性
由于此功能叫做动态光源而不是静态光源,您可以在运行时刻自如地改变光的特性,其效果会在下一个渲染帧中看到。
在此范例中,我们让光源围绕着立方体旋转,从而使您清楚的看到不同光源会产生何种效果。方向性光源的颜色是棕黄色,点源是绿色的,而聚光灯是黄色的。并且,每个光源都有一小部分其他颜色的环境光。您可以根据自己的需要或兴趣自行设定这个光源的特性。
范例使用的代码会在渲染每一帧之后更新光源特性,但您也可以在其他位置使用此代码。下面的代码循环使用sin/cos函数来生成光源位置,其效果为光源围绕原点旋转,也就是围绕3D模型旋转
您可以随时使用setEnabled()来实现光源的开启与关闭。如果没有光源处于开启状态,那么所有的物体都是在光源关闭状态下渲染的。也就是说,只有物体的颜色被渲染,场景不会受光源或全局环境颜色的干扰。全局环境颜色设定可以和动态光源一起使用来添加“基本光”,这样物体就不会呈现为纯黑色。- // Windows
- // Lights circle around
- float time = timeGetTime() / 1000.0f;
- const metaio::Vector3d lightPos(200*cosf(time), 120*sinf(0.25f*time), 200*sinf(time));
- const float FREQ2MUL = 0.4f;
- const metaio::Vector3d lightPos2(150*cosf(FREQ2MUL*2.2f*time) * (1 + 2+2*sinf(FREQ2MUL*0.6f*time)), 30*sinf(FREQ2MUL*0.35f*time), 150*sinf(FREQ2MUL*2.2f*time));
- const metaio::Vector3d directionalLightDir(cosf(1.2f*time), sinf(0.25f*time), sinf(0.8f*time));
- // This will only apply in the upcoming frame:
- // Directional light
- m_pDirectionalLight->setDirection(directionalLightDir);
- updateLightIndicator(m_pDirectionalLightGeo, m_pDirectionalLight);
- // Point light
- m_pPointLight->setTranslation(lightPos);
- updateLightIndicator(m_pPointLightGeo, m_pPointLight);
- // Spot light
- m_pSpotLight->setTranslation(lightPos2);
- m_pSpotLight->setDirection(-lightPos2); // spot towards origin of COS
- updateLightIndicator(m_pSpotLightGeo, m_pSpotLight);
复制代码- // Android
- // Lights circle around
- final double time = System.currentTimeMillis() / 1000.0;
- final Vector3d lightPos = new Vector3d(
- 200.0f * (float)Math.cos(time),
- 120.0f * (float)Math.sin(0.25f*time),
- 200.0f * (float)Math.sin(time));
-
- final float FREQ2MUL = 0.4f;
- final Vector3d lightPos2 = new Vector3d(
- 150.0f * (float)(Math.cos(FREQ2MUL*2.2*time) * (1 + 2+2*Math.sin(FREQ2MUL*0.6*time))),
- 30.0f * (float)Math.sin(FREQ2MUL*0.35*time),
- 150.0f * (float)Math.sin(FREQ2MUL*2.2*time));
-
- final Vector3d directionalLightDir = new Vector3d(
- (float)Math.cos(1.2*time),
- (float)Math.sin(0.25*time),
- (float)Math.sin(0.8*time));
-
- // This will only apply in the upcoming frame:
-
- // Directional light
- mDirectionalLight.setDirection(directionalLightDir);
- updateLightIndicator(mDirectionalLightGeo, mDirectionalLight);
-
- // Point light
- mPointLight.setTranslation(lightPos);
- updateLightIndicator(mPointLightGeo, mPointLight);
-
- // Spot light
- mSpotLight.setTranslation(lightPos2);
- // Spot towards origin of COS
- mSpotLight.setDirection(new Vector3d(-lightPos2.getX(), -lightPos2.getY(), -lightPos2.getZ()));
- updateLightIndicator(mSpotLightGeo, mSpotLight);
复制代码- // IOS
- // Lights circle around
- const float time = (float)CACurrentMediaTime();
- const metaio::Vector3d lightPos(200*cosf(time), 120*sinf(0.25f*time), 200*sinf(time));
-
- const float FREQ2MUL = 0.4f;
- const metaio::Vector3d lightPos2(150*cosf(FREQ2MUL*2.2f*time) * (1 + 2+2*sinf(FREQ2MUL*0.6f*time)), 30*sinf(FREQ2MUL*0.35f*time), 150*sinf(FREQ2MUL*2.2f*time));
-
- const metaio::Vector3d directionalLightDir(cosf(1.2f*time), sinf(0.25f*time), sinf(0.8f*time));
-
-
- // This will only apply in the upcoming frame:
-
- // Directional light
- m_pDirectionalLight->setDirection(directionalLightDir);
- [self updateLightIndicator:m_pDirectionalLightGeo light:m_pDirectionalLight];
-
- // Point light
- m_pPointLight->setTranslation(lightPos);
- [self updateLightIndicator:m_pPointLightGeo light:m_pPointLight];
-
- // Spot light
- m_pSpotLight->setTranslation(lightPos2);
- m_pSpotLight->setDirection(-lightPos2); // spot towards origin of COS
- [self updateLightIndicator:m_pSpotLightGeo light:m_pSpotLight];
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|