add basic edge shading
This commit is contained in:
parent
c600c82e8f
commit
c19a19166b
5 changed files with 73 additions and 182 deletions
|
|
@ -6,6 +6,13 @@ uniform vec2 textureTiling;
|
|||
in vec2 fragTexCoord;
|
||||
in vec2 fragTexCoord2;
|
||||
in vec4 fragColor;
|
||||
flat in int ambientOcclusionSide1;
|
||||
flat in int ambientOcclusionSide2;
|
||||
flat in int ambientOcclusionCorner1;
|
||||
flat in int ambientOcclusionCorner2;
|
||||
flat in int ambientOcclusionCorner3;
|
||||
flat in int quadHeight;
|
||||
flat in int quadWidth;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
|
|
@ -13,4 +20,10 @@ void main()
|
|||
{
|
||||
vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTexCoord2)) / textureTiling;
|
||||
outColor = texture(diffuseMap, texCoord);
|
||||
|
||||
ivec2 floorFragTexCoord2 = ivec2(fragTexCoord2);
|
||||
if ((fragTexCoord2.x < 0.05 || fragTexCoord2.x > quadWidth-0.05) && (((ambientOcclusionSide1 >> floorFragTexCoord2.y) & 1) == 1)) outColor *= 0.5;
|
||||
else if((fragTexCoord2.y < 0.05 || fragTexCoord2.y > quadHeight-0.05) && (((ambientOcclusionSide2 >> floorFragTexCoord2.y) & 1) == 1)) outColor *= 0.5;
|
||||
|
||||
outColor.a = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,22 @@
|
|||
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec2 vertexTexCoord2;
|
||||
in vec2 vertexTexCoord2;
|
||||
in vec4 vertexColor;
|
||||
in vec4 vertexTangent; // metadata1
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec2 fragTexCoord2;
|
||||
out vec4 fragColor;
|
||||
|
||||
flat out int ambientOcclusionSide1;
|
||||
flat out int ambientOcclusionSide2;
|
||||
flat out int ambientOcclusionCorner1;
|
||||
flat out int ambientOcclusionCorner2;
|
||||
flat out int ambientOcclusionCorner3;
|
||||
flat out int quadHeight;
|
||||
flat out int quadWidth;
|
||||
|
||||
uniform mat4 mvp;
|
||||
|
||||
void main() {
|
||||
|
|
@ -16,4 +25,15 @@ void main() {
|
|||
fragColor = vertexColor;
|
||||
fragTexCoord2 = vertexTexCoord2;
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
|
||||
// metadata 1 processing
|
||||
ambientOcclusionSide1 = floatBitsToInt(vertexTangent.x);
|
||||
ambientOcclusionSide2 = floatBitsToInt(vertexTangent.y);
|
||||
int metadata1Z = floatBitsToInt(vertexTangent.z);
|
||||
int metadata1W = floatBitsToInt(vertexTangent.w);
|
||||
ambientOcclusionCorner1 = (metadata1Z & 0x1) >> 0;
|
||||
ambientOcclusionCorner2 = (metadata1Z & 0x2) >> 1;
|
||||
ambientOcclusionCorner3 = (metadata1Z & 0x4) >> 2;
|
||||
quadHeight = (metadata1Z & 0x1f8) >> 3;
|
||||
quadWidth = (metadata1Z & 0x7e00) >> 9;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,177 +0,0 @@
|
|||
const std = @import("std");
|
||||
const raylib_helper = @import("../lib_helpers/raylib_helper.zig");
|
||||
const raylib = raylib_helper.raylib;
|
||||
|
||||
const MAX_VBOS = 4;
|
||||
|
||||
const VERTICES_VBO_ID = 0;
|
||||
const TEXCOORDS_VBO_ID = 1;
|
||||
const TEXCOORDS2_VBO_ID = 2;
|
||||
const NORMALS_VBO_ID = 3;
|
||||
|
||||
const ChunkMesh = packed struct {
|
||||
vertexCount: i32,
|
||||
triangleCount: i32,
|
||||
|
||||
vertices: [*]f32, // vertex position, XYZ, 3 vars per vertex
|
||||
texcoords: [*]f32, // vertex texture coorinates, UV, 2 vars per vertex
|
||||
texcoords2: [*]f32, // vertex second texture coorinates, UV, 2 vars per vertex
|
||||
normals: [*]f32, // vertex normals, XYZ, 3 vars per vertex
|
||||
|
||||
vaoId: u32,
|
||||
vboId: [*]u32,
|
||||
};
|
||||
|
||||
pub fn UploadChunkMesh(mesh: ChunkMesh, dynamic: bool) void {
|
||||
if (mesh.vaoId > 0) {
|
||||
raylib.TraceLog(raylib.LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded chunk mesh", mesh.vaoId);
|
||||
return;
|
||||
}
|
||||
|
||||
mesh.vboId = @ptrCast(@alignCast(raylib.MemAlloc(@sizeOf(u32) * MAX_VBOS)));
|
||||
mesh.vaoId = 0;
|
||||
|
||||
mesh.vboId[VERTICES_VBO_ID] = 0;
|
||||
mesh.vboId[TEXCOORDS_VBO_ID] = 0;
|
||||
mesh.vboId[TEXCOORDS2_VBO_ID] = 0;
|
||||
mesh.vboId[NORMALS_VBO_ID] = 0;
|
||||
|
||||
mesh.vaoId = raylib.rlLoadVertexArray();
|
||||
raylib.rlEnableVertexArray(mesh.vaoId);
|
||||
|
||||
mesh.vboId[VERTICES_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.vertices, mesh.vertexCount * 3 * @sizeOf(f32), dynamic);
|
||||
raylib.rlSetVertexAttribute(VERTICES_VBO_ID, 3, raylib.RL_FLOAT, false, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(VERTICES_VBO_ID);
|
||||
|
||||
mesh.vboId[TEXCOORDS_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.texcoords, mesh.vertexCount * 2 * @sizeOf(f32), dynamic);
|
||||
raylib.rlSetVertexAttribute(TEXCOORDS_VBO_ID, 2, raylib.RL_FLOAT, false, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(TEXCOORDS_VBO_ID);
|
||||
|
||||
mesh.vboId[TEXCOORDS2_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.texcoords, mesh.vertexCount * 2 * @sizeOf(f32), dynamic);
|
||||
raylib.rlSetVertexAttribute(TEXCOORDS2_VBO_ID, 2, raylib.RL_FLOAT, false, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(TEXCOORDS2_VBO_ID);
|
||||
|
||||
mesh.vboId[NORMALS_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.vertices, mesh.vertexCount * 3 * @sizeOf(f32), dynamic);
|
||||
raylib.rlSetVertexAttribute(NORMALS_VBO_ID, 3, raylib.RL_FLOAT, false, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(NORMALS_VBO_ID);
|
||||
|
||||
if (mesh.vaoId > 0) {
|
||||
raylib.TraceLog(raylib.LOG_INFO, "VAO: [ID %i] Chunk mesh uploaded successfully to VRAM (GPU)", mesh.vaoId);
|
||||
} else {
|
||||
raylib.TraceLog(raylib.LOG_INFO, "VBO: Chunk mesh uploaded successfully to VRAM (GPU)");
|
||||
}
|
||||
raylib.rlDisableVertexArray();
|
||||
}
|
||||
pub fn UpdateChunkMeshBuffer(mesh: ChunkMesh, index: i32, data: ?*const anyopaque, dataSize: i32, offset: i32) void {
|
||||
raylib.rlUpdateVertexBuffer(mesh.vboId[index], data, dataSize, offset);
|
||||
}
|
||||
pub fn UnloadChunkMesh(mesh: ChunkMesh) void {
|
||||
raylib.rlUnloadVertexArray(mesh.vaoId);
|
||||
if (mesh.vboId != null) {
|
||||
for (0..MAX_VBOS) |i| {
|
||||
raylib.rlUnloadVertexBuffer(mesh.vboId[i]);
|
||||
}
|
||||
}
|
||||
raylib.MemFree(mesh.vboId);
|
||||
|
||||
raylib.MemFree(mesh.vertices);
|
||||
raylib.MemFree(mesh.texcoords);
|
||||
raylib.MemFree(mesh.texcoords2);
|
||||
raylib.MemFree(mesh.normals);
|
||||
}
|
||||
pub fn DrawChunkMesh(mesh: ChunkMesh, material: raylib.Material, transform: raylib.Matrix) void {
|
||||
raylib.rlEnableShader(material.shader.id);
|
||||
if (material.shader.locs[raylib.SHADER_LOC_COLOR_DIFFUSE] != -1) {
|
||||
const values: [4]f32 = [4]f32{
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.r)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.g)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.b)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.a)) / 255.0,
|
||||
};
|
||||
raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_COLOR_DIFFUSE], values, raylib.SHADER_UNIFORM_VEC4, 1);
|
||||
}
|
||||
if (material.shader.locs[raylib.SHADER_LOC_COLOR_SPECULAR] != -1) {
|
||||
const values: [4]f32 = [4]f32{
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.r)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.g)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.b)) / 255.0,
|
||||
@as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.a)) / 255.0,
|
||||
};
|
||||
raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_COLOR_SPECULAR], values, raylib.SHADER_UNIFORM_VEC4, 1);
|
||||
}
|
||||
|
||||
var matModel: raylib.Matrix = raylib.MatrixIdentity();
|
||||
const matView: raylib.Matrix = raylib.rlGetMatrixModelview();
|
||||
var matModelView: raylib.Matrix = raylib.MatrixIdentity();
|
||||
const matProjection: raylib.Matrix = raylib.rlGetMatrixProjection();
|
||||
|
||||
if (material.shader.locs[raylib.SHADER_LOC_MATRIX_VIEW] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_VIEW], matView);
|
||||
if (material.shader.locs[raylib.SHADER_LOC_MATRIX_PROJECTION] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_PROJECTION], matProjection);
|
||||
|
||||
matModel = raylib.MatrixMultiply(transform, raylib.rlGetMatrixTransform());
|
||||
if (material.shader.locs[raylib.SHADER_LOC_MATRIX_MODEL] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_MODEL], matModel);
|
||||
|
||||
matModelView = raylib.MatrixMultiply(matModel, matView);
|
||||
if (material.shader.locs[raylib.SHADER_LOC_MATRIX_NORMAL] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_NORMAL], raylib.MatrixTranspose(raylib.MatrixInvert(matModel)));
|
||||
|
||||
for (0..raylib.MAX_MATERIAL_MAPS) |i| {
|
||||
if (material.maps[i].texture.id > 0) {
|
||||
raylib.rlActiveTextureSlot(i);
|
||||
if (i == raylib.MATERIAL_MAP_IRRADIANCE or i == raylib.MATERIAL_MAP_PREFILTER or i == raylib.MATERIAL_MAP_CUBEMAP) {
|
||||
raylib.rlEnableTextureCubemap(material.maps[i].texture.id);
|
||||
} else {
|
||||
raylib.rlEnableTexture(material.maps[i].texture.id);
|
||||
}
|
||||
raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE + i], &i, raylib.SHADER_UNIFORM_INT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!raylib.rlEnableVertexArray(mesh.vaoId)) {
|
||||
raylib.rlEnableVertexBuffer(mesh.vboId[0]);
|
||||
raylib.rlSetVertexAttribute(material.shader.locs[VERTICES_VBO_ID], 3, raylib.RL_FLOAT, 0, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(material.shader.locs[VERTICES_VBO_ID]);
|
||||
|
||||
raylib.rlEnableVertexBuffer(mesh.vboId[1]);
|
||||
raylib.rlSetVertexAttribute(material.shader.locs[TEXCOORDS_VBO_ID], 2, raylib.RL_FLOAT, 0, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(material.shader.locs[TEXCOORDS_VBO_ID]);
|
||||
|
||||
raylib.rlEnableVertexBuffer(mesh.vboId[2]);
|
||||
raylib.rlSetVertexAttribute(material.shader.locs[TEXCOORDS2_VBO_ID], 2, raylib.RL_FLOAT, 0, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(material.shader.locs[TEXCOORDS2_VBO_ID]);
|
||||
|
||||
raylib.rlEnableVertexBuffer(mesh.vboId[3]);
|
||||
raylib.rlSetVertexAttribute(material.shader.locs[NORMALS_VBO_ID], 3, raylib.RL_FLOAT, 0, 0, 0);
|
||||
raylib.rlEnableVertexAttribute(material.shader.locs[NORMALS_VBO_ID]);
|
||||
}
|
||||
var eyeCount = 1;
|
||||
if (raylib.rlIsStereoRenderEnabled()) {
|
||||
eyeCount = 2;
|
||||
}
|
||||
for (0..eyeCount) |eye| {
|
||||
var matModelViewProjection: raylib.Matrix = raylib.MatrixIdentity();
|
||||
if (eyeCount == 1) {
|
||||
matModelViewProjection = raylib.MatrixMultiply(matModelView, matProjection);
|
||||
} else {
|
||||
raylib.rlViewport(@divTrunc(eye * raylib.rlGetFramebufferWidth(), 2), 0, @divTrunc(raylib.rlGetFramebufferWidth(), 2), raylib.rlGetFramebufferHeight());
|
||||
matModelViewProjection = raylib.MatrixMultiply(raylib.MatrixMultiply(matModelView, raylib.rlGetMatrixViewOffsetStereo(eye)), raylib.rlGetMatrixProjectionStereo(eye));
|
||||
}
|
||||
raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_MVP], matModelViewProjection);
|
||||
raylib.rlDrawVertexArray(0, mesh.vertexCount);
|
||||
}
|
||||
for (0..raylib.MAX_MATERIAL_MAPS) |i| {
|
||||
if (material.maps[i].texture.id > 0) {
|
||||
raylib.rlActiveTextureSlot(i);
|
||||
if (((i == raylib.MATERIAL_MAP_IRRADIANCE) or (i == raylib.MATERIAL_MAP_PREFILTER)) or (i == raylib.MATERIAL_MAP_CUBEMAP)) {
|
||||
raylib.rlDisableTextureCubemap();
|
||||
} else {
|
||||
raylib.rlDisableTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
raylib.rlDisableVertexArray();
|
||||
raylib.rlDisableVertexBuffer();
|
||||
raylib.rlDisableVertexBufferElement();
|
||||
raylib.rlDisableShader();
|
||||
raylib.rlSetMatrixModelview(matView);
|
||||
raylib.rlSetMatrixProjection(matProjection);
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ const raylib_helper = @import("../lib_helpers/raylib_helper.zig");
|
|||
const raylib = raylib_helper.raylib;
|
||||
const v3 = raylib_helper.v3;
|
||||
const A7r = std.mem.Allocator;
|
||||
const comptimePrint = std.fmt.comptimePrint;
|
||||
|
||||
const RawQuad = struct {
|
||||
tile: u32,
|
||||
|
|
@ -15,6 +16,24 @@ const RawQuad = struct {
|
|||
height: f32,
|
||||
};
|
||||
|
||||
const Metadata1 = packed struct {
|
||||
ambient_occlusion_1: u32,
|
||||
ambient_occlusion_2: u32,
|
||||
ambient_occlusion_corner1: bool,
|
||||
ambient_occlusion_corner2: bool,
|
||||
ambient_occlusion_corner3: bool,
|
||||
quad_height: u6,
|
||||
quad_width: u6,
|
||||
unused: u17 = 0,
|
||||
unused_2: u32 = 0,
|
||||
};
|
||||
|
||||
comptime {
|
||||
if (@bitSizeOf(Metadata1) != 128) {
|
||||
@compileError(comptimePrint("Metadata 1 has wrong size. Expected 128 bits, found {}", .{@bitSizeOf(Metadata1)}));
|
||||
}
|
||||
}
|
||||
|
||||
pub const Chunk = struct {
|
||||
tiles: []u32,
|
||||
a7r: A7r,
|
||||
|
|
@ -151,6 +170,7 @@ pub const Chunk = struct {
|
|||
const texcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
|
||||
const texcoords2: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
|
||||
const normals: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
|
||||
const metadata1_packed: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4)));
|
||||
|
||||
for (raw_quads.items, 0..) |raw_quad, i| {
|
||||
if (raw_quad.tile <= 0) continue;
|
||||
|
|
@ -214,6 +234,22 @@ pub const Chunk = struct {
|
|||
texcoords[12 * i + 11] = bottom_uv;
|
||||
texcoords2[12 * i + 10] = 0.0;
|
||||
texcoords2[12 * i + 11] = raw_quad.height;
|
||||
|
||||
for (0..6) |j| {
|
||||
const metadata1 = Metadata1{
|
||||
.ambient_occlusion_1 = 0xffffffff,
|
||||
.ambient_occlusion_2 = 0xffffffff,
|
||||
.ambient_occlusion_corner1 = true,
|
||||
.ambient_occlusion_corner2 = true,
|
||||
.ambient_occlusion_corner3 = true,
|
||||
.quad_height = @intFromFloat(raw_quad.height),
|
||||
.quad_width = @intFromFloat(raw_quad.width),
|
||||
};
|
||||
const metadata1_baked: [4]f32 = @bitCast(metadata1);
|
||||
for (0..4) |k| {
|
||||
metadata1_packed[24 * i + 4 * j + k] = @bitCast(@as(f32, metadata1_baked[k]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mesh = raylib.Mesh{
|
||||
|
|
@ -224,6 +260,7 @@ pub const Chunk = struct {
|
|||
.texcoords = texcoords,
|
||||
.texcoords2 = texcoords2,
|
||||
.normals = normals,
|
||||
.tangents = metadata1_packed,
|
||||
|
||||
.vaoId = 0,
|
||||
.vboId = null,
|
||||
|
|
|
|||
6
todo.md
6
todo.md
|
|
@ -2,11 +2,9 @@
|
|||
yoink implementation of mesh into meshes.zig so i could modify it to add ambient occlusion vars
|
||||
implement ambient occlusion either
|
||||
- via passing extra info to shader (can use 132 bits to indicate what tiles around the quad are obsuring light. need to pass as an extra variable)
|
||||
implement animated textures by either
|
||||
- making literally everything animated
|
||||
- somehow passing extra info to shader
|
||||
implement animations (smooth or minecraft like), random orientation/mirroring, metallicity (shine on edges)
|
||||
implement second layer of textures on top of first one for more details
|
||||
limit vertical camera rotations
|
||||
update libraries like raylib
|
||||
|
||||
# future tasks
|
||||
implement chunk meshing cache to reduce delay on block placement
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue