Ver Fonte

Adds example 49-hextile (#2922)

* First commit - tested with dx11 on windows

* Minor changes & adding some comments.

* Update hextile.cpp

* update some bin files

* rename texture

* minor comment update

* Added support to configure tile rate as well as tile rotation strength, update bin files & screenshot

* use texture from polyhaven, updated screenshot, updated bin files & minor changes to shader.

* missed pushing texture

* update license

* Update hextile.cpp

* Fix regular tiling

* use ktx with mipmaps

* minor change to ensure that regular tiling & hextile matches with default tile rate.

* minor c

Co-authored-by: Бранимир Караџић <[email protected]>
blackhole há 3 anos atrás
pai
commit
a8a10b0b89

+ 15 - 0
docs/examples.rst

@@ -689,3 +689,18 @@ Reference(s):
 
 .. figure:: https://github.com/bkaradzic/bgfx/raw/master/examples/48-drawindirect/screenshot.png
    :alt: example-48-drawindirect
+   
+
+`49-hextile  <https://github.com/bkaradzic/bgfx/tree/master/examples/49-hextile>`__
+---------------------------------------------------------------------------------------------
+
+Realtime Hex-Tiling
+
+Simple example of how to use Hex-tiling in real time, ported from https://github.com/mmikk/hextile-demo
+
+Reference(s):
+ - `Hex-Tiling demo <https://github.com/mmikk/hextile-demo>`__.
+ - `Paper explaining concepts - <https://github.com/mmikk/mmikk.github.io/blob/master/papers3d/mm_hex_compressed.pdf>`__.
+
+.. figure:: https://github.com/bkaradzic/bgfx/raw/master/examples/49-hextile/screenshot.png
+   :alt: example-49-hextile

+ 5 - 0
docs/license.rst

@@ -126,3 +126,8 @@ Normal map texture (GFDL License)
 
  - `Julian Herzog <https://julianherzog.com/>`__
  - https://commons.wikimedia.org/wiki/File:Normal_map_example_with_scene_and_result.png
+
+Hextile example-49 texture (CC0 License)
+
+ - `Rob Tuytel`__
+ - https://polyhaven.com/a/aerial_rocks_04

+ 226 - 0
examples/49-hextile/fs_hextile.sc

@@ -0,0 +1,226 @@
+$input v_position, v_texcoord0
+
+/*
+ * Copyright 2022 Preetish Kakkar. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
+ */
+ 
+ /*
+
+	Most of the code is inspired/ported from https://github.com/mmikk/hextile-demo/blob/main/hextile-demo/shader_lighting.hlsl
+	
+	The basic idea behind the algorithm is to use tiling & blending schema but instead of regular linear blending, the algorithm uses blending operator that prevents visual artifacts caused by linear blending
+	
+	We partition the uv-space on a triangle grid and compute the local triangle and the barycentric coordinates inside the triangle. We use a hash function to associate a random offset with each vertex of the triangle
+	grid and use this random offset to fetch the example texture.
+	
+	Finally, we blend the result using the barycentric coordinates as blending weights.
+ 
+ */
+
+#include "../common/common.sh"
+
+#define M_PI 3.1415926535897932384626433832795
+
+SAMPLER2D(s_trx_d, 0);
+
+uniform vec4 u_params;
+
+#ifndef fmod
+#define fmod(x, y) (x - y * trunc(x / y))
+#endif
+
+#define moduleOper(a, b) a - (float(b) * floor(a/float(b)))
+
+#define u_showWeights u_params.x
+#define u_tileRate u_params.y
+#define u_tileRotStrength u_params.z
+#define u_useRegularTiling u_params.w
+
+vec3 Gain3(vec3 x, float r)
+{
+	// increase contrast when r>0.5 and
+	// reduce contrast if less
+	float k = log(1.0 - r) / log(0.5);
+
+	vec3 s = 2.0 * step(0.5, x);
+	vec3 m = 2.0 * (1.0 - s);
+
+	vec3 res = 0.5 * s + 0.25 * m * pow(max(vec3_splat(0.0), s + x * m), vec3_splat(k));
+
+	return res.xyz / (res.x + res.y + res.z);
+}
+
+mat2 LoadRot2x2(vec2 idx, float rotStrength)
+{
+	float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + M_PI;
+
+	// remap to +/-pi
+	//angle = fmod(angle, 2.0*M_PI); 
+	if (angle < 0.0) angle += 2.0 * M_PI;
+	if (angle > M_PI) angle -= 2.0 * M_PI;
+
+	angle *= rotStrength;
+
+	float cs = cos(angle);
+	float si = sin(angle);
+
+	return mat2(cs, -si, si, cs);
+}
+
+vec2 MakeCenST(vec2 Vertex)
+{
+	mat2 invSkewMat = mat2(1.0, 0.5, 0.0, 1.0 / 1.15470054);
+
+	return mul(invSkewMat, Vertex) / (2.0 * sqrt(3.0));
+}
+
+
+vec3 ProduceHexWeights(vec3 W, vec2 vertex1, vec2 vertex2, vec2 vertex3)
+{
+	vec3 res = vec3_splat(0.0);
+
+	float v1 = moduleOper(((vertex1.x - vertex1.y)), 3.0);
+	if (v1 < 0.0) v1 += 3.0;
+
+	float vh = v1 < 2.0 ? (v1 + 1.0) : 0.0;
+	float vl = v1 > 0.0 ? (v1 - 1.0) : 2.0;
+	float v2 = vertex1.x < vertex3.x ? vl : vh;
+	float v3 = vertex1.x < vertex3.x ? vh : vl;
+
+	res.x = v3 == 0.0 ? W.z : (v2 == 0.0 ? W.y : W.x);
+	res.y = v3 == 1.0 ? W.z : (v2 == 1.0 ? W.y : W.x);
+	res.z = v3 == 2.0 ? W.z : (v2 == 2.0 ? W.y : W.x);
+
+	return res;
+}
+
+vec2 hash(vec2 p)
+{
+	vec2 r = mul(mat2(127.1, 311.7, 269.5, 183.3), p);
+
+	return fract(sin(r) * 43758.5453);
+}
+
+// Given a point in UV, compute local triangle barycentric coordinates and vertex IDs
+void TriangleGrid(out float w1, out float w2, out float w3,
+	out vec2 vertex1, out vec2 vertex2, out vec2 vertex3,
+	vec2 uv)
+{
+	// Scaling of the input
+	uv *= 2.0 * sqrt(3.0); // controls the size of the input with respect to the size of the tiles. 
+
+	// Skew input space into simplex triangle grid
+	const mat2 gridToSkewedGrid =
+		mat2(1.0, -0.57735027, 0.0, 1.15470054);
+	vec2 skewedCoord = mul(gridToSkewedGrid, uv);
+
+	vec2 baseId = floor(skewedCoord);
+	vec3 temp = vec3(fract(skewedCoord), 0.0);
+	temp.z = 1.0 - temp.x - temp.y;
+
+	float s = step(0.0, -temp.z);
+	float s2 = 2.0 * s - 1.0;
+
+	w1 = -temp.z * s2;
+	w2 = s - temp.y * s2;
+	w3 = s - temp.x * s2;
+
+	vertex1 = baseId + vec2(s, s);
+	vertex2 = baseId + vec2(s, 1.0 - s);
+	vertex3 = baseId + vec2(1.0 - s, s);
+}
+
+void hex2colTex(out vec4 color, out vec3 weights, vec2 uv,
+	float rotStrength, float r)
+{
+	// compute uv derivatives
+	vec2 dSTdx = dFdx(uv), dSTdy = dFdy(uv);
+
+	// Get triangle info
+	float w1, w2, w3;
+	vec2 vertex1, vertex2, vertex3;
+	TriangleGrid(w1, w2, w3, vertex1, vertex2, vertex3, uv);
+
+	mat2 rot1 = LoadRot2x2(vertex1, rotStrength);
+	mat2 rot2 = LoadRot2x2(vertex2, rotStrength);
+	mat2 rot3 = LoadRot2x2(vertex3, rotStrength);
+
+	vec2 cen1 = MakeCenST(vertex1);
+	vec2 cen2 = MakeCenST(vertex2);
+	vec2 cen3 = MakeCenST(vertex3);
+
+	// assign random offset to each triangle vertex
+	// this is used later to fetch from texture
+	vec2 uv1 = mul(uv - cen1, rot1) + cen1 + hash(vertex1);
+	vec2 uv2 = mul(uv - cen2, rot2) + cen2 + hash(vertex2);
+	vec2 uv3 = mul(uv - cen3, rot3) + cen3 + hash(vertex3);
+
+	// Fetch input
+	// We could simply use texture2D function, however, the sreen space derivatives could be broken 
+	// since we are using random offsets, we use texture2DGrad to make sure that we pass correct derivatives explicitly.
+	vec4 c1 = texture2DGrad(s_trx_d, uv1,
+		mul(dSTdx, rot1), mul(dSTdy, rot1));
+	vec4 c2 = texture2DGrad(s_trx_d, uv2,
+		mul(dSTdx, rot2), mul(dSTdy, rot2));
+	vec4 c3 = texture2DGrad(s_trx_d, uv3,
+		mul(dSTdx, rot3), mul(dSTdy, rot3));
+
+	// use luminance as weight
+	vec3 Lw = vec3(0.299, 0.587, 0.114);
+	vec3 Dw = vec3(dot(c1.xyz, Lw), dot(c2.xyz, Lw), dot(c3.xyz, Lw));
+
+	Dw = mix(vec3_splat(1.0), Dw, 0.6); // 0.6 is fall off constant
+	vec3 W = Dw * pow(vec3(w1, w2, w3), vec3_splat(7.0));	// 7 is g_exp
+	W /= (W.x + W.y + W.z);
+	if (r != 0.5) W = Gain3(W, r);
+
+	// blend weights with color linearly 
+	// histogram preserving blending will be better but requires precompution step to create histogram texture
+	color = W.x * c1 + W.y * c2 + W.z * c3;
+	weights = ProduceHexWeights(W.xyz, vertex1, vertex2, vertex3);
+}
+
+
+float GetTileRate()
+{
+	return 0.05 * u_tileRate;
+}
+
+void FetchColorAndWeight(out vec3 color, out vec3 weights, vec2 uv)
+{
+	vec4 col4;
+	hex2colTex(col4, weights, uv, u_tileRotStrength, 0.7);
+	color = col4.xyz;
+}
+
+void main()
+{
+	if(u_useRegularTiling > 0.0) 
+	{
+		gl_FragColor = vec4(texture2D(s_trx_d, v_texcoord0.xy));
+	} 
+	else 
+	{
+		// actual world space position
+		vec3 surfPosInWorld = v_position.xyz;
+
+		vec3 sp = GetTileRate() * surfPosInWorld;
+
+		vec2 uv0 = vec2(sp.x, sp.z);
+
+		vec3 color, weights;
+		FetchColorAndWeight(color, weights, uv0);
+		
+		if (u_showWeights > 0.0)
+		{
+			gl_FragColor = vec4(weights, 1.0);
+		}
+		else
+		{
+			gl_FragColor = vec4(color, 1.0);
+		}
+	}
+
+	
+}

+ 327 - 0
examples/49-hextile/hextile.cpp

@@ -0,0 +1,327 @@
+/*
+ * Copyright 2022-2022 Preetish Kakkar. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
+ */
+
+#include <bx/allocator.h>
+#include <bx/debug.h>
+#include <bx/math.h>
+#include "common.h"
+#include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
+	struct PosTextCoord0Vertex
+	{
+		float m_x;
+		float m_y;
+		float m_z;
+		float m_u;
+		float m_v;
+
+		static void init()
+		{
+			ms_layout
+				.begin()
+				.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
+				.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+				.end();
+		}
+
+		static bgfx::VertexLayout ms_layout;
+	};
+
+	bgfx::VertexLayout PosTextCoord0Vertex::ms_layout;
+
+
+	static PosTextCoord0Vertex s_screenSpaceQuadVertices[] =
+	{
+		{-1.0f, 0.0f, -1.0f, 0.0, 0.0 },
+		{-1.0f, 0.0f,  1.0f, 0.0, 1.0 },
+		{ 1.0f, 0.0f, -1.0f, 1.0, 0.0 },
+		{ 1.0f, 0.0f,  1.0f, 1.0, 1.0 },
+	};
+
+	static const uint16_t s_screenSpaceQuadIndices[] =
+	{
+		2, 3, 1,
+		0, 2, 1,
+	};
+
+
+	struct HextileData
+	{
+		bool    m_showWeights = false;
+		int		m_tileRate = 10;
+		float	m_tileRotationStrength = 0.0f;
+		bool	m_useRegularTiling = false;
+		bool	m_pauseAnimation;
+	};
+
+	class ExampleHextile : public entry::AppI
+	{
+	public:
+		ExampleHextile(const char* _name, const char* _description, const char* _url)
+			: entry::AppI(_name, _description, _url)
+			, m_width(0)
+			, m_height(0)
+			, m_debug(BGFX_DEBUG_NONE)
+			, m_reset()
+		{
+		}
+
+		void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
+		{
+			Args args(_argc, _argv);
+
+			m_width = _width;
+			m_height = _height;
+			m_debug = BGFX_DEBUG_NONE;
+			m_reset = BGFX_RESET_VSYNC;
+
+			bgfx::Init init;
+			init.type = args.m_type;
+			init.vendorId = args.m_pciId;
+			init.platformData.nwh = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+			init.platformData.ndt = entry::getNativeDisplayHandle();
+			init.resolution.width = m_width;
+			init.resolution.height = m_height;
+			init.resolution.reset = m_reset;
+			bgfx::init(init);
+
+			// Enable m_debug text.
+			bgfx::setDebug(m_debug);
+
+			// Set view 0 clear state.
+			bgfx::setViewClear(0
+				, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+				, 0x303030ff
+				, 1.0f
+				, 0
+			);
+
+			m_hexTileData.m_showWeights = false;
+			m_hexTileData.m_pauseAnimation = false;
+
+			// Create vertex stream declaration.
+			PosTextCoord0Vertex::init();
+
+			// Create static vertex buffer.
+			m_vbh = bgfx::createVertexBuffer(
+				// Static data can be passed with bgfx::makeRef
+				bgfx::makeRef(s_screenSpaceQuadVertices, sizeof(s_screenSpaceQuadVertices))
+				, PosTextCoord0Vertex::ms_layout
+			);
+
+			// Create static index buffer
+			m_ibh = bgfx::createIndexBuffer(
+				// Static data can be passed with bgfx::makeRef
+				bgfx::makeRef(s_screenSpaceQuadIndices, sizeof(s_screenSpaceQuadIndices))
+			);
+
+			// Create program from shaders.
+			m_hextileProgram = loadProgram("vs_hextile", "fs_hextile");
+
+			// load texture to hextile
+			m_tileTexture = loadTexture("textures/aerial_rocks_04_diff_2k.ktx");
+
+			// Imgui.
+			imguiCreate();
+
+			m_timeOffset = bx::getHPCounter();
+
+			s_tileSampler = bgfx::createUniform("s_trx_d", bgfx::UniformType::Sampler);
+
+			u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 3);
+		}
+
+		virtual int shutdown() override
+		{
+			// Cleanup.
+			imguiDestroy();
+
+			if (bgfx::isValid(m_ibh))
+			{
+				bgfx::destroy(m_ibh);
+			}
+
+			if (bgfx::isValid(m_vbh))
+			{
+				bgfx::destroy(m_vbh);
+			}
+
+			if (bgfx::isValid(m_tileTexture))
+			{
+				bgfx::destroy(m_tileTexture);
+			}
+
+			if (bgfx::isValid(s_tileSampler))
+			{
+				bgfx::destroy(s_tileSampler);
+			}
+
+			if (bgfx::isValid(u_params))
+			{
+				bgfx::destroy(u_params);
+			}
+
+			bgfx::destroy(m_hextileProgram);
+
+			/// When data is passed to bgfx via makeRef we need to make
+			/// sure library is done with it before freeing memory blocks.
+			bgfx::frame();
+
+
+			// Shutdown bgfx.
+			bgfx::shutdown();
+
+			return 0;
+		}
+
+		bool update() override
+		{
+			if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
+			{
+				int64_t now = bx::getHPCounter();
+				static int64_t last = now;
+				const int64_t frameTime = now - last;
+				last = now;
+				const double freq = double(bx::getHPFrequency());
+				const float deltaTime = float(frameTime / freq);
+
+				imguiBeginFrame(m_mouseState.m_mx
+					, m_mouseState.m_my
+					, (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
+					| (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
+					| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
+					, m_mouseState.m_mz
+					, uint16_t(m_width)
+					, uint16_t(m_height)
+				);
+
+				showExampleDialog(this);
+
+				ImGui::SetNextWindowPos(
+					ImVec2(m_width - m_width / 4.5f - 5.0f, 10.0f)
+					, ImGuiCond_FirstUseEver
+				);
+				ImGui::SetNextWindowSize(
+					ImVec2(m_width / 4.5f, m_height / 4.0f)
+					, ImGuiCond_FirstUseEver
+				);
+				ImGui::Begin("Settings"
+					, NULL
+					, 0
+				);
+
+				ImGui::Separator();
+
+				ImGui::Checkbox("Use Regular Tiling", &m_hexTileData.m_useRegularTiling);
+				ImGui::Checkbox("Show Weights", &m_hexTileData.m_showWeights);
+				ImGui::Checkbox("Pause Animation", &m_hexTileData.m_pauseAnimation);
+
+				ImGui::SliderInt("Tile Rate", &m_hexTileData.m_tileRate, 2, 25);
+
+				ImGui::SliderFloat("Tile Rotation", &m_hexTileData.m_tileRotationStrength, 0.0f, 20.0f);
+
+				ImGui::Separator();
+
+				ImGui::End();
+				imguiEndFrame();
+
+				// This dummy draw call is here to make sure that view 0 is cleared
+				// if no other draw calls are submitted to view 0.
+				bgfx::touch(0);
+
+				const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
+
+				if (!m_hexTileData.m_pauseAnimation)
+				{
+					m_eye.z = bx::abs(m_eye.z) + (deltaTime / 4.0f);
+
+					if (m_eye.z < 10.0f)
+					{
+						m_eye.z *= -1;
+					}
+					else
+					{
+						m_eye.z = -0.01f;
+					}
+				}
+
+				float viewMtx[16];
+				bx::mtxLookAt(viewMtx, m_eye, at);
+
+				float projMtx[16];
+				bx::mtxProj(projMtx, 30.0f, float(m_width) / float(m_height), 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth);
+
+				bgfx::setViewTransform(0, viewMtx, projMtx);
+
+				// Set view 0 default viewport.
+				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
+
+				float modelTransform[16];
+				bx::mtxSRT(modelTransform, 30.0f, 30.0f, 30.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+				bgfx::setTransform(modelTransform);
+
+				bgfx::setVertexBuffer(0, m_vbh);
+				bgfx::setIndexBuffer(m_ibh);
+
+				bgfx::setTexture(0, s_tileSampler, m_tileTexture);
+
+				const float data[4] = { float(m_hexTileData.m_showWeights), float(m_hexTileData.m_tileRate),
+										float(m_hexTileData.m_tileRotationStrength), float(m_hexTileData.m_useRegularTiling) };
+				bgfx::setUniform(u_params, data);
+
+				bgfx::setState(0
+					| BGFX_STATE_WRITE_RGB
+					| BGFX_STATE_WRITE_A
+					| BGFX_STATE_WRITE_Z
+					| BGFX_STATE_DEPTH_TEST_LESS
+					| BGFX_STATE_MSAA
+				);
+
+				bgfx::submit(0, m_hextileProgram);
+
+				// Advance to next frame. Rendering thread will be kicked to
+				// process submitted rendering primitives.
+				bgfx::frame();
+
+				return true;
+			}
+
+			return false;
+		}
+
+		bgfx::VertexBufferHandle m_vbh;
+		bgfx::IndexBufferHandle m_ibh;
+
+		bgfx::ProgramHandle m_hextileProgram;
+		bgfx::UniformHandle s_tileSampler;
+		bgfx::TextureHandle m_tileTexture;
+
+		uint32_t m_width;
+		uint32_t m_height;
+		uint32_t m_debug;
+		uint32_t m_reset;
+
+		HextileData m_hexTileData;
+
+		entry::MouseState m_mouseState;
+
+		bgfx::UniformHandle u_params;
+
+		int64_t m_timeOffset;
+
+		bx::Vec3 m_eye = { 0.0f, 2.0f, -0.01f };
+	};
+
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(
+	ExampleHextile
+	, "49-hextile"
+	, "Hextile example."
+	, "https://bkaradzic.github.io/bgfx/examples.html#hextile"
+);

+ 10 - 0
examples/49-hextile/makefile

@@ -0,0 +1,10 @@
+#
+# Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+# License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
+#
+
+BGFX_DIR=../..
+RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
+BUILD_DIR=../../.build
+
+include $(BGFX_DIR)/scripts/shader.mk

BIN
examples/49-hextile/screenshot.png


+ 13 - 0
examples/49-hextile/varying.def.sc

@@ -0,0 +1,13 @@
+vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
+vec3 v_position  : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
+vec3 v_view      : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
+vec3 v_normal    : NORMAL    = vec3(0.0, 0.0, 1.0);
+vec3 v_tangent   : TANGENT   = vec3(1.0, 0.0, 0.0);
+vec3 v_bitangent : BINORMAL  = vec3(0.0, 1.0, 0.0);
+vec4 v_color0    : COLOR     = vec4(1.0, 0.0, 0.0, 1.0);
+
+vec3 a_position  : POSITION;
+vec4 a_normal    : NORMAL;
+vec4 a_tangent   : TANGENT;
+vec2 a_texcoord0 : TEXCOORD0;
+vec4 a_color0    : COLOR0;

+ 18 - 0
examples/49-hextile/vs_hextile.sc

@@ -0,0 +1,18 @@
+$input a_position, a_texcoord0
+$output v_position, v_texcoord0
+
+/*
+ * Copyright 2015 Andrew Mac. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
+ */
+
+#include "../common/common.sh"
+
+void main()
+{
+	vec3 vp = mul(u_model[0], vec4(a_position.xyz, 1.0)).xyz;
+	v_position = vp;
+	v_texcoord0 = mul(u_model[0], vec4(a_texcoord0.xy, 1.0, 1.0)).xy;
+
+	gl_Position = mul(u_viewProj, vec4(vp.xyz, 1.0));
+}

BIN
examples/assets/textures/aerial_rocks_04_diff_2k.jpg


+ 20 - 18
examples/assets/textures/textures.ninja

@@ -1,18 +1,20 @@
-textures = $pwd/../../runtime/textures
-
-build $textures/texture_compression_bc1.ktx:  texturec_bc1  $pwd/texture-compression-test.png
-build $textures/texture_compression_bc2.ktx:  texturec_bc2  $pwd/texture-compression-test.png
-build $textures/texture_compression_bc3.ktx:  texturec_bc3  $pwd/texture-compression-test.png
-build $textures/texture_compression_bc7.ktx:  texturec_bc7  $pwd/texture-compression-test.png
-build $textures/texture_compression_etc1.ktx: texturec_etc1 $pwd/texture-compression-test.png
-build $textures/texture_compression_etc2.ktx: texturec_etc2 $pwd/texture-compression-test.png
-
-build $textures/parallax-d.ktx: texturec_diffuse  $pwd/parallax-d.png
-build $textures/parallax-n.ktx: texturec_normal   $pwd/parallax-n.png
-build $textures/parallax-h.ktx: texturec_height   $pwd/parallax-h.png
-build $textures/lightmap.ktx:   texturec_height   $pwd/../sky/lightmap.png
-build $textures/uffizi.ktx:     texturec_equirect $pwd/uffizi-large.exr
-
-build $textures/texture_compression_rgba8.dds: texturec_rgba8 $pwd/texture-compression-test.png
-build $textures/pf_alpha_test.dds:             texturec_rgba8 $pwd/texture-alpha-test.png
-build $textures/pf_uv_filtering_test.dds:      texturec_rgba8 $pwd/texture-uv-filtering-test.png
+textures = $pwd/../../runtime/textures
+
+build $textures/texture_compression_bc1.ktx:  texturec_bc1  $pwd/texture-compression-test.png
+build $textures/texture_compression_bc2.ktx:  texturec_bc2  $pwd/texture-compression-test.png
+build $textures/texture_compression_bc3.ktx:  texturec_bc3  $pwd/texture-compression-test.png
+build $textures/texture_compression_bc7.ktx:  texturec_bc7  $pwd/texture-compression-test.png
+build $textures/texture_compression_etc1.ktx: texturec_etc1 $pwd/texture-compression-test.png
+build $textures/texture_compression_etc2.ktx: texturec_etc2 $pwd/texture-compression-test.png
+
+build $textures/parallax-d.ktx: texturec_diffuse  $pwd/parallax-d.png
+build $textures/parallax-n.ktx: texturec_normal   $pwd/parallax-n.png
+build $textures/parallax-h.ktx: texturec_height   $pwd/parallax-h.png
+build $textures/lightmap.ktx:   texturec_height   $pwd/../sky/lightmap.png
+build $textures/uffizi.ktx:     texturec_equirect $pwd/uffizi-large.exr
+
+build $textures/texture_compression_rgba8.dds: texturec_rgba8 $pwd/texture-compression-test.png
+build $textures/pf_alpha_test.dds:             texturec_rgba8 $pwd/texture-alpha-test.png
+build $textures/pf_uv_filtering_test.dds:      texturec_rgba8 $pwd/texture-uv-filtering-test.png
+
+build $textures/aerial_rocks_04_diff_2k.ktx:   texturec_bc7 $pwd/aerial_rocks_04_diff_2k.jpg

+ 2 - 0
examples/makefile

@@ -52,6 +52,7 @@ all:
 	@make -s --no-print-directory build -C 46-fsr
 	@make -s --no-print-directory build -C 47-pixelformats
 	@make -s --no-print-directory build -C 48-drawindirect
+	@make -s --no-print-directory build -C 49-hextile
 
 rebuild:
 	@make -s --no-print-directory rebuild -C 01-cubes
@@ -102,6 +103,7 @@ rebuild:
 	@make -s --no-print-directory rebuild -C 46-fsr
 	@make -s --no-print-directory rebuild -C 47-pixelformats
 	@make -s --no-print-directory rebuild -C 48-drawindirect
+	@make -s --no-print-directory rebuild -C 49-hextile
 
 rebuild-embedded:
 	@make -s --no-print-directory rebuild -C 02-metaballs

BIN
examples/runtime/shaders/dx11/fs_hextile.bin


BIN
examples/runtime/shaders/dx11/vs_hextile.bin


BIN
examples/runtime/shaders/essl/fs_hextile.bin


BIN
examples/runtime/shaders/essl/vs_hextile.bin


BIN
examples/runtime/shaders/glsl/fs_hextile.bin


BIN
examples/runtime/shaders/glsl/vs_hextile.bin


BIN
examples/runtime/shaders/metal/fs_hextile.bin


BIN
examples/runtime/shaders/metal/vs_hextile.bin


BIN
examples/runtime/shaders/spirv/fs_hextile.bin


BIN
examples/runtime/shaders/spirv/vs_hextile.bin


BIN
examples/runtime/textures/aerial_rocks_04_diff_2k.ktx


+ 1 - 0
scripts/genie.lua

@@ -592,6 +592,7 @@ or _OPTIONS["with-combined-examples"] then
 		, "46-fsr"
 		, "47-pixelformats"
 		, "48-drawindirect"
+		, "49-hextile"		
 		)
 
 	-- 17-drawstress requires multithreading, does not compile for singlethreaded wasm