diff options
author | omnisci3nce <omniscient.oce@gmail.com> | 2024-07-18 12:03:15 +1000 |
---|---|---|
committer | omnisci3nce <omniscient.oce@gmail.com> | 2024-07-18 12:03:15 +1000 |
commit | 4d198fe4f5cbe9e022776bdbd0bd8ec8094c8953 (patch) | |
tree | 4fbbf2feba811ded8923bd964f940f1c71c78c0d | |
parent | c3737fff1be704e14a2bada69bbf8a6709c5f670 (diff) |
draw pbr container
-rw-r--r-- | assets/shaders/pbr_textured.frag | 8 | ||||
-rw-r--r-- | assets/shaders/pbr_textured.vert | 5 | ||||
-rw-r--r-- | examples/game_demo/game_demo.c | 5 | ||||
-rw-r--r-- | src/new_render/pbr.c | 72 | ||||
-rw-r--r-- | src/new_render/pbr.h | 4 | ||||
-rw-r--r-- | src/new_render/render.c | 1 | ||||
-rw-r--r-- | src/new_render/shader_layouts.h | 29 | ||||
-rw-r--r-- | src/ral/backends/opengl/backend_opengl.c | 4 | ||||
-rw-r--r-- | src/ral/ral_types.h | 1 |
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{ |