Open10

OpenSiv3D v0.6, 3D 描画メモ

ピン留めされたアイテム
Ryo SuzukiRyo Suzuki

OpenSiv3D v0.6 の 3D 機能検証用サンプル

Ryo SuzukiRyo Suzuki

Test1

  • ColorSpace: ガンマスペース
  • RenderTarget: デフォルト (scene)

# include <Siv3D.hpp> // OpenSiv3D v0.6

void DrawModel(const Model& model, const Mat4x4& mat)
{
	const Transformer3D t{ mat };

	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Model::Draw(object, materials);
	}
}

void DrawMillModel(const Model& model, const Mat4x4& mat)
{
	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Mat4x4 m = Mat4x4::Identity();

		// 風車の羽根の回転
		if (object.name == U"Mill_Blades_Cube.007")
		{
			m *= Mat4x4::Rotate(Vec3{ 0,0,-1 }, (Scene::Time() * -120_deg), Vec3{ 0, 9.37401, 0 });
		}

		const Transformer3D t{ (m * mat) };

		Model::Draw(object, materials);
	}
}

void Main()
{
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4, 0.6, 0.8 });

	const Mesh groundPlane{ MeshData::OneSidedPlane(2000, { 400, 400 }) };
	const Texture groundTexture{ U"example/texture/ground.jpg", TextureDesc::Mipped };
	const Model blacksmithModel{ U"example/obj/blacksmith.obj", ColorOption::ApplySRGBCurve };
	const Model millModel{ U"example/obj/mill.obj", ColorOption::ApplySRGBCurve };
	const Model treeModel{ U"example/obj/tree.obj", ColorOption::ApplySRGBCurve };
	const Model pineModel{ U"example/obj/pine.obj", ColorOption::ApplySRGBCurve };
	Model::RegisterDiffuseTextures(treeModel, TextureDesc::Mipped);
	Model::RegisterDiffuseTextures(pineModel, TextureDesc::Mipped);

	DebugCamera3D camera{ Graphics3D::GetRenderTargetSize(), 25_deg, Vec3{ 0, 3, -16 } };
	Graphics3D::SetGlobalAmbientColor(ColorF{ 0.5 });
	Graphics3D::SetSunColor(ColorF{ 0.5 });

	while (System::Update())
	{
		// 3D
		{
			camera.update(4.0);
			Graphics3D::SetCameraTransform(camera);

			// draw models
			{
				// 地面の描画
				groundPlane.draw(groundTexture);

				// 球の描画
				Sphere{ { 0, 1, 0 }, 1 }.draw(ColorF{ 0.75 });

				// 鍛冶屋の描画
				DrawModel(blacksmithModel, Mat4x4::Translate(8, 0, 4));

				// 風車の描画
				DrawMillModel(millModel, Mat4x4::Translate(-8, 0, 4));

				// 木の描画
				{
					const ScopedRenderStates3D bl{ BlendState::OpaqueAlphaToCoverage, RasterizerState::SolidCullNone };
					DrawModel(treeModel, Mat4x4::Translate(16, 0, 4));
					DrawModel(pineModel, Mat4x4::Translate(16, 0, 0));
				}
			}
		}
	}
}
Ryo SuzukiRyo Suzuki

Test2

  • ColorSpace: リニアスペース
  • RenderTarget: RenderTexture

# include <Siv3D.hpp> // OpenSiv3D v0.6

void DrawModel(const Model& model, const Mat4x4& mat)
{
	const Transformer3D t{ mat };

	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Model::Draw(object, materials);
	}
}

void DrawMillModel(const Model& model, const Mat4x4& mat)
{
	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Mat4x4 m = Mat4x4::Identity();

		// 風車の羽根の回転
		if (object.name == U"Mill_Blades_Cube.007")
		{
			m *= Mat4x4::Rotate(Vec3{ 0,0,-1 }, (Scene::Time() * -120_deg), Vec3{ 0, 9.37401, 0 });
		}

		const Transformer3D t{ (m * mat) };

		Model::Draw(object, materials);
	}
}

void Main()
{
	Window::Resize(1280, 720);

	const Mesh groundPlane{ MeshData::OneSidedPlane(2000, { 400, 400 }) };
	const Texture groundTexture{ U"example/texture/ground.jpg", TextureDesc::MippedSRGB };
	const Model blacksmithModel{ U"example/obj/blacksmith.obj" };
	const Model millModel{ U"example/obj/mill.obj" };
	const Model treeModel{ U"example/obj/tree.obj" };
	const Model pineModel{ U"example/obj/pine.obj" };
	Model::RegisterDiffuseTextures(treeModel, TextureDesc::MippedSRGB);
	Model::RegisterDiffuseTextures(pineModel, TextureDesc::MippedSRGB);

	const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
	DebugCamera3D camera{ Graphics3D::GetRenderTargetSize(), 25_deg, Vec3{ 0, 3, -16 } };
	Graphics3D::SetGlobalAmbientColor(ColorF{ 0.5 });
	Graphics3D::SetSunColor(ColorF{ 1.0 });

	while (System::Update())
	{
		// 3D
		{
			camera.update(4.0);
			Graphics3D::SetCameraTransform(camera);
			renderTexture.clear(ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve());
			const ScopedRenderTarget3D target{ renderTexture };

			// draw models
			{
				// 地面の描画
				groundPlane.draw(groundTexture);

				// 球の描画
				Sphere{ { 0, 1, 0 }, 1 }.draw(ColorF{ 0.75 }.removeSRGBCurve());

				// 鍛冶屋の描画
				DrawModel(blacksmithModel, Mat4x4::Translate(8, 0, 4));

				// 風車の描画
				DrawMillModel(millModel, Mat4x4::Translate(-8, 0, 4));

				// 木の描画
				{
					const ScopedRenderStates3D bl{ BlendState::OpaqueAlphaToCoverage, RasterizerState::SolidCullNone };
					DrawModel(treeModel, Mat4x4::Translate(16, 0, 4));
					DrawModel(pineModel, Mat4x4::Translate(16, 0, 0));
				}
			}
		}

		// RenderTexture を 2D シーンに描画
		{
			Graphics3D::Flush();
			renderTexture.resolve();
			Shader::LinearToScreen(renderTexture);
		}
	}
}
Ryo SuzukiRyo Suzuki

Test3

  • ColorSpace: ガンマスペース
  • RenderTarget: デフォルト (scene)

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	DebugCamera3D camera{ Graphics3D::GetRenderTargetSize(), 45_deg, Vec3{ 0, 3, -16 } };
	Graphics3D::SetGlobalAmbientColor(ColorF{ 1.0 });
	Graphics3D::SetSunColor(ColorF{ 0.0 });

	while (System::Update())
	{
		// 3D
		{
			camera.update(4.0);
			Graphics3D::SetCameraTransform(camera);

			Plane{ 80 }.draw(ColorF{ 0.9, 0.8, 0.7 });

			for (auto i : Range(0, 10))
			{
				Sphere{ {i * 2, 1, 20}, 1 }.draw(ColorF{ i * 0.1 });
			}

			for (auto i : Range(0, 10))
			{
				Sphere{ {i * 2, 1, 0}, 1 }.draw(ColorF{ HSV{ i * 36, 0.8, 0.9 } });
			}
		}

		for (auto i : Range(0, 10))
		{
			Rect{ 200 + i * 40, 0, 40 }.draw(ColorF{ i * 0.1 });
		}

		for (auto i : Range(0, 10))
		{
			Rect{ 200 + i * 40, 200, 40 }.draw(HSV{ i * 36, 0.8, 0.9 });
		}

		PutText(U"色見本と球の色が一致すれば OK です。", Scene::Center());
	}
}
Ryo SuzukiRyo Suzuki

Test4

  • ColorSpace: リニアスペース
  • RenderTarget: RenderTexture

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	const RenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
	DebugCamera3D camera{ Graphics3D::GetRenderTargetSize(), 45_deg, Vec3{ 0, 3, -16 } };

	Graphics3D::SetGlobalAmbientColor(ColorF{ 1.0 });
	Graphics3D::SetSunColor(ColorF{ 0.0 });

	while (System::Update())
	{
		// 3D
		{
			renderTexture.clear(ColorF{ 0.8, 0.9, 1.0 }.removeSRGBCurve());
			camera.update(4.0);
			Graphics3D::SetCameraTransform(camera);
			const ScopedRenderTarget3D target{ renderTexture };

			Plane{ 80 }.draw(ColorF{ 0.9, 0.8, 0.7 }.removeSRGBCurve());

			for (auto i : Range(0, 10))
			{
				Sphere{ {i * 2, 1, 20}, 1 }.draw(ColorF{ i * 0.1 }.removeSRGBCurve());
			}

			for (auto i : Range(0, 10))
			{
				Sphere{ {i * 2, 1, 0}, 1 }.draw(ColorF{ HSV{ i * 36, 0.8, 0.9 } }.removeSRGBCurve());
			}
		}

		// RenderTexture を 2D シーンに描画
		{
			Graphics3D::Flush();
			Shader::LinearToScreen(renderTexture);
		}

		for (auto i : Range(0, 10))
		{
			Rect{ 200 + i * 40, 0, 40 }.draw(ColorF{ i * 0.1 });
		}

		for (auto i : Range(0, 10))
		{
			Rect{ 200 + i * 40, 200, 40 }.draw(HSV{ i * 36, 0.8, 0.9 });
		}

		PutText(U"色見本と球の色が一致すれば OK です。", Scene::Center());
	}
}
Ryo SuzukiRyo Suzuki

Test5

  • ColorSpace: リニアスペース
  • RenderTarget: MSRenderTexture

# include <Siv3D.hpp> // OpenSiv3D v0.6

void DrawModel(const Model& model, const Mat4x4& mat)
{
	const Transformer3D t{ mat };

	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Model::Draw(object, materials);
	}
}

void DrawMillModel(const Model& model, const Mat4x4& mat)
{
	const auto& materials = model.materials();

	for (const auto& object : model.objects())
	{
		Mat4x4 m = Mat4x4::Identity();

		// 風車の羽根の回転
		if (object.name == U"Mill_Blades_Cube.007")
		{
			m *= Mat4x4::Rotate(Vec3{ 0,0,-1 }, (Scene::Time() * -120_deg), Vec3{ 0, 9.37401, 0 });
		}

		const Transformer3D t{ (m * mat) };

		Model::Draw(object, materials);
	}
}

void Main()
{
	Window::Resize(1280, 720);

	const Mesh groundPlane{ MeshData::OneSidedPlane(2000, { 400, 400 }) };
	const Texture groundTexture{ U"example/texture/ground.jpg", TextureDesc::MippedSRGB };
	const Model blacksmithModel{ U"example/obj/blacksmith.obj" };
	const Model millModel{ U"example/obj/mill.obj" };
	const Model treeModel{ U"example/obj/tree.obj" };
	const Model pineModel{ U"example/obj/pine.obj" };
	Model::RegisterDiffuseTextures(treeModel, TextureDesc::MippedSRGB);
	Model::RegisterDiffuseTextures(pineModel, TextureDesc::MippedSRGB);

	const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
	DebugCamera3D camera{ Graphics3D::GetRenderTargetSize(), 40_deg, Vec3{ 0, 3, -16 } };

	Sky sky;
	double skyTime = 0.5;
	bool showUI = true;

	while (System::Update())
	{
		ClearPrint();
		Print << Profiler::FPS();

		// 3D
		{
			camera.update(4.0);
			Graphics3D::SetCameraTransform(camera);
			renderTexture.clear(ColorF{ 0.0 });
			const ScopedRenderTarget3D target{ renderTexture };

			// draw models
			{
				// 地面の描画
				groundPlane.draw(groundTexture);

				// 球の描画
				Sphere{ { 0, 1, 0 }, 1 }.draw(ColorF{ 0.75 }.removeSRGBCurve());

				// 鍛冶屋の描画
				DrawModel(blacksmithModel, Mat4x4::Translate(8, 0, 4));

				// 風車の描画
				DrawMillModel(millModel, Mat4x4::Translate(-8, 0, 4));

				// 木の描画
				{
					const ScopedRenderStates3D bl{ BlendState::OpaqueAlphaToCoverage, RasterizerState::SolidCullNone };
					DrawModel(treeModel, Mat4x4::Translate(16, 0, 4));
					DrawModel(pineModel, Mat4x4::Translate(16, 0, 0));
				}
			}

			// sky renderer
			{
				const double time0_2 = Math::Fraction(skyTime * 0.5) * 2.0;
				const double halfDay0_1 = Math::Fraction(skyTime);
				const double distanceFromNoon0_1 = Math::Saturate(1.0 - (Abs(0.5 - halfDay0_1) * 2.0));
				const bool night = (1.0 < time0_2);
				const double tf = EaseOutCubic(distanceFromNoon0_1);
				const double tc = EaseInOutCubic(distanceFromNoon0_1);
				const double starCenteredTime = Math::Fmod(time0_2 + 1.5, 2.0);

				// set sun
				{
					const Quaternion q = (Quaternion::RotateY(halfDay0_1 * 180_deg) * Quaternion::RotateX(50_deg));
					const Vec3 sunDirection = q * Vec3::Right();
					const ColorF sunColor{ 0.1 + Math::Pow(tf, 1.0 / 2.0) * (night ? 0.1 : 0.9) };

					Graphics3D::SetSunDirection(sunDirection);
					Graphics3D::SetSunColor(sunColor);
					Graphics3D::SetGlobalAmbientColor(ColorF{ sky.zenithColor });
				}

				// set sky color
				{
					if (night)
					{
						sky.zenithColor = ColorF{ 0.3, 0.05, 0.1 }.lerp(ColorF{ 0.1, 0.1, 0.15 }, tf);
						sky.horizonColor = ColorF{ 0.1, 0.1, 0.15 }.lerp(ColorF{ 0.1, 0.1, 0.2 }, tf);
					}
					else
					{
						sky.zenithColor = ColorF{ 0.4, 0.05, 0.1 }.lerp(ColorF{ 0.15, 0.24, 0.56 }, tf);
						sky.horizonColor = ColorF{ 0.2, 0.05, 0.15 }.lerp(ColorF{ 0.3, 0.4, 0.5 }, tf);
					}
				}

				// set parameters
				{
					sky.starBrightness = Math::Saturate(1.0 - Pow(Abs(1.0 - starCenteredTime) * 1.8, 4));
					sky.fogHeightSky = (1.0 - tf);
					sky.cloudColor = ColorF{ 0.02 + (night ? 0.0 : (0.98 * tc)) };
					sky.sunEnabled = (not night);
					sky.cloudTime = skyTime * sky.cloudScale * 40.0;
					sky.starTime = skyTime;
				}

				sky.draw();
			}
		}

		// RenderTexture を 2D シーンに描画
		{
			Graphics3D::Flush();
			renderTexture.resolve();
			Shader::LinearToScreen(renderTexture);
		}

		// 天空レンダリングエンジンのパラメータ設定
		if (showUI)
		{
			Rect{ 20, 20, 480, 76 }.draw();
			SimpleGUI::GetFont()(U"zenith:").draw(28, 24, ColorF{ 0.11 });
			Rect{ 100, 26, 28 }.draw(sky.zenithColor.gamma(2.2)).drawFrame(1, 0, ColorF{ 0.5 });
			SimpleGUI::GetFont()(U"horizon:").draw(148, 24, ColorF{ 0.11 });
			Rect{ 230, 26, 28 }.draw(sky.horizonColor.gamma(2.2)).drawFrame(1, 0, ColorF{ 0.5 });
			SimpleGUI::GetFont()(U"cloud:").draw(276, 24, ColorF{ 0.11 });
			Rect{ 340, 26, 28 }.draw(sky.cloudColor.gamma(2.2)).drawFrame(1, 0, ColorF{ 0.5 });
			SimpleGUI::GetFont()(U"sun:").draw(386, 24, ColorF{ 0.11 });
			Rect{ 430, 26, 28 }.draw(Graphics3D::GetSunColor().gamma(2.2)).drawFrame(1, 0, ColorF{ 0.5 });
			SimpleGUI::GetFont()(U"sunDir: {:.2f}   cloudTime: {:.1f}"_fmt(Graphics3D::GetSunDirection(), sky.cloudTime)).draw(28, 60, ColorF{ 0.11 });

			SimpleGUI::Slider(U"cloudiness: {:.3f}"_fmt(sky.cloudiness), sky.cloudiness, Vec2{ 20, 100 }, 180, 300);
			SimpleGUI::Slider(U"cloudScale: {:.2f}"_fmt(sky.cloudScale), sky.cloudScale, 0.0, 2.0, Vec2{ 20, 140 }, 180, 300);
			SimpleGUI::Slider(U"cloudHeight: {:.0f}"_fmt(sky.cloudPlaneHeight), sky.cloudPlaneHeight, 20.0, 6000.0, Vec2{ 20, 180 }, 180, 300);
			SimpleGUI::Slider(U"orientation: {:.0f}"_fmt(Math::ToDegrees(sky.cloudOrientation)), sky.cloudOrientation, 0.0, Math::TwoPi, Vec2{ 20, 220 }, 180, 300);
			SimpleGUI::Slider(U"fogHeightSky: {:.2f}"_fmt(sky.fogHeightSky), sky.fogHeightSky, Vec2{ 20, 260 }, 180, 300, false);
			SimpleGUI::Slider(U"star: {:.2f}"_fmt(sky.starBrightness), sky.starBrightness, Vec2{ 20, 300 }, 180, 300, false);
			SimpleGUI::Slider(U"starF: {:.2f}"_fmt(sky.starBrightnessFactor), sky.starBrightnessFactor, Vec2{ 20, 340 }, 180, 300);
			SimpleGUI::Slider(U"starSat: {:.2f}"_fmt(sky.starSaturation), sky.starSaturation, 0.0, 1.0, Vec2{ 20, 380 }, 180, 300);
			SimpleGUI::CheckBox(sky.sunEnabled, U"sun", Vec2{ 20, 420 }, 120, false);
			SimpleGUI::CheckBox(sky.cloudsEnabled, U"clouds", Vec2{ 150, 420 }, 120);
			SimpleGUI::CheckBox(sky.cloudsLightingEnabled, U"cloudsLighting", Vec2{ 280, 420 }, 220);
		}

		SimpleGUI::CheckBox(showUI, U"UI", Vec2{ 20, Scene::Height() - 100 });
		SimpleGUI::Slider(U"time: {:.2f}"_fmt(skyTime), skyTime, -2.0, 4.0, Vec2{ 20, Scene::Height() - 60 }, 120, Scene::Width() - 160);
	}
}
Ryo SuzukiRyo Suzuki

Test6

  • ColorSpace: ガンマスペース
  • RenderTarget: デフォルト (scene)

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	Window::Resize(1280, 720);
	Window::SetStyle(WindowStyle::Sizable);
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	const Texture windmillTexture{ U"example/windmill.png", TextureDesc::Mipped };
	const Texture earthTexture{ U"example/texture/earth.jpg", TextureDesc::Mipped };
	const Texture emoji{ U"🐈"_emoji };

	const Plane floorPlane{ { 0, 0.01, 0 }, 20 };
	Image image{ 1000, 1000, Palette::White };
	DynamicTexture dtexture{ image };
	Optional<Vec2> previousPenPos;

	const Mesh mesh{ MeshData::Cylinder({0, 4, 0}, 3, 3) };

	Graphics3D::SetGlobalAmbientColor(ColorF{ 0.6 });
	Graphics3D::SetSunColor(ColorF{ 0.4 });

	while (System::Update())
	{
		const double t = Scene::Time();
		constexpr double verticlaFOV = 30_deg;
		const Vec3 eyePosition = Cylindrical{ 20, (t * 1_deg), (8 + Periodic::Sine0_1(40s) * 8) };
		constexpr Vec3 focusPosition{ 0, 0, 0 };
		const BasicCamera3D camera{ Graphics3D::GetRenderTargetSize(), verticlaFOV, eyePosition, focusPosition, Vec3::Up(), 0.1 };
		const Ray ray = camera.screenToRay(Cursor::PosF());
		Graphics3D::SetCameraTransform(camera);

		if (const auto pos = ray.intersectsAt(floorPlane))
		{
			Sphere{ *pos, 0.2 }.draw(Palette::Orange);
			const Vec2 penPos = pos->xz();

			if (MouseL.pressed())
			{
				const Vec2 from = (previousPenPos ? *previousPenPos : penPos);
				const Vec2 to = penPos;
				previousPenPos = penPos;
				Line{ (from * Vec2{ 50, -50 }), (to * Vec2{ 50, -50 }) }
					.movedBy(500, 500)
					.overwrite(image, 5, Palette::Orange);
				dtexture.fill(image);
			}
			else
			{
				previousPenPos.reset();
			}
		}
		else
		{
			previousPenPos.reset();
		}

		Plane{ {8, 0, 9}, 12 }.draw(Quaternion::RotateY(30_deg), HSV{ 250, 0.5, 0.9 });

		for (auto x : Range(-20, 20))
		{
			Line3D{ {x,4,-20},{x,4,20} }.draw(ColorF{ 1.0, 0.0, 0.0 });
		}

		Plane{ {-12, 0, 6}, 12 }.draw(Quaternion::RotateY(50_deg), HSV{ 170, 0.5, 0.9 });
		Plane{ {7, 0, -7}, 12 }.draw(Quaternion::RotateY(10_deg), HSV{ 30, 0.5, 0.9 });
		floorPlane.draw(dtexture);

		for (auto x : Range(-20, 20))
		{
			Line3D{ {-20,4,x},{20,4,x} }.draw(ColorF{ 1.0, 0.0, 0.0 });
		}

		for (auto i : step(36))
		{
			const Vec3 pos = Cylindrical{ 3.5, (t + 20_deg + i * 10_deg), (3 + Math::Sin(i * 10_deg * 1 + t * 40_deg)) };
			Box{ pos, 0.25 }
				.draw(Quaternion::RotateX(i * 10_deg), HSV{ i * 10, 0.8, 1.0 });
		}

		Box{ {-8,1,0}, 2 }.draw(ColorF{ 0.25 });
		Box{ {8,1,0}, 2 }.draw(windmillTexture);
		Sphere{ {-2, (1 + Periodic::Jump0_1(2s) * 4), 8}, 1 }.draw(ColorF{ 0.5, 0.8, 0.4 });
		Sphere{ {0, (1 + Periodic::Jump0_1(2s, t + 0.3) * 4), 8}, 1 }.draw(ColorF{ 0.8, 0.4, 0.5, });
		Sphere{ {2, (1 + Periodic::Jump0_1(2s, t + 0.6) * 4), 8}, 1 }.draw(ColorF{ 0.4, 0.5, 0.8 });
		Disc{ {-2, (0.2 + Periodic::Jump0_1(2s) * 4), 5}, 1 }.draw(ColorF{ 0.5, 0.8, 0.4 });
		Cylinder{ {0, (1 + Periodic::Jump0_1(2s, t + 0.3) * 4), 5}, 1, 2 }.draw(ColorF{ 0.8, 0.4, 0.5, });
		Cylinder{ {2, (1 + Periodic::Jump0_1(2s, t + 0.6) * 4), 5}, 0.1, 2 }.draw(ColorF{ 0.4, 0.5, 0.8 });
		Sphere{ {0, 3, 0}, 3 }
			.draw(Quaternion::RotateY(t * -15_deg), earthTexture);

		emoji.draw(Cursor::Pos());
	}
}
Ryo SuzukiRyo Suzuki

Test7

  • ColorSpace: リニアスペース
  • RenderTarget: MSRenderTexture

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	Window::Resize(1280, 720);
	Window::SetStyle(WindowStyle::Sizable);

	const Texture windmillTexture{ U"example/windmill.png", TextureDesc::MippedSRGB };
	const Texture earthTexture{ U"example/texture/earth.jpg", TextureDesc::MippedSRGB };
	const Texture emoji{ U"🐈"_emoji };

	const Plane floorPlane{ { 0, 0.01, 0 }, 20 };
	Image image{ 1000, 1000, Palette::White };
	DynamicTexture dtexture{ image, TextureDesc::MippedSRGB };
	Optional<Vec2> previousPenPos;

	const Mesh mesh{ MeshData::Cylinder({0, 4, 0}, 3, 3) };

	const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
	Graphics3D::SetGlobalAmbientColor(ColorF{ 0.6 });
	Graphics3D::SetSunColor(ColorF{ 0.4 });

	while (System::Update())
	{
		const double t = Scene::Time();
		constexpr double verticlaFOV = 30_deg;
		const Vec3 eyePosition = Cylindrical{ 20, (t * 1_deg), (8 + Periodic::Sine0_1(40s) * 8) };
		constexpr Vec3 focusPosition{ 0, 0, 0 };
		const BasicCamera3D camera{ Graphics3D::GetRenderTargetSize(), verticlaFOV, eyePosition, focusPosition, Vec3::Up(), 0.1 };
		const Ray ray = camera.screenToRay(Cursor::PosF());
		{
			Graphics3D::SetCameraTransform(camera);
			renderTexture.clear(ColorF{ 0.8, 0.9, 1.0 }.removeSRGBCurve());
			const ScopedRenderTarget3D target{ renderTexture };

			if (const auto pos = ray.intersectsAt(floorPlane))
			{
				Sphere{ *pos, 0.2 }.draw(ColorF{ Palette::Orange }.removeSRGBCurve());
				const Vec2 penPos = pos->xz();

				if (MouseL.pressed())
				{
					const Vec2 from = (previousPenPos ? *previousPenPos : penPos);
					const Vec2 to = penPos;
					previousPenPos = penPos;
					Line{ (from * Vec2{ 50, -50 }), (to * Vec2{ 50, -50 }) }
						.movedBy(500, 500)
						.overwrite(image, 5, ColorF{ Palette::Orange }.removeSRGBCurve());
					dtexture.fill(image);
				}
				else
				{
					previousPenPos.reset();
				}
			}
			else
			{
				previousPenPos.reset();
			}

			Plane{ {8, 0, 9}, 12 }.draw(Quaternion::RotateY(30_deg), ColorF{ HSV{ 250, 0.5, 0.9 } }.removeSRGBCurve());

			for (auto x : Range(-20, 20))
			{
				Line3D{ {x,4,-20},{x,4,20} }.draw(ColorF{ 1.0, 0.0, 0.0 }.removeSRGBCurve());
			}

			Plane{ {-12, 0, 6}, 12 }.draw(Quaternion::RotateY(50_deg), ColorF{ HSV{ 170, 0.5, 0.9 } }.removeSRGBCurve());
			Plane{ {7, 0, -7}, 12 }.draw(Quaternion::RotateY(10_deg), ColorF{ HSV{ 30, 0.5, 0.9 } }.removeSRGBCurve());
			floorPlane.draw(dtexture);

			for (auto x : Range(-20, 20))
			{
				Line3D{ {-20,4,x},{20,4,x} }.draw(ColorF{ 1.0, 0.0, 0.0 }.removeSRGBCurve());
			}

			for (auto i : step(36))
			{
				const Vec3 pos = Cylindrical{ 3.5, (t + 20_deg + i * 10_deg), (3 + Math::Sin(i * 10_deg * 1 + t * 40_deg)) };
				Box{ pos, 0.25 }
				.draw(Quaternion::RotateX(i * 10_deg), ColorF{ HSV{ i * 10, 0.8, 1.0 } }.removeSRGBCurve());
			}

			Box{ {-8,1,0}, 2 }.draw(ColorF{ 0.25 });
			Box{ {8,1,0}, 2 }.draw(windmillTexture);
			Sphere{ {-2, (1 + Periodic::Jump0_1(2s) * 4), 8}, 1 }.draw(ColorF{ 0.5, 0.8, 0.4 }.removeSRGBCurve());
			Sphere{ {0, (1 + Periodic::Jump0_1(2s, t + 0.3) * 4), 8}, 1 }.draw(ColorF{ 0.8, 0.4, 0.5, }.removeSRGBCurve());
			Sphere{ {2, (1 + Periodic::Jump0_1(2s, t + 0.6) * 4), 8}, 1 }.draw(ColorF{ 0.4, 0.5, 0.8 }.removeSRGBCurve());
			Disc{ {-2, (0.2 + Periodic::Jump0_1(2s) * 4), 5}, 1 }.draw(ColorF{ 0.5, 0.8, 0.4 }.removeSRGBCurve());
			Cylinder{ {0, (1 + Periodic::Jump0_1(2s, t + 0.3) * 4), 5}, 1, 2 }.draw(ColorF{ 0.8, 0.4, 0.5, }.removeSRGBCurve());
			Cylinder{ {2, (1 + Periodic::Jump0_1(2s, t + 0.6) * 4), 5}, 0.1, 2 }.draw(ColorF{ 0.4, 0.5, 0.8 }.removeSRGBCurve());
			Sphere{ {0, 3, 0}, 3 }
				.draw(Quaternion::RotateY(t * -15_deg), earthTexture);
		}

		// RenderTexture を 2D シーンに描画
		{
			Graphics3D::Flush();
			renderTexture.resolve();
			Shader::LinearToScreen(renderTexture);
		}

		emoji.draw(Cursor::Pos());
	}
}
Ryo SuzukiRyo Suzuki

Test8

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	Window::Resize(900, 600);
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	Graphics3D::SetGlobalAmbientColor(ColorF{ 0.0 });
	Graphics3D::SetSunColor(ColorF{ 1.0 });

	const MSRenderTexture renderTexture8{ 300, 600, TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };
	const MSRenderTexture renderTexture16{ 300, 600, TextureFormat::R16G16B16A16_Float, HasDepth::Yes };
	DebugCamera3D camera{ Size{ 300, 600 }, 45_deg, Vec3{ -12, 3, -12 } };

	while (System::Update())
	{
		{
			const ScopedViewport3D viewPort{ Rect{ 0, 0, 300, 600 } };
			Graphics3D::SetCameraTransform(camera);
			Sphere{ {0, 3, 0}, 3 }.draw();
		}

		{
			renderTexture8.clear(ColorF{ 0.8, 0.9, 1.0 }.removeSRGBCurve());
			const ScopedRenderTarget3D rt{ renderTexture8 };
			Graphics3D::SetCameraTransform(camera);
			Sphere{ {0, 3, 0}, 3 }.draw();
		}

		{
			renderTexture16.clear(ColorF{ 0.8, 0.9, 1.0 }.removeSRGBCurve());
			const ScopedRenderTarget3D rt{ renderTexture16 };
			Graphics3D::SetCameraTransform(camera);
			Sphere{ {0, 3, 0}, 3 }.draw();
		}

		// RenderTexture を 2D シーンに描画
		{
			Graphics3D::Flush();
			renderTexture8.resolve();
			Shader::LinearToScreen(renderTexture8, Rect{ 300, 0, 300, 600 });

			renderTexture16.resolve();
			Shader::LinearToScreen(renderTexture16, Rect{ 600, 0, 300, 600 });
		}

		PutText(U"中央と右(リニアレンダリング)はライトのエッジがはっきりする", Scene::Center().movedBy(0, 80));
	}
}
Ryo SuzukiRyo Suzuki

Test9

# include <Siv3D.hpp> // OpenSiv3D v0.6

void Main()
{
	const Texture texture{ U"example/windmill.png", TextureDesc::Mipped };
	const Texture textureSRGB{ U"example/windmill.png", TextureDesc::MippedSRGB };
	RenderTexture renderTexture{ 400, 100, ColorF{0.8, 0.9, 1.0} };
	RenderTexture renderTextureSRGB{ 400, 100, ColorF{0.8, 0.9, 1.0}, TextureFormat::R8G8B8A8_Unorm_SRGB };
	RenderTexture renderTextureSRGB2{ 400, 100, ColorF{0.8, 0.9, 1.0}.removeSRGBCurve(), TextureFormat::R8G8B8A8_Unorm_SRGB };

	while (System::Update())
	{
		texture.draw(0, 0);
		textureSRGB.draw(400, 0);
		renderTexture.draw(0, 320);
		renderTextureSRGB.draw(400, 320);
		renderTextureSRGB2.draw(0, 425);
		Shader::LinearToScreen(renderTextureSRGB2, Vec2{ 400, 425 });
	}
}