Skip to content

Commit

Permalink
gpu: fix texture hillskew
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam- committed Mar 20, 2024
1 parent c1699c8 commit a4bed9b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ int4 rotate_vertex(__constant struct uniform *uni, int4 vertex, int orientation)
return (int4)(x, vertex.y, z, vertex.w);
}

float3 rotatef_vertex(float3 vertex, int orientation) {
float4 rotatef_vertex(float4 vertex, int orientation) {
float rad = orientation * UNIT;
float s = sin(rad);
float c = cos(rad);
float x = vertex.z * s + vertex.x * c;
float z = vertex.z * c - vertex.x * s;
return (float3)(x, vertex.y, z);
return (float4)(x, vertex.y, z, vertex.w);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ ivec4 rotate(ivec4 vertex, int orientation) {
return ivec4(x, vertex.y, z, vertex.w);
}

vec3 rotatef(vec3 vertex, int orientation) {
vec4 rotatef(vec4 vertex, int orientation) {
float rad = orientation * UNIT;
float s = sin(rad);
float c = cos(rad);
mat3 m = mat3(c, 0, s, 0, 1, 0, -s, 0, c);
mat4 m = mat4(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
return vertex * m;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,22 @@ int4 hillskew_vertex(read_only image3d_t tileHeightImage, int4 v, int hillskew,
}
}

float4 hillskew_vertexf(read_only image3d_t tileHeightImage, float4 v, int hillskew, int y, int plane) {
if (hillskew == 1) {
float fx = v.x / 128;
float fz = v.z / 128;
int sx = (int)(floor(fx));
int sz = (int)(floor(fz));
float it;
float h1 = mix(tile_height(tileHeightImage, plane, sx, sz), tile_height(tileHeightImage, plane, sx + 1, sz), fract(fx, &it));
float h2 = mix(tile_height(tileHeightImage, plane, sx, sz + 1), tile_height(tileHeightImage, plane, sx + 1, sz + 1), fract(fx, &it));
float h3 = mix(h1, h2, fract(fz, &it));
return (float4)(v.x, v.y + h3 - y, v.z, v.w);
} else {
return v;
}
}

void sort_and_insert(__local struct shared_data *shared, __constant struct uniform *uni, __global const float4 *texb, __global const float4 *temptexb,
__global int4 *vout, __global float4 *uvout, uint localId, struct modelinfo minfo, int thisPriority, int thisDistance, int4 thisrvA,
int4 thisrvB, int4 thisrvC, read_only image3d_t tileHeightImage) {
Expand Down Expand Up @@ -290,9 +306,25 @@ void sort_and_insert(__local struct shared_data *shared, __constant struct unifo
}

int orientation = flags & 0x7ff;
uvout[outOffset + myOffset * 3] = (float4)(texA.x, rotatef_vertex(texA.yzw, orientation) + convert_float3(pos.xyz));
uvout[outOffset + myOffset * 3 + 1] = (float4)(texB.x, rotatef_vertex(texB.yzw, orientation) + convert_float3(pos.xyz));
uvout[outOffset + myOffset * 3 + 2] = (float4)(texC.x, rotatef_vertex(texC.yzw, orientation) + convert_float3(pos.xyz));
// swizzle from (tex,x,y,z) to (x,y,z,tex) for rotate and hillskew
texA = texA.yzwx;
texB = texB.yzwx;
texC = texC.yzwx;
// rotate
texA = rotatef_vertex(texA, orientation);
texB = rotatef_vertex(texB, orientation);
texC = rotatef_vertex(texC, orientation);
// position
texA += convert_float4(pos);
texB += convert_float4(pos);
texC += convert_float4(pos);
// hillskew
texA = hillskew_vertexf(tileHeightImage, texA, hillskew, minfo.y, plane);
texB = hillskew_vertexf(tileHeightImage, texB, hillskew, minfo.y, plane);
texC = hillskew_vertexf(tileHeightImage, texC, hillskew, minfo.y, plane);
uvout[outOffset + myOffset * 3] = texA.wxyz;
uvout[outOffset + myOffset * 3 + 1] = texB.wxyz;
uvout[outOffset + myOffset * 3 + 2] = texC.wxyz;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ int tile_height(int z, int x, int y) {
return texelFetch(tileHeightSampler, ivec3(x + ESCENE_OFFSET, y + ESCENE_OFFSET, z), 0).r << 3;
}

vec4 hillskew_vertexf(vec4 v, int hillskew, int y, int plane) {
if (hillskew == 1) {
float fx = v.x / 128;
float fz = v.z / 128;
int sx = int(floor(fx));
int sz = int(floor(fz));
float h1 = mix(tile_height(plane, sx, sz), tile_height(plane, sx + 1, sz), fract(fx));
float h2 = mix(tile_height(plane, sx, sz + 1), tile_height(plane, sx + 1, sz + 1), fract(fx));
float h3 = mix(h1, h2, fract(fz));
return vec4(v.x, v.y + h3 - y, v.z, v.w);
} else {
return v;
}
}

ivec4 hillskew_vertex(ivec4 v, int hillskew, int y, int plane) {
if (hillskew == 1) {
int px = v.x & 127;
Expand Down Expand Up @@ -285,9 +300,25 @@ void sort_and_insert(uint localId, modelinfo minfo, int thisPriority, int thisDi
}

int orientation = flags & 0x7ff;
uvout[outOffset + myOffset * 3] = vec4(texA.x, rotatef(texA.yzw, orientation) + pos.xyz);
uvout[outOffset + myOffset * 3 + 1] = vec4(texB.x, rotatef(texB.yzw, orientation) + pos.xyz);
uvout[outOffset + myOffset * 3 + 2] = vec4(texC.x, rotatef(texC.yzw, orientation) + pos.xyz);
// swizzle from (tex,x,y,z) to (x,y,z,tex) for rotate and hillskew
texA = texA.yzwx;
texB = texB.yzwx;
texC = texC.yzwx;
// rotate
texA = rotatef(texA, orientation);
texB = rotatef(texB, orientation);
texC = rotatef(texC, orientation);
// position
texA += pos;
texB += pos;
texC += pos;
// hillskew
texA = hillskew_vertexf(texA, hillskew, minfo.y, plane);
texB = hillskew_vertexf(texB, hillskew, minfo.y, plane);
texC = hillskew_vertexf(texC, hillskew, minfo.y, plane);
uvout[outOffset + myOffset * 3] = texA.wxyz;
uvout[outOffset + myOffset * 3 + 1] = texB.wxyz;
uvout[outOffset + myOffset * 3 + 2] = texC.wxyz;
}
}
}

0 comments on commit a4bed9b

Please sign in to comment.