📄 directionalshadowmappass.java
字号:
/* * Copyright (c) 2003-2009 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'jMonkeyEngine' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package com.jme.renderer.pass;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import com.jme.image.Texture;import com.jme.image.Texture2D;import com.jme.image.Texture.DepthTextureCompareFunc;import com.jme.image.Texture.DepthTextureCompareMode;import com.jme.image.Texture.DepthTextureMode;import com.jme.light.DirectionalLight;import com.jme.math.Matrix4f;import com.jme.math.Vector3f;import com.jme.renderer.AbstractCamera;import com.jme.renderer.ColorRGBA;import com.jme.renderer.Renderer;import com.jme.renderer.TextureRenderer;import com.jme.scene.Node;import com.jme.scene.Spatial;import com.jme.scene.Spatial.CullHint;import com.jme.scene.state.BlendState;import com.jme.scene.state.ClipState;import com.jme.scene.state.ColorMaskState;import com.jme.scene.state.CullState;import com.jme.scene.state.GLSLShaderObjectsState;import com.jme.scene.state.LightState;import com.jme.scene.state.MaterialState;import com.jme.scene.state.RenderState;import com.jme.scene.state.TextureState;import com.jme.system.DisplaySystem;/** * A pass providing a shadow mapping layer across the top of an existing scene. * * Based on code by Robert Larsson and Joshua Slack * * @author kevglass */public class DirectionalShadowMapPass extends Pass { private static final long serialVersionUID = 1L; /** Bias matrix borrowed from the projected texture utility */ private static Matrix4f biasMatrix = new Matrix4f(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f); // bias from [-1, 1] to [0, 1] /** The renderer used to produce the shadow map */ private TextureRenderer shadowMapRenderer; /** The texture storing the shadow map */ private Texture2D shadowMapTexture; /** The near plane when rendering the shadow map */ private float nearPlane = 1f; /** * The far plane when rendering the shadow map - currently tuned for the * test */ private float farPlane = 3000.0f; /** * The location the shadow light source is looking at - must point at the * focus of the scene */ private Vector3f shadowCameraLookAt; /** * The effective location of the light source - derived based on the * distance of casting, look at and direction */ private Vector3f shadowCameraLocation; /** The list of occluding nodes */ private ArrayList<Spatial> occluderNodes = new ArrayList<Spatial>(); /** Culling front faces when rendering shadow maps */ private CullState cullFrontFace; /** Turn off textures when rendering shadow maps */ private TextureState noTexture; /** Turn off colours when rendering shadow maps - depth only */ private ColorMaskState colorDisabled; /** Turn off lighting when rendering shadow maps - depth only */ private LightState noLights; /** * The blending to both discard the fragements that have been determined to * be free of shadows and to blend into the background scene */ private BlendState discardShadowFragments; /** The state applying the shadow map */ private TextureState shadowTextureState; /** The bright light used to blend the shadows version into the scene */ private LightState brightLights; /** The dark material used to blend the shadows into the scene */ private MaterialState darkMaterial; /** Don't perform any plane clipping when rendering the shadowed scene */ private ClipState noClip; /** True once the pass has been initialised */ protected boolean initialised = false; /** The direction shadows are being cast from - directional light? */ protected Vector3f direction; /** The size of the shadow map texture */ private int shadowMapSize; /** * The scaling applied to the shadow map when rendered to - lower number * means higher res but less ara covered by the shadow map */ protected float shadowMapScale = 0.4f; /** * The distance we're modelling the direction light source as being away * from the focal point, again the higher the number the more of the scene * is covered but at lower resolution */ protected float dis = 500; /** * A place to internally save previous enforced states setup before * rendering this pass */ private RenderState[] preStates = new RenderState[RenderState.StateType.values().length]; /** The colour of shadows cast */ private ColorRGBA shadowCol = new ColorRGBA(0, 0, 0, 0.3f); /** The optional shader for smoothing */ private GLSLShaderObjectsState shader; /** True if the pass should use shaders */ private boolean useShaders; /** True if we should cull occluders - if not we'll draw all includers */ private boolean cullOccluders = true; /** Node providing easy rendering of all occluders added to the pass */ private final OccludersRenderNode occludersRenderNode = new OccludersRenderNode(); /** * Create a shadow map pass casting shadows from a light with the direction * given. * * @param direction * The direction of the light casting the shadows */ public DirectionalShadowMapPass(Vector3f direction) { this(direction, 2048); } /** * Create a shadow map pass casting shadows from a light with the direction * given. * * @param shadowMapSize * The size of the shadow map texture * @param direction * The direction of the light casting the shadows */ public DirectionalShadowMapPass(Vector3f direction, int shadowMapSize) { this.shadowMapSize = shadowMapSize; this.direction = direction; setViewTarget(new Vector3f(0, 0, 0)); useShaders = GLSLShaderObjectsState.isSupported(); } /** * Set the colour of the shadows to be cast * * @param col * The colour of the shadows to be cast */ public void setShadowAlpha(float alpha) { shadowCol.a = alpha; if (darkMaterial != null) { darkMaterial.setDiffuse(shadowCol); } } /** * Set the distance of the camera representing the directional light. The * further away the more of the scene will be shadowed but at a lower * resolution * * @param dis * The distance to be used for the shadow map camera (default = * 500) */ public void setViewDistance(float dis) { this.dis = dis; } /** * Indicate whether occluders should be culled against shadow map frustrum * * @param cullOccluders * True if occluders should be culled against shadow map frustrum */ public void setCullOccluders(boolean cullOccluders) { this.cullOccluders = cullOccluders; } /** * Set the scale factor thats used to stretch the shadow map texture across * the scene. * * Higher the number the more of the scene will be convered but at a lower * resolution. * * @param scale * The scale used to stretch the shadow map across the scene. */ public void setShadowMapScale(float scale) { shadowMapScale = scale; } /** * Set the target of the view. This will be where the camera points when * generating the shadow map and should be the centre of the scene * * @param target * The target of the view */ public void setViewTarget(Vector3f target) { if (target.equals(shadowCameraLookAt)) { return; } shadowCameraLookAt = new Vector3f(target); Vector3f temp = new Vector3f(direction); temp.normalizeLocal(); temp.multLocal(-dis); shadowCameraLocation = new Vector3f(target); shadowCameraLocation.addLocal(temp); if (shadowMapRenderer != null) { updateShadowCamera(); } } /** * saves any states enforced by the user for replacement at the end of the * pass. */ protected void saveEnforcedStates() { for (int x = RenderState.StateType.values().length; --x >= 0;) { preStates[x] = context.enforcedStateList[x]; } } /** * replaces any states enforced by the user at the end of the pass. */ protected void replaceEnforcedStates() { for (int x = RenderState.StateType.values().length; --x >= 0;) { context.enforcedStateList[x] = preStates[x]; } } /** * Add a spatial that will occlude light and hence cast a shadow *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -