PBR shader and PBR test case with custom model
This commit is contained in:
parent
3135f2f4bf
commit
81c995edc4
@ -6,4 +6,30 @@
|
|||||||
<template>license.txt</template>
|
<template>license.txt</template>
|
||||||
<property name="organization">jMonkeyEngine</property>
|
<property name="organization">jMonkeyEngine</property>
|
||||||
</license-header>
|
</license-header>
|
||||||
|
<built-in-tasks>
|
||||||
|
<task>
|
||||||
|
<display-name>run</display-name>
|
||||||
|
<non-blocking>no</non-blocking>
|
||||||
|
<task-names>
|
||||||
|
<name must-exist="no">run</name>
|
||||||
|
</task-names>
|
||||||
|
<task-args/>
|
||||||
|
<task-jvm-args>
|
||||||
|
<arg>-ea</arg>
|
||||||
|
</task-jvm-args>
|
||||||
|
</task>
|
||||||
|
<task>
|
||||||
|
<display-name>run.single</display-name>
|
||||||
|
<non-blocking>no</non-blocking>
|
||||||
|
<task-names>
|
||||||
|
<name must-exist="no">${project}:run</name>
|
||||||
|
</task-names>
|
||||||
|
<task-args>
|
||||||
|
<arg>-PmainClass=${selected-class}</arg>
|
||||||
|
</task-args>
|
||||||
|
<task-jvm-args>
|
||||||
|
<arg>-ea</arg>
|
||||||
|
</task-jvm-args>
|
||||||
|
</task>
|
||||||
|
</built-in-tasks>
|
||||||
</gradle-project-properties>
|
</gradle-project-properties>
|
||||||
|
@ -6,7 +6,7 @@ jmeMainVersion = 3.1
|
|||||||
jmeVersionTag = snapshot-github
|
jmeVersionTag = snapshot-github
|
||||||
|
|
||||||
# specify if JavaDoc should be built
|
# specify if JavaDoc should be built
|
||||||
buildJavaDoc = true
|
buildJavaDoc = false
|
||||||
|
|
||||||
# specify if SDK and Native libraries get built
|
# specify if SDK and Native libraries get built
|
||||||
buildSdkProject = true
|
buildSdkProject = true
|
||||||
|
@ -0,0 +1,243 @@
|
|||||||
|
#import "Common/ShaderLib/Parallax.glsllib"
|
||||||
|
#import "Common/ShaderLib/PBR.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
varying vec2 texCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 Color;
|
||||||
|
|
||||||
|
uniform vec4 g_LightData[NB_LIGHTS];
|
||||||
|
|
||||||
|
uniform vec3 g_CameraPosition;
|
||||||
|
|
||||||
|
uniform float m_Roughness;
|
||||||
|
uniform float m_Metallic;
|
||||||
|
|
||||||
|
varying vec3 wPosition;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef INDIRECT_LIGHTING
|
||||||
|
uniform sampler2D m_IntegrateBRDF;
|
||||||
|
uniform samplerCube m_PrefEnvMap;
|
||||||
|
uniform samplerCube m_IrradianceMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BASECOLORMAP
|
||||||
|
uniform sampler2D m_BaseColorMap;
|
||||||
|
#endif
|
||||||
|
#ifdef METALLICMAP
|
||||||
|
uniform sampler2D m_MetallicMap;
|
||||||
|
#endif
|
||||||
|
#ifdef ROUGHNESSMAP
|
||||||
|
uniform sampler2D m_RoughnessMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EMISSIVE
|
||||||
|
uniform vec4 m_Emissive;
|
||||||
|
#endif
|
||||||
|
#ifdef EMISSIVEMAP
|
||||||
|
uniform sampler2D m_EmissiveMap;
|
||||||
|
#endif
|
||||||
|
#if defined(EMISSIVE) || defined(EMISSIVEMAP)
|
||||||
|
uniform float m_EmissivePower;
|
||||||
|
uniform float m_EmissiveIntensity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPECGLOSSPIPELINE
|
||||||
|
uniform sampler2D m_SpecularMap;
|
||||||
|
uniform sampler2D m_GlossMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PARALLAXMAP
|
||||||
|
uniform sampler2D m_ParallaxMap;
|
||||||
|
#endif
|
||||||
|
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
|
||||||
|
uniform float m_ParallaxHeight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIGHTMAP
|
||||||
|
uniform sampler2D m_LightMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
uniform sampler2D m_NormalMap;
|
||||||
|
varying vec3 wTangent;
|
||||||
|
varying vec3 wBinormal;
|
||||||
|
#endif
|
||||||
|
varying vec3 wNormal;
|
||||||
|
|
||||||
|
#ifdef DISCARD_ALPHA
|
||||||
|
uniform float m_AlphaDiscardThreshold;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 newTexCoord;
|
||||||
|
|
||||||
|
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
|
||||||
|
|
||||||
|
#ifdef STEEP_PARALLAX
|
||||||
|
#ifdef NORMALMAP_PARALLAX
|
||||||
|
//parallax map is stored in the alpha channel of the normal map
|
||||||
|
newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#else
|
||||||
|
//parallax map is a texture
|
||||||
|
newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef NORMALMAP_PARALLAX
|
||||||
|
//parallax map is stored in the alpha channel of the normal map
|
||||||
|
newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#else
|
||||||
|
//parallax map is a texture
|
||||||
|
newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
newTexCoord = texCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BASECOLORMAP
|
||||||
|
vec4 albedo = texture2D(m_BaseColorMap, newTexCoord);
|
||||||
|
#else
|
||||||
|
vec4 albedo = Color;
|
||||||
|
#endif
|
||||||
|
#ifdef ROUGHNESSMAP
|
||||||
|
float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness,1e-8);
|
||||||
|
#else
|
||||||
|
float Roughness = max(m_Roughness,1e-8);
|
||||||
|
#endif
|
||||||
|
#ifdef METALLICMAP
|
||||||
|
float Metallic = texture2D(m_MetallicMap, newTexCoord).r;
|
||||||
|
#else
|
||||||
|
float Metallic = max(m_Metallic,0.00);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Roughness = max(m_Roughness,1e-8);
|
||||||
|
//Metallic = max(m_Metallic,0.00);
|
||||||
|
float alpha = Color.a * albedo.a;
|
||||||
|
|
||||||
|
#ifdef DISCARD_ALPHA
|
||||||
|
if(alpha < m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ***********************
|
||||||
|
// Read from textures
|
||||||
|
// ***********************
|
||||||
|
#if defined(NORMALMAP)
|
||||||
|
vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);
|
||||||
|
//Note the -2.0 and -1.0. We invert the green channel of the normal map,
|
||||||
|
//as it's complient with normal maps generated with blender.
|
||||||
|
//see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
|
||||||
|
//for more explanation.
|
||||||
|
vec3 normal = normalize((normalHeight.xyz * vec3(2.0,-2.0,2.0) - vec3(1.0,-1.0,1.0)));
|
||||||
|
#else
|
||||||
|
vec3 normal = normalize(wNormal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LIGHTMAP
|
||||||
|
vec3 lightMapColor;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
|
||||||
|
#else
|
||||||
|
lightMapColor = texture2D(m_LightMap, texCoord).rgb;
|
||||||
|
#endif
|
||||||
|
specularColor.rgb *= lightMapColor;
|
||||||
|
albedo.rgb *= lightMapColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
mat3 tbnMat = mat3(normalize(wTangent.xyz) , normalize(wBinormal.xyz) , normalize(wNormal.xyz));
|
||||||
|
normal = normalize(tbnMat * normal);
|
||||||
|
// normal = normalize(normal * inverse(tbnMat));
|
||||||
|
#endif
|
||||||
|
vec3 viewDir = normalize(g_CameraPosition - wPosition);
|
||||||
|
|
||||||
|
|
||||||
|
float specular = 0.5;
|
||||||
|
|
||||||
|
#ifdef SPECGLOSSPIPELINE
|
||||||
|
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
|
||||||
|
vec4 diffuseColor = albedo;
|
||||||
|
Roughness = 1.0 - texture2D(m_GlossMap, newTexCoord);
|
||||||
|
#else
|
||||||
|
float nonMetalSpec = 0.08 * specular;
|
||||||
|
vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
|
||||||
|
vec4 diffuseColor = albedo - albedo * Metallic;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor.rgb = vec3(0.0);
|
||||||
|
float ndotv = max( dot( normal, viewDir ),0.0);
|
||||||
|
for( int i = 0;i < NB_LIGHTS; i+=3){
|
||||||
|
vec4 lightColor = g_LightData[i];
|
||||||
|
vec4 lightData1 = g_LightData[i+1];
|
||||||
|
vec4 lightDir;
|
||||||
|
vec3 lightVec;
|
||||||
|
lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec);
|
||||||
|
|
||||||
|
float fallOff = 1.0;
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(lightColor.w > 1.0){
|
||||||
|
#endif
|
||||||
|
fallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//point light attenuation
|
||||||
|
fallOff *= lightDir.w;
|
||||||
|
|
||||||
|
lightDir.xyz = normalize(lightDir.xyz);
|
||||||
|
vec3 directDiffuse;
|
||||||
|
vec3 directSpecular;
|
||||||
|
|
||||||
|
PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
|
||||||
|
lightColor.rgb,specular, Roughness, ndotv,
|
||||||
|
directDiffuse, directSpecular);
|
||||||
|
|
||||||
|
vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular * specularColor.rgb;
|
||||||
|
|
||||||
|
gl_FragColor.rgb += directLighting * fallOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef INDIRECT_LIGHTING
|
||||||
|
vec3 rv = reflect(-viewDir.xyz, normal.xyz);
|
||||||
|
|
||||||
|
//horizon fade from http://marmosetco.tumblr.com/post/81245981087
|
||||||
|
float horiz = dot(rv, wNormal.xyz);
|
||||||
|
float horizFadePower= 1.0 - Roughness;
|
||||||
|
horiz = clamp( 1.0 + horizFadePower * horiz, 0.0, 1.0 );
|
||||||
|
horiz *= horiz;
|
||||||
|
|
||||||
|
vec3 indirectDiffuse = vec3(0.0);
|
||||||
|
vec3 indirectSpecular = vec3(0.0);
|
||||||
|
indirectDiffuse = textureCube(m_IrradianceMap, rv.xyz).rgb * albedo.rgb;
|
||||||
|
|
||||||
|
indirectSpecular = ApproximateSpecularIBL(m_PrefEnvMap,m_IntegrateBRDF, specularColor.rgb, Roughness, ndotv, rv.xyz);
|
||||||
|
indirectSpecular *= vec3(horiz);
|
||||||
|
|
||||||
|
vec3 indirectLighting = indirectDiffuse + indirectSpecular;
|
||||||
|
|
||||||
|
gl_FragColor.rgb = gl_FragColor.rgb + indirectLighting ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(EMISSIVE) || defined (EMISSIVEMAP)
|
||||||
|
#ifdef EMISSIVEMAP
|
||||||
|
vec4 emissive = texture2D(m_EmissiveMap, newTexCoord);
|
||||||
|
#else
|
||||||
|
vec4 emissive = m_Emissive;
|
||||||
|
#endif
|
||||||
|
gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor.a = alpha;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,305 @@
|
|||||||
|
MaterialDef PBR Lighting {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
|
||||||
|
// Alpha threshold for fragment discarding
|
||||||
|
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
||||||
|
|
||||||
|
//metalness of the material
|
||||||
|
Float Metallic : 0.0
|
||||||
|
//Roughness of the material
|
||||||
|
Float Roughness : 1.0
|
||||||
|
// Base material color
|
||||||
|
Color BaseColor
|
||||||
|
// The emissive color of the object
|
||||||
|
Color Emissive
|
||||||
|
// the emissive power
|
||||||
|
Float EmissivePower : 3.0
|
||||||
|
// the emissive intensity
|
||||||
|
Float EmissiveIntensity : 1.0
|
||||||
|
|
||||||
|
// BaseColor map
|
||||||
|
Texture2D BaseColorMap
|
||||||
|
|
||||||
|
// Specular/gloss map
|
||||||
|
Texture2D MetallicMap -LINEAR
|
||||||
|
|
||||||
|
// Roughness Map
|
||||||
|
Texture2D RoughnessMap -LINEAR
|
||||||
|
|
||||||
|
// Texture of the emissive parts of the material
|
||||||
|
Texture2D EmissiveMap
|
||||||
|
|
||||||
|
// Normal map
|
||||||
|
Texture2D NormalMap -LINEAR
|
||||||
|
|
||||||
|
// For Spec gloss pipeline
|
||||||
|
Texture2D SpecularMap
|
||||||
|
Texture2D GlossMap
|
||||||
|
|
||||||
|
// Prefiltered Env Map for indirect specular lighting
|
||||||
|
TextureCubeMap PrefEnvMap -LINEAR
|
||||||
|
|
||||||
|
// Irradiance map for indirect diffuse lighting
|
||||||
|
TextureCubeMap IrradianceMap -LINEAR
|
||||||
|
|
||||||
|
//integrate BRDF map for indirect Lighting
|
||||||
|
Texture2D IntegrateBRDF -LINEAR
|
||||||
|
|
||||||
|
// Parallax/height map
|
||||||
|
Texture2D ParallaxMap -LINEAR
|
||||||
|
|
||||||
|
//Set to true is parallax map is stored in the alpha channel of the normal map
|
||||||
|
Boolean PackedNormalParallax
|
||||||
|
|
||||||
|
//Sets the relief height for parallax mapping
|
||||||
|
Float ParallaxHeight : 0.05
|
||||||
|
|
||||||
|
//Set to true to activate Steep Parallax mapping
|
||||||
|
Boolean SteepParallax
|
||||||
|
|
||||||
|
// Set to Use Lightmap
|
||||||
|
Texture2D LightMap
|
||||||
|
|
||||||
|
// Set to use TexCoord2 for the lightmap sampling
|
||||||
|
Boolean SeparateTexCoord
|
||||||
|
|
||||||
|
//shadows
|
||||||
|
Int FilterMode
|
||||||
|
Boolean HardwareShadows
|
||||||
|
|
||||||
|
Texture2D ShadowMap0
|
||||||
|
Texture2D ShadowMap1
|
||||||
|
Texture2D ShadowMap2
|
||||||
|
Texture2D ShadowMap3
|
||||||
|
//pointLights
|
||||||
|
Texture2D ShadowMap4
|
||||||
|
Texture2D ShadowMap5
|
||||||
|
|
||||||
|
Float ShadowIntensity
|
||||||
|
Vector4 Splits
|
||||||
|
Vector2 FadeInfo
|
||||||
|
|
||||||
|
Matrix4 LightViewProjectionMatrix0
|
||||||
|
Matrix4 LightViewProjectionMatrix1
|
||||||
|
Matrix4 LightViewProjectionMatrix2
|
||||||
|
Matrix4 LightViewProjectionMatrix3
|
||||||
|
//pointLight
|
||||||
|
Matrix4 LightViewProjectionMatrix4
|
||||||
|
Matrix4 LightViewProjectionMatrix5
|
||||||
|
Vector3 LightPos
|
||||||
|
Vector3 LightDir
|
||||||
|
|
||||||
|
Float PCFEdge
|
||||||
|
Float ShadowMapSize
|
||||||
|
|
||||||
|
// For hardware skinning
|
||||||
|
Int NumberOfBones
|
||||||
|
Matrix4Array BoneMatrices
|
||||||
|
|
||||||
|
//For instancing
|
||||||
|
Boolean UseInstancing
|
||||||
|
|
||||||
|
//For Vertex Color
|
||||||
|
Boolean UseVertexColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
LightMode SinglePass
|
||||||
|
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Light/PBRLighting.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Light/PBRLighting.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
CameraPosition
|
||||||
|
WorldMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
BASECOLORMAP : BaseColorMap
|
||||||
|
NORMALMAP : NormalMap
|
||||||
|
METALLICMAP : MetallicMap
|
||||||
|
ROUGHNESSMAP : RoughnessMap
|
||||||
|
EMISSIVEMAP : EmissiveMap
|
||||||
|
EMISSIVE : Emissive
|
||||||
|
SPECGLOSSPIPELINE : SpecularMap
|
||||||
|
PARALLAXMAP : ParallaxMap
|
||||||
|
NORMALMAP_PARALLAX : PackedNormalParallax
|
||||||
|
STEEP_PARALLAX : SteepParallax
|
||||||
|
LIGHTMAP : LightMap
|
||||||
|
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
INDIRECT_LIGHTING : IntegrateBRDF
|
||||||
|
VERTEX_COLOR : UseVertexColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Technique PreShadow {
|
||||||
|
|
||||||
|
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
||||||
|
FragmentShader GLSL100 : Common/MatDefs/Shadow/PreShadow.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
COLOR_MAP : ColorMap
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
|
||||||
|
ForcedRenderState {
|
||||||
|
FaceCull Off
|
||||||
|
DepthTest On
|
||||||
|
DepthWrite On
|
||||||
|
PolyOffset 5 3
|
||||||
|
ColorWrite Off
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Technique PostShadow15{
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
|
FILTER_MODE : FilterMode
|
||||||
|
PCFEDGE : PCFEdge
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
COLOR_MAP : ColorMap
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
|
FADE : FadeInfo
|
||||||
|
PSSM : Splits
|
||||||
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
|
||||||
|
ForcedRenderState {
|
||||||
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique PostShadow{
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Shadow/PostShadow.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadow.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
|
FILTER_MODE : FilterMode
|
||||||
|
PCFEDGE : PCFEdge
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
COLOR_MAP : ColorMap
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
|
FADE : FadeInfo
|
||||||
|
PSSM : Splits
|
||||||
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
|
||||||
|
ForcedRenderState {
|
||||||
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique PreNormalPass {
|
||||||
|
|
||||||
|
VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert
|
||||||
|
FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
NormalMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
DIFFUSEMAP_ALPHA : DiffuseMap
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Technique PreNormalPassDerivative {
|
||||||
|
|
||||||
|
VertexShader GLSL100 : Common/MatDefs/MSSAO/normal.vert
|
||||||
|
FragmentShader GLSL100 : Common/MatDefs/MSSAO/normal.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
NormalMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
DIFFUSEMAP_ALPHA : DiffuseMap
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique GBuf {
|
||||||
|
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Light/GBuf.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Light/GBuf.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
NormalMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
WorldMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
VERTEX_COLOR : UseVertexColor
|
||||||
|
MATERIAL_COLORS : UseMaterialColors
|
||||||
|
V_TANGENT : VTangent
|
||||||
|
MINNAERT : Minnaert
|
||||||
|
WARDISO : WardIso
|
||||||
|
|
||||||
|
DIFFUSEMAP : DiffuseMap
|
||||||
|
NORMALMAP : NormalMap
|
||||||
|
SPECULARMAP : SpecularMap
|
||||||
|
PARALLAXMAP : ParallaxMap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
#import "Common/ShaderLib/Instancing.glsllib"
|
||||||
|
#import "Common/ShaderLib/Skinning.glsllib"
|
||||||
|
|
||||||
|
uniform vec4 m_BaseColor;
|
||||||
|
|
||||||
|
uniform vec4 g_AmbientLightColor;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
varying vec2 texCoord2;
|
||||||
|
attribute vec2 inTexCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 Color;
|
||||||
|
|
||||||
|
attribute vec3 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
|
||||||
|
#ifdef VERTEX_COLOR
|
||||||
|
attribute vec4 inColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec3 wNormal;
|
||||||
|
varying vec3 wPosition;
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
attribute vec4 inTangent;
|
||||||
|
varying vec3 wTangent;
|
||||||
|
varying vec3 wBinormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 modelSpacePos = vec4(inPosition, 1.0);
|
||||||
|
vec3 modelSpaceNorm = inNormal;
|
||||||
|
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
vec3 modelSpaceTan = inTangent.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NUM_BONES
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
|
||||||
|
#else
|
||||||
|
Skinning_Compute(modelSpacePos, modelSpaceNorm);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
texCoord2 = inTexCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wPosition = TransformWorld(modelSpacePos).xyz;
|
||||||
|
wNormal = TransformWorld(vec4(modelSpaceNorm,0.0)).xyz;
|
||||||
|
|
||||||
|
#if defined(NORMALMAP)
|
||||||
|
wTangent = TransformWorld(vec4(modelSpaceTan,0.0)).xyz;
|
||||||
|
wBinormal = cross(wNormal, wTangent)* inTangent.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Color = m_BaseColor;
|
||||||
|
|
||||||
|
#ifdef VERTEX_COLOR
|
||||||
|
Color *= inColor;
|
||||||
|
#endif
|
||||||
|
}
|
120
jme3-core/src/main/resources/Common/ShaderLib/PBR.glsllib
Normal file
120
jme3-core/src/main/resources/Common/ShaderLib/PBR.glsllib
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.14159265358979323846264
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Specular fresnel computation
|
||||||
|
vec3 F_Shlick(float vh, vec3 F0){
|
||||||
|
float fresnelFact = pow(2.0, (-5.55473*vh - 6.98316) * vh);
|
||||||
|
return mix(F0, vec3(1.0, 1.0, 1.0), fresnelFact);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PBR_ComputeDirectLightSpecWF(vec3 normal, vec3 lightDir, vec3 viewDir,
|
||||||
|
vec3 lightColor, vec3 specColor, float roughness, float ndotv,
|
||||||
|
out vec3 outDiffuse, out vec3 outSpecular){
|
||||||
|
// Compute halfway vector.
|
||||||
|
vec3 halfVec = normalize(lightDir + viewDir);
|
||||||
|
|
||||||
|
// Compute ndotl, ndoth, vdoth terms which are needed later.
|
||||||
|
float ndotl = max( dot(normal, lightDir), 0.0);
|
||||||
|
float ndoth = max( dot(normal, halfVec), 0.0);
|
||||||
|
float hdotv = max( dot(viewDir, halfVec), 0.0);
|
||||||
|
|
||||||
|
// Compute diffuse using energy-conserving Lambert.
|
||||||
|
// Alternatively, use Oren-Nayar for really rough
|
||||||
|
// materials or if you have lots of processing power ...
|
||||||
|
outDiffuse = vec3(ndotl) * lightColor;
|
||||||
|
|
||||||
|
//cook-torrence, microfacet BRDF : http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||||
|
|
||||||
|
float alpha = roughness * roughness;
|
||||||
|
|
||||||
|
//D, GGX normaal Distribution function
|
||||||
|
float alpha2 = alpha * alpha;
|
||||||
|
float sum = ((ndoth * ndoth) * (alpha2 - 1.0) + 1.0);
|
||||||
|
float denom = PI * sum * sum;
|
||||||
|
float D = alpha2 / denom;
|
||||||
|
|
||||||
|
// Compute Fresnel function via Schlick's approximation.
|
||||||
|
vec3 fresnel = F_Shlick(hdotv, specColor);
|
||||||
|
|
||||||
|
//G Shchlick GGX Gometry shadowing term, k = alpha/2
|
||||||
|
float k = alpha * 0.5;
|
||||||
|
|
||||||
|
// UE4 way to optimise shlick GGX Gometry shadowing term
|
||||||
|
//http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
|
||||||
|
float G_V = ndotv + sqrt( (ndotv - ndotv * k) * ndotv + k );
|
||||||
|
float G_L = ndotl + sqrt( (ndotl - ndotl * k) * ndotl + k );
|
||||||
|
// the max here is to avoid division by 0 that may cause some small glitches.
|
||||||
|
float G = 1.0/max( G_V * G_L ,0.01);
|
||||||
|
|
||||||
|
float specular = D * G * ndotl;
|
||||||
|
|
||||||
|
outSpecular = fresnel * vec3(specular) * lightColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PBR_ComputeDirectLight(vec3 normal, vec3 lightDir, vec3 viewDir,
|
||||||
|
vec3 lightColor, float fZero, float roughness, float ndotv,
|
||||||
|
out vec3 outDiffuse, out vec3 outSpecular){
|
||||||
|
// Compute halfway vector.
|
||||||
|
vec3 halfVec = normalize(lightDir + viewDir);
|
||||||
|
|
||||||
|
// Compute ndotl, ndoth, vdoth terms which are needed later.
|
||||||
|
float ndotl = max( dot(normal, lightDir), 0.0);
|
||||||
|
float ndoth = max( dot(normal, halfVec), 0.0);
|
||||||
|
float hdotv = max( dot(viewDir, halfVec), 0.0);
|
||||||
|
|
||||||
|
// Compute diffuse using energy-conserving Lambert.
|
||||||
|
// Alternatively, use Oren-Nayar for really rough
|
||||||
|
// materials or if you have lots of processing power ...
|
||||||
|
outDiffuse = vec3(ndotl) * lightColor;
|
||||||
|
|
||||||
|
//cook-torrence, microfacet BRDF : http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||||
|
|
||||||
|
float alpha = roughness * roughness;
|
||||||
|
|
||||||
|
//D, GGX normaal Distribution function
|
||||||
|
float alpha2 = alpha * alpha;
|
||||||
|
float sum = ((ndoth * ndoth) * (alpha2 - 1.0) + 1.0);
|
||||||
|
float denom = PI * sum * sum;
|
||||||
|
float D = alpha2 / denom;
|
||||||
|
|
||||||
|
// Compute Fresnel function via Schlick's approximation.
|
||||||
|
float fresnel = fZero + ( 1.0 - fZero ) * pow( 1.0 - hdotv, 5.0 );
|
||||||
|
|
||||||
|
//G Shchlick GGX Gometry shadowing term, k = alpha/2
|
||||||
|
float k = alpha * 0.5;
|
||||||
|
|
||||||
|
/*
|
||||||
|
//classic Schlick ggx
|
||||||
|
float G_V = ndotv / (ndotv * (1.0 - k) + k);
|
||||||
|
float G_L = ndotl / (ndotl * (1.0 - k) + k);
|
||||||
|
float G = ( G_V * G_L );
|
||||||
|
|
||||||
|
float specular =(D* fresnel * G) /(4 * ndotv);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// UE4 way to optimise shlick GGX Gometry shadowing term
|
||||||
|
//http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
|
||||||
|
float G_V = ndotv + sqrt( (ndotv - ndotv * k) * ndotv + k );
|
||||||
|
float G_L = ndotl + sqrt( (ndotl - ndotl * k) * ndotl + k );
|
||||||
|
// the max here is to avoid division by 0 that may cause some small glitches.
|
||||||
|
float G = 1.0/max( G_V * G_L ,0.01);
|
||||||
|
|
||||||
|
float specular = D * fresnel * G * ndotl;
|
||||||
|
|
||||||
|
outSpecular = vec3(specular) * lightColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 ApproximateSpecularIBL(samplerCube envMap,sampler2D integrateBRDF, vec3 SpecularColor , float Roughness, float ndotv, vec3 refVec){
|
||||||
|
//TODO magic values should be replaced by defines.
|
||||||
|
float Lod = log2(Roughness) * 1.2 + 6.0 - 1.0;
|
||||||
|
vec3 PrefilteredColor = textureCube(envMap, refVec.xyz,Lod).rgb;
|
||||||
|
vec2 EnvBRDF = texture2D(integrateBRDF,vec2(Roughness, ndotv)).rg;
|
||||||
|
return PrefilteredColor * ( SpecularColor * EnvBRDF.x+ EnvBRDF.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
jme3-core/src/main/resources/Common/Textures/integrateBRDF.ktx
Normal file
BIN
jme3-core/src/main/resources/Common/Textures/integrateBRDF.ktx
Normal file
Binary file not shown.
@ -296,6 +296,12 @@ public class DDSLoader implements AssetLoader {
|
|||||||
// exit here, the rest of the structure is not valid
|
// exit here, the rest of the structure is not valid
|
||||||
// the real format will be available in the DX10 header
|
// the real format will be available in the DX10 header
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 113:
|
||||||
|
compressed = false;
|
||||||
|
bpp = 64;
|
||||||
|
pixelFormat = Image.Format.RGBA16F;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
|
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
|
||||||
}
|
}
|
||||||
|
131
jme3-examples/src/main/java/jme3test/light/TestShadowBug.java
Normal file
131
jme3-examples/src/main/java/jme3test/light/TestShadowBug.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2015 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 jme3test.light;
|
||||||
|
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Quaternion;
|
||||||
|
import com.jme3.math.Vector2f;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.shape.Box;
|
||||||
|
import com.jme3.shadow.EdgeFilteringMode;
|
||||||
|
import com.jme3.shadow.PointLightShadowRenderer;
|
||||||
|
import com.jme3.shadow.SpotLightShadowRenderer;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
|
|
||||||
|
|
||||||
|
public class TestShadowBug extends SimpleApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestShadowBug app = new TestShadowBug();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp() {
|
||||||
|
flyCam.setMoveSpeed(100f);
|
||||||
|
rootNode.attachChild(makeFloor());
|
||||||
|
|
||||||
|
Node characters = new Node("Characters");
|
||||||
|
characters.setShadowMode(ShadowMode.Cast);
|
||||||
|
rootNode.attachChild(characters);
|
||||||
|
|
||||||
|
Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
|
||||||
|
golem.scale(0.5f);
|
||||||
|
golem.setLocalTranslation(200.0f, -6f, 200f);
|
||||||
|
golem.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
characters.attachChild(golem);
|
||||||
|
|
||||||
|
DirectionalLight sun = new DirectionalLight();
|
||||||
|
sun.setDirection(new Vector3f(-1f, -1f, 1f));
|
||||||
|
sun.setColor(ColorRGBA.White.mult(1.3f));
|
||||||
|
rootNode.addLight(sun);
|
||||||
|
characters.addLight(sun);
|
||||||
|
|
||||||
|
SpotLight spot = new SpotLight();
|
||||||
|
spot.setSpotRange(13f); // distance
|
||||||
|
spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD); // inner light cone (central beam)
|
||||||
|
spot.setSpotOuterAngle(20f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light)
|
||||||
|
spot.setColor(ColorRGBA.White.mult(1.3f)); // light color
|
||||||
|
spot.setPosition(new Vector3f(192.0f, -1f, 192f));
|
||||||
|
spot.setDirection(new Vector3f(1, -0.5f, 1));
|
||||||
|
rootNode.addLight(spot);
|
||||||
|
|
||||||
|
PointLight lamp_light = new PointLight();
|
||||||
|
lamp_light.setColor(ColorRGBA.Yellow);
|
||||||
|
lamp_light.setRadius(20f);
|
||||||
|
lamp_light.setPosition(new Vector3f(210.0f, 0f, 210f));
|
||||||
|
rootNode.addLight(lamp_light);
|
||||||
|
|
||||||
|
SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512);
|
||||||
|
slsr.setLight(spot);
|
||||||
|
slsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||||
|
slsr.setShadowIntensity(0.6f);
|
||||||
|
slsr.setFlushQueues(false);
|
||||||
|
viewPort.addProcessor(slsr);
|
||||||
|
|
||||||
|
PointLightShadowRenderer plsr = new PointLightShadowRenderer(assetManager, 512);
|
||||||
|
plsr.setLight(lamp_light);
|
||||||
|
plsr.setShadowIntensity(0.6f);
|
||||||
|
plsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||||
|
plsr.setFlushQueues(false);
|
||||||
|
viewPort.addProcessor(plsr);
|
||||||
|
|
||||||
|
viewPort.getCamera().setLocation(new Vector3f(192.0f, 10f, 192f));
|
||||||
|
float[] angles = new float[]{3.14f/2, 3.14f/2, 0};
|
||||||
|
viewPort.getCamera().setRotation(new Quaternion(angles));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Geometry makeFloor() {
|
||||||
|
Box box = new Box(220, .2f, 220);
|
||||||
|
box.scaleTextureCoordinates(new Vector2f(10, 10));
|
||||||
|
Geometry floor = new Geometry("the Floor", box);
|
||||||
|
floor.setLocalTranslation(200, -9, 200);
|
||||||
|
Material matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||||
|
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
|
||||||
|
grass.setWrap(WrapMode.Repeat);
|
||||||
|
matGroundL.setTexture("DiffuseMap", grass);
|
||||||
|
floor.setMaterial(matGroundL);
|
||||||
|
floor.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
return floor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
package jme3test.light.pbr;
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.input.ChaseCamera;
|
||||||
|
import com.jme3.input.KeyInput;
|
||||||
|
import com.jme3.input.controls.ActionListener;
|
||||||
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.post.FilterPostProcessor;
|
||||||
|
import com.jme3.post.filters.FXAAFilter;
|
||||||
|
import com.jme3.post.filters.ToneMapFilter;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.texture.pbr.EnvironmentCamera;
|
||||||
|
import com.jme3.texture.plugins.ktx.KTXLoader;
|
||||||
|
import com.jme3.util.SkyFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test case for PBR lighting.
|
||||||
|
* Still experimental.
|
||||||
|
*
|
||||||
|
* @author nehon
|
||||||
|
*/
|
||||||
|
public class TestPBRLighting extends SimpleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestPBRLighting app = new TestPBRLighting();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
private Geometry model;
|
||||||
|
private DirectionalLight dl;
|
||||||
|
private Node modelNode;
|
||||||
|
private int frame = 0;
|
||||||
|
private boolean indirectLighting = true;
|
||||||
|
private Material pbrMat;
|
||||||
|
private Material adHocMat;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp() {
|
||||||
|
assetManager.registerLoader(KTXLoader.class, "ktx");
|
||||||
|
|
||||||
|
viewPort.setBackgroundColor(ColorRGBA.White);
|
||||||
|
modelNode = (Node) new Node("modelNode");
|
||||||
|
model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o");
|
||||||
|
modelNode.attachChild(model);
|
||||||
|
|
||||||
|
dl = new DirectionalLight();
|
||||||
|
dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
|
||||||
|
rootNode.addLight(dl);
|
||||||
|
dl.setColor(ColorRGBA.White);
|
||||||
|
rootNode.attachChild(modelNode);
|
||||||
|
|
||||||
|
final EnvironmentCamera envCam = new EnvironmentCamera(128, new Vector3f(0, 3f, 0));
|
||||||
|
stateManager.attach(envCam);
|
||||||
|
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
|
fpp.addFilter(new FXAAFilter());
|
||||||
|
fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(2.0f)));
|
||||||
|
viewPort.addProcessor(fpp);
|
||||||
|
|
||||||
|
//Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Sky_Cloudy.hdr", SkyFactory.EnvMapType.EquirectMap);
|
||||||
|
Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
|
||||||
|
//Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Stonewall.hdr", SkyFactory.EnvMapType.EquirectMap);
|
||||||
|
//Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/road.hdr", SkyFactory.EnvMapType.EquirectMap);
|
||||||
|
rootNode.attachChild(sky);
|
||||||
|
|
||||||
|
pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m");
|
||||||
|
model.setMaterial(pbrMat);
|
||||||
|
|
||||||
|
ChaseCamera chaser = new ChaseCamera(cam, modelNode, inputManager);
|
||||||
|
chaser.setDragToRotate(true);
|
||||||
|
chaser.setMinVerticalRotation(-FastMath.HALF_PI);
|
||||||
|
chaser.setMaxDistance(1000);
|
||||||
|
chaser.setSmoothMotion(true);
|
||||||
|
chaser.setRotationSensitivity(10);
|
||||||
|
chaser.setZoomSensitivity(5);
|
||||||
|
flyCam.setEnabled(false);
|
||||||
|
//flyCam.setMoveSpeed(100);
|
||||||
|
|
||||||
|
inputManager.addListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void onAction(String name, boolean isPressed, float tpf) {
|
||||||
|
if (name.equals("toggle") && isPressed) {
|
||||||
|
if (!indirectLighting) {
|
||||||
|
toggleIBL();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pbrMat.clearParam("IntegrateBRDF");
|
||||||
|
indirectLighting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("switchMats") && isPressed) {
|
||||||
|
if (model.getMaterial() == pbrMat) {
|
||||||
|
model.setMaterial(adHocMat);
|
||||||
|
} else {
|
||||||
|
model.setMaterial(pbrMat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("debug") && isPressed) {
|
||||||
|
envCam.toggleDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("up") && isPressed) {
|
||||||
|
model.move(0, tpf * 100f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("down") && isPressed) {
|
||||||
|
model.move(0, -tpf * 100f, 0);
|
||||||
|
}
|
||||||
|
if (name.equals("left") && isPressed) {
|
||||||
|
model.move(0, 0, tpf * 100f);
|
||||||
|
}
|
||||||
|
if (name.equals("right") && isPressed) {
|
||||||
|
model.move(0, 0, -tpf * 100f);
|
||||||
|
}
|
||||||
|
if (name.equals("light") && isPressed) {
|
||||||
|
dl.setDirection(cam.getDirection().normalize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "toggle", "light", "up", "down", "left", "right", "debug");
|
||||||
|
|
||||||
|
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_RETURN));
|
||||||
|
inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F));
|
||||||
|
inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP));
|
||||||
|
inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN));
|
||||||
|
inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));
|
||||||
|
inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));
|
||||||
|
inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_D));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleIBL() {
|
||||||
|
ensurePbrMat();
|
||||||
|
pbrMat.setTexture("IrradianceMap", stateManager.getState(EnvironmentCamera.class).getIrradianceMap());
|
||||||
|
pbrMat.setTexture("PrefEnvMap", stateManager.getState(EnvironmentCamera.class).getPrefilteredEnvMap());
|
||||||
|
pbrMat.setTexture("IntegrateBRDF", assetManager.loadTexture("Common/Textures/integrateBRDF.ktx"));
|
||||||
|
indirectLighting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensurePbrMat() {
|
||||||
|
if (model.getMaterial() != pbrMat && model.getMaterial() != adHocMat) {
|
||||||
|
pbrMat = model.getMaterial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleUpdate(float tpf) {
|
||||||
|
frame++;
|
||||||
|
|
||||||
|
if (frame == 2) {
|
||||||
|
modelNode.removeFromParent();
|
||||||
|
stateManager.getState(EnvironmentCamera.class).snapshot(rootNode, new Runnable() {
|
||||||
|
|
||||||
|
//this code is ensured to be called in the update loop, the run method is called by the EnvCamera app state in it's update cycle
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
toggleIBL();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (frame > 2 && modelNode.getParent() == null) {
|
||||||
|
rootNode.attachChild(modelNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Base_Color.png
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Base_Color.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 MiB |
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Emissive.png
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Emissive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Metallic.png
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Metallic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 MiB |
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Normal.png
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 MiB |
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Roughness.png
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/Tank_Roughness.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 MiB |
14
jme3-testdata/src/main/resources/Models/Tank/tank.j3m
Normal file
14
jme3-testdata/src/main/resources/Models/Tank/tank.j3m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Material Tank : Common/MatDefs/Light/PBRLighting.j3md {
|
||||||
|
MaterialParameters {
|
||||||
|
|
||||||
|
MetallicMap : Flip Models/Tank/Tank_Metallic.png
|
||||||
|
RoughnessMap : Flip Models/Tank/Tank_Roughness.png
|
||||||
|
NormalMap : Flip Models/Tank/Tank_Normal.png
|
||||||
|
BaseColorMap : Flip Models/Tank/Tank_Base_Color.png
|
||||||
|
EmissiveMap : Flip Models/Tank/Tank_Emissive.png
|
||||||
|
EmissiveIntensity : 2.0
|
||||||
|
|
||||||
|
}
|
||||||
|
AdditionalRenderState {
|
||||||
|
}
|
||||||
|
}
|
BIN
jme3-testdata/src/main/resources/Models/Tank/tank.j3o
Normal file
BIN
jme3-testdata/src/main/resources/Models/Tank/tank.j3o
Normal file
Binary file not shown.
@ -0,0 +1,3 @@
|
|||||||
|
#
|
||||||
|
#Sat Apr 11 15:27:27 CEST 2015
|
||||||
|
ORIGINAL_PATH=Models/Tank/tank.obj
|
BIN
jme3-testdata/src/main/resources/Textures/Sky/Path.hdr
Normal file
BIN
jme3-testdata/src/main/resources/Textures/Sky/Path.hdr
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user