SpotLight and Shadow
В интернете я наткнулся на неплохую 3D модель уличного фонаря и решил написать эту статью , SpotLight(Пятно света) — этот источник света я охарактеризовал так , рассеянный направленный источник света имеющий форму конуса.
Я думаю можно перейти к коду.
package test; import com.jme3.app.SimpleApplication; import com.jme3.asset.plugins.FileLocator; import com.jme3.light.AmbientLight; import com.jme3.light.PointLight; import com.jme3.light.SpotLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Vector3f; import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.scene.Geometry; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Box; import com.jme3.shadow.EdgeFilteringMode; import com.jme3.shadow.SpotLightShadowRenderer; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; public class TestSpotLightShadow extends SimpleApplication { public static void main(String[] args) { new TestSpotLightShadow().start(); } @Override public void simpleInitApp() { flyCam.setMoveSpeed(20); createScene(); createSpotShadowLight(); createAmbienLight(); createPointLight(); } //Создание сцены private void createScene(){ Material matGrass = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); matGrass.setTexture("DiffuseMap", grass); Box box1 = new Box(20, 1, 20); Geometry geomBox1 = new Geometry("box1", box1); geomBox1.setMaterial(matGrass); rootNode.attachChild(geomBox1); assetManager.registerLocator("E:/Models/StreetLight/", FileLocator.class); Spatial streetlamp = assetManager.loadModel("streetlamp.obj"); streetlamp.setLocalTranslation(0, 15, 0); rootNode.attachChild(streetlamp); Material matPond = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); matPond.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); matPond.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); matPond.setBoolean("UseMaterialColors", true); matPond.setColor("Diffuse", ColorRGBA.White.clone()); matPond.setColor("Ambient", ColorRGBA.White.clone()); matPond.setFloat("Shininess", 0); Box box2 = new Box(1, 1, 1); Geometry geomBox2 = new Geometry("box2", box2); geomBox2.setLocalTranslation(2, 5, 0); geomBox2.setMaterial(matPond); rootNode.attachChild(geomBox2); } // Создание источника света Spot Light private void createSpotShadowLight() { SpotLight spot = new SpotLight(); spot.setSpotRange(100f); // Дистанция spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD); // Начальный радиус spot.setSpotOuterAngle(50f * FastMath.DEG_TO_RAD); // Конечный радиус spot.setColor(ColorRGBA.White.mult(2.3f)); // Цвет spot.setPosition(new Vector3f(0.4f, 14.5f, 0)); // Позиция spot.setDirection(new Vector3f(0, -5, 0)); // Направление rootNode.addLight(spot); rootNode.setShadowMode(ShadowMode.CastAndReceive);// Включаем отражения SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512); slsr.setLight(spot); // Установка освещения slsr.setShadowIntensity(0.6f); // Интенсивность отражения slsr.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON);// Режим фильтрации тени viewPort.addProcessor(slsr); } // Создание точечного света private void createPointLight() { PointLight pointLight = new PointLight(); pointLight.setColor(ColorRGBA.Yellow); pointLight.setRadius(4f); pointLight.setPosition(new Vector3f(0.8f, 14.0f, 0)); rootNode.addLight(pointLight); } // Рассеянный свет private void createAmbienLight() { AmbientLight al = new AmbientLight(); al.setColor(ColorRGBA.White.mult(0.72f)); rootNode.addLight(al); } }
SpotLight очень хорошо использовать в таких вещах как фонари прожекторы ну и так далее ,в этом коде я привел пример освещения уличного фонаря а так же тени.
Как вы видите этот источник света идеально подходит для иллюстрации уличного освещения , в этом коде я использовал три источника света AmbientLight он придает сцене объемности а точнее как я уже писал в пред идущей статье он распределяется равномерно по всем объектам , а PointLight я использовал для подсветки самого фонаря это видно по последнем изображении , на тему PointLight мы поговорим в отдельной статье.
В классе SpotLight по сравнению с другими источниками света он имеет больше настроек что на мое мнение придает ему огромные преимущества в использовании, ну а теперь перейдем к описании создания данного источника света и тени.
Эта функция установки дистанции освещения (в пикселях) , то есть если установленное значение будет меньше от отражаемого объекта то вы там ничего не увидите.
spot.setSpotRange(100f);
Начальный радиус источника света
spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD);
Конечный радиус источника света
spot.setSpotOuterAngle(50f * FastMath.DEG_TO_RAD);
Цвет источника света где входящий параметр функции mult(2.3f) говорит об интенсивности освещения
spot.setColor(ColorRGBA.White.mult(2.3f));
Начальная позиция
spot.setPosition(new Vector3f(0.4f, 14.5f, 0));
Функция указывает направление
spot.setDirection(new Vector3f(0, -5, 0));
Ну а теперь функции создание теней.
Класс SpotLightShadowRenderer(assetManager, 512) он предназначен для прорисовки теней assetManager нужен ему для загрузки шейдеров , а второй параметр нужен для создания карты теней он может быть размером кратно (512,1024,2048 и тд) , а простыми словами чем больше число тем детальней будет прорисовка теней.
Функция говорит что в данном узле нужно разрешить отражения
rootNode.setShadowMode(ShadowMode.CastAndReceive);
Установка нашего источника света
slsr.setLight(spot);
Функция интенсивности освещения, чем больше параметр тем ярче освещение
slsr.setShadowIntensity(0.6f);
Функция установка сглаживания теней
slsr.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON);
Добавление процессора для пост обработки теней ну короче без этого работать не будет
viewPort.addProcessor(slsr);
Ну наверно все что я хотел дополнить не завышайте размер карты теней так как на вашей видео карте оно может работать нормально а на другой более слабой очень снизится fps , да и модель фонаря вы можете скачать по ссылке .
Спасибо за внимание!!
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.