Several changes

- Make the weapons selector fixed in place, doesn't move with the head yaw now which is more comfortable
- Removed a lot of the stuff being copied on start-up into a single pakQ3Q.pk3 file for ease
This commit is contained in:
Simon 2022-03-08 22:29:26 +00:00
parent a156e3cc1b
commit a155e985be
42 changed files with 2662 additions and 73 deletions

View file

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.ioq3quest" package="com.drbeef.ioq3quest"
android:installLocation="preferExternal" android:installLocation="preferExternal"
android:versionCode="27" android:versionCode="28"
android:versionName="0.19.1"> android:versionName="0.20.0">
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" /> <uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" /> <uses-feature android:glEsVersion="0x00030001" />
<!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>--> <!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>-->

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -620,6 +620,7 @@ typedef struct {
int weaponHolsterSelection; int weaponHolsterSelection;
int weaponHolsterTime; int weaponHolsterTime;
float weaponHolsterYaw;
// blend blobs // blend blobs
float damageTime; float damageTime;
@ -1390,6 +1391,7 @@ void CG_HolsterSelect_f( void );
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out); void rotateAboutOrigin(float x, float y, float rotation, vec2_t out);
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles ); void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void CG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles );
void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out); void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
void CG_RegisterWeapon( int weaponNum ); void CG_RegisterWeapon( int weaponNum );

View file

@ -1049,7 +1049,8 @@ static void CG_RegisterGraphics( void ) {
cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" ); cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" );
cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" ); cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" );
cgs.media.reticleShader = trap_R_RegisterShader( "scope.tga" ); //Load from pakQ3Q
cgs.media.reticleShader = trap_R_RegisterShader( "gfx/weapon/scope" );
//Used for the weapon selector //Used for the weapon selector
cgs.media.smallSphereModel = trap_R_RegisterModel("models/powerups/health/small_sphere.md3"); cgs.media.smallSphereModel = trap_R_RegisterModel("models/powerups/health/small_sphere.md3");

View file

@ -2026,6 +2026,7 @@ void CG_DrawHolsteredWeapons( void )
if (cg.weaponHolsterTime == 0) if (cg.weaponHolsterTime == 0)
{ {
cg.weaponHolsterTime = cg.time; cg.weaponHolsterTime = cg.time;
cg.weaponHolsterYaw = vr->hmdorientation[YAW];
} }
int j = 0; int j = 0;
@ -2040,34 +2041,37 @@ void CG_DrawHolsteredWeapons( void )
} }
} }
const float SCALE = 0.1f; float SCALE = 0.05f;
const float DIST = 10.0f; const float DIST = 9.0f;
const float SEP = 14.0f; const float SEP = 16.0f;
cg.weaponHolsterSelection = WP_NONE; cg.weaponHolsterSelection = WP_NONE;
vec3_t weaponOrigin, weaponAngles; vec3_t controllerOrigin, controllerAngles;
CG_CalculateVRWeaponPosition(weaponOrigin, weaponAngles); CG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles);
{ {
refEntity_t blob; refEntity_t blob;
memset( &blob, 0, sizeof( blob ) ); memset( &blob, 0, sizeof( blob ) );
VectorCopy( weaponOrigin, blob.origin ); VectorCopy( controllerOrigin, blob.origin );
AnglesToAxis(weaponAngles, blob.axis); AnglesToAxis(vec3_origin, blob.axis);
VectorScale( blob.axis[0], 0.07f, blob.axis[0] ); VectorScale( blob.axis[0], 0.045f, blob.axis[0] );
VectorScale( blob.axis[1], 0.07f, blob.axis[1] ); VectorScale( blob.axis[1], 0.045f, blob.axis[1] );
VectorScale( blob.axis[2], 0.07f, blob.axis[2] ); VectorScale( blob.axis[2], 0.045f, blob.axis[2] );
blob.nonNormalizedAxes = qtrue; blob.nonNormalizedAxes = qtrue;
blob.hModel = cgs.media.smallSphereModel; blob.hModel = cgs.media.smallSphereModel;
trap_R_AddRefEntityToScene( &blob ); trap_R_AddRefEntityToScene( &blob );
} }
vec3_t viewangles, vieworg; vec3_t viewangles, vieworg, viewForward, viewRight, viewUp;
VectorCopy(cg.refdefViewAngles, viewangles); VectorCopy(cg.refdefViewAngles, viewangles);
VectorCopy(cg.refdef.vieworg, vieworg); VectorCopy(cg.refdef.vieworg, vieworg);
VectorCopy(vr->hmdorientation, viewangles);
viewangles[YAW] = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]) +
vr->clientviewangles[YAW] - vr->hmdorientation[YAW] + cg.weaponHolsterYaw;
if (!cgs.localServer) if (!cgs.localServer)
{ {
VectorCopy(vr->hmdorientation, viewangles);
viewangles[YAW] = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]) + vr->clientviewangles[YAW];
vec3_t pos, hmdposition; vec3_t pos, hmdposition;
VectorClear(pos); VectorClear(pos);
VectorSubtract(vr->hmdposition, vr->hmdorigin, hmdposition); VectorSubtract(vr->hmdposition, vr->hmdorigin, hmdposition);
@ -2077,8 +2081,9 @@ void CG_DrawHolsteredWeapons( void )
VectorSubtract(cg.refdef.vieworg, pos, vieworg); VectorSubtract(cg.refdef.vieworg, pos, vieworg);
} }
float startingPositionYaw = viewangles[YAW] + (((j - (j&1 ? 0 : 1)) / 2.0f) * SEP); AngleVectors(viewangles, viewForward, viewRight, viewUp);
startingPositionYaw = AngleNormalize360(startingPositionYaw);
float startingPositionYaw = AngleNormalize360(viewangles[YAW] + (((j-1)/2.0f) * SEP));
for (int w = j-1; w >= 0; --w) for (int w = j-1; w >= 0; --w)
{ {
if ( cg_weapons[ weapons[w] ].item ) { if ( cg_weapons[ weapons[w] ].item ) {
@ -2089,7 +2094,7 @@ void CG_DrawHolsteredWeapons( void )
vec3_t forward; vec3_t forward;
AngleVectors(angles, forward, NULL, NULL); AngleVectors(angles, forward, NULL, NULL);
int dist = (cg.time - cg.weaponHolsterTime) / 10; float dist = (cg.time - cg.weaponHolsterTime) / 10;
if (dist > DIST) dist = DIST; if (dist > DIST) dist = DIST;
VectorMA(vieworg, dist, forward, iconOrigin); VectorMA(vieworg, dist, forward, iconOrigin);
VectorMA(vieworg, dist+0.01f, forward, iconBackground); VectorMA(vieworg, dist+0.01f, forward, iconBackground);
@ -2101,13 +2106,14 @@ void CG_DrawHolsteredWeapons( void )
iconBackground[2] += (vr->hmdposition[1] * 0.85f) * worldscale; iconBackground[2] += (vr->hmdposition[1] * 0.85f) * worldscale;
//Float sprite above selected weapon //Float sprite above selected weapon
qboolean selected = qfalse; vec3_t diff;
vec3_t length; VectorSubtract(controllerOrigin, iconOrigin, diff);
VectorSubtract(weaponOrigin, iconOrigin, length); float length = VectorLength(diff);
if (VectorLength(length) <= 1.75f && dist == DIST) if (length <= 1.5f &&
dist == DIST &&
cg.weaponHolsterSelection == WP_NONE)
{ {
cg.weaponHolsterSelection = weapons[w]; cg.weaponHolsterSelection = weapons[w];
selected = qtrue;
refEntity_t sprite; refEntity_t sprite;
memset( &sprite, 0, sizeof( sprite ) ); memset( &sprite, 0, sizeof( sprite ) );
@ -2129,6 +2135,21 @@ void CG_DrawHolsteredWeapons( void )
memset(&ent, 0, sizeof(ent)); memset(&ent, 0, sizeof(ent));
VectorCopy(iconOrigin, ent.origin); VectorCopy(iconOrigin, ent.origin);
//Shift the weapon model a bit to be in the sphere
if (weapons[w] == WP_GAUNTLET)
{
SCALE = 0.065f;
VectorMA(ent.origin, 0.3f, viewUp, ent.origin);
VectorMA(ent.origin, 0.15f, viewRight, ent.origin);
VectorMA(ent.origin, -0.15f, viewForward, ent.origin);
}
else
{
VectorMA(ent.origin, 0.3f, viewForward, ent.origin);
VectorMA(ent.origin, -0.2f, viewRight, ent.origin);
VectorMA(ent.origin, 0.5f, viewUp, ent.origin);
}
vec3_t iconAngles; vec3_t iconAngles;
VectorCopy(viewangles, iconAngles); VectorCopy(viewangles, iconAngles);
iconAngles[YAW] -= 145.0f; iconAngles[YAW] -= 145.0f;
@ -2137,9 +2158,9 @@ void CG_DrawHolsteredWeapons( void )
iconAngles[ROLL] -= 90.0f; iconAngles[ROLL] -= 90.0f;
} }
AnglesToAxis(iconAngles, ent.axis); AnglesToAxis(iconAngles, ent.axis);
VectorScale(ent.axis[0], SCALE + (selected ? 0.04f : 0), ent.axis[0]); VectorScale(ent.axis[0], SCALE + (cg.weaponHolsterSelection == weapons[w] ? 0.04f : 0), ent.axis[0]);
VectorScale(ent.axis[1], SCALE + (selected ? 0.04f : 0), ent.axis[1]); VectorScale(ent.axis[1], SCALE + (cg.weaponHolsterSelection == weapons[w] ? 0.04f : 0), ent.axis[1]);
VectorScale(ent.axis[2], SCALE + (selected ? 0.04f : 0), ent.axis[2]); VectorScale(ent.axis[2], SCALE + (cg.weaponHolsterSelection == weapons[w] ? 0.04f : 0), ent.axis[2]);
ent.nonNormalizedAxes = qtrue; ent.nonNormalizedAxes = qtrue;
if( weapons[w] == WP_RAILGUN ) { if( weapons[w] == WP_RAILGUN ) {
@ -2156,6 +2177,23 @@ void CG_DrawHolsteredWeapons( void )
} }
} }
//Wrap weapon in a small sphere
{
refEntity_t blob;
memset( &blob, 0, sizeof( blob ) );
VectorCopy( iconOrigin, blob.origin );
AnglesToAxis(vec3_origin, blob.axis);
VectorScale( blob.axis[0], 0.1f + (cg.weaponHolsterSelection == weapons[w] ? 0.035f : 0), blob.axis[0] );
VectorScale( blob.axis[1], 0.1f + (cg.weaponHolsterSelection == weapons[w] ? 0.035f : 0), blob.axis[1] );
VectorScale( blob.axis[2], 0.1f + (cg.weaponHolsterSelection == weapons[w] ? 0.035f : 0), blob.axis[2] );
blob.nonNormalizedAxes = qtrue;
blob.hModel = cgs.media.smallSphereModel;
blob.shaderRGBA[0] = 255;
blob.shaderRGBA[1] = 255;
blob.shaderRGBA[2] = 255;
blob.shaderRGBA[3] = 80;
trap_R_AddRefEntityToScene( &blob );
}
ent.hModel = cg_weapons[weapons[w]].weaponModel; ent.hModel = cg_weapons[weapons[w]].weaponModel;
trap_R_AddRefEntityToScene(&ent); trap_R_AddRefEntityToScene(&ent);
@ -2182,7 +2220,7 @@ void CG_DrawHolsteredWeapons( void )
VectorCopy( iconOrigin, sprite.origin ); VectorCopy( iconOrigin, sprite.origin );
sprite.reType = RT_SPRITE; sprite.reType = RT_SPRITE;
sprite.customShader = cg_weapons[weapons[w]].weaponIcon; sprite.customShader = cg_weapons[weapons[w]].weaponIcon;
sprite.radius = 0.6f + (selected ? 0.1f : 0); sprite.radius = 0.6f + (cg.weaponHolsterSelection == weapons[w] ? 0.1f : 0);
sprite.shaderRGBA[0] = 255; sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255; sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255; sprite.shaderRGBA[2] = 255;
@ -2192,7 +2230,7 @@ void CG_DrawHolsteredWeapons( void )
//And now the selection background //And now the selection background
VectorCopy( iconBackground, sprite.origin ); VectorCopy( iconBackground, sprite.origin );
sprite.customShader = cgs.media.selectShader; sprite.customShader = cgs.media.selectShader;
sprite.radius = 0.7f + (selected ? 0.1f : 0); sprite.radius = 0.7f + (cg.weaponHolsterSelection == weapons[w] ? 0.1f : 0);
sprite.shaderRGBA[0] = 255; sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255; sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255; sprite.shaderRGBA[2] = 255;

View file

@ -82,34 +82,6 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
} }
} }
public static void unzip(File zipFile, File targetDirectory) throws IOException {
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(new FileInputStream(zipFile)));
try {
ZipEntry ze;
int count;
byte[] buffer = new byte[8192];
while ((ze = zis.getNextEntry()) != null) {
File file = new File(targetDirectory, ze.getName());
File dir = ze.isDirectory() ? file : file.getParentFile();
if (!dir.isDirectory() && !dir.mkdirs())
throw new FileNotFoundException("Failed to ensure directory: " +
dir.getAbsolutePath());
if (ze.isDirectory())
continue;
FileOutputStream fout = new FileOutputStream(file);
try {
while ((count = zis.read(buffer)) != -1)
fout.write(buffer, 0, count);
} finally {
fout.close();
}
}
} finally {
zis.close();
}
}
public void create() throws IOException { public void create() throws IOException {
//Make the directories //Make the directories
new File("/sdcard/ioquake3Quest/baseq3").mkdirs(); new File("/sdcard/ioquake3Quest/baseq3").mkdirs();
@ -123,21 +95,9 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
//copy demo //copy demo
copy_asset("/sdcard/ioquake3Quest/baseq3", "pak0.pk3", false); copy_asset("/sdcard/ioquake3Quest/baseq3", "pak0.pk3", false);
//Scope //our special pak file
copy_asset("/sdcard/ioquake3Quest/baseq3", "scope.tga", false); copy_asset("/sdcard/ioquake3Quest/baseq3", "pakQ3Q.pk3", true);
copy_asset("/sdcard/ioquake3Quest/missionpack", "pakQ3Q.pk3", true);
//glsl
copy_asset("/sdcard/ioquake3Quest", "glsl.zip", true);
new File("/sdcard/ioquake3Quest/baseq3/glsl").mkdirs();
unzip(new File("/sdcard/ioquake3Quest/glsl.zip"), new File("/sdcard/ioquake3Quest/baseq3/glsl"));
new File("/sdcard/ioquake3Quest/missionpack/glsl").mkdirs();
unzip(new File("/sdcard/ioquake3Quest/glsl.zip"), new File("/sdcard/ioquake3Quest/missionpack/glsl"));
copy_asset("/sdcard/ioquake3Quest", "ui.zip", true);
unzip(new File("/sdcard/ioquake3Quest/ui.zip"), new File("/sdcard/ioquake3Quest/missionpack"));
new File("/sdcard/ioquake3Quest/glsl.zip").delete();
new File("/sdcard/ioquake3Quest/ui.zip").delete();
//Read these from a file and pass through //Read these from a file and pass through
commandLineParams = new String(); commandLineParams = new String();

View file

@ -0,0 +1,84 @@
uniform sampler2D u_TextureMap;
uniform vec4 u_Color;
uniform vec2 u_InvTexRes;
varying vec2 var_TexCoords;
void main()
{
vec4 color;
vec2 tc;
#if 0
float c[7];
c[0] = 1.0;
c[1] = 0.9659258263;
c[2] = 0.8660254038;
c[3] = 0.7071067812;
c[4] = 0.5;
c[5] = 0.2588190451;
c[6] = 0.0;
tc = var_TexCoords + u_InvTexRes * vec2( c[0], c[6]); color = texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[1], c[5]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[2], c[4]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[3], c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[4], c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[5], c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[6], c[0]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[1], -c[5]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[2], -c[4]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[3], -c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[4], -c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[5], -c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[6], -c[0]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[0], c[6]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[1], c[5]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[2], c[4]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[3], c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[4], c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[5], c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[1], -c[5]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[2], -c[4]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[3], -c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[4], -c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[5], -c[1]); color += texture2D(u_TextureMap, tc);
gl_FragColor = color * 0.04166667 * u_Color;
#endif
float c[5];
c[0] = 1.0;
c[1] = 0.9238795325;
c[2] = 0.7071067812;
c[3] = 0.3826834324;
c[4] = 0.0;
tc = var_TexCoords + u_InvTexRes * vec2( c[0], c[4]); color = texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[1], c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[2], c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[3], c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[4], c[0]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[1], -c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[2], -c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[3], -c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( c[4], -c[0]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[0], c[4]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[1], c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[2], c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[3], c[1]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[1], -c[3]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[2], -c[2]); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( -c[3], -c[1]); color += texture2D(u_TextureMap, tc);
gl_FragColor = color * 0.0625 * u_Color;
}

View file

@ -0,0 +1,13 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec2 var_TexCoords;
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_TexCoords = attr_TexCoord0.st;
}

View file

@ -0,0 +1,60 @@
uniform sampler2D u_TextureMap;
uniform vec4 u_Color;
uniform vec2 u_InvTexRes;
varying vec2 var_TexCoords;
const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.587, 0.114);
vec3 GetValues(vec2 offset, vec3 current)
{
vec2 tc = var_TexCoords + u_InvTexRes * offset;
vec3 minAvgMax = texture2D(u_TextureMap, tc).rgb;
#ifdef FIRST_PASS
#if defined(USE_PBR)
minAvgMax *= minAvgMax;
#endif
float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);
float loglumi = clamp(log2(lumi), -10.0, 10.0);
minAvgMax = vec3(loglumi * 0.05 + 0.5);
#endif
return vec3(min(current.x, minAvgMax.x), current.y + minAvgMax.y, max(current.z, minAvgMax.z));
}
void main()
{
vec3 current = vec3(1.0, 0.0, 0.0);
#ifdef FIRST_PASS
current = GetValues(vec2( 0.0, 0.0), current);
#else
current = GetValues(vec2(-1.5, -1.5), current);
current = GetValues(vec2(-0.5, -1.5), current);
current = GetValues(vec2( 0.5, -1.5), current);
current = GetValues(vec2( 1.5, -1.5), current);
current = GetValues(vec2(-1.5, -0.5), current);
current = GetValues(vec2(-0.5, -0.5), current);
current = GetValues(vec2( 0.5, -0.5), current);
current = GetValues(vec2( 1.5, -0.5), current);
current = GetValues(vec2(-1.5, 0.5), current);
current = GetValues(vec2(-0.5, 0.5), current);
current = GetValues(vec2( 0.5, 0.5), current);
current = GetValues(vec2( 1.5, 0.5), current);
current = GetValues(vec2(-1.5, 1.5), current);
current = GetValues(vec2(-0.5, 1.5), current);
current = GetValues(vec2( 0.5, 1.5), current);
current = GetValues(vec2( 1.5, 1.5), current);
current.y *= 0.0625;
#endif
gl_FragColor = vec4(current, 1.0);
}

View file

@ -0,0 +1,13 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec2 var_TexCoords;
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_TexCoords = attr_TexCoord0.st;
}

View file

@ -0,0 +1,88 @@
uniform sampler2D u_ScreenImageMap;
uniform sampler2D u_ScreenDepthMap;
uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex;
//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
//float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
//float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
//float gauss[3] = float[3](0.60, 0.19, 0.0066);
#define BLUR_SIZE 4
#if !defined(USE_DEPTH)
//#define USE_GAUSS
#endif
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
float sampleZDivW = texture2D(depthMap, tex).r;
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
{
float gauss[4];
gauss[0] = 0.40;
gauss[1] = 0.24;
gauss[2] = 0.054;
gauss[3] = 0.0044;
#if defined(USE_DEPTH)
float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
#endif
#if defined(USE_HORIZONTAL_BLUR)
vec2 direction = vec2(scale.x * 2.0, 0.0);
vec2 nudge = vec2(0.0, scale.y * 0.5);
#else // if defined(USE_VERTICAL_BLUR)
vec2 direction = vec2(0.0, scale.y * 2.0);
vec2 nudge = vec2(-scale.x * 0.5, 0.0);
#endif
#if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0];
float total = gauss[0];
#else
vec4 result = texture2D(imageMap, tex);
float total = 1.0;
#endif
float zLimit = 5.0 / zFar;
int i, j;
for (i = 0; i < 2; i++)
{
for (j = 1; j < BLUR_SIZE; j++)
{
vec2 offset = direction * (float(j) - 0.25) + nudge;
#if defined(USE_DEPTH)
float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
float depthExpected = depthCenter + dot(slope, offset);
float useSample = float(abs(depthSample - depthExpected) < zLimit);
#else
float useSample = 1.0;
#endif
#if defined(USE_GAUSS)
result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
total += gauss[j] * useSample;
#else
result += texture2D(imageMap, tex + offset) * useSample;
total += useSample;
#endif
nudge = -nudge;
}
direction = -direction;
nudge = -nudge;
}
return result / total;
}
void main()
{
gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
}

View file

@ -0,0 +1,16 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex;
void main()
{
gl_Position = attr_Position;
vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0);
var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw;
//vec2 screenCoords = gl_Position.xy / gl_Position.w;
//var_ScreenTex = screenCoords * 0.5 + 0.5;
}

View file

@ -0,0 +1,32 @@
uniform sampler2D u_DiffuseMap;
uniform int u_AlphaTest;
varying vec2 var_Tex1;
varying vec4 var_Color;
void main()
{
vec4 color = texture2D(u_DiffuseMap, var_Tex1);
float alpha = color.a * var_Color.a;
if (u_AlphaTest == 1)
{
if (alpha == 0.0)
discard;
}
else if (u_AlphaTest == 2)
{
if (alpha >= 0.5)
discard;
}
else if (u_AlphaTest == 3)
{
if (alpha < 0.5)
discard;
}
gl_FragColor.rgb = color.rgb * var_Color.rgb;
gl_FragColor.a = alpha;
}

View file

@ -0,0 +1,92 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
attribute vec3 attr_Normal;
uniform vec4 u_DlightInfo;
#if defined(USE_DEFORM_VERTEXES)
uniform int u_DeformGen;
uniform float u_DeformParams[5];
uniform float u_Time;
#endif
uniform vec4 u_Color;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec2 var_Tex1;
varying vec4 var_Color;
#if defined(USE_DEFORM_VERTEXES)
vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
{
if (u_DeformGen == 0)
{
return pos;
}
float base = u_DeformParams[0];
float amplitude = u_DeformParams[1];
float phase = u_DeformParams[2];
float frequency = u_DeformParams[3];
float spread = u_DeformParams[4];
if (u_DeformGen == DGEN_BULGE)
{
phase *= st.x;
}
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
{
phase += dot(pos.xyz, vec3(spread));
}
float value = phase + (u_Time * frequency);
float func;
if (u_DeformGen == DGEN_WAVE_SIN)
{
func = sin(value * 2.0 * M_PI);
}
else if (u_DeformGen == DGEN_WAVE_SQUARE)
{
func = sign(0.5 - fract(value));
}
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
{
func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
}
else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
{
func = fract(value);
}
else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
{
func = (1.0 - fract(value));
}
else // if (u_DeformGen == DGEN_BULGE)
{
func = sin(value);
}
return pos + normal * (base + func * amplitude);
}
#endif
void main()
{
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#if defined(USE_DEFORM_VERTEXES)
position = DeformPosition(position, normal, attr_TexCoord0.st);
#endif
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
vec3 dist = u_DlightInfo.xyz - position;
var_Tex1 = dist.xy * u_DlightInfo.a + vec2(0.5);
float dlightmod = step(0.0, dot(dist, normal));
dlightmod *= clamp(2.0 * (1.0 - abs(dist.z) * u_DlightInfo.a), 0.0, 1.0);
var_Color = u_Color * dlightmod;
}

View file

@ -0,0 +1,34 @@
uniform sampler2D u_TextureMap;
uniform vec2 u_InvTexRes;
varying vec2 var_TexCoords;
void main()
{
vec4 color;
vec2 tc;
tc = var_TexCoords + u_InvTexRes * vec2(-1.5, -1.5); color = texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-0.5, -1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 0.5, -1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 1.5, -1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-1.5, -0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-0.5, -0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 0.5, -0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 1.5, -0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-1.5, 0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-0.5, 0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 0.5, 0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 1.5, 0.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-1.5, 1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2(-0.5, 1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 0.5, 1.5); color += texture2D(u_TextureMap, tc);
tc = var_TexCoords + u_InvTexRes * vec2( 1.5, 1.5); color += texture2D(u_TextureMap, tc);
color *= 0.0625;
gl_FragColor = color;
}

View file

@ -0,0 +1,13 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec2 var_TexCoords;
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_TexCoords = attr_TexCoord0.st;
}

View file

@ -0,0 +1,9 @@
uniform vec4 u_Color;
varying float var_Scale;
void main()
{
gl_FragColor = u_Color;
gl_FragColor.a = sqrt(clamp(var_Scale, 0.0, 1.0));
}

View file

@ -0,0 +1,131 @@
attribute vec3 attr_Position;
attribute vec3 attr_Normal;
attribute vec4 attr_TexCoord0;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif
uniform vec4 u_FogDistance;
uniform vec4 u_FogDepth;
uniform float u_FogEyeT;
#if defined(USE_DEFORM_VERTEXES)
uniform int u_DeformGen;
uniform float u_DeformParams[5];
#endif
uniform float u_Time;
uniform mat4 u_ModelViewProjectionMatrix;
#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif
uniform vec4 u_Color;
varying float var_Scale;
#if defined(USE_DEFORM_VERTEXES)
vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
{
if (u_DeformGen == 0)
{
return pos;
}
float base = u_DeformParams[0];
float amplitude = u_DeformParams[1];
float phase = u_DeformParams[2];
float frequency = u_DeformParams[3];
float spread = u_DeformParams[4];
if (u_DeformGen == DGEN_BULGE)
{
phase *= st.x;
}
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
{
phase += dot(pos.xyz, vec3(spread));
}
float value = phase + (u_Time * frequency);
float func;
if (u_DeformGen == DGEN_WAVE_SIN)
{
func = sin(value * 2.0 * M_PI);
}
else if (u_DeformGen == DGEN_WAVE_SQUARE)
{
func = sign(0.5 - fract(value));
}
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
{
func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
}
else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
{
func = fract(value);
}
else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
{
func = (1.0 - fract(value));
}
else // if (u_DeformGen == DGEN_BULGE)
{
func = sin(value);
}
return pos + normal * (base + func * amplitude);
}
#endif
float CalcFog(vec3 position)
{
float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
float t = dot(vec4(position, 1.0), u_FogDepth);
float eyeOutside = float(u_FogEyeT < 0.0);
float fogged = float(t >= eyeOutside);
t += 1e-6;
t *= fogged / (t - u_FogEyeT * eyeOutside);
return s * t;
}
void main()
{
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));
vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#endif
#if defined(USE_DEFORM_VERTEXES)
position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
#endif
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
var_Scale = CalcFog(position) * u_Color.a * u_Color.a;
}

View file

@ -0,0 +1,33 @@
uniform sampler2D u_DiffuseMap;
uniform int u_AlphaTest;
varying vec2 var_DiffuseTex;
varying vec4 var_Color;
void main()
{
vec4 color = texture2D(u_DiffuseMap, var_DiffuseTex);
float alpha = color.a * var_Color.a;
if (u_AlphaTest == 1)
{
if (alpha == 0.0)
discard;
}
else if (u_AlphaTest == 2)
{
if (alpha >= 0.5)
discard;
}
else if (u_AlphaTest == 3)
{
if (alpha < 0.5)
discard;
}
gl_FragColor.rgb = color.rgb * var_Color.rgb;
gl_FragColor.a = alpha;
}

View file

@ -0,0 +1,253 @@
attribute vec3 attr_Position;
attribute vec3 attr_Normal;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif
attribute vec4 attr_Color;
attribute vec4 attr_TexCoord0;
#if defined(USE_TCGEN)
attribute vec4 attr_TexCoord1;
#endif
uniform vec4 u_DiffuseTexMatrix;
uniform vec4 u_DiffuseTexOffTurb;
#if defined(USE_TCGEN) || defined(USE_RGBAGEN)
uniform vec3 u_LocalViewOrigin;
#endif
#if defined(USE_TCGEN)
uniform int u_TCGen0;
uniform vec3 u_TCGen0Vector0;
uniform vec3 u_TCGen0Vector1;
#endif
#if defined(USE_FOG)
uniform vec4 u_FogDistance;
uniform vec4 u_FogDepth;
uniform float u_FogEyeT;
uniform vec4 u_FogColorMask;
#endif
#if defined(USE_DEFORM_VERTEXES)
uniform int u_DeformGen;
uniform float u_DeformParams[5];
uniform float u_Time;
#endif
uniform mat4 u_ModelViewProjectionMatrix;
uniform vec4 u_BaseColor;
uniform vec4 u_VertColor;
#if defined(USE_RGBAGEN)
uniform int u_ColorGen;
uniform int u_AlphaGen;
uniform vec3 u_AmbientLight;
uniform vec3 u_DirectedLight;
uniform vec3 u_ModelLightDir;
uniform float u_PortalRange;
#endif
#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif
varying vec2 var_DiffuseTex;
varying vec4 var_Color;
#if defined(USE_DEFORM_VERTEXES)
vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
{
float base = u_DeformParams[0];
float amplitude = u_DeformParams[1];
float phase = u_DeformParams[2];
float frequency = u_DeformParams[3];
float spread = u_DeformParams[4];
if (u_DeformGen == DGEN_BULGE)
{
phase *= st.x;
}
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
{
phase += dot(pos.xyz, vec3(spread));
}
float value = phase + (u_Time * frequency);
float func;
if (u_DeformGen == DGEN_WAVE_SIN)
{
func = sin(value * 2.0 * M_PI);
}
else if (u_DeformGen == DGEN_WAVE_SQUARE)
{
func = sign(fract(0.5 - value));
}
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
{
func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
}
else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
{
func = fract(value);
}
else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
{
func = (1.0 - fract(value));
}
else // if (u_DeformGen == DGEN_BULGE)
{
func = sin(value);
}
return pos + normal * (base + func * amplitude);
}
#endif
#if defined(USE_TCGEN)
vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 TCGenVector1)
{
vec2 tex = attr_TexCoord0.st;
if (TCGen == TCGEN_LIGHTMAP)
{
tex = attr_TexCoord1.st;
}
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
{
vec3 viewer = normalize(u_LocalViewOrigin - position);
vec2 ref = reflect(viewer, normal).yz;
tex.s = ref.x * -0.5 + 0.5;
tex.t = ref.y * 0.5 + 0.5;
}
else if (TCGen == TCGEN_VECTOR)
{
tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
}
return tex;
}
#endif
#if defined(USE_TCMOD)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
{
float amplitude = offTurb.z;
float phase = offTurb.w * 2.0 * M_PI;
vec2 st2;
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
vec2 offsetPos = vec2(position.x + position.z, position.y);
vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
return st2 + texOffset * amplitude;
}
#endif
#if defined(USE_RGBAGEN)
vec4 CalcColor(vec3 position, vec3 normal)
{
vec4 color = u_VertColor * attr_Color + u_BaseColor;
if (u_ColorGen == CGEN_LIGHTING_DIFFUSE)
{
float incoming = clamp(dot(normal, u_ModelLightDir), 0.0, 1.0);
color.rgb = clamp(u_DirectedLight * incoming + u_AmbientLight, 0.0, 1.0);
}
vec3 viewer = u_LocalViewOrigin - position;
if (u_AlphaGen == AGEN_LIGHTING_SPECULAR)
{
vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position);
vec3 reflected = -reflect(lightDir, normal);
color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0);
color.a *= color.a;
color.a *= color.a;
}
else if (u_AlphaGen == AGEN_PORTAL)
{
color.a = clamp(length(viewer) / u_PortalRange, 0.0, 1.0);
}
return color;
}
#endif
#if defined(USE_FOG)
float CalcFog(vec3 position)
{
float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
float t = dot(vec4(position, 1.0), u_FogDepth);
float eyeOutside = float(u_FogEyeT < 0.0);
float fogged = float(t >= eyeOutside);
t += 1e-6;
t *= fogged / (t - u_FogEyeT * eyeOutside);
return s * t;
}
#endif
void main()
{
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));
vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#endif
#if defined(USE_DEFORM_VERTEXES)
position = DeformPosition(position, normal, attr_TexCoord0.st);
#endif
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
#if defined(USE_TCGEN)
vec2 tex = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
#else
vec2 tex = attr_TexCoord0.st;
#endif
#if defined(USE_TCMOD)
var_DiffuseTex = ModTexCoords(tex, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
#else
var_DiffuseTex = tex;
#endif
#if defined(USE_RGBAGEN)
var_Color = CalcColor(position, normal);
#else
var_Color = u_VertColor * attr_Color + u_BaseColor;
#endif
#if defined(USE_FOG)
var_Color *= vec4(1.0) - u_FogColorMask * sqrt(clamp(CalcFog(position), 0.0, 1.0));
#endif
}

View file

@ -0,0 +1,519 @@
precision mediump sampler2D;
uniform sampler2D u_DiffuseMap;
#if defined(USE_LIGHTMAP)
uniform sampler2D u_LightMap;
#endif
#if defined(USE_NORMALMAP)
uniform sampler2D u_NormalMap;
#endif
#if defined(USE_DELUXEMAP)
uniform sampler2D u_DeluxeMap;
#endif
#if defined(USE_SPECULARMAP)
uniform sampler2D u_SpecularMap;
#endif
#if defined(USE_SHADOWMAP)
uniform sampler2D u_ShadowMap;
#endif
#if defined(USE_CUBEMAP)
uniform samplerCube u_CubeMap;
#endif
#if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP)
// y = deluxe, w = cube
uniform vec4 u_EnableTextures;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec3 u_PrimaryLightColor;
uniform vec3 u_PrimaryLightAmbient;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
uniform vec4 u_NormalScale;
uniform vec4 u_SpecularScale;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
#if defined(USE_CUBEMAP)
uniform vec4 u_CubeMapInfo;
#endif
#endif
uniform int u_AlphaTest;
varying vec4 var_TexCoords;
varying vec4 var_Color;
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
varying vec4 var_ColorAmbient;
#endif
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
varying vec4 var_Normal;
varying vec4 var_Tangent;
varying vec4 var_Bitangent;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
varying vec4 var_LightDir;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
varying vec4 var_PrimaryLightDir;
#endif
#define EPSILON 0.00000001
#if defined(USE_PARALLAXMAP)
float SampleDepth(sampler2D normalMap, vec2 t)
{
#if defined(SWIZZLE_NORMALMAP)
return 1.0 - texture2D(normalMap, t).r;
#else
return 1.0 - texture2D(normalMap, t).a;
#endif
}
float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
{
const int linearSearchSteps = 16;
const int binarySearchSteps = 6;
// current size of search window
float size = 1.0 / float(linearSearchSteps);
// current depth position
float depth = 0.0;
// best match found (starts with last position 1.0)
float bestDepth = 1.0;
// texture depth at best depth
float texDepth = 0.0;
float prevT = SampleDepth(normalMap, dp);
float prevTexDepth = prevT;
// search front to back for first point inside object
for(int i = 0; i < linearSearchSteps - 1; ++i)
{
depth += size;
float t = SampleDepth(normalMap, dp + ds * depth);
if(bestDepth > 0.996) // if no depth found yet
if(depth >= t)
{
bestDepth = depth; // store best depth
texDepth = t;
prevTexDepth = prevT;
}
prevT = t;
}
depth = bestDepth;
#if !defined (USE_RELIEFMAP)
float div = 1.0 / (1.0 + (prevTexDepth - texDepth) * float(linearSearchSteps));
bestDepth -= (depth - size - prevTexDepth) * div;
#else
// recurse around first point (depth) for closest match
for(int i = 0; i < binarySearchSteps; ++i)
{
size *= 0.5;
float t = SampleDepth(normalMap, dp + ds * depth);
if(depth >= t)
{
bestDepth = depth;
depth -= 2.0 * size;
}
depth += size;
}
#endif
return bestDepth;
}
float LightRay(vec2 dp, vec2 ds, sampler2D normalMap)
{
const int linearSearchSteps = 16;
// current size of search window
float size = 1.0 / float(linearSearchSteps);
// current height from initial texel depth
float height = 0.0;
float startDepth = SampleDepth(normalMap, dp);
// find a collision or escape
for(int i = 0; i < linearSearchSteps - 1; ++i)
{
height += size;
if (startDepth < height)
return 1.0;
float t = SampleDepth(normalMap, dp + ds * height);
if (startDepth > t + height)
return 0.0;
}
return 1.0;
}
#endif
vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
{
#if defined(USE_BURLEY)
// modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
float fd90 = -0.5 + EH * EH * roughness;
float burley = 1.0 + fd90 * 0.04 / NH;
burley *= burley;
return diffuseAlbedo * burley;
#else
return diffuseAlbedo;
#endif
}
vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular)
{
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
float v = 1.0 - max(roughness, NE);
v *= v * v;
return vec3(v) + specular;
}
vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness)
{
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
float rr = roughness*roughness;
float rrrr = rr*rr;
float d = (NH * NH) * (rrrr - 1.0) + 1.0;
float v = (EH * EH) * (roughness + 0.5);
return specular * (rrrr / (4.0 * d * d * v));
}
float CalcLightAttenuation(float point, float normDist)
{
// zero light at 1.0, approximating q3 style
// also don't attenuate directional light
float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
// clamp attenuation
#if defined(NO_LIGHT_CLAMP)
attenuation = max(attenuation, 0.0);
#else
attenuation = clamp(attenuation, 0.0, 1.0);
#endif
return attenuation;
}
#if defined(USE_BOX_CUBEMAP_PARALLAX)
vec4 hitCube(vec3 ray, vec3 pos, vec3 invSize, float lod, samplerCube tex)
{
// find any hits on cubemap faces facing the camera
vec3 scale = (sign(ray) - pos) / ray;
// find the nearest hit
float minScale = min(min(scale.x, scale.y), scale.z);
// if the nearest hit is behind the camera, ignore
// should not be necessary as long as pos is inside the cube
//if (minScale < 0.0)
//return vec4(0.0);
// calculate the hit position, that's our texture coordinates
vec3 tc = pos + ray * minScale;
// if the texture coordinates are outside the cube, ignore
// necessary since we're not fading out outside the cube
if (any(greaterThan(abs(tc), vec3(1.00001))))
return vec4(0.0);
// fade out when approaching the cubemap edges
//vec3 fade3 = abs(pos);
//float fade = max(max(fade3.x, fade3.y), fade3.z);
//fade = clamp(1.0 - fade, 0.0, 1.0);
//return vec4(textureCubeLod(tex, tc, lod).rgb * fade, fade);
return vec4(textureCubeLod(tex, tc, lod).rgb, 1.0);
}
#endif
void main()
{
vec3 viewDir, lightColor, ambientColor, reflectance;
vec3 L, N, E, H;
float NL, NH, NE, EH, attenuation;
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
E = normalize(viewDir);
#endif
lightColor = var_Color.rgb;
#if defined(USE_LIGHTMAP)
vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
#if defined(RGBM_LIGHTMAP)
lightmapColor.rgb *= lightmapColor.a;
#endif
#if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
lightmapColor.rgb *= lightmapColor.rgb;
#endif
lightColor *= lightmapColor.rgb;
#endif
vec2 texCoords = var_TexCoords.xy;
#if defined(USE_PARALLAXMAP)
vec3 offsetDir = E * tangentToWorld;
offsetDir.xy *= -u_NormalScale.a / offsetDir.z;
texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap);
#endif
vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
float alpha = diffuse.a * var_Color.a;
if (u_AlphaTest == 1)
{
if (alpha == 0.0)
discard;
}
else if (u_AlphaTest == 2)
{
if (alpha >= 0.5)
discard;
}
else if (u_AlphaTest == 3)
{
if (alpha < 0.5)
discard;
}
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
L = var_LightDir.xyz;
#if defined(USE_DELUXEMAP)
L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
#endif
float sqrLightDist = dot(L, L);
L /= sqrt(sqrLightDist);
#if defined(USE_LIGHT_VECTOR)
attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
#else
attenuation = 1.0;
#endif
#if defined(USE_NORMALMAP)
#if defined(SWIZZLE_NORMALMAP)
N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5);
#else
N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5);
#endif
N.xy *= u_NormalScale.xy;
N.z = sqrt(clamp((0.25 - N.x * N.x) - N.y * N.y, 0.0, 1.0));
N = tangentToWorld * N;
#else
N = var_Normal.xyz;
#endif
N = normalize(N);
#if defined(USE_SHADOWMAP)
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed
shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
#if defined(SHADOWMAP_MODULATE)
lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
#endif
#endif
#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
offsetDir = L * tangentToWorld;
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
#endif
#if !defined(USE_LIGHT_VECTOR)
ambientColor = lightColor;
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
// reserve 25% ambient to avoid black areas on normalmaps
lightColor *= 0.75;
// Scale the incoming light to compensate for the baked-in light angle
// attenuation.
lightColor /= max(surfNL, 0.25);
// Recover any unused light as ambient, in case attenuation is over 4x or
// light is below the surface
ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
#else
ambientColor = var_ColorAmbient.rgb;
#endif
NL = clamp(dot(N, L), 0.0, 1.0);
NE = clamp(dot(N, E), 0.0, 1.0);
H = normalize(L + E);
EH = clamp(dot(E, H), 0.0, 1.0);
NH = clamp(dot(N, H), 0.0, 1.0);
#if defined(USE_SPECULARMAP)
vec4 specular = texture2D(u_SpecularMap, texCoords);
#else
vec4 specular = vec4(1.0);
#endif
specular *= u_SpecularScale;
#if defined(USE_PBR)
diffuse.rgb *= diffuse.rgb;
#endif
#if defined(USE_PBR)
// diffuse rgb is base color
// specular red is gloss
// specular green is metallicness
float gloss = specular.r;
float metal = specular.g;
specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal);
diffuse.rgb *= 1.0 - metal;
#else
// diffuse rgb is diffuse
// specular rgb is specular reflectance at normal incidence
// specular alpha is gloss
float gloss = specular.a;
// adjust diffuse by specular reflectance, to maintain energy conservation
diffuse.rgb *= vec3(1.0) - specular.rgb;
#endif
#if defined(GLOSS_IS_GLOSS)
float roughness = exp2(-3.0 * gloss);
#elif defined(GLOSS_IS_SMOOTHNESS)
float roughness = 1.0 - gloss;
#elif defined(GLOSS_IS_ROUGHNESS)
float roughness = gloss;
#elif defined(GLOSS_IS_SHININESS)
float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
#endif
reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
#if defined(r_deluxeSpecular)
#if defined(USE_LIGHT_VECTOR)
reflectance += CalcSpecular(specular.rgb, NH, EH, roughness) * r_deluxeSpecular;
#else
reflectance += CalcSpecular(specular.rgb, NH, EH, pow(roughness, r_deluxeSpecular));
#endif
#endif
gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
gl_FragColor.rgb += ambientColor * diffuse.rgb;
#if defined(USE_CUBEMAP)
reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
vec3 R = reflect(E, N);
// parallax corrected cubemap (cheaper trick)
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
#if defined(USE_BOX_CUBEMAP_PARALLAX)
vec3 cubeLightColor = hitCube(R * u_CubeMapInfo.w, parallax, u_CubeMapInfo.www, ROUGHNESS_MIPS * roughness, u_CubeMap).rgb * u_EnableTextures.w;
#else
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
#endif
// normalize cubemap based on last roughness mip (~diffuse)
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
//vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, ROUGHNESS_MIPS).rgb, 0.5 / 255.0);
//cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
#if defined(USE_PBR)
cubeLightColor *= cubeLightColor;
#endif
// multiply cubemap values by lighting
// not technically correct, but helps make reflections look less unnatural
//cubeLightColor *= lightColor * (attenuation * NL) + ambientColor;
gl_FragColor.rgb += cubeLightColor * reflectance;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE)
vec3 L2, H2;
float NL2, EH2, NH2;
L2 = var_PrimaryLightDir.xyz;
// enable when point lights are supported as primary lights
//sqrLightDist = dot(L2, L2);
//L2 /= sqrt(sqrLightDist);
NL2 = clamp(dot(N, L2), 0.0, 1.0);
H2 = normalize(L2 + E);
EH2 = clamp(dot(E, H2), 0.0, 1.0);
NH2 = clamp(dot(N, H2), 0.0, 1.0);
reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness);
// bit of a hack, with modulated shadowmaps, ignore diffuse
#if !defined(SHADOWMAP_MODULATE)
reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
#endif
lightColor = u_PrimaryLightColor;
#if defined(USE_SHADOWMAP)
lightColor *= shadowValue;
#endif
// enable when point lights are supported as primary lights
//lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);
#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
offsetDir = L2 * tangentToWorld;
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
#endif
gl_FragColor.rgb += lightColor * reflectance * NL2;
#endif
#if defined(USE_PBR)
gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
#endif
#else
gl_FragColor.rgb = diffuse.rgb * lightColor;
#endif
gl_FragColor.a = alpha;
}

View file

@ -0,0 +1,263 @@
attribute vec4 attr_TexCoord0;
#if defined(USE_LIGHTMAP) || defined(USE_TCGEN)
attribute vec4 attr_TexCoord1;
#endif
attribute vec4 attr_Color;
attribute vec3 attr_Position;
attribute vec3 attr_Normal;
attribute vec4 attr_Tangent;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
attribute vec4 attr_Tangent2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif
#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
attribute vec3 attr_LightDirection;
#endif
#if defined(USE_DELUXEMAP)
uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
uniform vec3 u_ViewOrigin;
#endif
#if defined(USE_TCGEN)
uniform int u_TCGen0;
uniform vec3 u_TCGen0Vector0;
uniform vec3 u_TCGen0Vector1;
uniform vec3 u_LocalViewOrigin;
#endif
#if defined(USE_TCMOD)
uniform vec4 u_DiffuseTexMatrix;
uniform vec4 u_DiffuseTexOffTurb;
#endif
uniform mat4 u_ModelViewProjectionMatrix;
uniform vec4 u_BaseColor;
uniform vec4 u_VertColor;
#if defined(USE_MODELMATRIX)
uniform mat4 u_ModelMatrix;
#endif
#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif
#if defined(USE_LIGHT_VECTOR)
uniform vec4 u_LightOrigin;
uniform float u_LightRadius;
uniform vec3 u_DirectedLight;
uniform vec3 u_AmbientLight;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec4 u_PrimaryLightOrigin;
uniform float u_PrimaryLightRadius;
#endif
varying vec4 var_TexCoords;
varying vec4 var_Color;
#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
varying vec4 var_ColorAmbient;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
varying vec4 var_Normal;
varying vec4 var_Tangent;
varying vec4 var_Bitangent;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
varying vec4 var_LightDir;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
varying vec4 var_PrimaryLightDir;
#endif
#if defined(USE_TCGEN)
vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 TCGenVector1)
{
vec2 tex = attr_TexCoord0.st;
if (TCGen == TCGEN_LIGHTMAP)
{
tex = attr_TexCoord1.st;
}
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
{
vec3 viewer = normalize(u_LocalViewOrigin - position);
vec2 ref = reflect(viewer, normal).yz;
tex.s = ref.x * -0.5 + 0.5;
tex.t = ref.y * 0.5 + 0.5;
}
else if (TCGen == TCGEN_VECTOR)
{
tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
}
return tex;
}
#endif
#if defined(USE_TCMOD)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
{
float amplitude = offTurb.z;
float phase = offTurb.w * 2.0 * M_PI;
vec2 st2;
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
vec2 offsetPos = vec2(position.x + position.z, position.y);
vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
return st2 + texOffset * amplitude;
}
#endif
float CalcLightAttenuation(float point, float normDist)
{
// zero light at 1.0, approximating q3 style
// also don't attenuate directional light
float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
// clamp attenuation
#if defined(NO_LIGHT_CLAMP)
attenuation = max(attenuation, 0.0);
#else
attenuation = clamp(attenuation, 0.0, 1.0);
#endif
return attenuation;
}
void main()
{
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
#endif
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));
vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 tangent = normalize(nrmMat * attr_Tangent.xyz);
#endif
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 tangent = attr_Tangent.xyz;
#endif
#endif
#if defined(USE_TCGEN)
vec2 texCoords = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
#else
vec2 texCoords = attr_TexCoord0.st;
#endif
#if defined(USE_TCMOD)
var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
#else
var_TexCoords.xy = texCoords;
#endif
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
#if defined(USE_MODELMATRIX)
position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
#endif
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 bitangent = cross(normal, tangent) * attr_Tangent.w;
#endif
#if defined(USE_LIGHT_VECTOR)
vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 L = attr_LightDirection;
#if defined(USE_MODELMATRIX)
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
#endif
#endif
#if defined(USE_LIGHTMAP)
var_TexCoords.zw = attr_TexCoord1.st;
#endif
var_Color = u_VertColor * attr_Color + u_BaseColor;
#if defined(USE_LIGHT_VECTOR)
#if defined(USE_FAST_LIGHT)
float sqrLightDist = dot(L, L);
float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
#else
var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
var_Color.rgb *= u_DirectedLight;
#if defined(USE_PBR)
var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
#endif
#endif
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
var_Color.rgb *= var_Color.rgb;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w);
var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius;
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
#if defined(USE_LIGHT_VECTOR)
var_LightDir = vec4(L, u_LightRadius * u_LightRadius);
#else
var_LightDir = vec4(L, 0.0);
#endif
#if defined(USE_DELUXEMAP)
var_LightDir -= u_EnableTextures.y * var_LightDir;
#endif
#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 viewDir = u_ViewOrigin - position;
// store view direction in tangent space to save on varyings
var_Normal = vec4(normal, viewDir.x);
var_Tangent = vec4(tangent, viewDir.y);
var_Bitangent = vec4(bitangent, viewDir.z);
#endif
}

View file

@ -0,0 +1,79 @@
precision mediump sampler2D;
uniform sampler2D u_ShadowMap;
uniform vec3 u_LightForward;
uniform vec3 u_LightUp;
uniform vec3 u_LightRight;
uniform vec4 u_LightOrigin;
uniform float u_LightRadius;
varying vec3 var_Position;
varying vec3 var_Normal;
void main()
{
vec3 lightToPos = var_Position - u_LightOrigin.xyz;
vec2 st = vec2(-dot(u_LightRight, lightToPos), dot(u_LightUp, lightToPos));
float fade = length(st);
#if defined(USE_DISCARD)
if (fade >= 1.0)
{
discard;
}
#endif
fade = clamp(8.0 - fade * 8.0, 0.0, 1.0);
st = st * 0.5 + vec2(0.5);
#if defined(USE_SOLID_PSHADOWS)
float intensity = max(sign(u_LightRadius - length(lightToPos)), 0.0);
#else
float intensity = clamp((1.0 - dot(lightToPos, lightToPos) / (u_LightRadius * u_LightRadius)) * 2.0, 0.0, 1.0);
#endif
float lightDist = length(lightToPos);
float dist;
#if defined(USE_DISCARD)
if (dot(u_LightForward, lightToPos) <= 0.0)
{
discard;
}
if (dot(var_Normal, lightToPos) > 0.0)
{
discard;
}
#else
intensity *= max(sign(dot(u_LightForward, lightToPos)), 0.0);
intensity *= max(sign(-dot(var_Normal, lightToPos)), 0.0);
#endif
intensity *= fade;
float part;
#if defined(USE_PCF)
part = float(texture2D(u_ShadowMap, st + vec2(-1.0/512.0, -1.0/512.0)).r != 1.0);
part += float(texture2D(u_ShadowMap, st + vec2( 1.0/512.0, -1.0/512.0)).r != 1.0);
part += float(texture2D(u_ShadowMap, st + vec2(-1.0/512.0, 1.0/512.0)).r != 1.0);
part += float(texture2D(u_ShadowMap, st + vec2( 1.0/512.0, 1.0/512.0)).r != 1.0);
#else
part = float(texture2D(u_ShadowMap, st).r != 1.0);
#endif
if (part <= 0.0)
{
discard;
}
#if defined(USE_PCF)
intensity *= part * 0.25;
#else
intensity *= part;
#endif
gl_FragColor.rgb = vec3(0);
gl_FragColor.a = clamp(intensity, 0.0, 0.75);
}

View file

@ -0,0 +1,15 @@
attribute vec3 attr_Position;
attribute vec3 attr_Normal;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec3 var_Position;
varying vec3 var_Normal;
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_Position = attr_Position;
var_Normal = attr_Normal;
}

View file

@ -0,0 +1,41 @@
uniform vec4 u_LightOrigin;
uniform float u_LightRadius;
varying vec3 var_Position;
void main()
{
#if defined(USE_DEPTH)
float depth = length(u_LightOrigin.xyz - var_Position) / u_LightRadius;
#if 0
// 32 bit precision
const vec4 bitSh = vec4( 256 * 256 * 256, 256 * 256, 256, 1);
const vec4 bitMsk = vec4( 0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 comp;
comp = depth * bitSh;
comp.xyz = fract(comp.xyz);
comp -= comp.xxyz * bitMsk;
gl_FragColor = comp;
#endif
#if 1
// 24 bit precision
const vec3 bitSh = vec3( 256 * 256, 256, 1);
const vec3 bitMsk = vec3( 0, 1.0 / 256.0, 1.0 / 256.0);
vec3 comp;
comp = depth * bitSh;
comp.xy = fract(comp.xy);
comp -= comp.xxy * bitMsk;
gl_FragColor = vec4(comp, 1.0);
#endif
#if 0
// 8 bit precision
gl_FragColor = vec4(depth, depth, depth, 1);
#endif
#else
gl_FragColor = vec4(0, 0, 0, 1);
#endif
}

View file

@ -0,0 +1,108 @@
attribute vec3 attr_Position;
attribute vec3 attr_Normal;
attribute vec4 attr_TexCoord0;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif
//#if defined(USE_DEFORM_VERTEXES)
uniform int u_DeformGen;
uniform float u_DeformParams[5];
//#endif
uniform float u_Time;
uniform mat4 u_ModelViewProjectionMatrix;
uniform mat4 u_ModelMatrix;
#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif
varying vec3 var_Position;
vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
{
if (u_DeformGen == 0)
{
return pos;
}
float base = u_DeformParams[0];
float amplitude = u_DeformParams[1];
float phase = u_DeformParams[2];
float frequency = u_DeformParams[3];
float spread = u_DeformParams[4];
if (u_DeformGen == DGEN_BULGE)
{
phase *= st.x;
}
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
{
phase += dot(pos.xyz, vec3(spread));
}
float value = phase + (u_Time * frequency);
float func;
if (u_DeformGen == DGEN_WAVE_SIN)
{
func = sin(value * 2.0 * M_PI);
}
else if (u_DeformGen == DGEN_WAVE_SQUARE)
{
func = sign(0.5 - fract(value));
}
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
{
func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
}
else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
{
func = fract(value);
}
else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
{
func = (1.0 - fract(value));
}
else // if (u_DeformGen == DGEN_BULGE)
{
func = sin(value);
}
return pos + normal * (base + func * amplitude);
}
void main()
{
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));
vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#endif
position = DeformPosition(position, normal, attr_TexCoord0.st);
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
var_Position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
}

View file

@ -0,0 +1,146 @@
precision mediump sampler2D;
precision mediump sampler2DShadow;
uniform sampler2D u_ScreenDepthMap;
uniform sampler2DShadow u_ShadowMap;
#if defined(USE_SHADOW_CASCADE)
uniform sampler2DShadow u_ShadowMap2;
uniform sampler2DShadow u_ShadowMap3;
uniform sampler2DShadow u_ShadowMap4;
#endif
uniform mat4 u_ShadowMvp;
#if defined(USE_SHADOW_CASCADE)
uniform mat4 u_ShadowMvp2;
uniform mat4 u_ShadowMvp3;
uniform mat4 u_ShadowMvp4;
#endif
uniform vec3 u_ViewOrigin;
uniform vec4 u_ViewInfo; // zfar / znear, zfar
varying vec2 var_DepthTex;
varying vec3 var_ViewDir;
// depth is GL_DEPTH_COMPONENT24
// so the maximum error is 1.0 / 2^24
#define DEPTH_MAX_ERROR 0.000000059604644775390625
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
// Author: Michael Pohoreski
// Copyright: Copyleft 2012 :-)
// Source: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader
float random( const vec2 p )
{
// We need irrationals for pseudo randomness.
// Most (all?) known transcendental numbers will (generally) work.
const vec2 r = vec2(
23.1406926327792690, // e^pi (Gelfond's constant)
2.6651441426902251); // 2^sqrt(2) (Gelfond-Schneider constant)
//return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );
return mod( 123456789., 1e-7 + 256. * dot(p,r) );
}
float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
{
float mult;
float scale = 2.0 / r_shadowMapSize;
#if 0
// from http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
vec2 offset = vec2(greaterThan(fract(var_DepthTex.xy * r_FBufScale * 0.5), vec2(0.25)));
offset.y += offset.x;
if (offset.y > 1.1) offset.y = 0.0;
mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, 0.5)) * scale, dist))
+ shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, 0.5)) * scale, dist))
+ shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist))
+ shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist));
mult *= 0.25;
#endif
#if defined(USE_SHADOW_FILTER)
float r = random(var_DepthTex.xy);
float sinr = sin(r) * scale;
float cosr = cos(r) * scale;
mat2 rmat = mat2(cosr, sinr, -sinr, cosr);
mult = shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist));
#if defined(USE_SHADOW_FILTER2)
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist));
mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist));
mult *= 0.11111;
#else
mult *= 0.33333;
#endif
#else
mult = shadow2D(shadowmap, vec3(st, dist));
#endif
return mult;
}
float getLinearDepth(sampler2D depthMap, vec2 tex, float zFarDivZNear)
{
float sampleZDivW = texture2D(depthMap, tex).r - DEPTH_MAX_ERROR;
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
void main()
{
float result;
float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x);
vec4 biasPos = vec4(u_ViewOrigin + var_ViewDir * (depth - 0.5 / u_ViewInfo.x), 1.0);
vec4 shadowpos = u_ShadowMvp * biasPos;
#if defined(USE_SHADOW_CASCADE)
if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
{
#endif
shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
result = PCF(u_ShadowMap, shadowpos.xy, shadowpos.z);
#if defined(USE_SHADOW_CASCADE)
}
else
{
shadowpos = u_ShadowMvp2 * biasPos;
if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
{
shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
result = PCF(u_ShadowMap2, shadowpos.xy, shadowpos.z);
}
else
{
shadowpos = u_ShadowMvp3 * biasPos;
if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
{
shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
result = PCF(u_ShadowMap3, shadowpos.xy, shadowpos.z);
}
else
{
shadowpos = u_ShadowMvp4 * biasPos;
shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
result = PCF(u_ShadowMap4, shadowpos.xy, shadowpos.z);
}
}
}
#endif
gl_FragColor = vec4(vec3(result), 1.0);
}

View file

@ -0,0 +1,18 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
uniform vec3 u_ViewForward;
uniform vec3 u_ViewLeft;
uniform vec3 u_ViewUp;
uniform vec4 u_ViewInfo; // zfar / znear
varying vec2 var_DepthTex;
varying vec3 var_ViewDir;
void main()
{
gl_Position = attr_Position;
vec2 screenCoords = gl_Position.xy / gl_Position.w;
var_DepthTex = attr_TexCoord0.xy;
var_ViewDir = u_ViewForward + u_ViewLeft * -screenCoords.x + u_ViewUp * screenCoords.y;
}

View file

@ -0,0 +1,101 @@
uniform sampler2D u_ScreenDepthMap;
uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex;
#if 0
vec2 poissonDisc[9] = vec2[9](
vec2(-0.7055767, 0.196515), vec2(0.3524343, -0.7791386),
vec2(0.2391056, 0.9189604), vec2(-0.07580382, -0.09224417),
vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181),
vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
vec2(0.7320465, 0.6317794)
);
#endif
#define NUM_SAMPLES 3
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
// Author: Michael Pohoreski
// Copyright: Copyleft 2012 :-)
// Source: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader
float random( const vec2 p )
{
// We need irrationals for pseudo randomness.
// Most (all?) known transcendental numbers will (generally) work.
const vec2 r = vec2(
23.1406926327792690, // e^pi (Gelfond's constant)
2.6651441426902251); // 2^sqrt(2) (Gelfond-Schneider constant)
//return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );
return mod( 123456789., 1e-7 + 256. * dot(p,r) );
}
mat2 randomRotation( const vec2 p )
{
float r = random(p);
float sinr = sin(r);
float cosr = cos(r);
return mat2(cosr, sinr, -sinr, cosr);
}
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
float sampleZDivW = texture2D(depthMap, tex).r;
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
{
vec2 poissonDisc[9];
poissonDisc[0] = vec2(-0.7055767, 0.196515);
poissonDisc[1] = vec2(0.3524343, -0.7791386);
poissonDisc[2] = vec2(0.2391056, 0.9189604);
poissonDisc[3] = vec2(-0.07580382, -0.09224417);
poissonDisc[4] = vec2(0.5784913, -0.002528916);
poissonDisc[5] = vec2(0.192888, 0.4064181);
poissonDisc[6] = vec2(-0.6335801, -0.5247476);
poissonDisc[7] = vec2(-0.5579782, 0.7491854);
poissonDisc[8] = vec2(0.7320465, 0.6317794);
float result = 0.0;
float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
float scaleZ = zFarDivZNear * sampleZ;
vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
if (length(slope) * zFar > 5000.0)
return 1.0;
vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
mat2 rmat = randomRotation(tex);
float invZFar = 1.0 / zFar;
float zLimit = 20.0 * invZFar;
int i;
for (i = 0; i < NUM_SAMPLES; i++)
{
vec2 offset = rmat * poissonDisc[i] * offsetScale;
float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
bool s1 = abs(sampleDiff) > zLimit;
bool s2 = sampleDiff + invZFar > dot(slope, offset);
result += float(s1 || s2);
}
result *= 1.0 / float(NUM_SAMPLES);
return result;
}
void main()
{
float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
gl_FragColor = vec4(vec3(result), 1.0);
}

View file

@ -0,0 +1,12 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
varying vec2 var_ScreenTex;
void main()
{
gl_Position = attr_Position;
var_ScreenTex = attr_TexCoord0.xy;
//vec2 screenCoords = gl_Position.xy / gl_Position.w;
//var_ScreenTex = screenCoords * 0.5 + 0.5;
}

View file

@ -0,0 +1,10 @@
uniform sampler2D u_DiffuseMap;
uniform vec4 u_Color;
varying vec2 var_Tex1;
void main()
{
gl_FragColor = texture2D(u_DiffuseMap, var_Tex1) * u_Color;
}

View file

@ -0,0 +1,13 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
uniform mat4 u_ModelViewProjectionMatrix;
varying vec2 var_Tex1;
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_Tex1 = attr_TexCoord0.st;
}

View file

@ -0,0 +1,57 @@
uniform sampler2D u_TextureMap;
uniform sampler2D u_LevelsMap;
uniform vec4 u_Color;
uniform vec2 u_AutoExposureMinMax;
uniform vec3 u_ToneMinAvgMaxLinear;
varying vec2 var_TexCoords;
varying float var_InvWhite;
const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.587, 0.114);
float FilmicTonemap(float x)
{
const float SS = 0.22; // Shoulder Strength
const float LS = 0.30; // Linear Strength
const float LA = 0.10; // Linear Angle
const float TS = 0.20; // Toe Strength
const float TAN = 0.01; // Toe Angle Numerator
const float TAD = 0.30; // Toe Angle Denominator
return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/TAD;
}
void main()
{
vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
#if defined(USE_PBR)
color.rgb *= color.rgb;
#endif
vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;
vec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x);
float invAvgLum = u_ToneMinAvgMaxLinear.y * exp2(-logMinAvgMaxLum.y);
color.rgb = color.rgb * invAvgLum - u_ToneMinAvgMaxLinear.xxx;
color.rgb = max(vec3(0.0), color.rgb);
color.r = FilmicTonemap(color.r);
color.g = FilmicTonemap(color.g);
color.b = FilmicTonemap(color.b);
color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
#if defined(USE_PBR)
color.rgb = sqrt(color.rgb);
#endif
// add a bit of dither to reduce banding
color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0);
gl_FragColor = color;
}

View file

@ -0,0 +1,27 @@
attribute vec3 attr_Position;
attribute vec4 attr_TexCoord0;
uniform mat4 u_ModelViewProjectionMatrix;
uniform vec3 u_ToneMinAvgMaxLinear;
varying vec2 var_TexCoords;
varying float var_InvWhite;
float FilmicTonemap(float x)
{
const float SS = 0.22; // Shoulder Strength
const float LS = 0.30; // Linear Strength
const float LA = 0.10; // Linear Angle
const float TS = 0.20; // Toe Strength
const float TAN = 0.01; // Toe Angle Numerator
const float TAD = 0.30; // Toe Angle Denominator
return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/TAD;
}
void main()
{
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
var_TexCoords = attr_TexCoord0.st;
var_InvWhite = 1.0 / FilmicTonemap(u_ToneMinAvgMaxLinear.z - u_ToneMinAvgMaxLinear.x);
}

View file

@ -0,0 +1,308 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define ITEM_TYPE_TEXT 0 // simple text
#define ITEM_TYPE_BUTTON 1 // button, basically text with a border
#define ITEM_TYPE_RADIOBUTTON 2 // toggle button, may be grouped
#define ITEM_TYPE_CHECKBOX 3 // check box
#define ITEM_TYPE_EDITFIELD 4 // editable text, associated with a cvar
#define ITEM_TYPE_COMBO 5 // drop down list
#define ITEM_TYPE_LISTBOX 6 // scrollable list
#define ITEM_TYPE_MODEL 7 // model
#define ITEM_TYPE_OWNERDRAW 8 // owner draw, name specs what it is
#define ITEM_TYPE_NUMERICFIELD 9 // editable text, associated with a cvar
#define ITEM_TYPE_SLIDER 10 // mouse speed, volume, etc.
#define ITEM_TYPE_YESNO 11 // yes no cvar setting
#define ITEM_TYPE_MULTI 12 // multiple list setting, enumerated
#define ITEM_TYPE_BIND 13 // multiple list setting, enumerated
#define ITEM_ALIGN_LEFT 0 // left alignment
#define ITEM_ALIGN_CENTER 1 // center alignment
#define ITEM_ALIGN_RIGHT 2 // right alignment
#define ITEM_TEXTSTYLE_NORMAL 0 // normal text
#define ITEM_TEXTSTYLE_BLINK 1 // fast blinking
#define ITEM_TEXTSTYLE_PULSE 2 // slow pulsing
#define ITEM_TEXTSTYLE_SHADOWED 3 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_OUTLINED 4 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_OUTLINESHADOWED 5 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_SHADOWEDMORE 6 // drop shadow ( need a color for this )
#define WINDOW_BORDER_NONE 0 // no border
#define WINDOW_BORDER_FULL 1 // full border based on border color ( single pixel )
#define WINDOW_BORDER_HORZ 2 // horizontal borders only
#define WINDOW_BORDER_VERT 3 // vertical borders only
#define WINDOW_BORDER_KCGRADIENT 4 // horizontal border using the gradient bars
#define WINDOW_STYLE_EMPTY 0 // no background
#define WINDOW_STYLE_FILLED 1 // filled with background color
#define WINDOW_STYLE_GRADIENT 2 // gradient bar based on background color
#define WINDOW_STYLE_SHADER 3 // gradient bar based on background color
#define WINDOW_STYLE_TEAMCOLOR 4 // team color
#define WINDOW_STYLE_CINEMATIC 5 // cinematic
#define MENU_TRUE 1 // uh.. true
#define MENU_FALSE 0 // and false
#define HUD_VERTICAL 0x00
#define HUD_HORIZONTAL 0x01
// list box element types
#define LISTBOX_TEXT 0x00
#define LISTBOX_IMAGE 0x01
// list feeders
#define FEEDER_HEADS 0x00 // model heads
#define FEEDER_MAPS 0x01 // text maps based on game type
#define FEEDER_SERVERS 0x02 // servers
#define FEEDER_CLANS 0x03 // clan names
#define FEEDER_ALLMAPS 0x04 // all maps available, in graphic format
#define FEEDER_REDTEAM_LIST 0x05 // red team members
#define FEEDER_BLUETEAM_LIST 0x06 // blue team members
#define FEEDER_PLAYER_LIST 0x07 // players
#define FEEDER_TEAM_LIST 0x08 // team members for team voting
#define FEEDER_MODS 0x09 // team members for team voting
#define FEEDER_DEMOS 0x0a // team members for team voting
#define FEEDER_SCOREBOARD 0x0b // team members for team voting
#define FEEDER_Q3HEADS 0x0c // model heads
#define FEEDER_SERVERSTATUS 0x0d // server status
#define FEEDER_FINDPLAYER 0x0e // find player
#define FEEDER_CINEMATICS 0x0f // cinematics
// display flags
#define CG_SHOW_BLUE_TEAM_HAS_REDFLAG 0x00000001
#define CG_SHOW_RED_TEAM_HAS_BLUEFLAG 0x00000002
#define CG_SHOW_ANYTEAMGAME 0x00000004
#define CG_SHOW_HARVESTER 0x00000008
#define CG_SHOW_ONEFLAG 0x00000010
#define CG_SHOW_CTF 0x00000020
#define CG_SHOW_OBELISK 0x00000040
#define CG_SHOW_HEALTHCRITICAL 0x00000080
#define CG_SHOW_SINGLEPLAYER 0x00000100
#define CG_SHOW_TOURNAMENT 0x00000200
#define CG_SHOW_DURINGINCOMINGVOICE 0x00000400
#define CG_SHOW_IF_PLAYER_HAS_FLAG 0x00000800
#define CG_SHOW_LANPLAYONLY 0x00001000
#define CG_SHOW_MINED 0x00002000
#define CG_SHOW_HEALTHOK 0x00004000
#define CG_SHOW_TEAMINFO 0x00008000
#define CG_SHOW_NOTEAMINFO 0x00010000
#define CG_SHOW_OTHERTEAMHASFLAG 0x00020000
#define CG_SHOW_YOURTEAMHASENEMYFLAG 0x00040000
#define CG_SHOW_ANYNONTEAMGAME 0x00080000
#define CG_SHOW_2DONLY 0x10000000
#define UI_SHOW_LEADER 0x00000001
#define UI_SHOW_NOTLEADER 0x00000002
#define UI_SHOW_FAVORITESERVERS 0x00000004
#define UI_SHOW_ANYNONTEAMGAME 0x00000008
#define UI_SHOW_ANYTEAMGAME 0x00000010
#define UI_SHOW_NEWHIGHSCORE 0x00000020
#define UI_SHOW_DEMOAVAILABLE 0x00000040
#define UI_SHOW_NEWBESTTIME 0x00000080
#define UI_SHOW_FFA 0x00000100
#define UI_SHOW_NOTFFA 0x00000200
#define UI_SHOW_NETANYNONTEAMGAME 0x00000400
#define UI_SHOW_NETANYTEAMGAME 0x00000800
#define UI_SHOW_NOTFAVORITESERVERS 0x00001000
// owner draw types
// ideally these should be done outside of this file but
// this makes it much easier for the macro expansion to
// convert them for the designers ( from the .menu files )
#define CG_OWNERDRAW_BASE 1
#define CG_PLAYER_ARMOR_ICON 1
#define CG_PLAYER_ARMOR_VALUE 2
#define CG_PLAYER_HEAD 3
#define CG_PLAYER_HEALTH 4
#define CG_PLAYER_AMMO_ICON 5
#define CG_PLAYER_AMMO_VALUE 6
#define CG_SELECTEDPLAYER_HEAD 7
#define CG_SELECTEDPLAYER_NAME 8
#define CG_SELECTEDPLAYER_LOCATION 9
#define CG_SELECTEDPLAYER_STATUS 10
#define CG_SELECTEDPLAYER_WEAPON 11
#define CG_SELECTEDPLAYER_POWERUP 12
#define CG_FLAGCARRIER_HEAD 13
#define CG_FLAGCARRIER_NAME 14
#define CG_FLAGCARRIER_LOCATION 15
#define CG_FLAGCARRIER_STATUS 16
#define CG_FLAGCARRIER_WEAPON 17
#define CG_FLAGCARRIER_POWERUP 18
#define CG_PLAYER_ITEM 19
#define CG_PLAYER_SCORE 20
#define CG_BLUE_FLAGHEAD 21
#define CG_BLUE_FLAGSTATUS 22
#define CG_BLUE_FLAGNAME 23
#define CG_RED_FLAGHEAD 24
#define CG_RED_FLAGSTATUS 25
#define CG_RED_FLAGNAME 26
#define CG_BLUE_SCORE 27
#define CG_RED_SCORE 28
#define CG_RED_NAME 29
#define CG_BLUE_NAME 30
#define CG_HARVESTER_SKULLS 31 // only shows in harvester
#define CG_ONEFLAG_STATUS 32 // only shows in one flag
#define CG_PLAYER_LOCATION 33
#define CG_TEAM_COLOR 34
#define CG_CTF_POWERUP 35
#define CG_AREA_POWERUP 36
#define CG_AREA_LAGOMETER 37 // painted with old system
#define CG_PLAYER_HASFLAG 38
#define CG_GAME_TYPE 39 // not done
#define CG_SELECTEDPLAYER_ARMOR 40
#define CG_SELECTEDPLAYER_HEALTH 41
#define CG_PLAYER_STATUS 42
#define CG_FRAGGED_MSG 43 // painted with old system
#define CG_PROXMINED_MSG 44 // painted with old system
#define CG_AREA_FPSINFO 45 // painted with old system
#define CG_AREA_SYSTEMCHAT 46 // painted with old system
#define CG_AREA_TEAMCHAT 47 // painted with old system
#define CG_AREA_CHAT 48 // painted with old system
#define CG_GAME_STATUS 49
#define CG_KILLER 50
#define CG_PLAYER_ARMOR_ICON2D 51
#define CG_PLAYER_AMMO_ICON2D 52
#define CG_ACCURACY 53
#define CG_ASSISTS 54
#define CG_DEFEND 55
#define CG_EXCELLENT 56
#define CG_IMPRESSIVE 57
#define CG_PERFECT 58
#define CG_GAUNTLET 59
#define CG_SPECTATORS 60
#define CG_TEAMINFO 61
#define CG_VOICE_HEAD 62
#define CG_VOICE_NAME 63
#define CG_PLAYER_HASFLAG2D 64
#define CG_HARVESTER_SKULLS2D 65 // only shows in harvester
#define CG_CAPFRAGLIMIT 66
#define CG_1STPLACE 67
#define CG_2NDPLACE 68
#define CG_CAPTURES 69
#define UI_OWNERDRAW_BASE 200
#define UI_HANDICAP 200
#define UI_EFFECTS 201
#define UI_PLAYERMODEL 202
#define UI_CLANNAME 203
#define UI_CLANLOGO 204
#define UI_GAMETYPE 205
#define UI_MAPPREVIEW 206
#define UI_SKILL 207
#define UI_BLUETEAMNAME 208
#define UI_REDTEAMNAME 209
#define UI_BLUETEAM1 210
#define UI_BLUETEAM2 211
#define UI_BLUETEAM3 212
#define UI_BLUETEAM4 213
#define UI_BLUETEAM5 214
#define UI_REDTEAM1 215
#define UI_REDTEAM2 216
#define UI_REDTEAM3 217
#define UI_REDTEAM4 218
#define UI_REDTEAM5 219
#define UI_NETSOURCE 220
#define UI_NETMAPPREVIEW 221
#define UI_NETFILTER 222
#define UI_TIER 223
#define UI_OPPONENTMODEL 224
#define UI_TIERMAP1 225
#define UI_TIERMAP2 226
#define UI_TIERMAP3 227
#define UI_PLAYERLOGO 228
#define UI_OPPONENTLOGO 229
#define UI_PLAYERLOGO_METAL 230
#define UI_OPPONENTLOGO_METAL 231
#define UI_PLAYERLOGO_NAME 232
#define UI_OPPONENTLOGO_NAME 233
#define UI_TIER_MAPNAME 234
#define UI_TIER_GAMETYPE 235
#define UI_ALLMAPS_SELECTION 236
#define UI_OPPONENT_NAME 237
#define UI_VOTE_KICK 238
#define UI_BOTNAME 239
#define UI_BOTSKILL 240
#define UI_REDBLUE 241
#define UI_CROSSHAIR 242
#define UI_SELECTEDPLAYER 243
#define UI_MAPCINEMATIC 244
#define UI_NETGAMETYPE 245
#define UI_NETMAPCINEMATIC 246
#define UI_SERVERREFRESHDATE 247
#define UI_SERVERMOTD 248
#define UI_GLINFO 249
#define UI_KEYBINDSTATUS 250
#define UI_CLANCINEMATIC 251
#define UI_MAP_TIMETOBEAT 252
#define UI_JOINGAMETYPE 253
#define UI_PREVIEWCINEMATIC 254
#define UI_STARTMAPCINEMATIC 255
#define UI_MAPS_SELECTION 256
#define VOICECHAT_GETFLAG "getflag" // command someone to get the flag
#define VOICECHAT_OFFENSE "offense" // command someone to go on offense
#define VOICECHAT_DEFEND "defend" // command someone to go on defense
#define VOICECHAT_DEFENDFLAG "defendflag" // command someone to defend the flag
#define VOICECHAT_PATROL "patrol" // command someone to go on patrol (roam)
#define VOICECHAT_CAMP "camp" // command someone to camp (we don't have sounds for this one)
#define VOICECHAT_FOLLOWME "followme" // command someone to follow you
#define VOICECHAT_RETURNFLAG "returnflag" // command someone to return our flag
#define VOICECHAT_FOLLOWFLAGCARRIER "followflagcarrier" // command someone to follow the flag carrier
#define VOICECHAT_YES "yes" // yes, affirmative, etc.
#define VOICECHAT_NO "no" // no, negative, etc.
#define VOICECHAT_ONGETFLAG "ongetflag" // I'm getting the flag
#define VOICECHAT_ONOFFENSE "onoffense" // I'm on offense
#define VOICECHAT_ONDEFENSE "ondefense" // I'm on defense
#define VOICECHAT_ONPATROL "onpatrol" // I'm on patrol (roaming)
#define VOICECHAT_ONCAMPING "oncamp" // I'm camping somewhere
#define VOICECHAT_ONFOLLOW "onfollow" // I'm following
#define VOICECHAT_ONFOLLOWCARRIER "onfollowcarrier" // I'm following the flag carrier
#define VOICECHAT_ONRETURNFLAG "onreturnflag" // I'm returning our flag
#define VOICECHAT_INPOSITION "inposition" // I'm in position
#define VOICECHAT_IHAVEFLAG "ihaveflag" // I have the flag
#define VOICECHAT_BASEATTACK "baseattack" // the base is under attack
#define VOICECHAT_ENEMYHASFLAG "enemyhasflag" // the enemy has our flag (CTF)
#define VOICECHAT_STARTLEADER "startleader" // I'm the leader
#define VOICECHAT_STOPLEADER "stopleader" // I resign leadership
#define VOICECHAT_TRASH "trash" // lots of trash talk
#define VOICECHAT_WHOISLEADER "whoisleader" // who is the team leader
#define VOICECHAT_WANTONDEFENSE "wantondefense" // I want to be on defense
#define VOICECHAT_WANTONOFFENSE "wantonoffense" // I want to be on offense
#define VOICECHAT_KILLINSULT "kill_insult" // I just killed you
#define VOICECHAT_TAUNT "taunt" // I want to taunt you
#define VOICECHAT_DEATHINSULT "death_insult" // you just killed me
#define VOICECHAT_KILLGAUNTLET "kill_gauntlet" // I just killed you with the gauntlet
#define VOICECHAT_PRAISE "praise" // you did something good