Implemented texture loading and PBR metalness/roughness pipeline support
Fixed some mesh loading issues.
This commit is contained in:
parent
3bbfabed5e
commit
40c4f7936d
@ -9,9 +9,7 @@ varying vec2 texCoord;
|
|||||||
varying vec2 texCoord2;
|
varying vec2 texCoord2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BASECOLORMAP
|
varying vec4 Color;
|
||||||
varying vec4 Color;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform vec4 g_LightData[NB_LIGHTS];
|
uniform vec4 g_LightData[NB_LIGHTS];
|
||||||
|
|
||||||
@ -33,11 +31,16 @@ varying vec3 wPosition;
|
|||||||
#ifdef BASECOLORMAP
|
#ifdef BASECOLORMAP
|
||||||
uniform sampler2D m_BaseColorMap;
|
uniform sampler2D m_BaseColorMap;
|
||||||
#endif
|
#endif
|
||||||
#ifdef METALLICMAP
|
|
||||||
uniform sampler2D m_MetallicMap;
|
#ifdef USE_PACKED_MR
|
||||||
#endif
|
uniform sampler2D m_MetallicRoughnessMap;
|
||||||
#ifdef ROUGHNESSMAP
|
#else
|
||||||
uniform sampler2D m_RoughnessMap;
|
#ifdef METALLICMAP
|
||||||
|
uniform sampler2D m_MetallicMap;
|
||||||
|
#endif
|
||||||
|
#ifdef ROUGHNESSMAP
|
||||||
|
uniform sampler2D m_RoughnessMap;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMISSIVE
|
#ifdef EMISSIVE
|
||||||
@ -109,19 +112,26 @@ void main(){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BASECOLORMAP
|
#ifdef BASECOLORMAP
|
||||||
vec4 albedo = texture2D(m_BaseColorMap, newTexCoord);
|
vec4 albedo = texture2D(m_BaseColorMap, newTexCoord) * Color;
|
||||||
#else
|
#else
|
||||||
vec4 albedo = Color;
|
vec4 albedo = Color;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ROUGHNESSMAP
|
|
||||||
float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-8);
|
#ifdef USE_PACKED_MR
|
||||||
|
vec2 rm = texture2D(m_MetallicRoughnessMap, newTexCoord).gb;
|
||||||
|
float Roughness = rm.x * max(m_Roughness, 1e-8);
|
||||||
|
float Metallic = rm.y * max(m_Metallic, 0.0);
|
||||||
#else
|
#else
|
||||||
float Roughness = max(m_Roughness, 1e-8);
|
#ifdef ROUGHNESSMAP
|
||||||
#endif
|
float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-8);
|
||||||
#ifdef METALLICMAP
|
#else
|
||||||
float Metallic = texture2D(m_MetallicMap, newTexCoord).r;
|
float Roughness = max(m_Roughness, 1e-8);
|
||||||
#else
|
#endif
|
||||||
float Metallic = max(m_Metallic, 0.0);
|
#ifdef METALLICMAP
|
||||||
|
float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0);
|
||||||
|
#else
|
||||||
|
float Metallic = max(m_Metallic, 0.0);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float alpha = albedo.a;
|
float alpha = albedo.a;
|
||||||
@ -141,7 +151,7 @@ void main(){
|
|||||||
//as it's complient with normal maps generated with blender.
|
//as it's complient with normal maps generated with blender.
|
||||||
//see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
|
//see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
|
||||||
//for more explanation.
|
//for more explanation.
|
||||||
vec3 normal = normalize((normalHeight.xyz * vec3(2.0,-2.0,2.0) - vec3(1.0,-1.0,1.0)));
|
vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)));
|
||||||
normal = normalize(tbnMat * normal);
|
normal = normalize(tbnMat * normal);
|
||||||
//normal = normalize(normal * inverse(tbnMat));
|
//normal = normalize(normal * inverse(tbnMat));
|
||||||
#else
|
#else
|
||||||
@ -239,5 +249,4 @@ void main(){
|
|||||||
|
|
||||||
gl_FragColor.a = alpha;
|
gl_FragColor.a = alpha;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,33 +6,39 @@ MaterialDef PBR Lighting {
|
|||||||
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
||||||
|
|
||||||
//metalness of the material
|
//metalness of the material
|
||||||
Float Metallic : 0.0
|
Float Metallic : 1.0
|
||||||
//Roughness of the material
|
//Roughness of the material
|
||||||
Float Roughness : 1.0
|
Float Roughness : 1.0
|
||||||
// Base material color
|
// Base material color
|
||||||
Color BaseColor
|
Color BaseColor : 1.0 1.0 1.0 1.0
|
||||||
// The emissive color of the object
|
// The emissive color of the object
|
||||||
Color Emissive
|
Color Emissive
|
||||||
// the emissive power
|
// the emissive power
|
||||||
Float EmissivePower : 3.0
|
Float EmissivePower : 3.0
|
||||||
// the emissive intensity
|
// the emissive intensity
|
||||||
Float EmissiveIntensity : 1.0
|
Float EmissiveIntensity : 2.0
|
||||||
|
|
||||||
// BaseColor map
|
// BaseColor map
|
||||||
Texture2D BaseColorMap
|
Texture2D BaseColorMap
|
||||||
|
|
||||||
// Specular/gloss map
|
// Metallic map
|
||||||
Texture2D MetallicMap -LINEAR
|
Texture2D MetallicMap -LINEAR
|
||||||
|
|
||||||
// Roughness Map
|
// Roughness Map
|
||||||
Texture2D RoughnessMap -LINEAR
|
Texture2D RoughnessMap -LINEAR
|
||||||
|
|
||||||
|
//Metallic and Roughness are packed respectively in the b and g channel of a single map
|
||||||
|
Texture2D MetallicRoughnessMap -LINEAR
|
||||||
|
|
||||||
// Texture of the emissive parts of the material
|
// Texture of the emissive parts of the material
|
||||||
Texture2D EmissiveMap
|
Texture2D EmissiveMap
|
||||||
|
|
||||||
// Normal map
|
// Normal map
|
||||||
Texture2D NormalMap -LINEAR
|
Texture2D NormalMap -LINEAR
|
||||||
|
|
||||||
|
//The type of normal map: -1.0 (DirectX), 1.0 (OpenGl)
|
||||||
|
Float NormalType : -1.0
|
||||||
|
|
||||||
// For Spec gloss pipeline
|
// For Spec gloss pipeline
|
||||||
Texture2D SpecularMap
|
Texture2D SpecularMap
|
||||||
Texture2D GlossMap
|
Texture2D GlossMap
|
||||||
@ -138,7 +144,8 @@ MaterialDef PBR Lighting {
|
|||||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
NUM_BONES : NumberOfBones
|
NUM_BONES : NumberOfBones
|
||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
//INDIRECT_LIGHTING : IntegrateBRDF
|
USE_PACKED_MR: MetallicRoughnessMap
|
||||||
|
NORMAL_TYPE: NormalType
|
||||||
VERTEX_COLOR : UseVertexColor
|
VERTEX_COLOR : UseVertexColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,7 @@ varying vec2 texCoord;
|
|||||||
attribute vec2 inTexCoord2;
|
attribute vec2 inTexCoord2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BASECOLORMAP
|
varying vec4 Color;
|
||||||
varying vec4 Color;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute vec3 inPosition;
|
attribute vec3 inPosition;
|
||||||
attribute vec2 inTexCoord;
|
attribute vec2 inTexCoord;
|
||||||
@ -61,9 +59,7 @@ void main(){
|
|||||||
wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w);
|
wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BASECOLORMAP
|
Color = m_BaseColor;
|
||||||
Color = m_BaseColor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VERTEX_COLOR
|
#ifdef VERTEX_COLOR
|
||||||
Color *= inColor;
|
Color *= inColor;
|
||||||
|
@ -143,7 +143,7 @@ vec3 ApproximateSpecularIBL(samplerCube envMap,sampler2D integrateBRDF, vec3 Spe
|
|||||||
|
|
||||||
vec3 ApproximateSpecularIBLPolynomial(samplerCube envMap, vec3 SpecularColor , float Roughness, float ndotv, vec3 refVec){
|
vec3 ApproximateSpecularIBLPolynomial(samplerCube envMap, vec3 SpecularColor , float Roughness, float ndotv, vec3 refVec){
|
||||||
//TODO magic values should be replaced by defines.
|
//TODO magic values should be replaced by defines.
|
||||||
float Lod = log2(Roughness) * 1.5 + 6.0 - 1.0;
|
float Lod = log2(Roughness) * 1.6 + 5.0;
|
||||||
vec3 PrefilteredColor = textureCubeLod(envMap, refVec.xyz, Lod).rgb;
|
vec3 PrefilteredColor = textureCubeLod(envMap, refVec.xyz, Lod).rgb;
|
||||||
return PrefilteredColor * EnvDFGPolynomial(SpecularColor, Roughness, ndotv);
|
return PrefilteredColor * EnvDFGPolynomial(SpecularColor, Roughness, ndotv);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import com.jme3.material.RenderState;
|
|||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
import com.jme3.renderer.queue.RenderQueue;
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
import com.jme3.scene.*;
|
import com.jme3.scene.*;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
@ -35,6 +37,9 @@ public class GltfLoader implements AssetLoader {
|
|||||||
private JsonArray bufferViews;
|
private JsonArray bufferViews;
|
||||||
private JsonArray buffers;
|
private JsonArray buffers;
|
||||||
private JsonArray materials;
|
private JsonArray materials;
|
||||||
|
private JsonArray textures;
|
||||||
|
private JsonArray images;
|
||||||
|
private JsonArray samplers;
|
||||||
private Material defaultMat;
|
private Material defaultMat;
|
||||||
private AssetInfo info;
|
private AssetInfo info;
|
||||||
|
|
||||||
@ -75,6 +80,9 @@ public class GltfLoader implements AssetLoader {
|
|||||||
bufferViews = root.getAsJsonArray("bufferViews");
|
bufferViews = root.getAsJsonArray("bufferViews");
|
||||||
buffers = root.getAsJsonArray("buffers");
|
buffers = root.getAsJsonArray("buffers");
|
||||||
materials = root.getAsJsonArray("materials");
|
materials = root.getAsJsonArray("materials");
|
||||||
|
textures = root.getAsJsonArray("textures");
|
||||||
|
images = root.getAsJsonArray("images");
|
||||||
|
samplers = root.getAsJsonArray("samplers");
|
||||||
|
|
||||||
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
||||||
|
|
||||||
@ -123,9 +131,11 @@ public class GltfLoader implements AssetLoader {
|
|||||||
activeChild = defaultScene.getAsInt();
|
activeChild = defaultScene.getAsInt();
|
||||||
}
|
}
|
||||||
root.getChild(activeChild).setCullHint(Spatial.CullHint.Inherit);
|
root.getChild(activeChild).setCullHint(Spatial.CullHint.Inherit);
|
||||||
|
System.err.println(nbPrim + " Geoms loaded");
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nbPrim = 0;
|
||||||
private Spatial loadNode(int nodeIndex) throws IOException {
|
private Spatial loadNode(int nodeIndex) throws IOException {
|
||||||
Spatial spatial = fetchFromCache("nodes", nodeIndex, Spatial.class);
|
Spatial spatial = fetchFromCache("nodes", nodeIndex, Spatial.class);
|
||||||
if (spatial != null) {
|
if (spatial != null) {
|
||||||
@ -134,20 +144,18 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return spatial.clone();
|
return spatial.clone();
|
||||||
}
|
}
|
||||||
JsonObject nodeData = nodes.get(nodeIndex).getAsJsonObject();
|
JsonObject nodeData = nodes.get(nodeIndex).getAsJsonObject();
|
||||||
|
JsonArray children = nodeData.getAsJsonArray("children");
|
||||||
Integer meshIndex = getAsInteger(nodeData, "mesh");
|
Integer meshIndex = getAsInteger(nodeData, "mesh");
|
||||||
if (meshIndex != null) {
|
if (meshIndex != null) {
|
||||||
if (meshes == null) {
|
if (meshes == null) {
|
||||||
throw new AssetLoadException("Can't find any mesh data, yet a node references a mesh");
|
throw new AssetLoadException("Can't find any mesh data, yet a node references a mesh");
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO material
|
|
||||||
Material mat = defaultMat;
|
|
||||||
|
|
||||||
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
||||||
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
||||||
Geometry[] primitives = loadMeshPrimitives(meshIndex);
|
Geometry[] primitives = loadMeshPrimitives(meshIndex);
|
||||||
if (primitives.length > 1) {
|
if (primitives.length == 1 && children == null) {
|
||||||
//only one geometry, let's not wrap it in another node.
|
//only one geometry, let's not wrap it in another node unless the node has children.
|
||||||
spatial = primitives[0];
|
spatial = primitives[0];
|
||||||
} else {
|
} else {
|
||||||
//several geometries, let's make a parent Node and attach them to it
|
//several geometries, let's make a parent Node and attach them to it
|
||||||
@ -157,21 +165,23 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
spatial = node;
|
spatial = node;
|
||||||
}
|
}
|
||||||
|
nbPrim += primitives.length;
|
||||||
spatial.setName(loadMeshName(meshIndex));
|
spatial.setName(loadMeshName(meshIndex));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//no mesh, we have a node. Can be a camera node or a regular node.
|
//no mesh, we have a node. Can be a camera node or a regular node.
|
||||||
//TODO handle camera nodes?
|
//TODO handle camera nodes?
|
||||||
Node node = new Node();
|
Node node = new Node();
|
||||||
JsonArray children = nodeData.getAsJsonArray("children");
|
|
||||||
if (children != null) {
|
|
||||||
for (JsonElement child : children) {
|
|
||||||
node.attachChild(loadNode(child.getAsInt()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spatial = node;
|
spatial = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (children != null) {
|
||||||
|
for (JsonElement child : children) {
|
||||||
|
((Node) spatial).attachChild(loadNode(child.getAsInt()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (spatial.getName() == null) {
|
if (spatial.getName() == null) {
|
||||||
spatial.setName(getAsString(nodeData.getAsJsonObject(), "name"));
|
spatial.setName(getAsString(nodeData.getAsJsonObject(), "name"));
|
||||||
}
|
}
|
||||||
@ -236,6 +246,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
if (primitives == null) {
|
if (primitives == null) {
|
||||||
throw new AssetLoadException("Can't find any primitives in mesh " + meshIndex);
|
throw new AssetLoadException("Can't find any primitives in mesh " + meshIndex);
|
||||||
}
|
}
|
||||||
|
String name = getAsString(meshData, "name");
|
||||||
|
|
||||||
geomArray = new Geometry[primitives.size()];
|
geomArray = new Geometry[primitives.size()];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -267,11 +278,15 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
geom.setName(name + (primitives.size() > 1 ? ("_" + index) : ""));
|
||||||
|
}
|
||||||
|
|
||||||
geom.updateModelBound();
|
geom.updateModelBound();
|
||||||
geomArray[index] = geom;
|
geomArray[index] = geom;
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
//TODO material, targets(morph anim...)
|
//TODO targets(morph anim...)
|
||||||
}
|
}
|
||||||
|
|
||||||
addToCache("meshes", meshIndex, geomArray, meshes.size());
|
addToCache("meshes", meshIndex, geomArray, meshes.size());
|
||||||
@ -404,20 +419,86 @@ public class GltfLoader implements AssetLoader {
|
|||||||
adapter.setParam(mat, "metallicFactor", getAsFloat(pbrMat, "metallicFactor", 1f));
|
adapter.setParam(mat, "metallicFactor", getAsFloat(pbrMat, "metallicFactor", 1f));
|
||||||
adapter.setParam(mat, "roughnessFactor", getAsFloat(pbrMat, "roughnessFactor", 1f));
|
adapter.setParam(mat, "roughnessFactor", getAsFloat(pbrMat, "roughnessFactor", 1f));
|
||||||
adapter.setParam(mat, "emissiveFactor", getAsColor(matData, "emissiveFactor", ColorRGBA.Black));
|
adapter.setParam(mat, "emissiveFactor", getAsColor(matData, "emissiveFactor", ColorRGBA.Black));
|
||||||
adapter.setParam(mat, "alphaMode", getAsString(matData, "alphaMode"));
|
String alphaMode = getAsString(matData, "alphaMode");
|
||||||
adapter.setParam(mat, "alphaCutoff", getAsFloat(matData, "alphaCutoff"));
|
adapter.setParam(mat, "alphaMode", alphaMode);
|
||||||
|
if (alphaMode != null && alphaMode.equals("MASK")) {
|
||||||
|
adapter.setParam(mat, "alphaCutoff", getAsFloat(matData, "alphaCutoff"));
|
||||||
|
}
|
||||||
adapter.setParam(mat, "doubleSided", getAsBoolean(matData, "doubleSided"));
|
adapter.setParam(mat, "doubleSided", getAsBoolean(matData, "doubleSided"));
|
||||||
|
|
||||||
//TODO textures
|
adapter.setParam(mat, "baseColorTexture", readTexture(pbrMat.getAsJsonObject("baseColorTexture")));
|
||||||
//adapter.setParam(mat, "baseColorTexture", readTexture);
|
adapter.setParam(mat, "metallicRoughnessTexture", readTexture(pbrMat.getAsJsonObject("metallicRoughnessTexture")));
|
||||||
//adapter.setParam(mat, "metallicRoughnessTexture", readTexture);
|
adapter.setParam(mat, "normalTexture", readTexture(matData.getAsJsonObject("normalTexture")));
|
||||||
//adapter.setParam(mat, "normalTexture", readTexture);
|
adapter.setParam(mat, "occlusionTexture", readTexture(matData.getAsJsonObject("occlusionTexture")));
|
||||||
//adapter.setParam(mat, "occlusionTexture", readTexture);
|
adapter.setParam(mat, "emissiveTexture", readTexture(matData.getAsJsonObject("emissiveTexture")));
|
||||||
//adapter.setParam(mat, "emissiveTexture", readTexture);
|
|
||||||
|
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Texture2D readTexture(JsonObject texture) {
|
||||||
|
if (texture == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Integer textureIndex = getAsInteger(texture, "index");
|
||||||
|
if (textureIndex == null) {
|
||||||
|
throw new AssetLoadException("Texture as no index");
|
||||||
|
}
|
||||||
|
if (textures == null) {
|
||||||
|
throw new AssetLoadException("There are no textures, yet one is referenced by a material");
|
||||||
|
}
|
||||||
|
JsonObject textureData = textures.get(textureIndex).getAsJsonObject();
|
||||||
|
Integer sourceIndex = getAsInteger(textureData, "source");
|
||||||
|
Integer samplerIndex = getAsInteger(textureData, "sampler");
|
||||||
|
|
||||||
|
Texture2D texture2d = loadImage(sourceIndex);
|
||||||
|
readSampler(samplerIndex, texture2d);
|
||||||
|
|
||||||
|
return texture2d;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Texture2D loadImage(int sourceIndex) {
|
||||||
|
if (images == null) {
|
||||||
|
throw new AssetLoadException("No image defined");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject image = images.get(sourceIndex).getAsJsonObject();
|
||||||
|
String uri = getAsString(image, "uri");
|
||||||
|
if (uri == null) {
|
||||||
|
//Image is embed in a buffer not supported yet
|
||||||
|
//TODO support images embed in a buffer
|
||||||
|
throw new AssetLoadException("Images embed in a buffer are not supported yet");
|
||||||
|
} else if (uri.startsWith("data:")) {
|
||||||
|
//base64 encoded image, not supported yet
|
||||||
|
//TODO support base64 encoded images
|
||||||
|
throw new AssetLoadException("Base64 encoded embed images are not supported yet");
|
||||||
|
} else {
|
||||||
|
TextureKey key = new TextureKey(info.getKey().getFolder() + uri, false);
|
||||||
|
Texture tex = info.getManager().loadTexture(key);
|
||||||
|
return (Texture2D) tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readSampler(int samplerIndex, Texture2D texture) {
|
||||||
|
if (samplers == null) {
|
||||||
|
throw new AssetLoadException("No samplers defined");
|
||||||
|
}
|
||||||
|
JsonObject sampler = samplers.get(samplerIndex).getAsJsonObject();
|
||||||
|
Texture.MagFilter magFilter = getMagFilter(getAsInteger(sampler, "magFilter"));
|
||||||
|
Texture.MinFilter minFilter = getMinFilter(getAsInteger(sampler, "minFilter"));
|
||||||
|
Texture.WrapMode wrapS = getWrapMode(getAsInteger(sampler, "wrapS"));
|
||||||
|
Texture.WrapMode wrapT = getWrapMode(getAsInteger(sampler, "wrapT"));
|
||||||
|
|
||||||
|
if (magFilter != null) {
|
||||||
|
texture.setMagFilter(magFilter);
|
||||||
|
}
|
||||||
|
if (minFilter != null) {
|
||||||
|
texture.setMinFilter(minFilter);
|
||||||
|
}
|
||||||
|
texture.setWrap(Texture.WrapAxis.S, wrapS);
|
||||||
|
texture.setWrap(Texture.WrapAxis.T, wrapT);
|
||||||
|
}
|
||||||
|
|
||||||
private String loadMeshName(int meshIndex) {
|
private String loadMeshName(int meshIndex) {
|
||||||
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
||||||
return getAsString(meshData, "name");
|
return getAsString(meshData, "name");
|
||||||
|
@ -5,6 +5,7 @@ import com.jme3.asset.AssetLoadException;
|
|||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.util.LittleEndien;
|
import com.jme3.util.LittleEndien;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -116,6 +117,55 @@ public class GltfUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Texture.MagFilter getMagFilter(Integer value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (value) {
|
||||||
|
case 9728:
|
||||||
|
return Texture.MagFilter.Nearest;
|
||||||
|
case 9729:
|
||||||
|
return Texture.MagFilter.Bilinear;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Texture.MinFilter getMinFilter(Integer value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (value) {
|
||||||
|
case 9728:
|
||||||
|
return Texture.MinFilter.NearestNoMipMaps;
|
||||||
|
case 9729:
|
||||||
|
return Texture.MinFilter.BilinearNoMipMaps;
|
||||||
|
case 9984:
|
||||||
|
return Texture.MinFilter.NearestNearestMipMap;
|
||||||
|
case 9985:
|
||||||
|
return Texture.MinFilter.BilinearNearestMipMap;
|
||||||
|
case 9986:
|
||||||
|
return Texture.MinFilter.NearestLinearMipMap;
|
||||||
|
case 9987:
|
||||||
|
return Texture.MinFilter.Trilinear;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Texture.WrapMode getWrapMode(Integer value) {
|
||||||
|
if (value == null) {
|
||||||
|
return Texture.WrapMode.Repeat;
|
||||||
|
}
|
||||||
|
switch (value) {
|
||||||
|
case 33071:
|
||||||
|
return Texture.WrapMode.EdgeClamp;
|
||||||
|
case 33648:
|
||||||
|
return Texture.WrapMode.MirroredRepeat;
|
||||||
|
default:
|
||||||
|
return Texture.WrapMode.Repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void padBuffer(Buffer buffer, int bufferSize) {
|
public static void padBuffer(Buffer buffer, int bufferSize) {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
if (buffer instanceof IntBuffer) {
|
if (buffer instanceof IntBuffer) {
|
||||||
@ -255,7 +305,7 @@ public class GltfUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsonArray color = el.getAsJsonArray();
|
JsonArray color = el.getAsJsonArray();
|
||||||
return new ColorRGBA(color.get(0).getAsFloat(), color.get(1).getAsFloat(), color.get(2).getAsFloat(), color.get(3).getAsFloat());
|
return new ColorRGBA(color.get(0).getAsFloat(), color.get(1).getAsFloat(), color.get(2).getAsFloat(), color.size() > 3 ? color.get(3).getAsFloat() : 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ColorRGBA getAsColor(JsonObject parent, String name, ColorRGBA defaultValue) {
|
public static ColorRGBA getAsColor(JsonObject parent, String name, ColorRGBA defaultValue) {
|
||||||
|
@ -81,6 +81,7 @@ public abstract class MaterialAdapter {
|
|||||||
if (value instanceof Vector2f) return VarType.Vector2;
|
if (value instanceof Vector2f) return VarType.Vector2;
|
||||||
if (value instanceof Matrix3f) return VarType.Matrix3;
|
if (value instanceof Matrix3f) return VarType.Matrix3;
|
||||||
if (value instanceof Matrix4f) return VarType.Matrix4;
|
if (value instanceof Matrix4f) return VarType.Matrix4;
|
||||||
|
if (value instanceof String) return VarType.Boolean;
|
||||||
throw new AssetLoadException("Unsupported material parameter type : " + value.getClass().getSimpleName());
|
throw new AssetLoadException("Unsupported material parameter type : " + value.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@ public class PBRMaterialAdapter extends MaterialAdapter {
|
|||||||
addParamMapping("metallicRoughnessTexture", "MetallicRoughnessMap");
|
addParamMapping("metallicRoughnessTexture", "MetallicRoughnessMap");
|
||||||
addParamMapping("normalTexture", "NormalMap");
|
addParamMapping("normalTexture", "NormalMap");
|
||||||
addParamMapping("occlusionTexture", "LightMap");
|
addParamMapping("occlusionTexture", "LightMap");
|
||||||
addParamMapping("emisiveTexture", "EmissiveMap");
|
addParamMapping("emissiveTexture", "EmissiveMap");
|
||||||
addParamMapping("emisiveFactor", "Emissive");
|
addParamMapping("emissiveFactor", "Emissive");
|
||||||
addParamMapping("alphaMode", "alpha");
|
addParamMapping("alphaMode", "alpha");
|
||||||
addParamMapping("alphaCutoff", "AlphaDiscardThreshold");
|
// addParamMapping("alphaCutoff", "AlphaDiscardThreshold");
|
||||||
addParamMapping("doubleSided", "doubleSided");
|
addParamMapping("doubleSided", "doubleSided");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,9 +47,9 @@ public class PBRMaterialAdapter extends MaterialAdapter {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (param.getName().equals("MetallicRoughnessMap")) {
|
if (param.getName().equals("NormalMap")) {
|
||||||
//use packed Metallic/Roughness
|
//Set the normal map type to OpenGl
|
||||||
mat.setBoolean("UsePackedMR", true);
|
mat.setFloat("NormalType", 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user