mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-21 20:35:17 +02:00
#15 PSV water effects support; split water and compose shaders by type;
This commit is contained in:
12
src/cache.h
12
src/cache.h
@@ -830,6 +830,7 @@ struct WaterCache {
|
|||||||
Core::setColorWrite(false, false, false, true);
|
Core::setColorWrite(false, false, false, true);
|
||||||
Core::setDepthWrite(false);
|
Core::setDepthWrite(false);
|
||||||
Core::setCullMode(cmNone);
|
Core::setCullMode(cmNone);
|
||||||
|
Core::setBlendMode(bmNone);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Item &item = items[i];
|
Item &item = items[i];
|
||||||
@@ -894,7 +895,7 @@ struct WaterCache {
|
|||||||
Core::noiseTex->bind(sDiffuse);
|
Core::noiseTex->bind(sDiffuse);
|
||||||
item.mask->bind(sMask);
|
item.mask->bind(sMask);
|
||||||
// add water drops
|
// add water drops
|
||||||
drop(item);
|
drop(item);
|
||||||
// simulation step
|
// simulation step
|
||||||
step(item);
|
step(item);
|
||||||
}
|
}
|
||||||
@@ -1037,16 +1038,17 @@ struct WaterCache {
|
|||||||
vertices[1].light =
|
vertices[1].light =
|
||||||
vertices[2].light =
|
vertices[2].light =
|
||||||
vertices[3].light = ubyte4(255, 255, 255, 255);
|
vertices[3].light = ubyte4(255, 255, 255, 255);
|
||||||
vertices[0].texCoord = short4( 0, 32767, 0, 0);
|
|
||||||
vertices[1].texCoord = short4(32767, 32767, 0, 0);
|
|
||||||
vertices[2].texCoord = short4(32767, 0, 0, 0);
|
|
||||||
vertices[3].texCoord = short4( 0, 0, 0, 0);
|
|
||||||
|
|
||||||
#if defined(_GAPI_D3D9) || defined(_GAPI_GXM)
|
#if defined(_GAPI_D3D9) || defined(_GAPI_GXM)
|
||||||
vertices[0].texCoord = short4( 0, 0, 0, 0);
|
vertices[0].texCoord = short4( 0, 0, 0, 0);
|
||||||
vertices[1].texCoord = short4(32767, 0, 0, 0);
|
vertices[1].texCoord = short4(32767, 0, 0, 0);
|
||||||
vertices[2].texCoord = short4(32767, 32767, 0, 0);
|
vertices[2].texCoord = short4(32767, 32767, 0, 0);
|
||||||
vertices[3].texCoord = short4( 0, 32767, 0, 0);
|
vertices[3].texCoord = short4( 0, 32767, 0, 0);
|
||||||
|
#else
|
||||||
|
vertices[0].texCoord = short4( 0, 32767, 0, 0);
|
||||||
|
vertices[1].texCoord = short4(32767, 32767, 0, 0);
|
||||||
|
vertices[2].texCoord = short4(32767, 0, 0, 0);
|
||||||
|
vertices[3].texCoord = short4( 0, 0, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Core::setDepthTest(false);
|
Core::setDepthTest(false);
|
||||||
|
37
src/core.h
37
src/core.h
@@ -116,43 +116,6 @@ extern void osJoyVibrate (int index, float L, float R);
|
|||||||
|
|
||||||
#define OS_LOCK(mutex) Core::Lock _lock(mutex)
|
#define OS_LOCK(mutex) Core::Lock _lock(mutex)
|
||||||
|
|
||||||
/*
|
|
||||||
extern void* osRWLockInit ();
|
|
||||||
extern void osRWLockFree (void *obj);
|
|
||||||
extern void osRWLockRead (void *obj);
|
|
||||||
extern void osRWUnlockRead (void *obj);
|
|
||||||
extern void osRWLockWrite (void *obj);
|
|
||||||
extern void osRWUnlockWrite (void *obj);
|
|
||||||
|
|
||||||
struct RWLock {
|
|
||||||
void *obj;
|
|
||||||
|
|
||||||
RWLock() { obj = osRWLockInit(); }
|
|
||||||
~RWLock() { osRWLockFree(obj); }
|
|
||||||
void lockRead() { osRWLockRead(obj); }
|
|
||||||
void unlockRead() { osRWUnlockRead(obj); }
|
|
||||||
void lockWrite() { osRWLockWrite(obj); }
|
|
||||||
void unlockWrite() { osRWUnlockWrite(obj); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LockRead {
|
|
||||||
RWLock &lock;
|
|
||||||
|
|
||||||
LockRead(RWLock &lock) : lock(lock) { lock.lockRead(); }
|
|
||||||
~LockRead() { lock.unlockRead(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LockWrite {
|
|
||||||
RWLock &lock;
|
|
||||||
|
|
||||||
LockWrite(RWLock &lock) : lock(lock) { lock.lockWrite(); }
|
|
||||||
~LockWrite() { lock.unlockWrite(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OS_LOCK_READ(rwLock) LockRead _rLock(rwLock)
|
|
||||||
#define OS_LOCK_WRITE(rwLock) LockWrite _wLock(rwLock)
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum InputKey { ikNone,
|
enum InputKey { ikNone,
|
||||||
// keyboard
|
// keyboard
|
||||||
ikLeft, ikRight, ikUp, ikDown, ikSpace, ikTab, ikEnter, ikEscape, ikShift, ikCtrl, ikAlt,
|
ikLeft, ikRight, ikUp, ikDown, ikSpace, ikTab, ikEnter, ikEscape, ikShift, ikCtrl, ikAlt,
|
||||||
|
@@ -50,14 +50,32 @@ void D3DCHECK(HRESULT res) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace GAPI {
|
namespace GAPI {
|
||||||
#include "shaders/d3d9/compose_vs.h"
|
#include "shaders/d3d9/compose_sprite_vs.h"
|
||||||
#include "shaders/d3d9/compose_ps.h"
|
#include "shaders/d3d9/compose_sprite_ps.h"
|
||||||
|
#include "shaders/d3d9/compose_flash_vs.h"
|
||||||
|
#include "shaders/d3d9/compose_flash_ps.h"
|
||||||
|
#include "shaders/d3d9/compose_room_vs.h"
|
||||||
|
#include "shaders/d3d9/compose_room_ps.h"
|
||||||
|
#include "shaders/d3d9/compose_entity_vs.h"
|
||||||
|
#include "shaders/d3d9/compose_entity_ps.h"
|
||||||
|
#include "shaders/d3d9/compose_mirror_vs.h"
|
||||||
|
#include "shaders/d3d9/compose_mirror_ps.h"
|
||||||
#include "shaders/d3d9/shadow_vs.h"
|
#include "shaders/d3d9/shadow_vs.h"
|
||||||
#include "shaders/d3d9/shadow_ps.h"
|
#include "shaders/d3d9/shadow_ps.h"
|
||||||
#include "shaders/d3d9/ambient_vs.h"
|
#include "shaders/d3d9/ambient_vs.h"
|
||||||
#include "shaders/d3d9/ambient_ps.h"
|
#include "shaders/d3d9/ambient_ps.h"
|
||||||
#include "shaders/d3d9/water_vs.h"
|
#include "shaders/d3d9/water_drop_vs.h"
|
||||||
#include "shaders/d3d9/water_ps.h"
|
#include "shaders/d3d9/water_drop_ps.h"
|
||||||
|
#include "shaders/d3d9/water_simulate_vs.h"
|
||||||
|
#include "shaders/d3d9/water_simulate_ps.h"
|
||||||
|
#include "shaders/d3d9/water_caustics_vs.h"
|
||||||
|
#include "shaders/d3d9/water_caustics_ps.h"
|
||||||
|
#include "shaders/d3d9/water_rays_vs.h"
|
||||||
|
#include "shaders/d3d9/water_rays_ps.h"
|
||||||
|
#include "shaders/d3d9/water_mask_vs.h"
|
||||||
|
#include "shaders/d3d9/water_mask_ps.h"
|
||||||
|
#include "shaders/d3d9/water_compose_vs.h"
|
||||||
|
#include "shaders/d3d9/water_compose_ps.h"
|
||||||
#include "shaders/d3d9/filter_vs.h"
|
#include "shaders/d3d9/filter_vs.h"
|
||||||
#include "shaders/d3d9/filter_ps.h"
|
#include "shaders/d3d9/filter_ps.h"
|
||||||
#include "shaders/d3d9/gui_vs.h"
|
#include "shaders/d3d9/gui_vs.h"
|
||||||
@@ -141,10 +159,29 @@ namespace GAPI {
|
|||||||
void init(Core::Pass pass, int type, int *def, int defCount) {
|
void init(Core::Pass pass, int type, int *def, int defCount) {
|
||||||
const BYTE *vSrc, *pSrc;
|
const BYTE *vSrc, *pSrc;
|
||||||
switch (pass) {
|
switch (pass) {
|
||||||
case Core::passCompose : vSrc = COMPOSE_VS; pSrc = COMPOSE_PS; break;
|
case Core::passCompose :
|
||||||
|
switch (type) {
|
||||||
|
case 0 : vSrc = COMPOSE_SPRITE_VS; pSrc = COMPOSE_SPRITE_PS; break;
|
||||||
|
case 1 : vSrc = COMPOSE_FLASH_VS; pSrc = COMPOSE_FLASH_PS; break;
|
||||||
|
case 2 : vSrc = COMPOSE_ROOM_VS; pSrc = COMPOSE_ROOM_PS; break;
|
||||||
|
case 3 : vSrc = COMPOSE_ENTITY_VS; pSrc = COMPOSE_ENTITY_PS; break;
|
||||||
|
case 4 : vSrc = COMPOSE_MIRROR_VS; pSrc = COMPOSE_MIRROR_PS; break;
|
||||||
|
default : ASSERT(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Core::passShadow : vSrc = SHADOW_VS; pSrc = SHADOW_PS; break;
|
case Core::passShadow : vSrc = SHADOW_VS; pSrc = SHADOW_PS; break;
|
||||||
case Core::passAmbient : vSrc = AMBIENT_VS; pSrc = AMBIENT_PS; break;
|
case Core::passAmbient : vSrc = AMBIENT_VS; pSrc = AMBIENT_PS; break;
|
||||||
case Core::passWater : vSrc = WATER_VS; pSrc = WATER_PS; break;
|
case Core::passWater :
|
||||||
|
switch (type) {
|
||||||
|
case 0 : vSrc = WATER_DROP_VS; pSrc = WATER_DROP_PS; break;
|
||||||
|
case 1 : vSrc = WATER_SIMULATE_VS; pSrc = WATER_SIMULATE_PS; break;
|
||||||
|
case 2 : vSrc = WATER_CAUSTICS_VS; pSrc = WATER_CAUSTICS_PS; break;
|
||||||
|
case 3 : vSrc = WATER_RAYS_VS; pSrc = WATER_RAYS_PS; break;
|
||||||
|
case 4 : vSrc = WATER_MASK_VS; pSrc = WATER_MASK_PS; break;
|
||||||
|
case 5 : vSrc = WATER_COMPOSE_VS; pSrc = WATER_COMPOSE_PS; break;
|
||||||
|
default : ASSERT(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Core::passFilter : vSrc = FILTER_VS; pSrc = FILTER_PS; break;
|
case Core::passFilter : vSrc = FILTER_VS; pSrc = FILTER_PS; break;
|
||||||
case Core::passGUI : vSrc = GUI_VS; pSrc = GUI_PS; break;
|
case Core::passGUI : vSrc = GUI_VS; pSrc = GUI_PS; break;
|
||||||
default : ASSERT(false); LOG("! wrong pass id\n"); return;
|
default : ASSERT(false); LOG("! wrong pass id\n"); return;
|
||||||
@@ -227,14 +264,14 @@ namespace GAPI {
|
|||||||
int bpp;
|
int bpp;
|
||||||
D3DFORMAT format;
|
D3DFORMAT format;
|
||||||
} formats[FMT_MAX] = {
|
} formats[FMT_MAX] = {
|
||||||
{ 8, D3DFMT_L8 },
|
{ 8, D3DFMT_L8 },
|
||||||
{ 32, D3DFMT_A8R8G8B8 },
|
{ 32, D3DFMT_A8R8G8B8 },
|
||||||
{ 16, D3DFMT_R5G6B5 },
|
{ 16, D3DFMT_R5G6B5 },
|
||||||
{ 16, D3DFMT_A1R5G5B5 },
|
{ 16, D3DFMT_A1R5G5B5 },
|
||||||
{ 128, D3DFMT_A32B32G32R32F },
|
{ 64, D3DFMT_G32R32F },
|
||||||
{ 64, D3DFMT_A16B16G16R16F },
|
{ 32, D3DFMT_G16R16F },
|
||||||
{ 16, D3DFMT_D16 },
|
{ 16, D3DFMT_D16 },
|
||||||
{ 16, D3DFMT_D24X8 },
|
{ 16, D3DFMT_D24X8 },
|
||||||
};
|
};
|
||||||
|
|
||||||
FormatDesc desc = formats[fmt];
|
FormatDesc desc = formats[fmt];
|
||||||
@@ -253,7 +290,18 @@ namespace GAPI {
|
|||||||
if (data && !isTarget) {
|
if (data && !isTarget) {
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
D3DCHECK(tex2D->LockRect(0, &rect, NULL, 0));
|
D3DCHECK(tex2D->LockRect(0, &rect, NULL, 0));
|
||||||
memcpy(rect.pBits, data, width * height * (desc.bpp / 8));
|
if (width != origWidth || height != origHeight) {
|
||||||
|
memset(rect.pBits, 0, width * height * (desc.bpp / 8));
|
||||||
|
uint8 *dst = (uint8*)rect.pBits;
|
||||||
|
uint8 *src = (uint8*)data;
|
||||||
|
for (int y = 0; y < origHeight; y++) {
|
||||||
|
memcpy(dst, src, origWidth * (desc.bpp / 8));
|
||||||
|
src += origWidth * (desc.bpp / 8);
|
||||||
|
dst += width * (desc.bpp / 8);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(rect.pBits, data, width * height * (desc.bpp / 8));
|
||||||
|
}
|
||||||
D3DCHECK(tex2D->UnlockRect(0));
|
D3DCHECK(tex2D->UnlockRect(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,7 @@ namespace GAPI {
|
|||||||
delete[] memory;
|
delete[] memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swizzle(uint8* out, const uint8* in, uint32 width, uint32 height) {
|
void swizzle(uint8 *out, const uint8 *in, uint32 width, uint32 height) {
|
||||||
int rowblocks = width / 16;
|
int rowblocks = width / 16;
|
||||||
|
|
||||||
for (int j = 0; j < height; j++)
|
for (int j = 0; j < height; j++)
|
||||||
|
357
src/gapi_gxm.h
357
src/gapi_gxm.h
@@ -11,8 +11,6 @@
|
|||||||
#define PROFILE_LABEL(id, name, label)
|
#define PROFILE_LABEL(id, name, label)
|
||||||
#define PROFILE_TIMING(time)
|
#define PROFILE_TIMING(time)
|
||||||
|
|
||||||
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
|
||||||
|
|
||||||
#define DISPLAY_WIDTH 960
|
#define DISPLAY_WIDTH 960
|
||||||
#define DISPLAY_HEIGHT 544
|
#define DISPLAY_HEIGHT 544
|
||||||
#define DISPLAY_STRIDE 1024
|
#define DISPLAY_STRIDE 1024
|
||||||
@@ -21,14 +19,32 @@
|
|||||||
#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
||||||
|
|
||||||
namespace GAPI {
|
namespace GAPI {
|
||||||
#include "shaders/gxm/compose_vp.h"
|
#include "shaders/gxm/compose_sprite_vp.h"
|
||||||
#include "shaders/gxm/compose_fp.h"
|
#include "shaders/gxm/compose_sprite_fp.h"
|
||||||
|
#include "shaders/gxm/compose_flash_vp.h"
|
||||||
|
#include "shaders/gxm/compose_flash_fp.h"
|
||||||
|
#include "shaders/gxm/compose_room_vp.h"
|
||||||
|
#include "shaders/gxm/compose_room_fp.h"
|
||||||
|
#include "shaders/gxm/compose_entity_vp.h"
|
||||||
|
#include "shaders/gxm/compose_entity_fp.h"
|
||||||
|
#include "shaders/gxm/compose_mirror_vp.h"
|
||||||
|
#include "shaders/gxm/compose_mirror_fp.h"
|
||||||
#include "shaders/gxm/shadow_vp.h"
|
#include "shaders/gxm/shadow_vp.h"
|
||||||
#include "shaders/gxm/shadow_fp.h"
|
#include "shaders/gxm/shadow_fp.h"
|
||||||
#include "shaders/gxm/ambient_vp.h"
|
#include "shaders/gxm/ambient_vp.h"
|
||||||
#include "shaders/gxm/ambient_fp.h"
|
#include "shaders/gxm/ambient_fp.h"
|
||||||
#include "shaders/gxm/water_vp.h"
|
#include "shaders/gxm/water_drop_vp.h"
|
||||||
#include "shaders/gxm/water_fp.h"
|
#include "shaders/gxm/water_drop_fp.h"
|
||||||
|
#include "shaders/gxm/water_simulate_vp.h"
|
||||||
|
#include "shaders/gxm/water_simulate_fp.h"
|
||||||
|
#include "shaders/gxm/water_caustics_vp.h"
|
||||||
|
#include "shaders/gxm/water_caustics_fp.h"
|
||||||
|
#include "shaders/gxm/water_rays_vp.h"
|
||||||
|
#include "shaders/gxm/water_rays_fp.h"
|
||||||
|
#include "shaders/gxm/water_mask_vp.h"
|
||||||
|
#include "shaders/gxm/water_mask_fp.h"
|
||||||
|
#include "shaders/gxm/water_compose_vp.h"
|
||||||
|
#include "shaders/gxm/water_compose_fp.h"
|
||||||
#include "shaders/gxm/filter_vp.h"
|
#include "shaders/gxm/filter_vp.h"
|
||||||
#include "shaders/gxm/filter_fp.h"
|
#include "shaders/gxm/filter_fp.h"
|
||||||
#include "shaders/gxm/gui_vp.h"
|
#include "shaders/gxm/gui_vp.h"
|
||||||
@@ -197,6 +213,23 @@ namespace GAPI {
|
|||||||
sceKernelFreeMemBlock(uid);
|
sceKernelFreeMemBlock(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 *SWIZZE_TABLE = NULL;
|
||||||
|
#define SWIZZLE(x, y) ((SWIZZE_TABLE[(x)] << 1) | (SWIZZE_TABLE[(y)]))
|
||||||
|
|
||||||
|
void initSwizzleTable() {
|
||||||
|
SWIZZE_TABLE = new uint32[4096];
|
||||||
|
uint32 value = 0;
|
||||||
|
for (int i = 0; i < 4096; i++) {
|
||||||
|
SWIZZE_TABLE[i] = value;
|
||||||
|
value += 0x2AAAAAAB;
|
||||||
|
value &= 0x55555555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeSwizzleTable() {
|
||||||
|
delete[] SWIZZE_TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
void *vdmRingBuffer = allocGPU(
|
void *vdmRingBuffer = allocGPU(
|
||||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
||||||
@@ -229,6 +262,8 @@ namespace GAPI {
|
|||||||
params.fragmentUsseRingBufferOffset = offset;
|
params.fragmentUsseRingBufferOffset = offset;
|
||||||
|
|
||||||
sceGxmCreateContext(¶ms, &gxmContext);
|
sceGxmCreateContext(¶ms, &gxmContext);
|
||||||
|
|
||||||
|
initSwizzleTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinit() {
|
void deinit() {
|
||||||
@@ -240,6 +275,7 @@ namespace GAPI {
|
|||||||
freeGPU(fragmentRingBufferUID);
|
freeGPU(fragmentRingBufferUID);
|
||||||
freeFragmentUSSE(fragmentUsseRingBufferUID);
|
freeFragmentUSSE(fragmentUsseRingBufferUID);
|
||||||
sceGxmDestroyContext(gxmContext);
|
sceGxmDestroyContext(gxmContext);
|
||||||
|
freeSwizzleTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkPendings() {
|
void checkPendings() {
|
||||||
@@ -251,6 +287,67 @@ namespace GAPI {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void swizzleTiles(T *dst, T *src, int width, int tilesX, int tilesY) {
|
||||||
|
int tileSize = width / tilesX;
|
||||||
|
int tileArea = SQR(tileSize);
|
||||||
|
|
||||||
|
for (int j = 0; j < tilesY; j++) {
|
||||||
|
for (int i = 0; i < tilesX; i++) {
|
||||||
|
T *tilePtr = dst + ((tileArea * tilesX) * j) + (tileArea * i);
|
||||||
|
|
||||||
|
for (int y = 0; y < tileSize; y++) {
|
||||||
|
T *ptr = src + (width * (tileSize * j)) + (tileSize * i) + width * y;
|
||||||
|
|
||||||
|
for (int x = 0; x < tileSize; x++)
|
||||||
|
*(tilePtr + SWIZZLE(x, y)) = *ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swizzleImage(void *dst, void *src, int width, int height, int bpp) {
|
||||||
|
ASSERT(SWIZZLE_TABLE);
|
||||||
|
|
||||||
|
int tilesX, tilesY;
|
||||||
|
|
||||||
|
if (width > height) {
|
||||||
|
tilesX = width / height;
|
||||||
|
tilesY = 1;
|
||||||
|
} else {
|
||||||
|
tilesX = 1;
|
||||||
|
tilesY = height / width;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bpp) {
|
||||||
|
case 8 : swizzleTiles( (uint8*) dst, (uint8*) src, width, tilesX, tilesY ); break;
|
||||||
|
case 16 : swizzleTiles( (uint16*) dst, (uint16*) src, width, tilesX, tilesY ); break;
|
||||||
|
case 32 : swizzleTiles( (uint32*) dst, (uint32*) src, width, tilesX, tilesY ); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TILE_SIZE 32
|
||||||
|
|
||||||
|
void tileImage(void *dst, void *src, int width, int height, int bpp) {
|
||||||
|
int tilesX = width / TILE_SIZE;
|
||||||
|
int tilesY = height / TILE_SIZE;
|
||||||
|
|
||||||
|
uint8 *tilePtr = (uint8*)dst;
|
||||||
|
for (int y = 0; y < tilesY; y++) {
|
||||||
|
for (int x = 0; x < tilesX; x++) {
|
||||||
|
uint8 *ptr = (uint8*)src + (width * y + x) * TILE_SIZE * bpp / 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < TILE_SIZE; i++) {
|
||||||
|
memcpy(tilePtr, ptr, TILE_SIZE * bpp / 8);
|
||||||
|
ptr += width * bpp / 8;
|
||||||
|
tilePtr += TILE_SIZE * bpp / 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TILE_SIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace SwapChain {
|
namespace SwapChain {
|
||||||
@@ -398,6 +495,8 @@ namespace GAPI {
|
|||||||
vec4 cbMem[98 + MAX_CONTACTS];
|
vec4 cbMem[98 + MAX_CONTACTS];
|
||||||
int cbCount[uMAX];
|
int cbCount[uMAX];
|
||||||
|
|
||||||
|
SceGxmOutputRegisterFormat outputFmt;
|
||||||
|
|
||||||
int colorMask, blendMode;
|
int colorMask, blendMode;
|
||||||
int psoIndex;
|
int psoIndex;
|
||||||
|
|
||||||
@@ -406,12 +505,33 @@ namespace GAPI {
|
|||||||
void init(Pass pass, int type, int *def, int defCount) {
|
void init(Pass pass, int type, int *def, int defCount) {
|
||||||
memset(pso, 0, sizeof(pso));
|
memset(pso, 0, sizeof(pso));
|
||||||
|
|
||||||
|
outputFmt = SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4;
|
||||||
|
|
||||||
const uint8 *vpSrc, *fpSrc;
|
const uint8 *vpSrc, *fpSrc;
|
||||||
switch (pass) {
|
switch (pass) {
|
||||||
case passCompose : vpSrc = COMPOSE_VP; fpSrc = COMPOSE_FP; break;
|
case passCompose :
|
||||||
|
switch (type) {
|
||||||
|
case 0 : vpSrc = COMPOSE_SPRITE_VP; fpSrc = COMPOSE_SPRITE_FP; break;
|
||||||
|
case 1 : vpSrc = COMPOSE_FLASH_VP; fpSrc = COMPOSE_FLASH_FP; break;
|
||||||
|
case 2 : vpSrc = COMPOSE_ROOM_VP; fpSrc = COMPOSE_ROOM_FP; break;
|
||||||
|
case 3 : vpSrc = COMPOSE_ENTITY_VP; fpSrc = COMPOSE_ENTITY_FP; break;
|
||||||
|
case 4 : vpSrc = COMPOSE_MIRROR_VP; fpSrc = COMPOSE_MIRROR_FP; break;
|
||||||
|
default : ASSERT(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case passShadow : vpSrc = SHADOW_VP; fpSrc = SHADOW_FP; break;
|
case passShadow : vpSrc = SHADOW_VP; fpSrc = SHADOW_FP; break;
|
||||||
case passAmbient : vpSrc = AMBIENT_VP; fpSrc = AMBIENT_FP; break;
|
case passAmbient : vpSrc = AMBIENT_VP; fpSrc = AMBIENT_FP; break;
|
||||||
case passWater : vpSrc = WATER_VP; fpSrc = WATER_FP; break;
|
case passWater :
|
||||||
|
switch (type) {
|
||||||
|
case 0 : vpSrc = WATER_DROP_VP; fpSrc = WATER_DROP_FP; outputFmt = SCE_GXM_OUTPUT_REGISTER_FORMAT_HALF2; break;
|
||||||
|
case 1 : vpSrc = WATER_SIMULATE_VP; fpSrc = WATER_SIMULATE_FP; outputFmt = SCE_GXM_OUTPUT_REGISTER_FORMAT_HALF2; break;
|
||||||
|
case 2 : vpSrc = WATER_CAUSTICS_VP; fpSrc = WATER_CAUSTICS_FP; break;
|
||||||
|
case 3 : vpSrc = WATER_RAYS_VP; fpSrc = WATER_RAYS_FP; break;
|
||||||
|
case 4 : vpSrc = WATER_MASK_VP; fpSrc = WATER_MASK_FP; break;
|
||||||
|
case 5 : vpSrc = WATER_COMPOSE_VP; fpSrc = WATER_COMPOSE_FP; break;
|
||||||
|
default : ASSERT(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case passFilter : vpSrc = FILTER_VP; fpSrc = FILTER_FP; break;
|
case passFilter : vpSrc = FILTER_VP; fpSrc = FILTER_FP; break;
|
||||||
case passGUI : vpSrc = GUI_VP; fpSrc = GUI_FP; break;
|
case passGUI : vpSrc = GUI_VP; fpSrc = GUI_FP; break;
|
||||||
case PASS_CLEAR : vpSrc = CLEAR_VP; fpSrc = CLEAR_FP; break;
|
case PASS_CLEAR : vpSrc = CLEAR_VP; fpSrc = CLEAR_FP; break;
|
||||||
@@ -502,39 +622,17 @@ namespace GAPI {
|
|||||||
this->colorMask = colorMask;
|
this->colorMask = colorMask;
|
||||||
this->blendMode = blendMode;
|
this->blendMode = blendMode;
|
||||||
|
|
||||||
SceGxmBlendInfo blendInfo;
|
|
||||||
blendInfo.colorMask = SceGxmColorMask(colorMask);
|
|
||||||
blendInfo.colorFunc = SCE_GXM_BLEND_FUNC_ADD;
|
|
||||||
blendInfo.alphaFunc = SCE_GXM_BLEND_FUNC_ADD;
|
|
||||||
blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
|
||||||
blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
|
||||||
|
|
||||||
psoIndex = 0;
|
psoIndex = 0;
|
||||||
switch (blendMode) {
|
switch (blendMode) {
|
||||||
case RS_BLEND_ALPHA :
|
case RS_BLEND_ALPHA : psoIndex = bmAlpha; break;
|
||||||
psoIndex = bmAlpha;
|
case RS_BLEND_ADD : psoIndex = bmAdd; break;
|
||||||
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA;
|
case RS_BLEND_MULT : psoIndex = bmMult; break;
|
||||||
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
case RS_BLEND_PREMULT : psoIndex = bmPremult; break;
|
||||||
break;
|
default : psoIndex = bmNone;
|
||||||
case RS_BLEND_ADD :
|
}
|
||||||
psoIndex = bmAdd;
|
|
||||||
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
if (outputFmt != SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4) {
|
||||||
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE;
|
psoIndex = 0;
|
||||||
break;
|
|
||||||
case RS_BLEND_MULT :
|
|
||||||
psoIndex = bmMult;
|
|
||||||
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR;
|
|
||||||
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
|
||||||
break;
|
|
||||||
case RS_BLEND_PREMULT :
|
|
||||||
psoIndex = bmPremult;
|
|
||||||
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
|
||||||
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
psoIndex = bmNone;
|
|
||||||
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
|
||||||
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorMask != SCE_GXM_COLOR_MASK_ALL) {
|
if (colorMask != SCE_GXM_COLOR_MASK_ALL) {
|
||||||
@@ -544,13 +642,45 @@ namespace GAPI {
|
|||||||
PSO &p = pso[psoIndex];
|
PSO &p = pso[psoIndex];
|
||||||
|
|
||||||
if (!p.fp) {
|
if (!p.fp) {
|
||||||
sceGxmShaderPatcherRegisterProgram(shaderPatcher, fpPtr, &p.fpUID);
|
SceGxmBlendInfo blendInfo;
|
||||||
sceGxmShaderPatcherCreateFragmentProgram(shaderPatcher, p.fpUID, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, &blendInfo, vpPtr, &p.fp);
|
blendInfo.colorMask = SceGxmColorMask(colorMask);
|
||||||
|
blendInfo.colorFunc = SCE_GXM_BLEND_FUNC_ADD;
|
||||||
|
blendInfo.alphaFunc = SCE_GXM_BLEND_FUNC_ADD;
|
||||||
|
blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
||||||
|
blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
||||||
|
|
||||||
|
switch (blendMode) {
|
||||||
|
case RS_BLEND_ALPHA :
|
||||||
|
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA;
|
||||||
|
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
break;
|
||||||
|
case RS_BLEND_ADD :
|
||||||
|
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
||||||
|
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE;
|
||||||
|
break;
|
||||||
|
case RS_BLEND_MULT :
|
||||||
|
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR;
|
||||||
|
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
||||||
|
break;
|
||||||
|
case RS_BLEND_PREMULT :
|
||||||
|
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
||||||
|
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE;
|
||||||
|
blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO;
|
||||||
|
}
|
||||||
|
createFP(p, &blendInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
rebind = true;
|
rebind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createFP(PSO &p, SceGxmBlendInfo *blendInfo) {
|
||||||
|
sceGxmShaderPatcherRegisterProgram(shaderPatcher, fpPtr, &p.fpUID);
|
||||||
|
sceGxmShaderPatcherCreateFragmentProgram(shaderPatcher, p.fpUID, outputFmt, SCE_GXM_MULTISAMPLE_NONE, blendInfo, vpPtr, &p.fp);
|
||||||
|
}
|
||||||
|
|
||||||
void bind() {
|
void bind() {
|
||||||
if (active.shader != this) {
|
if (active.shader != this) {
|
||||||
active.shader = this;
|
active.shader = this;
|
||||||
@@ -602,80 +732,99 @@ namespace GAPI {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
|
static const struct FormatDesc {
|
||||||
|
uint32 bpp, textureFormat, targetFormat;
|
||||||
|
} formats[FMT_MAX] = {
|
||||||
|
{ 8, SCE_GXM_TEXTURE_FORMAT_U8_1RRR , SCE_GXM_COLOR_FORMAT_U8_R }, // LUMINANCE
|
||||||
|
{ 32, SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR , SCE_GXM_COLOR_FORMAT_A8B8G8R8 }, // RGBA
|
||||||
|
{ 16, SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR , SCE_GXM_COLOR_FORMAT_U5U6U5_BGR }, // RGB16
|
||||||
|
{ 16, SCE_GXM_TEXTURE_FORMAT_U1U5U5U5_ABGR , SCE_GXM_COLOR_FORMAT_U1U5U5U5_ABGR }, // RGBA16
|
||||||
|
{ 64, SCE_GXM_TEXTURE_FORMAT_F32F32_GR , SCE_GXM_COLOR_FORMAT_F32F32_GR }, // RG_FLOAT // not supported
|
||||||
|
{ 32, SCE_GXM_TEXTURE_FORMAT_F16F16_GR , SCE_GXM_COLOR_FORMAT_F16F16_GR }, // RG_HALF
|
||||||
|
{ 32, SCE_GXM_TEXTURE_FORMAT_F32M_R , SCE_GXM_DEPTH_STENCIL_FORMAT_DF32 }, // DEPTH
|
||||||
|
{ 32, SCE_GXM_TEXTURE_FORMAT_F32M_R , SCE_GXM_DEPTH_STENCIL_FORMAT_DF32 }, // SHADOW
|
||||||
|
};
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
SceGxmTexture ID;
|
SceGxmTexture ID;
|
||||||
void *data;
|
uint8 *data;
|
||||||
SceUID uid;
|
SceUID uid;
|
||||||
int size;
|
|
||||||
|
|
||||||
int width, height, origWidth, origHeight;
|
int width, height, origWidth, origHeight, aWidth, aHeight;
|
||||||
TexFormat fmt;
|
TexFormat fmt;
|
||||||
uint32 opt;
|
uint32 opt;
|
||||||
|
|
||||||
SceGxmColorSurface colorSurface;
|
SceGxmColorSurface colorSurface;
|
||||||
SceGxmRenderTarget *renderTarget;
|
SceGxmRenderTarget *renderTarget;
|
||||||
|
|
||||||
SceUID depthBufferUID;
|
SceUID depthBufferUID;
|
||||||
SceGxmDepthStencilSurface depthSurface;
|
SceGxmDepthStencilSurface depthSurface;
|
||||||
void *depthBufferData;
|
void *depthBufferData;
|
||||||
|
|
||||||
|
Texture(int width, int height, uint32 opt) : width(width), height(height), origWidth(width), origHeight(height), fmt(FMT_RGBA), opt(opt) { opt |= OPT_NEAREST; }
|
||||||
Texture(int width, int height, uint32 opt) : width(width), height(height), origWidth(width), origHeight(height), fmt(FMT_RGBA), opt(opt) {}
|
|
||||||
|
|
||||||
void init(void *data) {
|
void init(void *data) {
|
||||||
ASSERT((opt & OPT_PROXY) == 0);
|
ASSERT((opt & OPT_PROXY) == 0);
|
||||||
|
|
||||||
bool filter = (opt & OPT_NEAREST) == 0;
|
bool filter = (opt & OPT_NEAREST) == 0;
|
||||||
bool mipmaps = (opt & OPT_MIPMAPS) != 0;
|
bool mipmaps = (opt & OPT_MIPMAPS) != 0;
|
||||||
bool cube = (opt & OPT_CUBEMAP) != 0;
|
bool isCube = (opt & OPT_CUBEMAP) != 0;
|
||||||
bool isTarget = (opt & OPT_TARGET) != 0;
|
bool isTarget = (opt & OPT_TARGET) != 0;
|
||||||
bool isShadow = fmt == FMT_SHADOW;
|
bool isShadow = fmt == FMT_SHADOW;
|
||||||
|
bool isTiled = isTarget || fmt == FMT_DEPTH || fmt == FMT_SHADOW;
|
||||||
static const struct FormatDesc {
|
bool isSwizzled = false;//!isTiled;
|
||||||
uint32 bpp, textureFormat, targetFormat;
|
|
||||||
} formats[FMT_MAX] = {
|
|
||||||
{ 8, SCE_GXM_TEXTURE_FORMAT_U8_1RRR , SCE_GXM_COLOR_FORMAT_U8_R }, // LUMINANCE
|
|
||||||
{ 32, SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB , SCE_GXM_COLOR_FORMAT_A8R8G8B8 }, // RGBA
|
|
||||||
{ 16, SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB , SCE_GXM_COLOR_FORMAT_U5U6U5_RGB }, // RGB16
|
|
||||||
{ 16, SCE_GXM_TEXTURE_FORMAT_U1U5U5U5_ARGB , SCE_GXM_COLOR_FORMAT_U1U5U5U5_ARGB }, // RGBA16
|
|
||||||
{ 32, SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB , SCE_GXM_COLOR_FORMAT_A8R8G8B8 }, // RGBA
|
|
||||||
{ 32, SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB , SCE_GXM_COLOR_FORMAT_A8R8G8B8 }, // RGBA
|
|
||||||
// { 64, SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_ARGB , SCE_GXM_COLOR_FORMAT_F16F16F16F16_RGBA }, // RGBA_FLOAT // not supported
|
|
||||||
// { 64, SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_ARGB , SCE_GXM_COLOR_FORMAT_F16F16F16F16_RGBA }, // RGBA_HALF
|
|
||||||
{ 32, SCE_GXM_TEXTURE_FORMAT_F32M_R , SCE_GXM_DEPTH_STENCIL_FORMAT_DF32 }, // DEPTH
|
|
||||||
{ 32, SCE_GXM_TEXTURE_FORMAT_F32M_R , SCE_GXM_DEPTH_STENCIL_FORMAT_DF32 }, // SHADOW
|
|
||||||
};
|
|
||||||
|
|
||||||
FormatDesc desc = formats[fmt];
|
FormatDesc desc = formats[fmt];
|
||||||
|
|
||||||
if (data && !support.texNPOT && (width != origWidth || height != origHeight))
|
if (isSwizzled) {
|
||||||
data = NULL;
|
aWidth = width = nextPow2(width);
|
||||||
|
aHeight = height = nextPow2(height);
|
||||||
uint32 aWidth = width;
|
} else if (isTiled) {
|
||||||
uint32 aHeight = height;
|
aWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
|
||||||
|
aHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
|
||||||
if (fmt == FMT_DEPTH || fmt == FMT_SHADOW) {
|
} else {
|
||||||
aWidth = ALIGN(aWidth, SCE_GXM_TILE_SIZEX);
|
aWidth = ALIGN(width, 8);
|
||||||
aHeight = ALIGN(aHeight, SCE_GXM_TILE_SIZEY);
|
aHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = aWidth * aHeight * desc.bpp / 8 * (cube ? 6 : 1);
|
int size = aWidth * aHeight * desc.bpp / 8 * (isCube ? 6 : 1);
|
||||||
|
|
||||||
SceGxmMemoryAttribFlags flags = isTarget ? SCE_GXM_MEMORY_ATTRIB_RW : SCE_GXM_MEMORY_ATTRIB_READ;
|
SceGxmMemoryAttribFlags flags = isTarget ? SCE_GXM_MEMORY_ATTRIB_RW : SCE_GXM_MEMORY_ATTRIB_READ;
|
||||||
this->data = Context::allocGPU(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, size, flags, &uid);
|
this->data = (uint8*)Context::allocGPU(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, size, flags, &uid);
|
||||||
|
|
||||||
if (data && this->data) {
|
if (data && this->data) {
|
||||||
memcpy(this->data, data, size);
|
if (isSwizzled || isTiled) {
|
||||||
|
if (aWidth != origWidth || aHeight != origHeight) {
|
||||||
|
uint8 *tmp = new uint8[aWidth * aHeight * desc.bpp / 8];
|
||||||
|
swap(this->data, tmp);
|
||||||
|
updateData(data);
|
||||||
|
swap(this->data, tmp);
|
||||||
|
if (isSwizzled) {
|
||||||
|
Context::swizzleImage(this->data, tmp, aWidth, aHeight, desc.bpp);
|
||||||
|
} else {
|
||||||
|
Context::tileImage(this->data, tmp, aWidth, aHeight, desc.bpp);
|
||||||
|
}
|
||||||
|
delete[] tmp;
|
||||||
|
} else {
|
||||||
|
if (isSwizzled) {
|
||||||
|
Context::swizzleImage(this->data, data, aWidth, aHeight, desc.bpp);
|
||||||
|
} else {
|
||||||
|
Context::tileImage(this->data, data, aWidth, aHeight, desc.bpp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateData(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmt == FMT_DEPTH || fmt == FMT_SHADOW) {
|
if (isCube) {
|
||||||
sceGxmTextureInitTiled(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 1);
|
sceGxmTextureInitCube(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 0);
|
||||||
|
} else if (isSwizzled) {
|
||||||
|
sceGxmTextureInitSwizzled(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 0);
|
||||||
|
} else if (isTiled) {
|
||||||
|
sceGxmTextureInitTiled(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 0);
|
||||||
} else {
|
} else {
|
||||||
if (cube) {
|
sceGxmTextureInitLinear(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 0);
|
||||||
sceGxmTextureInitCube(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 1);
|
|
||||||
} else {
|
|
||||||
sceGxmTextureInitLinear(&ID, this->data, SceGxmTextureFormat(desc.textureFormat), width, height, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceGxmTextureAddrMode addrMode;
|
SceGxmTextureAddrMode addrMode;
|
||||||
@@ -684,6 +833,7 @@ namespace GAPI {
|
|||||||
} else {
|
} else {
|
||||||
addrMode = (isShadow && support.texBorder) ? SCE_GXM_TEXTURE_ADDR_CLAMP_FULL_BORDER : SCE_GXM_TEXTURE_ADDR_CLAMP;
|
addrMode = (isShadow && support.texBorder) ? SCE_GXM_TEXTURE_ADDR_CLAMP_FULL_BORDER : SCE_GXM_TEXTURE_ADDR_CLAMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
sceGxmTextureSetUAddrMode(&ID, addrMode);
|
sceGxmTextureSetUAddrMode(&ID, addrMode);
|
||||||
sceGxmTextureSetUAddrMode(&ID, addrMode);
|
sceGxmTextureSetUAddrMode(&ID, addrMode);
|
||||||
|
|
||||||
@@ -704,10 +854,10 @@ namespace GAPI {
|
|||||||
} else {
|
} else {
|
||||||
sceGxmColorSurfaceInit(&colorSurface,
|
sceGxmColorSurfaceInit(&colorSurface,
|
||||||
SceGxmColorFormat(desc.targetFormat),
|
SceGxmColorFormat(desc.targetFormat),
|
||||||
SCE_GXM_COLOR_SURFACE_LINEAR,
|
isSwizzled ? SCE_GXM_COLOR_SURFACE_SWIZZLED : (isTiled ? SCE_GXM_COLOR_SURFACE_TILED : SCE_GXM_COLOR_SURFACE_LINEAR),
|
||||||
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
|
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
|
||||||
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
|
desc.bpp > 32 ? SCE_GXM_OUTPUT_REGISTER_SIZE_64BIT : SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
|
||||||
width, height, width, this->data);
|
aWidth, aHeight, aWidth, this->data);
|
||||||
|
|
||||||
uint32 dsWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
|
uint32 dsWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
|
||||||
uint32 dsHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
|
uint32 dsHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
|
||||||
@@ -726,8 +876,8 @@ namespace GAPI {
|
|||||||
|
|
||||||
SceGxmRenderTargetParams params;
|
SceGxmRenderTargetParams params;
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.width = width;
|
params.width = aWidth;
|
||||||
params.height = height;
|
params.height = aHeight;
|
||||||
params.scenesPerFrame = 1;
|
params.scenesPerFrame = 1;
|
||||||
params.multisampleMode = SCE_GXM_MULTISAMPLE_NONE;
|
params.multisampleMode = SCE_GXM_MULTISAMPLE_NONE;
|
||||||
params.driverMemBlock = -1;
|
params.driverMemBlock = -1;
|
||||||
@@ -758,9 +908,26 @@ namespace GAPI {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateData(void *data) {
|
||||||
|
FormatDesc desc = formats[fmt];
|
||||||
|
|
||||||
|
if (aWidth != origWidth || aHeight != origHeight) {
|
||||||
|
uint8 *dst = (uint8*)this->data;
|
||||||
|
uint8 *src = (uint8*)data;
|
||||||
|
for (int y = 0; y < origHeight; y++) {
|
||||||
|
memcpy(dst, src, origWidth * desc.bpp / 8);
|
||||||
|
src += origWidth * desc.bpp / 8;
|
||||||
|
dst += aWidth * desc.bpp / 8;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(this->data, data, aWidth * aHeight * desc.bpp / 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void update(void *data) {
|
void update(void *data) {
|
||||||
if (!data) return;
|
if (data) {
|
||||||
memcpy(this->data, data, size);
|
updateData(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(int sampler) {
|
void bind(int sampler) {
|
||||||
|
@@ -80,8 +80,8 @@ void inputUpdate() {
|
|||||||
|
|
||||||
vec2 stickL = vec2(float(pad.lx), float(pad.ly)) / 128.0f - 1.0f;
|
vec2 stickL = vec2(float(pad.lx), float(pad.ly)) / 128.0f - 1.0f;
|
||||||
vec2 stickR = vec2(float(pad.rx), float(pad.ry)) / 128.0f - 1.0f;
|
vec2 stickR = vec2(float(pad.rx), float(pad.ry)) / 128.0f - 1.0f;
|
||||||
if (fabsf(stickL.x) < 0.2f && fabsf(stickL.y) < 0.2f) stickL = vec2(0.0f);
|
if (fabsf(stickL.x) < 0.3f && fabsf(stickL.y) < 0.3f) stickL = vec2(0.0f);
|
||||||
if (fabsf(stickR.x) < 0.2f && fabsf(stickR.y) < 0.2f) stickR = vec2(0.0f);
|
if (fabsf(stickR.x) < 0.3f && fabsf(stickR.y) < 0.3f) stickR = vec2(0.0f);
|
||||||
Input::setJoyPos(0, jkL, stickL);
|
Input::setJoyPos(0, jkL, stickL);
|
||||||
Input::setJoyPos(0, jkR, stickR);
|
Input::setJoyPos(0, jkR, stickR);
|
||||||
|
|
||||||
@@ -193,7 +193,8 @@ int main() {
|
|||||||
osTimerFreq = sceRtcGetTickResolution();
|
osTimerFreq = sceRtcGetTickResolution();
|
||||||
osStartTime = osGetTime();
|
osStartTime = osGetTime();
|
||||||
|
|
||||||
Game::init();
|
Game::init("PSXDATA/LEVEL2.PSX");
|
||||||
|
// sceRazorGpuCaptureSetTrigger(100, "ux0:data/OpenLara/capture.sgx");
|
||||||
|
|
||||||
while (!Core::isQuit) {
|
while (!Core::isQuit) {
|
||||||
inputUpdate();
|
inputUpdate();
|
||||||
|
@@ -25,9 +25,9 @@
|
|||||||
// hint to the driver to use discrete GPU
|
// hint to the driver to use discrete GPU
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// NVIDIA
|
// NVIDIA
|
||||||
__declspec(dllexport) int NvOptimusEnablement = 1;
|
__declspec(dllexport) int NvOptimusEnablement = 1;
|
||||||
// AMD
|
// AMD
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VR_SUPPORT
|
#ifdef VR_SUPPORT
|
||||||
@@ -57,34 +57,6 @@ void osMutexUnlock(void *obj) {
|
|||||||
LeaveCriticalSection((CRITICAL_SECTION*)obj);
|
LeaveCriticalSection((CRITICAL_SECTION*)obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void* osRWLockInit() {
|
|
||||||
SRWLOCK *lock = new SRWLOCK();
|
|
||||||
InitializeSRWLock(lock);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osRWLockFree(void *obj) {
|
|
||||||
delete (SRWLOCK*)obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osRWLockRead(void *obj) {
|
|
||||||
AcquireSRWLockShared((SRWLOCK*)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void osRWUnlockRead(void *obj) {
|
|
||||||
ReleaseSRWLockShared((SRWLOCK*)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void osRWLockWrite(void *obj) {
|
|
||||||
AcquireSRWLockExclusive((SRWLOCK*)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void osRWUnlockWrite(void *obj) {
|
|
||||||
ReleaseSRWLockExclusive((SRWLOCK*)obj);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// timing
|
// timing
|
||||||
int osStartTime = 0;
|
int osStartTime = 0;
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#pragma pack_matrix( column_major )
|
#pragma pack_matrix( column_major )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ALPHA_REF 0.5
|
||||||
#define MAX_LIGHTS 4
|
#define MAX_LIGHTS 4
|
||||||
#define MAX_CONTACTS 15
|
#define MAX_CONTACTS 15
|
||||||
#define WATER_FOG_DIST (1.0 / (6.0 * 1024.0))
|
#define WATER_FOG_DIST (1.0 / (6.0 * 1024.0))
|
||||||
@@ -20,11 +21,13 @@ static const float3 SHADOW_TEXEL = float3(1.0 / SHADOW_SIZE, 1.0 / SHADOW_SIZE,
|
|||||||
#define FLAGS_TYPE float4
|
#define FLAGS_TYPE float4
|
||||||
#define RGBA(c) (c).rgba
|
#define RGBA(c) (c).rgba
|
||||||
#define RGB(c) (c).rgb
|
#define RGB(c) (c).rgb
|
||||||
|
#define F2_TEX2D(s,uv) h2tex2Dlod(s, float4(uv, 0, 0))
|
||||||
#else
|
#else
|
||||||
#define FLAGS_REG b0
|
#define FLAGS_REG b0
|
||||||
#define FLAGS_TYPE bool4
|
#define FLAGS_TYPE bool4
|
||||||
#define RGBA(c) (c).bgra
|
#define RGBA(c) (c).rgba
|
||||||
#define RGB(c) (c).bgr
|
#define RGB(c) (c).rgb
|
||||||
|
#define F2_TEX2D(s,uv) tex2Dlod(s, float4(uv, 0, 0)).xy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct VS_INPUT {
|
struct VS_INPUT {
|
||||||
@@ -65,19 +68,13 @@ float4 uContacts[MAX_CONTACTS] : register( c98 );
|
|||||||
#define FILTER_BLUR uFlags[1].x
|
#define FILTER_BLUR uFlags[1].x
|
||||||
#define FILTER_EQUIRECTANGULAR uFlags[1].y
|
#define FILTER_EQUIRECTANGULAR uFlags[1].y
|
||||||
|
|
||||||
#define WATER_DROP uFlags[0].x
|
|
||||||
#define WATER_SIMULATE uFlags[0].y
|
|
||||||
#define WATER_CAUSTICS uFlags[0].z
|
|
||||||
#define WATER_RAYS uFlags[0].w
|
|
||||||
#define WATER_MASK uFlags[1].x
|
|
||||||
#define WATER_COMPOSE uFlags[1].y
|
|
||||||
|
|
||||||
// options for compose, shadow, ambient passes
|
// options for compose, shadow, ambient passes
|
||||||
#define TYPE_SPRITE uFlags[0].x
|
#define TYPE_SPRITE uFlags[0].x
|
||||||
#define TYPE_FLASH uFlags[0].y
|
#define TYPE_FLASH uFlags[0].y
|
||||||
#define TYPE_ROOM uFlags[0].z
|
#define TYPE_ROOM uFlags[0].z
|
||||||
#define TYPE_ENTITY uFlags[0].w
|
#define TYPE_ENTITY uFlags[0].w
|
||||||
#define TYPE_MIRROR uFlags[1].x
|
#define TYPE_MIRROR uFlags[1].x
|
||||||
|
|
||||||
#define UNDERWATER uFlags[1].y
|
#define UNDERWATER uFlags[1].y
|
||||||
#define ALPHA_TEST uFlags[1].z
|
#define ALPHA_TEST uFlags[1].z
|
||||||
#define CLIP_PLANE uFlags[1].w
|
#define CLIP_PLANE uFlags[1].w
|
||||||
@@ -109,4 +106,106 @@ float3 calcAmbient(float3 n) {
|
|||||||
return sqr.x * lerp(uAmbient[1].xyz, uAmbient[0].xyz, pos.x) +
|
return sqr.x * lerp(uAmbient[1].xyz, uAmbient[0].xyz, pos.x) +
|
||||||
sqr.y * lerp(uAmbient[3].xyz, uAmbient[2].xyz, pos.y) +
|
sqr.y * lerp(uAmbient[3].xyz, uAmbient[2].xyz, pos.y) +
|
||||||
sqr.z * lerp(uAmbient[5].xyz, uAmbient[4].xyz, pos.z);
|
sqr.z * lerp(uAmbient[5].xyz, uAmbient[4].xyz, pos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float calcSpecular(float3 normal, float3 viewVec, float3 lightVec, float intensity) {
|
||||||
|
float3 vv = normalize(viewVec);
|
||||||
|
float3 rv = reflect(-vv, normal);
|
||||||
|
float3 lv = normalize(lightVec);
|
||||||
|
return pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcCaustics(float3 coord, float3 n) {
|
||||||
|
float2 cc = saturate((coord.xz - uRoomSize.xy) / uRoomSize.zw);
|
||||||
|
return tex2Dlod(sReflect, float4(cc.x, 1.0 - cc.y, 0, 0)).x * max(0.0, -n.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 calcNormal(float2 tc, float base) {
|
||||||
|
float dx = F2_TEX2D(sNormal, float2(tc.x + uTexParam.x, tc.y)).x - base;
|
||||||
|
float dz = F2_TEX2D(sNormal, float2(tc.x, tc.y + uTexParam.y)).x - base;
|
||||||
|
return normalize( float3(dx, 64.0 / (1024.0 * 8.0), dz) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyFogUW(inout float3 color, float3 coord, float waterFogDist) {
|
||||||
|
float dist;
|
||||||
|
if (uViewPos.y < uParam.y)
|
||||||
|
dist = abs((coord.y - uParam.y) / normalize(uViewPos.xyz - coord.xyz).y);
|
||||||
|
else
|
||||||
|
dist = length(uViewPos.xyz - coord.xyz);
|
||||||
|
float fog = saturate(1.0 / exp(dist * waterFogDist));
|
||||||
|
dist += coord.y - uParam.y;
|
||||||
|
color.xyz *= lerp(float3(1.0, 1.0, 1.0), UNDERWATER_COLOR, clamp(dist * waterFogDist, 0.0, 2.0));
|
||||||
|
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, fog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyFog(inout float3 color, float fogFactor) {
|
||||||
|
color.xyz = lerp(uFogParams.xyz, color.xyz, fogFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHADOW(float2 p) {
|
||||||
|
#ifdef SHADOW_DEPTH
|
||||||
|
return tex2Dlod(sShadow, float4(p, 0, 0)).x;
|
||||||
|
#else
|
||||||
|
return unpack(tex2Dlod(sShadow, float4(p, 0, 0)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float getShadowValue(float3 lightVec, float4 lightProj) {
|
||||||
|
/*
|
||||||
|
float sMin = min(lightProj.x, lightProj.y);
|
||||||
|
float sMax = max(lightProj.x, lightProj.y);
|
||||||
|
float vis = lightProj.w;
|
||||||
|
if (TYPE_ROOM) {
|
||||||
|
vis = min(vis, dot(normal, lightVec));
|
||||||
|
}
|
||||||
|
sMin = min(vis, sMin);
|
||||||
|
*/
|
||||||
|
float factor = step(0.0, lightProj.w); //float((sMin > 0.0f) && (sMax < lightProj.w)); //
|
||||||
|
lightProj.xyz *= factor;
|
||||||
|
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
lightProj.z += SHADOW_CONST_BIAS * SHADOW_TEXEL.x * lightProj.w;
|
||||||
|
float rShadow = f1tex2Dproj(sShadow, lightProj);
|
||||||
|
#else
|
||||||
|
float3 p = lightProj.xyz / lightProj.w;
|
||||||
|
|
||||||
|
p.z -= SHADOW_CONST_BIAS * SHADOW_TEXEL.x;
|
||||||
|
|
||||||
|
p.z = saturate(p.z);
|
||||||
|
|
||||||
|
float4 samples = float4(
|
||||||
|
SHADOW(p.xy ),
|
||||||
|
SHADOW(p.xy + SHADOW_TEXEL.xz),
|
||||||
|
SHADOW(p.xy + SHADOW_TEXEL.zy),
|
||||||
|
SHADOW(p.xy + SHADOW_TEXEL.xy)
|
||||||
|
);
|
||||||
|
samples = step(p.zzzz, samples);
|
||||||
|
|
||||||
|
float2 f = frac(p.xy / SHADOW_TEXEL.xy);
|
||||||
|
samples.xy = lerp(samples.xz, samples.yw, f.xx);
|
||||||
|
float rShadow = lerp(samples.x, samples.y, f.y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//rShadow = lerp(1.0, rShadow, factor);
|
||||||
|
|
||||||
|
float fade = saturate(dot(lightVec, lightVec));
|
||||||
|
return rShadow + (1.0 - rShadow) * fade;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getShadow(float3 lightVec, float3 normal, float4 lightProj) {
|
||||||
|
float factor = clamp(1.0 - dot(normalize(lightVec), normal), 0.0, 1.0);
|
||||||
|
factor *= SHADOW_NORMAL_BIAS;
|
||||||
|
return getShadowValue(lightVec, lightProj /*mul(uLightProj, float4(coord + normal * factor, 1.0)) */ );
|
||||||
|
}
|
||||||
|
|
||||||
|
float getContactAO(float3 p, float3 n) {
|
||||||
|
float res = 1.0;
|
||||||
|
#pragma loop (unroll: always)
|
||||||
|
for (int i = 0; i < MAX_CONTACTS; i++) {
|
||||||
|
float3 v = uContacts[i].xyz - p;
|
||||||
|
float a = uContacts[i].w;
|
||||||
|
float o = a * saturate(dot(n, v)) / dot(v, v);
|
||||||
|
res *= saturate(1.0 - o);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
@@ -1,14 +1,35 @@
|
|||||||
@echo off
|
@echo off
|
||||||
rd /S /Q d3d9
|
rd /S /Q d3d9
|
||||||
mkdir d3d9
|
mkdir d3d9
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_VS /Fh d3d9/compose_vs.h compose.hlsl /DPASS_COMPOSE /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_SPRITE_VS /Fh d3d9/compose_sprite_vs.h compose_sprite.hlsl /DVERTEX
|
||||||
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_PS /Fh d3d9/compose_ps.h compose.hlsl /DPASS_COMPOSE /DPIXEL
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_SPRITE_PS /Fh d3d9/compose_sprite_ps.h compose_sprite.hlsl /DPIXEL
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn SHADOW_VS /Fh d3d9/shadow_vs.h shadow.hlsl /DPASS_SHADOW /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_FLASH_VS /Fh d3d9/compose_flash_vs.h compose_flash.hlsl /DVERTEX
|
||||||
fxc /nologo /T ps_3_0 /O3 /Gec /Vn SHADOW_PS /Fh d3d9/shadow_ps.h shadow.hlsl /DPASS_SHADOW /DPIXEL
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_FLASH_PS /Fh d3d9/compose_flash_ps.h compose_flash.hlsl /DPIXEL
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn AMBIENT_VS /Fh d3d9/ambient_vs.h ambient.hlsl /DPASS_AMBIENT /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_ROOM_VS /Fh d3d9/compose_room_vs.h compose_room.hlsl /DVERTEX
|
||||||
fxc /nologo /T ps_3_0 /O3 /Gec /Vn AMBIENT_PS /Fh d3d9/ambient_ps.h ambient.hlsl /DPASS_AMBIENT /DPIXEL
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_ROOM_PS /Fh d3d9/compose_room_ps.h compose_room.hlsl /DPIXEL
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_VS /Fh d3d9/water_vs.h water.hlsl /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_ENTITY_VS /Fh d3d9/compose_entity_vs.h compose_entity.hlsl /DVERTEX
|
||||||
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_PS /Fh d3d9/water_ps.h water.hlsl /DPIXEL
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_ENTITY_PS /Fh d3d9/compose_entity_ps.h compose_entity.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn COMPOSE_MIRROR_VS /Fh d3d9/compose_mirror_vs.h compose_mirror.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn COMPOSE_MIRROR_PS /Fh d3d9/compose_mirror_ps.h compose_mirror.hlsl /DPIXEL
|
||||||
|
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn SHADOW_VS /Fh d3d9/shadow_vs.h shadow.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn SHADOW_PS /Fh d3d9/shadow_ps.h shadow.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn AMBIENT_VS /Fh d3d9/ambient_vs.h ambient.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn AMBIENT_PS /Fh d3d9/ambient_ps.h ambient.hlsl /DPIXEL
|
||||||
|
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_DROP_VS /Fh d3d9/water_drop_vs.h water_drop.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_DROP_PS /Fh d3d9/water_drop_ps.h water_drop.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_SIMULATE_VS /Fh d3d9/water_simulate_vs.h water_simulate.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_SIMULATE_PS /Fh d3d9/water_simulate_ps.h water_simulate.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_CAUSTICS_VS /Fh d3d9/water_caustics_vs.h water_caustics.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_CAUSTICS_PS /Fh d3d9/water_caustics_ps.h water_caustics.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_RAYS_VS /Fh d3d9/water_rays_vs.h water_rays.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_RAYS_PS /Fh d3d9/water_rays_ps.h water_rays.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_MASK_VS /Fh d3d9/water_mask_vs.h water_mask.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_MASK_PS /Fh d3d9/water_mask_ps.h water_mask.hlsl /DPIXEL
|
||||||
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn WATER_COMPOSE_VS /Fh d3d9/water_compose_vs.h water_compose.hlsl /DVERTEX
|
||||||
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn WATER_COMPOSE_PS /Fh d3d9/water_compose_ps.h water_compose.hlsl /DPIXEL
|
||||||
|
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn FILTER_VS /Fh d3d9/filter_vs.h filter.hlsl /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn FILTER_VS /Fh d3d9/filter_vs.h filter.hlsl /DVERTEX
|
||||||
fxc /nologo /T ps_3_0 /O3 /Gec /Vn FILTER_PS /Fh d3d9/filter_ps.h filter.hlsl /DPIXEL
|
fxc /nologo /T ps_3_0 /O3 /Gec /Vn FILTER_PS /Fh d3d9/filter_ps.h filter.hlsl /DPIXEL
|
||||||
fxc /nologo /T vs_3_0 /O3 /Gec /Vn GUI_VS /Fh d3d9/gui_vs.h gui.hlsl /DVERTEX
|
fxc /nologo /T vs_3_0 /O3 /Gec /Vn GUI_VS /Fh d3d9/gui_vs.h gui.hlsl /DVERTEX
|
||||||
|
@@ -1,14 +1,37 @@
|
|||||||
@echo off
|
@echo off
|
||||||
rd /S /Q gxm
|
rd /S /Q gxm
|
||||||
mkdir gxm
|
mkdir gxm
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_vp.gxp compose.hlsl -DPASS_COMPOSE -DVERTEX
|
|
||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_fp.gxp compose.hlsl -DPASS_COMPOSE -DPIXEL
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_sprite_vp.gxp compose_sprite.hlsl -DVERTEX
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/shadow_vp.gxp shadow.hlsl -DPASS_SHADOW -DVERTEX
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_sprite_fp.gxp compose_sprite.hlsl -DPIXEL
|
||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/shadow_fp.gxp shadow.hlsl -DPASS_SHADOW -DPIXEL
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_flash_vp.gxp compose_flash.hlsl -DVERTEX
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/ambient_vp.gxp ambient.hlsl -DPASS_AMBIENT -DVERTEX
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_flash_fp.gxp compose_flash.hlsl -DPIXEL
|
||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/ambient_fp.gxp ambient.hlsl -DPASS_AMBIENT -DPIXEL
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_room_vp.gxp compose_room.hlsl -DVERTEX
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_vp.gxp water.hlsl -DVERTEX
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_room_fp.gxp compose_room.hlsl -DPIXEL
|
||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_fp.gxp water.hlsl -DPIXEL
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_entity_vp.gxp compose_entity.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_entity_fp.gxp compose_entity.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/compose_mirror_vp.gxp compose_mirror.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/compose_mirror_fp.gxp compose_mirror.hlsl -DPIXEL
|
||||||
|
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/shadow_vp.gxp shadow.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/shadow_fp.gxp shadow.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/ambient_vp.gxp ambient.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/ambient_fp.gxp ambient.hlsl -DPIXEL
|
||||||
|
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_drop_vp.gxp water_drop.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_drop_fp.gxp water_drop.hlsl -DPIXE
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_simulate_vp.gxp water_simulate.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_simulate_fp.gxp water_simulate.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_caustics_vp.gxp water_caustics.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_caustics_fp.gxp water_caustics.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_rays_vp.gxp water_rays.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_rays_fp.gxp water_rays.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_mask_vp.gxp water_mask.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_mask_fp.gxp water_mask.hlsl -DPIXEL
|
||||||
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/water_compose_vp.gxp water_compose.hlsl -DVERTEX
|
||||||
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/water_compose_fp.gxp water_compose.hlsl -DPIXEL
|
||||||
|
|
||||||
|
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/filter_vp.gxp filter.hlsl -DVERTEX
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/filter_vp.gxp filter.hlsl -DVERTEX
|
||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/filter_fp.gxp filter.hlsl -DPIXEL
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/filter_fp.gxp filter.hlsl -DPIXEL
|
||||||
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/gui_vp.gxp gui.hlsl -DVERTEX
|
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/gui_vp.gxp gui.hlsl -DVERTEX
|
||||||
@@ -17,14 +40,35 @@ psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic -o gxm/clear_vp.gxp clear.hlsl
|
|||||||
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/clear_fp.gxp clear.hlsl -DPIXEL
|
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic -o gxm/clear_fp.gxp clear.hlsl -DPIXEL
|
||||||
|
|
||||||
cd gxm
|
cd gxm
|
||||||
..\bin2c.exe compose_vp.gxp compose_vp.h COMPOSE_VP
|
..\bin2c.exe compose_sprite_vp.gxp compose_sprite_vp.h COMPOSE_SPRITE_VP
|
||||||
..\bin2c.exe compose_fp.gxp compose_fp.h COMPOSE_FP
|
..\bin2c.exe compose_sprite_fp.gxp compose_sprite_fp.h COMPOSE_SPRITE_FP
|
||||||
|
..\bin2c.exe compose_flash_vp.gxp compose_flash_vp.h COMPOSE_FLASH_VP
|
||||||
|
..\bin2c.exe compose_flash_fp.gxp compose_flash_fp.h COMPOSE_FLASH_FP
|
||||||
|
..\bin2c.exe compose_room_vp.gxp compose_room_vp.h COMPOSE_ROOM_VP
|
||||||
|
..\bin2c.exe compose_room_fp.gxp compose_room_fp.h COMPOSE_ROOM_FP
|
||||||
|
..\bin2c.exe compose_entity_vp.gxp compose_entity_vp.h COMPOSE_ENTITY_VP
|
||||||
|
..\bin2c.exe compose_entity_fp.gxp compose_entity_fp.h COMPOSE_ENTITY_FP
|
||||||
|
..\bin2c.exe compose_mirror_vp.gxp compose_mirror_vp.h COMPOSE_MIRROR_VP
|
||||||
|
..\bin2c.exe compose_mirror_fp.gxp compose_mirror_fp.h COMPOSE_MIRROR_FP
|
||||||
|
|
||||||
..\bin2c.exe shadow_vp.gxp shadow_vp.h SHADOW_VP
|
..\bin2c.exe shadow_vp.gxp shadow_vp.h SHADOW_VP
|
||||||
..\bin2c.exe shadow_fp.gxp shadow_fp.h SHADOW_FP
|
..\bin2c.exe shadow_fp.gxp shadow_fp.h SHADOW_FP
|
||||||
..\bin2c.exe ambient_vp.gxp ambient_vp.h AMBIENT_VP
|
..\bin2c.exe ambient_vp.gxp ambient_vp.h AMBIENT_VP
|
||||||
..\bin2c.exe ambient_fp.gxp ambient_fp.h AMBIENT_FP
|
..\bin2c.exe ambient_fp.gxp ambient_fp.h AMBIENT_FP
|
||||||
..\bin2c.exe water_vp.gxp water_vp.h WATER_VP
|
|
||||||
..\bin2c.exe water_fp.gxp water_fp.h WATER_FP
|
..\bin2c.exe water_drop_vp.gxp water_drop_vp.h WATER_DROP_VP
|
||||||
|
..\bin2c.exe water_drop_fp.gxp water_drop_fp.h WATER_DROP_FP
|
||||||
|
..\bin2c.exe water_simulate_vp.gxp water_simulate_vp.h WATER_SIMULATE_VP
|
||||||
|
..\bin2c.exe water_simulate_fp.gxp water_simulate_fp.h WATER_SIMULATE_FP
|
||||||
|
..\bin2c.exe water_caustics_vp.gxp water_caustics_vp.h WATER_CAUSTICS_VP
|
||||||
|
..\bin2c.exe water_caustics_fp.gxp water_caustics_fp.h WATER_CAUSTICS_FP
|
||||||
|
..\bin2c.exe water_rays_vp.gxp water_rays_vp.h WATER_RAYS_VP
|
||||||
|
..\bin2c.exe water_rays_fp.gxp water_rays_fp.h WATER_RAYS_FP
|
||||||
|
..\bin2c.exe water_mask_vp.gxp water_mask_vp.h WATER_MASK_VP
|
||||||
|
..\bin2c.exe water_mask_fp.gxp water_mask_fp.h WATER_MASK_FP
|
||||||
|
..\bin2c.exe water_compose_vp.gxp water_compose_vp.h WATER_COMPOSE_VP
|
||||||
|
..\bin2c.exe water_compose_fp.gxp water_compose_fp.h WATER_COMPOSE_FP
|
||||||
|
|
||||||
..\bin2c.exe filter_vp.gxp filter_vp.h FILTER_VP
|
..\bin2c.exe filter_vp.gxp filter_vp.h FILTER_VP
|
||||||
..\bin2c.exe filter_fp.gxp filter_fp.h FILTER_FP
|
..\bin2c.exe filter_fp.gxp filter_fp.h FILTER_FP
|
||||||
..\bin2c.exe gui_vp.gxp gui_vp.h GUI_VP
|
..\bin2c.exe gui_vp.gxp gui_vp.h GUI_VP
|
||||||
|
@@ -1,332 +0,0 @@
|
|||||||
#include "common.hlsl"
|
|
||||||
|
|
||||||
struct VS_OUTPUT {
|
|
||||||
float4 pos : POSITION;
|
|
||||||
float3 coord : TEXCOORD0;
|
|
||||||
float4 texCoord : TEXCOORD1;
|
|
||||||
float4 viewVec : TEXCOORD2;
|
|
||||||
float4 normal : TEXCOORD3;
|
|
||||||
float4 diffuse : TEXCOORD4;
|
|
||||||
float3 ambient : TEXCOORD5;
|
|
||||||
float3 lightMap : TEXCOORD6;
|
|
||||||
float4 light : TEXCOORD7;
|
|
||||||
float4 lightProj : TEXCOORD8;
|
|
||||||
#ifdef _GAPI_GXM
|
|
||||||
float clipDist : CLP0;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef VERTEX
|
|
||||||
VS_OUTPUT main(VS_INPUT In) {
|
|
||||||
VS_OUTPUT Out;
|
|
||||||
Out.ambient = 0.0;
|
|
||||||
Out.lightMap = 0.0;
|
|
||||||
Out.light = 0.0;
|
|
||||||
|
|
||||||
int index = int(In.aCoord.w * 2.0);
|
|
||||||
float4 rBasisRot = uBasis[index];
|
|
||||||
float4 rBasisPos = uBasis[index + 1];
|
|
||||||
|
|
||||||
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
|
|
||||||
|
|
||||||
if (TYPE_SPRITE) {
|
|
||||||
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz + In.aCoord.xyz, float3(In.aTexCoord.z, In.aTexCoord.w, 0.0));
|
|
||||||
} else {
|
|
||||||
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
|
|
||||||
Out.texCoord.xy *= Out.texCoord.zw;
|
|
||||||
}
|
|
||||||
|
|
||||||
Out.viewVec = float4((uViewPos.xyz - Out.coord) * uFogParams.w, Out.coord.y * uParam.z);
|
|
||||||
|
|
||||||
if (TYPE_SPRITE) {
|
|
||||||
Out.normal.xyz = normalize(Out.viewVec.xyz);
|
|
||||||
} else {
|
|
||||||
Out.normal.xyz = mulQuat(rBasisRot, normalize(In.aNormal.xyz));
|
|
||||||
}
|
|
||||||
|
|
||||||
float fog;
|
|
||||||
|
|
||||||
if (!TYPE_FLASH) {
|
|
||||||
float3 lv0 = (uLightPos[0].xyz - Out.coord) * uLightColor[0].w;
|
|
||||||
float3 lv1 = (uLightPos[1].xyz - Out.coord) * uLightColor[1].w;
|
|
||||||
float3 lv2 = (uLightPos[2].xyz - Out.coord) * uLightColor[2].w;
|
|
||||||
float3 lv3 = (uLightPos[3].xyz - Out.coord) * uLightColor[3].w;
|
|
||||||
|
|
||||||
float4 lum, att;
|
|
||||||
if (TYPE_ENTITY) {
|
|
||||||
lum.x = dot(Out.normal.xyz, normalize(lv0));
|
|
||||||
att.x = dot(lv0, lv0);
|
|
||||||
if (OPT_AMBIENT) {
|
|
||||||
Out.ambient = calcAmbient(Out.normal.xyz);
|
|
||||||
} else {
|
|
||||||
Out.ambient = min(uMaterial.yyy, RGB(In.aLight));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (TYPE_SPRITE) {
|
|
||||||
lum.x = uMaterial.y;
|
|
||||||
} else {
|
|
||||||
lum.x = 1.0;
|
|
||||||
}
|
|
||||||
att.x = 0.0;
|
|
||||||
|
|
||||||
Out.ambient = min(uMaterial.yyy, RGB(In.aLight));
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 light;
|
|
||||||
lum.y = dot(Out.normal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
|
|
||||||
lum.z = dot(Out.normal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
|
|
||||||
lum.w = dot(Out.normal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
|
|
||||||
light = max((float4)0.0, lum) * max((float4)0.0, (float4)1.0 - att);
|
|
||||||
|
|
||||||
if (UNDERWATER) {
|
|
||||||
light.x *= abs(sin(dot(Out.coord.xyz, 1.0 / 512.0) + uParam.x)) * 1.5 + 0.5;
|
|
||||||
|
|
||||||
float d;
|
|
||||||
if (uViewPos.y < uParam.y) {
|
|
||||||
d = abs((Out.coord.y - uParam.y) / normalize(uViewPos.xyz - Out.coord.xyz).y);
|
|
||||||
} else {
|
|
||||||
d = length(uViewPos.xyz - Out.coord.xyz);
|
|
||||||
}
|
|
||||||
fog = d * WATER_FOG_DIST;
|
|
||||||
fog *= step(uParam.y, Out.coord.y);
|
|
||||||
Out.normal.w = fog;
|
|
||||||
} else {
|
|
||||||
fog = length(Out.viewVec.xyz);
|
|
||||||
Out.normal.w = saturate(1.0 / exp(fog));
|
|
||||||
}
|
|
||||||
Out.normal.w = saturate(1.0 / exp(fog));
|
|
||||||
|
|
||||||
if (OPT_SHADOW) {
|
|
||||||
Out.light = light;
|
|
||||||
Out.lightMap = RGB(In.aLight) * light.x;
|
|
||||||
} else {
|
|
||||||
Out.light.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
|
|
||||||
Out.light.w = 0.0;
|
|
||||||
|
|
||||||
if (TYPE_ENTITY) {
|
|
||||||
Out.light.xyz += Out.ambient + uLightColor[0].xyz * light.x;
|
|
||||||
} else {
|
|
||||||
Out.light.xyz += RGB(In.aLight) * light.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
Out.normal.w = 1.0;
|
|
||||||
|
|
||||||
if (TYPE_MIRROR) {
|
|
||||||
Out.diffuse = uMaterial;
|
|
||||||
} else {
|
|
||||||
Out.diffuse = float4(RGB(In.aColor) * (uMaterial.x * 1.8), 1.0);
|
|
||||||
|
|
||||||
if (TYPE_FLASH) {
|
|
||||||
Out.diffuse.xyz += uMaterial.w;
|
|
||||||
} else {
|
|
||||||
Out.diffuse *= uMaterial.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_SPRITE) {
|
|
||||||
Out.diffuse *= RGBA(In.aLight).a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Out.pos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
|
||||||
Out.lightProj = mul(uLightProj, float4(Out.coord, 1.0));
|
|
||||||
/*
|
|
||||||
if (TYPE_ROOM) {
|
|
||||||
float3 lightVec = uLightPos[0].xyz - Out.coord;
|
|
||||||
if (dot(Out.normal.xyz, lightVec) < 0.0) {
|
|
||||||
Out.lightProj.w = -1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#ifdef _GAPI_GXM
|
|
||||||
Out.clipDist = uParam.w - Out.viewVec.w;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return Out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // PIXEL
|
|
||||||
|
|
||||||
float SHADOW(float2 p) {
|
|
||||||
#ifdef SHADOW_DEPTH
|
|
||||||
return tex2Dlod(sShadow, float4(p, 0, 0)).x;
|
|
||||||
#else
|
|
||||||
return unpack(tex2Dlod(sShadow, float4(p, 0, 0)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
float getShadow(float3 lightVec, float3 normal, float4 lightProj) {
|
|
||||||
/*
|
|
||||||
float sMin = min(lightProj.x, lightProj.y);
|
|
||||||
float sMax = max(lightProj.x, lightProj.y);
|
|
||||||
float vis = lightProj.w;
|
|
||||||
if (TYPE_ROOM) {
|
|
||||||
vis = min(vis, dot(normal, lightVec));
|
|
||||||
}
|
|
||||||
sMin = min(vis, sMin);
|
|
||||||
*/
|
|
||||||
float factor = step(0.0, lightProj.w); //float((sMin > 0.0f) && (sMax < lightProj.w)); //
|
|
||||||
lightProj.xyz *= factor;
|
|
||||||
|
|
||||||
#ifdef _GAPI_GXM
|
|
||||||
lightProj.z += SHADOW_CONST_BIAS * SHADOW_TEXEL.x * lightProj.w;
|
|
||||||
float rShadow = f1tex2Dproj(sShadow, lightProj);
|
|
||||||
#else
|
|
||||||
float3 p = lightProj.xyz / lightProj.w;
|
|
||||||
|
|
||||||
p.z -= SHADOW_CONST_BIAS * SHADOW_TEXEL.x;
|
|
||||||
|
|
||||||
p.z = saturate(p.z);
|
|
||||||
|
|
||||||
float4 samples = float4(
|
|
||||||
SHADOW(p.xy ),
|
|
||||||
SHADOW(p.xy + SHADOW_TEXEL.xz),
|
|
||||||
SHADOW(p.xy + SHADOW_TEXEL.zy),
|
|
||||||
SHADOW(p.xy + SHADOW_TEXEL.xy)
|
|
||||||
);
|
|
||||||
samples = step(p.zzzz, samples);
|
|
||||||
|
|
||||||
float2 f = frac(p.xy / SHADOW_TEXEL.xy);
|
|
||||||
samples.xy = lerp(samples.xz, samples.yw, f.xx);
|
|
||||||
float rShadow = lerp(samples.x, samples.y, f.y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//rShadow = lerp(1.0, rShadow, factor);
|
|
||||||
|
|
||||||
float fade = saturate(dot(lightVec, lightVec));
|
|
||||||
return rShadow + (1.0 - rShadow) * fade;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getShadow(float3 coord, float3 lightVec, float3 normal, float4 lightProj) {
|
|
||||||
float factor = clamp(1.0 - dot(normalize(lightVec), normal), 0.0, 1.0);
|
|
||||||
factor *= SHADOW_NORMAL_BIAS;
|
|
||||||
return getShadow(lightVec, normal, lightProj /*mul(uLightProj, float4(coord + normal * factor, 1.0)) */ );
|
|
||||||
}
|
|
||||||
|
|
||||||
float getContactAO(float3 p, float3 n) {
|
|
||||||
float res = 1.0;
|
|
||||||
for (int i = 0; i < MAX_CONTACTS; i++) {
|
|
||||||
float3 v = uContacts[i].xyz - p;
|
|
||||||
float a = uContacts[i].w;
|
|
||||||
float o = a * saturate(dot(n, v)) / dot(v, v);
|
|
||||||
res *= saturate(1.0 - o);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
float calcCaustics(float3 coord, float3 n) {
|
|
||||||
float2 cc = saturate((coord.xz - uRoomSize.xy) / uRoomSize.zw);
|
|
||||||
return tex2Dlod(sReflect, float4(cc.x, 1.0 - cc.y, 0, 0)).x * max(0.0, -n.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float calcSpecular(float3 normal, float3 viewVec, float3 lightVec, float intensity) {
|
|
||||||
float3 vv = normalize(viewVec);
|
|
||||||
float3 rv = reflect(-vv, normal);
|
|
||||||
float3 lv = normalize(lightVec);
|
|
||||||
return pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 main(VS_OUTPUT In) : COLOR0 {
|
|
||||||
float2 uv = In.texCoord.xy;
|
|
||||||
|
|
||||||
if (!TYPE_SPRITE) {
|
|
||||||
uv /= In.texCoord.zw;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 color;
|
|
||||||
|
|
||||||
if (TYPE_MIRROR) {
|
|
||||||
float3 rv = reflect(-normalize(In.viewVec.xyz), normalize(In.normal.xyz));
|
|
||||||
color = texCUBE(sEnvironment, normalize(rv)).bgra;
|
|
||||||
} else {
|
|
||||||
color = tex2D(sDiffuse, uv).bgra;
|
|
||||||
|
|
||||||
if (ALPHA_TEST) {
|
|
||||||
if (color.w <= 0.5)
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _GAPI_GXM
|
|
||||||
if (CLIP_PLANE) {
|
|
||||||
if (In.viewVec.w > uParam.w) {
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
color *= In.diffuse;
|
|
||||||
|
|
||||||
if (TYPE_FLASH) {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_MIRROR) {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 lightVec = (uLightPos[0].xyz - In.coord) * uLightColor[0].w;
|
|
||||||
float3 normal = normalize(In.normal.xyz);
|
|
||||||
|
|
||||||
float rSpecular = 0.0;
|
|
||||||
|
|
||||||
float3 light;
|
|
||||||
if (OPT_SHADOW) {
|
|
||||||
light = uLightColor[1].xyz * In.light.y + uLightColor[2].xyz * In.light.z + uLightColor[3].xyz * In.light.w;
|
|
||||||
|
|
||||||
if (TYPE_ENTITY) {
|
|
||||||
float rShadow = getShadow(In.coord, lightVec, normal, In.lightProj);
|
|
||||||
rSpecular = (uMaterial.z + 0.03) * rShadow;
|
|
||||||
light += In.ambient + uLightColor[0].xyz * (In.light.x * rShadow);
|
|
||||||
} else if (TYPE_ROOM) {
|
|
||||||
float rShadow = getShadow(In.coord, lightVec, normal, In.lightProj);
|
|
||||||
light += lerp(In.ambient, In.lightMap, rShadow);
|
|
||||||
} else if (TYPE_SPRITE) {
|
|
||||||
light += In.lightMap;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
light = In.light.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
float uwSign = 1.0;
|
|
||||||
if (UNDERWATER) {
|
|
||||||
if (TYPE_ENTITY) {
|
|
||||||
uwSign = step(uParam.y, In.coord.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OPT_CAUSTICS) {
|
|
||||||
light += calcCaustics(In.coord, normal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OPT_CONTACT) {
|
|
||||||
light *= getContactAO(In.coord, normal) * 0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
color.xyz *= light;
|
|
||||||
|
|
||||||
if (TYPE_ENTITY) {
|
|
||||||
float specular = calcSpecular(normal, In.viewVec.xyz, lightVec, rSpecular);
|
|
||||||
if (UNDERWATER) {
|
|
||||||
specular *= (1.0 - uwSign);
|
|
||||||
}
|
|
||||||
color.xyz += specular;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UNDERWATER) {
|
|
||||||
float dist;
|
|
||||||
if (uViewPos.y < uParam.y)
|
|
||||||
dist = abs((In.coord.y - uParam.y) / normalize(uViewPos.xyz - In.coord.xyz).y);
|
|
||||||
else
|
|
||||||
dist = length(uViewPos.xyz - In.coord.xyz);
|
|
||||||
float fog = saturate(1.0 / exp(dist * WATER_FOG_DIST * uwSign));
|
|
||||||
dist += In.coord.y - uParam.y;
|
|
||||||
color.xyz *= lerp(float3(1.0, 1.0, 1.0), UNDERWATER_COLOR, clamp(dist * WATER_COLOR_DIST * uwSign, 0.0, 2.0));
|
|
||||||
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, fog);
|
|
||||||
} else {
|
|
||||||
color.xyz = lerp(uFogParams.xyz, color.xyz, In.normal.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
#endif
|
|
144
src/shaders/compose_entity.hlsl
Normal file
144
src/shaders/compose_entity.hlsl
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
// UNDERWATER, ALPHA_TEST, CLIP_PLANE (D3D9 only), OPT_SHADOW, OPT_CAUSTICS, OPT_AMBIENT
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 coord : TEXCOORD0;
|
||||||
|
float4 texCoord : TEXCOORD1;
|
||||||
|
float4 viewVec : TEXCOORD2;
|
||||||
|
float4 normal : TEXCOORD3;
|
||||||
|
float4 diffuse : TEXCOORD4;
|
||||||
|
float3 ambient : TEXCOORD5;
|
||||||
|
float4 light : TEXCOORD6;
|
||||||
|
float4 lightProj : TEXCOORD7;
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float clipDist : CLP0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
Out.ambient = 0.0;
|
||||||
|
|
||||||
|
int index = int(In.aCoord.w * 2.0);
|
||||||
|
float4 rBasisRot = uBasis[index];
|
||||||
|
float4 rBasisPos = uBasis[index + 1];
|
||||||
|
|
||||||
|
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
|
||||||
|
Out.texCoord.xy *= Out.texCoord.zw;
|
||||||
|
|
||||||
|
Out.viewVec = float4((uViewPos.xyz - Out.coord) * uFogParams.w, uParam.w - Out.coord.y * uParam.z);
|
||||||
|
|
||||||
|
Out.normal.xyz = mulQuat(rBasisRot, normalize(In.aNormal.xyz));
|
||||||
|
|
||||||
|
float3 lv0 = (uLightPos[0].xyz - Out.coord) * uLightColor[0].w;
|
||||||
|
float3 lv1 = (uLightPos[1].xyz - Out.coord) * uLightColor[1].w;
|
||||||
|
float3 lv2 = (uLightPos[2].xyz - Out.coord) * uLightColor[2].w;
|
||||||
|
float3 lv3 = (uLightPos[3].xyz - Out.coord) * uLightColor[3].w;
|
||||||
|
|
||||||
|
if (OPT_AMBIENT) {
|
||||||
|
Out.ambient = calcAmbient(Out.normal.xyz);
|
||||||
|
} else {
|
||||||
|
Out.ambient = min(uMaterial.yyy, RGB(In.aLight));
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 lum, att, light;
|
||||||
|
lum.x = dot(Out.normal.xyz, normalize(lv0)); att.x = dot(lv0, lv0);
|
||||||
|
lum.y = dot(Out.normal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
|
||||||
|
lum.z = dot(Out.normal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
|
||||||
|
lum.w = dot(Out.normal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
|
||||||
|
light = max((float4)0.0, lum) * max((float4)0.0, (float4)1.0 - att);
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
light.x *= abs(sin(dot(Out.coord.xyz, 1.0 / 512.0) + uParam.x)) * 1.5 + 0.5;
|
||||||
|
Out.normal.w = 0.0;
|
||||||
|
} else {
|
||||||
|
Out.normal.w = saturate(1.0 / exp(length(Out.viewVec.xyz)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_SHADOW) {
|
||||||
|
Out.light = light;
|
||||||
|
} else {
|
||||||
|
Out.light.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
|
||||||
|
Out.light.w = 0.0;
|
||||||
|
|
||||||
|
Out.light.xyz += Out.ambient + uLightColor[0].xyz * light.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out.diffuse = float4(RGB(In.aColor) * (uMaterial.x * 1.8), 1.0);
|
||||||
|
|
||||||
|
Out.diffuse *= uMaterial.w;
|
||||||
|
|
||||||
|
Out.pos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
||||||
|
Out.lightProj = mul(uLightProj, float4(Out.coord, 1.0));
|
||||||
|
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
Out.clipDist = Out.viewVec.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float4 color = tex2D(sDiffuse, In.texCoord.xy / In.texCoord.zw);
|
||||||
|
|
||||||
|
if (ALPHA_TEST) {
|
||||||
|
clip(color.w - ALPHA_REF);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
if (CLIP_PLANE) {
|
||||||
|
clip(In.viewVec.w);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color *= In.diffuse;
|
||||||
|
|
||||||
|
float3 lightVec = (uLightPos[0].xyz - In.coord) * uLightColor[0].w;
|
||||||
|
float3 normal = normalize(In.normal.xyz);
|
||||||
|
|
||||||
|
float rSpecular = 0.0;
|
||||||
|
|
||||||
|
float3 light;
|
||||||
|
if (OPT_SHADOW) {
|
||||||
|
light = uLightColor[1].xyz * In.light.y + uLightColor[2].xyz * In.light.z + uLightColor[3].xyz * In.light.w;
|
||||||
|
float rShadow = getShadow(lightVec, normal, In.lightProj);
|
||||||
|
rSpecular = (uMaterial.z + 0.03) * rShadow;
|
||||||
|
light += In.ambient + uLightColor[0].xyz * (In.light.x * rShadow);
|
||||||
|
} else {
|
||||||
|
light = In.light.xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_CAUSTICS) {
|
||||||
|
light += calcCaustics(In.coord, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_CONTACT) {
|
||||||
|
light *= getContactAO(In.coord, normal) * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
color.xyz *= light;
|
||||||
|
|
||||||
|
float specular = calcSpecular(normal, In.viewVec.xyz, lightVec, rSpecular);
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
float uwSign = step(uParam.y, In.coord.y);
|
||||||
|
specular *= (1.0 - uwSign);
|
||||||
|
color.xyz += specular;
|
||||||
|
|
||||||
|
applyFogUW(color.xyz, In.coord, WATER_FOG_DIST * uwSign);
|
||||||
|
} else {
|
||||||
|
color.xyz += specular;
|
||||||
|
applyFog(color.xyz, In.normal.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
src/shaders/compose_flash.hlsl
Normal file
51
src/shaders/compose_flash.hlsl
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
// CLIP_PLANE (D3D9 only)
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float4 texCoord : TEXCOORD0;
|
||||||
|
float3 diffuse : TEXCOORD1;
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float clipDist : CLP0;
|
||||||
|
#else
|
||||||
|
float clipDist : TEXCOORD2;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
int index = int(In.aCoord.w * 2.0);
|
||||||
|
float4 rBasisRot = uBasis[index];
|
||||||
|
float4 rBasisPos = uBasis[index + 1];
|
||||||
|
|
||||||
|
float3 coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
|
||||||
|
|
||||||
|
Out.pos = mul(uViewProj, float4(coord, rBasisPos.w));
|
||||||
|
Out.diffuse = In.aColor.rgb * (uMaterial.x * 1.8) + uMaterial.w;
|
||||||
|
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
|
||||||
|
Out.texCoord.xy *= Out.texCoord.zw;
|
||||||
|
|
||||||
|
Out.clipDist = uParam.w - coord.y * uParam.z;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float4 color = tex2D(sDiffuse, In.texCoord.xy / In.texCoord.zw);
|
||||||
|
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
if (CLIP_PLANE) {
|
||||||
|
clip(In.clipDist);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color.xyz *= In.diffuse.xyz;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
58
src/shaders/compose_mirror.hlsl
Normal file
58
src/shaders/compose_mirror.hlsl
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
// CLIP_PLANE (D3D9 only)
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float4 viewVec : TEXCOORD0;
|
||||||
|
float4 normal : TEXCOORD1;
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float clipDist : CLP0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
int index = int(In.aCoord.w * 2.0);
|
||||||
|
float4 rBasisRot = uBasis[index];
|
||||||
|
float4 rBasisPos = uBasis[index + 1];
|
||||||
|
|
||||||
|
float3 coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
|
||||||
|
|
||||||
|
Out.viewVec = float4((uViewPos.xyz - coord) * uFogParams.w, uParam.w - coord.y * uParam.z);
|
||||||
|
|
||||||
|
Out.normal.xyz = mulQuat(rBasisRot, normalize(In.aNormal.xyz));
|
||||||
|
Out.normal.w = saturate(1.0 / exp(length(Out.viewVec.xyz)));
|
||||||
|
|
||||||
|
Out.pos = mul(uViewProj, float4(coord, rBasisPos.w));
|
||||||
|
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
Out.clipDist = Out.viewVec.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float3 rv = reflect(-In.viewVec.xyz, In.normal.xyz);
|
||||||
|
float4 color = texCUBE(sEnvironment, normalize(rv));
|
||||||
|
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
if (CLIP_PLANE) {
|
||||||
|
clip(In.viewVec.w);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color *= uMaterial;
|
||||||
|
color.xyz = saturate(color.xyz);
|
||||||
|
|
||||||
|
applyFog(color.xyz, In.normal.w);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
131
src/shaders/compose_room.hlsl
Normal file
131
src/shaders/compose_room.hlsl
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
// UNDERWATER, ALPHA_TEST, CLIP_PLANE (D3D9 only), OPT_SHADOW, OPT_CAUSTICS, OPT_CONTACT
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 coord : TEXCOORD0;
|
||||||
|
float4 texCoord : TEXCOORD1;
|
||||||
|
float4 normal : TEXCOORD2;
|
||||||
|
float4 diffuse : TEXCOORD3;
|
||||||
|
float3 ambient : TEXCOORD4;
|
||||||
|
float3 lightMap : TEXCOORD5;
|
||||||
|
float4 light : TEXCOORD6;
|
||||||
|
float4 lightProj : TEXCOORD7;
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float clipDist : CLP0;
|
||||||
|
#else
|
||||||
|
float clipDist : TEXCOORD8;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float4 rBasisRot = uBasis[0];
|
||||||
|
float4 rBasisPos = uBasis[1];
|
||||||
|
|
||||||
|
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
|
||||||
|
Out.texCoord.xy *= Out.texCoord.zw;
|
||||||
|
|
||||||
|
float3 viewVec = (uViewPos.xyz - Out.coord) * uFogParams.w;
|
||||||
|
|
||||||
|
Out.normal.xyz = mulQuat(rBasisRot, normalize(In.aNormal.xyz));
|
||||||
|
|
||||||
|
float3 lv1 = (uLightPos[1].xyz - Out.coord) * uLightColor[1].w;
|
||||||
|
float3 lv2 = (uLightPos[2].xyz - Out.coord) * uLightColor[2].w;
|
||||||
|
float3 lv3 = (uLightPos[3].xyz - Out.coord) * uLightColor[3].w;
|
||||||
|
|
||||||
|
float4 lum, att;
|
||||||
|
lum.x = 1.0;
|
||||||
|
att.x = 0.0;
|
||||||
|
|
||||||
|
Out.ambient = min(uMaterial.yyy, In.aLight.rgb);
|
||||||
|
|
||||||
|
float4 light;
|
||||||
|
lum.y = dot(Out.normal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
|
||||||
|
lum.z = dot(Out.normal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
|
||||||
|
lum.w = dot(Out.normal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
|
||||||
|
light = max((float4)0.0, lum) * max((float4)0.0, (float4)1.0 - att);
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
light.x *= abs(sin(dot(Out.coord.xyz, 1.0 / 512.0) + uParam.x)) * 1.5 + 0.5;
|
||||||
|
Out.normal.w = 0.0;
|
||||||
|
} else {
|
||||||
|
Out.normal.w = saturate(1.0 / exp(length(viewVec.xyz)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_SHADOW) {
|
||||||
|
Out.light = light;
|
||||||
|
Out.lightMap = In.aLight.rgb * light.x;
|
||||||
|
} else {
|
||||||
|
Out.light.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
|
||||||
|
Out.light.w = 0.0;
|
||||||
|
Out.light.xyz += In.aLight.rgb * light.x;
|
||||||
|
Out.lightMap = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out.diffuse = float4(In.aColor.rgb * (uMaterial.x * 1.8), 1.0);
|
||||||
|
|
||||||
|
Out.diffuse *= uMaterial.w;
|
||||||
|
|
||||||
|
Out.pos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
||||||
|
Out.lightProj = mul(uLightProj, float4(Out.coord, 1.0));
|
||||||
|
|
||||||
|
Out.clipDist = uParam.w - Out.coord.y * uParam.z;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float4 color = tex2D(sDiffuse, In.texCoord.xy / In.texCoord.zw);
|
||||||
|
|
||||||
|
if (ALPHA_TEST) {
|
||||||
|
clip(color.w - ALPHA_REF);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
if (CLIP_PLANE) {
|
||||||
|
clip(In.clipDist);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color *= In.diffuse;
|
||||||
|
|
||||||
|
float3 lightVec = (uLightPos[0].xyz - In.coord) * uLightColor[0].w;
|
||||||
|
float3 normal = normalize(In.normal.xyz);
|
||||||
|
|
||||||
|
float3 light;
|
||||||
|
if (OPT_SHADOW) {
|
||||||
|
light = uLightColor[1].xyz * In.light.y + uLightColor[2].xyz * In.light.z + uLightColor[3].xyz * In.light.w;
|
||||||
|
float rShadow = getShadow(lightVec, normal, In.lightProj);
|
||||||
|
light += lerp(In.ambient, In.lightMap, rShadow);
|
||||||
|
} else {
|
||||||
|
light = In.light.xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_CAUSTICS) {
|
||||||
|
light += calcCaustics(In.coord, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OPT_CONTACT) {
|
||||||
|
light *= getContactAO(In.coord, normal) * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
color.xyz *= light;
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
applyFogUW(color.xyz, In.coord, WATER_FOG_DIST);
|
||||||
|
} else {
|
||||||
|
applyFog(color.xyz, In.normal.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
107
src/shaders/compose_sprite.hlsl
Normal file
107
src/shaders/compose_sprite.hlsl
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
// UNDERWATER, OPT_CAUSTICS, CLIP_PLANE (D3D9 only), ALPHA_TEST
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 coord : TEXCOORD0;
|
||||||
|
float4 texCoord : TEXCOORD1;
|
||||||
|
float4 normal : TEXCOORD2;
|
||||||
|
float4 diffuse : TEXCOORD3;
|
||||||
|
float4 light : TEXCOORD4;
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float clipDist : CLP0;
|
||||||
|
#else
|
||||||
|
float clipDist : TEXCOORD5;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float4 rBasisRot = uBasis[0];
|
||||||
|
float4 rBasisPos = uBasis[1];
|
||||||
|
|
||||||
|
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz + In.aCoord.xyz, float3(In.aTexCoord.z, In.aTexCoord.w, 0.0));
|
||||||
|
|
||||||
|
float3 viewVec = (uViewPos.xyz - Out.coord) * uFogParams.w;
|
||||||
|
|
||||||
|
Out.normal.xyz = normalize(viewVec);
|
||||||
|
|
||||||
|
float3 lv1 = (uLightPos[1].xyz - Out.coord) * uLightColor[1].w;
|
||||||
|
float3 lv2 = (uLightPos[2].xyz - Out.coord) * uLightColor[2].w;
|
||||||
|
float3 lv3 = (uLightPos[3].xyz - Out.coord) * uLightColor[3].w;
|
||||||
|
|
||||||
|
float4 lum, att;
|
||||||
|
lum.x = uMaterial.y;
|
||||||
|
att.x = 0.0;
|
||||||
|
|
||||||
|
float4 light;
|
||||||
|
lum.y = dot(Out.normal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
|
||||||
|
lum.z = dot(Out.normal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
|
||||||
|
lum.w = dot(Out.normal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
|
||||||
|
light = max((float4)0.0, lum) * max((float4)0.0, (float4)1.0 - att);
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
Out.normal.w = 0.0;
|
||||||
|
} else {
|
||||||
|
Out.normal.w = saturate(1.0 / exp(length(viewVec.xyz)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Out.light.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
|
||||||
|
Out.light.w = 0.0;
|
||||||
|
|
||||||
|
Out.light.xyz += In.aLight.rgb * light.x;
|
||||||
|
|
||||||
|
Out.diffuse = float4(In.aColor.rgb * (uMaterial.x * 1.8), 1.0);
|
||||||
|
|
||||||
|
Out.diffuse *= uMaterial.w;
|
||||||
|
Out.diffuse *= In.aLight.a;
|
||||||
|
|
||||||
|
Out.pos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
||||||
|
|
||||||
|
Out.clipDist = uParam.w - Out.coord.y * uParam.z;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float4 color = tex2D(sDiffuse, In.texCoord.xy);
|
||||||
|
|
||||||
|
if (ALPHA_TEST) {
|
||||||
|
clip(color.w - ALPHA_REF);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
if (CLIP_PLANE) {
|
||||||
|
clip(In.clipDist);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color *= In.diffuse;
|
||||||
|
|
||||||
|
float3 normal = normalize(In.normal.xyz);
|
||||||
|
|
||||||
|
float3 light = In.light.xyz;
|
||||||
|
|
||||||
|
if (OPT_CAUSTICS) {
|
||||||
|
light += calcCaustics(In.coord, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
color.xyz *= light;
|
||||||
|
|
||||||
|
if (UNDERWATER) {
|
||||||
|
applyFogUW(color.xyz, In.coord, WATER_FOG_DIST);
|
||||||
|
} else {
|
||||||
|
applyFog(color.xyz, In.normal.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -46,7 +46,7 @@ float4 downsample(float2 uv) { // uParam (1 / textureSize, unused, unused, unuse
|
|||||||
float4 grayscale(float2 uv) { // uParam (factor, unused, unused, unused)
|
float4 grayscale(float2 uv) { // uParam (factor, unused, unused, unused)
|
||||||
float4 color = tex2D(sDiffuse, uv);
|
float4 color = tex2D(sDiffuse, uv);
|
||||||
float3 gray = dot(color, float4(0.299, 0.587, 0.114, 0.0));
|
float3 gray = dot(color, float4(0.299, 0.587, 0.114, 0.0));
|
||||||
return float4(lerp(color.xyz, gray, uParam.w) * uParam.xyz, color.w).bgra;
|
return float4(lerp(color.xyz, gray, uParam.w) * uParam.xyz, color.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused)
|
float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused)
|
||||||
@@ -68,7 +68,7 @@ float4 upscale(float2 uv) {
|
|||||||
float2 fuv = frac(uv);
|
float2 fuv = frac(uv);
|
||||||
uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv);
|
uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv);
|
||||||
uv = (uv - 0.5) / uParam.xy;
|
uv = (uv - 0.5) / uParam.xy;
|
||||||
return tex2D(sDiffuse, uv).bgra;
|
return tex2D(sDiffuse, uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 main(VS_OUTPUT In) : COLOR0 {
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
@@ -11,13 +11,13 @@ VS_OUTPUT main(VS_INPUT In) {
|
|||||||
VS_OUTPUT Out;
|
VS_OUTPUT Out;
|
||||||
Out.pos = mul(uViewProj, float4(In.aCoord.xy, 0.0, 1.0));
|
Out.pos = mul(uViewProj, float4(In.aCoord.xy, 0.0, 1.0));
|
||||||
Out.texCoord = In.aTexCoord.xy * (1.0 / 32767.0);
|
Out.texCoord = In.aTexCoord.xy * (1.0 / 32767.0);
|
||||||
Out.diffuse = RGBA(In.aLight) * uMaterial;
|
Out.diffuse = In.aLight * uMaterial;
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // PIXEL
|
#else // PIXEL
|
||||||
|
|
||||||
float4 main(VS_OUTPUT In) : COLOR0 {
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
return In.diffuse * tex2D(sDiffuse, In.texCoord.xy).bgra;
|
return In.diffuse * tex2Dlod(sDiffuse, float4(In.texCoord, 0, 0));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@@ -1,251 +0,0 @@
|
|||||||
#include "common.hlsl"
|
|
||||||
|
|
||||||
struct VS_OUTPUT {
|
|
||||||
float4 pos : POSITION;
|
|
||||||
float3 coord : TEXCOORD0;
|
|
||||||
float2 texCoord : TEXCOORD1;
|
|
||||||
float3 viewVec : TEXCOORD2;
|
|
||||||
float3 lightVec : TEXCOORD3;
|
|
||||||
float3 oldPos : TEXCOORD4;
|
|
||||||
float3 newPos : TEXCOORD5;
|
|
||||||
float4 hpos : TEXCOORD6;
|
|
||||||
};
|
|
||||||
|
|
||||||
float2 invUV(float2 uv) {
|
|
||||||
return float2(uv.x, 1.0 - uv.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 getInvUV(float2 uv, float4 param) {
|
|
||||||
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
|
|
||||||
#ifndef _GAPI_GXM
|
|
||||||
p.xy += 0.5 * param.xy;
|
|
||||||
#endif
|
|
||||||
return float3(p, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float2 getUV(float2 uv, float4 param) {
|
|
||||||
float2 p = (uv.xy * 0.5 + 0.5) * param.zw;
|
|
||||||
#ifndef _GAPI_GXM
|
|
||||||
//p.xy += 0.5 * param.xy;
|
|
||||||
#endif
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VERTEX
|
|
||||||
VS_OUTPUT main(VS_INPUT In) {
|
|
||||||
VS_OUTPUT Out;
|
|
||||||
|
|
||||||
Out.pos = 0.0;
|
|
||||||
Out.coord = 0.0;
|
|
||||||
Out.viewVec = 0.0;
|
|
||||||
Out.lightVec = 0.0;
|
|
||||||
Out.oldPos = 0.0;
|
|
||||||
Out.newPos = 0.0;
|
|
||||||
Out.hpos = 0.0;
|
|
||||||
|
|
||||||
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
|
||||||
|
|
||||||
Out.texCoord = getUV(coord.xy, uTexParam);
|
|
||||||
|
|
||||||
if (WATER_COMPOSE) {
|
|
||||||
Out.coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
|
|
||||||
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
|
|
||||||
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
|
|
||||||
Out.lightVec = uLightPos[0].xyz - Out.coord.xyz;
|
|
||||||
Out.oldPos = getInvUV(coord.xy, uTexParam);
|
|
||||||
Out.texCoord = getUV(coord.xy, uRoomSize);
|
|
||||||
} else if (WATER_DROP) {
|
|
||||||
Out.pos = float4(coord.xyz, 1.0);
|
|
||||||
Out.oldPos = getInvUV(coord.xy, uTexParam);
|
|
||||||
} else if (WATER_SIMULATE) {
|
|
||||||
Out.pos = float4(coord.xyz, 1.0);
|
|
||||||
Out.oldPos = getInvUV(coord.xy, uTexParam);
|
|
||||||
Out.texCoord = getUV(coord.xy, uRoomSize);
|
|
||||||
} else if (WATER_CAUSTICS) {
|
|
||||||
float3 rCoord = float3(coord.x, coord.y, 0.0) * uPosScale[1].xzy;
|
|
||||||
float2 uv = getInvUV(rCoord.xy, uTexParam).xy;
|
|
||||||
float4 info = tex2Dlod(sNormal, float4(uv, 0, 0));
|
|
||||||
float3 normal = float3(info.z, info.w, sqrt(1.0 - dot(info.zw, info.zw)));
|
|
||||||
|
|
||||||
float3 light = float3(0.0, 0.0, 1.0);
|
|
||||||
float3 refOld = refract(-light, float3(0.0, 0.0, 1.0), 0.75);
|
|
||||||
float3 refNew = refract(-light, normal, 0.75);
|
|
||||||
|
|
||||||
Out.oldPos = rCoord + refOld * (-1.0 / refOld.z) + refOld * ((-refOld.z - 1.0) / refOld.z);
|
|
||||||
Out.newPos = rCoord + refNew * ((info.r - 1.0) / refNew.z) + refOld * ((-refNew.z - 1.0) / refOld.z);
|
|
||||||
|
|
||||||
Out.pos = float4(Out.newPos.xy + refOld.xy / refOld.z, 0.0, 1.0);
|
|
||||||
} else if (WATER_MASK) {
|
|
||||||
Out.coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
|
|
||||||
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
|
|
||||||
} else if (WATER_RAYS) {
|
|
||||||
Out.coord = In.aCoord.xyz + uParam.xyz;
|
|
||||||
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
|
|
||||||
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
Out.hpos = Out.pos;
|
|
||||||
|
|
||||||
return Out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // PIXEL
|
|
||||||
|
|
||||||
float calcFresnel(float VoH, float f0) {
|
|
||||||
float f = pow(1.0 - VoH, 5.0);
|
|
||||||
return f + f0 * (1.0f - f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 drop(VS_OUTPUT In) {
|
|
||||||
float2 iuv = In.oldPos.xy;
|
|
||||||
|
|
||||||
float4 v = tex2D(sNormal, iuv);
|
|
||||||
|
|
||||||
float value = max(0.0, 1.0 - length(uParam.xy - In.texCoord / uTexParam.xy) / uParam.z);
|
|
||||||
value = 0.5 - cos(value * PI) * 0.5;
|
|
||||||
|
|
||||||
v.x += value * uParam.w;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 simulate(VS_OUTPUT In) {
|
|
||||||
float2 iuv = In.oldPos.xy;
|
|
||||||
float2 uv = In.texCoord;
|
|
||||||
|
|
||||||
if (tex2D(sMask, uv).a < 0.5)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
float4 v = tex2D(sNormal, iuv); // height, speed, normal.xz
|
|
||||||
|
|
||||||
float3 d = float3(float2(uTexParam.x, -uTexParam.y), 0.0);
|
|
||||||
float4 f = float4(
|
|
||||||
tex2D(sNormal, iuv + d.xz).x, tex2D(sNormal, iuv + d.zy).x,
|
|
||||||
tex2D(sNormal, iuv - d.xz).x, tex2D(sNormal, iuv - d.zy).x
|
|
||||||
);
|
|
||||||
|
|
||||||
float average = dot(f, (float4)0.25);
|
|
||||||
|
|
||||||
// normal
|
|
||||||
v.zw = normalize( float3(f.x - f.z, 64.0 / (1024.0 * 4.0), f.y - f.w) ).xz;
|
|
||||||
|
|
||||||
// integrate
|
|
||||||
const float vel = 1.4;
|
|
||||||
const float vis = 0.995;
|
|
||||||
|
|
||||||
v.y += (average - v.x) * vel;
|
|
||||||
v.y *= vis;
|
|
||||||
v.x += v.y + (tex2D(sDiffuse, uv + uParam.zw).x * 2.0 - 1.0) * 0.00025;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 caustics(VS_OUTPUT In) {
|
|
||||||
float rOldArea = length(ddx(In.oldPos)) * length(ddy(In.oldPos));
|
|
||||||
float rNewArea = length(ddx(In.newPos)) * length(ddy(In.newPos));
|
|
||||||
rNewArea = max(rNewArea, 0.00002); // WebGL NVIDIA workaround >_<
|
|
||||||
float value = saturate(rOldArea / rNewArea * 0.2);
|
|
||||||
return float4(value, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float boxIntersect(float3 rayPos, float3 rayDir, float3 center, float3 hsize) {
|
|
||||||
center -= rayPos;
|
|
||||||
float3 bMin = (center - hsize) / rayDir;
|
|
||||||
float3 bMax = (center + hsize) / rayDir;
|
|
||||||
float3 m = min(bMin, bMax);
|
|
||||||
return max(0.0, max(m.x, max(m.y, m.z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 rays(VS_OUTPUT In, float2 pixelCoord) {
|
|
||||||
#define RAY_STEPS 16.0
|
|
||||||
|
|
||||||
float3 viewVec = normalize(In.viewVec);
|
|
||||||
|
|
||||||
float t = boxIntersect(uViewPos.xyz, -viewVec, uPosScale[0].xyz, uPosScale[1].xyz);
|
|
||||||
|
|
||||||
float3 p0 = uViewPos.xyz - viewVec * t;
|
|
||||||
float3 p1 = In.coord.xyz;
|
|
||||||
|
|
||||||
float dither = tex2Dlod(sMask, float4(pixelCoord * (1.0 / 8.0), 0, 0)).x;
|
|
||||||
|
|
||||||
float3 delta = (p1 - p0) / RAY_STEPS;
|
|
||||||
float3 pos = p0 + delta * dither;
|
|
||||||
|
|
||||||
float sum = 0.0;
|
|
||||||
for (float i = 0.0; i < RAY_STEPS; i++) {
|
|
||||||
float3 wpos = (pos - uPosScale[0].xyz) / uPosScale[1].xyz;
|
|
||||||
float2 tc = wpos.xz * 0.5 + 0.5;
|
|
||||||
float light = tex2Dlod(sReflect, float4(tc, 0, 0)).x;
|
|
||||||
sum += light * (1.0 - (clamp(wpos.y, -1.0, 1.0) * 0.5 + 0.5));
|
|
||||||
pos += delta;
|
|
||||||
}
|
|
||||||
sum /= RAY_STEPS;
|
|
||||||
sum *= uParam.w;
|
|
||||||
|
|
||||||
return float4(UNDERWATER_COLOR * sum, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 mask() {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 compose(VS_OUTPUT In) {
|
|
||||||
float3 viewVec = normalize(In.viewVec);
|
|
||||||
float2 iuv = In.oldPos.xy;
|
|
||||||
|
|
||||||
float4 value = tex2D(sNormal, iuv);
|
|
||||||
float3 normal = float3(value.z, sqrt(1.0 - dot(value.zw, value.zw)) * sign(viewVec.y), value.w);
|
|
||||||
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy;
|
|
||||||
|
|
||||||
float3 rv = reflect(-viewVec, normal);
|
|
||||||
float3 lv = normalize(In.lightVec);
|
|
||||||
|
|
||||||
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
|
|
||||||
|
|
||||||
float2 tc = In.hpos.xy / In.hpos.w * 0.5 + 0.5;
|
|
||||||
|
|
||||||
float4 refrA = tex2D(sDiffuse, uParam.xy * invUV(clamp(tc + dudv * uParam.z, 0.0, 0.999)) );
|
|
||||||
float4 refrB = tex2D(sDiffuse, uParam.xy * invUV(tc) );
|
|
||||||
float4 refr = float4(lerp(refrA.xyz, refrB.xyz, refrA.w), 1.0);
|
|
||||||
float4 refl = tex2D(sReflect, tc.xy + dudv * uParam.w);
|
|
||||||
|
|
||||||
float fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
|
|
||||||
|
|
||||||
float4 color = lerp(refr, refl, fresnel) + spec * 1.5;
|
|
||||||
color.w *= tex2D(sMask, In.texCoord).a;
|
|
||||||
|
|
||||||
float dist = In.viewVec.y / viewVec.y;
|
|
||||||
dist *= step(In.coord.y, uViewPos.y);
|
|
||||||
color.xyz *= lerp(float3(1.0, 1.0, 1.0), UNDERWATER_COLOR, clamp(dist * WATER_COLOR_DIST, 0.0, 2.0));
|
|
||||||
float fog = saturate(1.0 / exp(dist * WATER_FOG_DIST));
|
|
||||||
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, fog);
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _GAPI_GXM
|
|
||||||
float4 main(VS_OUTPUT In) : COLOR0 {
|
|
||||||
float2 pixelCoord = float2(__pixel_x(), __pixel_y());
|
|
||||||
#else
|
|
||||||
float4 main(VS_OUTPUT In, float4 pixelCoord: VPOS) : COLOR0 {
|
|
||||||
#endif
|
|
||||||
if (WATER_DROP)
|
|
||||||
return drop(In);
|
|
||||||
|
|
||||||
if (WATER_SIMULATE)
|
|
||||||
return simulate(In);
|
|
||||||
|
|
||||||
if (WATER_CAUSTICS)
|
|
||||||
return caustics(In);
|
|
||||||
|
|
||||||
if (WATER_RAYS)
|
|
||||||
return rays(In, pixelCoord.xy);
|
|
||||||
|
|
||||||
if (WATER_MASK)
|
|
||||||
return mask();
|
|
||||||
|
|
||||||
if (WATER_COMPOSE)
|
|
||||||
return compose(In);
|
|
||||||
|
|
||||||
return float4(1.0, 0.0, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
#endif
|
|
58
src/shaders/water_caustics.hlsl
Normal file
58
src/shaders/water_caustics.hlsl
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float2 texCoord : TEXCOORD0;
|
||||||
|
float3 oldPos : TEXCOORD1;
|
||||||
|
float3 newPos : TEXCOORD2;
|
||||||
|
};
|
||||||
|
|
||||||
|
float2 getInvUV(float2 uv, float4 param) {
|
||||||
|
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
p.xy += 0.5 * param.xy;
|
||||||
|
#endif
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 getUV(float2 uv, float4 param) {
|
||||||
|
return (uv.xy * 0.5 + 0.5) * param.zw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.texCoord = getUV(coord.xy, uTexParam);
|
||||||
|
|
||||||
|
float3 rCoord = float3(coord.x, coord.y, 0.0) * uPosScale[1].xzy;
|
||||||
|
|
||||||
|
float2 uv = getInvUV(rCoord.xy, uTexParam).xy;
|
||||||
|
float2 info = F2_TEX2D(sNormal, uv).xy;
|
||||||
|
float3 normal = calcNormal(uv, info.x).xzy;
|
||||||
|
|
||||||
|
float3 light = float3(0.0, 0.0, 1.0);
|
||||||
|
float3 refOld = refract(-light, float3(0.0, 0.0, 1.0), 0.75);
|
||||||
|
float3 refNew = refract(-light, normal, 0.75);
|
||||||
|
|
||||||
|
Out.oldPos = rCoord + refOld * (-1.0 / refOld.z) + refOld * ((-refOld.z - 1.0) / refOld.z);
|
||||||
|
Out.newPos = rCoord + refNew * ((info.r - 1.0) / refNew.z) + refOld * ((-refNew.z - 1.0) / refOld.z);
|
||||||
|
|
||||||
|
Out.pos = float4(Out.newPos.xy + refOld.xy / refOld.z, 0.0, 1.0);
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float rOldArea = length(ddx(In.oldPos)) * length(ddy(In.oldPos));
|
||||||
|
float rNewArea = length(ddx(In.newPos)) * length(ddy(In.newPos));
|
||||||
|
rNewArea = max(rNewArea, 0.00002); // WebGL NVIDIA workaround >_<
|
||||||
|
float value = saturate(rOldArea / rNewArea * 0.2);
|
||||||
|
return float4(value, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
88
src/shaders/water_compose.hlsl
Normal file
88
src/shaders/water_compose.hlsl
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 coord : TEXCOORD0;
|
||||||
|
float2 texCoord : TEXCOORD1;
|
||||||
|
float2 maskCoord : TEXCOORD2;
|
||||||
|
float3 viewVec : TEXCOORD3;
|
||||||
|
float3 lightVec : TEXCOORD4;
|
||||||
|
float3 hpos : TEXCOORD5;
|
||||||
|
};
|
||||||
|
|
||||||
|
float2 invUV(float2 uv) {
|
||||||
|
return float2(uv.x, 1.0 - uv.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 getInvUV(float2 uv, float4 param) {
|
||||||
|
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
p.xy += 0.5 * param.xy;
|
||||||
|
#endif
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 getUV(float2 uv, float4 param) {
|
||||||
|
return (uv.xy * 0.5 + 0.5) * param.zw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
|
||||||
|
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
|
||||||
|
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
|
||||||
|
Out.lightVec = uLightPos[0].xyz - Out.coord.xyz;
|
||||||
|
Out.texCoord = getInvUV(coord.xy, uTexParam);
|
||||||
|
Out.maskCoord = getUV(coord.xy, uRoomSize);
|
||||||
|
Out.hpos = Out.pos.xyw;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float calcFresnel(float VoH, float f0) {
|
||||||
|
float f = pow(1.0 - VoH, 5.0);
|
||||||
|
return f + f0 * (1.0f - f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float3 viewVec = normalize(In.viewVec);
|
||||||
|
|
||||||
|
float2 value = F2_TEX2D(sNormal, In.texCoord).xy;
|
||||||
|
|
||||||
|
float3 normal = calcNormal(In.texCoord, value.x);
|
||||||
|
normal.y *= sign(viewVec.y);
|
||||||
|
|
||||||
|
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy;
|
||||||
|
|
||||||
|
float3 rv = reflect(-viewVec, normal);
|
||||||
|
float3 lv = normalize(In.lightVec);
|
||||||
|
|
||||||
|
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
|
||||||
|
|
||||||
|
float2 tc = In.hpos.xy / In.hpos.z * 0.5 + 0.5;
|
||||||
|
|
||||||
|
float4 refrA = tex2Dlod(sDiffuse, float4(uParam.xy * invUV(clamp(tc + dudv * uParam.z, 0.0, 0.999)), 0, 0) );
|
||||||
|
float4 refrB = tex2Dlod(sDiffuse, float4(uParam.xy * invUV(tc), 0, 0) );
|
||||||
|
float4 refr = float4(lerp(refrA.xyz, refrB.xyz, refrA.w), 1.0);
|
||||||
|
float4 refl = tex2Dlod(sReflect, float4(tc.xy + dudv * uParam.w, 0, 0));
|
||||||
|
|
||||||
|
float fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
|
||||||
|
|
||||||
|
float4 color = lerp(refr, refl, fresnel) + spec * 1.5;
|
||||||
|
color.w *= tex2Dlod(sMask, float4(In.maskCoord, 0, 0)).a;
|
||||||
|
|
||||||
|
float dist = In.viewVec.y / viewVec.y;
|
||||||
|
dist *= step(In.coord.y, uViewPos.y);
|
||||||
|
color.xyz *= lerp(float3(1.0, 1.0, 1.0), UNDERWATER_COLOR, clamp(dist * WATER_COLOR_DIST, 0.0, 2.0));
|
||||||
|
float fog = saturate(1.0 / exp(dist * WATER_FOG_DIST));
|
||||||
|
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, fog);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
src/shaders/water_drop.hlsl
Normal file
51
src/shaders/water_drop.hlsl
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float2 texCoord : TEXCOORD0;
|
||||||
|
float2 dropCoord : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
float2 getInvUV(float2 uv, float4 param) {
|
||||||
|
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
p.xy += 0.5 * param.xy;
|
||||||
|
#endif
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 getUV(float2 uv, float4 param) {
|
||||||
|
float2 p = (uv.xy * 0.5 + 0.5) * param.zw;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.pos = float4(coord.xyz, 1.0);
|
||||||
|
Out.texCoord = getInvUV(coord.xy, uTexParam);
|
||||||
|
Out.dropCoord = getUV(coord.xy, uTexParam);
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
half4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
half2 v = (half2)tex2Dlod(sNormal, float4(In.texCoord.xy, 0, 0)).xy;
|
||||||
|
|
||||||
|
float value = max(0.0, 1.0 - length(uParam.xy - In.dropCoord / uTexParam.xy) / uParam.z);
|
||||||
|
value = 0.5 - cos(value * PI) * 0.5;
|
||||||
|
value *= uParam.w;
|
||||||
|
|
||||||
|
v.x += (half)value;
|
||||||
|
//v.x = 1.0;
|
||||||
|
|
||||||
|
return half4(v, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
17
src/shaders/water_mask.hlsl
Normal file
17
src/shaders/water_mask.hlsl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
|
||||||
|
float4 main(VS_INPUT In) : POSITION {
|
||||||
|
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
||||||
|
coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
|
||||||
|
return mul(uViewProj, float4(coord, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float4 main() : COLOR0 {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
65
src/shaders/water_rays.hlsl
Normal file
65
src/shaders/water_rays.hlsl
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
#define RAY_STEPS 16.0
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 coord : TEXCOORD0;
|
||||||
|
float3 viewVec : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
Out.coord = In.aCoord.xyz + uParam.xyz;
|
||||||
|
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
|
||||||
|
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
float boxIntersect(float3 rayPos, float3 rayDir, float3 center, float3 hsize) {
|
||||||
|
center -= rayPos;
|
||||||
|
float3 bMin = (center - hsize) / rayDir;
|
||||||
|
float3 bMax = (center + hsize) / rayDir;
|
||||||
|
float3 m = min(bMin, bMax);
|
||||||
|
return max(0.0, max(m.x, max(m.y, m.z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _GAPI_GXM
|
||||||
|
float4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float2 pixelCoord = float2(__pixel_x(), __pixel_y());
|
||||||
|
#else
|
||||||
|
float4 main(VS_OUTPUT In, float2 pixelCoord: VPOS) : COLOR0 {
|
||||||
|
#endif
|
||||||
|
float3 viewVec = normalize(In.viewVec);
|
||||||
|
|
||||||
|
float t = boxIntersect(uViewPos.xyz, -viewVec, uPosScale[0].xyz, uPosScale[1].xyz);
|
||||||
|
|
||||||
|
float3 p0 = uViewPos.xyz - viewVec * t;
|
||||||
|
float3 p1 = In.coord.xyz;
|
||||||
|
|
||||||
|
float dither = tex2Dlod(sMask, float4(pixelCoord * (1.0 / 8.0), 0.0, 0.0)).x;
|
||||||
|
|
||||||
|
float3 delta = (p1 - p0) / RAY_STEPS;
|
||||||
|
float3 pos = p0 + delta * dither;
|
||||||
|
|
||||||
|
float sum = 0.0;
|
||||||
|
for (float i = 0.0; i < RAY_STEPS; i++) {
|
||||||
|
float3 wpos = (pos - uPosScale[0].xyz) / uPosScale[1].xyz;
|
||||||
|
float2 tc = wpos.xz * 0.5 + 0.5;
|
||||||
|
float light = tex2Dlod(sReflect, float4(tc, 0, 0)).x;
|
||||||
|
sum += light * (1.0 - (clamp(wpos.y, -1.0, 1.0) * 0.5 + 0.5));
|
||||||
|
pos += delta;
|
||||||
|
}
|
||||||
|
sum /= RAY_STEPS;
|
||||||
|
sum *= uParam.w;
|
||||||
|
|
||||||
|
return float4(UNDERWATER_COLOR * sum, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
63
src/shaders/water_simulate.hlsl
Normal file
63
src/shaders/water_simulate.hlsl
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include "common.hlsl"
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float2 texCoord : TEXCOORD0;
|
||||||
|
float2 maskCoord : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
float2 getInvUV(float2 uv, float4 param) {
|
||||||
|
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
|
||||||
|
#ifndef _GAPI_GXM
|
||||||
|
p.xy += 0.5 * param.xy;
|
||||||
|
#endif
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 getUV(float2 uv, float4 param) {
|
||||||
|
return (uv.xy * 0.5 + 0.5) * param.zw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
VS_OUTPUT main(VS_INPUT In) {
|
||||||
|
VS_OUTPUT Out;
|
||||||
|
|
||||||
|
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
|
||||||
|
|
||||||
|
Out.pos = float4(coord.xyz, 1.0);
|
||||||
|
Out.texCoord = getInvUV(coord.xy, uTexParam);
|
||||||
|
Out.maskCoord = getUV(coord.xy, uRoomSize);
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PIXEL
|
||||||
|
|
||||||
|
half4 main(VS_OUTPUT In) : COLOR0 {
|
||||||
|
float2 uv = In.texCoord.xy;
|
||||||
|
if (tex2Dlod(sMask, float4(In.maskCoord, 0, 0)).a < 0.5)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
half2 v = (half2)tex2Dlod(sNormal, float4(uv, 0, 0)).xy; // height, speed
|
||||||
|
|
||||||
|
float3 d = float3(float2(uTexParam.x, -uTexParam.y), 0.0);
|
||||||
|
float4 f = float4(
|
||||||
|
F2_TEX2D(sNormal, uv + d.xz).x, F2_TEX2D(sNormal, uv + d.zy).x,
|
||||||
|
F2_TEX2D(sNormal, uv - d.xz).x, F2_TEX2D(sNormal, uv - d.zy).x
|
||||||
|
);
|
||||||
|
|
||||||
|
float average = dot(f, (float4)0.25);
|
||||||
|
|
||||||
|
// integrate
|
||||||
|
const half vel = 1.4;
|
||||||
|
const half vis = 0.995;
|
||||||
|
|
||||||
|
v.y += (half)((average - v.x) * vel);
|
||||||
|
v.y *= vis;
|
||||||
|
v.x += v.y + (half)(tex2Dlod(sDiffuse, float4(uv + uParam.zw, 0, 0)).x * 2.0 - 1.0) * 0.00025;
|
||||||
|
|
||||||
|
return half4(v, 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
5
src/ui.h
5
src/ui.h
@@ -6,7 +6,10 @@
|
|||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
#define PICKUP_SHOW_TIME 5.0f
|
#define PICKUP_SHOW_TIME 5.0f
|
||||||
//#define UI_SHOW_FPS
|
|
||||||
|
#ifdef _OS_PSV
|
||||||
|
#define UI_SHOW_FPS
|
||||||
|
#endif
|
||||||
|
|
||||||
enum StringID {
|
enum StringID {
|
||||||
STR_NOT_IMPLEMENTED
|
STR_NOT_IMPLEMENTED
|
||||||
|
@@ -96,6 +96,7 @@ typedef unsigned long long uint64;
|
|||||||
|
|
||||||
#define FOURCC(str) uint32(((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) | (((uint8*)(str))[2] << 16) | (((uint8*)(str))[3] << 24) )
|
#define FOURCC(str) uint32(((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) | (((uint8*)(str))[2] << 16) | (((uint8*)(str))[3] << 24) )
|
||||||
|
|
||||||
|
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||||
#define COUNT(arr) int(sizeof(arr) / sizeof(arr[0]))
|
#define COUNT(arr) int(sizeof(arr) / sizeof(arr[0]))
|
||||||
#define OFFSETOF(T, E) ((size_t)&(((T*)0)->E))
|
#define OFFSETOF(T, E) ((size_t)&(((T*)0)->E))
|
||||||
#define TEST_BIT(arr, bit) ((arr[bit / 32] >> (bit % 32)) & 1)
|
#define TEST_BIT(arr, bit) ((arr[bit / 32] >> (bit % 32)) & 1)
|
||||||
@@ -178,6 +179,12 @@ float hermite(float x) {
|
|||||||
return x * x * (3.0f - 2.0f * x);
|
return x * x * (3.0f - 2.0f * x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float lerpHermite(float a, float b, float t) {
|
||||||
|
if (t <= 0.0f) return a;
|
||||||
|
if (t >= 1.0f) return b;
|
||||||
|
return a + (b - a) * hermite(t);
|
||||||
|
}
|
||||||
|
|
||||||
float lerp(float a, float b, float t) {
|
float lerp(float a, float b, float t) {
|
||||||
if (t <= 0.0f) return a;
|
if (t <= 0.0f) return a;
|
||||||
if (t >= 1.0f) return b;
|
if (t >= 1.0f) return b;
|
||||||
|
Reference in New Issue
Block a user