Improvements to rendering speeds.

origin
Joshua Sigona 3 years ago
parent 8e0af6413e
commit 234520ced4
  1. 214
      src/sig/Panel.java
  2. 10
      src/sig/SigRenderer.java
  3. 6
      src/sig/Triangle.java
  4. 2
      src/sig/utils/DrawUtils.java

@ -9,6 +9,7 @@ import java.awt.Color;
import java.awt.Image; import java.awt.Image;
import java.awt.image.MemoryImageSource; import java.awt.image.MemoryImageSource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.awt.image.ColorModel; import java.awt.image.ColorModel;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
@ -65,6 +66,7 @@ public class Panel extends JPanel implements Runnable {
thread.start(); thread.start();
} }
SigRenderer.depthBuffer = new float[width*height]; SigRenderer.depthBuffer = new float[width*height];
SigRenderer.depthBuffer_tri = new Triangle[width*height];
} }
/** /**
* Do your draws in here !! * Do your draws in here !!
@ -84,6 +86,7 @@ public class Panel extends JPanel implements Runnable {
for (int y=0;y<height;y++) { for (int y=0;y<height;y++) {
p[ (int)(x*SigRenderer.RESOLUTION) + (int)(y*SigRenderer.RESOLUTION) * width] = 0; p[ (int)(x*SigRenderer.RESOLUTION) + (int)(y*SigRenderer.RESOLUTION) * width] = 0;
SigRenderer.depthBuffer[x+y*width]=0; SigRenderer.depthBuffer[x+y*width]=0;
SigRenderer.depthBuffer_tri[x+y*width]=null;
} }
} }
@ -107,110 +110,120 @@ public class Panel extends JPanel implements Runnable {
Matrix matView = Matrix.QuickInverse(matCamera); Matrix matView = Matrix.QuickInverse(matCamera);
for (Triangle t : SigRenderer.triRender) { for (Triangle t : SigRenderer.triRender) {
Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle(); if (t.nextRenderTime<=System.currentTimeMillis()) {
Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle();
if (t.b!=null) { if (t.b!=null) {
matWorld = Matrix.MakeTranslation(t.b.pos.x,t.b.pos.y,t.b.pos.z); matWorld = Matrix.MakeTranslation(t.b.pos.x,t.b.pos.y,t.b.pos.z);
} }
triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
triTransformed.C = Matrix.MultiplyVector(matWorld,t.C);
triTransformed.T = t.T;
triTransformed.U = t.U;
triTransformed.V = t.V;
triTransformed.tex = t.tex;
triTransformed.b=t.b;
Vector normal=new Vector(),line1=new Vector(),line2=new Vector(); triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
line1 = Vector.subtract(triTransformed.B,triTransformed.A); triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
line2 = Vector.subtract(triTransformed.C,triTransformed.A); triTransformed.C = Matrix.MultiplyVector(matWorld,t.C);
triTransformed.T = t.T;
triTransformed.U = t.U;
triTransformed.V = t.V;
triTransformed.tex = t.tex;
triTransformed.b=t.b;
triTransformed.unmodifiedTri=t;
normal = Vector.crossProduct(line1,line2); Vector normal=new Vector(),line1=new Vector(),line2=new Vector();
normal = Vector.normalize(normal); line1 = Vector.subtract(triTransformed.B,triTransformed.A);
line2 = Vector.subtract(triTransformed.C,triTransformed.A);
Vector cameraRay = Vector.subtract(triTransformed.A,SigRenderer.vCamera); normal = Vector.crossProduct(line1,line2);
normal = Vector.normalize(normal);
if (Vector.dotProduct(normal,cameraRay)<0) { Vector cameraRay = Vector.subtract(triTransformed.A,SigRenderer.vCamera);
Vector lightDir = Vector.multiply(SigRenderer.vLookDir, -1);
lightDir = Vector.normalize(lightDir);
//System.out.println(-Vector.dotProduct(normal,Vector.normalize(cameraRay))); float distSquared = ((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+
float dp = 0.1f;
if (t.b!=null) {
dp = Math.max(0.1f,Math.min(1,(1f/((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+
(triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+
(triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z))*64)))*0.5f+Math.max(0.1f,Math.min(1,1-Vector.dotProduct(normal,SigRenderer.vLookDir)))*0.5f;
} else {
dp = Math.max(0.1f,Vector.dotProduct(lightDir,normal));
}
/*Vector center = Vector.divide(Vector.add(triTransformed.A,Vector.add(triTransformed.B,triTransformed.C)),3);
Vector cameraRay2 = Vector.subtract(center,SigRenderer.vCamera);
float dp = Math.max(0.1f,Math.min(1,(1f/((cameraRay2.x-center.x)*(cameraRay2.x-center.x)+
(cameraRay2.y-center.y)*(cameraRay2.y-center.y)+
(cameraRay2.z-center.z)*(cameraRay2.z-center.z))*4)));*/
/*float dp = Math.max(0.1f,Math.min(1,(1f/((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+
(triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+ (triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+
(triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z))*4)));*/ (triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z));
triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A); if (Vector.dotProduct(normal,cameraRay)<0&&Vector.dotProduct(cameraRay,SigRenderer.vLookDir)>0.1f&&distSquared<4096) {
triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B); Vector lightDir = Vector.multiply(SigRenderer.vLookDir, -1);
triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C); lightDir = Vector.normalize(lightDir);
triTransformed.copyExtraDataTo(triViewed);
triViewed.setColor((0)+(0<<8)+((int)(dp*255)<<16)); //System.out.println(-Vector.dotProduct(normal,Vector.normalize(cameraRay)));
float dp = 0.1f;
int clippedTriangles = 0; if (t.b!=null) {
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; dp = Math.max(0.1f,Math.min(1,(1f/((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+
(triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+
clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,0.1f),new Vector(0,0,1), triViewed, clipped); (triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z))*64)))*0.5f+Math.max(0.1f,Math.min(1,1-Vector.dotProduct(normal,SigRenderer.vLookDir)))*0.5f;
for (int i=0;i<clippedTriangles;i++) { } else {
if (i>0) { dp = Math.max(0.1f,Vector.dotProduct(lightDir,normal));
triProjected = new Triangle(); }
/*Vector center = Vector.divide(Vector.add(triTransformed.A,Vector.add(triTransformed.B,triTransformed.C)),3);
Vector cameraRay2 = Vector.subtract(center,SigRenderer.vCamera);
float dp = Math.max(0.1f,Math.min(1,(1f/((cameraRay2.x-center.x)*(cameraRay2.x-center.x)+
(cameraRay2.y-center.y)*(cameraRay2.y-center.y)+
(cameraRay2.z-center.z)*(cameraRay2.z-center.z))*4)));*/
/*float dp = Math.max(0.1f,Math.min(1,(1f/((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+
(triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+
(triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z))*4)));*/
triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A);
triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B);
triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C);
triTransformed.copyExtraDataTo(triViewed);
triViewed.setColor((0)+(0<<8)+((int)(dp*255)<<16));
int clippedTriangles = 0;
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()};
clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,0.1f),new Vector(0,0,1), triViewed, clipped);
for (int i=0;i<clippedTriangles;i++) {
if (i>0) {
triProjected = new Triangle();
}
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].A);
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B);
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
triProjected.col = clipped[i].col;
triProjected.tex = clipped[i].tex;
triProjected.T = (Vector2)clipped[i].T.clone();
triProjected.U = (Vector2)clipped[i].U.clone();
triProjected.V = (Vector2)clipped[i].V.clone();
triProjected.b=clipped[i].b;
triProjected.unmodifiedTri=clipped[i].unmodifiedTri;
triProjected.T.u = triProjected.T.u/triProjected.A.w;
triProjected.U.u = triProjected.U.u/triProjected.B.w;
triProjected.V.u = triProjected.V.u/triProjected.C.w;
triProjected.T.v = triProjected.T.v/triProjected.A.w;
triProjected.U.v = triProjected.U.v/triProjected.B.w;
triProjected.V.v = triProjected.V.v/triProjected.C.w;
triProjected.T.w = 1.0f/triProjected.A.w;
triProjected.U.w = 1.0f/triProjected.B.w;
triProjected.V.w = 1.0f/triProjected.C.w;
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
triProjected.C = Vector.divide(triProjected.C, triProjected.C.w);
triProjected.A.x*=-1f;
triProjected.A.y*=-1f;
triProjected.B.x*=-1f;
triProjected.B.y*=-1f;
triProjected.C.x*=-1f;
triProjected.C.y*=-1f;
Vector viewOffset = new Vector(1,1,0);
triProjected.A = Vector.add(triProjected.A,viewOffset);
triProjected.B = Vector.add(triProjected.B,viewOffset);
triProjected.C = Vector.add(triProjected.C,viewOffset);
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.B.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
triProjected.C.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.C.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
accumulatedTris.add(triProjected);
} }
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].A); } else {
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B); t.nextRenderTime=System.currentTimeMillis()+200;
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
triProjected.col = clipped[i].col;
triProjected.tex = clipped[i].tex;
triProjected.T = (Vector2)clipped[i].T.clone();
triProjected.U = (Vector2)clipped[i].U.clone();
triProjected.V = (Vector2)clipped[i].V.clone();
triProjected.b=clipped[i].b;
triProjected.T.u = triProjected.T.u/triProjected.A.w;
triProjected.U.u = triProjected.U.u/triProjected.B.w;
triProjected.V.u = triProjected.V.u/triProjected.C.w;
triProjected.T.v = triProjected.T.v/triProjected.A.w;
triProjected.U.v = triProjected.U.v/triProjected.B.w;
triProjected.V.v = triProjected.V.v/triProjected.C.w;
triProjected.T.w = 1.0f/triProjected.A.w;
triProjected.U.w = 1.0f/triProjected.B.w;
triProjected.V.w = 1.0f/triProjected.C.w;
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
triProjected.C = Vector.divide(triProjected.C, triProjected.C.w);
triProjected.A.x*=-1f;
triProjected.A.y*=-1f;
triProjected.B.x*=-1f;
triProjected.B.y*=-1f;
triProjected.C.x*=-1f;
triProjected.C.y*=-1f;
Vector viewOffset = new Vector(1,1,0);
triProjected.A = Vector.add(triProjected.A,viewOffset);
triProjected.B = Vector.add(triProjected.B,viewOffset);
triProjected.C = Vector.add(triProjected.C,viewOffset);
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.B.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
triProjected.C.x*=0.5f*SigRenderer.SCREEN_WIDTH;
triProjected.C.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
accumulatedTris.add(triProjected);
} }
} }
} }
@ -258,6 +271,7 @@ public class Panel extends JPanel implements Runnable {
} }
for (Triangle tt : triList) { for (Triangle tt : triList) {
if (tt.tex!=null) { if (tt.tex!=null) {
tt.unmodifiedTri.nextRenderTime=System.currentTimeMillis()+200;
DrawUtils.TexturedTriangle(p, DrawUtils.TexturedTriangle(p,
(int)tt.A.x,(int)tt.A.y,tt.T.u,tt.T.v,tt.T.w, (int)tt.A.x,(int)tt.A.y,tt.T.u,tt.T.v,tt.T.w,
(int)tt.B.x,(int)tt.B.y,tt.U.u,tt.U.v,tt.U.w, (int)tt.B.x,(int)tt.B.y,tt.U.u,tt.U.v,tt.U.w,
@ -274,6 +288,14 @@ public class Panel extends JPanel implements Runnable {
totalTime+=System.nanoTime()-startTime2; totalTime+=System.nanoTime()-startTime2;
} }
} }
for (int x=0;x<SigRenderer.SCREEN_WIDTH;x++) {
for (int y=0;y<SigRenderer.SCREEN_HEIGHT;y++) {
Triangle t = SigRenderer.depthBuffer_tri[x+y*SigRenderer.SCREEN_WIDTH];
if (t!=null) {
t.nextRenderTime=-1;
}
}
}
SigRenderer.request=null; SigRenderer.request=null;
SigRenderer.answer=SigRenderer.tempAnswer; SigRenderer.answer=SigRenderer.tempAnswer;
if (SigRenderer.PROFILING) { if (SigRenderer.PROFILING) {

@ -36,6 +36,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
public static final float RESOLUTION=1; public static final float RESOLUTION=1;
public static float rot = (float)Math.PI/4; //In radians. public static float rot = (float)Math.PI/4; //In radians.
public static Map<String,Block> blockGrid = new HashMap<>(); public static Map<String,Block> blockGrid = new HashMap<>();
public static HashMap<String,Triangle> renderMap = new HashMap<>();
public static List<Pixel> pixels; public static List<Pixel> pixels;
@ -45,16 +46,17 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH; public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH;
public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar); public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar);
public static Vector vCamera = new Vector(0.5f,2f,-15f); public static Vector vCamera = new Vector(63.5f,20f,63.5f);
public static Vector vLookDir = new Vector(0,0,1); public static Vector vLookDir = new Vector(0,0,1);
public static float yaw = (float)(-Math.PI/8); public static float yaw = (float)(-Math.PI/8);
public static float pitch = (float)(Math.PI/8); public static float pitch = (float)(-Math.PI/6);
public static float roll = 0; public static float roll = 0;
final float MOVESPEED = 0.2f; final float MOVESPEED = 0.2f;
final float TURNSPEED = 0.05f; final float TURNSPEED = 0.05f;
public static float[] depthBuffer; public static float[] depthBuffer;
public static Triangle[] depthBuffer_tri;
public static HashMap<TextureType,Texture> blockTextures = new HashMap<TextureType,Texture>(); public static HashMap<TextureType,Texture> blockTextures = new HashMap<TextureType,Texture>();
@ -121,8 +123,8 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
SigRenderer(JFrame f) { SigRenderer(JFrame f) {
//cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false)); //cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false));
Random r = new Random(438107); Random r = new Random(438107);
for (int x=0;x<64;x++) { for (int x=0;x<128;x++) {
for (int z=0;z<64;z++) { for (int z=0;z<128;z++) {
if (Math.random()<=0.5) { if (Math.random()<=0.5) {
addBlock(new Vector(x,0,z),BlockType.DIRT); addBlock(new Vector(x,0,z),BlockType.DIRT);
} else { } else {

@ -7,6 +7,8 @@ public class Triangle {
int col = Color.WHITE.getRGB(); int col = Color.WHITE.getRGB();
public Block b = null; public Block b = null;
public Texture tex = null; public Texture tex = null;
public long nextRenderTime = -1l;
public Triangle unmodifiedTri;
public Triangle() { public Triangle() {
this(new Vector(),new Vector(),new Vector()); this(new Vector(),new Vector(),new Vector());
} }
@ -28,6 +30,7 @@ public class Triangle {
targetTriangle.col=this.col; targetTriangle.col=this.col;
targetTriangle.tex=this.tex; targetTriangle.tex=this.tex;
targetTriangle.b=this.b; targetTriangle.b=this.b;
targetTriangle.unmodifiedTri=this.unmodifiedTri;
} }
@Override @Override
protected Object clone(){ protected Object clone(){
@ -35,6 +38,7 @@ public class Triangle {
t.col = col; t.col = col;
t.tex=tex; t.tex=tex;
t.b=b; t.b=b;
t.unmodifiedTri=unmodifiedTri;
return t; return t;
} }
@Override @Override
@ -100,6 +104,7 @@ public class Triangle {
out_tri[0].col = in.col; out_tri[0].col = in.col;
out_tri[0].tex = in.tex; out_tri[0].tex = in.tex;
out_tri[0].b=in.b; out_tri[0].b=in.b;
out_tri[0].unmodifiedTri=in.unmodifiedTri;
out_tri[0].A = inside_points[0]; out_tri[0].A = inside_points[0];
out_tri[0].T = inside_tex[0]; out_tri[0].T = inside_tex[0];
out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0],t); out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0],t);
@ -117,6 +122,7 @@ public class Triangle {
out_tri[0].col=out_tri[1].col=in.col; out_tri[0].col=out_tri[1].col=in.col;
out_tri[0].tex=out_tri[1].tex=in.tex; out_tri[0].tex=out_tri[1].tex=in.tex;
out_tri[0].b=out_tri[1].b=in.b; out_tri[0].b=out_tri[1].b=in.b;
out_tri[0].unmodifiedTri=out_tri[1].unmodifiedTri=in.unmodifiedTri;
out_tri[0].A = inside_points[0]; out_tri[0].A = inside_points[0];
out_tri[0].B = inside_points[1]; out_tri[0].B = inside_points[1];
out_tri[0].T = inside_tex[0]; out_tri[0].T = inside_tex[0];

@ -86,6 +86,7 @@ public class DrawUtils {
} }
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f)); Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f));
SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w;
SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri;
} }
t+=tstep; t+=tstep;
} }
@ -141,6 +142,7 @@ public class DrawUtils {
} }
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f)); Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f));
SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w;
SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri;
} }
t+=tstep; t+=tstep;
} }

Loading…
Cancel
Save