mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 03:29:48 -04:00
Improve performance by storing the noise-based fake reflection in a cube map
This commit is contained in:
parent
1951416317
commit
1a3a16c852
@ -12,6 +12,8 @@ uniform int time;
|
|||||||
uniform vec3 ambientLight;
|
uniform vec3 ambientLight;
|
||||||
uniform sampler2DArray texture_sampler;
|
uniform sampler2DArray texture_sampler;
|
||||||
uniform sampler2DArray emissionSampler;
|
uniform sampler2DArray emissionSampler;
|
||||||
|
uniform samplerCube reflectionMap;
|
||||||
|
uniform float reflectionMapSize;
|
||||||
|
|
||||||
layout(binding = 3) uniform sampler2D depthTexture;
|
layout(binding = 3) uniform sampler2D depthTexture;
|
||||||
|
|
||||||
@ -68,51 +70,6 @@ uniform float zFar;
|
|||||||
|
|
||||||
uniform Fog fog;
|
uniform Fog fog;
|
||||||
|
|
||||||
ivec3 random3to3(ivec3 v) {
|
|
||||||
v &= 15;
|
|
||||||
ivec3 fac = ivec3(11248723, 105436839, 45399083);
|
|
||||||
int seed = v.x*fac.x ^ v.y*fac.y ^ v.z*fac.z;
|
|
||||||
v = seed*fac;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
float snoise(vec3 v){ // TODO: Maybe use a cubemap.
|
|
||||||
const vec2 C = vec2(1.0/6.0, 1.0/3.0);
|
|
||||||
|
|
||||||
// First corner
|
|
||||||
vec3 i = floor(v + dot(v, C.yyy));
|
|
||||||
vec3 x0 = v - i + dot(i, C.xxx);
|
|
||||||
|
|
||||||
// Other corners
|
|
||||||
vec3 g = step(x0.yzx, x0.xyz);
|
|
||||||
vec3 l = 1.0 - g;
|
|
||||||
vec3 i1 = min(g.xyz, l.zxy);
|
|
||||||
vec3 i2 = max(g.xyz, l.zxy);
|
|
||||||
|
|
||||||
// x0 = x0 - 0. + 0.0 * C
|
|
||||||
vec3 x1 = x0 - i1 + 1.0*C.xxx;
|
|
||||||
vec3 x2 = x0 - i2 + 2.0*C.xxx;
|
|
||||||
vec3 x3 = x0 - 1. + 3.0*C.xxx;
|
|
||||||
|
|
||||||
// Get gradients:
|
|
||||||
ivec3 rand = random3to3(ivec3(i));
|
|
||||||
vec3 p0 = vec3(rand);
|
|
||||||
|
|
||||||
rand = random3to3((ivec3(i + i1)));
|
|
||||||
vec3 p1 = vec3(rand);
|
|
||||||
|
|
||||||
rand = random3to3((ivec3(i + i2)));
|
|
||||||
vec3 p2 = vec3(rand);
|
|
||||||
|
|
||||||
rand = random3to3((ivec3(i + 1)));
|
|
||||||
vec3 p3 = vec3(rand);
|
|
||||||
|
|
||||||
// Mix final noise value
|
|
||||||
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
|
||||||
m = m*m;
|
|
||||||
return 42.0*dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)))/(1 << 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 unpackColor(uint color) {
|
vec3 unpackColor(uint color) {
|
||||||
return vec3(
|
return vec3(
|
||||||
color>>16 & 255u,
|
color>>16 & 255u,
|
||||||
@ -177,6 +134,15 @@ vec2 getTextureCoordsNormal(vec3 voxelPosition, int textureDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
|
||||||
|
float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||||
|
float scale = (reflectionMapSize - 1)/reflectionMapSize;
|
||||||
|
if (abs(v.x) != M) v.x *= scale;
|
||||||
|
if (abs(v.y) != M) v.y *= scale;
|
||||||
|
if (abs(v.z) != M) v.z *= scale;
|
||||||
|
return texture(reflectionMap, v);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
int textureIndex = textureData[blockType].textureIndices[faceNormal];
|
int textureIndex = textureData[blockType].textureIndices[faceNormal];
|
||||||
textureIndex = textureIndex + time / animation[textureIndex].time % animation[textureIndex].frames;
|
textureIndex = textureIndex + time / animation[textureIndex].time % animation[textureIndex].frames;
|
||||||
@ -199,7 +165,7 @@ void main() {
|
|||||||
// TODO: Change this when it rains.
|
// TODO: Change this when it rains.
|
||||||
// TODO: Normal mapping.
|
// TODO: Normal mapping.
|
||||||
// TODO: Allow textures to contribute to this term.
|
// TODO: Allow textures to contribute to this term.
|
||||||
textureColor.rgb += (textureData[blockType].reflectivity/2*vec3(snoise(normalize(reflect(direction, normals[faceNormal])))) + vec3(textureData[blockType].reflectivity))*ambientLight*normalVariation;
|
textureColor.rgb += (textureData[blockType].reflectivity*fixedCubeMapLookup(reflect(direction, normals[faceNormal])).xyz)*ambientLight*normalVariation;
|
||||||
textureColor.rgb += texture(emissionSampler, vec3(getTextureCoordsNormal(startPosition/16, faceNormal), textureIndex)).rgb;
|
textureColor.rgb += texture(emissionSampler, vec3(getTextureCoordsNormal(startPosition/16, faceNormal), textureIndex)).rgb;
|
||||||
blendColor.rgb *= 1 - textureColor.a;
|
blendColor.rgb *= 1 - textureColor.a;
|
||||||
textureColor.a = 1;
|
textureColor.a = 1;
|
||||||
|
62
assets/cubyz/shaders/fake_reflection.fs
Normal file
62
assets/cubyz/shaders/fake_reflection.fs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
in vec3 coords;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec3 normalVector;
|
||||||
|
uniform vec3 upVector;
|
||||||
|
uniform vec3 rightVector;
|
||||||
|
uniform float frequency;
|
||||||
|
|
||||||
|
ivec3 random3to3(ivec3 v) {
|
||||||
|
v &= 15;
|
||||||
|
ivec3 fac = ivec3(11248723, 105436839, 45399083);
|
||||||
|
int seed = v.x*fac.x ^ v.y*fac.y ^ v.z*fac.z;
|
||||||
|
v = seed*fac;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
float snoise(vec3 v) {
|
||||||
|
const vec2 C = vec2(1.0/6.0, 1.0/3.0);
|
||||||
|
|
||||||
|
// First corner
|
||||||
|
vec3 i = floor(v + dot(v, C.yyy));
|
||||||
|
vec3 x0 = v - i + dot(i, C.xxx);
|
||||||
|
|
||||||
|
// Other corners
|
||||||
|
vec3 g = step(x0.yzx, x0.xyz);
|
||||||
|
vec3 l = 1.0 - g;
|
||||||
|
vec3 i1 = min(g.xyz, l.zxy);
|
||||||
|
vec3 i2 = max(g.xyz, l.zxy);
|
||||||
|
|
||||||
|
// x0 = x0 - 0. + 0.0 * C
|
||||||
|
vec3 x1 = x0 - i1 + 1.0*C.xxx;
|
||||||
|
vec3 x2 = x0 - i2 + 2.0*C.xxx;
|
||||||
|
vec3 x3 = x0 - 1. + 3.0*C.xxx;
|
||||||
|
|
||||||
|
// Get gradients:
|
||||||
|
ivec3 rand = random3to3(ivec3(i));
|
||||||
|
vec3 p0 = vec3(rand);
|
||||||
|
|
||||||
|
rand = random3to3((ivec3(i + i1)));
|
||||||
|
vec3 p1 = vec3(rand);
|
||||||
|
|
||||||
|
rand = random3to3((ivec3(i + i2)));
|
||||||
|
vec3 p2 = vec3(rand);
|
||||||
|
|
||||||
|
rand = random3to3((ivec3(i + 1)));
|
||||||
|
vec3 p3 = vec3(rand);
|
||||||
|
|
||||||
|
// Mix final noise value
|
||||||
|
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
||||||
|
m = m*m;
|
||||||
|
return 42.0*dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)))/(1 << 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 position = normalize(coords);
|
||||||
|
position = position.x*rightVector + position.y*upVector + position.z*normalVector;
|
||||||
|
position *= frequency;
|
||||||
|
fragColor = vec4(vec3(snoise(position)*0.5 + 0.5), 1);
|
||||||
|
}
|
12
assets/cubyz/shaders/fake_reflection.vs
Normal file
12
assets/cubyz/shaders/fake_reflection.vs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location=0) in vec2 inTexCoords;
|
||||||
|
|
||||||
|
out vec3 coords;
|
||||||
|
|
||||||
|
uniform float reflectionMapSize;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
coords = vec3((inTexCoords*2 - vec2(1, 1))*(reflectionMapSize + 1)/reflectionMapSize, 1);
|
||||||
|
gl_Position = vec4(inTexCoords*2 - vec2(1, 1), 0, 1);
|
||||||
|
}
|
@ -397,6 +397,8 @@ pub const meshing = struct {
|
|||||||
@"fog.density": c_int,
|
@"fog.density": c_int,
|
||||||
texture_sampler: c_int,
|
texture_sampler: c_int,
|
||||||
emissionSampler: c_int,
|
emissionSampler: c_int,
|
||||||
|
reflectionMap: c_int,
|
||||||
|
reflectionMapSize: c_int,
|
||||||
time: c_int,
|
time: c_int,
|
||||||
visibilityMask: c_int,
|
visibilityMask: c_int,
|
||||||
voxelSize: c_int,
|
voxelSize: c_int,
|
||||||
@ -449,6 +451,8 @@ pub const meshing = struct {
|
|||||||
|
|
||||||
c.glUniform1i(uniforms.texture_sampler, 0);
|
c.glUniform1i(uniforms.texture_sampler, 0);
|
||||||
c.glUniform1i(uniforms.emissionSampler, 1);
|
c.glUniform1i(uniforms.emissionSampler, 1);
|
||||||
|
c.glUniform1i(uniforms.reflectionMap, 2);
|
||||||
|
c.glUniform1f(uniforms.reflectionMapSize, renderer.reflectionCubeMapSize);
|
||||||
|
|
||||||
c.glUniformMatrix4fv(uniforms.viewMatrix, 1, c.GL_FALSE, @ptrCast(&game.camera.viewMatrix));
|
c.glUniformMatrix4fv(uniforms.viewMatrix, 1, c.GL_FALSE, @ptrCast(&game.camera.viewMatrix));
|
||||||
|
|
||||||
@ -472,6 +476,8 @@ pub const meshing = struct {
|
|||||||
|
|
||||||
c.glUniform1i(transparentUniforms.texture_sampler, 0);
|
c.glUniform1i(transparentUniforms.texture_sampler, 0);
|
||||||
c.glUniform1i(transparentUniforms.emissionSampler, 1);
|
c.glUniform1i(transparentUniforms.emissionSampler, 1);
|
||||||
|
c.glUniform1i(transparentUniforms.reflectionMap, 2);
|
||||||
|
c.glUniform1f(transparentUniforms.reflectionMapSize, renderer.reflectionCubeMapSize);
|
||||||
|
|
||||||
c.glUniformMatrix4fv(transparentUniforms.viewMatrix, 1, c.GL_FALSE, @ptrCast(&game.camera.viewMatrix));
|
c.glUniformMatrix4fv(transparentUniforms.viewMatrix, 1, c.GL_FALSE, @ptrCast(&game.camera.viewMatrix));
|
||||||
|
|
||||||
|
102
src/graphics.zig
102
src/graphics.zig
@ -6,12 +6,13 @@ const std = @import("std");
|
|||||||
const freetype = @import("freetype");
|
const freetype = @import("freetype");
|
||||||
const harfbuzz = @import("harfbuzz");
|
const harfbuzz = @import("harfbuzz");
|
||||||
|
|
||||||
const Mat4f = @import("vec.zig").Mat4f;
|
const vec = @import("vec.zig");
|
||||||
const Vec4i = @import("vec.zig").Vec4i;
|
const Mat4f = vec.Mat4f;
|
||||||
const Vec4f = @import("vec.zig").Vec4f;
|
const Vec4i = vec.Vec4i;
|
||||||
const Vec2f = @import("vec.zig").Vec2f;
|
const Vec4f = vec.Vec4f;
|
||||||
const Vec2i = @import("vec.zig").Vec2i;
|
const Vec2f = vec.Vec2f;
|
||||||
const Vec3f = @import("vec.zig").Vec3f;
|
const Vec2i = vec.Vec2i;
|
||||||
|
const Vec3f = vec.Vec3f;
|
||||||
|
|
||||||
const main = @import("main.zig");
|
const main = @import("main.zig");
|
||||||
const Window = main.Window;
|
const Window = main.Window;
|
||||||
@ -1323,7 +1324,7 @@ pub const FrameBuffer = struct {
|
|||||||
c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT);
|
c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate(self: *FrameBuffer) bool {
|
pub fn validate(self: *const FrameBuffer) bool {
|
||||||
c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.frameBuffer);
|
c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.frameBuffer);
|
||||||
defer c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
|
defer c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
|
||||||
if(c.glCheckFramebufferStatus(c.GL_FRAMEBUFFER) != c.GL_FRAMEBUFFER_COMPLETE) {
|
if(c.glCheckFramebufferStatus(c.GL_FRAMEBUFFER) != c.GL_FRAMEBUFFER_COMPLETE) {
|
||||||
@ -1333,22 +1334,22 @@ pub const FrameBuffer = struct {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bindTexture(self: *FrameBuffer, target: c_uint) void {
|
pub fn bindTexture(self: *const FrameBuffer, target: c_uint) void {
|
||||||
c.glActiveTexture(target);
|
c.glActiveTexture(target);
|
||||||
c.glBindTexture(c.GL_TEXTURE_2D, self.texture);
|
c.glBindTexture(c.GL_TEXTURE_2D, self.texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bindDepthTexture(self: *FrameBuffer, target: c_uint) void {
|
pub fn bindDepthTexture(self: *const FrameBuffer, target: c_uint) void {
|
||||||
std.debug.assert(self.hasDepthTexture);
|
std.debug.assert(self.hasDepthTexture);
|
||||||
c.glActiveTexture(target);
|
c.glActiveTexture(target);
|
||||||
c.glBindTexture(c.GL_TEXTURE_2D, self.depthTexture);
|
c.glBindTexture(c.GL_TEXTURE_2D, self.depthTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind(self: *FrameBuffer) void {
|
pub fn bind(self: *const FrameBuffer) void {
|
||||||
c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.frameBuffer);
|
c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.frameBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbind(_: *FrameBuffer) void {
|
pub fn unbind(_: *const FrameBuffer) void {
|
||||||
c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
|
c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1533,6 +1534,85 @@ pub const Texture = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const CubeMapTexture = struct {
|
||||||
|
textureID: c_uint,
|
||||||
|
|
||||||
|
pub fn init() CubeMapTexture {
|
||||||
|
var self: CubeMapTexture = undefined;
|
||||||
|
c.glGenTextures(1, &self.textureID);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: CubeMapTexture) void {
|
||||||
|
c.glDeleteTextures(1, &self.textureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bindTo(self: CubeMapTexture, binding: u5) void {
|
||||||
|
c.glActiveTexture(@intCast(c.GL_TEXTURE0 + binding));
|
||||||
|
c.glBindTexture(c.GL_TEXTURE_CUBE_MAP, self.textureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(self: CubeMapTexture) void {
|
||||||
|
c.glBindTexture(c.GL_TEXTURE_CUBE_MAP, self.textureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// (Re-)Generates the GPU buffer.
|
||||||
|
pub fn generate(self: CubeMapTexture, width: u31, height: u31) void {
|
||||||
|
self.bind();
|
||||||
|
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexImage2D(c.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, c.GL_RGBA8, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_WRAP_S, c.GL_CLAMP_TO_EDGE);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_WRAP_T, c.GL_CLAMP_TO_EDGE);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_WRAP_R, c.GL_CLAMP_TO_EDGE);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
|
c.glTexParameteri(c.GL_TEXTURE_CUBE_MAP, c.GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn faceNormal(face: usize) Vec3f {
|
||||||
|
const normals = [_]Vec3f {
|
||||||
|
.{ 1, 0, 0}, // +x
|
||||||
|
.{-1, 0, 0}, // -x
|
||||||
|
.{0, 1, 0}, // +y
|
||||||
|
.{0, -1, 0}, // -y
|
||||||
|
.{0, 0, 1}, // +z
|
||||||
|
.{0, 0, -1}, // -z
|
||||||
|
};
|
||||||
|
return normals[face];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn faceUp(face: usize) Vec3f {
|
||||||
|
const ups = [_]Vec3f {
|
||||||
|
.{0, -1, 0}, // +x
|
||||||
|
.{0, -1, 0}, // -x
|
||||||
|
.{0, 0, 1}, // +y
|
||||||
|
.{0, 0, -1}, // -y
|
||||||
|
.{0, -1, 0}, // +z
|
||||||
|
.{0, -1, 0}, // -z
|
||||||
|
};
|
||||||
|
return ups[face];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn faceRight(face: usize) Vec3f {
|
||||||
|
comptime var rights: [6]Vec3f = undefined;
|
||||||
|
inline for(0..6) |i| {
|
||||||
|
rights[i] = comptime vec.cross(faceNormal(i), faceUp(i));
|
||||||
|
}
|
||||||
|
return rights[face];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bindToFramebuffer(self: CubeMapTexture, fb: FrameBuffer, face: c_uint) void {
|
||||||
|
fb.bind();
|
||||||
|
c.glFramebufferTexture2D(c.GL_FRAMEBUFFER, c.GL_COLOR_ATTACHMENT0, @as(c_uint, c.GL_TEXTURE_CUBE_MAP_POSITIVE_X) + face, self.textureID, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const Color = extern struct {
|
pub const Color = extern struct {
|
||||||
r: u8,
|
r: u8,
|
||||||
g: u8,
|
g: u8,
|
||||||
|
@ -40,24 +40,62 @@ var deferredUniforms: struct {
|
|||||||
zNear: c_int,
|
zNear: c_int,
|
||||||
zFar: c_int,
|
zFar: c_int,
|
||||||
} = undefined;
|
} = undefined;
|
||||||
|
var fakeReflectionShader: graphics.Shader = undefined;
|
||||||
|
var fakeReflectionUniforms: struct {
|
||||||
|
normalVector: c_int,
|
||||||
|
upVector: c_int,
|
||||||
|
rightVector: c_int,
|
||||||
|
frequency: c_int,
|
||||||
|
reflectionMapSize: c_int,
|
||||||
|
} = undefined;
|
||||||
|
|
||||||
pub var activeFrameBuffer: c_uint = 0;
|
pub var activeFrameBuffer: c_uint = 0;
|
||||||
|
|
||||||
|
pub const reflectionCubeMapSize = 64;
|
||||||
|
var reflectionCubeMap: graphics.CubeMapTexture = undefined;
|
||||||
|
|
||||||
pub fn init() !void {
|
pub fn init() !void {
|
||||||
deferredRenderPassShader = try Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", &deferredUniforms);
|
deferredRenderPassShader = try Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", &deferredUniforms);
|
||||||
|
fakeReflectionShader = try Shader.initAndGetUniforms("assets/cubyz/shaders/fake_reflection.vs", "assets/cubyz/shaders/fake_reflection.fs", &fakeReflectionUniforms);
|
||||||
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
|
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
|
||||||
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGBA16F);
|
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGBA16F);
|
||||||
try Bloom.init();
|
try Bloom.init();
|
||||||
try MeshSelection.init();
|
try MeshSelection.init();
|
||||||
try MenuBackGround.init();
|
try MenuBackGround.init();
|
||||||
|
reflectionCubeMap = graphics.CubeMapTexture.init();
|
||||||
|
reflectionCubeMap.generate(reflectionCubeMapSize, reflectionCubeMapSize);
|
||||||
|
initReflectionCubeMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
deferredRenderPassShader.deinit();
|
deferredRenderPassShader.deinit();
|
||||||
|
fakeReflectionShader.deinit();
|
||||||
worldFrameBuffer.deinit();
|
worldFrameBuffer.deinit();
|
||||||
Bloom.deinit();
|
Bloom.deinit();
|
||||||
MeshSelection.deinit();
|
MeshSelection.deinit();
|
||||||
MenuBackGround.deinit();
|
MenuBackGround.deinit();
|
||||||
|
reflectionCubeMap.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initReflectionCubeMap() void {
|
||||||
|
c.glViewport(0, 0, reflectionCubeMapSize, reflectionCubeMapSize);
|
||||||
|
var framebuffer: graphics.FrameBuffer = undefined;
|
||||||
|
framebuffer.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE);
|
||||||
|
defer framebuffer.deinit();
|
||||||
|
framebuffer.bind();
|
||||||
|
fakeReflectionShader.bind();
|
||||||
|
c.glUniform1f(fakeReflectionUniforms.frequency, 1);
|
||||||
|
c.glUniform1f(fakeReflectionUniforms.reflectionMapSize, reflectionCubeMapSize);
|
||||||
|
for(0..6) |face| {
|
||||||
|
c.glUniform3fv(fakeReflectionUniforms.normalVector, 1, @ptrCast(&graphics.CubeMapTexture.faceNormal(face)));
|
||||||
|
c.glUniform3fv(fakeReflectionUniforms.upVector, 1, @ptrCast(&graphics.CubeMapTexture.faceUp(face)));
|
||||||
|
c.glUniform3fv(fakeReflectionUniforms.rightVector, 1, @ptrCast(&graphics.CubeMapTexture.faceRight(face)));
|
||||||
|
reflectionCubeMap.bindToFramebuffer(framebuffer, @intCast(face));
|
||||||
|
c.glBindVertexArray(graphics.draw.rectVAO);
|
||||||
|
c.glDisable(c.GL_DEPTH_TEST);
|
||||||
|
c.glDisable(c.GL_CULL_FACE);
|
||||||
|
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var worldFrameBuffer: graphics.FrameBuffer = undefined;
|
var worldFrameBuffer: graphics.FrameBuffer = undefined;
|
||||||
@ -138,6 +176,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
|
|||||||
// Update the uniforms. The uniforms are needed to render the replacement meshes.
|
// Update the uniforms. The uniforms are needed to render the replacement meshes.
|
||||||
chunk.meshing.bindShaderAndUniforms(game.projectionMatrix, ambientLight, time);
|
chunk.meshing.bindShaderAndUniforms(game.projectionMatrix, ambientLight, time);
|
||||||
|
|
||||||
|
reflectionCubeMap.bindTo(2);
|
||||||
c.glActiveTexture(c.GL_TEXTURE0);
|
c.glActiveTexture(c.GL_TEXTURE0);
|
||||||
blocks.meshes.blockTextureArray.bind();
|
blocks.meshes.blockTextureArray.bind();
|
||||||
c.glActiveTexture(c.GL_TEXTURE1);
|
c.glActiveTexture(c.GL_TEXTURE1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user