use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.
the class PssmShadowRenderer method setMatParams.
private void setMatParams() {
GeometryList l = lightReceivers;
//iteration throught all the geometries of the list to gather the materials
matCache.clear();
for (int i = 0; i < l.size(); i++) {
Material mat = l.get(i).getMaterial();
//checking if the material has the post technique and adding it to the material cache
if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) {
if (!matCache.contains(mat)) {
matCache.add(mat);
}
} else {
needsfallBackMaterial = true;
}
}
//iterating through the mat cache and setting the parameters
for (Material mat : matCache) {
mat.setColor("Splits", splits);
mat.setFloat("ShadowMapSize", shadowMapSize);
for (int j = 0; j < nbSplits; j++) {
mat.setMatrix4("LightViewProjectionMatrix" + j, lightViewProjectionsMatrices[j]);
}
for (int j = 0; j < nbSplits; 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);
if (fadeInfo != null) {
mat.setVector2("FadeInfo", fadeInfo);
}
}
applyHWShadows = false;
applyFilterMode = false;
applyPCFEdge = false;
applyShadowIntensity = false;
applyFadeInfo = false;
//so we fall back to the forced material solution (transparent shadows won't be supported for these objects)
if (needsfallBackMaterial) {
setPostShadowParams();
}
}
use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.
the class ShadowUtil method getGeometriesInCamFrustum.
/**
* Populates the outputGeometryList with the geometry of the
* inputGeomtryList that are in the frustum of the given camera
*
* @param inputGeometryList The list containing all geometry to check
* against the camera frustum
* @param camera the camera to check geometries against
* @param outputGeometryList the list of all geometries that are in the
* camera frustum
*/
public static void getGeometriesInCamFrustum(GeometryList inputGeometryList, Camera camera, GeometryList outputGeometryList) {
for (int i = 0; i < inputGeometryList.size(); i++) {
Geometry g = inputGeometryList.get(i);
int planeState = camera.getPlaneState();
camera.setPlaneState(0);
if (camera.contains(g.getWorldBound()) != Camera.FrustumIntersect.Outside) {
outputGeometryList.add(g);
}
camera.setPlaneState(planeState);
}
}
use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.
the class ShadowUtil method addGeometriesInCamFrustumAndViewPortFromNode.
/**
* Helper function to recursively collect the geometries for getLitGeometriesInViewPort function.
*
* @param vpCamera the viewPort camera
* @param cameras the camera array to check geometries against, representing the light viewspace
* @param scene the Node to traverse or geometry to possibly add
* @param outputGeometryList the output list of all geometries that are in the camera frustum
*/
private static void addGeometriesInCamFrustumAndViewPortFromNode(Camera vpCamera, Camera[] cameras, Spatial scene, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) {
if (scene.getCullHint() == Spatial.CullHint.Always)
return;
boolean inFrustum = false;
for (int j = 0; j < cameras.length && inFrustum == false; j++) {
Camera camera = cameras[j];
int planeState = camera.getPlaneState();
camera.setPlaneState(0);
inFrustum = camera.contains(scene.getWorldBound()) != Camera.FrustumIntersect.Outside && scene.checkCulling(vpCamera);
camera.setPlaneState(planeState);
}
if (inFrustum) {
if (scene instanceof Node) {
Node node = (Node) scene;
for (Spatial child : node.getChildren()) {
addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, child, mode, outputGeometryList);
}
} else if (scene instanceof Geometry) {
if (checkShadowMode(scene.getShadowMode(), mode) && !((Geometry) scene).isGrouped()) {
outputGeometryList.add((Geometry) scene);
}
}
}
}
use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.
the class ShadowUtil method updateShadowCamera.
/**
* Updates the shadow camera to properly contain the given points (which
* contain the eye camera frustum corners) and the shadow occluder objects
* collected through the traverse of the scene hierarchy
*/
public static void updateShadowCamera(ViewPort viewPort, GeometryList receivers, Camera shadowCam, Vector3f[] points, GeometryList splitOccluders, float shadowMapSize) {
boolean ortho = shadowCam.isParallelProjection();
shadowCam.setProjectionMatrix(null);
if (ortho) {
shadowCam.setFrustum(-shadowCam.getFrustumFar(), shadowCam.getFrustumFar(), -1, 1, 1, -1);
}
// create transform to rotate points to viewspace
Matrix4f viewProjMatrix = shadowCam.getViewProjectionMatrix();
BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);
TempVars vars = TempVars.get();
BoundingBox casterBB = new BoundingBox();
BoundingBox receiverBB = new BoundingBox();
int casterCount = 0, receiverCount = 0;
for (int i = 0; i < receivers.size(); i++) {
// convert bounding box to light's viewproj space
Geometry receiver = receivers.get(i);
BoundingVolume bv = receiver.getWorldBound();
BoundingVolume recvBox = bv.transform(viewProjMatrix, vars.bbox);
if (splitBB.intersects(recvBox)) {
//Nehon : prevent NaN and infinity values to screw the final bounding box
if (!Float.isNaN(recvBox.getCenter().x) && !Float.isInfinite(recvBox.getCenter().x)) {
receiverBB.mergeLocal(recvBox);
receiverCount++;
}
}
}
// collect splitOccluders through scene recursive traverse
OccludersExtractor occExt = new OccludersExtractor(viewProjMatrix, casterCount, splitBB, casterBB, splitOccluders, vars);
for (Spatial scene : viewPort.getScenes()) {
occExt.addOccluders(scene);
}
casterCount = occExt.casterCount;
//Nehon 08/18/2010 this is to avoid shadow bleeding when the ground is set to only receive shadows
if (casterCount != receiverCount) {
casterBB.setXExtent(casterBB.getXExtent() + 2.0f);
casterBB.setYExtent(casterBB.getYExtent() + 2.0f);
casterBB.setZExtent(casterBB.getZExtent() + 2.0f);
}
Vector3f casterMin = casterBB.getMin(vars.vect1);
Vector3f casterMax = casterBB.getMax(vars.vect2);
Vector3f receiverMin = receiverBB.getMin(vars.vect3);
Vector3f receiverMax = receiverBB.getMax(vars.vect4);
Vector3f splitMin = splitBB.getMin(vars.vect5);
Vector3f splitMax = splitBB.getMax(vars.vect6);
splitMin.z = 0;
// if (!ortho) {
// shadowCam.setFrustumPerspective(45, 1, 1, splitMax.z);
// }
Matrix4f projMatrix = shadowCam.getProjectionMatrix();
Vector3f cropMin = vars.vect7;
Vector3f cropMax = vars.vect8;
// IMPORTANT: Special handling for Z values
cropMin.x = max(max(casterMin.x, receiverMin.x), splitMin.x);
cropMax.x = min(min(casterMax.x, receiverMax.x), splitMax.x);
cropMin.y = max(max(casterMin.y, receiverMin.y), splitMin.y);
cropMax.y = min(min(casterMax.y, receiverMax.y), splitMax.y);
cropMin.z = min(casterMin.z, splitMin.z);
cropMax.z = min(receiverMax.z, splitMax.z);
// Create the crop matrix.
float scaleX, scaleY, scaleZ;
float offsetX, offsetY, offsetZ;
scaleX = (2.0f) / (cropMax.x - cropMin.x);
scaleY = (2.0f) / (cropMax.y - cropMin.y);
//Shadow map stabilization approximation from shaderX 7
//from Practical Cascaded Shadow maps adapted to PSSM
//scale stabilization
float halfTextureSize = shadowMapSize * 0.5f;
if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
float scaleQuantizer = 0.1f;
scaleX = 1.0f / FastMath.ceil(1.0f / scaleX * scaleQuantizer) * scaleQuantizer;
scaleY = 1.0f / FastMath.ceil(1.0f / scaleY * scaleQuantizer) * scaleQuantizer;
}
offsetX = -0.5f * (cropMax.x + cropMin.x) * scaleX;
offsetY = -0.5f * (cropMax.y + cropMin.y) * scaleY;
//offset stabilization
if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
offsetX = FastMath.ceil(offsetX * halfTextureSize) / halfTextureSize;
offsetY = FastMath.ceil(offsetY * halfTextureSize) / halfTextureSize;
}
scaleZ = 1.0f / (cropMax.z - cropMin.z);
offsetZ = -cropMin.z * scaleZ;
Matrix4f cropMatrix = vars.tempMat4;
cropMatrix.set(scaleX, 0f, 0f, offsetX, 0f, scaleY, 0f, offsetY, 0f, 0f, scaleZ, offsetZ, 0f, 0f, 0f, 1f);
Matrix4f result = new Matrix4f();
result.set(cropMatrix);
result.multLocal(projMatrix);
vars.release();
shadowCam.setProjectionMatrix(result);
}
use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.
the class DirectionalLightShadowRenderer method getOccludersToRender.
@Override
protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) {
// update frustum points based on current camera and split
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), splitsArray[shadowMapIndex], splitsArray[shadowMapIndex + 1], 1.0f, points);
//Updating shadow cam with curent split frustra
if (lightReceivers.size() == 0) {
for (Spatial scene : viewPort.getScenes()) {
ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers);
}
}
ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, shadowMapOccluders, stabilize ? shadowMapSize : 0);
return shadowMapOccluders;
}
Aggregations