I was trying to make a simple Shadow example and ran into a Bad Compile warning. It looks like it is perhaps an error within one of the jME files (although I wouldn’t be surprised if I was doing something dumb either).
How do I fix this?
The system prints the following:
Dec 11, 2014 1:21:11 PM com.jme3.renderer.lwjgl.LwjglRenderer updateShaderSourceData WARNING: Bad compile of: 1 #version 150 core 2 #define FILTER_MODE 1 3 #define HARDWARE_SHADOWS 1 4 #define PCFEDGE 1.0 5 #define PSSM 1 6 #define SHADOWMAP_SIZE 1024.0 7 // Because gpu_shader5 is actually where those 8 // gather functions are declared to work on shadowmaps 9 #extension GL_ARB_gpu_shader5 : enable 10 11 #ifdef HARDWARE_SHADOWS 12 #define SHADOWMAP sampler2DShadow 13 #define SHADOWCOMPAREOFFSET(tex,coord,offset) textureProjOffset(tex, coord, offset) 14 #define SHADOWCOMPARE(tex,coord) textureProj(tex, coord) 15 #define SHADOWGATHER(tex,coord) textureGather(tex, coord.xy, coord.z) 16 #else 17 #define SHADOWMAP sampler2D 18 #define SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z, textureProjOffset(tex, coord, offset).r) 19 #define SHADOWCOMPARE(tex,coord) step(coord.z, textureProj(tex, coord).r) 20 #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy)) 21 #endif 22 23 24 #if FILTER_MODE == 0 25 #define GETSHADOW Shadow_Nearest 26 #define KERNEL 1.0 27 #elif FILTER_MODE == 1 28 #ifdef HARDWARE_SHADOWS 29 #define GETSHADOW Shadow_Nearest 30 #else 31 #define GETSHADOW Shadow_DoBilinear_2x2 32 #endif 33 #define KERNEL 1.0 34 #elif FILTER_MODE == 2 35 #define GETSHADOW Shadow_DoDither_2x2 36 #define KERNEL 1.0 37 #elif FILTER_MODE == 3 38 #define GETSHADOW Shadow_DoPCF 39 #define KERNEL 4.0 40 #elif FILTER_MODE == 4 41 #define GETSHADOW Shadow_DoPCFPoisson 42 #define KERNEL 4.0 43 #elif FILTER_MODE == 5 44 #define GETSHADOW Shadow_DoPCF 45 #define KERNEL 8.0 46 #endif 47 48 49 50 uniform SHADOWMAP m_ShadowMap0; 51 uniform SHADOWMAP m_ShadowMap1; 52 uniform SHADOWMAP m_ShadowMap2; 53 uniform SHADOWMAP m_ShadowMap3; 54 #ifdef POINTLIGHT 55 uniform SHADOWMAP m_ShadowMap4; 56 uniform SHADOWMAP m_ShadowMap5; 57 #endif 58 59 #ifdef PSSM 60 uniform vec4 m_Splits; 61 #endif 62 uniform float m_ShadowIntensity; 63 64 const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE); 65 float shadowBorderScale = 1.0; 66 67 float Shadow_BorderCheck(in vec2 coord){ 68 // Fastest, "hack" method (uses 4-5 instructions) 69 vec4 t = vec4(coord.xy, 0.0, 1.0); 70 t = step(t.wwxy, t.xyzz); 71 return dot(t,t); 72 } 73 74 float Shadow_Nearest(in SHADOWMAP tex, in vec4 projCoord){ 75 float border = Shadow_BorderCheck(projCoord.xy); 76 if (border > 0.0){ 77 return 1.0; 78 } 79 return SHADOWCOMPARE(tex,projCoord); 80 } 81 82 float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){ 83 float border = Shadow_BorderCheck(projCoord.xy); 84 if (border > 0.0) 85 return 1.0; 86 87 vec2 pixSize = pixSize2 * shadowBorderScale; 88 89 float shadow = 0.0; 90 ivec2 o = ivec2(mod(floor(gl_FragCoord.xy), 2.0)); 91 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, 1.5)+o), projCoord.zw)); 92 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, 1.5)+o), projCoord.zw)); 93 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, -0.5)+o), projCoord.zw)); 94 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, -0.5)+o), projCoord.zw)); 95 shadow *= 0.25; 96 return shadow; 97 } 98 99 float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){ 100 float border = Shadow_BorderCheck(projCoord.xy); 101 if (border > 0.0) 102 return 1.0; 103 104 #ifdef GL_ARB_gpu_shader5 105 vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0); 106 vec4 gather = SHADOWGATHER(tex, coord); 107 #else 108 vec4 gather = vec4(0.0); 109 gather.x = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 0)); 110 gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0)); 111 gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1)); 112 gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1)); 113 #endif 114 115 vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE ); 116 vec2 mx = mix( gather.xz, gather.yw, f.x ); 117 return mix( mx.x, mx.y, f.y ); 118 } 119 120 float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){ 121 122 vec2 pixSize = pixSize2 * shadowBorderScale; 123 float shadow = 0.0; 124 float border = Shadow_BorderCheck(projCoord.xy); 125 if (border > 0.0) 126 return 1.0; 127 128 float bound = KERNEL * 0.5 - 0.5; 129 bound *= PCFEDGE; 130 for (float y = -bound; y <= bound; y += PCFEDGE){ 131 for (float x = -bound; x <= bound; x += PCFEDGE){ 132 vec4 coord = vec4(projCoord.xy + vec2(x,y) * pixSize, projCoord.zw); 133 shadow += SHADOWCOMPARE(tex, coord); 134 } 135 } 136 137 shadow = shadow / (KERNEL * KERNEL); 138 return shadow; 139 } 140 141 142 //12 tap poisson disk 143 const vec2 poissonDisk0 = vec2(-0.1711046, -0.425016); 144 const vec2 poissonDisk1 = vec2(-0.7829809, 0.2162201); 145 const vec2 poissonDisk2 = vec2(-0.2380269, -0.8835521); 146 const vec2 poissonDisk3 = vec2(0.4198045, 0.1687819); 147 const vec2 poissonDisk4 = vec2(-0.684418, -0.3186957); 148 const vec2 poissonDisk5 = vec2(0.6026866, -0.2587841); 149 const vec2 poissonDisk6 = vec2(-0.2412762, 0.3913516); 150 const vec2 poissonDisk7 = vec2(0.4720655, -0.7664126); 151 const vec2 poissonDisk8 = vec2(0.9571564, 0.2680693); 152 const vec2 poissonDisk9 = vec2(-0.5238616, 0.802707); 153 const vec2 poissonDisk10 = vec2(0.5653144, 0.60262); 154 const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419); 155 156 157 float Shadow_DoPCFPoisson(in SHADOWMAP tex, in vec4 projCoord){ 158 159 float shadow = 0.0; 160 float border = Shadow_BorderCheck(projCoord.xy); 161 if (border > 0.0){ 162 return 1.0; 163 } 164 165 vec2 texelSize = pixSize2 * 4.0 * PCFEDGE * shadowBorderScale; 166 167 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk0 * texelSize, projCoord.zw)); 168 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk1 * texelSize, projCoord.zw)); 169 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk2 * texelSize, projCoord.zw)); 170 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk3 * texelSize, projCoord.zw)); 171 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk4 * texelSize, projCoord.zw)); 172 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk5 * texelSize, projCoord.zw)); 173 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk6 * texelSize, projCoord.zw)); 174 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk7 * texelSize, projCoord.zw)); 175 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk8 * texelSize, projCoord.zw)); 176 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk9 * texelSize, projCoord.zw)); 177 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk10 * texelSize, projCoord.zw)); 178 shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk11 * texelSize, projCoord.zw)); 179 180 //this is divided by 12 181 return shadow * 0.08333333333; 182 } 183 184 #ifdef POINTLIGHT 185 float getPointLightShadows(in vec4 worldPos,in vec3 lightPos, 186 in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3,in SHADOWMAP shadowMap4,in SHADOWMAP shadowMap5, 187 in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3,in vec4 projCoord4,in vec4 projCoord5){ 188 float shadow = 1.0; 189 vec3 vect = worldPos.xyz - lightPos; 190 vec3 absv= abs(vect); 191 float maxComp = max(absv.x,max(absv.y,absv.z)); 192 if(maxComp == absv.y){ 193 if(vect.y < 0.0){ 194 shadow = GETSHADOW(shadowMap0, projCoord0 / projCoord0.w); 195 }else{ 196 shadow = GETSHADOW(shadowMap1, projCoord1 / projCoord1.w); 197 } 198 }else if(maxComp == absv.z){ 199 if(vect.z < 0.0){ 200 shadow = GETSHADOW(shadowMap2, projCoord2 / projCoord2.w); 201 }else{ 202 shadow = GETSHADOW(shadowMap3, projCoord3 / projCoord3.w); 203 } 204 }else if(maxComp == absv.x){ 205 if(vect.x < 0.0){ 206 shadow = GETSHADOW(shadowMap4, projCoord4 / projCoord4.w); 207 }else{ 208 shadow = GETSHADOW(shadowMap5, projCoord5 / projCoord5.w); 209 } 210 } 211 return shadow; 212 } 213 #else 214 #ifdef PSSM 215 float getDirectionalLightShadows(in vec4 splits,in float shadowPosition, 216 in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3, 217 in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3){ 218 float shadow = 1.0; 219 if(shadowPosition < splits.x){ 220 shadow = GETSHADOW(shadowMap0, projCoord0 ); 221 }else if( shadowPosition < splits.y){ 222 shadowBorderScale = 0.5; 223 shadow = GETSHADOW(shadowMap1, projCoord1); 224 }else if( shadowPosition < splits.z){ 225 shadowBorderScale = 0.25; 226 shadow = GETSHADOW(shadowMap2, projCoord2); 227 }else if( shadowPosition < splits.w){ 228 shadowBorderScale = 0.125; 229 shadow = GETSHADOW(shadowMap3, projCoord3); 230 } 231 return shadow; 232 } 233 #else 234 float getSpotLightShadows(in SHADOWMAP shadowMap,in vec4 projCoord){ 235 float shadow = 1.0; 236 projCoord /= projCoord.w; 237 shadow = GETSHADOW(shadowMap,projCoord); 238 239 //a small falloff to make the shadow blend nicely into the not lighten 240 //we translate the texture coordinate value to a -1,1 range so the length 241 //of the texture coordinate vector is actually the radius of the lighten area on the ground 242 projCoord = projCoord * 2.0 - 1.0; 243 float fallOff = ( length(projCoord.xy) - 0.9 ) / 0.1; 244 return mix(shadow,1.0,clamp(fallOff,0.0,1.0)); 245 246 } 247 #endif 248 #endif 249 250 out vec4 outFragColor; 251 252 #ifdef PSSM 253 in float shadowPosition; 254 #endif 255 256 in vec4 projCoord0; 257 in vec4 projCoord1; 258 in vec4 projCoord2; 259 in vec4 projCoord3; 260 261 #ifdef POINTLIGHT 262 in vec4 projCoord4; 263 in vec4 projCoord5; 264 in vec4 worldPos; 265 uniform vec3 m_LightPos; 266 #endif 267 268 #ifdef DISCARD_ALPHA 269 #ifdef COLOR_MAP 270 uniform sampler2D m_ColorMap; 271 #else 272 uniform sampler2D m_DiffuseMap; 273 #endif 274 uniform float m_AlphaDiscardThreshold; 275 varying vec2 texCoord; 276 #endif 277 278 #ifdef FADE 279 uniform vec2 m_FadeInfo; 280 #endif 281 282 void main(){ 283 284 #ifdef DISCARD_ALPHA 285 #ifdef COLOR_MAP 286 float alpha = texture2D(m_ColorMap,texCoord).a; 287 #else 288 float alpha = texture2D(m_DiffuseMap,texCoord).a; 289 #endif 290 291 if(alpha < m_AlphaDiscardThreshold){ 292 discard; 293 } 294 #endif 295 296 float shadow = 1.0; 297 #ifdef POINTLIGHT 298 shadow = getPointLightShadows(worldPos, m_LightPos, 299 m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3,m_ShadowMap4,m_ShadowMap5, 300 projCoord0, projCoord1, projCoord2, projCoord3, projCoord4, projCoord5); 301 #else 302 #ifdef PSSM 303 shadow = getDirectionalLightShadows(m_Splits, shadowPosition, 304 m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3, 305 projCoord0, projCoord1, projCoord2, projCoord3); 306 #else 307 //spotlight 308 shadow = getSpotLightShadows(m_ShadowMap0,projCoord0); 309 #endif 310 #endif 311 312 #ifdef FADE 313 shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y)); 314 #endif 315 316 shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity); 317 outFragColor = vec4(shadow, shadow, shadow, 1.0); 318 }
My code is:
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory;
public class Shadows extends SimpleApplication {
private String MATERIAL_LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
private String TEXTURE_STONE_WALL = "Textures/Terrain/BrickWall/BrickWall.jpg";
private String TEXTURE_STONE_WALL_NORMAL = "Textures/Terrain/BrickWall/BrickWall_normal.jpg";
private String TEXTURE_FLOOR = "Textures/Terrain/Pond/Pond.jpg";
private String TEXTURE_FLOOR_NORMAL = "Textures/Terrain/Pond/Pond_normal.png";
private String TEXTURE_MISSING = "";
private String TEXTURE_SKY = "Textures/Sky/Lagoon/";
private Vector3f LIGHT_DIRECTION_VECTOR = new Vector3f(5f, -2f, 5f);
private DirectionalLight sun;
@Override
public void simpleInitApp() {
setUpLight();
// Make something to look at
Geometry box1Geom = makeTexturedBox("box", ColorRGBA.Gray,
TEXTURE_STONE_WALL, TEXTURE_MISSING, TEXTURE_STONE_WALL_NORMAL,
TEXTURE_MISSING, false);
Geometry floor = makeFloor();
floor.setLocalTranslation(new Vector3f(0, -1.05f, 0));
cam.setLocation(cam.getLocation().add(new Vector3f(5, 4, 2)));
cam.lookAt(box1Geom.getWorldTranslation(), Vector3f.UNIT_Y);
// Make a sky box from 6 pictures
makeSky();
DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(
assetManager, 1024, 2);
dlsr.setLight(sun);
viewPort.addProcessor(dlsr);
rootNode.attachChild(box1Geom);
rootNode.attachChild(floor);
}
private Geometry makeTexturedBox(String name, ColorRGBA color,
String textureMap, String heightMap, String normalMap,
String specularMap, boolean invert) {
Box box = new Box(1, 1, 1);
Geometry boxGeom = new Geometry(name, box);
Material mat = new Material(assetManager, MATERIAL_LIGHTING);
mat.setBoolean("UseMaterialColors", true);
mat.setColor("Diffuse", color);
mat.setColor("Ambient", ColorRGBA.DarkGray);
mat.setColor("Specular", ColorRGBA.White);
mat.setFloat("Shininess", 128f); // [1,128]
if (!textureMap.equals("")) {
TextureKey diffuse = new TextureKey(textureMap, invert);
mat.setTexture("DiffuseMap", assetManager.loadTexture(diffuse));
}
if (!normalMap.equals("")) {
TextureKey normal = new TextureKey(normalMap, invert);
mat.setTexture("NormalMap", assetManager.loadTexture(normal));
}
if (!heightMap.equals("")) {
TextureKey parallax = new TextureKey(heightMap, invert);
mat.setTexture("ParallaxMap", assetManager.loadTexture(parallax));
}
if (!specularMap.equals("")) {
TextureKey specular = new TextureKey(specularMap, invert);
mat.setTexture("SpecularMap", assetManager.loadTexture(specular));
}
boxGeom.setMaterial(mat);
boxGeom.setShadowMode(ShadowMode.CastAndReceive);
return boxGeom;
}
/* Makes a simple pebbled floor */
private Geometry makeFloor() {
Box box = new Box(10, 0.1f, 10);
Geometry boxGeom = new Geometry("floor", box);
Material mat = new Material(assetManager, MATERIAL_LIGHTING);
mat.setColor("Ambient", ColorRGBA.Gray);
TextureKey diffuse = new TextureKey(TEXTURE_FLOOR, false);
mat.setTexture("DiffuseMap", assetManager.loadTexture(diffuse));
TextureKey normal = new TextureKey(TEXTURE_FLOOR_NORMAL, false);
mat.setTexture("NormalMap", assetManager.loadTexture(normal));
boxGeom.setMaterial(mat);
boxGeom.setShadowMode(ShadowMode.Receive);
return boxGeom;
}
/* Makes the sky box from jME3-testdata.jar files */
private void makeSky() {
Texture north = assetManager.loadTexture(TEXTURE_SKY
+ "lagoon_north.jpg");
Texture south = assetManager.loadTexture(TEXTURE_SKY
+ "lagoon_south.jpg");
Texture east = assetManager
.loadTexture(TEXTURE_SKY + "lagoon_east.jpg");
Texture west = assetManager
.loadTexture(TEXTURE_SKY + "lagoon_west.jpg");
Texture up = assetManager.loadTexture(TEXTURE_SKY + "lagoon_up.jpg");
Texture down = assetManager
.loadTexture(TEXTURE_SKY + "lagoon_down.jpg");
Spatial skyBox = SkyFactory.createSky(assetManager, west, east, north,
south, up, down);
rootNode.attachChild(skyBox);
}
private void setUpLight() {
sun = new DirectionalLight();
sun.setDirection(LIGHT_DIRECTION_VECTOR);
sun.setColor(ColorRGBA.White);
rootNode.addLight(sun);
AmbientLight ambient = new AmbientLight();
ambient.setColor(ColorRGBA.White);
rootNode.addLight(ambient);
}
/** Start the jMonkeyEngine application */
public static void main(String[] args) {
Shadows app = new Shadows();
app.start(); // use settings and run
}
}
Thanks!!