Skip to content

Instantly share code, notes, and snippets.

View NotAPenguin0's full-sized avatar
๐Ÿ‘€
I code graphics

NotAPenguin NotAPenguin0

๐Ÿ‘€
I code graphics
View GitHub Profile
@NotAPenguin0
NotAPenguin0 / promise_compose.rs
Created March 29, 2023 14:44
promise_compose
use anyhow::Result;
use poll_promise::Promise;
use crate::thread::yield_now;
pub trait SpawnPromise {
type Output: Send + 'static;
fn spawn<F: FnOnce() -> Self::Output + Send + 'static>(func: F) -> Self;
}
using ModelMaterials = std::vector<Handle<Material>>;
static Handle<Texture> get_texture_if_present(Context& ctx, fs::path const& cwd, aiMaterial* material, aiTextureType type, bool srgb = false) {
if (material->GetTextureCount(type) > 0) {
aiString path;
material->GetTexture(type, 0, &path);
fs::path load_path = cwd / fs::path(path.C_Str());
Handle<Texture> handle = ctx.request_texture(load_path.generic_string(), srgb);
void calculate_depth_range() {
// Coordinate of the pixel on screen
ivec2 screen_pixel = ivec2(gl_GlobalInvocationID.xy);
vec2 UV = vec2(screen_pixel) / pc.screen_size;
ivec2 tex_size = ivec2(textureSize(depth_map));
ivec2 texels = ivec2(UV * tex_size);
float depth = texelFetch(depth_map, texels, 0).r;
// Depth values must be linearized because we stored them after applying projection
float saturate(float x) {
return max(0.0, min(x, 1.0));
}
float calculate_attenuation(PointLight light) {
float dist = length(world_pos - light.transform.xyz);
float radius = light.transform.w;
float num = saturate(1 - pow(dist / radius, 4));
return light.color.a * num * num / (dist * dist + 1);
}
#version 450
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout (binding = 0) uniform samplerCube cube_map;
layout (binding = 1, rgba32f) uniform imageCube irradiance_map;
vec3 view_pos = vec3(0, 0, 0);
vec3 view_target[6] = {
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout (binding = 0) uniform samplerCube cube_map;
layout (binding = 1, rgba32f) uniform imageCube specular_map;
vec3 view_pos = vec3(0, 0, 0);
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout (binding = 0) uniform samplerCube cube_map;
layout (binding = 1, rgba32f) uniform imageCube specular_map;
vec3 view_pos = vec3(0, 0, 0);
@NotAPenguin0
NotAPenguin0 / task_scheduler.hpp
Last active July 5, 2020 16:55
task scheduler
#ifndef ANDROMEDA_TASK_MANAGER_HPP_
#define ANDROMEDA_TASK_MANAGER_HPP_
#include <ftl/task_scheduler.h>
#include <memory>
#include <functional>
namespace andromeda {
class TaskManager;

How do you descriptor set?

Descriptor sets have vexed me at every step of development. They're new and different and they have a lot of rules which aren't all that obvious. This document will hopefully lay out everything in one convenient place that I - and also you - can refer to

First, let's talk about what we're trying to do

Use Case

Most renderers need some way for shaders to access resources like textures, buffers, etc. For the Vulkan API, this way is the almighty descriptor set. Descriptor sets, as I understand them, are essentially a pointer to a resource. You update your descriptor sets with your resource, then you bind the descriptor sets to your command buffer, then shaders involved in subsequent drawcalls can look at the descriptors to know what resources they should actually read from. I'm not entirely sure why there's this indirection - and in fact, on AMD GPUs descriptor sets are actually just pointers - but the indirection exists, and we all have to find a way to deal with it

void EnvMapLoader::create_specular_map(ftl::TaskScheduler* scheduler, ph::VulkanContext& vulkan, EnvMapProcessData& process_data) {
const uint32_t mip_count = std::log2(process_data.specular_map_base_size) + 1;
process_data.specular_map = ph::create_image(vulkan, process_data.specular_map_base_size, process_data.specular_map_base_size,
ph::ImageType::EnvMap, vk::Format::eR32G32B32A32Sfloat, 6, mip_count);
process_data.specular_map_view = ph::create_image_view(vulkan.device, process_data.specular_map);
process_data.specular_map_mips.resize(mip_count);
for (uint32_t level = 0; level < mip_count; ++level) {
process_data.specular_map_mips[level] = ph::create_image_view_level(vulkan.device, process_data.specular_map, level);