Skip to content

Commit

Permalink
webgpu skybox
Browse files Browse the repository at this point in the history
  • Loading branch information
GrigoryGraborenko committed Feb 9, 2025
1 parent 4c75557 commit a9a8cb7
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 30 deletions.
1 change: 1 addition & 0 deletions Src/IncludeAll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "OpenGL/PipelineGL.cpp"
#endif
#include "Core.cpp"
#include "Resources.cpp"
#include "EditorViewers.cpp"
#include "Geometry.cpp"
#ifndef NESHNY_SKIP_TESTS
Expand Down
51 changes: 51 additions & 0 deletions Src/Resources.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

namespace Neshny {

#if defined(NESHNY_GL)
#elif defined(NESHNY_WEBGPU)

// TODO: move all appropriate code out of .h into here

bool TextureSkybox::Init(std::string_view path, Params params, std::string& err) {
std::vector<std::string> names = { "right", "left", "top", "bottom", "front", "back" };
for (int i = 0; i < 6; i++) {

std::string fullname = ReplaceAll(path, "*", names[i]);

SDL_Surface* surface = IMG_Load(fullname.data());
if (!surface) {
err = std::format("Could not load image {}", path);
return false;
}

if (surface->format->format != g_CorrectSDLFormat) {
SDL_Surface* converted_surface = SDL_ConvertSurfaceFormat(surface, g_CorrectSDLFormat, 0);
SDL_FreeSurface(surface);
surface = converted_surface;
}

if (i == 0) {
m_Texture.InitCubeMap(surface->w, surface->h);
}
auto sync_token = Core::Singleton().SyncWithMainThread();
m_Texture.CopyDataLayer(i, (unsigned char*)surface->pixels, surface->format->BytesPerPixel, surface->pitch, false);
}
return true;
};

void TextureSkybox::Render(WebGPURTT& rtt, const Matrix4& view_perspective) {
WebGPUPipeline::RenderParams render_params;
render_params.p_DepthWriteEnabled = false;
render_params.p_DepthCompare = WGPUCompareFunction_Always;
Neshny::EntityPipeline::RenderBuffer(SrcStr(), "SkyBox", Core::GetBuffer("Square"), render_params)
.SetUniform(view_perspective.ToGPU())
.AddTexture("SkyBox", &m_Texture)
.AddSampler("Sampler", Core::GetSampler(WGPUAddressMode_Repeat))
.Render(&rtt);
}

#endif

} // namespace Neshny
33 changes: 5 additions & 28 deletions Src/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,39 +148,16 @@ class TextureSkybox : public Resource {
struct Params {};
#pragma pack(pop)

virtual ~TextureSkybox(void) {}
virtual bool Init(std::string_view path, Params params, std::string& err) {
std::vector<std::string> names = { "right", "left", "top", "bottom", "front", "back" };
for (int i = 0; i < 6; i++) {

std::string fullname = ReplaceAll(path, "*", names[i]);

SDL_Surface* surface = IMG_Load(fullname.data());
if (!surface) {
err = std::format("Could not load image {}", path);
return false;
}

if (surface->format->format != g_CorrectSDLFormat) {
SDL_Surface* converted_surface = SDL_ConvertSurfaceFormat(surface, g_CorrectSDLFormat, 0);
SDL_FreeSurface(surface);
surface = converted_surface;
}
virtual ~TextureSkybox ( void ) {}
virtual bool Init ( std::string_view path, Params params, std::string& err );

if (i == 0) {
m_Texture.InitCubeMap(surface->w, surface->h);
}
auto sync_token = Core::Singleton().SyncWithMainThread();
m_Texture.CopyDataLayer(i, (unsigned char*)surface->pixels, surface->format->BytesPerPixel, surface->pitch, false);
}
return true;
};
void Render ( WebGPURTT& rtt, const Matrix4& view_perspective );

const WebGPUTexture& Get ( void ) const { return m_Texture; }
WGPUTextureView GetTextureView ( void ) const { return m_Texture.GetTextureView(); }

virtual uint64_t GetMemoryEstimate ( void ) const { return 0; }
virtual uint64_t GetGPUMemoryEstimate ( void ) const { return m_Texture.GetWidth() * m_Texture.GetHeight() * m_Texture.GetDepthBytes() * 6; }
virtual uint64_t GetMemoryEstimate ( void ) const { return 0; }
virtual uint64_t GetGPUMemoryEstimate ( void ) const { return m_Texture.GetWidth() * m_Texture.GetHeight() * m_Texture.GetDepthBytes() * 6; }

protected:
WebGPUTexture m_Texture;
Expand Down
29 changes: 29 additions & 0 deletions Src/Shaders/SkyBox.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct VertexIn {
@location(0) aPos : vec2f
}
struct VertexOut {
@builtin(position) Position : vec4f,
@location(0) vScreenPos : vec2f
}

@vertex
fn vertex_main(input : VertexIn) -> VertexOut {
var output : VertexOut;
output.vScreenPos = input.aPos;
output.Position = vec4f(input.aPos, 0.0, 1.0);
return output;
}
@fragment
fn frag_main(input: VertexOut) -> @location(0) vec4f {

var eye_pos_a : vec4f = Uniform.Matrix4x4 * vec4f(input.vScreenPos.xy, -1.0, 1.0);
var eye_pos_b : vec4f = Uniform.Matrix4x4 * vec4f(input.vScreenPos.xy, -0.9, 1.0);
eye_pos_a /= eye_pos_a.w;
eye_pos_b /= eye_pos_b.w;
let eye_pos_dir : vec3f = normalize(eye_pos_b.xyz - eye_pos_a.xyz);

let skybox_lookup = textureSampleLevel(SkyBox, Sampler, eye_pos_dir, 0.0).xyz;

return vec4f(skybox_lookup, 1.0);
}
8 changes: 6 additions & 2 deletions Src/WebGPU/PipelineWebGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ class EntityPipeline {
EntityPipeline& SetUniform ( const T& uniform ) {

m_Uniform.p_Spec.clear();
Serialiser<T> serializeFunc(m_Uniform.p_Spec);
meta::doForAllMembers<T>(serializeFunc);
if constexpr (std::is_same<T, fMatrix4>::value) {
m_Uniform.p_Spec.push_back({ "Matrix4x4", MemberSpec::T_MAT4, sizeof(fMatrix4), false });
} else {
Serialiser<T> serializeFunc(m_Uniform.p_Spec);
meta::doForAllMembers<T>(serializeFunc);
}
m_Uniform.p_Data = { (unsigned char*)&uniform, sizeof(uniform) };
return *this;
}
Expand Down

0 comments on commit a9a8cb7

Please sign in to comment.