1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-04-21 03:21:51 +02:00

3DS add lighting and blob shadows

This commit is contained in:
XProger 2019-07-06 14:25:03 +03:00
parent 3850dee839
commit 23258fcf1f
8 changed files with 551 additions and 35 deletions

View File

@ -28,11 +28,32 @@ namespace GAPI {
// Shader
extern "C" {
#include "compose_shbin.h"
#include "gui_shbin.h"
#include "compose_sprite_shbin.h"
#include "compose_flash_shbin.h"
#include "compose_room_shbin.h"
#include "compose_entity_shbin.h"
#include "compose_mirror_shbin.h"
#include "shadow_entity_shbin.h"
#include "filter_upscale_shbin.h"
#include "gui_shbin.h"
#include "dummy_shbin.h"
}
#define SHADERS_LIST(E) \
E( compose_sprite ) \
E( compose_flash ) \
E( compose_room ) \
E( compose_entity ) \
E( compose_mirror ) \
E( shadow_entity ) \
E( filter_upscale ) \
E( gui ) \
E( dummy )
#define SHADER_DECL(v) DVLB_s* v;
#define SHADER_INIT(v) v = DVLB_ParseFile((u32*)v##_shbin, v##_shbin_size);
#define SHADER_FREE(v) DVLB_Free(v);
static const int bindings[uMAX] = {
94, // uFlags
0, // uParam
@ -51,13 +72,12 @@ namespace GAPI {
98, // uContacts
};
DVLB_s* compose_dvlb;
DVLB_s* filter_upscale_dvlb;
DVLB_s* gui_dvlb;
SHADERS_LIST(SHADER_DECL);
struct Shader {
shaderProgram_s program;
C3D_TexEnv env[2];
int envCount;
int32 uID[uMAX];
@ -72,9 +92,19 @@ namespace GAPI {
DVLB_s* src = NULL;
switch (pass) {
case Core::passFilter : src = filter_upscale_dvlb; break;
case Core::passGUI : src = gui_dvlb; break;
default : src = compose_dvlb;
case Core::passCompose :
switch (type) {
case 0 : src = compose_sprite; break;
case 1 : src = compose_flash; break;
case 2 : src = compose_room; break;
case 3 : src = compose_entity; break;
case 4 : src = compose_mirror; break;
}
break;
case Core::passShadow : src = shadow_entity; break;
case Core::passFilter : src = filter_upscale; break;
case Core::passGUI : src = gui; break;
default : src = dummy;
}
shaderProgramSetVsh(&program, &src->DVLE[0]);
@ -91,20 +121,28 @@ namespace GAPI {
}
rebind = true;
envCount = 0;
C3D_TexEnvInit(&env[0]);
C3D_TexEnvInit(&env[1]);
for (int i = 0; i < COUNT(env); i++) {
C3D_TexEnvInit(env + i);
}
C3D_TexEnvSrc(&env[0], C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(&env[0], C3D_Both, GPU_MODULATE);
if (Core::pass == Core::passCompose && type == 2) { // rooms
C3D_TexEnvScale(&env[0], C3D_RGB, GPU_TEVSCALE_2);
{
C3D_TexEnv *e = env + envCount;
C3D_TexEnvSrc(e, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(e, C3D_Both, GPU_MODULATE);
if (pass == Core::passCompose) {
C3D_TexEnvScale(e, C3D_RGB, GPU_TEVSCALE_2);
}
envCount++;
}
if (underwater) {
C3D_TexEnvSrc(&env[1], C3D_Both, GPU_PREVIOUS, GPU_CONSTANT, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(&env[1], C3D_Both, GPU_MODULATE);
C3D_TexEnvColor(&env[1], 0xFFE5E599); // modulate by underwater color
C3D_TexEnv *e = env + envCount;
C3D_TexEnvSrc(e, C3D_Both, GPU_PREVIOUS, GPU_CONSTANT, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(e, C3D_Both, GPU_MODULATE);
C3D_TexEnvColor(e, 0xFFE5E599); // multiply by underwater color
envCount++;
}
}
@ -123,8 +161,9 @@ namespace GAPI {
void validate() {
if (rebind) {
C3D_BindProgram(&program);
C3D_SetTexEnv(0, &env[0]);
C3D_SetTexEnv(1, &env[1]);
for (int i = 0; i < COUNT(env); i++) {
C3D_SetTexEnv(i, env + i);
}
rebind = false;
}
@ -455,31 +494,17 @@ namespace GAPI {
AttrInfo_AddLoader(&vertexAttribs, aTexCoord , GPU_SHORT , 4);
AttrInfo_AddLoader(&vertexAttribs, aColor , GPU_UNSIGNED_BYTE , 4);
AttrInfo_AddLoader(&vertexAttribs, aLight , GPU_UNSIGNED_BYTE , 4);
// default texture env params
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
C3D_TexEnvScale(env, C3D_RGB, GPU_TEVSCALE_2);
//C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR);
//C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
clearColor = 0; //0x68B0D8FF;
colorMask = GPU_WRITE_COLOR;
depthMask = GPU_WRITE_DEPTH;
// init shaders
compose_dvlb = DVLB_ParseFile((u32*)compose_shbin, compose_shbin_size);
filter_upscale_dvlb = DVLB_ParseFile((u32*)filter_upscale_shbin, filter_upscale_shbin_size);
gui_dvlb = DVLB_ParseFile((u32*)gui_shbin, gui_shbin_size);
SHADERS_LIST(SHADER_INIT);
}
void deinit() {
DVLB_Free(compose_dvlb);
DVLB_Free(filter_upscale_dvlb);
DVLB_Free(gui_dvlb);
SHADERS_LIST(SHADER_FREE);
C3D_Fini();
gfxExit();

View File

@ -0,0 +1,122 @@
; constants
.constf const0(0.0, 0.5, 1.0, 2.0)
.constf const1(0.00392156886, 3.05185094e-005, 0.00001, 0.0)
.alias ZERO const0.x
.alias HALF const0.y
.alias ONE const0.z
.alias TWO const0.w
.alias INV_BYTE const1.x
.alias INV_SHORT const1.y
.alias EPS const1.z
; uniforms
.fvec uViewProj[4]
.fvec uBasis[32*2]
.fvec uLightPos[4];
.fvec uLightColor[4];
.fvec uMaterial
.alias MAT_AMBIENT uMaterial.y
.alias MAT_ALPHA uMaterial.w
; in
.alias aCoord v0
.alias aNormal v1
.alias aTexCoord v2
.alias aColor v3
.alias aLight v4
; variables
.alias lv0 r0
.alias lv1 r1
.alias lv2 r2
.alias lv3 r3
.alias normal r4
.alias att r5
.alias light r6
.alias pos r7
.alias tmp r8
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
; joint = int(aCoord.w * 2)
mul tmp.x, TWO, aCoord.w
mova a0.x, tmp.x
; pos = mulQuatPos(uBasis[joint], aCoord)
mul pos.xyz, uBasis[a0.x], aCoord.zxyw
mad pos.xyz, aCoord, uBasis[a0.x].zxyw, -pos
mad pos.xyz, aCoord.yzxw, uBasis[a0.x].w, pos
mul tmp.xyz, uBasis[a0.x].zxyw, pos
mad pos.xyz, pos.yzxw, uBasis[a0.x].yzxw, -tmp
mad pos.xyz, pos, TWO, aCoord
add pos.xyz, uBasis[a0.x + 1], pos
mov pos.w, uBasis[a0.x + 1].w
; vPosition = uViewProj * pos
mul tmp, uViewProj[0], pos.x
mad tmp, pos.y, uViewProj[1], tmp
mad tmp, pos.z, uViewProj[2], tmp
mad vPosition, pos.w, uViewProj[3], tmp
; lighting
; lv[0..3] = (uLightPos[0..3].xyz - pos) * uLightColor[0..3].w;
add lv0.xyz, uLightPos[0], -pos
add lv1.xyz, uLightPos[1], -pos
add lv2.xyz, uLightPos[2], -pos
add lv3.xyz, uLightPos[3], -pos
mul lv0.xyz, uLightColor[0].w, lv0
mul lv1.xyz, uLightColor[1].w, lv1
mul lv2.xyz, uLightColor[2].w, lv2
mul lv3.xyz, uLightColor[3].w, lv3
; att[0..3] = dot(lv[0..3], lv[0..3])
dp3 att.x, lv0, lv0
dp3 att.y, lv1, lv1
dp3 att.z, lv2, lv2
dp3 att.w, lv3, lv3
; normalize lv[0..3]
rsq tmp, att
mul lv0.xyz, lv0, tmp.x
mul lv1.xyz, lv1, tmp.y
mul lv2.xyz, lv2, tmp.z
mul lv3.xyz, lv3, tmp.w
; att = max(0, 1 - att)
add att, ONE, -att
max att, ZERO, att
; normal = mulQuat(uBasis[joint], aNormal/32767)
mul normal, INV_SHORT, aNormal
mul pos.xyz, uBasis[a0.x], normal.zxyw
mad pos.xyz, normal, uBasis[a0.x].zxyw, -pos
mad pos.xyz, normal.yzxw, uBasis[a0.x].w, pos
mul tmp.xyz, uBasis[a0.x].zxyw, pos
mad pos.xyz, pos.yzxw, uBasis[a0.x].yzxw, -tmp
mad normal.xyz, pos, TWO, normal
; light = max(0, dot(normal, lv[0..3]))
dp3 light.x, lv0, normal
dp3 light.y, lv1, normal
dp3 light.z, lv2, normal
dp3 light.w, lv3, normal
; light = max(0, light)
max light, ZERO, light
; light *= att
mul light, light, att
; vColor = aColor/255 * material.alpha * (material.ambient + light[0..3] * uLightColor[0..3])
mul pos, INV_BYTE, aColor
mul pos, MAT_ALPHA, pos
mov tmp.xyz, MAT_AMBIENT
mov tmp.w, ONE
mad tmp.xyz, light.x, uLightColor[0], tmp
mad tmp.xyz, light.y, uLightColor[1], tmp
mad tmp.xyz, light.z, uLightColor[2], tmp
mad tmp.xyz, light.w, uLightColor[3], tmp
mul vColor, pos, tmp
; vTecCoord = aTexCoord/32767
mul vTexCoord, INV_SHORT, aTexCoord
end
.end

View File

@ -0,0 +1,70 @@
; constants
.constf const0(0.0, 0.5, 1.0, 2.0)
.constf const1(0.00392156886, 3.05185094e-005, 0.00001, 0.1)
.alias ZERO const0.x
.alias HALF const0.y
.alias ONE const0.z
.alias TWO const0.w
.alias INV_BYTE const1.x
.alias INV_SHORT const1.y
.alias EPS const1.z
; uniforms
.fvec uViewProj[4]
.fvec uBasis[2]
.fvec uMaterial
.alias MAT_DIFFUSE uMaterial.x
.alias MAT_EMISSIVE uMaterial.w
; in
.alias aCoord v0
.alias aNormal v1
.alias aTexCoord v2
.alias aColor v3
.alias aLight v4
; variables
.alias lv0 r0
.alias lv1 r1
.alias lv2 r2
.alias lv3 r3
.alias normal r4
.alias att r5
.alias light r6
.alias pos r7
.alias tmp r8
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
; pos = mulQuatPos(uBasis[0], aCoord)
mul pos.xyz, uBasis[0], aCoord.zxyw
mad pos.xyz, aCoord, uBasis[0].zxyw, -pos
mad pos.xyz, aCoord.yzxw, uBasis[0].w, pos
mul tmp.xyz, uBasis[0].zxyw, pos
mad pos.xyz, pos.yzxw, uBasis[0].yzxw, -tmp
mad pos.xyz, pos, TWO, aCoord
add pos.xyz, uBasis[1], pos
mov pos.w, uBasis[1].w
; vPosition = uViewProj * pos
mul tmp, uViewProj[0], pos.x
mad tmp, pos.y, uViewProj[1], tmp
mad tmp, pos.z, uViewProj[2], tmp
mad vPosition, pos.w, uViewProj[3], tmp
; vColor = aColor/255 * material.diffuse + material.emissive * 0.5
mul tmp, INV_BYTE, aColor
mul tmp.xyz, MAT_DIFFUSE, tmp
mov pos.xyz, MAT_EMISSIVE
mad tmp.xyz, pos, HALF, tmp
mov vColor, tmp
; vTecCoord = aTexCoord/32767
mul vTexCoord, INV_SHORT, aTexCoord
end
.end

View File

@ -0,0 +1,68 @@
; constants
.constf const0(0.0, 0.5, 1.0, 2.0)
.constf const1(0.00392156886, 3.05185094e-005, 0.00001, 0.0)
.alias ZERO const0.x
.alias HALF const0.y
.alias ONE const0.z
.alias TWO const0.w
.alias INV_BYTE const1.x
.alias INV_SHORT const1.y
.alias EPS const1.z
; uniforms
.fvec uViewProj[4]
.fvec uBasis[32*2]
.fvec uMaterial
; in
.alias aCoord v0
.alias aNormal v1
.alias aTexCoord v2
.alias aColor v3
.alias aLight v4
; variables
.alias lv0 r0
.alias lv1 r1
.alias lv2 r2
.alias lv3 r3
.alias normal r4
.alias att r5
.alias light r6
.alias pos r7
.alias tmp r8
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
; joint = int(aCoord.w * 2)
mul tmp.x, TWO, aCoord.w
mova a0.x, tmp.x
; pos = mulQuatPos(uBasis[joint], aCoord)
mul pos.xyz, uBasis[a0.x], aCoord.zxyw
mad pos.xyz, aCoord, uBasis[a0.x].zxyw, -pos
mad pos.xyz, aCoord.yzxw, uBasis[a0.x].w, pos
mul tmp.xyz, uBasis[a0.x].zxyw, pos
mad pos.xyz, pos.yzxw, uBasis[a0.x].yzxw, -tmp
mad pos.xyz, pos, TWO, aCoord
add pos.xyz, uBasis[a0.x + 1], pos
mov pos.w, uBasis[a0.x + 1].w
; vPosition = uViewProj * pos
mul tmp, uViewProj[0], pos.x
mad tmp, pos.y, uViewProj[1], tmp
mad tmp, pos.z, uViewProj[2], tmp
mad vPosition, pos.w, uViewProj[3], tmp
; vColor = uMaterial
mov vColor, uMaterial
; vTecCoord = aTexCoord/32767
mul vTexCoord, INV_SHORT, aTexCoord
end
.end

View File

@ -0,0 +1,101 @@
; constants
.constf const0(0.0, 0.5, 1.0, 2.0)
.constf const1(0.00392156886, 3.05185094e-005, 0.00001, 0.0)
.alias ZERO const0.x
.alias HALF const0.y
.alias ONE const0.z
.alias TWO const0.w
.alias INV_BYTE const1.x
.alias INV_SHORT const1.y
.alias EPS const1.z
; uniforms
.fvec uViewProj[4]
.fvec uBasis[2]
.fvec uLightPos[4];
.fvec uLightColor[4];
; in
.alias aCoord v0
.alias aNormal v1
.alias aTexCoord v2
.alias aColor v3
.alias aLight v4
; variables
.alias lv1 r1
.alias lv2 r2
.alias lv3 r3
.alias normal r4
.alias att r5
.alias light r6
.alias pos r7
.alias tmp r8
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
; pos = mulQuatPos(uBasis[0], aCoord)
mul pos.xyz, uBasis[0], aCoord.zxyw
mad pos.xyz, aCoord, uBasis[0].zxyw, -pos
mad pos.xyz, aCoord.yzxw, uBasis[0].w, pos
mul tmp.xyz, uBasis[0].zxyw, pos
mad pos.xyz, pos.yzxw, uBasis[0].yzxw, -tmp
mad pos.xyz, pos, TWO, aCoord
add pos.xyz, uBasis[1], pos
mov pos.w, ONE
; vPosition = uViewProj * pos
mul tmp, uViewProj[0], pos.x
mad tmp, pos.y, uViewProj[1], tmp
mad tmp, pos.z, uViewProj[2], tmp
mad vPosition, pos.w, uViewProj[3], tmp
; lighting
; lv[1..3] = (uLightPos[1..3].xyz - pos) * uLightColor[1..3].w;
add lv1.xyz, uLightPos[1], -pos
add lv2.xyz, uLightPos[2], -pos
add lv3.xyz, uLightPos[3], -pos
mul lv1.xyz, uLightColor[1].w, lv1
mul lv2.xyz, uLightColor[2].w, lv2
mul lv3.xyz, uLightColor[3].w, lv3
; att[1..3] = dot(lv[1..3], lv[1..3])
mov att.x, ONE
dp3 att.y, lv1, lv1
dp3 att.z, lv2, lv2
dp3 att.w, lv3, lv3
; normalize lv[1..3]
rsq tmp, att
mul lv1.xyz, lv1, tmp.y
mul lv2.xyz, lv2, tmp.z
mul lv3.xyz, lv3, tmp.w
; att = max(0, 1 - att)
add att, ONE, -att
max att, ZERO, att
; normal = aNormal/32767
mul normal, INV_SHORT, aNormal
; light = max(0, dot(normal, lv[1..3]))
mov light.x, ZERO
dp3 light.y, lv1, normal
dp3 light.z, lv2, normal
dp3 light.w, lv3, normal
max light, ZERO, light
; light *= att
mul light, light, att
; vColor = (aLight/255 + light[1..3] * uLightColor[1..3]) * aColor/255
mul pos, INV_BYTE, aColor
mul tmp, INV_BYTE, aLight
mad tmp.xyz, light.y, uLightColor[1], tmp
mad tmp.xyz, light.z, uLightColor[2], tmp
mad tmp.xyz, light.w, uLightColor[3], tmp
mul vColor, pos, tmp
; vTecCoord = aTexCoord/32767
mul vTexCoord, INV_SHORT, aTexCoord
end
.end

View File

@ -0,0 +1,116 @@
; constants
.constf const0(0.0, 0.5, 1.0, 2.0)
.constf const1(0.00392156886, 3.05185094e-005, 0.00001, 0.0)
.alias ZERO const0.x
.alias HALF const0.y
.alias ONE const0.z
.alias TWO const0.w
.alias INV_BYTE const1.x
.alias INV_SHORT const1.y
.alias EPS const1.z
; uniforms
.fvec uViewPos
.fvec uViewProj[4]
.fvec uBasis[32*2]
.fvec uLightPos[4];
.fvec uLightColor[4];
.fvec uMaterial
.alias MAT_AMBIENT uMaterial.y
.alias MAT_ALPHA uMaterial.w
; in
.alias aCoord v0
.alias aNormal v1
.alias aTexCoord v2
.alias aColor v3
.alias aLight v4
; variables
.alias lv0 r0
.alias lv1 r1
.alias lv2 r2
.alias lv3 r3
.alias normal r4
.alias att r5
.alias light r6
.alias pos r7
.alias tmp r8
.alias size r4
.alias vv r6
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
; pos = aCoord + mulQuatPos(uBasis[joint], aTexCoord.zw)
mov pos.z, ZERO
mov pos.xy, aTexCoord.zw
mul size.xyz, uBasis[0], pos.zxy
mad size.xyz, pos.xyz, uBasis[0].zxy, -size
mad size.xyz, pos.yzx, uBasis[0].w, size
mul tmp.xyz, uBasis[0].zxy, size.xyz
mad size.xyz, size.yzx, uBasis[0].yzx, -tmp
mad pos.xyz, size, TWO, pos
add size.xyz, uBasis[1], aCoord
add pos.xyz, pos, size
mov pos.w, ONE
; vPosition = uViewProj * pos
mul tmp, uViewProj[0], pos.x
mad tmp, pos.y, uViewProj[1], tmp
mad tmp, pos.z, uViewProj[2], tmp
mad vPosition, pos.w, uViewProj[3], tmp
; lighting
; lv[1..3] = (uLightPos[1..3].xyz - pos) * uLightColor[1..3].w;
add lv1.xyz, uLightPos[1], -pos
add lv2.xyz, uLightPos[2], -pos
add lv3.xyz, uLightPos[3], -pos
mul lv1.xyz, uLightColor[1].w, lv1
mul lv2.xyz, uLightColor[2].w, lv2
mul lv3.xyz, uLightColor[3].w, lv3
; att[1..3] = dot(lv[1..3], lv[1..3])
mov att.x, ONE
dp3 att.y, lv1, lv1
dp3 att.z, lv2, lv2
dp3 att.w, lv3, lv3
; normalize lv[1..3]
rsq tmp, att
mul lv1.xyz, lv1, tmp.y
mul lv2.xyz, lv2, tmp.z
mul lv3.xyz, lv3, tmp.w
; att = max(0, 1 - att)
add att, ONE, -att
max att, ZERO, att
; viewVec = uViewPos - pos
add vv.xyz, uViewPos, -pos
; normal = normalize(viewVec)
dp3 tmp.x, vv, vv
rsq tmp.x, tmp.x
mul normal, vv, tmp.x
; light = max(0, dot(normal, lv[1..3]))
mov light.x, MAT_AMBIENT
dp3 light.y, lv1, normal
dp3 light.z, lv2, normal
dp3 light.w, lv3, normal
max light, ZERO, light
; light *= att
mul light, light, att
; vColor = vec4(aLight.rgb * aLight.a, aLight.a)
mul tmp, INV_BYTE, aLight
mad tmp.xyz, light.x, uLightColor[0], tmp
mad tmp.xyz, light.y, uLightColor[1], tmp
mad tmp.xyz, light.z, uLightColor[2], tmp
mad tmp.xyz, light.w, uLightColor[3], tmp
mul tmp.xyz, tmp, tmp.w
mov vColor, tmp
; vTecCoord = aTexCoord/32767
mul vTexCoord, INV_SHORT, aTexCoord
end
.end

View File

@ -0,0 +1,14 @@
; constants
.constf const0(0.0, 0.0, 0.0, 0.0)
; out
.out vPosition position
.out vTexCoord texcoord0
.out vColor color
.proc main
mov vPosition, const0.xxxx
mov vTexCoord, const0.xxxx
mov vColor, const0.xxxx
end
.end