shadows...
-
- Posts: 11
- Joined: Wed Apr 23, 2008 11:44 am
shadows...
gta chinatown wars apparently uses stencil shadow volume, but for a scene where there are many shadow cast objects, this technique can be a great performance hit.
does anyone know how shadows are achieved in silent hill game? Based in artifacts sometimes visible in the edges of shadows, the technique used must be shadowmap, but the PSP hardware doesn't have pixel shader or something like the opengl extensions necessary to make it work...
does anyone know how shadows are achieved in silent hill game? Based in artifacts sometimes visible in the edges of shadows, the technique used must be shadowmap, but the PSP hardware doesn't have pixel shader or something like the opengl extensions necessary to make it work...
Who says shadow mapping depends on pixel shaders?
http://www.paulsprojects.net/tutorials/smt/smt.html
Also, there are other methods to achieve shadows that don't depend on shaders.
http://www.paulsprojects.net/tutorials/smt/smt.html
Also, there are other methods to achieve shadows that don't depend on shaders.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 11
- Joined: Wed Apr 23, 2008 11:44 am
shadowmap implementantion modifying SDK reflexion sample.
----------------------------------------------------------------------------
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <pspgu.h>
#include <pspgum.h>
#include <pspvfpu.h>
PSP_MODULE_INFO("ShadowMap Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
static unsigned int __attribute__((aligned(16))) list[262144];
extern unsigned char logo_start[];
struct Vertex
{
float u, v;
unsigned int color;
float x,y,z;
};
struct Vertex __attribute__((aligned(16))) obj[36] = {
{0, 0, 0xff6666ff,-1,-1, 1},
{1, 0, 0xff6666ff, 1,-1, 1},
{1, 1, 0xff6666ff, 1, 1, 1},
{0, 0, 0xff6666ff,-1,-1, 1},
{1, 1, 0xff6666ff, 1, 1, 1},
{0, 1, 0xff6666ff,-1, 1, 1},
{1, 1, 0xff66ff66, 1, 1, 1},
{0, 1, 0xff66ff66, 1,-1, 1},
{0, 0, 0xff66ff66, 1,-1,-1},
{1, 1, 0xff66ff66, 1, 1, 1},
{0, 0, 0xff66ff66, 1,-1,-1},
{1, 0, 0xff66ff66, 1, 1,-1},
{0, 1, 0xffff6666,-1, 1, 1},
{0, 0, 0xffff6666, 1, 1, 1},
{1, 0, 0xffff6666, 1, 1,-1},
{0, 1, 0xffff6666,-1, 1, 1},
{1, 0, 0xffff6666, 1, 1,-1},
{1, 1, 0xffff6666,-1, 1,-1},
{1, 1, 0xff6666ff, 1.0f,-1.0f,-1.0f},
{0, 1, 0xff6666ff,-1.0f,-1.0f,-1.0f},
{0, 0, 0xff6666ff,-1.0f, 1.0f,-1.0f},
{1, 1, 0xff6666ff, 1.0f,-1.0f,-1.0f},
{0, 0, 0xff6666ff,-1.0f, 1.0f,-1.0f},
{1, 0, 0xff6666ff, 1.0f, 1.0f,-1.0f},
{1, 0, 0xff66ff66,-1,-1,-1},
{1, 1, 0xff66ff66,-1,-1, 1},
{0, 1, 0xff66ff66,-1, 1, 1},
{1, 0, 0xff66ff66,-1,-1,-1},
{0, 1, 0xff66ff66,-1, 1, 1},
{0, 0, 0xff66ff66,-1, 1,-1},
{0, 1, 0xffff6666,-1,-1,-1},
{0, 0, 0xffff6666, 1,-1,-1},
{1, 0, 0xffff6666, 1,-1, 1},
{0, 1, 0xffff6666,-1,-1,-1},
{1, 0, 0xffff6666, 1,-1, 1},
{1, 1, 0xffff6666,-1,-1, 1},
};
struct Vertex __attribute__((aligned(16))) mirror[6] = {
{0, 0, 0xaa000000, -2.0f, 0, -2.0f},
{2, 2, 0xaa000000, 2.0f, 0, 2.0f},
{2, 0, 0xaa000000, 2.0f, 0, -2.0f},
{0, 0, 0xaa000000, -2.0f, 0, -2.0f},
{0, 2, 0xaa000000, -2.0f, 0, 2.0f},
{2, 2, 0xaa000000, 2.0f, 0, 2.0f}
};
struct Vertex __attribute__((aligned(16))) border[6] = {
{0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f},
{2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f},
{2, 0, 0xff0055aa, 2.125f, -0.01, -2.125f},
{0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f},
{0, 2, 0xff0055aa, -2.125f, -0.01, 2.125f},
{2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f}
};
int SetupCallbacks();
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (2) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH * SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
#define ZBUFFER_LINEAR(x) (0x600000 + x)
#define ZBUFFER_UNSWIZ(x) (0x200000 + x)
#define VRAM_OFFSET(x) (0x4000000 + x)
#define ZBUFFER_LINEAR16BPP ZBUFFER_UNSWIZ
ScePspFMatrix4 projMatrix, viewMatrixCam, viewMatrixLight;
ScePspFMatrix4 projFinal, unprojFinal;
void setUnProjMatrix(const float *mat)
{
__asm__ volatile (
"ulv.q C000, 0x0 (%0)\n"
"ulv.q C010, 0x10(%0)\n"
"ulv.q C020, 0x20(%0)\n"
"ulv.q C030, 0x30(%0)\n"
: :"r" (mat) );
}
void setProjMatrix(const float *mat)
{
__asm__ volatile (
"ulv.q C100, 0x0 (%0)\n"
"ulv.q C110, 0x10(%0)\n"
"ulv.q C120, 0x20(%0)\n"
"ulv.q C130, 0x30(%0)\n"
: :"r" (mat) );
}
float output[4] __attribute__((aligned(VFPU_ALIGNMENT)));
void TransformArraysInOutByMatUnProj(const float *vec, float *out)
{
__asm__ volatile (
"ulv.q R200, 0x0(%1)\n"
"vone.s S230\n"
"vtfm4.q R300, E000, R200\n"
"sv.q R300, 0x0(%0)\n"
: : "r"(output) , "r" (vec) );
out[0]=output[0];
out[1]=output[1];
out[2]=output[2];
out[3]=output[3];
}
void TransformArraysInOutByMatProj(const float *vec, float *out)
{
__asm__ volatile (
"ulv.q R200, 0x0(%1)\n"
"vone.s S230\n"
"vtfm4.q R300, E100, R200\n"
"sv.q R300, 0x0(%0)\n"
: : "r"(output) , "r" (vec) );
out[0]=output[0];
out[1]=output[1];
out[2]=output[2];
out[3]=output[3];
}
void toScreen(float nx, float ny, float nz,
int *sx, int *sy, int *sz)
{
*sx = ((nx+1.0f)/2.0f) * 480.0f;
*sy = (1.0f - ((ny+1.0f)/2.0f)) * 272.0f;
*sz = (1.0f-nz)*32768;
}
void fromScreen(int sx, int sy, int sz,
float *nx, float *ny, float *nz)
{
*nx = sx*(2.0f/480.0f)-1.0f;
*ny = 1.0f-sy*(2.0f/272.0f);
*nz = 1.0f-sz/32768.0f;
}
ScePspFMatrix4 finalMatrix;
void gumProjectF2(float objx, float objy, float objz,
float *winx, float *winy, float *winz)
{
float in[4];
in[0]=objx;
in[1]=objy;
in[2]=objz;
in[3]=1.0;
TransformArraysInOutByMatProj(in,in);
if (in[3] == 0.0) return;
*winx = in[0]/in[3];
*winy = in[1]/in[3];
*winz = in[2]/in[3];
}
void gumProjectI2(float objx, float objy, float objz,
int *winx, int *winy, int *winz)
{
float fwx,fwy,fwz;
gumProjectF2(objx,objy,objz,&fwx,&fwy,&fwz);
toScreen(fwx,fwy,fwz,winx,winy,winz);
}
void gumUnProjectF2(float winx, float winy, float winz,
float *objx, float *objy, float *objz)
{
float in[4];
in[0]=winx;
in[1]=winy;
in[2]=winz;
in[3]=1.0;
TransformArraysInOutByMatUnProj(in,in);
if (in[3] == 0.0) return;
*objx = in[0]/in[3];
*objy = in[1]/in[3];
*objz = in[2]/in[3];
}
void gumUnProjectI2(int winx, int winy, unsigned short winz,
float *objx, float *objy, float *objz)
{
float x,y,z;
fromScreen(winx,winy,winz,&x,&y,&z);
gumUnProjectF2(x,y,z,objx,objy,objz);
}
int main(int argc, char* argv[])
{
SetupCallbacks();
pspDebugScreenInit();
// setup GU
sceGuInit();
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_4444,(void*)0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)(FRAME_SIZE),BUF_WIDTH);
sceGuDepthBuffer((void*)(2*FRAME_SIZE),BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(65535,0);
// sceGuDepthRange(0xc350,0x2710);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CCW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuFinish();
sceGuSync(0,0);
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumPerspective(60.0f,16.0f/9.0f,0.5f,1000.0f);
sceGumStoreMatrix(&projMatrix);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
// run sample
int val = 0;
unsigned short *buf = (void *)VRAM_OFFSET(0);
for(;;)
{
float move = sinf(((float)val / 180.0f) * GU_PI);
if(move < 0) {
move *= -1;
}
move += 1;
float rot = ((float)val / 180.0f) * GU_PI;
sceGuStart(GU_DIRECT,list);
sceGuDepthBuffer((void*)(2*FRAME_SIZE),BUF_WIDTH);
sceGuFrontFace(GU_CW);
sceGuPixelMask(0xFFFFFFFF);
sceGuClearDepth(0);
sceGuClear(GU_DEPTH_BUFFER_BIT);
sceGumMatrixMode(GU_VIEW);
float eye1[3]={0.0f,6.0f,4.0f};
float center1[3]={0,0,0};
float up1[3]={0,1,0};
sceGumLoadIdentity();
sceGumLookAt(eye1,center1,up1);
sceGumStoreMatrix(&viewMatrixLight);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
// draw normal view
sceGuDisable(GU_TEXTURE_2D);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, border);
{
ScePspFVector3 pos = {0,move,0};
ScePspFVector3 rvec = {0,rot * -0.83f, 0};
sceGumTranslate(&pos);
sceGumRotateXYZ(&rvec);
}
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj);
sceGuFinish();
gumMultMatrix(&projFinal, &projMatrix, &viewMatrixLight);
sceGuSync(0,0);
sceGuStart(GU_DIRECT,list);
sceGuDepthBuffer((void*)(2*FRAME_SIZE+ZBUF_SIZE),BUF_WIDTH);
sceGuFrontFace(GU_CCW);
sceGuPixelMask(0);
// clear screen
sceGuClearColor(0xff554433);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
// setup matrices for cube
sceGumMatrixMode(GU_VIEW);
float eye2[3]={0.0f,3.0f,5.0f};
float center2[3]={0,0,0};
float up2[3]={0,1,0};
sceGumLoadIdentity();
sceGumLookAt(eye2,center2,up2);
sceGumStoreMatrix(&viewMatrixCam);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
// draw normal view
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_4444,0,0,0);
sceGuTexImage(0,64,64,64,logo_start);
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR,GU_LINEAR);
sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror);
sceGuDisable(GU_BLEND);
sceGuDisable(GU_TEXTURE_2D);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, border);
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_4444,0,0,0);
sceGuTexImage(0,64,64,64,logo_start);
sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB);
sceGuTexFilter(GU_LINEAR,GU_LINEAR);
sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f);
{
ScePspFVector3 pos = {0,move,0};
ScePspFVector3 rvec = {0,rot * -0.83f, 0};
sceGumTranslate(&pos);
sceGumRotateXYZ(&rvec);
}
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj);
sceGuDisable(GU_TEXTURE_2D);
sceGuFinish();
gumMultMatrix(&unprojFinal, &projMatrix, &viewMatrixCam);
gumFullInverse(&unprojFinal,&unprojFinal);
sceGuSync(0,0);
int i,j;
unsigned short *zbufptr = (void *)VRAM_OFFSET(ZBUFFER_LINEAR16BPP(2*FRAME_SIZE));
unsigned short *zbuf = (void *)VRAM_OFFSET(ZBUFFER_LINEAR16BPP(2*FRAME_SIZE+ZBUF_SIZE));
unsigned short *bufptr = buf;
setUnProjMatrix(&unprojFinal);
setProjMatrix(&projFinal);
#define HALF
#ifdef HALF
for(i=0;i<272;i+=2)
#else
for(i=0;i<272;i++)
#endif
{
#ifdef HALF
for(j=0;j<480;j+=2)
#else
for(j=0;j<480;j++)
#endif
{
float fx,fy,fz;
int x,y,z;
if(zbuf[j]==0) continue;
gumUnProjectI2(j,i,zbuf[j],&fx,&fy,&fz);
gumProjectI2(fx,fy,fz,&x,&y,&z);
int shadow=1;
if((x<0)||(x>479)||(y<0)||(y>271)) shadow=0;
if(z>zbufptr[y*512+x]) shadow=0;
if(shadow)
{
bufptr[j]=(bufptr[j]&0xeeee)>>1;
#ifdef HALF
bufptr[j+1]=(bufptr[j+1]&0xeeee)>>1;
bufptr[j+512]=(bufptr[j+512]&0xeeee)>>1;
bufptr[j+512+1]=(bufptr[j+512+1]&0xeeee)>>1;
#endif
}
}
#ifdef HALF
zbuf+=512*2;
bufptr+=512*2;
#else
zbuf+=512;
bufptr+=512;
#endif
}
sceDisplayWaitVblankStart();
buf = (void *)VRAM_OFFSET(sceGuSwapBuffers());
val++;
}
sceGuTerm();
sceKernelExitGame();
return 0;
}
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
----------------------------------------------------------------------------
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <pspgu.h>
#include <pspgum.h>
#include <pspvfpu.h>
PSP_MODULE_INFO("ShadowMap Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
static unsigned int __attribute__((aligned(16))) list[262144];
extern unsigned char logo_start[];
struct Vertex
{
float u, v;
unsigned int color;
float x,y,z;
};
struct Vertex __attribute__((aligned(16))) obj[36] = {
{0, 0, 0xff6666ff,-1,-1, 1},
{1, 0, 0xff6666ff, 1,-1, 1},
{1, 1, 0xff6666ff, 1, 1, 1},
{0, 0, 0xff6666ff,-1,-1, 1},
{1, 1, 0xff6666ff, 1, 1, 1},
{0, 1, 0xff6666ff,-1, 1, 1},
{1, 1, 0xff66ff66, 1, 1, 1},
{0, 1, 0xff66ff66, 1,-1, 1},
{0, 0, 0xff66ff66, 1,-1,-1},
{1, 1, 0xff66ff66, 1, 1, 1},
{0, 0, 0xff66ff66, 1,-1,-1},
{1, 0, 0xff66ff66, 1, 1,-1},
{0, 1, 0xffff6666,-1, 1, 1},
{0, 0, 0xffff6666, 1, 1, 1},
{1, 0, 0xffff6666, 1, 1,-1},
{0, 1, 0xffff6666,-1, 1, 1},
{1, 0, 0xffff6666, 1, 1,-1},
{1, 1, 0xffff6666,-1, 1,-1},
{1, 1, 0xff6666ff, 1.0f,-1.0f,-1.0f},
{0, 1, 0xff6666ff,-1.0f,-1.0f,-1.0f},
{0, 0, 0xff6666ff,-1.0f, 1.0f,-1.0f},
{1, 1, 0xff6666ff, 1.0f,-1.0f,-1.0f},
{0, 0, 0xff6666ff,-1.0f, 1.0f,-1.0f},
{1, 0, 0xff6666ff, 1.0f, 1.0f,-1.0f},
{1, 0, 0xff66ff66,-1,-1,-1},
{1, 1, 0xff66ff66,-1,-1, 1},
{0, 1, 0xff66ff66,-1, 1, 1},
{1, 0, 0xff66ff66,-1,-1,-1},
{0, 1, 0xff66ff66,-1, 1, 1},
{0, 0, 0xff66ff66,-1, 1,-1},
{0, 1, 0xffff6666,-1,-1,-1},
{0, 0, 0xffff6666, 1,-1,-1},
{1, 0, 0xffff6666, 1,-1, 1},
{0, 1, 0xffff6666,-1,-1,-1},
{1, 0, 0xffff6666, 1,-1, 1},
{1, 1, 0xffff6666,-1,-1, 1},
};
struct Vertex __attribute__((aligned(16))) mirror[6] = {
{0, 0, 0xaa000000, -2.0f, 0, -2.0f},
{2, 2, 0xaa000000, 2.0f, 0, 2.0f},
{2, 0, 0xaa000000, 2.0f, 0, -2.0f},
{0, 0, 0xaa000000, -2.0f, 0, -2.0f},
{0, 2, 0xaa000000, -2.0f, 0, 2.0f},
{2, 2, 0xaa000000, 2.0f, 0, 2.0f}
};
struct Vertex __attribute__((aligned(16))) border[6] = {
{0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f},
{2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f},
{2, 0, 0xff0055aa, 2.125f, -0.01, -2.125f},
{0, 0, 0xff0055aa, -2.125f, -0.01, -2.125f},
{0, 2, 0xff0055aa, -2.125f, -0.01, 2.125f},
{2, 2, 0xff0055aa, 2.125f, -0.01, 2.125f}
};
int SetupCallbacks();
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (2) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH * SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
#define ZBUFFER_LINEAR(x) (0x600000 + x)
#define ZBUFFER_UNSWIZ(x) (0x200000 + x)
#define VRAM_OFFSET(x) (0x4000000 + x)
#define ZBUFFER_LINEAR16BPP ZBUFFER_UNSWIZ
ScePspFMatrix4 projMatrix, viewMatrixCam, viewMatrixLight;
ScePspFMatrix4 projFinal, unprojFinal;
void setUnProjMatrix(const float *mat)
{
__asm__ volatile (
"ulv.q C000, 0x0 (%0)\n"
"ulv.q C010, 0x10(%0)\n"
"ulv.q C020, 0x20(%0)\n"
"ulv.q C030, 0x30(%0)\n"
: :"r" (mat) );
}
void setProjMatrix(const float *mat)
{
__asm__ volatile (
"ulv.q C100, 0x0 (%0)\n"
"ulv.q C110, 0x10(%0)\n"
"ulv.q C120, 0x20(%0)\n"
"ulv.q C130, 0x30(%0)\n"
: :"r" (mat) );
}
float output[4] __attribute__((aligned(VFPU_ALIGNMENT)));
void TransformArraysInOutByMatUnProj(const float *vec, float *out)
{
__asm__ volatile (
"ulv.q R200, 0x0(%1)\n"
"vone.s S230\n"
"vtfm4.q R300, E000, R200\n"
"sv.q R300, 0x0(%0)\n"
: : "r"(output) , "r" (vec) );
out[0]=output[0];
out[1]=output[1];
out[2]=output[2];
out[3]=output[3];
}
void TransformArraysInOutByMatProj(const float *vec, float *out)
{
__asm__ volatile (
"ulv.q R200, 0x0(%1)\n"
"vone.s S230\n"
"vtfm4.q R300, E100, R200\n"
"sv.q R300, 0x0(%0)\n"
: : "r"(output) , "r" (vec) );
out[0]=output[0];
out[1]=output[1];
out[2]=output[2];
out[3]=output[3];
}
void toScreen(float nx, float ny, float nz,
int *sx, int *sy, int *sz)
{
*sx = ((nx+1.0f)/2.0f) * 480.0f;
*sy = (1.0f - ((ny+1.0f)/2.0f)) * 272.0f;
*sz = (1.0f-nz)*32768;
}
void fromScreen(int sx, int sy, int sz,
float *nx, float *ny, float *nz)
{
*nx = sx*(2.0f/480.0f)-1.0f;
*ny = 1.0f-sy*(2.0f/272.0f);
*nz = 1.0f-sz/32768.0f;
}
ScePspFMatrix4 finalMatrix;
void gumProjectF2(float objx, float objy, float objz,
float *winx, float *winy, float *winz)
{
float in[4];
in[0]=objx;
in[1]=objy;
in[2]=objz;
in[3]=1.0;
TransformArraysInOutByMatProj(in,in);
if (in[3] == 0.0) return;
*winx = in[0]/in[3];
*winy = in[1]/in[3];
*winz = in[2]/in[3];
}
void gumProjectI2(float objx, float objy, float objz,
int *winx, int *winy, int *winz)
{
float fwx,fwy,fwz;
gumProjectF2(objx,objy,objz,&fwx,&fwy,&fwz);
toScreen(fwx,fwy,fwz,winx,winy,winz);
}
void gumUnProjectF2(float winx, float winy, float winz,
float *objx, float *objy, float *objz)
{
float in[4];
in[0]=winx;
in[1]=winy;
in[2]=winz;
in[3]=1.0;
TransformArraysInOutByMatUnProj(in,in);
if (in[3] == 0.0) return;
*objx = in[0]/in[3];
*objy = in[1]/in[3];
*objz = in[2]/in[3];
}
void gumUnProjectI2(int winx, int winy, unsigned short winz,
float *objx, float *objy, float *objz)
{
float x,y,z;
fromScreen(winx,winy,winz,&x,&y,&z);
gumUnProjectF2(x,y,z,objx,objy,objz);
}
int main(int argc, char* argv[])
{
SetupCallbacks();
pspDebugScreenInit();
// setup GU
sceGuInit();
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_4444,(void*)0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)(FRAME_SIZE),BUF_WIDTH);
sceGuDepthBuffer((void*)(2*FRAME_SIZE),BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(65535,0);
// sceGuDepthRange(0xc350,0x2710);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CCW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuFinish();
sceGuSync(0,0);
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumPerspective(60.0f,16.0f/9.0f,0.5f,1000.0f);
sceGumStoreMatrix(&projMatrix);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
// run sample
int val = 0;
unsigned short *buf = (void *)VRAM_OFFSET(0);
for(;;)
{
float move = sinf(((float)val / 180.0f) * GU_PI);
if(move < 0) {
move *= -1;
}
move += 1;
float rot = ((float)val / 180.0f) * GU_PI;
sceGuStart(GU_DIRECT,list);
sceGuDepthBuffer((void*)(2*FRAME_SIZE),BUF_WIDTH);
sceGuFrontFace(GU_CW);
sceGuPixelMask(0xFFFFFFFF);
sceGuClearDepth(0);
sceGuClear(GU_DEPTH_BUFFER_BIT);
sceGumMatrixMode(GU_VIEW);
float eye1[3]={0.0f,6.0f,4.0f};
float center1[3]={0,0,0};
float up1[3]={0,1,0};
sceGumLoadIdentity();
sceGumLookAt(eye1,center1,up1);
sceGumStoreMatrix(&viewMatrixLight);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
// draw normal view
sceGuDisable(GU_TEXTURE_2D);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, border);
{
ScePspFVector3 pos = {0,move,0};
ScePspFVector3 rvec = {0,rot * -0.83f, 0};
sceGumTranslate(&pos);
sceGumRotateXYZ(&rvec);
}
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj);
sceGuFinish();
gumMultMatrix(&projFinal, &projMatrix, &viewMatrixLight);
sceGuSync(0,0);
sceGuStart(GU_DIRECT,list);
sceGuDepthBuffer((void*)(2*FRAME_SIZE+ZBUF_SIZE),BUF_WIDTH);
sceGuFrontFace(GU_CCW);
sceGuPixelMask(0);
// clear screen
sceGuClearColor(0xff554433);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
// setup matrices for cube
sceGumMatrixMode(GU_VIEW);
float eye2[3]={0.0f,3.0f,5.0f};
float center2[3]={0,0,0};
float up2[3]={0,1,0};
sceGumLoadIdentity();
sceGumLookAt(eye2,center2,up2);
sceGumStoreMatrix(&viewMatrixCam);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
// draw normal view
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_4444,0,0,0);
sceGuTexImage(0,64,64,64,logo_start);
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR,GU_LINEAR);
sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, mirror);
sceGuDisable(GU_BLEND);
sceGuDisable(GU_TEXTURE_2D);
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 6, 0, border);
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_4444,0,0,0);
sceGuTexImage(0,64,64,64,logo_start);
sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB);
sceGuTexFilter(GU_LINEAR,GU_LINEAR);
sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f);
{
ScePspFVector3 pos = {0,move,0};
ScePspFVector3 rvec = {0,rot * -0.83f, 0};
sceGumTranslate(&pos);
sceGumRotateXYZ(&rvec);
}
sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 36, 0, obj);
sceGuDisable(GU_TEXTURE_2D);
sceGuFinish();
gumMultMatrix(&unprojFinal, &projMatrix, &viewMatrixCam);
gumFullInverse(&unprojFinal,&unprojFinal);
sceGuSync(0,0);
int i,j;
unsigned short *zbufptr = (void *)VRAM_OFFSET(ZBUFFER_LINEAR16BPP(2*FRAME_SIZE));
unsigned short *zbuf = (void *)VRAM_OFFSET(ZBUFFER_LINEAR16BPP(2*FRAME_SIZE+ZBUF_SIZE));
unsigned short *bufptr = buf;
setUnProjMatrix(&unprojFinal);
setProjMatrix(&projFinal);
#define HALF
#ifdef HALF
for(i=0;i<272;i+=2)
#else
for(i=0;i<272;i++)
#endif
{
#ifdef HALF
for(j=0;j<480;j+=2)
#else
for(j=0;j<480;j++)
#endif
{
float fx,fy,fz;
int x,y,z;
if(zbuf[j]==0) continue;
gumUnProjectI2(j,i,zbuf[j],&fx,&fy,&fz);
gumProjectI2(fx,fy,fz,&x,&y,&z);
int shadow=1;
if((x<0)||(x>479)||(y<0)||(y>271)) shadow=0;
if(z>zbufptr[y*512+x]) shadow=0;
if(shadow)
{
bufptr[j]=(bufptr[j]&0xeeee)>>1;
#ifdef HALF
bufptr[j+1]=(bufptr[j+1]&0xeeee)>>1;
bufptr[j+512]=(bufptr[j+512]&0xeeee)>>1;
bufptr[j+512+1]=(bufptr[j+512+1]&0xeeee)>>1;
#endif
}
}
#ifdef HALF
zbuf+=512*2;
bufptr+=512*2;
#else
zbuf+=512;
bufptr+=512;
#endif
}
sceDisplayWaitVblankStart();
buf = (void *)VRAM_OFFSET(sceGuSwapBuffers());
val++;
}
sceGuTerm();
sceKernelExitGame();
return 0;
}
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
In all honesty most scenes can just have baked shadows, then you can just do real time/dynamic shadows on a few select objects that move, saving performance.
Code: Select all
.øOº'ºOø.
'ºOo.oOº'
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
Either that, or if your objects are not tesselated enough to give good enough results, it comes down to lightmapping. In this case, yes, you need seperate (light) texture for each object, but those are relatively low-res, though require a two-pass texturing scheme.
What you thought of was a one-pass scheme, where you'd have to combine the lightmaps into the object textures as a pre-process step. That could waste a lot of memory though for duplicate textures with slightly different lighting, yes.
What you thought of was a one-pass scheme, where you'd have to combine the lightmaps into the object textures as a pre-process step. That could waste a lot of memory though for duplicate textures with slightly different lighting, yes.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
-
- Posts: 11
- Joined: Wed Apr 23, 2008 11:44 am
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
Hi,
sure. I'm interested in, as in my current code I've currently no real clue how to deal with the following issues (may be you have solved them).
Rendering the shadow caster from light point of view results in strange block shadows if the object is far away from light source (due to the resolution of the rendering i guess)
Secondly the usage of texture matrix for rendering of shadow reciever results in shadows applied to an object which is closer to the light than the shadow caster.
Thanks regards
AnMaBaGiMa
sure. I'm interested in, as in my current code I've currently no real clue how to deal with the following issues (may be you have solved them).
Rendering the shadow caster from light point of view results in strange block shadows if the object is far away from light source (due to the resolution of the rendering i guess)
Secondly the usage of texture matrix for rendering of shadow reciever results in shadows applied to an object which is closer to the light than the shadow caster.
Thanks regards
AnMaBaGiMa
-
- Posts: 11
- Joined: Wed Apr 23, 2008 11:44 am
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
Hi,
yes I'm using the SDK samples with some minor adjustments ;)
I've read the article on shadow mapping posted at the beginning of this thread. This is using a multi pass approach which looked very similar to the one implemented in the SDK example. But as I'm a beginner in using GU and all the matrix stuff may be I didn't get the full picture out of this page. The openGL stuff mentioned there as sample code is completely new to me as I've used Direct3D in the past on PC for 3D rendering.
Thanks for any hints as I'm interested more into a "how do I" and I want to understand what I'm doing rather then just copy/paste other once code ;)
Best regards
yes I'm using the SDK samples with some minor adjustments ;)
I've read the article on shadow mapping posted at the beginning of this thread. This is using a multi pass approach which looked very similar to the one implemented in the SDK example. But as I'm a beginner in using GU and all the matrix stuff may be I didn't get the full picture out of this page. The openGL stuff mentioned there as sample code is completely new to me as I've used Direct3D in the past on PC for 3D rendering.
Thanks for any hints as I'm interested more into a "how do I" and I want to understand what I'm doing rather then just copy/paste other once code ;)
Best regards