Single pass lighting implementation.
Along with some light shaders refactoring and clean up
This commit is contained in:
parent
3ef5505faa
commit
c55717141e
@ -42,7 +42,6 @@ import com.jme3.material.TechniqueDef.LightMode;
|
||||
import com.jme3.material.TechniqueDef.ShadowMode;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.renderer.Caps;
|
||||
import com.jme3.renderer.GL1Renderer;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.RendererException;
|
||||
@ -52,7 +51,6 @@ import com.jme3.scene.Mesh;
|
||||
import com.jme3.scene.instancing.InstancedGeometry;
|
||||
import com.jme3.shader.Shader;
|
||||
import com.jme3.shader.Uniform;
|
||||
import com.jme3.shader.UniformBindingManager;
|
||||
import com.jme3.shader.VarType;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.image.ColorSpace;
|
||||
@ -697,12 +695,15 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
setParam(name, VarType.Vector4, value);
|
||||
}
|
||||
|
||||
private ColorRGBA getAmbientColor(LightList lightList) {
|
||||
private ColorRGBA getAmbientColor(LightList lightList, boolean removeLights) {
|
||||
ambientLightColor.set(0, 0, 0, 1);
|
||||
for (int j = 0; j < lightList.size(); j++) {
|
||||
Light l = lightList.get(j);
|
||||
if (l instanceof AmbientLight) {
|
||||
ambientLightColor.addLocal(l.getColor());
|
||||
if(removeLights){
|
||||
lightList.remove(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
ambientLightColor.a = 1.0f;
|
||||
@ -741,75 +742,106 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
* g_LightPosition.w is the inverse radius (1/r) of the light (for
|
||||
* attenuation) <br/> </p>
|
||||
*/
|
||||
protected void updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights) {
|
||||
protected int updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights, RenderManager rm, int startIndex) {
|
||||
if (numLights == 0) { // this shader does not do lighting, ignore.
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uniform lightColor = shader.getUniform("g_LightColor");
|
||||
Uniform lightPos = shader.getUniform("g_LightPosition");
|
||||
Uniform lightDir = shader.getUniform("g_LightDirection");
|
||||
lightColor.setVector4Length(numLights);
|
||||
lightPos.setVector4Length(numLights);
|
||||
lightDir.setVector4Length(numLights);
|
||||
|
||||
Uniform lightData = shader.getUniform("g_LightData");
|
||||
lightData.setVector4Length(numLights * 3);//8 lights * max 3
|
||||
Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
||||
|
||||
|
||||
int lightIndex = 0;
|
||||
|
||||
for (int i = 0; i < numLights; i++) {
|
||||
if (lightList.size() <= i) {
|
||||
lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
||||
lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
||||
} else {
|
||||
Light l = lightList.get(i);
|
||||
if (startIndex != 0) {
|
||||
// apply additive blending for 2nd and future passes
|
||||
rm.getRenderer().applyRenderState(additiveLight);
|
||||
ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
|
||||
}else{
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true));
|
||||
}
|
||||
|
||||
int lightDataIndex = 0;
|
||||
TempVars vars = TempVars.get();
|
||||
Vector4f tmpVec = vars.vect4f1;
|
||||
int curIndex;
|
||||
int endIndex = numLights + startIndex;
|
||||
for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
|
||||
|
||||
|
||||
Light l = lightList.get(curIndex);
|
||||
if(l.getType() == Light.Type.Ambient){
|
||||
endIndex++;
|
||||
continue;
|
||||
}
|
||||
ColorRGBA color = l.getColor();
|
||||
lightColor.setVector4InArray(color.getRed(),
|
||||
//Color
|
||||
lightData.setVector4InArray(color.getRed(),
|
||||
color.getGreen(),
|
||||
color.getBlue(),
|
||||
l.getType().getId(),
|
||||
i);
|
||||
|
||||
lightDataIndex);
|
||||
lightDataIndex++;
|
||||
|
||||
switch (l.getType()) {
|
||||
case Directional:
|
||||
DirectionalLight dl = (DirectionalLight) l;
|
||||
Vector3f dir = dl.getDirection();
|
||||
lightPos.setVector4InArray(dir.getX(), dir.getY(), dir.getZ(), -1, lightIndex);
|
||||
Vector3f dir = dl.getDirection();
|
||||
//Data directly sent in view space to avoid a matrix mult for each pixel
|
||||
tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
|
||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||
// tmpVec.divideLocal(tmpVec.w);
|
||||
// tmpVec.normalizeLocal();
|
||||
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
//PADDING
|
||||
lightData.setVector4InArray(0,0,0,0, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
break;
|
||||
case Point:
|
||||
PointLight pl = (PointLight) l;
|
||||
Vector3f pos = pl.getPosition();
|
||||
float invRadius = pl.getInvRadius();
|
||||
lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), invRadius, lightIndex);
|
||||
tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
|
||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||
//tmpVec.divideLocal(tmpVec.w);
|
||||
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
//PADDING
|
||||
lightData.setVector4InArray(0,0,0,0, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
break;
|
||||
case Spot:
|
||||
case Spot:
|
||||
SpotLight sl = (SpotLight) l;
|
||||
Vector3f pos2 = sl.getPosition();
|
||||
Vector3f dir2 = sl.getDirection();
|
||||
float invRange = sl.getInvSpotRange();
|
||||
float spotAngleCos = sl.getPackedAngleCos();
|
||||
|
||||
lightPos.setVector4InArray(pos2.getX(), pos2.getY(), pos2.getZ(), invRange, lightIndex);
|
||||
lightDir.setVector4InArray(dir2.getX(), dir2.getY(), dir2.getZ(), spotAngleCos, lightIndex);
|
||||
break;
|
||||
case Ambient:
|
||||
// skip this light. Does not increase lightIndex
|
||||
continue;
|
||||
tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f);
|
||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||
// tmpVec.divideLocal(tmpVec.w);
|
||||
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
|
||||
//We transform the spot direction in view space here to save 5 varying later in the lighting shader
|
||||
//one vec4 less and a vec4 that becomes a vec3
|
||||
//the downside is that spotAngleCos decoding happens now in the frag shader.
|
||||
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f);
|
||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||
tmpVec.normalizeLocal();
|
||||
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
|
||||
}
|
||||
}
|
||||
|
||||
lightIndex++;
|
||||
}
|
||||
|
||||
while (lightIndex < numLights) {
|
||||
lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
||||
lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
||||
|
||||
lightIndex++;
|
||||
}
|
||||
vars.release();
|
||||
//Padding of unsued buffer space
|
||||
while(lightDataIndex < numLights * 3) {
|
||||
lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
|
||||
lightDataIndex++;
|
||||
}
|
||||
return curIndex;
|
||||
}
|
||||
|
||||
protected void renderMultipassLighting(Shader shader, Geometry g, LightList lightList, RenderManager rm) {
|
||||
@ -830,7 +862,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
|
||||
if (isFirstLight) {
|
||||
// set ambient color for first light only
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList, false));
|
||||
isFirstLight = false;
|
||||
isSecondLight = true;
|
||||
} else if (isSecondLight) {
|
||||
@ -885,9 +917,9 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange);
|
||||
lightPos.setValue(VarType.Vector4, tmpLightPosition);
|
||||
|
||||
//We transform the spot directoin in view space here to save 5 varying later in the lighting shader
|
||||
//We transform the spot direction in view space here to save 5 varying later in the lighting shader
|
||||
//one vec4 less and a vec4 that becomes a vec3
|
||||
//the downside is that spotAngleCos decoding happen now in the frag shader.
|
||||
//the downside is that spotAngleCos decoding happens now in the frag shader.
|
||||
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0);
|
||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||
tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos);
|
||||
@ -906,7 +938,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
if (isFirstLight && lightList.size() > 0) {
|
||||
// There are only ambient lights in the scene. Render
|
||||
// a dummy "normal light" so we can see the ambient
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList, false));
|
||||
lightColor.setValue(VarType.Vector4, ColorRGBA.BlackNoAlpha);
|
||||
lightPos.setValue(VarType.Vector4, nullDirLight);
|
||||
r.setShader(shader);
|
||||
@ -955,9 +987,12 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
for (TechniqueDef techDef : techDefs) {
|
||||
if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
|
||||
// use the first one that supports all the caps
|
||||
tech = new Technique(this, techDef);
|
||||
tech = new Technique(this, techDef);
|
||||
techniques.put(name, tech);
|
||||
break;
|
||||
if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() ||
|
||||
tech.getDef().getLightMode() == LightMode.Disable){
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastTech = techDef;
|
||||
}
|
||||
@ -990,7 +1025,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
}
|
||||
|
||||
technique = tech;
|
||||
tech.makeCurrent(def.getAssetManager(), true, rendererCaps);
|
||||
tech.makeCurrent(def.getAssetManager(), true, rendererCaps, renderManager);
|
||||
|
||||
// shader was changed
|
||||
sortingId = -1;
|
||||
@ -1000,7 +1035,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
if (technique == null) {
|
||||
selectTechnique("Default", rm);
|
||||
} else {
|
||||
technique.makeCurrent(def.getAssetManager(), false, rm.getRenderer().getCaps());
|
||||
technique.makeCurrent(def.getAssetManager(), false, rm.getRenderer().getCaps(), rm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1162,8 +1197,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
||||
r.setLighting(null);
|
||||
break;
|
||||
case SinglePass:
|
||||
updateLightListUniforms(shader, geom, lights, 4);
|
||||
break;
|
||||
int nbRenderedLights = 0;
|
||||
resetUniformsNotSetByCurrent(shader);
|
||||
while(nbRenderedLights < lights.size()){
|
||||
nbRenderedLights = updateLightListUniforms(shader, geom, lights, rm.getSinglePassLightBatchSize(), rm, nbRenderedLights);
|
||||
r.setShader(shader);
|
||||
renderMeshFromGeometry(r, geom);
|
||||
}
|
||||
return;
|
||||
case FixedPipeline:
|
||||
r.setLighting(lights);
|
||||
break;
|
||||
|
@ -33,8 +33,8 @@ package com.jme3.material;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.renderer.Caps;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.shader.*;
|
||||
import com.jme3.util.ListMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@ -172,7 +172,7 @@ public class Technique /* implements Savable */ {
|
||||
*
|
||||
* @param assetManager The asset manager to use for loading shaders.
|
||||
*/
|
||||
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps) {
|
||||
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps, RenderManager rm) {
|
||||
if (!def.isUsingShaders()) {
|
||||
// No shaders are used, no processing is neccessary.
|
||||
return;
|
||||
@ -182,6 +182,13 @@ public class Technique /* implements Savable */ {
|
||||
if (defines.update(owner.getParamsMap(), def)) {
|
||||
needReload = true;
|
||||
}
|
||||
if(getDef().getLightMode()== TechniqueDef.LightMode.SinglePass){
|
||||
defines.set("SINGLE_PASS_LIGHTING", VarType.Boolean, true);
|
||||
defines.set("NB_LIGHTS", VarType.Int, rm.getSinglePassLightBatchSize()*3 );
|
||||
}else{
|
||||
defines.set("SINGLE_PASS_LIGHTING", VarType.Boolean, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (needReload) {
|
||||
|
@ -38,6 +38,7 @@ import com.jme3.material.Material;
|
||||
import com.jme3.material.MaterialDef;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.material.Technique;
|
||||
import com.jme3.material.TechniqueDef;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
@ -89,6 +90,8 @@ public class RenderManager {
|
||||
private boolean handleTranlucentBucket = true;
|
||||
private AppProfiler prof;
|
||||
private LightFilter lightFilter = new DefaultLightFilter();
|
||||
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
||||
private int singlePassLightBatchSize = 1;
|
||||
|
||||
/**
|
||||
* Create a high-level rendering interface over the
|
||||
@ -780,6 +783,33 @@ public class RenderManager {
|
||||
vp.getQueue().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the light filter to use when rendering Lighted Geometries
|
||||
*
|
||||
* @see LightFilter
|
||||
* @param lightFilter The light filter tose. Set it to null if you want all lights to be rendered
|
||||
*/
|
||||
public void setLightFilter(LightFilter lightFilter) {
|
||||
this.lightFilter = lightFilter;
|
||||
}
|
||||
|
||||
public void setPreferredLightMode(TechniqueDef.LightMode preferredLightMode) {
|
||||
this.preferredLightMode = preferredLightMode;
|
||||
}
|
||||
|
||||
public TechniqueDef.LightMode getPreferredLightMode() {
|
||||
return preferredLightMode;
|
||||
}
|
||||
|
||||
public int getSinglePassLightBatchSize() {
|
||||
return singlePassLightBatchSize;
|
||||
}
|
||||
|
||||
public void setSinglePassLightBatchSize(int singlePassLightBatchSize) {
|
||||
this.singlePassLightBatchSize = singlePassLightBatchSize;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the given viewport queues.
|
||||
* <p>
|
||||
|
@ -1,7 +1,9 @@
|
||||
#import "Common/ShaderLib/Parallax.glsllib"
|
||||
#import "Common/ShaderLib/Optics.glsllib"
|
||||
#define ATTENUATION
|
||||
//#define HQ_ATTENUATION
|
||||
#ifndef VERTEX_LIGHTING
|
||||
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||
#import "Common/ShaderLib/Lighting.glsllib"
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
#ifdef SEPARATE_TEXCOORD
|
||||
@ -58,82 +60,14 @@ varying vec3 SpecularSum;
|
||||
uniform float m_AlphaDiscardThreshold;
|
||||
|
||||
#ifndef VERTEX_LIGHTING
|
||||
uniform float m_Shininess;
|
||||
uniform float m_Shininess;
|
||||
#ifdef USE_REFLECTION
|
||||
uniform float m_ReflectionPower;
|
||||
uniform float m_ReflectionIntensity;
|
||||
varying vec4 refVec;
|
||||
|
||||
#ifdef HQ_ATTENUATION
|
||||
uniform vec4 g_LightPosition;
|
||||
#endif
|
||||
|
||||
#ifdef USE_REFLECTION
|
||||
uniform float m_ReflectionPower;
|
||||
uniform float m_ReflectionIntensity;
|
||||
varying vec4 refVec;
|
||||
|
||||
uniform ENVMAP m_EnvMap;
|
||||
#endif
|
||||
|
||||
float tangDot(in vec3 v1, in vec3 v2){
|
||||
float d = dot(v1,v2);
|
||||
#ifdef V_TANGENT
|
||||
d = 1.0 - d*d;
|
||||
return step(0.0, d) * sqrt(d);
|
||||
#else
|
||||
return d;
|
||||
uniform ENVMAP m_EnvMap;
|
||||
#endif
|
||||
}
|
||||
|
||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
|
||||
#ifdef MINNAERT
|
||||
float NdotL = max(0.0, dot(norm, lightdir));
|
||||
float NdotV = max(0.0, dot(norm, viewdir));
|
||||
return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;
|
||||
#else
|
||||
return max(0.0, dot(norm, lightdir));
|
||||
#endif
|
||||
}
|
||||
|
||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
||||
// NOTE: check for shiny <= 1 removed since shininess is now
|
||||
// 1.0 by default (uses matdefs default vals)
|
||||
#ifdef LOW_QUALITY
|
||||
// Blinn-Phong
|
||||
// Note: preferably, H should be computed in the vertex shader
|
||||
vec3 H = (viewdir + lightdir) * vec3(0.5);
|
||||
return pow(max(tangDot(H, norm), 0.0), shiny);
|
||||
#elif defined(WARDISO)
|
||||
// Isotropic Ward
|
||||
vec3 halfVec = normalize(viewdir + lightdir);
|
||||
float NdotH = max(0.001, tangDot(norm, halfVec));
|
||||
float NdotV = max(0.001, tangDot(norm, viewdir));
|
||||
float NdotL = max(0.001, tangDot(norm, lightdir));
|
||||
float a = tan(acos(NdotH));
|
||||
float p = max(shiny/128.0, 0.001);
|
||||
return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
|
||||
#else
|
||||
// Standard Phong
|
||||
vec3 R = reflect(-lightdir, norm);
|
||||
return pow(max(tangDot(R, viewdir), 0.0), shiny);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec2 computeLighting(in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
|
||||
float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
|
||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
|
||||
|
||||
#ifdef HQ_ATTENUATION
|
||||
float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);
|
||||
#else
|
||||
float att = vLightDir.w;
|
||||
#endif
|
||||
|
||||
if (m_Shininess <= 1.0) {
|
||||
specularFactor = 0.0; // should be one instruction on most cards ..
|
||||
}
|
||||
|
||||
specularFactor *= diffuseFactor;
|
||||
|
||||
return vec2(diffuseFactor, specularFactor) * vec2(att);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main(){
|
||||
@ -176,36 +110,7 @@ void main(){
|
||||
discard;
|
||||
}
|
||||
|
||||
#ifndef VERTEX_LIGHTING
|
||||
float spotFallOff = 1.0;
|
||||
|
||||
#if __VERSION__ >= 110
|
||||
// allow use of control flow
|
||||
if(g_LightDirection.w != 0.0){
|
||||
#endif
|
||||
|
||||
vec3 L = normalize(lightVec.xyz);
|
||||
vec3 spotdir = normalize(g_LightDirection.xyz);
|
||||
float curAngleCos = dot(-L, spotdir);
|
||||
float innerAngleCos = floor(g_LightDirection.w) * 0.001;
|
||||
float outerAngleCos = fract(g_LightDirection.w);
|
||||
float innerMinusOuter = innerAngleCos - outerAngleCos;
|
||||
spotFallOff = (curAngleCos - outerAngleCos) / innerMinusOuter;
|
||||
|
||||
#if __VERSION__ >= 110
|
||||
if(spotFallOff <= 0.0){
|
||||
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
|
||||
gl_FragColor.a = alpha;
|
||||
return;
|
||||
}else{
|
||||
spotFallOff = clamp(spotFallOff, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
spotFallOff = clamp(spotFallOff, step(g_LightDirection.w, 0.001), 1.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ***********************
|
||||
// Read from textures
|
||||
// ***********************
|
||||
@ -257,8 +162,23 @@ void main(){
|
||||
vec4 lightDir = vLightDir;
|
||||
lightDir.xyz = normalize(lightDir.xyz);
|
||||
vec3 viewDir = normalize(vViewDir);
|
||||
float spotFallOff = 1.0;
|
||||
|
||||
vec2 light = computeLighting(normal, viewDir, lightDir.xyz) * spotFallOff;
|
||||
#if __VERSION__ >= 110
|
||||
// allow use of control flow
|
||||
if(g_LightDirection.w != 0.0){
|
||||
#endif
|
||||
spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
|
||||
#if __VERSION__ >= 110
|
||||
if(spotFallOff <= 0.0){
|
||||
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
|
||||
gl_FragColor.a = alpha;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#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;
|
||||
|
@ -6,34 +6,12 @@ MaterialDef Phong Lighting {
|
||||
// For better performance
|
||||
Boolean VertexLighting
|
||||
|
||||
// Use more efficent algorithms to improve performance
|
||||
Boolean LowQuality
|
||||
|
||||
// Improve quality at the cost of performance
|
||||
Boolean HighQuality
|
||||
|
||||
// Output alpha from the diffuse map
|
||||
Boolean UseAlpha
|
||||
|
||||
// Alpha threshold for fragment discarding
|
||||
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
||||
|
||||
// Normal map is in BC5/ATI2n/LATC/3Dc compression format
|
||||
Boolean LATC
|
||||
|
||||
// Use the provided ambient, diffuse, and specular colors
|
||||
Boolean UseMaterialColors
|
||||
|
||||
// Activate shading along the tangent, instead of the normal
|
||||
// Requires tangent data to be available on the model.
|
||||
Boolean VTangent
|
||||
|
||||
// Use minnaert diffuse instead of lambert
|
||||
Boolean Minnaert
|
||||
|
||||
// Use ward specular instead of phong
|
||||
Boolean WardIso
|
||||
|
||||
// Use vertex color as an additional diffuse color.
|
||||
Boolean UseVertexColor
|
||||
|
||||
@ -133,9 +111,48 @@ MaterialDef Phong Lighting {
|
||||
Int NumberOfBones
|
||||
Matrix4Array BoneMatrices
|
||||
|
||||
//For instancing
|
||||
Boolean UseInstancing
|
||||
}
|
||||
|
||||
Technique {
|
||||
LightMode SinglePass
|
||||
|
||||
VertexShader GLSL100: Common/MatDefs/Light/SPLighting.vert
|
||||
FragmentShader GLSL100: Common/MatDefs/Light/SPLighting.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
NormalMatrix
|
||||
WorldViewMatrix
|
||||
ViewMatrix
|
||||
CameraPosition
|
||||
WorldMatrix
|
||||
ViewProjectionMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
VERTEX_COLOR : UseVertexColor
|
||||
VERTEX_LIGHTING : VertexLighting
|
||||
MATERIAL_COLORS : UseMaterialColors
|
||||
DIFFUSEMAP : DiffuseMap
|
||||
NORMALMAP : NormalMap
|
||||
SPECULARMAP : SpecularMap
|
||||
PARALLAXMAP : ParallaxMap
|
||||
NORMALMAP_PARALLAX : PackedNormalParallax
|
||||
STEEP_PARALLAX : SteepParallax
|
||||
ALPHAMAP : AlphaMap
|
||||
COLORRAMP : ColorRamp
|
||||
LIGHTMAP : LightMap
|
||||
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||
USE_REFLECTION : EnvMap
|
||||
SPHERE_MAP : SphereMap
|
||||
NUM_BONES : NumberOfBones
|
||||
INSTANCING : UseInstancing
|
||||
}
|
||||
}
|
||||
|
||||
Technique {
|
||||
|
||||
LightMode MultiPass
|
||||
@ -154,17 +171,9 @@ MaterialDef Phong Lighting {
|
||||
}
|
||||
|
||||
Defines {
|
||||
LATC : LATC
|
||||
VERTEX_COLOR : UseVertexColor
|
||||
VERTEX_LIGHTING : VertexLighting
|
||||
ATTENUATION : Attenuation
|
||||
VERTEX_LIGHTING : VertexLighting
|
||||
MATERIAL_COLORS : UseMaterialColors
|
||||
V_TANGENT : VTangent
|
||||
MINNAERT : Minnaert
|
||||
WARDISO : WardIso
|
||||
LOW_QUALITY : LowQuality
|
||||
HQ_ATTENUATION : HighQuality
|
||||
|
||||
DIFFUSEMAP : DiffuseMap
|
||||
NORMALMAP : NormalMap
|
||||
SPECULARMAP : SpecularMap
|
||||
@ -175,16 +184,16 @@ MaterialDef Phong Lighting {
|
||||
COLORRAMP : ColorRamp
|
||||
LIGHTMAP : LightMap
|
||||
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||
|
||||
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||
USE_REFLECTION : EnvMap
|
||||
SPHERE_MAP : SphereMap
|
||||
|
||||
NUM_BONES : NumberOfBones
|
||||
|
||||
NUM_BONES : NumberOfBones
|
||||
INSTANCING : UseInstancing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Technique PreShadow {
|
||||
|
||||
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
||||
@ -373,4 +382,4 @@ MaterialDef Phong Lighting {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#import "Common/ShaderLib/Instancing.glsllib"
|
||||
#define ATTENUATION
|
||||
//#define HQ_ATTENUATION
|
||||
|
||||
#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;
|
||||
@ -28,7 +30,6 @@ attribute vec2 inTexCoord;
|
||||
attribute vec3 inNormal;
|
||||
|
||||
varying vec3 lightVec;
|
||||
//varying vec4 spotVec;
|
||||
|
||||
#ifdef VERTEX_COLOR
|
||||
attribute vec4 inColor;
|
||||
@ -39,8 +40,7 @@ varying vec3 lightVec;
|
||||
|
||||
#ifndef NORMALMAP
|
||||
varying vec3 vNormal;
|
||||
#endif
|
||||
//varying vec3 vPosition;
|
||||
#endif
|
||||
varying vec3 vViewDir;
|
||||
varying vec4 vLightDir;
|
||||
#else
|
||||
@ -77,57 +77,6 @@ varying vec3 lightVec;
|
||||
}
|
||||
#endif
|
||||
|
||||
// JME3 lights in world space
|
||||
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
|
||||
float posLight = step(0.5, color.w);
|
||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
||||
lightVec = tempVec;
|
||||
#ifdef ATTENUATION
|
||||
float dist = length(tempVec);
|
||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
||||
lightDir.xyz = tempVec / vec3(dist);
|
||||
#else
|
||||
lightDir = vec4(normalize(tempVec), 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VERTEX_LIGHTING
|
||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
|
||||
return max(0.0, dot(norm, lightdir));
|
||||
}
|
||||
|
||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
||||
if (shiny <= 1.0){
|
||||
return 0.0;
|
||||
}
|
||||
#ifndef LOW_QUALITY
|
||||
vec3 H = (viewdir + lightdir) * vec3(0.5);
|
||||
return pow(max(dot(H, norm), 0.0), shiny);
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightPos){
|
||||
vec4 lightDir;
|
||||
lightComputeDir(wvPos, g_LightColor, wvLightPos, lightDir);
|
||||
float spotFallOff = 1.0;
|
||||
if(g_LightDirection.w != 0.0){
|
||||
vec3 L=normalize(lightVec.xyz);
|
||||
vec3 spotdir = normalize(g_LightDirection.xyz);
|
||||
float curAngleCos = dot(-L, spotdir);
|
||||
float innerAngleCos = floor(g_LightDirection.w) * 0.001;
|
||||
float outerAngleCos = fract(g_LightDirection.w);
|
||||
float innerMinusOuter = innerAngleCos - outerAngleCos;
|
||||
spotFallOff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);
|
||||
}
|
||||
float diffuseFactor = lightComputeDiffuse(wvNorm, lightDir.xyz);
|
||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, lightDir.xyz, m_Shininess);
|
||||
//specularFactor *= step(0.01, diffuseFactor);
|
||||
return vec2(diffuseFactor, specularFactor) * vec2(lightDir.w)*spotFallOff;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main(){
|
||||
vec4 modelSpacePos = vec4(inPosition, 1.0);
|
||||
vec3 modelSpaceNorm = inNormal;
|
||||
@ -154,11 +103,6 @@ void main(){
|
||||
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));//normalize(g_NormalMatrix * modelSpaceNorm);
|
||||
vec3 viewDir = normalize(-wvPosition);
|
||||
|
||||
//vec4 lightColor = g_LightColor[gl_InstanceID];
|
||||
//vec4 lightPos = g_LightPosition[gl_InstanceID];
|
||||
//vec4 wvLightPos = (g_ViewMatrix * vec4(lightPos.xyz, lightColor.w));
|
||||
//wvLightPos.w = lightPos.w;
|
||||
|
||||
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz,clamp(g_LightColor.w,0.0,1.0)));
|
||||
wvLightPos.w = g_LightPosition.w;
|
||||
vec4 lightColor = g_LightColor;
|
||||
@ -166,41 +110,24 @@ void main(){
|
||||
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||
vec3 wvTangent = normalize(TransformNormal(modelSpaceTan));
|
||||
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||
|
||||
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
|
||||
|
||||
//vPosition = wvPosition * tbnMat;
|
||||
//vViewDir = viewDir * tbnMat;
|
||||
|
||||
vViewDir = -wvPosition * tbnMat;
|
||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
||||
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
||||
#elif !defined(VERTEX_LIGHTING)
|
||||
vNormal = wvNormal;
|
||||
|
||||
//vPosition = wvPosition;
|
||||
vViewDir = viewDir;
|
||||
|
||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
||||
|
||||
#ifdef V_TANGENT
|
||||
vNormal = normalize(TransformNormal(inTangent.xyz));
|
||||
vNormal = -cross(cross(vLightDir.xyz, vNormal), vNormal);
|
||||
#endif
|
||||
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||
#endif
|
||||
|
||||
//computing spot direction in view space and unpacking spotlight cos
|
||||
// spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );
|
||||
// spotVec.w = floor(g_LightDirection.w) * 0.001;
|
||||
// lightVec.w = fract(g_LightDirection.w);
|
||||
|
||||
lightColor.w = 1.0;
|
||||
#ifdef MATERIAL_COLORS
|
||||
AmbientSum = (m_Ambient * g_AmbientLightColor).rgb;
|
||||
DiffuseSum = m_Diffuse * lightColor;
|
||||
DiffuseSum = m_Diffuse * vec4(lightColor.rgb, 1.0);
|
||||
SpecularSum = (m_Specular * lightColor).rgb;
|
||||
#else
|
||||
AmbientSum = vec3(0.2, 0.2, 0.2) * g_AmbientLightColor.rgb; // Default: ambient color is dark gray
|
||||
DiffuseSum = lightColor;
|
||||
AmbientSum = g_AmbientLightColor.rgb; // Default: ambient color is dark gray
|
||||
DiffuseSum = vec4(lightColor.rgb, 1.0);
|
||||
SpecularSum = vec3(0.0);
|
||||
#endif
|
||||
|
||||
@ -210,10 +137,22 @@ void main(){
|
||||
#endif
|
||||
|
||||
#ifdef VERTEX_LIGHTING
|
||||
vertexLightValues = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);
|
||||
float spotFallOff = 1.0;
|
||||
vec4 vLightDir;
|
||||
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||
#if __VERSION__ >= 110
|
||||
// allow use of control flow
|
||||
if(lightColor.w > 1.0){
|
||||
#endif
|
||||
spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
|
||||
#if __VERSION__ >= 110
|
||||
}
|
||||
#endif
|
||||
|
||||
vertexLightValues = computeLighting(wvNormal, viewDir, vLightDir.xyz, vLightDir.w * spotFallOff, m_Shininess);
|
||||
#endif
|
||||
|
||||
#ifdef USE_REFLECTION
|
||||
#ifdef USE_REFLECTION
|
||||
computeRef(modelSpacePos);
|
||||
#endif
|
||||
}
|
@ -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
|
||||
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||
#import "Common/ShaderLib/Lighting.glsllib"
|
||||
|
||||
uniform float m_Shininess;
|
||||
uniform vec4 g_LightDirection;
|
||||
@ -145,54 +147,6 @@ varying vec3 lightVec;
|
||||
varying vec3 wNormal;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
float tangDot(in vec3 v1, in vec3 v2){
|
||||
float d = dot(v1,v2);
|
||||
#ifdef V_TANGENT
|
||||
d = 1.0 - d*d;
|
||||
return step(0.0, d) * sqrt(d);
|
||||
#else
|
||||
return d;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
|
||||
return max(0.0, dot(norm, lightdir));
|
||||
}
|
||||
|
||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
||||
#ifdef WARDISO
|
||||
// Isotropic Ward
|
||||
vec3 halfVec = normalize(viewdir + lightdir);
|
||||
float NdotH = max(0.001, tangDot(norm, halfVec));
|
||||
float NdotV = max(0.001, tangDot(norm, viewdir));
|
||||
float NdotL = max(0.001, tangDot(norm, lightdir));
|
||||
float a = tan(acos(NdotH));
|
||||
float p = max(shiny/128.0, 0.001);
|
||||
return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
|
||||
#else
|
||||
// Standard Phong
|
||||
vec3 R = reflect(-lightdir, norm);
|
||||
return pow(max(tangDot(R, viewdir), 0.0), shiny);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
|
||||
float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
|
||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
|
||||
|
||||
if (m_Shininess <= 1.0) {
|
||||
specularFactor = 0.0; // should be one instruction on most cards ..
|
||||
}
|
||||
|
||||
float att = vLightDir.w;
|
||||
|
||||
return vec2(diffuseFactor, specularFactor) * vec2(att);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ALPHAMAP
|
||||
|
||||
vec4 calculateDiffuseBlend(in vec2 texCoord) {
|
||||
@ -355,7 +309,7 @@ vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 w
|
||||
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);
|
||||
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;
|
||||
@ -627,7 +581,7 @@ void main(){
|
||||
spotFallOff = clamp(spotFallOff, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------
|
||||
// normal calculations
|
||||
//---------------------
|
||||
@ -648,7 +602,7 @@ void main(){
|
||||
vec4 lightDir = vLightDir;
|
||||
lightDir.xyz = normalize(lightDir.xyz);
|
||||
|
||||
vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz)*spotFallOff;
|
||||
vec2 light = computeLighting(normal, vViewDir.xyz, lightDir.xyz,lightDir.w*spotFallOff,m_Shininess);
|
||||
|
||||
vec4 specularColor = vec4(1.0);
|
||||
|
||||
|
@ -163,6 +163,70 @@ MaterialDef Terrain Lighting {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Technique {
|
||||
|
||||
LightMode SinglePass
|
||||
|
||||
VertexShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.vert
|
||||
FragmentShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
NormalMatrix
|
||||
WorldViewMatrix
|
||||
ViewMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
TRI_PLANAR_MAPPING : useTriPlanarMapping
|
||||
TERRAIN_GRID : isTerrainGrid
|
||||
WARDISO : WardIso
|
||||
|
||||
DIFFUSEMAP : DiffuseMap
|
||||
DIFFUSEMAP_1 : DiffuseMap_1
|
||||
DIFFUSEMAP_2 : DiffuseMap_2
|
||||
DIFFUSEMAP_3 : DiffuseMap_3
|
||||
DIFFUSEMAP_4 : DiffuseMap_4
|
||||
DIFFUSEMAP_5 : DiffuseMap_5
|
||||
DIFFUSEMAP_6 : DiffuseMap_6
|
||||
DIFFUSEMAP_7 : DiffuseMap_7
|
||||
DIFFUSEMAP_8 : DiffuseMap_8
|
||||
DIFFUSEMAP_9 : DiffuseMap_9
|
||||
DIFFUSEMAP_10 : DiffuseMap_10
|
||||
DIFFUSEMAP_11 : DiffuseMap_11
|
||||
NORMALMAP : NormalMap
|
||||
NORMALMAP_1 : NormalMap_1
|
||||
NORMALMAP_2 : NormalMap_2
|
||||
NORMALMAP_3 : NormalMap_3
|
||||
NORMALMAP_4 : NormalMap_4
|
||||
NORMALMAP_5 : NormalMap_5
|
||||
NORMALMAP_6 : NormalMap_6
|
||||
NORMALMAP_7 : NormalMap_7
|
||||
NORMALMAP_8 : NormalMap_8
|
||||
NORMALMAP_9 : NormalMap_9
|
||||
NORMALMAP_10 : NormalMap_10
|
||||
NORMALMAP_11 : NormalMap_11
|
||||
SPECULARMAP : SpecularMap
|
||||
ALPHAMAP : AlphaMap
|
||||
ALPHAMAP_1 : AlphaMap_1
|
||||
ALPHAMAP_2 : AlphaMap_2
|
||||
DIFFUSEMAP_0_SCALE : DiffuseMap_0_scale
|
||||
DIFFUSEMAP_1_SCALE : DiffuseMap_1_scale
|
||||
DIFFUSEMAP_2_SCALE : DiffuseMap_2_scale
|
||||
DIFFUSEMAP_3_SCALE : DiffuseMap_3_scale
|
||||
DIFFUSEMAP_4_SCALE : DiffuseMap_4_scale
|
||||
DIFFUSEMAP_5_SCALE : DiffuseMap_5_scale
|
||||
DIFFUSEMAP_6_SCALE : DiffuseMap_6_scale
|
||||
DIFFUSEMAP_7_SCALE : DiffuseMap_7_scale
|
||||
DIFFUSEMAP_8_SCALE : DiffuseMap_8_scale
|
||||
DIFFUSEMAP_9_SCALE : DiffuseMap_9_scale
|
||||
DIFFUSEMAP_10_SCALE : DiffuseMap_10_scale
|
||||
DIFFUSEMAP_11_SCALE : DiffuseMap_11_scale
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Technique PreShadow {
|
||||
|
||||
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
||||
|
@ -1,3 +1,5 @@
|
||||
#import "Common/ShaderLib/Lighting.glsllib"
|
||||
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldViewMatrix;
|
||||
uniform mat3 g_NormalMatrix;
|
||||
@ -34,16 +36,6 @@ varying vec4 SpecularSum;
|
||||
varying vec3 wNormal;
|
||||
#endif
|
||||
|
||||
// JME3 lights in world space
|
||||
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
|
||||
float posLight = step(0.5, color.w);
|
||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
||||
lightVec.xyz = tempVec;
|
||||
float dist = length(tempVec);
|
||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
||||
lightDir.xyz = tempVec / vec3(dist);
|
||||
}
|
||||
|
||||
|
||||
void main(){
|
||||
vec4 pos = vec4(inPosition, 1.0);
|
||||
@ -66,35 +58,30 @@ void main(){
|
||||
// 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)
|
||||
vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
|
||||
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||
vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
|
||||
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||
|
||||
mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
|
||||
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
|
||||
|
||||
vPosition = wvPosition * tbnMat;
|
||||
vViewDir = viewDir * tbnMat;
|
||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
||||
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
||||
vPosition = wvPosition * tbnMat;
|
||||
vViewDir = viewDir * tbnMat;
|
||||
|
||||
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
||||
#else
|
||||
//-------------------------
|
||||
// general to all lighting
|
||||
//-------------------------
|
||||
vNormal = wvNormal;
|
||||
|
||||
//-------------------------
|
||||
// general to all lighting
|
||||
//-------------------------
|
||||
vNormal = wvNormal;
|
||||
vPosition = wvPosition;
|
||||
vViewDir = viewDir;
|
||||
|
||||
vPosition = wvPosition;
|
||||
vViewDir = viewDir;
|
||||
|
||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
||||
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||
|
||||
#endif
|
||||
|
||||
//computing spot direction in view space and unpacking spotlight cos
|
||||
// spotVec=(g_ViewMatrix *vec4(g_LightDirection.xyz,0.0) );
|
||||
// spotVec.w=floor(g_LightDirection.w)*0.001;
|
||||
// lightVec.w = fract(g_LightDirection.w);
|
||||
|
||||
AmbientSum = vec4(0.2, 0.2, 0.2, 1.0) * g_AmbientLightColor; // Default: ambient color is dark gray
|
||||
AmbientSum = g_AmbientLightColor; // Default: ambient color is dark gray
|
||||
DiffuseSum = lightColor;
|
||||
SpecularSum = lightColor;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user