parent
3135f2f4bf
commit
81c995edc4
@ -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 |
||||
} |
@ -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 ); |
||||
} |
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -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); |
||||
} |
||||
} |
||||
|
||||
} |
After Width: | Height: | Size: 4.0 MiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 18 MiB |
After Width: | Height: | Size: 2.8 MiB |
@ -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 { |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
# |
||||
#Sat Apr 11 15:27:27 CEST 2015 |
||||
ORIGINAL_PATH=Models/Tank/tank.obj |
Binary file not shown.
Loading…
Reference in new issue