Advertisement
Guest User

MyAbstractShadowRenderer

a guest
Oct 30th, 2014
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.31 KB | None | 0 0
  1. package com.dungeongame.gameclient.scene3d;
  2.  
  3. /*
  4. * Copyright (c) 2009-2012 jMonkeyEngine
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  19. * may be used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  24. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  25. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  26. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34.  
  35. import java.io.IOException;
  36. import java.util.ArrayList;
  37. import java.util.List;
  38.  
  39. import com.jme3.asset.AssetManager;
  40. import com.jme3.export.InputCapsule;
  41. import com.jme3.export.JmeExporter;
  42. import com.jme3.export.JmeImporter;
  43. import com.jme3.export.OutputCapsule;
  44. import com.jme3.export.Savable;
  45. import com.jme3.material.Material;
  46. import com.jme3.material.Technique;
  47. import com.jme3.math.ColorRGBA;
  48. import com.jme3.math.Matrix4f;
  49. import com.jme3.math.Vector3f;
  50. import com.jme3.post.SceneProcessor;
  51. import com.jme3.renderer.Camera;
  52. import com.jme3.renderer.Caps;
  53. import com.jme3.renderer.RenderManager;
  54. import com.jme3.renderer.Renderer;
  55. import com.jme3.renderer.ViewPort;
  56. import com.jme3.renderer.queue.GeometryList;
  57. import com.jme3.renderer.queue.OpaqueComparator;
  58. import com.jme3.renderer.queue.RenderQueue;
  59. import com.jme3.renderer.queue.RenderQueue.ShadowMode;
  60. import com.jme3.scene.Geometry;
  61. import com.jme3.scene.Spatial;
  62. import com.jme3.scene.debug.WireFrustum;
  63. import com.jme3.shader.Shader;
  64. import com.jme3.shadow.CompareMode;
  65. import com.jme3.shadow.EdgeFilteringMode;
  66. import com.jme3.texture.FrameBuffer;
  67. import com.jme3.texture.Image.Format;
  68. import com.jme3.texture.Texture.MagFilter;
  69. import com.jme3.texture.Texture.MinFilter;
  70. import com.jme3.texture.Texture.ShadowCompareMode;
  71. import com.jme3.texture.Texture2D;
  72. import com.jme3.ui.Picture;
  73.  
  74. /**
  75. * abstract shadow renderer that holds commons feature to have for a shadow
  76. * renderer
  77. *
  78. * @author RĂ©my Bouquet aka Nehon
  79. */
  80. public abstract class MyAbstractShadowRenderer implements SceneProcessor, Savable {
  81.  
  82. protected int nbShadowMaps = 1;
  83. protected float shadowMapSize;
  84. protected float shadowIntensity = 0.7f;
  85. protected RenderManager renderManager;
  86. protected ViewPort viewPort;
  87. protected FrameBuffer[] shadowFB;
  88. protected Texture2D[] shadowMaps;
  89. protected Texture2D dummyTex;
  90. protected Material preshadowMat;
  91. protected Material postshadowMat;
  92. protected Matrix4f[] lightViewProjectionsMatrices;
  93. protected AssetManager assetManager;
  94. protected boolean debug = false;
  95. protected float edgesThickness = 1.0f;
  96. protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
  97. protected CompareMode shadowCompareMode = CompareMode.Hardware;
  98. protected Picture[] dispPic;
  99. protected boolean flushQueues = true;
  100. // define if the fallback material should be used.
  101. protected boolean needsfallBackMaterial = false;
  102. //Name of the post material technique
  103. protected String postTechniqueName = "PostShadow";
  104. //flags to know when to change params in the materials
  105. //a list of material of the post shadow queue geometries.
  106. protected List<Material> matCache = new ArrayList<Material>();
  107. protected GeometryList sceneReceivers;
  108. protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
  109. protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator());
  110. private String[] shadowMapStringCache;
  111. private String[] lightViewStringCache;
  112.  
  113.  
  114. /**
  115. * used for serialization
  116. */
  117. protected MyAbstractShadowRenderer(){
  118. }
  119.  
  120. /**
  121. * Create an abstract shadow renderer, this is to be called in extending
  122. * classes
  123. *
  124. * @param assetManager the application asset manager
  125. * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
  126. * etc...)
  127. * @param nbShadowMaps the number of shadow maps rendered (the more shadow
  128. * maps the more quality, the less fps).
  129. */
  130. protected MyAbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) {
  131.  
  132. this.assetManager = assetManager;
  133. this.nbShadowMaps = nbShadowMaps;
  134. this.shadowMapSize = shadowMapSize;
  135. init(assetManager, nbShadowMaps, shadowMapSize);
  136.  
  137. }
  138.  
  139. private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize)
  140. {
  141. //this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
  142. this.postshadowMat = new Material(assetManager, "MatDefs/Shadow/PostShadowMS.j3md");
  143. shadowFB = new FrameBuffer[nbShadowMaps];
  144. shadowMaps = new Texture2D[nbShadowMaps];
  145. dispPic = new Picture[nbShadowMaps];
  146. lightViewProjectionsMatrices = new Matrix4f[nbShadowMaps];
  147. shadowMapStringCache = new String[nbShadowMaps];
  148. lightViewStringCache = new String[nbShadowMaps];
  149.  
  150. //DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
  151. dummyTex = new Texture2D(shadowMapSize, shadowMapSize, Format.RGBA8);
  152.  
  153. preshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PreShadow.j3md");
  154. postshadowMat.setFloat("ShadowMapSize", shadowMapSize);
  155.  
  156. for (int i = 0; i < nbShadowMaps; i++)
  157. {
  158. lightViewProjectionsMatrices[i] = new Matrix4f();
  159. shadowFB[i] = new FrameBuffer(shadowMapSize, shadowMapSize, 1);
  160. shadowMaps[i] = new Texture2D(shadowMapSize, shadowMapSize, Format.Depth);
  161.  
  162. shadowFB[i].setDepthTexture(shadowMaps[i]);
  163.  
  164. //DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
  165. shadowFB[i].setColorTexture(dummyTex);
  166. shadowMapStringCache[i] = "ShadowMap" + i;
  167. lightViewStringCache[i] = "LightViewProjectionMatrix" + i;
  168.  
  169. postshadowMat.setTexture(shadowMapStringCache[i], shadowMaps[i]);
  170.  
  171. //quads for debuging purpose
  172. dispPic[i] = new Picture("Picture" + i);
  173. dispPic[i].setTexture(assetManager, shadowMaps[i], false);
  174. }
  175.  
  176. setShadowCompareMode(shadowCompareMode);
  177. setEdgeFilteringMode(edgeFilteringMode);
  178. setShadowIntensity(shadowIntensity);
  179. }
  180.  
  181. /**
  182. * set the post shadow material for this renderer
  183. *
  184. * @param postShadowMat
  185. */
  186. protected final void setPostShadowMaterial(Material postShadowMat)
  187. {
  188. this.postshadowMat = postShadowMat;
  189. postshadowMat.setFloat("ShadowMapSize", shadowMapSize);
  190. for (int i = 0; i < nbShadowMaps; i++)
  191. {
  192. postshadowMat.setTexture(shadowMapStringCache[i], shadowMaps[i]);
  193. }
  194. setShadowCompareMode(shadowCompareMode);
  195. setEdgeFilteringMode(edgeFilteringMode);
  196. setShadowIntensity(shadowIntensity);
  197. }
  198.  
  199. /**
  200. * Sets the filtering mode for shadow edges see {@link EdgeFilteringMode}
  201. * for more info
  202. *
  203. * @param EdgeFilteringMode
  204. */
  205. final public void setEdgeFilteringMode(EdgeFilteringMode filterMode)
  206. {
  207. if (filterMode == null)
  208. {
  209. throw new NullPointerException();
  210. }
  211.  
  212. this.edgeFilteringMode = filterMode;
  213. postshadowMat.setInt("FilterMode", filterMode.getMaterialParamValue());
  214. postshadowMat.setFloat("PCFEdge", edgesThickness);
  215. if (shadowCompareMode == CompareMode.Hardware) {
  216. for (Texture2D shadowMap : shadowMaps) {
  217. if (filterMode == EdgeFilteringMode.Bilinear) {
  218. shadowMap.setMagFilter(MagFilter.Bilinear);
  219. shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
  220. } else {
  221. shadowMap.setMagFilter(MagFilter.Nearest);
  222. shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
  223. }
  224. }
  225. }
  226. }
  227.  
  228. /**
  229. * returns the the edge filtering mode
  230. *
  231. * @see EdgeFilteringMode
  232. * @return
  233. */
  234. public EdgeFilteringMode getEdgeFilteringMode() {
  235. return edgeFilteringMode;
  236. }
  237.  
  238. /**
  239. * sets the shadow compare mode see {@link CompareMode} for more info
  240. *
  241. * @param compareMode
  242. */
  243. final public void setShadowCompareMode(CompareMode compareMode) {
  244. if (compareMode == null) {
  245. throw new IllegalArgumentException("Shadow compare mode cannot be null");
  246. }
  247.  
  248. this.shadowCompareMode = compareMode;
  249. for (Texture2D shadowMap : shadowMaps) {
  250. if (compareMode == CompareMode.Hardware) {
  251. shadowMap.setShadowCompareMode(ShadowCompareMode.LessOrEqual);
  252. if (edgeFilteringMode == EdgeFilteringMode.Bilinear) {
  253. shadowMap.setMagFilter(MagFilter.Bilinear);
  254. shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
  255. } else {
  256. shadowMap.setMagFilter(MagFilter.Nearest);
  257. shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
  258. }
  259. } else {
  260. shadowMap.setShadowCompareMode(ShadowCompareMode.Off);
  261. shadowMap.setMagFilter(MagFilter.Nearest);
  262. shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
  263. }
  264. }
  265. postshadowMat.setBoolean("HardwareShadows", compareMode == CompareMode.Hardware);
  266. }
  267.  
  268. /**
  269. * returns the shadow compare mode
  270. *
  271. * @see CompareMode
  272. * @return the shadowCompareMode
  273. */
  274. public CompareMode getShadowCompareMode() {
  275. return shadowCompareMode;
  276. }
  277.  
  278. //debug function that create a displayable frustrum
  279. protected Geometry createFrustum(Vector3f[] pts, int i) {
  280. WireFrustum frustum = new WireFrustum(pts);
  281. Geometry frustumMdl = new Geometry("f", frustum);
  282. frustumMdl.setCullHint(Spatial.CullHint.Never);
  283. frustumMdl.setShadowMode(ShadowMode.Off);
  284. Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  285. mat.getAdditionalRenderState().setWireframe(true);
  286. frustumMdl.setMaterial(mat);
  287. switch (i) {
  288. case 0:
  289. frustumMdl.getMaterial().setColor("Color", ColorRGBA.Pink);
  290. break;
  291. case 1:
  292. frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red);
  293. break;
  294. case 2:
  295. frustumMdl.getMaterial().setColor("Color", ColorRGBA.Green);
  296. break;
  297. case 3:
  298. frustumMdl.getMaterial().setColor("Color", ColorRGBA.Blue);
  299. break;
  300. default:
  301. frustumMdl.getMaterial().setColor("Color", ColorRGBA.White);
  302. break;
  303. }
  304.  
  305. frustumMdl.updateGeometricState();
  306. return frustumMdl;
  307. }
  308.  
  309. public void initialize(RenderManager rm, ViewPort vp) {
  310. renderManager = rm;
  311. viewPort = vp;
  312. //checking for caps to chosse the appropriate post material technique
  313. if (renderManager.getRenderer().getCaps().contains(Caps.GLSL150)) {
  314. postTechniqueName = "PostShadow15";
  315. } else {
  316. postTechniqueName = "PostShadow";
  317. }
  318. }
  319.  
  320. public boolean isInitialized() {
  321. return viewPort != null;
  322. }
  323.  
  324. /**
  325. * This mehtod is called once per frame. it is responsible for updating the
  326. * shadow cams according to the light view.
  327. *
  328. * @param viewCam the scene cam
  329. */
  330. protected abstract void updateShadowCams(Camera viewCam);
  331.  
  332. /**
  333. * this method must return the geomtryList that contains the oclluders to be
  334. * rendered in the shadow map
  335. *
  336. * @param shadowMapIndex the index of the shadow map being rendered
  337. * @param sceneOccluders the occluders of the whole scene
  338. * @param sceneReceivers the recievers of the whole scene
  339. * @return
  340. */
  341. protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers, GeometryList shadowMapOccluders);
  342.  
  343. /**
  344. * return the shadow camera to use for rendering the shadow map according
  345. * the given index
  346. *
  347. * @param shadowMapIndex the index of the shadow map being rendered
  348. * @return the shadowCam
  349. */
  350. protected abstract Camera getShadowCam(int shadowMapIndex);
  351.  
  352. /**
  353. * responsible for displaying the frustum of the shadow cam for debug
  354. * purpose
  355. *
  356. * @param shadowMapIndex
  357. */
  358. protected void doDisplayFrustumDebug(int shadowMapIndex) {
  359. }
  360.  
  361. @SuppressWarnings("fallthrough")
  362. public void postQueue(RenderQueue rq)
  363. {
  364. GeometryList occluders = rq.getShadowQueueContent(ShadowMode.Cast);
  365. sceneReceivers = rq.getShadowQueueContent(ShadowMode.Receive);
  366. if (sceneReceivers.size() == 0 || occluders.size() == 0) {
  367. return;
  368. }
  369.  
  370. updateShadowCams(viewPort.getCamera());
  371.  
  372. Renderer r = renderManager.getRenderer();
  373. renderManager.setForcedMaterial(preshadowMat);
  374. renderManager.setForcedTechnique("PreShadow");
  375.  
  376. for (int shadowMapIndex = 0; shadowMapIndex < nbShadowMaps; shadowMapIndex++) {
  377.  
  378. if (debugfrustums) {
  379. doDisplayFrustumDebug(shadowMapIndex);
  380. }
  381. renderShadowMap(shadowMapIndex, occluders, sceneReceivers);
  382.  
  383. }
  384.  
  385. debugfrustums = false;
  386. if (flushQueues) {
  387. occluders.clear();
  388. }
  389. //restore setting for future rendering
  390. r.setFrameBuffer(viewPort.getOutputFrameBuffer());
  391. renderManager.setForcedMaterial(null);
  392. renderManager.setForcedTechnique(null);
  393. renderManager.setCamera(viewPort.getCamera(), false);
  394.  
  395. }
  396.  
  397. protected void renderShadowMap(int shadowMapIndex, GeometryList occluders, GeometryList receivers) {
  398. shadowMapOccluders = getOccludersToRender(shadowMapIndex, occluders, receivers, shadowMapOccluders);
  399. Camera shadowCam = getShadowCam(shadowMapIndex);
  400.  
  401. //saving light view projection matrix for this split
  402. lightViewProjectionsMatrices[shadowMapIndex].set(shadowCam.getViewProjectionMatrix());
  403. renderManager.setCamera(shadowCam, false);
  404.  
  405. renderManager.getRenderer().setFrameBuffer(shadowFB[shadowMapIndex]);
  406. renderManager.getRenderer().clearBuffers(false, true, false);
  407.  
  408. // render shadow casters to shadow map
  409. viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
  410. }
  411. boolean debugfrustums = false;
  412.  
  413. public void displayFrustum() {
  414. debugfrustums = true;
  415. }
  416.  
  417. //debug only : displays depth shadow maps
  418. protected void displayShadowMap(Renderer r)
  419. {
  420. Camera cam = viewPort.getCamera();
  421. renderManager.setCamera(cam, true);
  422. int h = cam.getHeight();
  423.  
  424. int mov = 0;
  425.  
  426. for (int i = 0; i < dispPic.length - mov; i++)
  427. {
  428. dispPic[i].setTexture(assetManager, shadowMaps[i + mov], false);
  429. dispPic[i + mov].setPosition((128 * i) + (150 + 34 * (i + 1)), h / 20f);
  430. dispPic[i + mov].setWidth(128);
  431. dispPic[i + mov].setHeight(128);
  432. dispPic[i + mov].updateGeometricState();
  433. renderManager.renderGeometry(dispPic[i + mov]);
  434. }
  435. renderManager.setCamera(cam, false);
  436. }
  437.  
  438. /**
  439. * For dubuging purpose Allow to "snapshot" the current frustrum to the
  440. * scene
  441. */
  442. public void displayDebug() {
  443. debug = true;
  444. }
  445.  
  446. abstract GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers);
  447.  
  448. public void postFrame(FrameBuffer out)
  449. {
  450.  
  451. if (debug) {
  452. displayShadowMap(renderManager.getRenderer());
  453. }
  454.  
  455. lightReceivers = getReceivers(sceneReceivers, lightReceivers);
  456.  
  457. updatePostShadowMatParams(postshadowMat);
  458.  
  459. if (lightReceivers.size() != 0)
  460. {
  461. //setting params to recieving geometry list
  462. setMatParams();
  463.  
  464. Camera cam = viewPort.getCamera();
  465. //some materials in the scene does not have a post shadow technique so we're using the fall back material
  466. if (needsfallBackMaterial)
  467. {
  468. renderManager.setForcedMaterial(postshadowMat);
  469. }
  470.  
  471. //forcing the post shadow technique and render state
  472. renderManager.setForcedTechnique(postTechniqueName);
  473.  
  474. //rendering the post shadow pass
  475. viewPort.getQueue().renderShadowQueue(lightReceivers, renderManager, cam, false);
  476. if (flushQueues) {
  477. sceneReceivers.clear();
  478. }
  479.  
  480. //resetting renderManager settings
  481. renderManager.setForcedTechnique(null);
  482. renderManager.setForcedMaterial(null);
  483. renderManager.setCamera(cam, false);
  484.  
  485. }
  486.  
  487. }
  488.  
  489. /**
  490. * This method is called once per frame and is responsible of setting the
  491. * material parameters than sub class may need to set on the post material
  492. *
  493. * @param material the materail to use for the post shadow pass
  494. */
  495. protected abstract void setMaterialParameters(Material material);
  496.  
  497. protected abstract void updatePostShadowMatParams(Material material);
  498.  
  499. private void setMatParams() {
  500.  
  501. GeometryList l = viewPort.getQueue().getShadowQueueContent(ShadowMode.Receive);
  502.  
  503. //iteration throught all the geometries of the list to gather the materials
  504.  
  505. matCache.clear();
  506. for (int i = 0; i < l.size(); i++) {
  507. Material mat = l.get(i).getMaterial();
  508. //checking if the material has the post technique and adding it to the material cache
  509. if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) {
  510. if (!matCache.contains(mat)) {
  511. matCache.add(mat);
  512. }
  513. } else {
  514. needsfallBackMaterial = true;
  515. }
  516. }
  517.  
  518. //iterating through the mat cache and setting the parameters
  519. for (Material mat : matCache) {
  520.  
  521. mat.setFloat("ShadowMapSize", shadowMapSize);
  522.  
  523. for (int j = 0; j < nbShadowMaps; j++) {
  524. mat.setMatrix4(lightViewStringCache[j], lightViewProjectionsMatrices[j]);
  525. }
  526. for (int j = 0; j < nbShadowMaps; j++) {
  527. mat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
  528. }
  529. mat.setBoolean("HardwareShadows", shadowCompareMode == CompareMode.Hardware);
  530. mat.setInt("FilterMode", edgeFilteringMode.getMaterialParamValue());
  531. mat.setFloat("PCFEdge", edgesThickness);
  532. mat.setFloat("ShadowIntensity", shadowIntensity);
  533.  
  534. setMaterialParameters(mat);
  535. }
  536.  
  537. //At least one material of the receiving geoms does not support the post shadow techniques
  538. //so we fall back to the forced material solution (transparent shadows won't be supported for these objects)
  539. if (needsfallBackMaterial)
  540. {
  541. setPostShadowParams(postshadowMat);
  542. }
  543.  
  544. }
  545.  
  546. /**
  547. * for internal use only
  548. */
  549. public void setPostShadowParams(Material mat)
  550. {
  551. setMaterialParameters(mat);
  552. for (int j = 0; j < nbShadowMaps; j++)
  553. {
  554. mat.setMatrix4(lightViewStringCache[j], lightViewProjectionsMatrices[j]);
  555. mat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
  556. }
  557. }
  558.  
  559. public void setPostShadowParams()
  560. {
  561. setPostShadowParams(postshadowMat);
  562. }
  563.  
  564. public void preFrame(float tpf) {
  565. }
  566.  
  567. public void cleanup() {
  568. }
  569.  
  570. public void reshape(ViewPort vp, int w, int h) {
  571. }
  572.  
  573. /**
  574. * returns the shdaow intensity
  575. *
  576. * @see #setShadowIntensity(float shadowIntensity)
  577. * @return shadowIntensity
  578. */
  579. public float getShadowIntensity() {
  580. return shadowIntensity;
  581. }
  582.  
  583. /**
  584. * Set the shadowIntensity, the value should be between 0 and 1, a 0 value
  585. * gives a bright and invisilble shadow, a 1 value gives a pitch black
  586. * shadow, default is 0.7
  587. *
  588. * @param shadowIntensity the darkness of the shadow
  589. */
  590. final public void setShadowIntensity(float shadowIntensity)
  591. {
  592. this.shadowIntensity = shadowIntensity;
  593. postshadowMat.setFloat("ShadowIntensity", shadowIntensity);
  594. }
  595.  
  596. /**
  597. * returns the edges thickness
  598. *
  599. * @see #setEdgesThickness(int edgesThickness)
  600. * @return edgesThickness
  601. */
  602. public int getEdgesThickness() {
  603. return (int) (edgesThickness * 10);
  604. }
  605.  
  606. /**
  607. * Sets the shadow edges thickness. default is 1, setting it to lower values
  608. * can help to reduce the jagged effect of the shadow edges
  609. *
  610. * @param edgesThickness
  611. */
  612. public void setEdgesThickness(int edgesThickness) {
  613. this.edgesThickness = Math.max(1, Math.min(edgesThickness, 10));
  614. this.edgesThickness *= 0.1f;
  615. postshadowMat.setFloat("PCFEdge", edgesThickness);
  616. }
  617.  
  618. /**
  619. * returns true if the PssmRenderer flushed the shadow queues
  620. *
  621. * @return flushQueues
  622. */
  623. public boolean isFlushQueues() {
  624. return flushQueues;
  625. }
  626.  
  627. /**
  628. * Set this to false if you want to use several PssmRederers to have
  629. * multiple shadows cast by multiple light sources. Make sure the last
  630. * PssmRenderer in the stack DO flush the queues, but not the others
  631. *
  632. * @param flushQueues
  633. */
  634. public void setFlushQueues(boolean flushQueues) {
  635. this.flushQueues = flushQueues;
  636. }
  637.  
  638. public void read(JmeImporter im) throws IOException {
  639. InputCapsule ic = (InputCapsule) im.getCapsule(this);
  640. assetManager = im.getAssetManager();
  641. nbShadowMaps = ic.readInt("nbShadowMaps", 1);
  642. shadowMapSize = ic.readInt("shadowMapSize", 0);
  643. shadowIntensity = ic.readFloat("shadowIntensity", 0.7f);
  644. edgeFilteringMode = ic.readEnum("edgeFilteringMode", EdgeFilteringMode.class, EdgeFilteringMode.Bilinear);
  645. shadowCompareMode = ic.readEnum("shadowCompareMode", CompareMode.class, CompareMode.Hardware);
  646. flushQueues = ic.readBoolean("flushQueues", false);
  647. init(assetManager, nbShadowMaps, (int) shadowMapSize);
  648. edgesThickness = ic.readFloat("edgesThickness", 1.0f);
  649. postshadowMat.setFloat("PCFEdge", edgesThickness);
  650.  
  651. }
  652.  
  653. public void write(JmeExporter ex) throws IOException {
  654. OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
  655. oc.write(nbShadowMaps, "nbShadowMaps", 1);
  656. oc.write(shadowMapSize, "shadowMapSize", 0);
  657. oc.write(shadowIntensity, "shadowIntensity", 0.7f);
  658. oc.write(edgeFilteringMode, "edgeFilteringMode", EdgeFilteringMode.Bilinear);
  659. oc.write(shadowCompareMode, "shadowCompareMode", CompareMode.Hardware);
  660. oc.write(flushQueues, "flushQueues", false);
  661. oc.write(edgesThickness, "edgesThickness", 1.0f);
  662. }
  663. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement