Skip to content

Instantly share code, notes, and snippets.

@Reputeless
Created October 24, 2023 08:13
Show Gist options
  • Save Reputeless/36cc7695fa1a3f6bc22b5d19773ed6c9 to your computer and use it in GitHub Desktop.
Save Reputeless/36cc7695fa1a3f6bc22b5d19773ed6c9 to your computer and use it in GitHub Desktop.
# include <Siv3D.hpp>
struct Particle3D : IEffect
{
Vec3 m_pos;
Mesh m_billboardMesh;
Texture m_texture;
std::shared_ptr<BasicCamera3D> m_pCamera;
explicit Particle3D(const Vec3& pos, const Mesh& billboardMesh, const Texture& texture, const std::shared_ptr<BasicCamera3D>& pCamera)
: m_pos{ pos }
, m_billboardMesh{ billboardMesh }
, m_texture{ texture }
, m_pCamera{ pCamera } {}
bool update(double t) override
{
const Vec3 pos = (m_pos + Vec3{ 0, 2, 0 } * t);
const double scale = (1.0 + t * 2.0);
const double alpha = (1.0 - t);
m_billboardMesh.draw(m_pCamera->billboard(pos, scale), m_texture, ColorF{ 0.97, alpha }.removeSRGBCurve());
// 1 秒未満なら継続する
return (t < 1.0);
}
};
void Main()
{
Window::Resize(1280, 720);
const ColorF backgroundColor = ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve();
const Texture uvChecker{ U"example/texture/uv.png", TextureDesc::MippedSRGB };
const Texture particleTexture{ U"example/particle.png", TextureDesc::MippedSRGB };
const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
// エフェクトに渡せるよう、カメラを shared_ptr で管理する
std::shared_ptr<DebugCamera3D> pCamera = std::make_shared<DebugCamera3D>(renderTexture.size(), 30_deg, Vec3{ 10, 16, -32 } );
const Mesh billboardMesh{ MeshData::Billboard() };
Effect effect3D;
while (System::Update())
{
pCamera->update(2.0);
Graphics3D::SetCameraTransform(*pCamera);
// 3D 描画
{
const ScopedRenderTarget3D target{ renderTexture.clear(backgroundColor) };
Plane{ 64 }.draw(uvChecker);
Sphere{ 0, 2, 0, 2 }.draw(ColorF{ 0.4, 0.8, 0.6 }.removeSRGBCurve());
// 3D のエフェクトを描画する
{
// ブレンドモード有効、深度書き込み無効
const ScopedRenderStates3D states{ BlendState::Default2D, DepthStencilState::DepthTest };
effect3D.update();
}
}
// 3D シーンを 2D シーンに描画
{
Graphics3D::Flush();
renderTexture.resolve();
Shader::LinearToScreen(renderTexture);
}
if (SimpleGUI::Button(U"Smoke", Vec2{ 40, 40 }))
{
const Vec3 pos = (Vec3{ 0, 4, 0 } + RandomVec3insideUnitSphere() * 1);
effect3D.add<Particle3D>(pos, billboardMesh, particleTexture, pCamera);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment