I have a working skybox now
This commit is contained in:
parent
fa1f9c6808
commit
274255556d
|
|
@ -41,6 +41,9 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json"));
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json"));
|
||||||
|
|
||||||
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.frag", b.path("shaders/skybox.frag.json"));
|
||||||
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "skybox.vert", b.path("shaders/skybox.vert.json"));
|
||||||
|
|
||||||
// ========== tests ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ SamplerState Sampler : register(s0, space2);
|
||||||
Texture2D<float> DirectionalShadowDepthMap : register(t1, space2);
|
Texture2D<float> DirectionalShadowDepthMap : register(t1, space2);
|
||||||
SamplerState DirectionalShadowSampler : register(s1, space2);
|
SamplerState DirectionalShadowSampler : register(s1, space2);
|
||||||
|
|
||||||
|
|
||||||
cbuffer Uniforms : register(b0, space3)
|
cbuffer Uniforms : register(b0, space3)
|
||||||
{
|
{
|
||||||
float4 viewPos;
|
float4 viewPos;
|
||||||
|
|
@ -111,7 +112,7 @@ float shadowCalculationPCF(float3 fragPos, float4 DirectionalShadowFragPos)
|
||||||
uv.y = -uv.y;
|
uv.y = -uv.y;
|
||||||
float fragDepth = DirectionalShadowFragPos.z;
|
float fragDepth = DirectionalShadowFragPos.z;
|
||||||
float combinedShadow = 0.0;
|
float combinedShadow = 0.0;
|
||||||
float bias = 0.001;
|
float bias = 0.005;
|
||||||
|
|
||||||
for (int y = -range ; y <= range ; y++) {
|
for (int y = -range ; y <= range ; y++) {
|
||||||
for (int x = -range ; x <= range ; x++) {
|
for (int x = -range ; x <= range ; x++) {
|
||||||
|
|
@ -124,8 +125,8 @@ float shadowCalculationPCF(float3 fragPos, float4 DirectionalShadowFragPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
combinedDepth = combinedDepth / count;
|
combinedDepth = combinedDepth / (count);
|
||||||
combinedShadow = combinedShadow / count;
|
combinedShadow = combinedShadow / (count);
|
||||||
|
|
||||||
// float fragDepth = DirectionalShadowFragPos.z;
|
// float fragDepth = DirectionalShadowFragPos.z;
|
||||||
// float shadow = fragDepth - bias > combinedDepth ? 1.0 : 0.0;
|
// float shadow = fragDepth - bias > combinedDepth ? 1.0 : 0.0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
TextureCube<float4> SkyboxTexture : register(t0, space2);
|
||||||
|
SamplerState SkyboxSampler : register(s0, space2);
|
||||||
|
|
||||||
|
float4 main(float3 TexCoord : TEXCOORD0) : SV_Target0
|
||||||
|
{
|
||||||
|
return pow(SkyboxTexture.Sample(SkyboxSampler, TexCoord), 1.0/2.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"entryPoints" : [
|
||||||
|
{
|
||||||
|
"name" : "main",
|
||||||
|
"mode" : "frag"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs" : [
|
||||||
|
{
|
||||||
|
"type" : "vec3",
|
||||||
|
"name" : "in.var.TEXCOORD0",
|
||||||
|
"location" : 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs" : [
|
||||||
|
{
|
||||||
|
"type" : "vec4",
|
||||||
|
"name" : "out.var.SV_Target0",
|
||||||
|
"location" : 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"separate_images" : [
|
||||||
|
{
|
||||||
|
"type" : "textureCube",
|
||||||
|
"name" : "SkyboxTexture",
|
||||||
|
"set" : 2,
|
||||||
|
"binding" : 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"separate_samplers" : [
|
||||||
|
{
|
||||||
|
"type" : "sampler",
|
||||||
|
"name" : "SkyboxSampler",
|
||||||
|
"set" : 2,
|
||||||
|
"binding" : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
struct Input
|
||||||
|
{
|
||||||
|
float3 Position : TEXCOORD0;
|
||||||
|
|
||||||
|
uint Instance : SV_InstanceID;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer Uniforms : register(b0, space1)
|
||||||
|
{
|
||||||
|
float4x4 ViewProjection : packoffset(c0);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Output
|
||||||
|
{
|
||||||
|
float3 UVW : TEXCOORD0;
|
||||||
|
float4 Position : SV_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output main(Input input)
|
||||||
|
{
|
||||||
|
Output output;
|
||||||
|
float4 pos = float4(input.Position, 1.0);
|
||||||
|
output.Position = mul(ViewProjection, pos);
|
||||||
|
output.UVW = input.Position;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"entryPoints" : [
|
||||||
|
{
|
||||||
|
"name" : "main",
|
||||||
|
"mode" : "vert"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"types" : {
|
||||||
|
"_5" : {
|
||||||
|
"name" : "type.Uniforms",
|
||||||
|
"members" : [
|
||||||
|
{
|
||||||
|
"name" : "ViewProjection",
|
||||||
|
"type" : "mat4",
|
||||||
|
"offset" : 0,
|
||||||
|
"matrix_stride" : 16,
|
||||||
|
"row_major" : true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inputs" : [
|
||||||
|
{
|
||||||
|
"type" : "vec3",
|
||||||
|
"name" : "in.var.TEXCOORD0",
|
||||||
|
"location" : 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs" : [
|
||||||
|
{
|
||||||
|
"type" : "vec3",
|
||||||
|
"name" : "out.var.TEXCOORD0",
|
||||||
|
"location" : 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ubos" : [
|
||||||
|
{
|
||||||
|
"type" : "_5",
|
||||||
|
"name" : "type.Uniforms",
|
||||||
|
"block_size" : 64,
|
||||||
|
"set" : 1,
|
||||||
|
"binding" : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ roll: f32 = 0,
|
||||||
finalPos: core.Vectorf = .{},
|
finalPos: core.Vectorf = .{},
|
||||||
final: Mat = zm.identity(),
|
final: Mat = zm.identity(),
|
||||||
finalAlt: Mat = zm.identity(),
|
finalAlt: Mat = zm.identity(),
|
||||||
|
noTranslate: Mat = zm.identity(),
|
||||||
|
|
||||||
entity: core.Entity = undefined,
|
entity: core.Entity = undefined,
|
||||||
|
|
||||||
|
|
@ -90,6 +91,9 @@ pub fn resolve(self: *@This()) void {
|
||||||
// self.transform = core.zm.identity();
|
// self.transform = core.zm.identity();
|
||||||
|
|
||||||
self.transform = mul(core.zm.matFromQuat(rotation.quat), self.transform);
|
self.transform = mul(core.zm.matFromQuat(rotation.quat), self.transform);
|
||||||
|
|
||||||
|
self.noTranslate = mul(self.transform, self.projection);
|
||||||
|
|
||||||
self.transform = mul(core.zm.translationV(position.toZm()), self.transform);
|
self.transform = mul(core.zm.translationV(position.toZm()), self.transform);
|
||||||
self.final = mul(self.transform, self.projection);
|
self.final = mul(self.transform, self.projection);
|
||||||
// core.engine_log("{any}", .{self.final});
|
// core.engine_log("{any}", .{self.final});
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ pub const getTexture = renderer.getTexture;
|
||||||
pub const texture = @import("texture/texture.zig");
|
pub const texture = @import("texture/texture.zig");
|
||||||
pub const Texture = texture.Texture;
|
pub const Texture = texture.Texture;
|
||||||
|
|
||||||
|
pub const setSkyboxTexture = renderer.setSkyboxTexture;
|
||||||
|
|
||||||
var rendAllocator: std.mem.Allocator = undefined;
|
var rendAllocator: std.mem.Allocator = undefined;
|
||||||
pub fn getAllocator() std.mem.Allocator {
|
pub fn getAllocator() std.mem.Allocator {
|
||||||
return rendAllocator;
|
return rendAllocator;
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,132 @@ pub fn loadAsset(self: *@This(), assetRef: assets.AssetRef, propertiesBag: ?asse
|
||||||
var name = assetRef.name;
|
var name = assetRef.name;
|
||||||
core.engine_log("loading texture {s}", .{name.utf8()});
|
core.engine_log("loading texture {s}", .{name.utf8()});
|
||||||
if (propertiesBag) |bag| {
|
if (propertiesBag) |bag| {
|
||||||
const installed = self.uploadTextureFromPath(name, bag.path) catch return error.UnableToLoad;
|
var installed: *Texture = undefined;
|
||||||
|
if (bag.textureCube) {
|
||||||
|
const pathList = bag.textureList.?;
|
||||||
|
core.engine_log("loading textures as a cubemap\n {s}\n {s}\n {s}\n {s}\n {s}\n {s}", .{
|
||||||
|
pathList[0],
|
||||||
|
pathList[1],
|
||||||
|
pathList[2],
|
||||||
|
pathList[3],
|
||||||
|
pathList[4],
|
||||||
|
pathList[5],
|
||||||
|
});
|
||||||
|
|
||||||
|
installed = self.uploadCubeFromPaths(name, pathList) catch return error.UnableToLoad;
|
||||||
|
} else {
|
||||||
|
installed = self.uploadTextureFromPath(name, bag.path) catch return error.UnableToLoad;
|
||||||
|
}
|
||||||
|
|
||||||
self.map.put(self.allocator, name.handle(), installed) catch return error.UnableToLoad;
|
self.map.put(self.allocator, name.handle(), installed) catch return error.UnableToLoad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn uploadCubeFromPaths(self: *@This(), name: core.Name, paths: []const []const u8) !*Texture {
|
||||||
|
if (paths.len != 6) {
|
||||||
|
return error.CubeNeedsSixFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cubeList = std.ArrayList(core.png.PngContents).init(self.allocator);
|
||||||
|
defer cubeList.deinit();
|
||||||
|
|
||||||
|
var gpuTexture: *gpu.GPUTexture = undefined;
|
||||||
|
|
||||||
|
var first: bool = true;
|
||||||
|
var textureSize: u32 = 0;
|
||||||
|
|
||||||
|
for (paths) |path| {
|
||||||
|
try cubeList.append(try core.png.PngContents.initFromFS(core.fs(), self.allocator, path));
|
||||||
|
const png = &cubeList.items[cubeList.items.len - 1];
|
||||||
|
|
||||||
|
const cmd = self.device.acquireGPUCommandBuffer();
|
||||||
|
|
||||||
|
const copyPass = cmd.beginGPUCopyPass();
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
textureSize = cubeList.items[0].size.x;
|
||||||
|
|
||||||
|
var tci: gpu.GPUTextureCreateInfo = std.mem.zeroInit(gpu.GPUTextureCreateInfo, .{
|
||||||
|
.type = .texturetypeCube,
|
||||||
|
.format = .textureformatR8g8b8a8UnormSrgb,
|
||||||
|
.usage = .{ .textureusageSampler = true },
|
||||||
|
.width = textureSize,
|
||||||
|
.height = textureSize,
|
||||||
|
.layer_count_or_depth = 6,
|
||||||
|
.num_levels = 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
gpuTexture = self.device.createGPUTexture(&tci);
|
||||||
|
|
||||||
|
try core.assert(cubeList.items[0].size.x == cubeList.items[0].size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const transferBuffer = self.device.createGPUTransferBuffer(&.{
|
||||||
|
.usage = .transferbufferusageUpload,
|
||||||
|
.size = textureSize * textureSize * @sizeOf(u32),
|
||||||
|
.props = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
defer self.device.releaseGPUTransferBuffer(transferBuffer);
|
||||||
|
|
||||||
|
const gtti: gpu.GPUTextureTransferInfo = .{
|
||||||
|
.transfer_buffer = transferBuffer,
|
||||||
|
.offset = 0,
|
||||||
|
.pixels_per_row = textureSize,
|
||||||
|
.rows_per_layer = textureSize,
|
||||||
|
};
|
||||||
|
|
||||||
|
const data: [*]u8 = @ptrCast(self.device.mapGPUTransferBuffer(transferBuffer, false));
|
||||||
|
for (png.pixels, 0..) |pixel, i| {
|
||||||
|
data[i] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
// TextureCube<float4> SkyboxTexture : register(t0, space2);
|
||||||
|
// SamplerState SkyboxSampler : register(s0, space2);
|
||||||
|
|
||||||
|
const textureRegion = std.mem.zeroInit(gpu.GPUTextureRegion, .{
|
||||||
|
.texture = gpuTexture,
|
||||||
|
.w = textureSize,
|
||||||
|
.h = textureSize,
|
||||||
|
.d = 1,
|
||||||
|
.layer = @as(u32, @intCast(cubeList.items.len - 1)),
|
||||||
|
});
|
||||||
|
|
||||||
|
copyPass.uploadToGPUTexture(>ti, &textureRegion, false);
|
||||||
|
|
||||||
|
copyPass.endGPUCopyPass();
|
||||||
|
|
||||||
|
_ = cmd.submitGPUCommandBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// what the fuck do we even do here.
|
||||||
|
|
||||||
|
// cubemapfacePositivex, right
|
||||||
|
// cubemapfaceNegativex, left
|
||||||
|
// cubemapfacePositivey, up
|
||||||
|
// cubemapfaceNegativey, down
|
||||||
|
// cubemapfacePositivez, forward
|
||||||
|
// cubemapfaceNegativez, backward
|
||||||
|
|
||||||
|
for (cubeList.items) |*i| {
|
||||||
|
i.deinit();
|
||||||
|
}
|
||||||
|
const tex = try self.allocator.create(Texture);
|
||||||
|
tex.* = .{
|
||||||
|
.id = 0,
|
||||||
|
.format = .f32_rgba,
|
||||||
|
.usage = .{ .cube = true },
|
||||||
|
.size = .{ .x = textureSize, .y = textureSize },
|
||||||
|
.name = name,
|
||||||
|
.texture = gpuTexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uploadTextureFromPath(self: *@This(), name: core.Name, path: []const u8) !*Texture {
|
pub fn uploadTextureFromPath(self: *@This(), name: core.Name, path: []const u8) !*Texture {
|
||||||
var png = try core.png.PngContents.initFromFS(core.fs(), self.allocator, path);
|
var png = try core.png.PngContents.initFromFS(core.fs(), self.allocator, path);
|
||||||
defer png.deinit();
|
defer png.deinit();
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ pub const Renderer = struct {
|
||||||
shadowMapProjection: core.Transform = core.zm.identity(),
|
shadowMapProjection: core.Transform = core.zm.identity(),
|
||||||
|
|
||||||
blockySampler: *gpu.GPUSampler = undefined,
|
blockySampler: *gpu.GPUSampler = undefined,
|
||||||
|
cubeSampler: *gpu.GPUSampler = undefined,
|
||||||
defaultTexture: *rend.Texture = undefined,
|
defaultTexture: *rend.Texture = undefined,
|
||||||
|
|
||||||
lightPosition: core.Vectorf = .{},
|
lightPosition: core.Vectorf = .{},
|
||||||
|
|
@ -65,6 +66,14 @@ pub const Renderer = struct {
|
||||||
// transients DO NOT TOUCH
|
// transients DO NOT TOUCH
|
||||||
swapchainTexture: ?*gpu.GPUTexture = undefined,
|
swapchainTexture: ?*gpu.GPUTexture = undefined,
|
||||||
|
|
||||||
|
skyboxMesh: ?rend.IndexedMesh = null,
|
||||||
|
skyboxTexture: ?*rend.Texture = null,
|
||||||
|
skyboxTextureName: ?core.Name = null,
|
||||||
|
skyboxPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
||||||
|
skyboxColor: core.colors.Color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 },
|
||||||
|
|
||||||
|
skyboxMeshName: core.Name = core.DefineName("m_skybox"),
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||||
|
|
||||||
pub const MaxObjectCount = 50000;
|
pub const MaxObjectCount = 50000;
|
||||||
|
|
@ -124,13 +133,12 @@ pub const Renderer = struct {
|
||||||
.{ .path = "meshes/primitive_box.obj" },
|
.{ .path = "meshes/primitive_box.obj" },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
var defaultTextureName = core.MakeName("t_default");
|
var defaultTextureName = core.MakeName("t_default");
|
||||||
self.defaultTexture = getTexture(&defaultTextureName).?;
|
self.defaultTexture = getTexture(&defaultTextureName).?;
|
||||||
|
|
||||||
self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem);
|
self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem);
|
||||||
|
|
||||||
try self.createDirectionalShadowsPipeline();
|
try self.createDirectionalShadowsPipeline();
|
||||||
|
try self.setupSkybox();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createDirectionalShadowsPipeline(self: *@This()) !void {
|
pub fn createDirectionalShadowsPipeline(self: *@This()) !void {
|
||||||
|
|
@ -138,6 +146,50 @@ pub const Renderer = struct {
|
||||||
try self.createShadowCastingPipeline();
|
try self.createShadowCastingPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setupSkybox(self: *@This()) !void {
|
||||||
|
try assets.load(
|
||||||
|
assets.MakeImportRefOptions(
|
||||||
|
"Mesh",
|
||||||
|
"m_skybox",
|
||||||
|
.{ .path = "meshes/skybox.obj" },
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
try self.createSkyboxPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn createSkyboxPipeline(self: *@This()) !void {
|
||||||
|
const vertex = try self.loadShader("skybox.vert", skybox_vert.LoadArgs);
|
||||||
|
const fragment = try self.loadShader("skybox.frag", skybox_frag.LoadArgs);
|
||||||
|
|
||||||
|
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
|
||||||
|
pci.vertex_shader = vertex;
|
||||||
|
pci.fragment_shader = fragment;
|
||||||
|
|
||||||
|
var attributes = try self.generateVertexAttributeList();
|
||||||
|
defer attributes.deinit();
|
||||||
|
|
||||||
|
pci.vertex_input_state = .{
|
||||||
|
.num_vertex_buffers = 1,
|
||||||
|
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
|
||||||
|
.{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 },
|
||||||
|
},
|
||||||
|
.num_vertex_attributes = @intCast(attributes.items.len),
|
||||||
|
.vertex_attributes = @ptrCast(attributes.items.ptr),
|
||||||
|
};
|
||||||
|
|
||||||
|
pci.target_info.num_color_targets = 1;
|
||||||
|
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
|
||||||
|
.{
|
||||||
|
.format = self.device.getGPUSwapchainTextureFormat(self.window),
|
||||||
|
.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pci.rasterizer_state.fill_mode = .fillmodeFill;
|
||||||
|
self.skyboxPipeline = self.device.createGPUGraphicsPipeline(&pci);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn createSamplers(self: *@This()) !void {
|
pub fn createSamplers(self: *@This()) !void {
|
||||||
core.engine_log("creating blocky sampler", .{});
|
core.engine_log("creating blocky sampler", .{});
|
||||||
self.blockySampler = self.device.createGPUSampler(&std.mem.zeroInit(gpu.GPUSamplerCreateInfo, .{
|
self.blockySampler = self.device.createGPUSampler(&std.mem.zeroInit(gpu.GPUSamplerCreateInfo, .{
|
||||||
|
|
@ -427,6 +479,17 @@ pub const Renderer = struct {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn uploadSkyboxUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
|
var data = std.mem.zeroes([@sizeOf(skybox_vert.Uniforms) / 8 + 1]usize);
|
||||||
|
const ptr: *skybox_vert.Uniforms = @ptrCast(@alignCast(&data));
|
||||||
|
|
||||||
|
if (self.activeCamera) |camera| {
|
||||||
|
ptr.ViewProjection = @bitCast(camera.noTranslate);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(skybox_vert.Uniforms));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uploadUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) !void {
|
pub fn uploadUniforms(self: *@This(), cmd: *gpu.GPUCommandBuffer) !void {
|
||||||
{
|
{
|
||||||
var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize);
|
var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize);
|
||||||
|
|
@ -441,6 +504,7 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(meshes_vert.Uniforms));
|
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(meshes_vert.Uniforms));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var data = std.mem.zeroes([@sizeOf(lit_mesh_frag.Uniforms) / 8 + 1]usize);
|
var data = std.mem.zeroes([@sizeOf(lit_mesh_frag.Uniforms) / 8 + 1]usize);
|
||||||
const ptr: *lit_mesh_frag.Uniforms = @ptrCast(@alignCast(&data));
|
const ptr: *lit_mesh_frag.Uniforms = @ptrCast(@alignCast(&data));
|
||||||
|
|
@ -589,13 +653,42 @@ pub const Renderer = struct {
|
||||||
_ = cmd.submitGPUCommandBuffer();
|
_ = cmd.submitGPUCommandBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try self.uploadUniforms(cmd);
|
// render the skybox
|
||||||
|
{
|
||||||
|
if (self.skyboxMesh == null) {
|
||||||
|
self.skyboxMesh = getMeshByName(&self.skyboxMeshName);
|
||||||
|
}
|
||||||
|
if (self.skyboxTexture == null) {
|
||||||
|
if (self.skyboxTextureName) |*name| {
|
||||||
|
self.skyboxTexture = getTexture(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.skyboxTexture) |skyboxTexture| {
|
||||||
|
if (self.skyboxMesh) |skyboxMesh| {
|
||||||
|
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
.texture = self.swapchainTexture.?,
|
||||||
|
.clear_color = self.skyboxColor,
|
||||||
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null);
|
||||||
|
|
||||||
|
self.uploadSkyboxUniforms(cmd);
|
||||||
|
renderpass.bindGPUGraphicsPipeline(self.skyboxPipeline);
|
||||||
|
renderpass.bindGPUFragmentSamplers(0, &.{ .texture = skyboxTexture.texture, .sampler = self.blockySampler }, 1);
|
||||||
|
renderpass.drawGPUIndexedPrimitives(skyboxMesh.index.size, 1, skyboxMesh.index.start, @intCast(skyboxMesh.vertex.start), 0);
|
||||||
|
renderpass.endGPURenderPass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// can cache this
|
// can cache this
|
||||||
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
.texture = self.swapchainTexture.?,
|
.texture = self.swapchainTexture.?,
|
||||||
.clear_color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 },
|
.clear_color = self.skyboxColor,
|
||||||
.load_op = .loadopClear,
|
.load_op = .loadopLoad,
|
||||||
.store_op = .storeopStore,
|
.store_op = .storeopStore,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -612,16 +705,18 @@ pub const Renderer = struct {
|
||||||
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget);
|
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget);
|
||||||
//renderpass.bindGPUGraphicsPipeline(self.testPipeline);
|
//renderpass.bindGPUGraphicsPipeline(self.testPipeline);
|
||||||
|
|
||||||
renderpass.bindGPUGraphicsPipeline(self.meshPipe);
|
|
||||||
|
|
||||||
renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1);
|
renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1);
|
||||||
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1);
|
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1);
|
||||||
renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
||||||
|
|
||||||
|
// render the meshes
|
||||||
|
renderpass.bindGPUGraphicsPipeline(self.meshPipe);
|
||||||
renderpass.bindGPUFragmentSamplers(1, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1);
|
renderpass.bindGPUFragmentSamplers(1, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1);
|
||||||
// todo move into materials system
|
// todo move into materials system
|
||||||
|
|
||||||
renderpass.setGPUScissor(&self.scissor);
|
renderpass.setGPUScissor(&self.scissor);
|
||||||
|
|
||||||
|
try self.uploadUniforms(cmd);
|
||||||
//rendering each mesh
|
//rendering each mesh
|
||||||
{
|
{
|
||||||
const container = rend.MeshComponent.BaseContainer;
|
const container = rend.MeshComponent.BaseContainer;
|
||||||
|
|
@ -693,6 +788,9 @@ const lit_mesh_frag = @import("lit_mesh.frag");
|
||||||
const depthOnly = @import("depthOnly.frag");
|
const depthOnly = @import("depthOnly.frag");
|
||||||
const sample_vert = @import("sample.vert");
|
const sample_vert = @import("sample.vert");
|
||||||
|
|
||||||
|
const skybox_vert = @import("skybox.vert");
|
||||||
|
const skybox_frag = @import("skybox.frag");
|
||||||
|
|
||||||
const MeshVertices = meshes_vert.Scene;
|
const MeshVertices = meshes_vert.Scene;
|
||||||
const MeshUniforms = meshes_vert.Uniforms;
|
const MeshUniforms = meshes_vert.Uniforms;
|
||||||
|
|
||||||
|
|
@ -743,6 +841,10 @@ pub fn registerRendererObject(comptime T: type, object: *anyopaque) !void {
|
||||||
return try gRenderer.registerRendererObject(T, object);
|
return try gRenderer.registerRendererObject(T, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setSkyboxTexture(name: []const u8) void {
|
||||||
|
gRenderer.skyboxTextureName = core.MakeName(name);
|
||||||
|
}
|
||||||
|
|
||||||
pub const getMesh = mesh_pool.getMesh;
|
pub const getMesh = mesh_pool.getMesh;
|
||||||
pub const getMeshByName = mesh_pool.getMeshByName;
|
pub const getMeshByName = mesh_pool.getMeshByName;
|
||||||
pub const pushMeshUpdate = mesh_pool.pushMeshUpdate;
|
pub const pushMeshUpdate = mesh_pool.pushMeshUpdate;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ pub const TextureFormat = enum(u8) {
|
||||||
};
|
};
|
||||||
pub const TextureUsage = struct {
|
pub const TextureUsage = struct {
|
||||||
mesh: bool = false,
|
mesh: bool = false,
|
||||||
|
cube: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// handle to a texture resource in the engine.
|
// handle to a texture resource in the engine.
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -92,7 +92,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo
|
||||||
for (int _163 = -4; _163 <= 4; )
|
for (int _163 = -4; _163 <= 4; )
|
||||||
{
|
{
|
||||||
_153++;
|
_153++;
|
||||||
_150 += float((in.in_var_TEXCOORD3.z - 0.001000000047497451305389404296875) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_142 + float2(float(_163) * 0.000244140625, float(_154) * 0.000244140625))).x);
|
_150 += float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_142 + float2(float(_163) * 0.000244140625, float(_154) * 0.000244140625))).x);
|
||||||
_163++;
|
_163++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 out_var_SV_Target0 [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
float3 in_var_TEXCOORD0 [[user(locn0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0(main0_in in [[stage_in]], texturecube<float> SkyboxTexture [[texture(0)]], sampler SkyboxSampler [[sampler(0)]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
out.out_var_SV_Target0 = powr(SkyboxTexture.sample(SkyboxSampler, in.in_var_TEXCOORD0), float4(0.4545454680919647216796875));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct type_Uniforms
|
||||||
|
{
|
||||||
|
float4x4 ViewProjection;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float3 out_var_TEXCOORD0 [[user(locn0)]];
|
||||||
|
float4 gl_Position [[position]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
float3 in_var_TEXCOORD0 [[attribute(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD0;
|
||||||
|
out.gl_Position = Uniforms.ViewProjection * float4(in.in_var_TEXCOORD0, 1.0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -51,6 +51,21 @@ const assetReferences = [_]assets.AssetImportReference{
|
||||||
"t_empire",
|
"t_empire",
|
||||||
.{ .path = "textures/lost_empire-RGBA.png" },
|
.{ .path = "textures/lost_empire-RGBA.png" },
|
||||||
),
|
),
|
||||||
|
assets.MakeImportRefOptions(
|
||||||
|
"Texture",
|
||||||
|
"t_skybox",
|
||||||
|
.{
|
||||||
|
.textureCube = true,
|
||||||
|
.textureList = &.{
|
||||||
|
"sky_air/cube_right.png", // cubemapfacePositivex, right
|
||||||
|
"sky_air/cube_left.png", // cubemapfacePositivex, right
|
||||||
|
"sky_air/cube_up.png", // cubemapfacePositivex, right
|
||||||
|
"sky_air/cube_down.png", // cubemapfacePositivex, right
|
||||||
|
"sky_air/cube_back.png", // cubemapfacePositivex, right
|
||||||
|
"sky_air/cube_front.png", // cubemapfacePositivex, right
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn prepare(self: *@This()) !void {
|
pub fn prepare(self: *@This()) !void {
|
||||||
|
|
@ -63,6 +78,8 @@ pub fn prepare(self: *@This()) !void {
|
||||||
|
|
||||||
try assets.loadList(assetReferences);
|
try assets.loadList(assetReferences);
|
||||||
|
|
||||||
|
rend.setSkyboxTexture("t_skybox");
|
||||||
|
|
||||||
const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
|
const exitInput = try core.ActionBinding.create(core.MakeName("exit"));
|
||||||
exitInput.addKey(.escape, .keyDown);
|
exitInput.addKey(.escape, .keyDown);
|
||||||
_ = exitInput.data.addListener(null, onExit);
|
_ = exitInput.data.addListener(null, onExit);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue