For those short on time:
#extension GL_NV_gpu_shader5 : enable
#extension GL_EXT_nonuniform_qualifier : enable
#ifdef GL_EXT_nonuniform_qualifier
#define NonUniformIndex(x) nonuniformEXT(x)
#include "glm/glm.hpp" | |
#include "entt/meta/meta.hpp" | |
#include <unordered_map> | |
// Components that we want to reflect for a hypothetical game. | |
struct LocalTransform | |
{ | |
glm::vec3 position; | |
glm::quat rotation; |
#include <glslang/Public/ShaderLang.h> | |
#include <glslang/SPIRV/GlslangToSpv.h> | |
#include <vector> | |
#include <cassert> | |
#include <stdexcept> | |
#include <fstream> | |
#include <stdexcept> | |
#include <memory> | |
#include <coro/coro.hpp> | |
namespace test | |
{ | |
class semaphore | |
{ | |
public: | |
enum class acquire_result | |
{ | |
acquired, |
uint pixel_index = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) * 4096u; | |
uint seed = pcg_hash(pixel_index); | |
float shadow = Shadow(seed, fragWorldPos, normal, -shadingUniforms.sunDir.xyz); | |
float shadow_accum = shadow; | |
int succ = 0; | |
for (int i = 0; i < 4; i++) | |
{ | |
if (shadow_accum / (i + 1) > 0.0 && shadow_accum / (i + 1) < 2.0 / (shadowUniforms.pcfSamples * (i + 1)) + 0.0001) | |
{ | |
succ++; |
/* | |
* This snippet demonstrates how to copy the contents of a buffer to another buffer without CPU readback | |
* using only features available in OpenGL 2.1. | |
* I use DSA for brevity, but hopefully it should be obvious how to convert this to ancient GL if needed :) | |
* The method involves creating a temporary texture and framebuffer, copying the source buffer's contents | |
* to the texture (via pixel unpack), then copying the texture's contents to the destination buffer using pixel pack. | |
*/ | |
// convenience | |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
#extension GL_ARB_shader_ballot : require | |
uint NonUniform(uint i) | |
{ | |
for (;;) | |
{ | |
uint cur = readFirstInvocationARB(i); | |
if (cur == i) | |
{ | |
return cur; | |
} |
// PCG hash, see: | |
// https://www.reedbeta.com/blog/hash-functions-for-gpu-rendering/ | |
// Used as initial seed to the PRNG. | |
uint pcg_hash(uint seed) | |
{ | |
uint state = seed * 747796405u + 2891336453u; | |
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; | |
return (word >> 22u) ^ word; | |
} |
int GetCubeFaceIndex(vec3 dir) | |
{ | |
float x = abs(dir.x); | |
float y = abs(dir.y); | |
float z = abs(dir.z); | |
if (x > y && x > z) | |
return 0 + (dir.x > 0 ? 0 : 1); | |
else if (y > z) | |
return 2 + (dir.y > 0 ? 0 : 1); | |
return 4 + (dir.z > 0 ? 0 : 1); |
#pragma once | |
class Timer | |
{ | |
public: | |
Timer(); | |
void Reset(); | |
double Elapsed_s() const; | |
Timer(const Timer& other); |