Start implementing alpha mask instead of alpha blend for everything,
add debug bounds rendering
This commit is contained in:
parent
8031b77c8a
commit
8e9cb3fa5b
29
assets/shaders/debug.glsl
Normal file
29
assets/shaders/debug.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
// UBOs
|
||||
layout(std140, binding = 0) uniform Matrices {
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
};
|
||||
|
||||
layout(location = 2) uniform vec3 color;
|
||||
|
||||
// Input, output blocks
|
||||
|
||||
#if VERTEX_SHADER
|
||||
|
||||
layout(location = 0) in vec3 aPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * vec4(aPos.xyz, 1.0);
|
||||
}
|
||||
#endif // VERTEX_SHADER
|
||||
|
||||
#if FRAGMENT_SHADER
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(vec3(1.0), 1.0f);
|
||||
}
|
||||
|
||||
|
||||
#endif // FRAGMNET_SHADER
|
5
assets/shaders/debug.prog
Normal file
5
assets/shaders/debug.prog
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"shader": "debug.glsl",
|
||||
"vertex": true,
|
||||
"fragment": true
|
||||
}
|
@ -341,6 +341,10 @@ vec3 ibl(int matIdx, vec3 N, vec3 V) {
|
||||
|
||||
void main() {
|
||||
int matIdx = draw_data[DrawID].materialIdx;
|
||||
if (getAlbedo(matIdx).a < 0.5) {
|
||||
FragColor = vec4(0);
|
||||
return;
|
||||
}
|
||||
sampler2D normal_map = materials[matIdx].normal_map;
|
||||
vec2 normal_map_uv_scale = materials[matIdx].normal_map_uv_scale;
|
||||
|
||||
@ -354,7 +358,8 @@ void main() {
|
||||
vec3 finalColor = vec3(0);
|
||||
|
||||
int n_lights = clamp(int(lights_count), 0, MAX_POINT_LIGHTS);
|
||||
for (int i = 0; i < n_lights; i++) {
|
||||
for (int i = 0; i < MAX_POINT_LIGHTS; i++) {
|
||||
if (i > lights_count) break;
|
||||
finalColor += microfacetModel(matIdx, i, VertexOut.vPos, N);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ void main() {
|
||||
|
||||
|
||||
void main() {
|
||||
//gl_FragDepth = gl_FragCoord.z / gl_FragCoord.w;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#extension GL_ARB_bindless_texture : enable
|
||||
|
||||
struct DrawCmdData {
|
||||
mat4 transform;
|
||||
@ -15,21 +16,63 @@ layout(std430, binding = 3) readonly buffer DrawCmdDatas {
|
||||
DrawCmdData draw_data[];
|
||||
};
|
||||
|
||||
VERTEX_EXPORT flat uint DrawID;
|
||||
|
||||
VERTEX_EXPORT VertexData {
|
||||
vec2 uv;
|
||||
} VertexOut;
|
||||
|
||||
#if VERTEX_SHADER
|
||||
|
||||
layout(location = 0) in vec3 aPos;
|
||||
layout(location = 2) in vec2 aUV;
|
||||
|
||||
void main() {
|
||||
mat4 model = draw_data[gl_BaseInstance + gl_InstanceID].transform;
|
||||
mat4 viewModel = view * model;
|
||||
vec4 vPos = viewModel * vec4(aPos.xyz, 1.0);
|
||||
gl_Position = projection * vPos;
|
||||
DrawID = gl_BaseInstance + gl_InstanceID;
|
||||
mat4 model = draw_data[DrawID].transform;
|
||||
mat4 viewModel = view * model;
|
||||
vec4 vPos = viewModel * vec4(aPos.xyz, 1.0);
|
||||
gl_Position = projection * vPos;
|
||||
VertexOut.uv = aUV;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if FRAGMENT_SHADER
|
||||
|
||||
void main() {}
|
||||
struct Material {
|
||||
vec4 albedo;
|
||||
sampler2D albedo_map;
|
||||
vec2 albedo_map_uv_scale;
|
||||
sampler2D normal_map;
|
||||
vec2 normal_map_uv_scale;
|
||||
float metallic;
|
||||
sampler2D metallic_map;
|
||||
vec2 metallic_map_uv_scale;
|
||||
float roughness;
|
||||
sampler2D roughness_map;
|
||||
vec2 roughness_map_uv_scale;
|
||||
vec3 emission;
|
||||
sampler2D emission_map;
|
||||
vec2 emission_map_uv_scale;
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) readonly buffer Materials {
|
||||
uint materials_count;
|
||||
Material materials[];
|
||||
};
|
||||
|
||||
vec4 getAlbedo(int materialIdx) {
|
||||
return textureSize(materials[materialIdx].albedo_map, 0) == ivec2(0) ? vec4(pow(materials[materialIdx].albedo.rgb, vec3(2.2)), materials[materialIdx].albedo.a) : texture(materials[materialIdx].albedo_map, VertexOut.uv * materials[materialIdx].albedo_map_uv_scale);
|
||||
}
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
int matIdx = draw_data[DrawID].materialIdx;
|
||||
if (getAlbedo(matIdx).a < 0.5) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@ const checkGLError = @import("Render.zig").checkGLError;
|
||||
const BuddyAllocator = @import("BuddyAllocator.zig");
|
||||
const Vec2 = @import("zalgebra").Vec2;
|
||||
const Vec3 = @import("zalgebra").Vec3;
|
||||
const Mat4 = @import("zalgebra").Mat4;
|
||||
const sdl = @import("sdl.zig");
|
||||
const tracy = @import("tracy");
|
||||
|
||||
@ -689,6 +690,35 @@ const LoadedScene = struct {
|
||||
pub const AABB = struct {
|
||||
min: Vec3 = Vec3.zero(),
|
||||
max: Vec3 = Vec3.zero(),
|
||||
|
||||
pub fn distance(self: *const AABB, point: Vec3) f32 {
|
||||
const center = self.min.add(self.max).scale(0.5);
|
||||
const extent = self.max.sub(self.min).scale(0.5);
|
||||
|
||||
var center_to_point = point.sub(center);
|
||||
center_to_point.data = @abs(center_to_point.data);
|
||||
var d = center_to_point.sub(extent);
|
||||
d.data = @max(d.data, @as(@Vector(3, f32), @splat(0.0)));
|
||||
|
||||
const sq_dist_to_side = d.dot(d);
|
||||
|
||||
if (std.math.approxEqAbs(f32, sq_dist_to_side, 0.0, 0.0001)) {
|
||||
const diff = point.sub(center);
|
||||
return diff.dot(diff);
|
||||
}
|
||||
|
||||
return sq_dist_to_side;
|
||||
}
|
||||
|
||||
pub fn transformBy(self: *const AABB, matrix: Mat4) AABB {
|
||||
var center = self.min.add(self.max).scale(0.5).toVec4(1.0);
|
||||
var extent = self.max.sub(self.min).scale(0.5).toVec4(0.0);
|
||||
|
||||
center = matrix.mulByVec4(center);
|
||||
extent = matrix.mulByVec4(extent);
|
||||
|
||||
return AABB{ .min = center.sub(extent).toVec3(), .max = center.add(extent).toVec3() };
|
||||
}
|
||||
};
|
||||
|
||||
pub const BufferSlice = struct {
|
||||
|
144
src/Render.zig
144
src/Render.zig
@ -7,6 +7,7 @@ const globals = @import("globals.zig");
|
||||
pub const Material = @import("formats.zig").Material;
|
||||
const math = @import("math.zig");
|
||||
const formats = @import("formats.zig");
|
||||
const AABB = AssetManager.AABB; // TODO: move AABB out of formats pls
|
||||
const tracy = @import("tracy");
|
||||
|
||||
const za = @import("zalgebra");
|
||||
@ -39,6 +40,7 @@ frame_arena: std.mem.Allocator,
|
||||
assetman: *AssetManager,
|
||||
camera: *Camera = &default_camera,
|
||||
mesh_vao: gl.GLuint = 0,
|
||||
z_prepass_vao: gl.GLuint = 0,
|
||||
tripple_buffer_index: usize = MAX_FRAMES_QUEUED - 1,
|
||||
gl_fences: [MAX_FRAMES_QUEUED]?gl.GLsync = [_]?gl.GLsync{null} ** MAX_FRAMES_QUEUED,
|
||||
camera_ubo: gl.GLuint = 0,
|
||||
@ -85,6 +87,10 @@ camera_view_proj: Mat4 = Mat4.identity(),
|
||||
world_camera_frustum: math.Frustum = .{},
|
||||
world_view_frustum_corners: [CSM_SPLITS][8]Vec3 = undefined,
|
||||
|
||||
// Debug Draw
|
||||
debug_drawer: DebugDrawer = undefined,
|
||||
debug_lines_vao: gl.GLuint = 0,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetman: *AssetManager) Render {
|
||||
var render = Render{
|
||||
.allocator = allocator,
|
||||
@ -137,6 +143,38 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// Z Prepass Mesh VAO
|
||||
var vao: gl.GLuint = 0;
|
||||
gl.createVertexArrays(1, &vao);
|
||||
std.debug.assert(vao != 0);
|
||||
render.z_prepass_vao = vao;
|
||||
|
||||
// positions
|
||||
// gl.vertexArrayVertexBuffer(vao, 0, vertices, 0, @sizeOf(formats.Vector3));
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.Position.value());
|
||||
gl.vertexArrayAttribBinding(vao, Attrib.Position.value(), 0);
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||
|
||||
// uvs
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
|
||||
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 2);
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// Debug Lines VAO
|
||||
var vao: gl.GLuint = 0;
|
||||
gl.createVertexArrays(1, &vao);
|
||||
std.debug.assert(vao != 0);
|
||||
render.debug_lines_vao = vao;
|
||||
|
||||
// positions
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.Position.value());
|
||||
gl.vertexArrayAttribBinding(vao, Attrib.Position.value(), 0);
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||
}
|
||||
|
||||
const PERSISTENT_BUFFER_FLAGS: gl.GLbitfield = gl.MAP_PERSISTENT_BIT | gl.MAP_WRITE_BIT | gl.MAP_COHERENT_BIT;
|
||||
|
||||
// Camera matrices ubo
|
||||
@ -372,6 +410,8 @@ pub fn begin(self: *Render) void {
|
||||
self.light_count = 0;
|
||||
self.tripple_buffer_index = (self.tripple_buffer_index + 1) % MAX_FRAMES_QUEUED;
|
||||
|
||||
self.debug_drawer = DebugDrawer.init(self.frame_arena);
|
||||
|
||||
gl.enable(gl.CULL_FACE);
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
if (self.gl_fences[self.tripple_buffer_index]) |fence| {
|
||||
@ -429,9 +469,8 @@ pub const LightCommand = union(LightKind) {
|
||||
};
|
||||
|
||||
const DrawCommandKey = packed struct {
|
||||
mesh: u16 = 0,
|
||||
distance: u15 = 0,
|
||||
transparent: u1 = 0,
|
||||
distance: u30 = 0,
|
||||
blend: u2 = 0,
|
||||
};
|
||||
|
||||
pub fn drawLight(self: *Render, cmd: LightCommand) void {
|
||||
@ -439,18 +478,78 @@ pub fn drawLight(self: *Render, cmd: LightCommand) void {
|
||||
self.light_count += 1;
|
||||
}
|
||||
|
||||
fn invLerp(aa: f32, b: f32, v: f32) f32 {
|
||||
return (v - aa) / (b - aa);
|
||||
}
|
||||
|
||||
const DebugDrawer = struct {
|
||||
const Self = @This();
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
// Wasting frame arena memory here, maybe redo this
|
||||
line_list: std.ArrayListUnmanaged([2][3]f32) = .{},
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) Self {
|
||||
return Self{ .allocator = allocator };
|
||||
}
|
||||
|
||||
pub fn drawAABB(self: *Self, in_aabb: AABB) void {
|
||||
var aabb = in_aabb;
|
||||
var new_lines: [12][2][3]f32 = undefined;
|
||||
|
||||
var min: [3]f32 = .{ aabb.min.x(), aabb.min.y(), aabb.min.z() };
|
||||
var max: [3]f32 = .{ aabb.max.x(), aabb.max.y(), aabb.max.z() };
|
||||
|
||||
for (0..2) |i| {
|
||||
new_lines[i * 6 + 0] = .{ min, .{ max[0], min[1], min[2] } };
|
||||
new_lines[i * 6 + 1] = .{ min, .{ min[0], max[1], min[2] } };
|
||||
new_lines[i * 6 + 2] = .{ min, .{ min[0], min[1], max[2] } };
|
||||
|
||||
new_lines[i * 6 + 3] = .{ max, .{ min[0], max[1], max[2] } };
|
||||
new_lines[i * 6 + 4] = .{ max, .{ max[0], min[1], max[2] } };
|
||||
new_lines[i * 6 + 5] = .{ max, .{ max[0], max[1], min[2] } };
|
||||
|
||||
std.mem.swap(f32, &min[1], &max[1]);
|
||||
}
|
||||
|
||||
self.line_list.appendSlice(self.allocator, &new_lines) catch {};
|
||||
}
|
||||
|
||||
pub fn uploadLinesBuffer(self: *const Self) gl.GLuint {
|
||||
var buf: gl.GLuint = 0;
|
||||
gl.createBuffers(1, &buf);
|
||||
std.debug.assert(buf != 0);
|
||||
|
||||
gl.namedBufferStorage(buf, @intCast(@sizeOf(f32) * 3 * 2 * self.line_list.items.len), self.line_list.items.ptr, 0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn draw(self: *Render, cmd: DrawCommand) void {
|
||||
self.command_buffer[self.command_count] = cmd;
|
||||
// TODO: don't load the whole mesh here
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
const aabb = mesh.aabb.transformBy(cmd.transform);
|
||||
|
||||
self.debug_drawer.drawAABB(aabb);
|
||||
const material: Material = if (cmd.material_override) |mat| mat else mesh.material;
|
||||
const view_origin = self.camera.view_mat.extractTranslation();
|
||||
const max_value = @as(f32, @floatFromInt(std.math.maxInt(u15)));
|
||||
const dist: u15 = @intFromFloat(std.math.clamp(view_origin.distance(cmd.transform.extractTranslation()) / max_value, 0.0, max_value));
|
||||
const distance = view_origin.distance(aabb.min.add(aabb.max).scale(0.5));
|
||||
const alpha = std.math.clamp(invLerp(self.camera.near, self.camera.far, distance), 0.0, 1.0);
|
||||
|
||||
const max_value = @as(f32, @floatFromInt(std.math.maxInt(u30)));
|
||||
const quantized_dist: u30 = @intFromFloat(alpha * max_value);
|
||||
const inv_quantized_dist: u30 = @intFromFloat((1.0 - alpha) * max_value);
|
||||
const key = DrawCommandKey{
|
||||
.transparent = if (material.blend_mode == .AlphaBlend) 1 else 0,
|
||||
.distance = if (material.blend_mode == .AlphaBlend) dist else dist, // TODO: calculate distance. Opaque should be front to back, transparent back to front
|
||||
.mesh = @intCast(cmd.mesh.id % std.math.maxInt(u16)),
|
||||
.blend = switch (material.blend_mode) {
|
||||
.Opaque => 0,
|
||||
.AlphaMask => 1,
|
||||
.AlphaBlend => 2,
|
||||
},
|
||||
.distance = if (material.blend_mode == .AlphaBlend) inv_quantized_dist else quantized_dist, // TODO: calculate distance. Opaque should be front to back, transparent back to front
|
||||
// .mesh = @intCast(cmd.mesh.id % std.math.maxInt(u16)),
|
||||
};
|
||||
self.command_buffer[self.command_count].key = key;
|
||||
self.command_count += 1;
|
||||
@ -846,11 +945,11 @@ pub fn finish(self: *Render) void {
|
||||
var materials_count: usize = 0;
|
||||
for (self.command_buffer[0..self.command_count]) |*cmd| {
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
// const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
|
||||
// if (!self.world_camera_frustum.intersectAABB(aabb.transform(cmd.transform))) {
|
||||
// continue;
|
||||
// }
|
||||
if (!self.world_camera_frustum.intersectAABB(aabb.transform(cmd.transform))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const material: Material = if (cmd.material_override) |mat| mat else mesh.material;
|
||||
|
||||
@ -919,11 +1018,13 @@ pub fn finish(self: *Render) void {
|
||||
// Z Prepass
|
||||
{
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.z_prepass).program);
|
||||
gl.bindVertexArray(self.shadow_vao);
|
||||
gl.bindVertexArray(self.z_prepass_vao);
|
||||
gl.depthFunc(gl.LESS);
|
||||
|
||||
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
|
||||
checkGLError();
|
||||
self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value());
|
||||
checkGLError();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
||||
checkGLError();
|
||||
|
||||
@ -936,6 +1037,7 @@ pub fn finish(self: *Render) void {
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program);
|
||||
gl.bindVertexArray(self.mesh_vao);
|
||||
gl.depthFunc(gl.EQUAL);
|
||||
defer gl.depthFunc(gl.LEQUAL);
|
||||
|
||||
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.EnvBRDF.value(), self.assetman.resolveTexture(a.Textures.@"ibl_brdf_lut.norm").handle);
|
||||
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMap2D.value(), self.shadow_texture_handle);
|
||||
@ -978,8 +1080,20 @@ pub fn finish(self: *Render) void {
|
||||
defer gl.polygonMode(gl.FRONT_AND_BACK, gl.FILL);
|
||||
gl.lineWidth(4);
|
||||
|
||||
const debug_lines_buffer = self.debug_drawer.uploadLinesBuffer();
|
||||
defer gl.deleteBuffers(1, &debug_lines_buffer);
|
||||
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.debug).program);
|
||||
gl.bindVertexArray(self.debug_lines_vao);
|
||||
|
||||
gl.uniform3f(Uniform.Color.value(), 1.0, 1.0, 1.0);
|
||||
|
||||
gl.bindVertexBuffer(Render.Attrib.Position.value(), debug_lines_buffer, 0, @intCast(@sizeOf(f32) * 3));
|
||||
|
||||
gl.drawArrays(gl.LINES, 0, @intCast(self.debug_drawer.line_list.items.len * 2));
|
||||
|
||||
// Frustum debug stuff, drawn only when view frustum is fixed
|
||||
if (!self.update_view_frustum) {
|
||||
if (false and !self.update_view_frustum) {
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.unlit).program);
|
||||
|
||||
// Draw wire frustum cubes
|
||||
@ -1162,9 +1276,9 @@ const cube_camera_dirs = [6]CubeCameraDir{
|
||||
};
|
||||
|
||||
fn renderShadow(self: *Render, frustum: *const math.Frustum) void {
|
||||
_ = frustum; // autofix
|
||||
const zone = tracy.initZone(@src(), .{ .name = "Render.renderShadow" });
|
||||
defer zone.deinit();
|
||||
_ = frustum; // autofix
|
||||
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
||||
|
||||
|
@ -369,8 +369,8 @@ test "write and read scene" {
|
||||
pub const Material = extern struct {
|
||||
pub const BlendMode = enum(u8) {
|
||||
Opaque = 0,
|
||||
AlphaBlend = 1,
|
||||
AlphaMask = 2,
|
||||
AlphaMask = 1,
|
||||
AlphaBlend = 2,
|
||||
};
|
||||
|
||||
albedo: Vec4 = Vec4.one(),
|
||||
|
16
src/math.zig
16
src/math.zig
@ -84,19 +84,14 @@ pub const AABB = struct {
|
||||
return AABB{ .origin = origin, .extents = extents };
|
||||
}
|
||||
|
||||
// TODO: optimize
|
||||
pub fn transform(self: *const AABB, matrix: Mat4) AABB {
|
||||
var min = Vec3.new(std.math.floatMax(f32), std.math.floatMax(f32), std.math.floatMax(f32));
|
||||
var max = Vec3.new(std.math.floatMin(f32), std.math.floatMin(f32), std.math.floatMin(f32));
|
||||
var origin = self.origin.toVec4(1.0);
|
||||
var extents = self.extents.toVec4(0.0);
|
||||
|
||||
inline for (box_corners) |corner| {
|
||||
const corner_pos = matrix.mulByVec4(self.origin.add(self.extents.mul(corner)).toVec4(1));
|
||||
const corner_pos3 = corner_pos.toVec3();
|
||||
min = corner_pos3.min(min);
|
||||
max = corner_pos3.max(max);
|
||||
}
|
||||
origin = matrix.mulByVec4(origin);
|
||||
extents = matrix.mulByVec4(extents);
|
||||
|
||||
return AABB.fromMinMax(min, max);
|
||||
return AABB{ .origin = origin.toVec3(), .extents = extents.toVec3() };
|
||||
}
|
||||
|
||||
pub fn toSphere(self: *const AABB) BoundingSphere {
|
||||
@ -232,6 +227,7 @@ pub const Frustum = struct {
|
||||
}
|
||||
|
||||
pub fn intersectAABB(self: *const Frustum, aabb: AABB) bool {
|
||||
@setRuntimeSafety(false);
|
||||
return self.intersectAABBInternal(aabb, false);
|
||||
}
|
||||
|
||||
|
@ -218,10 +218,8 @@ fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std
|
||||
// TODO: rgba
|
||||
mat_output.albedo = Vec4.new(base_color.r, base_color.g, base_color.b, base_color.a);
|
||||
|
||||
if (std.math.approxEqAbs(f32, base_color.a, 0.0, std.math.floatEps(f32))) {
|
||||
if (base_color.a < 1.0) {
|
||||
mat_output.blend_mode = .AlphaMask;
|
||||
} else if (base_color.a < 1.0) {
|
||||
mat_output.blend_mode = .AlphaBlend;
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +229,7 @@ fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std
|
||||
const entry = mat_texture.path.resolveAssetListEntry(texture_outputs, &has_alpha);
|
||||
mat_output.albedo_map.id = entry.getAssetId();
|
||||
if (has_alpha) {
|
||||
mat_output.blend_mode = .AlphaBlend;
|
||||
mat_output.blend_mode = .AlphaMask;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user