Changed the way post shadow pass is done. It's now a technique of the lighting material definition.
This allow to have shadows that fully works with partially transparent objects (like trees). If a material does not have the postShadow technique, the renderer uses the fallback material (like before). git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9279 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
7445565df3
commit
bf55974bf4
@ -99,6 +99,25 @@ MaterialDef Phong Lighting {
|
||||
|
||||
// the env map is a spheremap and not a cube map
|
||||
Boolean EnvMapAsSphereMap
|
||||
|
||||
//shadows
|
||||
Int FilterMode
|
||||
Boolean HardwareShadows
|
||||
|
||||
Texture2D ShadowMap0
|
||||
Texture2D ShadowMap1
|
||||
Texture2D ShadowMap2
|
||||
Texture2D ShadowMap3
|
||||
|
||||
Float ShadowIntensity
|
||||
Vector4 Splits
|
||||
|
||||
Matrix4 LightViewProjectionMatrix0
|
||||
Matrix4 LightViewProjectionMatrix1
|
||||
Matrix4 LightViewProjectionMatrix2
|
||||
Matrix4 LightViewProjectionMatrix3
|
||||
|
||||
Float PCFEdge
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -141,7 +160,7 @@ MaterialDef Phong Lighting {
|
||||
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||
|
||||
USE_REFLECTION : EnvMap
|
||||
SPHERE_MAP : SphereMap
|
||||
SPHERE_MAP : SphereMap
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +175,8 @@ MaterialDef Phong Lighting {
|
||||
}
|
||||
|
||||
Defines {
|
||||
DIFFUSEMAP_ALPHA : DiffuseMap
|
||||
COLOR_MAP : ColorMap
|
||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||
}
|
||||
|
||||
RenderState {
|
||||
@ -169,6 +189,51 @@ MaterialDef Phong Lighting {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Technique PostShadow15{
|
||||
VertexShader GLSL150: Common/MatDefs/Shadow/PostShadowPSSM.vert
|
||||
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadowPSSM15.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
HARDWARE_SHADOWS : HardwareShadows
|
||||
FILTER_MODE : FilterMode
|
||||
PCFEDGE : PCFEdge
|
||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||
COLOR_MAP : ColorMap
|
||||
}
|
||||
|
||||
RenderState {
|
||||
Blend Modulate
|
||||
}
|
||||
}
|
||||
|
||||
Technique PostShadow{
|
||||
VertexShader GLSL100: Common/MatDefs/Shadow/PostShadowPSSM.vert
|
||||
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowPSSM.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
HARDWARE_SHADOWS : HardwareShadows
|
||||
FILTER_MODE : FilterMode
|
||||
PCFEDGE : PCFEdge
|
||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||
COLOR_MAP : ColorMap
|
||||
}
|
||||
|
||||
RenderState {
|
||||
Blend Modulate
|
||||
}
|
||||
}
|
||||
|
||||
Technique PreNormalPass {
|
||||
|
||||
VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifdef HARDWARE_SHADOWS
|
||||
#define SHADOWMAP sampler2DShadow
|
||||
#define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r
|
||||
#define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r
|
||||
#else
|
||||
#define SHADOWMAP sampler2D
|
||||
#define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r)
|
||||
@ -27,6 +27,7 @@
|
||||
#define KERNEL 8.0
|
||||
#endif
|
||||
|
||||
|
||||
uniform SHADOWMAP m_ShadowMap0;
|
||||
uniform SHADOWMAP m_ShadowMap1;
|
||||
uniform SHADOWMAP m_ShadowMap2;
|
||||
@ -43,7 +44,7 @@ varying vec4 projCoord3;
|
||||
|
||||
varying float shadowPosition;
|
||||
|
||||
const float texSize = 1024.0;
|
||||
float texSize = 1024.0;
|
||||
const float pixSize = 1.0 / texSize;
|
||||
const vec2 pixSize2 = vec2(pixSize);
|
||||
|
||||
@ -64,6 +65,11 @@ float Shadow_BorderCheck(in vec2 coord){
|
||||
}
|
||||
|
||||
float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
||||
float border = Shadow_BorderCheck(projCoord.xy);
|
||||
if (border > 0.0)
|
||||
return 1.0;
|
||||
|
||||
|
||||
float shadow = 0.0;
|
||||
vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
|
||||
shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o);
|
||||
@ -75,6 +81,9 @@ float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
||||
}
|
||||
|
||||
float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
||||
float border = Shadow_BorderCheck(projCoord.xy);
|
||||
if (border > 0.0)
|
||||
return 1.0;
|
||||
vec4 gather = vec4(0.0);
|
||||
gather.x = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 0.0));
|
||||
gather.y = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 0.0));
|
||||
@ -88,12 +97,15 @@ float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
||||
|
||||
float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
||||
float shadow = 0.0;
|
||||
float border = Shadow_BorderCheck(projCoord.xy);
|
||||
if (border > 0.0)
|
||||
return 1.0;
|
||||
float bound = KERNEL * 0.5 - 0.5;
|
||||
bound *= PCFEDGE;
|
||||
for (float y = -bound; y <= bound; y += PCFEDGE){
|
||||
for (float x = -bound; x <= bound; x += PCFEDGE){
|
||||
shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) +
|
||||
Shadow_BorderCheck(projCoord.xy),
|
||||
border,
|
||||
0.0, 1.0);
|
||||
}
|
||||
}
|
||||
@ -102,18 +114,46 @@ float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
||||
return shadow;
|
||||
}
|
||||
|
||||
void main(){
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
uniform sampler2D m_ColorMap;
|
||||
#else
|
||||
uniform sampler2D m_DiffuseMap;
|
||||
#endif
|
||||
uniform float m_AlphaDiscardThreshold;
|
||||
varying vec2 texCoord;
|
||||
#endif
|
||||
|
||||
void main(){
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
float alpha = texture2D(m_ColorMap,texCoord).a;
|
||||
#else
|
||||
float alpha = texture2D(m_DiffuseMap,texCoord).a;
|
||||
#endif
|
||||
if(alpha<=m_AlphaDiscardThreshold){
|
||||
discard;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
vec4 shadowPerSplit = vec4(0.0);
|
||||
shadowPerSplit.x = GETSHADOW(m_ShadowMap0, projCoord0);
|
||||
shadowPerSplit.y = GETSHADOW(m_ShadowMap1, projCoord1);
|
||||
shadowPerSplit.z = GETSHADOW(m_ShadowMap2, projCoord2);
|
||||
shadowPerSplit.w = GETSHADOW(m_ShadowMap3, projCoord3);
|
||||
|
||||
|
||||
vec4 less = step( shadowPosition, m_Splits );
|
||||
vec4 more = vec4(1.0) - step( shadowPosition, vec4(0.0, m_Splits.xyz) );
|
||||
float shadow = dot(shadowPerSplit, less * more );
|
||||
|
||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||
|
||||
|
||||
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||
//gl_FragColor = vec4(alpha, alpha, alpha, 1.0);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,12 @@ varying vec4 projCoord3;
|
||||
|
||||
varying float shadowPosition;
|
||||
|
||||
varying vec2 texCoord;
|
||||
|
||||
attribute vec3 inPosition;
|
||||
#ifdef DISCARD_ALPHA
|
||||
attribute vec2 inTexCoord;
|
||||
#endif
|
||||
|
||||
const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
@ -28,7 +33,9 @@ void main(){
|
||||
// get the vertex in world space
|
||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
texCoord = inTexCoord;
|
||||
#endif
|
||||
// populate the light view matrices array and convert vertex to light viewProj space
|
||||
projCoord0 = biasMat * m_LightViewProjectionMatrix0 * worldPos;
|
||||
projCoord1 = biasMat * m_LightViewProjectionMatrix1 * worldPos;
|
||||
|
@ -120,9 +120,31 @@ float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
||||
return shadow;
|
||||
}
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
uniform sampler2D m_ColorMap;
|
||||
#else
|
||||
uniform sampler2D m_DiffuseMap;
|
||||
#endif
|
||||
uniform float m_AlphaDiscardThreshold;
|
||||
varying vec2 texCoord;
|
||||
#endif
|
||||
|
||||
void main(){
|
||||
float shadow = 0.0;
|
||||
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
float alpha = texture2D(m_ColorMap,texCoord).a;
|
||||
#else
|
||||
float alpha = texture2D(m_DiffuseMap,texCoord).a;
|
||||
#endif
|
||||
|
||||
if(alpha < m_AlphaDiscardThreshold){
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
if(shadowPosition < m_Splits.x){
|
||||
shadow = GETSHADOW(m_ShadowMap0, projCoord0);
|
||||
}else if( shadowPosition < m_Splits.y){
|
||||
@ -134,6 +156,6 @@ void main(){
|
||||
}
|
||||
|
||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||
outFragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||
outFragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,26 @@
|
||||
varying vec2 texCoord;
|
||||
|
||||
#ifdef DIFFUSEMAP_ALPHA
|
||||
uniform sampler2D m_DiffuseMap;
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
uniform sampler2D m_ColorMap;
|
||||
#else
|
||||
uniform sampler2D m_DiffuseMap;
|
||||
#endif
|
||||
uniform float m_AlphaDiscardThreshold;
|
||||
#endif
|
||||
|
||||
|
||||
void main(){
|
||||
#ifdef DIFFUSEMAP_ALPHA
|
||||
if (texture2D(m_DiffuseMap, texCoord).a <= 0.50)
|
||||
discard;
|
||||
#ifdef DISCARD_ALPHA
|
||||
#ifdef COLOR_MAP
|
||||
if (texture2D(m_ColorMap, texCoord).a <= m_AlphaDiscardThreshold){
|
||||
discard;
|
||||
}
|
||||
#else
|
||||
if (texture2D(m_DiffuseMap, texCoord).a <= m_AlphaDiscardThreshold){
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(1.0);
|
||||
|
@ -31,11 +31,13 @@ package com.jme3.shadow;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.Caps;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
@ -140,6 +142,12 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
private Picture[] dispPic;
|
||||
private Vector3f[] points = new Vector3f[8];
|
||||
private boolean flushQueues = true;
|
||||
//render state for post shadow pass
|
||||
private RenderState state = new RenderState();
|
||||
// define if the fallback material should be used.
|
||||
private boolean needsfallBackMaterial = false;
|
||||
//Name of the post material technique
|
||||
private String postTechniqueName = "PostShadow";
|
||||
|
||||
/**
|
||||
* Create a PSSM Shadow Renderer
|
||||
@ -208,13 +216,17 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
points[i] = new Vector3f();
|
||||
}
|
||||
|
||||
//initializing render state for post shadow pass (modulade blending and cullmode of for back faces )
|
||||
state.setBlendMode(RenderState.BlendMode.Modulate);
|
||||
state.setFaceCullMode(RenderState.FaceCullMode.Off);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filtering mode for shadow edges see {@link FilterMode} for more info
|
||||
* @param filterMode
|
||||
*/
|
||||
public void setFilterMode(FilterMode filterMode) {
|
||||
final public void setFilterMode(FilterMode filterMode) {
|
||||
if (filterMode == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@ -243,7 +255,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
* sets the shadow compare mode see {@link CompareMode} for more info
|
||||
* @param compareMode
|
||||
*/
|
||||
public void setCompareMode(CompareMode compareMode) {
|
||||
final public void setCompareMode(CompareMode compareMode) {
|
||||
if (compareMode == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@ -306,6 +318,12 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
public void initialize(RenderManager rm, ViewPort vp) {
|
||||
renderManager = rm;
|
||||
viewPort = vp;
|
||||
//checking for caps to chosse the appropriate post material technique
|
||||
if (renderManager.getRenderer().getCaps().contains(Caps.GLSL150)) {
|
||||
postTechniqueName = "PostShadow15";
|
||||
}else{
|
||||
postTechniqueName = "PostShadow";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
@ -430,15 +448,24 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
public void postFrame(FrameBuffer out) {
|
||||
Camera cam = viewPort.getCamera();
|
||||
if (!noOccluders) {
|
||||
postshadowMat.setColor("Splits", splits);
|
||||
for (int i = 0; i < nbSplits; i++) {
|
||||
postshadowMat.setMatrix4("LightViewProjectionMatrix" + i, lightViewProjectionsMatrices[i]);
|
||||
//setting params to recieving geometry list
|
||||
setMatParams();
|
||||
//some materials in the scene does not have a post shadow technique so we're using the fall back material
|
||||
if (needsfallBackMaterial) {
|
||||
renderManager.setForcedMaterial(postshadowMat);
|
||||
}
|
||||
renderManager.setForcedMaterial(postshadowMat);
|
||||
|
||||
|
||||
//forcing the post shadow technique and render state
|
||||
renderManager.setForcedTechnique(postTechniqueName);
|
||||
renderManager.setForcedRenderState(state);
|
||||
|
||||
//rendering the post shadow pass
|
||||
viewPort.getQueue().renderShadowQueue(ShadowMode.Receive, renderManager, cam, flushQueues);
|
||||
|
||||
//resetting renderManager settings
|
||||
renderManager.setForcedTechnique(null);
|
||||
renderManager.setForcedMaterial(null);
|
||||
renderManager.setForcedRenderState(null);
|
||||
renderManager.setCamera(cam, false);
|
||||
|
||||
}
|
||||
@ -447,6 +474,42 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void setMatParams() {
|
||||
|
||||
GeometryList l = viewPort.getQueue().getShadowQueueContent(ShadowMode.Receive);
|
||||
|
||||
//iteratin throught all the geometries of the list to set the material params
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
Material mat = l.get(i).getMaterial();
|
||||
//checking if the material has the post technique and setting the params.
|
||||
if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) {
|
||||
mat.setColor("Splits", splits);
|
||||
postshadowMat.setColor("Splits", splits);
|
||||
for (int j = 0; j < nbSplits; j++) {
|
||||
mat.setMatrix4("LightViewProjectionMatrix" + j, lightViewProjectionsMatrices[j]);
|
||||
mat.setTexture("ShadowMap" + j, shadowMaps[j]);
|
||||
}
|
||||
mat.setBoolean("HardwareShadows", compareMode == CompareMode.Hardware);
|
||||
mat.setInt("FilterMode", filterMode.ordinal());
|
||||
mat.setFloat("PCFEdge", edgesThickness);
|
||||
mat.setFloat("ShadowIntensity", shadowIntensity);
|
||||
} else {
|
||||
needsfallBackMaterial = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//At least one material of the receiving geoms does not support the post shadow techniques
|
||||
//so we fall back to the forced material solution (transparent shadows won't be supported for these objects)
|
||||
if (needsfallBackMaterial) {
|
||||
postshadowMat.setColor("Splits", splits);
|
||||
for (int j = 0; j < nbSplits; j++) {
|
||||
postshadowMat.setMatrix4("LightViewProjectionMatrix" + j, lightViewProjectionsMatrices[j]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void preFrame(float tpf) {
|
||||
}
|
||||
|
||||
@ -511,7 +574,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
* default is 0.7
|
||||
* @param shadowIntensity the darkness of the shadow
|
||||
*/
|
||||
public void setShadowIntensity(float shadowIntensity) {
|
||||
final public void setShadowIntensity(float shadowIntensity) {
|
||||
this.shadowIntensity = shadowIntensity;
|
||||
postshadowMat.setFloat("ShadowIntensity", shadowIntensity);
|
||||
}
|
||||
|
@ -42,10 +42,9 @@ import com.jme3.math.*;
|
||||
import com.jme3.renderer.queue.RenderQueue.Bucket;
|
||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.SceneGraphVisitorAdapter;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.LodControl;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.jme3.scene.shape.Sphere;
|
||||
import com.jme3.shadow.PssmShadowRenderer;
|
||||
import com.jme3.shadow.PssmShadowRenderer.CompareMode;
|
||||
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
|
||||
@ -59,15 +58,16 @@ public class TestTransparentShadow extends SimpleApplication {
|
||||
|
||||
public void simpleInitApp() {
|
||||
|
||||
cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f));
|
||||
cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f));
|
||||
cam.setLocation(new Vector3f(5.700248f, 6.161693f, 5.1404157f));
|
||||
cam.setRotation(new Quaternion(-0.09441641f, 0.8993388f, -0.24089815f, -0.35248178f));
|
||||
|
||||
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
|
||||
|
||||
Quad q = new Quad(20, 20);
|
||||
q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5));
|
||||
q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10));
|
||||
Geometry geom = new Geometry("floor", q);
|
||||
Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
|
||||
mat.setFloat("Shininess", 0);
|
||||
geom.setMaterial(mat);
|
||||
|
||||
geom.rotate(-FastMath.HALF_PI, 0, 0);
|
||||
@ -76,34 +76,21 @@ public class TestTransparentShadow extends SimpleApplication {
|
||||
rootNode.attachChild(geom);
|
||||
|
||||
// create the geometry and attach it
|
||||
Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o");
|
||||
teaGeom.setQueueBucket(Bucket.Transparent);
|
||||
teaGeom.setShadowMode(ShadowMode.Cast);
|
||||
Spatial tree = assetManager.loadModel("Models/Tree/Tree.mesh.j3o");
|
||||
tree.setQueueBucket(Bucket.Transparent);
|
||||
tree.setShadowMode(ShadowMode.CastAndReceive);
|
||||
|
||||
teaGeom.depthFirstTraversal(new SceneGraphVisitorAdapter(){
|
||||
@Override
|
||||
public void visit(Geometry geom) {
|
||||
LodControl lodCtrl = new LodControl();
|
||||
lodCtrl.setTrisPerPixel(0.25f);
|
||||
geom.addControl(lodCtrl);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
AmbientLight al = new AmbientLight();
|
||||
al.setColor(ColorRGBA.White.mult(2));
|
||||
al.setColor(ColorRGBA.White.mult(0.7f));
|
||||
rootNode.addLight(al);
|
||||
|
||||
DirectionalLight dl1 = new DirectionalLight();
|
||||
dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal());
|
||||
dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
|
||||
dl1.setDirection(new Vector3f(0, -1, 0.5f).normalizeLocal());
|
||||
dl1.setColor(ColorRGBA.White.mult(1.5f));
|
||||
rootNode.addLight(dl1);
|
||||
|
||||
DirectionalLight dl = new DirectionalLight();
|
||||
dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
|
||||
dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
|
||||
rootNode.addLight(dl);
|
||||
|
||||
rootNode.attachChild(teaGeom);
|
||||
rootNode.attachChild(tree);
|
||||
|
||||
/** Uses Texture from jme3-test-data library! */
|
||||
ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
|
||||
@ -125,16 +112,26 @@ public class TestTransparentShadow extends SimpleApplication {
|
||||
fire.setLocalTranslation(1.0f, 0, 1.0f);
|
||||
fire.setLocalScale(0.3f);
|
||||
fire.setQueueBucket(Bucket.Translucent);
|
||||
rootNode.attachChild(fire);
|
||||
// rootNode.attachChild(fire);
|
||||
|
||||
|
||||
Material mat2 = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
|
||||
|
||||
|
||||
Geometry ball = new Geometry("sphere", new Sphere(16, 16, 0.5f));
|
||||
ball.setMaterial(mat2);
|
||||
ball.setShadowMode(ShadowMode.CastAndReceive);
|
||||
rootNode.attachChild(ball);
|
||||
ball.setLocalTranslation(-1.0f, 1.5f, 1.0f);
|
||||
|
||||
|
||||
PssmShadowRenderer pssmRenderer = new PssmShadowRenderer(assetManager, 1024, 1);
|
||||
pssmRenderer.setDirection(new Vector3f(0.01f, -1f, 0.01f).normalizeLocal());
|
||||
pssmRenderer.setDirection(dl1.getDirection());
|
||||
pssmRenderer.setLambda(0.55f);
|
||||
pssmRenderer.setShadowIntensity(0.6f);
|
||||
pssmRenderer.setShadowIntensity(0.8f);
|
||||
pssmRenderer.setCompareMode(CompareMode.Software);
|
||||
pssmRenderer.setFilterMode(FilterMode.PCF4);
|
||||
pssmRenderer.displayDebug();
|
||||
//pssmRenderer.displayDebug();
|
||||
viewPort.addProcessor(pssmRenderer);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user