1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-11 15:45:05 +02:00

#23 trapezoidal texturing

This commit is contained in:
XProger
2017-07-16 05:21:48 +03:00
parent 730d027808
commit d57056e8a0
8 changed files with 163 additions and 74 deletions

View File

@@ -412,7 +412,8 @@ namespace TR {
struct Vertex {
int16 x, y, z;
operator vec3() const { return vec3((float)x, (float)y, (float)z); };
operator vec3() const { return vec3((float)x, (float)y, (float)z); }
operator short3() const { return *((short3*)this); }
};
struct Rectangle {

View File

@@ -425,10 +425,8 @@ struct Lara : Character {
if (level->extra.braid > -1)
braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f));
#ifdef _DEBUG
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool)
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, STAND_ONWATER); // gym (pool)
//reset(14, vec3(20215, 6656, 52942), PI); // level 1 (bridge)
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
//reset(61, vec3(27221, -1024, 29205), PI * 0.5f); // level 2 (blade)
@@ -1562,7 +1560,7 @@ struct Lara : Character {
if (getRoom().flags.water) {
wpnHide();
if (stand != STAND_UNDERWATER && (state != STATE_FALL && state != STATE_FALL_BACK && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE))
if (stand != STAND_UNDERWATER && stand != STAND_ONWATER && (state != STATE_FALL && state != STATE_FALL_BACK && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE))
animation.setAnim(ANIM_FALL_FORTH);
return STAND_UNDERWATER;
}

View File

@@ -411,6 +411,12 @@ struct Level : IGame {
fwrite(data, 1024 * 1024 * 4, 1, f);
fclose(f);
*/
/*
memset(data, 255, 4 * 1024 * 1024);
for (int i = 0; i < 1024; i++)
for (int j = 0; j < 1024; j++)
data[i * 1024 + j].b = data[i * 1024 + j].g = ((i % 8 == 0) || (j % 8 == 0)) ? 0 : 255;
*/
atlas = new Texture(1024, 1024, Texture::RGBA, false, data);
PROFILE_LABEL(TEXTURE, atlas->ID, "atlas");

View File

@@ -13,9 +13,10 @@
typedef unsigned short Index;
struct Vertex {
short4 coord; // xyz - position, w - unused
short4 texCoord; // xy - texture coordinates, z - anim tex range index, w - anim tex frame index
short4 coord; // xyz - position, w - joint index (for entities only)
short4 normal; // xyz - vertex normal<61> w - unused
short4 texCoord; // xy - texture coordinates, zw - trapezoid warping
ubyte4 param; // xy - anim tex range and frame index, zw - unused
ubyte4 color; // xyz - color, w - intensity
};
@@ -29,14 +30,16 @@ struct MeshRange {
void setup() const {
glEnableVertexAttribArray(aCoord);
glEnableVertexAttribArray(aTexCoord);
glEnableVertexAttribArray(aNormal);
glEnableVertexAttribArray(aTexCoord);
glEnableVertexAttribArray(aParam);
glEnableVertexAttribArray(aColor);
Vertex *v = (Vertex*)NULL + vStart;
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal);
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, true, sizeof(Vertex), &v->texCoord);
glVertexAttribPointer(aParam, 4, GL_UNSIGNED_BYTE, false, sizeof(Vertex), &v->param);
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
}
@@ -234,7 +237,7 @@ struct MeshBuilder {
if (Core::settings.detail.water)
roomRemoveWaterSurfaces(r, iCount, vCount);
for (int j = 0; j < r.meshesCount; j++) {
TR::Room::Mesh &m = r.meshes[j];
TR::StaticMesh *s = &level.staticMeshes[m.meshIndex];
@@ -402,8 +405,9 @@ struct MeshBuilder {
// build shadow blob
for (int i = 0; i < 9; i++) {
Vertex &v0 = vertices[vCount + i * 2 + 0];
v0.normal = { 0, -1, 0, 1 };
v0.texCoord = { 32688, 32688, 0, 0 };
v0.normal = { 0, -1, 0, 0 };
v0.texCoord = { 32688, 32688, 32767, 32767 };
v0.param = { 0, 0, 0, 0 };
v0.color = { 0, 0, 0, 0 };
if (i == 8) {
@@ -507,7 +511,8 @@ struct MeshBuilder {
Vertex &v = vertices[vCount + i];
v.normal = { 0, 0, 0, 0 };
v.color = { 255, 255, 255, 255 };
v.texCoord = { 32688, 32688, 0, 0 };
v.texCoord = { 32688, 32688, 32767, 32767 };
v.param = { 0, 0, 0, 0 };
}
vCount += 4;
aCount++;
@@ -522,7 +527,8 @@ struct MeshBuilder {
v.coord = { short(pos.x), short(pos.y), 0, 0 };
v.normal = { 0, 0, 0, 0 };
v.color = { 255, 255, 255, 255 };
v.texCoord = { 32688, 32688, 0, 0 };
v.texCoord = { 32688, 32688, 32767, 32767 };
v.param = { 0, 0, 0, 0 };
indices[iCount++] = i;
indices[iCount++] = (i + 1) % CIRCLE_SEGS;
@@ -700,8 +706,11 @@ struct MeshBuilder {
if (opaque != (t.attribute == 0))
continue;
addQuad(indices, iCount, vCount, vStart, vertices, &t);
addQuad(indices, iCount, vCount, vStart, vertices, &t,
d.vertices[f.vertices[0]].vertex,
d.vertices[f.vertices[1]].vertex,
d.vertices[f.vertices[2]].vertex,
d.vertices[f.vertices[3]].vertex);
TR::Vertex n;
CHECK_ROOM_NORMAL(n);
@@ -761,7 +770,11 @@ struct MeshBuilder {
TR::Color24 c = textured ? COLOR_WHITE : level.getColor(f.texture);
addQuad(indices, iCount, vCount, vStart, vertices, &t);
addQuad(indices, iCount, vCount, vStart, vertices, &t,
mesh.vertices[f.vertices[0]].coord,
mesh.vertices[f.vertices[1]].coord,
mesh.vertices[f.vertices[2]].coord,
mesh.vertices[f.vertices[3]].coord);
for (int k = 0; k < 4; k++) {
TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]];
@@ -808,7 +821,7 @@ struct MeshBuilder {
int tx = (tile % 4) * 256;
int ty = (tile / 4) * 256;
return vec2( (float)(((tx + tex.texCoord[0].x) << 5) + 16),
(float)(((ty + tex.texCoord[0].y) << 5) + 16) );
(float)(((ty + tex.texCoord[0].y) << 5) + 16) ) * (1.0f / 32767.0f);
}
void initAnimTextures(TR::Level &level) {
@@ -846,7 +859,7 @@ struct MeshBuilder {
}
}
TR::ObjectTexture* getAnimTexture(TR::ObjectTexture *tex, int &range, int &frame) {
TR::ObjectTexture* getAnimTexture(TR::ObjectTexture *tex, uint8 &range, uint8 &frame) {
range = frame = 0;
if (!level->animTexturesDataSize)
return tex;
@@ -869,28 +882,41 @@ struct MeshBuilder {
}
void addTexCoord(Vertex *vertices, int vCount, TR::ObjectTexture *tex, bool triangle) {
int range, frame;
uint8 range, frame;
tex = getAnimTexture(tex, range, frame);
int tile = tex->tile.index;
int tx = (tile % 4) * 256;
int ty = (tile / 4) * 256;
int count = triangle ? 3 : 4;
for (int i = 0; i < count; i++) {
Vertex &v = vertices[vCount + i];
v.texCoord.x = ((tx + tex->texCoord[i].x) << 5) + 16;
v.texCoord.y = ((ty + tex->texCoord[i].y) << 5) + 16;
v.texCoord.z = range;
v.texCoord.w = frame;
v.texCoord.z = 32767;
v.texCoord.w = 32767;
v.param = { range, frame, 0, 0 };
}
if (level->version == TR::Level::VER_TR1_PSX && !triangle)
swap(vertices[vCount + 2].texCoord, vertices[vCount + 3].texCoord);
/*
short2 uv[4] = {
{0, 0}, {32767, 0}, {32767, 32767}, {0, 32767}
};
for (int i = 0; i < count; i++) {
Vertex &v = vertices[vCount + i];
v.texCoord.x = uv[i].x;
v.texCoord.y = uv[i].y;
}
*/
}
void addTriangle(Index *indices, int &iCount, int vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex) {
int vIndex = vCount - vStart;
int vIndex = vCount - vStart;
indices[iCount + 0] = vIndex + 0;
indices[iCount + 1] = vIndex + 1;
@@ -902,7 +928,7 @@ struct MeshBuilder {
}
void addQuad(Index *indices, int &iCount, int vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex) {
int vIndex = vCount - vStart;
int vIndex = vCount - vStart;
indices[iCount + 0] = vIndex + 0;
indices[iCount + 1] = vIndex + 1;
@@ -917,6 +943,43 @@ struct MeshBuilder {
if (tex) addTexCoord(vertices, vCount, tex, false);
}
void addQuad(Index *indices, int &iCount, int &vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex,
const short3 &c0, const short3 &c1, const short3 &c2, const short3 &c3) {
addQuad(indices, iCount, vCount, vStart, vertices, tex);
vec3 a = c0 - c1;
vec3 b = c3 - c2;
vec3 c = c0 - c3;
vec3 d = c1 - c2;
float aL = a.length();
float bL = b.length();
float cL = c.length();
float dL = d.length();
float ab = a.dot(b) / (aL * bL);
float cd = c.dot(d) / (cL * dL);
int16 tx = abs(vertices[vCount + 0].texCoord.x - vertices[vCount + 3].texCoord.x);
int16 ty = abs(vertices[vCount + 0].texCoord.y - vertices[vCount + 3].texCoord.y);
if (ab > cd) {
int k = (tx > ty) ? 3 : 2;
if (aL > bL)
vertices[vCount + 2].texCoord[k] = vertices[vCount + 3].texCoord[k] = int16(bL / aL * 32767.0f);
else
vertices[vCount + 0].texCoord[k] = vertices[vCount + 1].texCoord[k] = int16(aL / bL * 32767.0f);
} else {
int k = (tx > ty) ? 2 : 3;
if (cL > dL) {
vertices[vCount + 1].texCoord[k] = vertices[vCount + 2].texCoord[k] = int16(dL / cL * 32767.0f);
} else
vertices[vCount + 0].texCoord[k] = vertices[vCount + 3].texCoord[k] = int16(cL / dL * 32767.0f);
}
}
void addSprite(Index *indices, Vertex *vertices, int &iCount, int &vCount, int vStart, int16 x, int16 y, int16 z, const TR::SpriteTexture &sprite, uint8 intensity, bool expand = false) {
addQuad(indices, iCount, vCount, vStart, NULL, NULL);
@@ -939,12 +1002,12 @@ struct MeshBuilder {
quad[2].coord = { x1, y1, z, 0 };
quad[3].coord = { x0, y1, z, 0 };
quad[0].normal = quad[1].normal = quad[2].normal = quad[3].normal = { 0, 0, 0, 0 };
quad[0].color = quad[1].color = quad[2].color = quad[3].color = { 255, 255, 255, intensity };
quad[0].param = quad[1].param = quad[2].param = quad[3].param = { 0, 0, 0, 0 };
int tx = (sprite.tile % 4) * 256;
int ty = (sprite.tile / 4) * 256;
int tx = (sprite.tile % 4) * 256;
int ty = (sprite.tile / 4) * 256;
int16 u0 = (((tx + sprite.texCoord[0].x) << 5));
int16 v0 = (((ty + sprite.texCoord[0].y) << 5));
@@ -992,7 +1055,8 @@ struct MeshBuilder {
s = int(s) * 32767 / 1024;
t = int(t) * 32767 / 1024;
v.texCoord = { s, t, 0, 0 };
v.texCoord = { s, t, 32767, 32767 };
v.param = { 0, 0, 0, 0 };
}
vCount += 4;
@@ -1018,7 +1082,7 @@ struct MeshBuilder {
Vertex &v = vertices[vCount + i];
v.normal = { 0, 0, 0, 0 };
v.color = *((ubyte4*)&color1);
v.texCoord = { 32688, 32688, 0, 0 };
v.texCoord = { 32688, 32688, 32767, 32767 };
}
addQuad(indices, iCount, vCount, 0, vertices, NULL); vCount += 4;
@@ -1038,7 +1102,7 @@ struct MeshBuilder {
Vertex &v = vertices[vCount + i];
v.normal = { 0, 0, 0, 0 };
v.color = *((ubyte4*)&color2);
v.texCoord = { 32688, 32688, 0, 0 };
v.texCoord = { 32688, 32688, 32767, 32767 };
}
addQuad(indices, iCount, vCount, 0, vertices, NULL); vCount += 4;

View File

@@ -5,8 +5,9 @@
#define SHADER_ATTRIBS(E) \
E( aCoord ) \
E( aTexCoord ) \
E( aNormal ) \
E( aTexCoord ) \
E( aParam ) \
E( aColor )
#define SHADER_SAMPLERS(E) \

View File

@@ -16,10 +16,8 @@ varying vec4 vColor;
attribute vec4 aTexCoord;
attribute vec4 aColor;
#define TEXCOORD_SCALE (1.0 / 32767.0)
void main() {
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
vTexCoord = aTexCoord.xy;
vColor = aColor * uMaterial;
gl_Position = uViewProj * vec4(aCoord.xy * uPosScale.zw + uPosScale.xy, 0.0, 1.0);
}

View File

@@ -4,19 +4,23 @@ R"====(
precision highp float;
#endif
varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction
#if defined(OPT_WATER) && defined(UNDERWATER)
varying vec2 vCausticsCoord; // - xy caustics texture coord
#endif
#ifndef PASS_SHADOW
varying vec4 vViewVec; // xyz - dir * dist, w - coord.y
uniform vec3 uViewPos;
varying vec4 vViewVec; // xyz - dir * dist, w - coord.y
varying vec4 vDiffuse;
#ifndef TYPE_FLASH
#ifdef PASS_COMPOSE
varying vec4 vNormal; // xyz - normal dir, w - fog factor
varying vec3 vNormal; // xyz - normal dir
varying vec4 vLightProj;
varying vec3 vLightVec;
varying vec4 vLightVec; // xyz - dir, w - fog factor
#ifdef OPT_SHADOW
varying vec3 vAmbient;
@@ -26,7 +30,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
uniform vec4 uLightColor[4]; // xyz - color, w - radius * intensity
#endif
varying vec4 vLight; // 4 lights intensity
varying vec4 vLight; // 4 lights intensity
#if defined(OPT_WATER) && defined(UNDERWATER)
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
@@ -38,15 +42,15 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
vec3 calcAmbient(vec3 n) {
vec3 sqr = n * n;
vec3 pos = step(0.0, n);
return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) +
sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) +
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) +
sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) +
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
}
#endif
#endif
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#endif
#ifdef VERTEX
@@ -71,6 +75,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
attribute vec4 aCoord;
attribute vec4 aTexCoord;
attribute vec4 aParam;
#ifndef PASS_AMBIENT
attribute vec4 aNormal;
@@ -80,7 +85,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
attribute vec4 aColor;
#endif
#define TEXCOORD_SCALE (1.0 / 32767.0)
#define TEXCOORD_SCALE 32767.0
vec3 mulQuat(vec4 q, vec3 v) {
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + v * q.w);
@@ -103,7 +108,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
vec4 coord = vec4(mulBasis(rBasisRot, rBasisPos, aCoord.xyz), rBasisPos.w);
#ifdef TYPE_SPRITE
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
coord.xyz += (uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w) * TEXCOORD_SCALE;
#endif
#ifndef PASS_SHADOW
@@ -129,7 +134,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
fog = length(vViewVec.xyz);
#endif
vNormal.w = clamp(1.0 / exp(fog), 0.0, 1.0);
vLightVec.w = clamp(1.0 / exp(fog), 0.0, 1.0);
#endif
return coord;
@@ -161,22 +166,24 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
vec3 lv2 = (uLightPos[2].xyz - coord) * uLightColor[2].w;
vec3 lv3 = (uLightPos[3].xyz - coord) * uLightColor[3].w;
vLightVec = lv0;
vLightVec.xyz = lv0;
vec4 lum, att;
#ifdef TYPE_ENTITY
lum.x = dot(vNormal.xyz, normalize(lv0)); att.x = dot(lv0, lv0);
lum.x = dot(vNormal.xyz, normalize(lv0));
att.x = dot(lv0, lv0);
#else
lum.x = aColor.w; att.x = 0.0;
lum.x = aColor.w;
att.x = 0.0;
#ifdef TYPE_SPRITE
lum.x *= uMaterial.y;
#endif
#endif
lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
vec4 light = max(vec4(0.0), lum) * max(vec4(0.0), vec4(1.0) - att);
#ifdef UNDERWATER
@@ -219,20 +226,18 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
}
void _uv(vec3 coord) {
vTexCoord = aTexCoord;
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
// animated texture coordinates
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
float frame = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y;
vec2 offset = uAnimTexOffsets[int(range.x + frame)]; // texCoord offset from first frame
vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE;
#else
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
vec2 range = uAnimTexRanges[int(aParam.x)]; // x - start index, y - count
float frame = fract((aParam.y + uParam.x * 4.0 - range.x) / range.y) * range.y;
vec2 offset = uAnimTexOffsets[int(range.x + frame)]; // texCoord offset from first frame
vTexCoord.xy += offset;
vTexCoord.xy *= vTexCoord.zw;
#endif
#if defined(OPT_WATER) && defined(UNDERWATER)
vTexCoord.zw = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
#else
vTexCoord.zw = vec2(1.0);
vCausticsCoord.xy = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
#endif
}
@@ -346,13 +351,13 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
} else
rShadow /= 4.0;
float fade = clamp(dot(vLightVec, vLightVec), 0.0, 1.0);
float fade = clamp(dot(vLightVec.xyz, vLightVec.xyz), 0.0, 1.0);
return rShadow + (1.0 - rShadow) * fade;
}
float getShadow() {
#ifdef TYPE_ROOM
float vis = min(dot(vNormal.xyz, vLightVec), vLightProj.w);
float vis = min(dot(vNormal.xyz, vLightVec.xyz), vLightProj.w);
#else
float vis = vLightProj.w;
#endif
@@ -369,9 +374,10 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
#if defined(OPT_WATER) && defined(UNDERWATER)
float calcCaustics(vec3 n) {
vec2 cc = vCausticsCoord.xy;
vec2 border = vec2(256.0) / (uRoomSize.zw - uRoomSize.xy);
vec2 fade = smoothstep(vec2(0.0), border, vTexCoord.zw) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), vTexCoord.zw));
return texture2D(sReflect, vTexCoord.zw).g * max(0.0, -n.y) * fade.x * fade.y;
vec2 fade = smoothstep(vec2(0.0), border, cc) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), cc));
return texture2D(sReflect, cc).g * max(0.0, -n.y) * fade.x * fade.y;
}
#endif
#endif
@@ -391,7 +397,11 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
color = textureCube(sEnvironment, normalize(rv));
#endif
#else
color = texture2D(sDiffuse, vTexCoord.xy);
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
color = texture2D(sDiffuse, vTexCoord.xy / vTexCoord.zw);
#else
color = texture2D(sDiffuse, vTexCoord.xy);
#endif
#endif
#ifdef ALPHA_TEST
@@ -444,7 +454,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
#endif
#ifdef TYPE_ENTITY
color.xyz += calcSpecular(n, vViewVec.xyz, vLightVec, uLightColor[0], uMaterial.z * rShadow + 0.03);
color.xyz += calcSpecular(n, vViewVec.xyz, vLightVec.xyz, uLightColor[0], uMaterial.z * rShadow + 0.03);
#endif
#endif
@@ -460,9 +470,9 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
#ifdef UNDERWATER
color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vNormal.w);
color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vLightVec.w);
#else
color.xyz = mix(vec3(0.0), color.xyz, vNormal.w);
color.xyz = mix(vec3(0.0), color.xyz, vLightVec.w);
#endif
#endif

View File

@@ -140,9 +140,9 @@ int nextPow2(uint32 x) {
}
uint32 fnv32(const char *data, int32 size, uint32 hash = 0x811c9dc5) {
for (int i = 0; i < size; i++)
hash = (hash ^ data[i]) * 0x01000193;
return hash;
for (int i = 0; i < size; i++)
hash = (hash ^ data[i]) * 0x01000193;
return hash;
}
struct vec2 {
@@ -711,12 +711,23 @@ struct short2 {
struct short3 {
int16 x, y, z;
short3() {}
short3(int16 x, int16 y, int16 z) : x(x), y(y), z(z) {}
operator vec3() const { return vec3((float)x, (float)y, (float)z); };
short3 operator + (const short3 &v) const { return short3(x + v.x, y + v.y, z + v.z); }
short3 operator - (const short3 &v) const { return short3(x - v.x, y - v.y, z - v.z); }
};
struct short4 {
int16 x, y, z, w;
operator vec3() const { return vec3((float)x, (float)y, (float)z); };
operator vec3() const { return vec3((float)x, (float)y, (float)z); };
operator short3() const { return *((short3*)this); }
inline int16& operator [] (int index) const { ASSERT(index >= 0 && index <= 3); return ((int16*)this)[index]; }
};
quat rotYXZ(const vec3 &a) {