Strange Shadows

Started by qcrist, September 03, 2011, 07:37:53 PM

Previous topic - Next topic

qcrist

I am getting some strang shadow from this code. Did I call a method wrong?



Models and textures:http://www.mediafire.com/?3aasqcoe7iih9hv

import java.awt.Color;
import java.io.File;

import com.threed.jpct.Config;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.Projector;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.util.Light;
import com.threed.jpct.util.ShadowHelper;

public class BasicMap extends Map{

public static String mapName = "basic";

static ShadowHelper sh;

static Object3D floor;
static Object3D obj;
static Light sun;
static Object3D sunObj;

public BasicMap(World w, String maps) {
super(w, maps, mapName);
}

@Override
public void doLoop() {
sh.drawScene();
System.out.println(camera.getPosition());
}

@Override
public void mapConfig() {
Config.fadeoutLight=true;
Config.linearDiv=Game.SEEING_DISTANCE/2;
Config.lightDiscardDistance=Game.SEEING_DISTANCE;
Config.oldStyle3DSLoader=true;
camera.setPosition(0,-Game.PLAYER_HEIGHT-90,0);

sun = new Light(world);
sun.setPosition(new SimpleVector(500,-600,500));
sun.setIntensity(255,255,255);
sun.setAttenuation(800);
moveObject(sunObj, sun.getPosition());

Projector projector = new Projector();
projector.setFOV(1.5f);
projector.setYFOV(1.5f);
projector.setPosition(sun.getPosition());
projector.lookAt(floor.getTransformedCenter());

sh = new ShadowHelper(world, Game.buffer, projector, 2048);
sh.setCullingMode(false);
sh.setAmbientLight(new Color(100,100,100));
sh.setLightMode(true);
sh.setFiltering(true);
sh.setBorder(0);

sh.addCaster(obj);
sh.addCaster(floor);

sh.addReceiver(floor);
sh.addReceiver(obj);

sh.updateShadowMap();
}

@Override
public void makeObjects() {

loadTextures(new File(MAPIMAGES));
loadTextures(new File(MAPMODELS));

floor = loadModel(MAPMODELS+"floor.3ds",null);
floor.setOrigin(new SimpleVector(0,0,0));
floor.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
floor.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
floor.translate(0,0,0);
world.addObject(floor);

obj = loadModel(MAPMODELS+"test.3ds",null);
obj.setOrigin(new SimpleVector(0,0,0));
obj.translate(0,0,0);
obj.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
obj.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
world.addObject(obj);

sunObj = Primitives.getSphere(5);
sunObj.setOrigin(new SimpleVector(0,0,0));
world.addObject(sunObj);

world.buildAllObjects();
}

}


import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Matrix;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.World;

public class Game {

final static float COLLISION_SPHERE_RADIUS=8f;
final static float PLAYER_HEIGHT=60f;
final static SimpleVector ELLIPSOID_RADIUS=new SimpleVector(COLLISION_SPHERE_RADIUS,PLAYER_HEIGHT/2f,COLLISION_SPHERE_RADIUS);
final static SimpleVector JUMPING_ELLIPSOID_RADIUS=new SimpleVector(COLLISION_SPHERE_RADIUS,PLAYER_HEIGHT/2f+10,COLLISION_SPHERE_RADIUS);
final static float GRAVITY=4f;
final static float SEEING_DISTANCE=1000;
final static float WALK_SPEED=2.5f;
final static float RUN_SPEED=WALK_SPEED*2;
final static float HYPER_SPEED=WALK_SPEED*5; //Couldn't resist :D
final static float LUDACRIS_SPEED=WALK_SPEED*10; // oh yes I did
final static String IMAGES = "img/";
final static String MAPS = "maps/";

private static Graphics graphics;
private static BufferedImage graphicsImage;
private static boolean graphicsUpdated = false;
private static Texture graphicsTexture;

static FrameBuffer buffer;
static World world;
static Camera camera;
static Map map;

static DisplayMode dm = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode();
static int displayWidth=dm.getWidth();
static int displayHeight=dm.getHeight();
static float CURRENT_SPEED=2.5f;

private int fallDistance = 0;
private boolean kill = false;
private boolean isJumping = false;

public static void main(String[] args) throws Exception {
new Game(args);
}

private Game(String[] args) throws Exception {

initObjects();
gameConfig();
map.makeObjects();
map.mapConfig();
gameLoop();
}

private void initObjects()
{
world=new World();
camera=world.getCamera();
map=new BasicMap(world,MAPS);
buffer=new FrameBuffer(displayWidth, displayHeight, FrameBuffer.SAMPLINGMODE_NORMAL);
}

private void gameConfig() throws Exception
{
world.setAmbientLight(255,255,255);
world.setFogging(World.FOGGING_ENABLED);
world.setFogParameters(0, SEEING_DISTANCE,0,0,0);
Config.farPlane=SEEING_DISTANCE*2;

buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);
Display.setFullscreen(true);
Mouse.setGrabbed(true);

int dw,dh;
dw = nearest2Pow(displayWidth);
dh = nearest2Pow(displayHeight);
graphicsImage = new BufferedImage(dw,dh,BufferedImage.TYPE_INT_RGB);
graphics = graphicsImage.getGraphics();
graphicsTexture = new Texture(graphicsImage);
}

public int nearest2Pow(int num)
{
return (int)Math.pow(2,(int)(Math.log10(num)/Math.log10(2)+1));
}

private void doCameraGravity()
{
fallDistance++;
SimpleVector camPos=camera.getPosition();
camPos.add(new SimpleVector(0, PLAYER_HEIGHT/2f, 0));
SimpleVector dir=new SimpleVector(0, GRAVITY*fallDistance/10, 0);
dir=world.checkCollisionEllipsoid(camPos, dir, ELLIPSOID_RADIUS, 1);
camPos.add(new SimpleVector(0, -PLAYER_HEIGHT/2f, 0));
if (isJumping && !dir.equals(new SimpleVector(0,GRAVITY*fallDistance/10,0)) && fallDistance<0)
dir.y/=2;
dir.x=0;
dir.z=0;
camPos.add(dir);
camera.setPosition(camPos);
if (!dir.equals(new SimpleVector(0,GRAVITY*fallDistance/10,0)))
{
if (fallDistance>0)
isJumping=false;
if (fallDistance>20)
System.out.println(fallDistance);
fallDistance=0;
}

}

private void doCameraMovement()
{
camera.moveCamera(new SimpleVector(0,1,0), PLAYER_HEIGHT/2f);
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL))
if (Keyboard.isKeyDown(Keyboard.KEY_CAPITAL)) //I bet you got help :D
CURRENT_SPEED=LUDACRIS_SPEED;
else
CURRENT_SPEED=HYPER_SPEED;
else
CURRENT_SPEED=RUN_SPEED;
else
CURRENT_SPEED=WALK_SPEED;
if (Keyboard.isKeyDown(Keyboard.KEY_W))
moveCamera(Camera.CAMERA_MOVEIN, CURRENT_SPEED);
if (Keyboard.isKeyDown(Keyboard.KEY_S))
moveCamera(Camera.CAMERA_MOVEOUT, CURRENT_SPEED);
if (Keyboard.isKeyDown(Keyboard.KEY_A))
moveCamera(Camera.CAMERA_MOVELEFT, CURRENT_SPEED);
if (Keyboard.isKeyDown(Keyboard.KEY_D))
moveCamera(Camera.CAMERA_MOVERIGHT, CURRENT_SPEED);
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !isJumping)
fallDistance=-12;
isJumping=true;
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
kill=true;
camera.moveCamera(new SimpleVector(0, -1, 0), PLAYER_HEIGHT/2f);
}

public void moveCamera(int paramInt, float paramFloat)
{
float f = -1.0F;
if ((paramInt & 0x1) == 1)
f = 1.0F;
f *= paramFloat;
int i = 2 - ((paramInt + 1) / 2 - 1);
float x,z;
x=camera.getBack().get(0, i);
z=camera.getBack().get(2, i);
cameraMove(camera,new SimpleVector(x*f,0,0));
cameraMove(camera,new SimpleVector(0,0,z*f));
}

public void cameraMove(Camera cam, SimpleVector dir)
{
SimpleVector move = world.checkCollisionEllipsoid(cam.getPosition(), dir, ELLIPSOID_RADIUS, 3);
move.add(cam.getPosition());
camera.setPosition(move);
}

public void doMouseMovement()
{
Mouse.poll();
Matrix rot = world.getCamera().getBack();
int dx = Mouse.getDX();
int dy = Mouse.getDY();
float ts;
float tsy;
ts = dx / 500f;
tsy = dy / 500f;
if (tsy>0)
if (camera.getDirection().y>-0.95)
rot.rotateX(tsy);
else;
else
if (camera.getDirection().y<0.95)
rot.rotateX(tsy);
rot.rotateAxis(rot.getYAxis(), ts);
}

private void gameLoop() throws LWJGLException {
World.setDefaultThread(Thread.currentThread());

Timer timer=new Timer(25);
timer.start();

Timer fpsTimer=new Timer(1000);
fpsTimer.start();

while (!kill) {

long ticks=timer.getElapsedTicks();
for (int i=0; i<ticks; i++)
{
doCameraMovement();
doCameraGravity();
}

doMouseMovement();

buffer.clear();
map.sky.render(world, buffer);
world.renderScene(buffer);
world.draw(buffer);
blitTesting(buffer);
map.doLoop();
buffer.update();
buffer.displayGLOnly();
Thread.yield();
}

buffer.dispose();
System.exit(0);
}

public void blitTesting(FrameBuffer buffer)
{
if (graphicsUpdated)
{
graphicsUpdated=false;
graphicsTexture = new Texture(graphicsImage);
}
buffer.blit(graphicsTexture,0,0,0,0,displayWidth,displayHeight,FrameBuffer.TRANSPARENT_BLITTING);
}

class Timer {
private long ticks=0;
private long granularity=0;

public Timer(int granularity) {
this.granularity=granularity;
}

public void start() {
ticks=System.currentTimeMillis();
}

public void reset() {
start();
}

public long getElapsedTicks() {
long cur=System.currentTimeMillis();
long l=cur-ticks;

if (l>=granularity) {
ticks=cur-l%granularity;
return l/granularity;
}
return 0;
}
}
}


import java.io.File;

import com.threed.jpct.Camera;
import com.threed.jpct.Loader;
import com.threed.jpct.Matrix;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.SkyBox;

public abstract class Map {

public World world;
public Camera camera;
public SkyBox sky;

public String MAPMODELS;
public String MAPIMAGES;

public Map(World w,String maps, String mapName)
{
world = w;
camera = w.getCamera();
String mapDir = maps+mapName+"/";
MAPIMAGES = mapDir+"img/";
MAPMODELS = mapDir+"model/";
loadSky(MAPIMAGES+"sky/",".png");
}

public void loadTextures(File dir)
{
String[] files=dir.list();
for (String name : files) {
if (name.toLowerCase().endsWith(".jpg"))
TextureManager.getInstance().addTexture(name, new Texture(dir.getPath()+"\\"+name));
}
}

public void addTexture(String name,String file)
{
TextureManager.getInstance().addTexture(name, new Texture(file));
}

public void loadSky(String dir,String extention)
{
System.out.println("Loading SkyBox from "+dir);
if (extention.charAt(0)!='.')
extention = "."+extention;
String sides[] = {"left","front","right","back","up","down"};
for (String side:sides)
{
addTexture(side,dir+side+extention);
}
sky = new SkyBox(Game.SEEING_DISTANCE*10);
sky.compile();
}

public Object3D loadModel(String filename, String image) {
if (image!=null)
if (!TextureManager.getInstance().containsTexture(image))
TextureManager.getInstance().addTexture(image, new Texture(image));
Object3D[] model = Loader.load3DS(filename, 1f);
Object3D o3d = new Object3D(0);
Object3D temp = null;
for (int i = 0; i < model.length; i++) {
temp = model[i];
temp.setCenter(SimpleVector.ORIGIN);
temp.rotateX((float)( -.5*Math.PI));
temp.rotateMesh();
temp.setRotationMatrix(new Matrix());
o3d = Object3D.mergeObjects(o3d, temp);
o3d.build();
}
if (image!=null)
o3d.setTexture(image);
o3d.build();
return o3d;
}

public void moveObject(Object3D obj, SimpleVector to)
{
SimpleVector move = to;
move.sub(obj.getTranslation());
obj.translate(move);
}

public abstract void doLoop();

public abstract void mapConfig();

public abstract void makeObjects();
}

EgonOlsen

These are self shadowing artifacts. They are the result of unaccuracies in the GPU and depending on the GPU's model and vendor, they will look different. There's not much you do about them. Try to avoid making a shadow caster a receiver too and leave it to the vertex lighting to darken the areas that are facing away from the light source instead. In Robombs, i had the same problem...and if you look closely, you'll notice that only the walls cast and receive shadows. Everything else is either a receiver or a caster, but not both. The walls suffer from the same artifacts but they aren't that bad because the walls a tiny and nobody looks closely at them during the action.