Merge remote-tracking branch 'origin/master' into in-pass-shadows

in-pass-shadows
Kirill Vainer 7 years ago
commit fca6d4a8b2
  1. 4
      jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler14.java
  2. 18
      jme3-core/src/main/java/com/jme3/environment/util/EnvMapUtils.java
  3. 16
      jme3-core/src/main/java/com/jme3/light/LightProbe.java
  4. 20
      jme3-core/src/main/java/com/jme3/material/MatParam.java
  5. 3
      jme3-core/src/main/java/com/jme3/scene/Geometry.java
  6. 16
      jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag
  7. 3
      jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md
  8. 44
      jme3-core/src/plugins/java/com/jme3/shader/plugins/GLSLLoader.java
  9. 112
      jme3-core/src/test/java/com/jme3/collision/CollideIgnoreTransformTest.java
  10. BIN
      jme3-testdata/src/main/resources/Scenes/defaultProbe.j3o

@ -139,8 +139,10 @@ public class AndroidInputHandler14 extends AndroidInputHandler implements View.O
boolean isJoystick = boolean isJoystick =
((source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK); ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK);
boolean isUnknown =
(source & android.view.InputDevice.SOURCE_UNKNOWN) == android.view.InputDevice.SOURCE_UNKNOWN;
if (isTouch && touchInput != null) { if (touchInput != null && (isTouch || (isUnknown && this.touchInput.isSimulateKeyboard()))) {
// logger.log(Level.INFO, "onKey source: {0}, isTouch: {1}", // logger.log(Level.INFO, "onKey source: {0}, isTouch: {1}",
// new Object[]{source, isTouch}); // new Object[]{source, isTouch});
consumed = touchInput.onKey(event); consumed = touchInput.onKey(event);

@ -509,15 +509,15 @@ public class EnvMapUtils {
float coef7 = coef5; float coef7 = coef5;
float coef8 = sqrt15Pi / 4f; float coef8 = sqrt15Pi / 4f;
shCoefs[0].multLocal(coef0); shCoefs[0].multLocal(coef0).multLocal(shBandFactor[0]);
shCoefs[1].multLocal(coef1); shCoefs[1].multLocal(coef1).multLocal(shBandFactor[1]);
shCoefs[2].multLocal(coef2); shCoefs[2].multLocal(coef2).multLocal(shBandFactor[2]);
shCoefs[3].multLocal(coef3); shCoefs[3].multLocal(coef3).multLocal(shBandFactor[3]);
shCoefs[4].multLocal(coef4); shCoefs[4].multLocal(coef4).multLocal(shBandFactor[4]);
shCoefs[5].multLocal(coef5); shCoefs[5].multLocal(coef5).multLocal(shBandFactor[5]);
shCoefs[6].multLocal(coef6); shCoefs[6].multLocal(coef6).multLocal(shBandFactor[6]);
shCoefs[7].multLocal(coef7); shCoefs[7].multLocal(coef7).multLocal(shBandFactor[7]);
shCoefs[8].multLocal(coef8); shCoefs[8].multLocal(coef8).multLocal(shBandFactor[8]);
} }

@ -120,20 +120,32 @@ public class LightProbe extends Light implements Savable {
oc.write(position, "position", null); oc.write(position, "position", null);
oc.write(bounds, "bounds", new BoundingSphere(1.0f, Vector3f.ZERO)); oc.write(bounds, "bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
oc.write(ready, "ready", false); oc.write(ready, "ready", false);
oc.write(nbMipMaps, "nbMipMaps", 0);
} }
@Override @Override
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
shCoeffs = (Vector3f[]) ic.readSavableArray("shCoeffs", null);
prefilteredEnvMap = (TextureCubeMap) ic.readSavable("prefilteredEnvMap", null); prefilteredEnvMap = (TextureCubeMap) ic.readSavable("prefilteredEnvMap", null);
position = (Vector3f) ic.readSavable("position", this); position = (Vector3f) ic.readSavable("position", this);
bounds = (BoundingVolume) ic.readSavable("bounds", new BoundingSphere(1.0f, Vector3f.ZERO)); bounds = (BoundingVolume) ic.readSavable("bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
nbMipMaps = ic.readInt("nbMipMaps", 0);
ready = ic.readBoolean("ready", false); ready = ic.readBoolean("ready", false);
if (shCoeffs == null) {
Savable[] coeffs = ic.readSavableArray("shCoeffs", null);
if (coeffs == null) {
ready = false; ready = false;
logger.log(Level.WARNING, "LightProbe is missing parameters, it should be recomputed. Please use lightProbeFactory.updateProbe()"); logger.log(Level.WARNING, "LightProbe is missing parameters, it should be recomputed. Please use lightProbeFactory.updateProbe()");
} else {
shCoeffs = new Vector3f[coeffs.length];
for (int i = 0; i < coeffs.length; i++) {
shCoeffs[i] = (Vector3f) coeffs[i];
}
} }
} }

@ -37,6 +37,7 @@ import com.jme3.math.*;
import com.jme3.shader.VarType; import com.jme3.shader.VarType;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode; import com.jme3.texture.Texture.WrapMode;
import java.io.IOException; import java.io.IOException;
/** /**
@ -301,20 +302,21 @@ When arrays can be inserted in J3M files
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.write(type, "varType", null); oc.write(type, "varType", null);
oc.write(name, "name", null); oc.write(name, "name", null);
if (value == null) {
return;
}
if (value instanceof Savable) { if (value instanceof Savable) {
Savable s = (Savable) value; oc.write((Savable) value, "value_savable", null);
oc.write(s, "value_savable", null);
} else if (value instanceof Float) { } else if (value instanceof Float) {
Float f = (Float) value; oc.write((Float) value, "value_float", 0f);
oc.write(f.floatValue(), "value_float", 0f);
} else if (value instanceof Integer) { } else if (value instanceof Integer) {
Integer i = (Integer) value; oc.write((Integer) value, "value_int", 0);
oc.write(i.intValue(), "value_int", 0);
} else if (value instanceof Boolean) { } else if (value instanceof Boolean) {
Boolean b = (Boolean) value; oc.write((Boolean) value, "value_bool", false);
oc.write(b.booleanValue(), "value_bool", false);
} else if (value.getClass().isArray() && value instanceof Savable[]) { } else if (value.getClass().isArray() && value instanceof Savable[]) {
oc.write((Savable[])value, "value_savable_array", null); oc.write((Savable[]) value, "value_savable_array", null);
} }
} }

@ -398,6 +398,9 @@ public class Geometry extends Spatial {
// Compute the cached world matrix // Compute the cached world matrix
cachedWorldMat.loadIdentity(); cachedWorldMat.loadIdentity();
if (ignoreTransform) {
return;
}
cachedWorldMat.setRotationQuaternion(worldTransform.getRotation()); cachedWorldMat.setRotationQuaternion(worldTransform.getRotation());
cachedWorldMat.setTranslation(worldTransform.getTranslation()); cachedWorldMat.setTranslation(worldTransform.getTranslation());

@ -91,8 +91,10 @@ void main(){
vec2 newTexCoord; vec2 newTexCoord;
vec3 viewDir = normalize(g_CameraPosition - wPosition); vec3 viewDir = normalize(g_CameraPosition - wPosition);
vec3 norm = normalize(wNormal);
#if defined(NORMALMAP) || defined(PARALLAXMAP) #if defined(NORMALMAP) || defined(PARALLAXMAP)
mat3 tbnMat = mat3(wTangent.xyz, wTangent.w * cross( (wNormal), (wTangent.xyz)), wNormal.xyz); vec3 tan = normalize(wTangent.xyz);
mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm);
#endif #endif
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
@ -126,13 +128,13 @@ void main(){
#ifdef USE_PACKED_MR #ifdef USE_PACKED_MR
vec2 rm = texture2D(m_MetallicRoughnessMap, newTexCoord).gb; vec2 rm = texture2D(m_MetallicRoughnessMap, newTexCoord).gb;
float Roughness = rm.x * max(m_Roughness, 1e-8); float Roughness = rm.x * max(m_Roughness, 1e-4);
float Metallic = rm.y * max(m_Metallic, 0.0); float Metallic = rm.y * max(m_Metallic, 0.0);
#else #else
#ifdef ROUGHNESSMAP #ifdef ROUGHNESSMAP
float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-8); float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4);
#else #else
float Roughness = max(m_Roughness, 1e-8); float Roughness = max(m_Roughness, 1e-4);
#endif #endif
#ifdef METALLICMAP #ifdef METALLICMAP
float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0);
@ -162,7 +164,7 @@ void main(){
normal = normalize(tbnMat * normal); normal = normalize(tbnMat * normal);
//normal = normalize(normal * inverse(tbnMat)); //normal = normalize(normal * inverse(tbnMat));
#else #else
vec3 normal = normalize(wNormal); vec3 normal = norm;
#endif #endif
float specular = 0.5; float specular = 0.5;
@ -185,7 +187,7 @@ void main(){
#endif #endif
specularColor *= m_Specular; specularColor *= m_Specular;
#endif #endif
vec4 diffuseColor = albedo * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b));
Roughness = 1.0 - glossiness; Roughness = 1.0 - glossiness;
#else #else
float nonMetalSpec = 0.08 * specular; float nonMetalSpec = 0.08 * specular;
@ -250,7 +252,7 @@ void main(){
rv = invRadius * (wPosition - g_LightProbeData.xyz) +rv; rv = invRadius * (wPosition - g_LightProbeData.xyz) +rv;
//horizon fade from http://marmosetco.tumblr.com/post/81245981087 //horizon fade from http://marmosetco.tumblr.com/post/81245981087
float horiz = dot(rv, wNormal.xyz); float horiz = dot(rv, norm);
float horizFadePower = 1.0 - Roughness; float horizFadePower = 1.0 - Roughness;
horiz = clamp( 1.0 + horizFadePower * horiz, 0.0, 1.0 ); horiz = clamp( 1.0 + horizFadePower * horiz, 0.0, 1.0 );
horiz *= horiz; horiz *= horiz;

@ -288,9 +288,6 @@ MaterialDef PBR Lighting {
Defines { Defines {
NEED_TEXCOORD1 NEED_TEXCOORD1
HAS_GLOWMAP : GlowMap
HAS_GLOWCOLOR : GlowColor
NUM_BONES : NumberOfBones NUM_BONES : NumberOfBones
INSTANCING : UseInstancing INSTANCING : UseInstancing
} }

@ -31,12 +31,9 @@
*/ */
package com.jme3.shader.plugins; package com.jme3.shader.plugins;
import com.jme3.asset.AssetInfo; import com.jme3.asset.*;
import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetLoadException;
import com.jme3.asset.AssetLoader;
import com.jme3.asset.AssetManager;
import com.jme3.asset.cache.AssetCache; import com.jme3.asset.cache.AssetCache;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -49,7 +46,7 @@ import java.util.*;
public class GLSLLoader implements AssetLoader { public class GLSLLoader implements AssetLoader {
private AssetManager assetManager; private AssetManager assetManager;
private final Map<String, ShaderDependencyNode> dependCache = new HashMap<>(); private Map<String, ShaderDependencyNode> dependCache = new HashMap<>();
/** /**
* Used to load {@link ShaderDependencyNode}s. * Used to load {@link ShaderDependencyNode}s.
@ -70,25 +67,27 @@ public class GLSLLoader implements AssetLoader {
/** /**
* Creates a {@link ShaderDependencyNode} from a stream representing shader code. * Creates a {@link ShaderDependencyNode} from a stream representing shader code.
* *
* @param in The input stream containing shader code * @param reader the reader with shader code
* @param nodeName * @param nodeName the node name.
* @return * @return the shader dependency node
* @throws IOException * @throws AssetLoadException if we failed to load the shader code.
*/ */
private ShaderDependencyNode loadNode(Reader reader, String nodeName) { private ShaderDependencyNode loadNode(Reader reader, String nodeName) {
ShaderDependencyNode node = new ShaderDependencyNode(nodeName);
ShaderDependencyNode node = new ShaderDependencyNode(nodeName);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
StringBuilder sbExt = new StringBuilder(); StringBuilder sbExt = new StringBuilder();
BufferedReader bufReader = null;
try { try (final BufferedReader bufferedReader = new BufferedReader(reader)) {
bufReader = new BufferedReader(reader);
String ln; String ln;
if (!nodeName.equals("[main]")) { if (!nodeName.equals("[main]")) {
sb.append("// -- begin import ").append(nodeName).append(" --\n"); sb.append("// -- begin import ").append(nodeName).append(" --\n");
} }
while ((ln = bufReader.readLine()) != null) {
while ((ln = bufferedReader.readLine()) != null) {
if (ln.trim().startsWith("#import ")) { if (ln.trim().startsWith("#import ")) {
ln = ln.trim().substring(8).trim(); ln = ln.trim().substring(8).trim();
if (ln.startsWith("\"") && ln.endsWith("\"") && ln.length() > 3) { if (ln.startsWith("\"") && ln.endsWith("\"") && ln.length() > 3) {
@ -118,13 +117,7 @@ public class GLSLLoader implements AssetLoader {
if (!nodeName.equals("[main]")) { if (!nodeName.equals("[main]")) {
sb.append("// -- end import ").append(nodeName).append(" --\n"); sb.append("// -- end import ").append(nodeName).append(" --\n");
} }
} catch (IOException ex) { } catch (final IOException ex) {
if (bufReader != null) {
try {
bufReader.close();
} catch (IOException ex1) {
}
}
throw new AssetLoadException("Failed to load shader node: " + nodeName, ex); throw new AssetLoadException("Failed to load shader node: " + nodeName, ex);
} }
@ -137,7 +130,7 @@ public class GLSLLoader implements AssetLoader {
private ShaderDependencyNode nextIndependentNode() throws IOException { private ShaderDependencyNode nextIndependentNode() throws IOException {
Collection<ShaderDependencyNode> allNodes = dependCache.values(); Collection<ShaderDependencyNode> allNodes = dependCache.values();
if (allNodes == null || allNodes.isEmpty()) { if (allNodes.isEmpty()) {
return null; return null;
} }
@ -182,8 +175,9 @@ public class GLSLLoader implements AssetLoader {
} }
} }
@Override
public Object load(AssetInfo info) throws IOException { public Object load(AssetInfo info) throws IOException {
// The input stream provided is for the vertex shader, // The input stream provided is for the vertex shader,
// to retrieve the fragment shader, use the content manager // to retrieve the fragment shader, use the content manager
this.assetManager = info.getManager(); this.assetManager = info.getManager();
Reader reader = new InputStreamReader(info.openStream()); Reader reader = new InputStreamReader(info.openStream());

@ -0,0 +1,112 @@
/*
* Copyright (c) 2017 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.jme3.collision;
import com.jme3.asset.AssetManager;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.material.Material;
import com.jme3.material.plugins.J3MLoader;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import org.junit.Test;
/**
* Verify that collideWith() works with ignoreTransforms. This was issue #744 at
* GitHub.
*
* @author Stephen Gold
*/
public class CollideIgnoreTransformTest {
AssetManager assetManager;
Node rootNode;
/**
* Cast a ray at the geometry and check the number of collisions.
*/
void castRay(Ray ray, int expectedNumResults) {
CollisionResults results = new CollisionResults();
rootNode.collideWith(ray, results);
int numResults = results.size();
if (numResults != expectedNumResults) {
String msg = String.format("Expected %d, got %d.",
expectedNumResults, numResults);
throw new RuntimeException(msg);
}
}
/**
* Attach a red square in the XY plane with its lower left corner at (0, 0,
* 0). It is composed of 2 triangles.
*/
void createRedSquare() {
Mesh quadMesh = new Quad(1f, 1f);
Geometry redSquare = new Geometry("red square", quadMesh);
Material red = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
redSquare.setMaterial(red);
rootNode.attachChild(redSquare);
redSquare.setLocalTranslation(0f, 3f, 0f);
redSquare.setIgnoreTransform(true);
}
@Test
public void testPhantomTriangles() {
assetManager = new DesktopAssetManager();
assetManager.registerLocator(null, ClasspathLocator.class);
assetManager.registerLoader(J3MLoader.class, "j3m", "j3md");
rootNode = new Node();
createRedSquare();
rootNode.updateLogicalState(0.01f);
rootNode.updateGeometricState();
/**
* ray in the -Z direction, starting from (0.5, 0.6, 10)
*/
Ray ray1 = new Ray(/* origin */new Vector3f(0.5f, 0.6f, 10f),
/* direction */ new Vector3f(0f, 0f, -1f));
castRay(ray1, 1);
/**
* ray in the -Z direction, starting from (0.5, 3, 10)
*/
Ray ray0 = new Ray(/* origin */new Vector3f(0.5f, 3f, 10f),
/* direction */ new Vector3f(0f, 0f, -1f));
castRay(ray0, 0);
}
}
Loading…
Cancel
Save