Along with some light shaders refactoring and clean upexperimental
parent
3ef5505faa
commit
c55717141e
@ -0,0 +1,218 @@ |
||||
#import "Common/ShaderLib/Parallax.glsllib" |
||||
#import "Common/ShaderLib/Optics.glsllib" |
||||
#ifndef VERTEX_LIGHTING |
||||
#import "Common/ShaderLib/PhongLighting.glsllib" |
||||
#import "Common/ShaderLib/Lighting.glsllib" |
||||
#endif |
||||
|
||||
varying vec2 texCoord; |
||||
#ifdef SEPARATE_TEXCOORD |
||||
varying vec2 texCoord2; |
||||
#endif |
||||
|
||||
varying vec3 AmbientSum; |
||||
varying vec4 DiffuseSum; |
||||
varying vec3 SpecularSum; |
||||
|
||||
#ifndef VERTEX_LIGHTING |
||||
uniform mat4 g_ViewMatrix; |
||||
uniform vec4 g_LightData[NB_LIGHTS]; |
||||
varying vec3 vPos; |
||||
#else |
||||
varying vec3 specularAccum; |
||||
varying vec4 diffuseAccum; |
||||
#endif |
||||
|
||||
#ifdef DIFFUSEMAP |
||||
uniform sampler2D m_DiffuseMap; |
||||
#endif |
||||
|
||||
#ifdef SPECULARMAP |
||||
uniform sampler2D m_SpecularMap; |
||||
#endif |
||||
|
||||
#ifdef PARALLAXMAP |
||||
uniform sampler2D m_ParallaxMap; |
||||
#endif |
||||
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING) |
||||
uniform float m_ParallaxHeight; |
||||
#endif |
||||
|
||||
#ifdef LIGHTMAP |
||||
uniform sampler2D m_LightMap; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
uniform sampler2D m_NormalMap; |
||||
varying vec3 vTangent; |
||||
varying vec3 vBinormal; |
||||
#endif |
||||
varying vec3 vNormal; |
||||
|
||||
#ifdef ALPHAMAP |
||||
uniform sampler2D m_AlphaMap; |
||||
#endif |
||||
|
||||
#ifdef COLORRAMP |
||||
uniform sampler2D m_ColorRamp; |
||||
#endif |
||||
|
||||
uniform float m_AlphaDiscardThreshold; |
||||
|
||||
#ifndef VERTEX_LIGHTING |
||||
uniform float m_Shininess; |
||||
|
||||
#ifdef USE_REFLECTION |
||||
uniform float m_ReflectionPower; |
||||
uniform float m_ReflectionIntensity; |
||||
varying vec4 refVec; |
||||
|
||||
uniform ENVMAP m_EnvMap; |
||||
#endif |
||||
#endif |
||||
|
||||
void main(){ |
||||
vec2 newTexCoord; |
||||
|
||||
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING) |
||||
|
||||
#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 DIFFUSEMAP |
||||
vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord); |
||||
#else |
||||
vec4 diffuseColor = vec4(1.0); |
||||
#endif |
||||
|
||||
float alpha = DiffuseSum.a * diffuseColor.a; |
||||
|
||||
#ifdef ALPHAMAP |
||||
alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r; |
||||
#endif |
||||
|
||||
#ifdef DISCARD_ALPHA |
||||
if(alpha < m_AlphaDiscardThreshold){ |
||||
discard; |
||||
} |
||||
#endif |
||||
|
||||
// *********************** |
||||
// Read from textures |
||||
// *********************** |
||||
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) |
||||
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))); |
||||
#elif !defined(VERTEX_LIGHTING) |
||||
vec3 normal = normalize(vNormal); |
||||
#endif |
||||
|
||||
#ifdef SPECULARMAP |
||||
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); |
||||
#else |
||||
vec4 specularColor = vec4(1.0); |
||||
#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; |
||||
diffuseColor.rgb *= lightMapColor; |
||||
#endif |
||||
|
||||
#ifdef VERTEX_LIGHTING |
||||
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb |
||||
+diffuseAccum.rgb *diffuseColor.rgb |
||||
+specularAccum.rgb * specularColor.rgb; |
||||
gl_FragColor.a=1.0; |
||||
#else |
||||
|
||||
int i = 0; |
||||
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb; |
||||
|
||||
#ifdef USE_REFLECTION |
||||
vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz); |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz)); |
||||
#endif |
||||
|
||||
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(vPos, lightColor.w, lightData1, lightDir,lightVec); |
||||
|
||||
float spotFallOff = 1.0; |
||||
#if __VERSION__ >= 110 |
||||
// allow use of control flow |
||||
if(lightColor.w > 1.0){ |
||||
#endif |
||||
spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec); |
||||
#if __VERSION__ >= 110 |
||||
} |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
//Normal map -> lighting is computed in tangent space |
||||
lightDir.xyz = normalize(lightDir.xyz * tbnMat); |
||||
vec3 viewDir = normalize(-vPos.xyz * tbnMat); |
||||
#else |
||||
//no Normal map -> lighting is computed in view space |
||||
lightDir.xyz = normalize(lightDir.xyz); |
||||
vec3 viewDir = normalize(-vPos.xyz); |
||||
#endif |
||||
|
||||
vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff , m_Shininess); |
||||
|
||||
#ifdef COLORRAMP |
||||
diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb; |
||||
specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb; |
||||
#endif |
||||
|
||||
// Workaround, since it is not possible to modify varying variables |
||||
vec4 SpecularSum2 = vec4(SpecularSum, 1.0); |
||||
#ifdef USE_REFLECTION |
||||
// Interpolate light specularity toward reflection color |
||||
// Multiply result by specular map |
||||
specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor; |
||||
|
||||
SpecularSum2 = vec4(1.0); |
||||
light.y = 1.0; |
||||
#endif |
||||
|
||||
gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) + |
||||
SpecularSum2.rgb * specularColor.rgb * vec3(light.y); |
||||
} |
||||
|
||||
#endif |
||||
gl_FragColor.a = alpha; |
||||
} |
@ -0,0 +1,172 @@ |
||||
#import "Common/ShaderLib/Instancing.glsllib" |
||||
#import "Common/ShaderLib/Skinning.glsllib" |
||||
#import "Common/ShaderLib/Lighting.glsllib" |
||||
#ifdef VERTEX_LIGHTING |
||||
#import "Common/ShaderLib/PhongLighting.glsllib" |
||||
#endif |
||||
|
||||
|
||||
uniform vec4 m_Ambient; |
||||
uniform vec4 m_Diffuse; |
||||
uniform vec4 m_Specular; |
||||
uniform float m_Shininess; |
||||
|
||||
#if defined(VERTEX_LIGHTING) |
||||
uniform vec4 g_LightData[NB_LIGHTS]; |
||||
#endif |
||||
uniform vec4 g_AmbientLightColor; |
||||
varying vec2 texCoord; |
||||
|
||||
#ifdef SEPARATE_TEXCOORD |
||||
varying vec2 texCoord2; |
||||
attribute vec2 inTexCoord2; |
||||
#endif |
||||
|
||||
varying vec3 AmbientSum; |
||||
varying vec4 DiffuseSum; |
||||
varying vec3 SpecularSum; |
||||
|
||||
attribute vec3 inPosition; |
||||
attribute vec2 inTexCoord; |
||||
attribute vec3 inNormal; |
||||
|
||||
#ifdef VERTEX_COLOR |
||||
attribute vec4 inColor; |
||||
#endif |
||||
|
||||
#ifndef VERTEX_LIGHTING |
||||
varying vec3 vNormal; |
||||
varying vec3 vPos; |
||||
#ifdef NORMALMAP |
||||
attribute vec4 inTangent; |
||||
varying vec3 vTangent; |
||||
varying vec3 vBinormal; |
||||
#endif |
||||
#else |
||||
varying vec3 specularAccum; |
||||
varying vec4 diffuseAccum; |
||||
#endif |
||||
|
||||
#ifdef USE_REFLECTION |
||||
uniform vec3 g_CameraPosition; |
||||
uniform vec3 m_FresnelParams; |
||||
varying vec4 refVec; |
||||
|
||||
/** |
||||
* Input: |
||||
* attribute inPosition |
||||
* attribute inNormal |
||||
* uniform g_WorldMatrix |
||||
* uniform g_CameraPosition |
||||
* |
||||
* Output: |
||||
* varying refVec |
||||
*/ |
||||
void computeRef(in vec4 modelSpacePos){ |
||||
// vec3 worldPos = (g_WorldMatrix * modelSpacePos).xyz; |
||||
vec3 worldPos = TransformWorld(modelSpacePos).xyz; |
||||
|
||||
vec3 I = normalize( g_CameraPosition - worldPos ).xyz; |
||||
// vec3 N = normalize( (g_WorldMatrix * vec4(inNormal, 0.0)).xyz ); |
||||
vec3 N = normalize( TransformWorld(vec4(inNormal, 0.0)).xyz ); |
||||
|
||||
refVec.xyz = reflect(I, N); |
||||
refVec.w = m_FresnelParams.x + m_FresnelParams.y * pow(1.0 + dot(I, N), m_FresnelParams.z); |
||||
} |
||||
#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 |
||||
|
||||
vec3 wvPosition = TransformWorldView(modelSpacePos).xyz; |
||||
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm)); |
||||
vec3 viewDir = normalize(-wvPosition); |
||||
|
||||
|
||||
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) |
||||
vTangent = TransformNormal(modelSpaceTan); |
||||
vBinormal = cross(wvNormal, vTangent)* inTangent.w; |
||||
vNormal = wvNormal; |
||||
vPos = wvPosition; |
||||
#elif !defined(VERTEX_LIGHTING) |
||||
vNormal = wvNormal; |
||||
vPos = wvPosition; |
||||
#endif |
||||
|
||||
#ifdef MATERIAL_COLORS |
||||
AmbientSum = m_Ambient.rgb * g_AmbientLightColor.rgb; |
||||
SpecularSum = m_Specular.rgb; |
||||
DiffuseSum = m_Diffuse; |
||||
#else |
||||
AmbientSum = g_AmbientLightColor.rgb; |
||||
SpecularSum = vec3(0.0); |
||||
DiffuseSum = vec4(1.0); |
||||
#endif |
||||
#ifdef VERTEX_COLOR |
||||
AmbientSum *= inColor.rgb; |
||||
DiffuseSum *= inColor; |
||||
#endif |
||||
#ifdef VERTEX_LIGHTING |
||||
int i = 0; |
||||
diffuseAccum = vec4(0.0); |
||||
specularAccum = vec3(0.0); |
||||
vec4 diffuseColor; |
||||
vec3 specularColor; |
||||
for (int i =0;i < NB_LIGHTS; i+=3){ |
||||
vec4 lightColor = g_LightData[i]; |
||||
vec4 lightData1 = g_LightData[i+1]; |
||||
DiffuseSum = vec4(1.0); |
||||
#ifdef MATERIAL_COLORS |
||||
diffuseColor = m_Diffuse * vec4(lightColor.rgb, 1.0); |
||||
specularColor = m_Specular.rgb * lightColor.rgb; |
||||
#else |
||||
diffuseColor = vec4(lightColor.rgb, 1.0); |
||||
specularColor = vec3(0.0); |
||||
#endif |
||||
|
||||
vec4 lightDir; |
||||
vec3 lightVec; |
||||
lightComputeDir(wvPosition, lightColor.w, lightData1, lightDir, lightVec); |
||||
// lightDir = normalize(lightDir); |
||||
// lightVec = normalize(lightVec); |
||||
|
||||
float spotFallOff = 1.0; |
||||
#if __VERSION__ >= 110 |
||||
// allow use of control flow |
||||
if(lightColor.w > 1.0){ |
||||
#endif |
||||
vec4 lightDirection = g_LightData[i+2]; |
||||
spotFallOff = computeSpotFalloff(lightDirection, lightVec); |
||||
#if __VERSION__ >= 110 |
||||
} |
||||
#endif |
||||
vec2 v = computeLighting(wvNormal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess); |
||||
diffuseAccum +=v.x * diffuseColor; |
||||
specularAccum += v.y * specularColor; |
||||
} |
||||
#endif |
||||
|
||||
|
||||
#ifdef USE_REFLECTION |
||||
computeRef(modelSpacePos); |
||||
#endif |
||||
} |
@ -1,48 +1,30 @@ |
||||
#ifndef NUM_LIGHTS |
||||
#define NUM_LIGHTS 4 |
||||
#endif |
||||
/*Common function for light calculations*/ |
||||
|
||||
uniform mat4 g_ViewMatrix; |
||||
uniform vec4 g_LightPosition[NUM_LIGHTS]; |
||||
uniform vec4 g_g_LightColor[NUM_LIGHTS]; |
||||
uniform float m_Shininess; |
||||
|
||||
float Lighting_Diffuse(vec3 norm, vec3 lightdir){ |
||||
return max(0.0, dot(norm, lightdir)); |
||||
} |
||||
|
||||
float Lighting_Specular(vec3 norm, vec3 viewdir, vec3 lightdir, float shiny){ |
||||
vec3 refdir = reflect(-lightdir, norm); |
||||
return pow(max(dot(refdir, viewdir), 0.0), shiny); |
||||
} |
||||
|
||||
void Lighting_Direction(vec3 worldPos, vec4 color, vec4 position, out vec4 lightDir){ |
||||
float posLight = step(0.5, color.w); |
||||
/* |
||||
* Computes light direction |
||||
* lightType should be 0.0,1.0,2.0, repectively for Directional, point and spot lights. |
||||
* Outputs the light direction and the light half vector. |
||||
*/ |
||||
void lightComputeDir(in vec3 worldPos, in float ligthType, in vec4 position, out vec4 lightDir, out vec3 lightVec){ |
||||
float posLight = step(0.5, ligthType); |
||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight); |
||||
lightVec = tempVec; |
||||
float dist = length(tempVec); |
||||
|
||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0); |
||||
lightDir.xyz = tempVec / dist; |
||||
lightDir.xyz = tempVec / vec3(dist); |
||||
} |
||||
|
||||
void Lighting_ComputePS(vec3 tanNormal, mat3 tbnMat, |
||||
int lightCount, out vec3 outDiffuse, out vec3 outSpecular){ |
||||
// find tangent view dir & vert pos |
||||
vec3 tanViewDir = viewDir * tbnMat; |
||||
|
||||
for (int i = 0; i < lightCount; i++){ |
||||
// find light dir in tangent space, works for point & directional lights |
||||
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition[i].xyz, g_LightColor[i].w)); |
||||
wvLightPos.w = g_LightPosition[i].w; |
||||
|
||||
vec4 tanLightDir; |
||||
Lighting_Direction(wvPosition, g_LightColor[i], wvLightPos, tanLightDir); |
||||
tanLightDir.xyz = tanLightDir.xyz * tbnMat; |
||||
|
||||
vec3 lightScale = g_LightColor[i].rgb * tanLightDir.w; |
||||
float specular = Lighting_Specular(tanNormal, tanViewDir, tanLightDir.xyz, m_Shininess); |
||||
float diffuse = Lighting_Diffuse(tanNormal, tanLightDir.xyz); |
||||
outSpecular += specular * lightScale * step(0.01, diffuse) * g_LightColor[i].rgb; |
||||
outDiffuse += diffuse * lightScale * g_LightColor[i].rgb; |
||||
} |
||||
/* |
||||
* Computes the spot falloff for a spotlight |
||||
*/ |
||||
float computeSpotFalloff(in vec4 lightDirection, in vec3 lightVector){ |
||||
vec3 L=normalize(lightVector); |
||||
vec3 spotdir = normalize(lightDirection.xyz); |
||||
float curAngleCos = dot(-L, spotdir); |
||||
float innerAngleCos = floor(lightDirection.w) * 0.001; |
||||
float outerAngleCos = fract(lightDirection.w); |
||||
float innerMinusOuter = innerAngleCos - outerAngleCos; |
||||
return clamp((curAngleCos - outerAngleCos) / innerMinusOuter, step(lightDirection.w, 0.001), 1.0); |
||||
} |
||||
|
||||
|
@ -0,0 +1,29 @@ |
||||
/*Standard Phong ligting*/ |
||||
|
||||
/* |
||||
* Computes diffuse factor |
||||
*/ |
||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){ |
||||
return max(0.0, dot(norm, lightdir)); |
||||
} |
||||
|
||||
/* |
||||
* Computes specular factor |
||||
*/ |
||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){ |
||||
vec3 R = reflect(-lightdir, norm); |
||||
return pow(max(dot(R, viewdir), 0.0), shiny); |
||||
} |
||||
|
||||
/* |
||||
* Computes diffuse and specular factors and pack them in a vec2 (x=diffuse, y=specular) |
||||
*/ |
||||
vec2 computeLighting(in vec3 norm, in vec3 viewDir, in vec3 lightDir, in float attenuation, in float shininess){ |
||||
float diffuseFactor = lightComputeDiffuse(norm, lightDir); |
||||
float specularFactor = lightComputeSpecular(norm, viewDir, lightDir, shininess); |
||||
if (shininess <= 1.0) { |
||||
specularFactor = 0.0; // should be one instruction on most cards .. |
||||
} |
||||
specularFactor *= diffuseFactor; |
||||
return vec2(diffuseFactor, specularFactor) * vec2(attenuation); |
||||
} |
@ -0,0 +1,255 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 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.BasicProfilerState; |
||||
import com.jme3.app.SimpleApplication; |
||||
import com.jme3.font.BitmapText; |
||||
import com.jme3.input.KeyInput; |
||||
import com.jme3.input.controls.ActionListener; |
||||
import com.jme3.input.controls.KeyTrigger; |
||||
import com.jme3.light.AmbientLight; |
||||
import com.jme3.light.DirectionalLight; |
||||
import com.jme3.light.Light; |
||||
import com.jme3.light.LightList; |
||||
import com.jme3.light.PointLight; |
||||
import com.jme3.light.SpotLight; |
||||
import com.jme3.material.Material; |
||||
import com.jme3.material.TechniqueDef; |
||||
import com.jme3.math.ColorRGBA; |
||||
import com.jme3.math.FastMath; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.LightNode; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
import com.jme3.scene.control.AbstractControl; |
||||
import com.jme3.scene.shape.Box; |
||||
|
||||
public class TestManyLightsSingle extends SimpleApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
TestManyLightsSingle app = new TestManyLightsSingle(); |
||||
app.start(); |
||||
} |
||||
TechniqueDef.LightMode lm = TechniqueDef.LightMode.MultiPass; |
||||
int lightNum = 6 ; |
||||
|
||||
@Override |
||||
public void simpleInitApp() { |
||||
renderManager.setPreferredLightMode(lm); |
||||
renderManager.setSinglePassLightBatchSize(lightNum); |
||||
|
||||
|
||||
flyCam.setMoveSpeed(10); |
||||
|
||||
Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene"); |
||||
rootNode.attachChild(scene); |
||||
Node n = (Node) rootNode.getChild(0); |
||||
LightList lightList = n.getWorldLightList(); |
||||
Geometry g = (Geometry) n.getChild("Grid-geom-1"); |
||||
|
||||
g.getMaterial().setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); |
||||
|
||||
/* A colored lit cube. Needs light source! */ |
||||
Box boxMesh = new Box(1f, 1f, 1f); |
||||
Geometry boxGeo = new Geometry("Colored Box", boxMesh); |
||||
Material boxMat = g.getMaterial().clone(); |
||||
boxMat.setBoolean("UseMaterialColors", true); |
||||
boxMat.setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); |
||||
boxMat.setColor("Diffuse", ColorRGBA.Blue); |
||||
boxGeo.setMaterial(boxMat); |
||||
|
||||
int nb = 0; |
||||
for (Light light : lightList) { |
||||
nb++; |
||||
PointLight p = (PointLight) light; |
||||
if (nb >60) { |
||||
n.removeLight(light); |
||||
} else { |
||||
|
||||
LightNode ln = new LightNode("l", light); |
||||
n.attachChild(ln); |
||||
ln.setLocalTranslation(p.getPosition()); |
||||
int rand = FastMath.nextRandomInt(0, 3); |
||||
switch (rand) { |
||||
case 0: |
||||
light.setColor(ColorRGBA.Red); |
||||
// ln.addControl(new MoveControl(5f));
|
||||
break; |
||||
case 1: |
||||
light.setColor(ColorRGBA.Yellow); |
||||
// ln.addControl(new MoveControl(5f));
|
||||
break; |
||||
case 2: |
||||
light.setColor(ColorRGBA.Green); |
||||
//ln.addControl(new MoveControl(-5f));
|
||||
break; |
||||
case 3: |
||||
light.setColor(ColorRGBA.Orange); |
||||
//ln.addControl(new MoveControl(-5f));
|
||||
break; |
||||
} |
||||
} |
||||
Geometry b = boxGeo.clone(); |
||||
n.attachChild(b); |
||||
b.setLocalTranslation(p.getPosition().x, 2, p.getPosition().z); |
||||
|
||||
} |
||||
|
||||
|
||||
// cam.setLocation(new Vector3f(3.1893547f, 17.977385f, 30.8378f));
|
||||
// cam.setRotation(new Quaternion(0.14317635f, 0.82302624f, -0.23777823f, 0.49557027f));
|
||||
|
||||
cam.setLocation(new Vector3f(-1.8901939f, 29.34097f, 73.07533f)); |
||||
cam.setRotation(new Quaternion(0.0021000702f, 0.971012f, -0.23886925f, 0.008527749f)); |
||||
|
||||
|
||||
BasicProfilerState profiler = new BasicProfilerState(true); |
||||
profiler.setGraphScale(1000f); |
||||
|
||||
// getStateManager().attach(profiler);
|
||||
// guiNode.setCullHint(CullHint.Always);
|
||||
|
||||
|
||||
|
||||
|
||||
flyCam.setDragToRotate(true); |
||||
flyCam.setMoveSpeed(50); |
||||
|
||||
|
||||
inputManager.addListener(new ActionListener() { |
||||
public void onAction(String name, boolean isPressed, float tpf) { |
||||
if (name.equals("toggle") && isPressed) { |
||||
if (lm == TechniqueDef.LightMode.SinglePass) { |
||||
lm = TechniqueDef.LightMode.MultiPass; |
||||
} else { |
||||
lm = TechniqueDef.LightMode.SinglePass; |
||||
} |
||||
renderManager.setPreferredLightMode(lm); |
||||
} |
||||
if (name.equals("lightsUp") && isPressed) { |
||||
lightNum++; |
||||
renderManager.setSinglePassLightBatchSize(lightNum); |
||||
helloText.setText("nb lights per batch : " + lightNum); |
||||
} |
||||
if (name.equals("lightsDown") && isPressed) { |
||||
lightNum--; |
||||
renderManager.setSinglePassLightBatchSize(lightNum); |
||||
helloText.setText("nb lights per batch : " + lightNum); |
||||
} |
||||
} |
||||
}, "toggle", "lightsUp", "lightsDown"); |
||||
|
||||
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); |
||||
inputManager.addMapping("lightsUp", new KeyTrigger(KeyInput.KEY_UP)); |
||||
inputManager.addMapping("lightsDown", new KeyTrigger(KeyInput.KEY_DOWN)); |
||||
|
||||
|
||||
SpotLight spot = new SpotLight(); |
||||
spot.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal()); |
||||
spot.setColor(ColorRGBA.Blue.mult(5)); |
||||
spot.setSpotOuterAngle(FastMath.DEG_TO_RAD * 20); |
||||
spot.setSpotInnerAngle(FastMath.DEG_TO_RAD * 5); |
||||
spot.setPosition(new Vector3f(10, 10, 20)); |
||||
rootNode.addLight(spot); |
||||
|
||||
DirectionalLight dl = new DirectionalLight(); |
||||
dl.setDirection(new Vector3f(-1, -1, 1)); |
||||
rootNode.addLight(dl); |
||||
|
||||
AmbientLight al = new AmbientLight(); |
||||
al.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); |
||||
rootNode.addLight(al); |
||||
|
||||
|
||||
/** |
||||
* Write text on the screen (HUD) |
||||
*/ |
||||
guiNode.detachAllChildren(); |
||||
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); |
||||
helloText = new BitmapText(guiFont, false); |
||||
helloText.setSize(guiFont.getCharSet().getRenderedSize()); |
||||
helloText.setText("nb lights per batch : " + lightNum); |
||||
helloText.setLocalTranslation(300, helloText.getLineHeight(), 0); |
||||
guiNode.attachChild(helloText); |
||||
|
||||
|
||||
} |
||||
BitmapText helloText; |
||||
long time; |
||||
long nbFrames; |
||||
long startTime = 0; |
||||
|
||||
@Override |
||||
public void simpleUpdate(float tpf) { |
||||
// if (nbFrames == 4000) {
|
||||
// startTime = System.nanoTime();
|
||||
// }
|
||||
// if (nbFrames > 4000) {
|
||||
// time = System.nanoTime();
|
||||
// float average = ((float) time - (float) startTime) / ((float) nbFrames - 4000f);
|
||||
// helloText.setText("Average = " + average);
|
||||
// }
|
||||
// nbFrames++;
|
||||
} |
||||
|
||||
class MoveControl extends AbstractControl { |
||||
|
||||
float direction; |
||||
Vector3f origPos = new Vector3f(); |
||||
|
||||
public MoveControl(float direction) { |
||||
this.direction = direction; |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
super.setSpatial(spatial); //To change body of generated methods, choose Tools | Templates.
|
||||
origPos.set(spatial.getLocalTranslation()); |
||||
} |
||||
float time = 0; |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
time += tpf; |
||||
spatial.setLocalTranslation(origPos.x + FastMath.cos(time) * direction, origPos.y, origPos.z + FastMath.sin(time) * direction); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,615 @@ |
||||
#import "Common/ShaderLib/PhongLighting.glsllib" |
||||
#import "Common/ShaderLib/Lighting.glsllib" |
||||
|
||||
uniform float m_Shininess; |
||||
|
||||
varying vec4 AmbientSum; |
||||
varying vec4 DiffuseSum; |
||||
varying vec4 SpecularSum; |
||||
|
||||
uniform mat4 g_ViewMatrix; |
||||
uniform vec4 g_LightData[NB_LIGHTS]; |
||||
varying vec3 vTangent; |
||||
varying vec3 vBinormal; |
||||
varying vec3 vPos; |
||||
varying vec3 vNormal; |
||||
varying vec2 texCoord; |
||||
|
||||
|
||||
#ifdef DIFFUSEMAP |
||||
uniform sampler2D m_DiffuseMap; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_1 |
||||
uniform sampler2D m_DiffuseMap_1; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_2 |
||||
uniform sampler2D m_DiffuseMap_2; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_3 |
||||
uniform sampler2D m_DiffuseMap_3; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_4 |
||||
uniform sampler2D m_DiffuseMap_4; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_5 |
||||
uniform sampler2D m_DiffuseMap_5; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_6 |
||||
uniform sampler2D m_DiffuseMap_6; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_7 |
||||
uniform sampler2D m_DiffuseMap_7; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_8 |
||||
uniform sampler2D m_DiffuseMap_8; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_9 |
||||
uniform sampler2D m_DiffuseMap_9; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_10 |
||||
uniform sampler2D m_DiffuseMap_10; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_11 |
||||
uniform sampler2D m_DiffuseMap_11; |
||||
#endif |
||||
|
||||
|
||||
#ifdef DIFFUSEMAP_0_SCALE |
||||
uniform float m_DiffuseMap_0_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_1_SCALE |
||||
uniform float m_DiffuseMap_1_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_2_SCALE |
||||
uniform float m_DiffuseMap_2_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_3_SCALE |
||||
uniform float m_DiffuseMap_3_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_4_SCALE |
||||
uniform float m_DiffuseMap_4_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_5_SCALE |
||||
uniform float m_DiffuseMap_5_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_6_SCALE |
||||
uniform float m_DiffuseMap_6_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_7_SCALE |
||||
uniform float m_DiffuseMap_7_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_8_SCALE |
||||
uniform float m_DiffuseMap_8_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_9_SCALE |
||||
uniform float m_DiffuseMap_9_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_10_SCALE |
||||
uniform float m_DiffuseMap_10_scale; |
||||
#endif |
||||
#ifdef DIFFUSEMAP_11_SCALE |
||||
uniform float m_DiffuseMap_11_scale; |
||||
#endif |
||||
|
||||
|
||||
#ifdef ALPHAMAP |
||||
uniform sampler2D m_AlphaMap; |
||||
#endif |
||||
#ifdef ALPHAMAP_1 |
||||
uniform sampler2D m_AlphaMap_1; |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
uniform sampler2D m_AlphaMap_2; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
uniform sampler2D m_NormalMap; |
||||
#endif |
||||
#ifdef NORMALMAP_1 |
||||
uniform sampler2D m_NormalMap_1; |
||||
#endif |
||||
#ifdef NORMALMAP_2 |
||||
uniform sampler2D m_NormalMap_2; |
||||
#endif |
||||
#ifdef NORMALMAP_3 |
||||
uniform sampler2D m_NormalMap_3; |
||||
#endif |
||||
#ifdef NORMALMAP_4 |
||||
uniform sampler2D m_NormalMap_4; |
||||
#endif |
||||
#ifdef NORMALMAP_5 |
||||
uniform sampler2D m_NormalMap_5; |
||||
#endif |
||||
#ifdef NORMALMAP_6 |
||||
uniform sampler2D m_NormalMap_6; |
||||
#endif |
||||
#ifdef NORMALMAP_7 |
||||
uniform sampler2D m_NormalMap_7; |
||||
#endif |
||||
#ifdef NORMALMAP_8 |
||||
uniform sampler2D m_NormalMap_8; |
||||
#endif |
||||
#ifdef NORMALMAP_9 |
||||
uniform sampler2D m_NormalMap_9; |
||||
#endif |
||||
#ifdef NORMALMAP_10 |
||||
uniform sampler2D m_NormalMap_10; |
||||
#endif |
||||
#ifdef NORMALMAP_11 |
||||
uniform sampler2D m_NormalMap_11; |
||||
#endif |
||||
|
||||
|
||||
#ifdef TRI_PLANAR_MAPPING |
||||
varying vec4 wVertex; |
||||
varying vec3 wNormal; |
||||
#endif |
||||
|
||||
|
||||
#ifdef ALPHAMAP |
||||
|
||||
vec4 calculateDiffuseBlend(in vec2 texCoord) { |
||||
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy ); |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy ); |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy ); |
||||
#endif |
||||
|
||||
vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord * m_DiffuseMap_0_scale); |
||||
diffuseColor *= alphaBlend.r; |
||||
#ifdef DIFFUSEMAP_1 |
||||
vec4 diffuseColor1 = texture2D(m_DiffuseMap_1, texCoord * m_DiffuseMap_1_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor1, alphaBlend.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_2 |
||||
vec4 diffuseColor2 = texture2D(m_DiffuseMap_2, texCoord * m_DiffuseMap_2_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor2, alphaBlend.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_3 |
||||
vec4 diffuseColor3 = texture2D(m_DiffuseMap_3, texCoord * m_DiffuseMap_3_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor3, alphaBlend.a ); |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
#ifdef DIFFUSEMAP_4 |
||||
vec4 diffuseColor4 = texture2D(m_DiffuseMap_4, texCoord * m_DiffuseMap_4_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor4, alphaBlend1.r ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_5 |
||||
vec4 diffuseColor5 = texture2D(m_DiffuseMap_5, texCoord * m_DiffuseMap_5_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor5, alphaBlend1.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_6 |
||||
vec4 diffuseColor6 = texture2D(m_DiffuseMap_6, texCoord * m_DiffuseMap_6_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor6, alphaBlend1.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_7 |
||||
vec4 diffuseColor7 = texture2D(m_DiffuseMap_7, texCoord * m_DiffuseMap_7_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor7, alphaBlend1.a ); |
||||
#endif |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_2 |
||||
#ifdef DIFFUSEMAP_8 |
||||
vec4 diffuseColor8 = texture2D(m_DiffuseMap_8, texCoord * m_DiffuseMap_8_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor8, alphaBlend2.r ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_9 |
||||
vec4 diffuseColor9 = texture2D(m_DiffuseMap_9, texCoord * m_DiffuseMap_9_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor9, alphaBlend2.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_10 |
||||
vec4 diffuseColor10 = texture2D(m_DiffuseMap_10, texCoord * m_DiffuseMap_10_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor10, alphaBlend2.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_11 |
||||
vec4 diffuseColor11 = texture2D(m_DiffuseMap_11, texCoord * m_DiffuseMap_11_scale); |
||||
diffuseColor = mix( diffuseColor, diffuseColor11, alphaBlend2.a ); |
||||
#endif |
||||
#endif |
||||
|
||||
return diffuseColor; |
||||
} |
||||
|
||||
vec3 calculateNormal(in vec2 texCoord) { |
||||
vec3 normal = vec3(0,0,1); |
||||
vec3 n = vec3(0,0,0); |
||||
|
||||
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy ); |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy ); |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy ); |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
n = texture2D(m_NormalMap, texCoord * m_DiffuseMap_0_scale).xyz; |
||||
normal += n * alphaBlend.r; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_1 |
||||
n = texture2D(m_NormalMap_1, texCoord * m_DiffuseMap_1_scale).xyz; |
||||
normal += n * alphaBlend.g; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_2 |
||||
n = texture2D(m_NormalMap_2, texCoord * m_DiffuseMap_2_scale).xyz; |
||||
normal += n * alphaBlend.b; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_3 |
||||
n = texture2D(m_NormalMap_3, texCoord * m_DiffuseMap_3_scale).xyz; |
||||
normal += n * alphaBlend.a; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.a; |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
#ifdef NORMALMAP_4 |
||||
n = texture2D(m_NormalMap_4, texCoord * m_DiffuseMap_4_scale).xyz; |
||||
normal += n * alphaBlend1.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_5 |
||||
n = texture2D(m_NormalMap_5, texCoord * m_DiffuseMap_5_scale).xyz; |
||||
normal += n * alphaBlend1.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_6 |
||||
n = texture2D(m_NormalMap_6, texCoord * m_DiffuseMap_6_scale).xyz; |
||||
normal += n * alphaBlend1.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_7 |
||||
n = texture2D(m_NormalMap_7, texCoord * m_DiffuseMap_7_scale).xyz; |
||||
normal += n * alphaBlend1.a; |
||||
#endif |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_2 |
||||
#ifdef NORMALMAP_8 |
||||
n = texture2D(m_NormalMap_8, texCoord * m_DiffuseMap_8_scale).xyz; |
||||
normal += n * alphaBlend2.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_9 |
||||
n = texture2D(m_NormalMap_9, texCoord * m_DiffuseMap_9_scale); |
||||
normal += n * alphaBlend2.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_10 |
||||
n = texture2D(m_NormalMap_10, texCoord * m_DiffuseMap_10_scale); |
||||
normal += n * alphaBlend2.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_11 |
||||
n = texture2D(m_NormalMap_11, texCoord * m_DiffuseMap_11_scale); |
||||
normal += n * alphaBlend2.a; |
||||
#endif |
||||
#endif |
||||
|
||||
normal = (normal.xyz * vec3(2.0) - vec3(1.0)); |
||||
return normalize(normal); |
||||
} |
||||
|
||||
#ifdef TRI_PLANAR_MAPPING |
||||
|
||||
vec4 getTriPlanarBlend(in vec4 coords, in vec3 blending, in sampler2D map, in float scale) { |
||||
vec4 col1 = texture2D( map, coords.yz * scale); |
||||
vec4 col2 = texture2D( map, coords.xz * scale); |
||||
vec4 col3 = texture2D( map, coords.xy * scale); |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex = col1 * blending.x + col2 * blending.y + col3 * blending.z; |
||||
return tex; |
||||
} |
||||
|
||||
vec4 calculateTriPlanarDiffuseBlend(in vec3 wNorm, in vec4 wVert, in vec2 texCoord) { |
||||
// tri-planar texture bending factor for this fragment's normal |
||||
vec3 blending = abs( wNorm ); |
||||
blending = (blending -0.2) * 0.7; |
||||
blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!) |
||||
float b = (blending.x + blending.y + blending.z); |
||||
blending /= vec3(b, b, b); |
||||
|
||||
// texture coords |
||||
vec4 coords = wVert; |
||||
|
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex0 = getTriPlanarBlend(coords, blending, m_DiffuseMap, m_DiffuseMap_0_scale); |
||||
|
||||
#ifdef DIFFUSEMAP_1 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex1 = getTriPlanarBlend(coords, blending, m_DiffuseMap_1, m_DiffuseMap_1_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_2 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex2 = getTriPlanarBlend(coords, blending, m_DiffuseMap_2, m_DiffuseMap_2_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_3 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex3 = getTriPlanarBlend(coords, blending, m_DiffuseMap_3, m_DiffuseMap_3_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_4 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex4 = getTriPlanarBlend(coords, blending, m_DiffuseMap_4, m_DiffuseMap_4_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_5 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex5 = getTriPlanarBlend(coords, blending, m_DiffuseMap_5, m_DiffuseMap_5_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_6 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex6 = getTriPlanarBlend(coords, blending, m_DiffuseMap_6, m_DiffuseMap_6_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_7 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex7 = getTriPlanarBlend(coords, blending, m_DiffuseMap_7, m_DiffuseMap_7_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_8 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex8 = getTriPlanarBlend(coords, blending, m_DiffuseMap_8, m_DiffuseMap_8_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_9 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex9 = getTriPlanarBlend(coords, blending, m_DiffuseMap_9, m_DiffuseMap_9_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_10 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex10 = getTriPlanarBlend(coords, blending, m_DiffuseMap_10, m_DiffuseMap_10_scale); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_11 |
||||
// blend the results of the 3 planar projections. |
||||
vec4 tex11 = getTriPlanarBlend(coords, blending, m_DiffuseMap_11, m_DiffuseMap_11_scale); |
||||
#endif |
||||
|
||||
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy ); |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy ); |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy ); |
||||
#endif |
||||
|
||||
vec4 diffuseColor = tex0 * alphaBlend.r; |
||||
#ifdef DIFFUSEMAP_1 |
||||
diffuseColor = mix( diffuseColor, tex1, alphaBlend.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_2 |
||||
diffuseColor = mix( diffuseColor, tex2, alphaBlend.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_3 |
||||
diffuseColor = mix( diffuseColor, tex3, alphaBlend.a ); |
||||
#endif |
||||
#ifdef ALPHAMAP_1 |
||||
#ifdef DIFFUSEMAP_4 |
||||
diffuseColor = mix( diffuseColor, tex4, alphaBlend1.r ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_5 |
||||
diffuseColor = mix( diffuseColor, tex5, alphaBlend1.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_6 |
||||
diffuseColor = mix( diffuseColor, tex6, alphaBlend1.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_7 |
||||
diffuseColor = mix( diffuseColor, tex7, alphaBlend1.a ); |
||||
#endif |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
#ifdef DIFFUSEMAP_8 |
||||
diffuseColor = mix( diffuseColor, tex8, alphaBlend2.r ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_9 |
||||
diffuseColor = mix( diffuseColor, tex9, alphaBlend2.g ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_10 |
||||
diffuseColor = mix( diffuseColor, tex10, alphaBlend2.b ); |
||||
#endif |
||||
#ifdef DIFFUSEMAP_11 |
||||
diffuseColor = mix( diffuseColor, tex11, alphaBlend2.a ); |
||||
#endif |
||||
#endif |
||||
|
||||
return diffuseColor; |
||||
} |
||||
|
||||
vec3 calculateNormalTriPlanar(in vec3 wNorm, in vec4 wVert,in vec2 texCoord) { |
||||
// tri-planar texture bending factor for this fragment's world-space normal |
||||
vec3 blending = abs( wNorm ); |
||||
blending = (blending -0.2) * 0.7; |
||||
blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!) |
||||
float b = (blending.x + blending.y + blending.z); |
||||
blending /= vec3(b, b, b); |
||||
|
||||
// texture coords |
||||
vec4 coords = wVert; |
||||
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy ); |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy ); |
||||
#endif |
||||
#ifdef ALPHAMAP_2 |
||||
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy ); |
||||
#endif |
||||
|
||||
vec3 normal = vec3(0,0,1); |
||||
vec3 n = vec3(0,0,0); |
||||
|
||||
#ifdef NORMALMAP |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap, m_DiffuseMap_0_scale).xyz; |
||||
normal += n * alphaBlend.r; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_1 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_1, m_DiffuseMap_1_scale).xyz; |
||||
normal += n * alphaBlend.g; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_2 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_2, m_DiffuseMap_2_scale).xyz; |
||||
normal += n * alphaBlend.b; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_3 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_3, m_DiffuseMap_3_scale).xyz; |
||||
normal += n * alphaBlend.a; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.a; |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_1 |
||||
#ifdef NORMALMAP_4 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_4, m_DiffuseMap_4_scale).xyz; |
||||
normal += n * alphaBlend1.r; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_5 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_5, m_DiffuseMap_5_scale).xyz; |
||||
normal += n * alphaBlend1.g; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_6 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_6, m_DiffuseMap_6_scale).xyz; |
||||
normal += n * alphaBlend1.b; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_7 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_7, m_DiffuseMap_7_scale).xyz; |
||||
normal += n * alphaBlend1.a; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.a; |
||||
#endif |
||||
#endif |
||||
|
||||
#ifdef ALPHAMAP_2 |
||||
#ifdef NORMALMAP_8 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_8, m_DiffuseMap_8_scale).xyz; |
||||
normal += n * alphaBlend2.r; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.r; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_9 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_9, m_DiffuseMap_9_scale).xyz; |
||||
normal += n * alphaBlend2.g; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.g; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_10 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_10, m_DiffuseMap_10_scale).xyz; |
||||
normal += n * alphaBlend2.b; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.b; |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP_11 |
||||
n = getTriPlanarBlend(coords, blending, m_NormalMap_11, m_DiffuseMap_11_scale).xyz; |
||||
normal += n * alphaBlend2.a; |
||||
#else |
||||
normal += vec3(0.5,0.5,1) * alphaBlend.a; |
||||
#endif |
||||
#endif |
||||
|
||||
normal = (normal.xyz * vec3(2.0) - vec3(1.0)); |
||||
return normalize(normal); |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
void main(){ |
||||
|
||||
//---------------------- |
||||
// diffuse calculations |
||||
//---------------------- |
||||
#ifdef DIFFUSEMAP |
||||
#ifdef ALPHAMAP |
||||
#ifdef TRI_PLANAR_MAPPING |
||||
vec4 diffuseColor = calculateTriPlanarDiffuseBlend(wNormal, wVertex, texCoord); |
||||
#else |
||||
vec4 diffuseColor = calculateDiffuseBlend(texCoord); |
||||
#endif |
||||
#else |
||||
vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord); |
||||
#endif |
||||
#else |
||||
vec4 diffuseColor = vec4(1.0); |
||||
#endif |
||||
|
||||
|
||||
//--------------------- |
||||
// normal calculations |
||||
//--------------------- |
||||
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11) |
||||
#ifdef TRI_PLANAR_MAPPING |
||||
vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord); |
||||
#else |
||||
vec3 normal = calculateNormal(texCoord); |
||||
#endif |
||||
mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz)); |
||||
#else |
||||
vec3 normal = vNormal; |
||||
#endif |
||||
|
||||
|
||||
//----------------------- |
||||
// lighting calculations |
||||
//----------------------- |
||||
gl_FragColor = AmbientSum * diffuseColor; |
||||
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(vPos, lightColor.w, lightData1, lightDir, lightVec); |
||||
|
||||
float spotFallOff = 1.0; |
||||
#if __VERSION__ >= 110 |
||||
// allow use of control flow |
||||
if(lightColor.w > 1.0){ |
||||
#endif |
||||
spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec); |
||||
#if __VERSION__ >= 110 |
||||
} |
||||
#endif |
||||
|
||||
#ifdef NORMALMAP |
||||
//Normal map -> lighting is computed in tangent space |
||||
lightDir.xyz = normalize(lightDir.xyz * tbnMat); |
||||
vec3 viewDir = normalize(-vPos.xyz * tbnMat); |
||||
#else |
||||
//no Normal map -> lighting is computed in view space |
||||
lightDir.xyz = normalize(lightDir.xyz); |
||||
vec3 viewDir = normalize(-vPos.xyz); |
||||
#endif |
||||
|
||||
vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess); |
||||
gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) + |
||||
SpecularSum.rgb * vec3(light.y); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,66 @@ |
||||
uniform mat4 g_WorldViewProjectionMatrix; |
||||
uniform mat4 g_WorldViewMatrix; |
||||
uniform mat3 g_NormalMatrix; |
||||
uniform mat4 g_ViewMatrix; |
||||
|
||||
uniform vec4 g_AmbientLightColor; |
||||
|
||||
attribute vec3 inPosition; |
||||
attribute vec3 inNormal; |
||||
attribute vec2 inTexCoord; |
||||
attribute vec4 inTangent; |
||||
|
||||
varying vec3 vNormal; |
||||
varying vec2 texCoord; |
||||
varying vec3 vPos; |
||||
varying vec3 vTangent; |
||||
varying vec3 vBinormal; |
||||
|
||||
varying vec4 AmbientSum; |
||||
varying vec4 DiffuseSum; |
||||
varying vec4 SpecularSum; |
||||
|
||||
#ifdef TRI_PLANAR_MAPPING |
||||
varying vec4 wVertex; |
||||
varying vec3 wNormal; |
||||
#endif |
||||
|
||||
|
||||
|
||||
void main(){ |
||||
vec4 pos = vec4(inPosition, 1.0); |
||||
gl_Position = g_WorldViewProjectionMatrix * pos; |
||||
#ifdef TERRAIN_GRID |
||||
texCoord = inTexCoord * 2.0; |
||||
#else |
||||
texCoord = inTexCoord; |
||||
#endif |
||||
|
||||
vec3 wvPosition = (g_WorldViewMatrix * pos).xyz; |
||||
vec3 wvNormal = normalize(g_NormalMatrix * inNormal); |
||||
|
||||
//-------------------------- |
||||
// specific to normal maps: |
||||
//-------------------------- |
||||
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11) |
||||
vTangent = g_NormalMatrix * inTangent.xyz; |
||||
vBinormal = cross(wvNormal, vTangent)* inTangent.w; |
||||
#endif |
||||
|
||||
//------------------------- |
||||
// general to all lighting |
||||
//------------------------- |
||||
vNormal = wvNormal; |
||||
vPos = wvPosition; |
||||
|
||||
AmbientSum = g_AmbientLightColor; |
||||
DiffuseSum = vec4(1.0); |
||||
SpecularSum = vec4(0.0); |
||||
|
||||
|
||||
#ifdef TRI_PLANAR_MAPPING |
||||
wVertex = vec4(inPosition,0.0); |
||||
wNormal = inNormal; |
||||
#endif |
||||
|
||||
} |
Loading…
Reference in new issue