summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromnisci3nce <omniscient.oce@gmail.com>2024-07-18 12:03:15 +1000
committeromnisci3nce <omniscient.oce@gmail.com>2024-07-18 12:03:15 +1000
commit4d198fe4f5cbe9e022776bdbd0bd8ec8094c8953 (patch)
tree4fbbf2feba811ded8923bd964f940f1c71c78c0d
parentc3737fff1be704e14a2bada69bbf8a6709c5f670 (diff)
draw pbr container
-rw-r--r--assets/shaders/pbr_textured.frag8
-rw-r--r--assets/shaders/pbr_textured.vert5
-rw-r--r--examples/game_demo/game_demo.c5
-rw-r--r--src/new_render/pbr.c72
-rw-r--r--src/new_render/pbr.h4
-rw-r--r--src/new_render/render.c1
-rw-r--r--src/new_render/shader_layouts.h29
-rw-r--r--src/ral/backends/opengl/backend_opengl.c4
-rw-r--r--src/ral/ral_types.h1
9 files changed, 111 insertions, 18 deletions
diff --git a/assets/shaders/pbr_textured.frag b/assets/shaders/pbr_textured.frag
index e76a099..5353fa7 100644
--- a/assets/shaders/pbr_textured.frag
+++ b/assets/shaders/pbr_textured.frag
@@ -6,6 +6,8 @@ in vec3 fragWorldPos;
in vec3 fragNormal;
in vec2 fragTexCoords;
+in vec4 viewPos;
+
struct PointLight {
vec4 position;
vec4 color;
@@ -15,11 +17,11 @@ struct PointLight {
// Lights data
#define NUM_POINT_LIGHTS 4
-uniform Scene_Lights {
+uniform Lights {
PointLight pointLights[NUM_POINT_LIGHTS];
- vec4 viewPos;
} scene;
+
// Material Textures
uniform sampler2D albedoMap;
uniform sampler2D metallicRoughnessMap;
@@ -62,7 +64,7 @@ void main() {
// vec3 norm = normalize(fragNormal); // N
vec3 norm = getNormalFromMap();
vec3 N = norm;
- vec3 viewDir = normalize(vec3(scene.viewPos) - fragWorldPos); // V
+ vec3 viewDir = normalize(vec3(viewPos) - fragWorldPos); // V
vec3 V = viewDir;
vec3 F0 = vec3(0.04);
diff --git a/assets/shaders/pbr_textured.vert b/assets/shaders/pbr_textured.vert
index 391cef3..2021691 100644
--- a/assets/shaders/pbr_textured.vert
+++ b/assets/shaders/pbr_textured.vert
@@ -8,6 +8,7 @@ layout(location = 2) in vec2 inTexCoords;
uniform Camera {
mat4 view;
mat4 proj;
+ vec4 viewPos;
} cam;
uniform Model {
@@ -19,10 +20,14 @@ layout(location = 0) out vec3 fragWorldPos;
layout(location = 1) out vec3 fragNormal;
layout(location = 2) out vec2 fragTexCoords;
+out vec4 viewPos;
+
void main() {
fragWorldPos = vec3(model.inner * vec4(inPosition, 1.0));
fragNormal = mat3(transpose(inverse(model.inner))) * inNormal; // world-space normal
fragTexCoords = inTexCoords;
+ viewPos = cam.viewPos;
+
gl_Position = cam.proj * cam.view * model.inner * vec4(inPosition, 1.0);
}
diff --git a/examples/game_demo/game_demo.c b/examples/game_demo/game_demo.c
index 10dd2be..73c879c 100644
--- a/examples/game_demo/game_demo.c
+++ b/examples/game_demo/game_demo.c
@@ -6,7 +6,6 @@
#include <assert.h>
#include "camera.h"
#include "core.h"
-#include "loaders.h"
#include "maths.h"
#include "primitives.h"
#include "ral_types.h"
@@ -15,8 +14,6 @@
#include "render_types.h"
#include "skybox.h"
#include "str.h"
-#include "terrain.h"
-#include "transform_hierarchy.h"
static const char* faces[6] = { "assets/demo/skybox/right.jpg", "assets/demo/skybox/left.jpg",
"assets/demo/skybox/top.jpg", "assets/demo/skybox/bottom.jpg",
@@ -70,7 +67,7 @@ int main() {
.pbr_ao_map = ao_map };
RenderEnt crate_renderable = {
- .mesh = &crate_mesh, .material = &crate_mat, .affine = mat4_ident(), .casts_shadows = true
+ .mesh = &crate_mesh, .material = &crate_mat, .affine = mat4_scale(3.0), .casts_shadows = true
};
RenderEnt entities[] = { crate_renderable };
diff --git a/src/new_render/pbr.c b/src/new_render/pbr.c
index b1ca005..6ac5613 100644
--- a/src/new_render/pbr.c
+++ b/src/new_render/pbr.c
@@ -1,9 +1,14 @@
#include "pbr.h"
+#include "camera.h"
+#include "core.h"
#include "file.h"
#include "log.h"
+#include "maths.h"
#include "ral_common.h"
#include "ral_impl.h"
#include "ral_types.h"
+#include "render_scene.h"
+#include "render_types.h"
#include "shader_layouts.h"
void PBR_Init(PBR_Storage* storage) {
@@ -31,12 +36,13 @@ GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass) {
ShaderData camera_data = { .get_layout = &Binding_Camera_GetLayout };
ShaderData model_data = { .get_layout = &Binding_Model_GetLayout };
ShaderData material_data = { .get_layout = &PBRMaterial_GetLayout };
+ ShaderData lights_data = { .get_layout = &Binding_Lights_GetLayout };
GraphicsPipelineDesc desc = {
.debug_name = "PBR Pipeline",
.vertex_desc = static_3d_vertex_description(),
- .data_layouts = {camera_data,model_data,material_data},
- .data_layouts_count = 3,
+ .data_layouts = {camera_data,model_data,material_data, lights_data },
+ .data_layouts_count = 4,
.vs = { .debug_name = "PBR (textured) Vertex Shader",
.filepath = vert_path,
.code = vertex_shader.contents },
@@ -50,6 +56,68 @@ GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass) {
return GPU_GraphicsPipeline_Create(desc, rpass);
}
+void PBR_Execute(PBR_Storage* storage, Camera camera, TextureHandle shadowmap_tex,
+ RenderEnt* entities, size_t entity_count) {
+ // 1. set up our pipeline
+
+ // 2. upload constant data (camera, lights)
+
+ // 3. draw each entity
+ // - upload material data
+ // - upload model transform
+ // - emit draw call
+
+ GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
+ GPU_CmdEncoder_BeginRender(enc, storage->pbr_pass);
+ GPU_EncodeBindPipeline(enc, storage->pbr_pipeline);
+
+ // Feed shader data
+ Mat4 view, proj;
+ Camera_ViewProj(&camera, 1000, 1000, &view, &proj);
+ Binding_Camera camera_data = { .view = view,
+ .projection = proj,
+ .viewPos = vec4(camera.position.x, camera.position.y,
+ camera.position.z, 1.0) };
+ GPU_EncodeBindShaderData(
+ enc, 0, (ShaderData){ .data = &camera_data, .get_layout = &Binding_Camera_GetLayout });
+
+ Vec3 light_color = vec3(300.0, 300.0, 300.0);
+ Binding_Lights
+ lights_data = { .pointLights = {
+ // FIXME: fill out soem default lights to use
+ (pbr_point_light){ .pos = vec3(10, 10, 10), .color = light_color },
+ (pbr_point_light){ .pos = vec3(-10, 10, 10), .color = light_color },
+ (pbr_point_light){ .pos = vec3(10, -10, 10), .color = light_color },
+ (pbr_point_light){ .pos = vec3(-10, -10, 10), .color = light_color },
+ } };
+ GPU_EncodeBindShaderData(
+ enc, 3, (ShaderData){ .data = &lights_data, .get_layout = &Binding_Lights_GetLayout });
+
+ // TODO: Add shadowmap texture to uniforms
+
+ for (size_t ent_i = 0; ent_i < entity_count; ent_i++) {
+ RenderEnt renderable = entities[ent_i];
+
+ // upload material data
+ PBRMaterialUniforms material_data = { .mat = *renderable.material };
+ GPU_EncodeBindShaderData(
+ enc, 2, (ShaderData){ .data = &material_data, .get_layout = PBRMaterial_GetLayout });
+
+ // upload model transform
+ Binding_Model model_data = { .model = renderable.affine };
+ GPU_EncodeBindShaderData(
+ enc, 1, (ShaderData){ .data = &model_data, .get_layout = &Binding_Model_GetLayout });
+
+ // set buffers
+ GPU_EncodeSetVertexBuffer(enc, renderable.mesh->vertex_buffer);
+ GPU_EncodeSetIndexBuffer(enc, renderable.mesh->index_buffer);
+ // draw
+ GPU_EncodeDrawIndexed(enc, renderable.mesh->geometry->indices->len);
+ }
+
+ GPU_CmdEncoder_EndRender(enc);
+}
+
ShaderDataLayout PBRMaterial_GetLayout(void* data) {
PBRMaterialUniforms* d = (PBRMaterialUniforms*)data;
bool has_data = data != NULL;
diff --git a/src/new_render/pbr.h b/src/new_render/pbr.h
index 4ee6810..f3bad4b 100644
--- a/src/new_render/pbr.h
+++ b/src/new_render/pbr.h
@@ -54,15 +54,15 @@ typedef struct PBR_Textures {
typedef struct MaterialMap MaterialMap;
GPU_Renderpass* PBR_RPassCreate();
+
GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass);
+
void PBR_Execute(
PBR_Storage* storage,
Camera camera,
TextureHandle shadowmap_tex,
- MaterialMap* materials, // map of String -> Material
RenderEnt* entities,
size_t entity_count
-
);
ShaderDataLayout PBRMaterial_GetLayout(void* data); \ No newline at end of file
diff --git a/src/new_render/render.c b/src/new_render/render.c
index 1213f1d..d98db4f 100644
--- a/src/new_render/render.c
+++ b/src/new_render/render.c
@@ -131,6 +131,7 @@ void Render_RenderEntities(RenderEnt* entities, size_t entity_count) {
// Mat4 light_view = mat4_look_at(pos, VEC3_ZERO, VEC3_Y);
// Mat4 light_space_matrix = mat4_mult(light_view, light_projection);
// Shadow_ShadowmapExecute(ren->shadows, light_space_matrix, entities, entity_count);
+ PBR_Execute(ren->pbr, scene.camera, INVALID_TEX_HANDLE, entities, entity_count);
}
TextureData TextureDataLoad(const char* path, bool invert_y) {
diff --git a/src/new_render/shader_layouts.h b/src/new_render/shader_layouts.h
index e34e790..c98f3c5 100644
--- a/src/new_render/shader_layouts.h
+++ b/src/new_render/shader_layouts.h
@@ -6,6 +6,7 @@
typedef struct Binding_Camera {
Mat4 view;
Mat4 projection;
+ Vec4 viewPos;
} Binding_Camera;
typedef struct Binding_Model {
@@ -24,10 +25,9 @@ typedef struct pbr_point_light {
f32 pad2;
} pbr_point_light;
-typedef struct Binding_PointLights {
+typedef struct Binding_Lights {
pbr_point_light pointLights[4];
- Vec4 viewPos;
-} Binding_PointLights;
+} Binding_Lights;
static ShaderDataLayout Binding_Camera_GetLayout(void* data) {
Binding_Camera* d = data;
@@ -35,7 +35,8 @@ static ShaderDataLayout Binding_Camera_GetLayout(void* data) {
ShaderBinding b1 = {
.label = "Camera",
- .kind = BINDING_BYTES
+ .kind = BINDING_BYTES,
+ .data.bytes = { .size = sizeof(Binding_Camera) }
};
if (has_data) {
b1.data.bytes.data = d;
@@ -49,7 +50,25 @@ static ShaderDataLayout Binding_Model_GetLayout(void* data) {
ShaderBinding b1 = {
.label = "Model",
- .kind = BINDING_BYTES
+ .kind = BINDING_BYTES,
+ .vis = VISIBILITY_VERTEX,
+ .data.bytes = { .size = sizeof(Binding_Model) }
+ };
+ if (has_data) {
+ b1.data.bytes.data = d;
+ }
+ return (ShaderDataLayout) {.bindings = {b1 }, .binding_count = 1};
+}
+
+static ShaderDataLayout Binding_Lights_GetLayout(void* data) {
+Binding_Lights* d = data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "Lights",
+ .kind = BINDING_BYTES,
+ .vis = VISIBILITY_FRAGMENT,
+ .data.bytes = { .size = sizeof(Binding_Lights) }
};
if (has_data) {
b1.data.bytes.data = d;
diff --git a/src/ral/backends/opengl/backend_opengl.c b/src/ral/backends/opengl/backend_opengl.c
index ecf0e80..f4786b9 100644
--- a/src/ral/backends/opengl/backend_opengl.c
+++ b/src/ral/backends/opengl/backend_opengl.c
@@ -126,7 +126,7 @@ GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description,
assert(binding_id < MAX_PIPELINE_UNIFORM_BUFFERS);
ShaderBinding binding = sdl.bindings[binding_j];
// Do I want Buffer vs Bytes?
- if (binding.kind == BINDING_BUFFER) {
+ if (binding.kind == BINDING_BYTES) {
static u32 s_binding_point = 0;
BufferHandle ubo_handle = GPU_BufferCreate(binding.data.bytes.size, BUFFER_UNIFORM,
BUFFER_FLAG_GPU, NULL); // no data right now
@@ -317,7 +317,7 @@ PUB void GPU_EncodeBindShaderData(GPU_CmdEncoder* encoder, u32 group, ShaderData
}
}
if (!found) {
- ERROR("Couldnt find uniform buffer object!!");
+ ERROR("Couldnt find uniform buffer object for %s!!", binding.label);
}
i32 blockIndex = glGetUniformBlockIndex(encoder->pipeline->shader_id, binding.label);
diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h
index 092bb2b..54dba56 100644
--- a/src/ral/ral_types.h
+++ b/src/ral/ral_types.h
@@ -21,6 +21,7 @@ CORE_DEFINE_HANDLE(ShaderHandle);
CORE_DEFINE_HANDLE(PipelineLayoutHandle);
CORE_DEFINE_HANDLE(PipelineHandle);
CORE_DEFINE_HANDLE(RenderpassHandle);
+#define INVALID_TEX_HANDLE ((TextureHandle){.raw = 9999999 })
// --- Buffers
typedef enum GPU_BufferType{