feat: LOD 网格分级——meshopt 解析期简化 + 按距离/级联选级
vendored meshoptimizer 1.2(submodule 环境故障改直接 vendor)。Mesh 多 LOD:各级索引连续拼进同一 index buffer(共享顶点,LodRange 区间 选择),解析期 meshopt_simplify 生成链(LOD0=原始,每级目标减半, 相对误差 1e-2,小网格复用上级);都在 worker 线程,加载零额外卡顿。 SceneRenderer 按 (mesh, LOD) 聚合 batch(lookup key = 指针<<8|lod): 主视图按屏占比近似 radius/dist 选级(阈值 10/20 倍半径);阴影级联 按级联序降级(越远越简)。Draw 按 batch.lod 选索引区间。 A/B 对比(100 背包 10×10,RTX 5060 Laptop,vsync off): - 纯背包:LOD 开 93-95 fps / 关 90-107 fps —— 无显著差异 - 加 SunTemple:LOD 开 52-56 / 关 51-55 —— 无显著差异 结论:当前场景瓶颈不在顶点数(5060 顶点吞吐富余),LOD 基础设施 保留(几何复杂资产/低端 GPU/更大场景生效),帧率问题转向 Tracy GPU 时间线定位真实瓶颈。 坑:LodRange 记录"LOD 不足复用最后一级"时 first 不得继续累加 (buffer 无重复数据,累加必越界——VUID-08798 抓的)。
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
MAKEFLAGS+=-r -j
|
||||
|
||||
config=debug
|
||||
files=demo/pirate.obj
|
||||
|
||||
BUILD=build/$(config)
|
||||
|
||||
LIBRARY_SOURCES=$(wildcard src/*.cpp)
|
||||
LIBRARY_OBJECTS=$(LIBRARY_SOURCES:%=$(BUILD)/%.o)
|
||||
|
||||
DEMO_SOURCES=$(wildcard demo/*.c demo/*.cpp) tools/objloader.cpp
|
||||
DEMO_OBJECTS=$(DEMO_SOURCES:%=$(BUILD)/%.o)
|
||||
|
||||
GLTFPACK_SOURCES=$(wildcard gltf/*.cpp)
|
||||
GLTFPACK_OBJECTS=$(GLTFPACK_SOURCES:%=$(BUILD)/%.o)
|
||||
|
||||
OBJECTS=$(LIBRARY_OBJECTS) $(DEMO_OBJECTS) $(GLTFPACK_OBJECTS)
|
||||
|
||||
LIBRARY=$(BUILD)/libmeshoptimizer.a
|
||||
DEMO=$(BUILD)/meshoptdemo
|
||||
|
||||
CFLAGS=-g -Wall -Wextra -std=c89
|
||||
CXXFLAGS=-g -Wall -Wextra -Wshadow -Wno-missing-field-initializers
|
||||
LDFLAGS=
|
||||
|
||||
$(LIBRARY_OBJECTS): CXXFLAGS+=-std=gnu++98
|
||||
$(DEMO_OBJECTS): CXXFLAGS+=-std=c++11
|
||||
$(GLTFPACK_OBJECTS): CXXFLAGS+=-std=c++11
|
||||
|
||||
ifdef BASISU
|
||||
$(GLTFPACK_OBJECTS): CXXFLAGS+=-DWITH_BASISU
|
||||
$(BUILD)/gltf/encodebasis.cpp.o: CXXFLAGS+=-I$(BASISU)
|
||||
gltfpack: LDFLAGS+=-lpthread $(BASISU)/libbasisu_encoder.a
|
||||
endif
|
||||
|
||||
WASI_SDK?=/opt/wasi-sdk
|
||||
WASMCC?=$(WASI_SDK)/bin/clang++
|
||||
WASIROOT?=$(WASI_SDK)/share/wasi-sysroot
|
||||
|
||||
WASM_FLAGS=--target=wasm32-wasi -Wno-deprecated --sysroot=$(WASIROOT) --no-wasm-opt
|
||||
WASM_FLAGS+=-Wall -Wextra
|
||||
WASM_FLAGS+=-O3 -DNDEBUG -DMESHOPTIMIZER_VERTEXCODEC_ZEROCOPY -nostartfiles -nostdlib -Wl,--no-entry -Wl,-s
|
||||
WASM_FLAGS+=-mcpu=mvp # make sure clang doesn't use post-MVP features like sign extension
|
||||
WASM_FLAGS+=-fno-slp-vectorize -fno-vectorize -fno-unroll-loops
|
||||
WASM_FLAGS+=-Wl,-z -Wl,stack-size=36864 -Wl,--initial-memory=65536
|
||||
WASM_EXPORT_PREFIX=-Wl,--export
|
||||
|
||||
WASM_DECODER_SOURCES=src/vertexcodec.cpp src/indexcodec.cpp src/vertexfilter.cpp tools/wasmstubs.cpp
|
||||
WASM_DECODER_EXPORTS=meshopt_decodeVertexBuffer meshopt_decodeIndexBuffer meshopt_decodeIndexSequence meshopt_decodeFilterOct meshopt_decodeFilterQuat meshopt_decodeFilterExp meshopt_decodeFilterColor sbrk __wasm_call_ctors
|
||||
|
||||
WASM_ENCODER_SOURCES=src/vertexcodec.cpp src/indexcodec.cpp src/vertexfilter.cpp src/vcacheoptimizer.cpp src/vfetchoptimizer.cpp src/spatialorder.cpp tools/wasmstubs.cpp
|
||||
WASM_ENCODER_EXPORTS=meshopt_encodeVertexBuffer meshopt_encodeVertexBufferBound meshopt_encodeVertexBufferLevel meshopt_encodeIndexBuffer meshopt_encodeIndexBufferBound meshopt_encodeIndexSequence meshopt_encodeIndexSequenceBound meshopt_encodeVertexVersion meshopt_encodeIndexVersion meshopt_encodeFilterOct meshopt_encodeFilterQuat meshopt_encodeFilterExp meshopt_encodeFilterColor meshopt_optimizeVertexCache meshopt_optimizeVertexCacheStrip meshopt_optimizeVertexFetchRemap meshopt_spatialSortRemap sbrk __wasm_call_ctors
|
||||
|
||||
WASM_SIMPLIFIER_SOURCES=src/simplifier.cpp src/remesher.cpp src/vfetchoptimizer.cpp src/indexgenerator.cpp tools/wasmstubs.cpp
|
||||
WASM_SIMPLIFIER_EXPORTS=meshopt_simplify meshopt_simplifyWithAttributes meshopt_simplifyWithUpdate meshopt_simplifyScale meshopt_simplifyPoints meshopt_simplifySloppy meshopt_simplifyPrune meshopt_remesh meshopt_optimizeVertexFetchRemap meshopt_generatePositionRemap sbrk __wasm_call_ctors
|
||||
|
||||
WASM_CLUSTERIZER_SOURCES=src/clusterizer.cpp src/meshletutils.cpp tools/wasmstubs.cpp
|
||||
WASM_CLUSTERIZER_EXPORTS=meshopt_buildMeshletsBound meshopt_buildMeshletsFlex meshopt_buildMeshletsSpatial meshopt_computeClusterBounds meshopt_computeMeshletBounds meshopt_computeSphereBounds meshopt_optimizeMeshlet sbrk __wasm_call_ctors
|
||||
|
||||
WASM_TANGENTS_SOURCES=src/tangentspace.cpp tools/wasmstubs.cpp
|
||||
WASM_TANGENTS_EXPORTS=meshopt_generateTangents meshopt_generateNormals sbrk __wasm_call_ctors
|
||||
|
||||
ifneq ($(werror),)
|
||||
CFLAGS+=-Werror
|
||||
CXXFLAGS+=-Werror
|
||||
endif
|
||||
|
||||
ifeq ($(config),iphone)
|
||||
IPHONESDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
|
||||
CFLAGS+=-arch armv7 -arch arm64 -isysroot $(IPHONESDK)
|
||||
CXXFLAGS+=-arch armv7 -arch arm64 -isysroot $(IPHONESDK) -stdlib=libc++
|
||||
LDFLAGS+=-arch armv7 -arch arm64 -isysroot $(IPHONESDK) -L $(IPHONESDK)/usr/lib -mios-version-min=7.0
|
||||
endif
|
||||
|
||||
ifeq ($(config),trace)
|
||||
CXXFLAGS+=-DTRACE=1
|
||||
endif
|
||||
|
||||
ifeq ($(config),tracev)
|
||||
CXXFLAGS+=-DTRACE=2
|
||||
endif
|
||||
|
||||
ifeq ($(config),release)
|
||||
CXXFLAGS+=-O3 -DNDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(config),coverage)
|
||||
CXXFLAGS+=-coverage
|
||||
LDFLAGS+=-coverage
|
||||
endif
|
||||
|
||||
ifeq ($(config),release-avx)
|
||||
CXXFLAGS+=-O3 -DNDEBUG -mavx
|
||||
endif
|
||||
|
||||
ifeq ($(config),release-avx512)
|
||||
CXXFLAGS+=-O3 -DNDEBUG -mavx512vl -mavx512vbmi -mavx512vbmi2 -mbmi2
|
||||
endif
|
||||
|
||||
ifeq ($(config),release-scalar)
|
||||
CXXFLAGS+=-O3 -DNDEBUG -DMESHOPTIMIZER_NO_SIMD
|
||||
endif
|
||||
|
||||
ifeq ($(config),coverage-scalar)
|
||||
CXXFLAGS+=-coverage -DMESHOPTIMIZER_NO_SIMD
|
||||
LDFLAGS+=-coverage
|
||||
endif
|
||||
|
||||
ifeq ($(config),sanitize)
|
||||
CXXFLAGS+=-fsanitize=address,undefined -fsanitize-undefined-trap-on-error
|
||||
LDFLAGS+=-fsanitize=address,undefined
|
||||
endif
|
||||
|
||||
ifeq ($(config),analyze)
|
||||
CXXFLAGS+=--analyze
|
||||
endif
|
||||
|
||||
ifeq ($(config),fuzz)
|
||||
CXXFLAGS+=-O1 -fsanitize=address,fuzzer
|
||||
LDFLAGS+=-fsanitize=address,fuzzer
|
||||
|
||||
$(GLTFPACK_OBJECTS): CXXFLAGS+=-DGLTFFUZZ
|
||||
endif
|
||||
|
||||
-include Makefile.config
|
||||
|
||||
all: $(DEMO)
|
||||
|
||||
test: $(DEMO)
|
||||
$(DEMO) $(files)
|
||||
|
||||
check: $(DEMO)
|
||||
$(DEMO)
|
||||
|
||||
dev: $(DEMO)
|
||||
$(DEMO) -d $(files)
|
||||
|
||||
nanite: $(DEMO)
|
||||
$(DEMO) -n $(files)
|
||||
|
||||
format:
|
||||
clang-format -i src/*.h src/*.cpp demo/*.cpp gltf/*.h gltf/*.cpp
|
||||
|
||||
formatjs:
|
||||
prettier -w js/*.js gltf/*.js demo/*.html js/*.ts
|
||||
|
||||
js: js/meshopt_decoder.cjs js/meshopt_decoder.mjs js/meshopt_encoder.js js/meshopt_simplifier.js js/meshopt_clusterizer.js js/meshopt_tangents.js
|
||||
|
||||
symbols: $(BUILD)/amalgamated.so
|
||||
nm $< -U -g
|
||||
|
||||
gltfpack: $(BUILD)/gltfpack
|
||||
ln -fs $^ $@
|
||||
|
||||
ifeq ($(config),fuzz)
|
||||
gltffuzz: $(BUILD)/gltfpack
|
||||
cp $^ $@
|
||||
mkdir -p /tmp/gltffuzz
|
||||
cp gltf/fuzz.glb /tmp/gltffuzz/
|
||||
./gltffuzz /tmp/gltffuzz -fork=16 -dict=gltf/fuzz.dict -ignore_crashes=1 -max_len=32768
|
||||
endif
|
||||
|
||||
$(BUILD)/gltfpack: $(GLTFPACK_OBJECTS) $(LIBRARY)
|
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
gltfpack.wasm: gltf/library.wasm
|
||||
|
||||
gltf/library.wasm: $(LIBRARY_SOURCES) $(GLTFPACK_SOURCES)
|
||||
$(WASMCC) $^ -o $@ -Wall -Os -DNDEBUG --target=wasm32-wasi -Wno-deprecated --sysroot=$(WASIROOT) -nostartfiles --no-wasm-opt -Wl,--no-entry -Wl,--export=pack -Wl,--export=malloc -Wl,--export=free -Wl,--export=__wasm_call_ctors -Wl,-s -Wl,--allow-undefined-file=gltf/wasistubs.txt
|
||||
|
||||
build/decoder_base.wasm: $(WASM_DECODER_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_DECODER_EXPORTS)) -o $@
|
||||
|
||||
build/decoder_simd.wasm: $(WASM_DECODER_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_DECODER_EXPORTS)) -o $@ -msimd128 -mbulk-memory -DMESHOPTIMIZER_VERTEXFILTER_SIMDNOTAIL
|
||||
|
||||
build/encoder.wasm: $(WASM_ENCODER_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_ENCODER_EXPORTS)) -lc -o $@
|
||||
|
||||
build/simplifier.wasm: $(WASM_SIMPLIFIER_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_SIMPLIFIER_EXPORTS)) -lc -o $@
|
||||
|
||||
build/clusterizer.wasm: $(WASM_CLUSTERIZER_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_CLUSTERIZER_EXPORTS)) -lc -o $@
|
||||
|
||||
build/tangents.wasm: $(WASM_TANGENTS_SOURCES)
|
||||
@mkdir -p build
|
||||
$(WASMCC) $^ $(WASM_FLAGS) $(patsubst %,$(WASM_EXPORT_PREFIX)=%,$(WASM_TANGENTS_EXPORTS)) -lc -o $@
|
||||
|
||||
js/meshopt_decoder.mjs: build/decoder_base.wasm build/decoder_simd.wasm tools/wasmpack.py
|
||||
sed -i "s#Built with clang.*#Built with $$($(WASMCC) --version | head -n 1 | sed 's/\s\+(.*//')#" $@
|
||||
sed -i "s#Built from meshoptimizer .*#Built from meshoptimizer $$(cat src/meshoptimizer.h | grep -Po '(?<=version )[0-9.]+')#" $@
|
||||
python3 tools/wasmpack.py patch $@ base <build/decoder_base.wasm
|
||||
python3 tools/wasmpack.py patch $@ simd <build/decoder_simd.wasm
|
||||
|
||||
js/meshopt_encoder.js: build/encoder.wasm tools/wasmpack.py
|
||||
js/meshopt_simplifier.js: build/simplifier.wasm tools/wasmpack.py
|
||||
js/meshopt_clusterizer.js: build/clusterizer.wasm tools/wasmpack.py
|
||||
js/meshopt_tangents.js: build/tangents.wasm tools/wasmpack.py
|
||||
|
||||
js/meshopt_encoder.js js/meshopt_simplifier.js js/meshopt_clusterizer.js js/meshopt_tangents.js:
|
||||
sed -i "s#Built with clang.*#Built with $$($(WASMCC) --version | head -n 1 | sed 's/\s\+(.*//')#" $@
|
||||
sed -i "s#Built from meshoptimizer .*#Built from meshoptimizer $$(cat src/meshoptimizer.h | grep -Po '(?<=version )[0-9.]+')#" $@
|
||||
python3 tools/wasmpack.py patch $@ wasm <$<
|
||||
|
||||
js/meshopt_decoder.cjs: js/meshopt_decoder.mjs
|
||||
sed '/export {/d' <$< >$@
|
||||
echo "if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptDecoder;" >>$@
|
||||
echo "else if (typeof define === 'function' && define['amd']) define([], function () { return MeshoptDecoder; });" >>$@
|
||||
echo "else if (typeof exports === 'object') exports['MeshoptDecoder'] = MeshoptDecoder;" >>$@
|
||||
echo "else (typeof self !== 'undefined' ? self : this).MeshoptDecoder = MeshoptDecoder;" >>$@
|
||||
|
||||
$(DEMO): $(DEMO_OBJECTS) $(LIBRARY)
|
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
vcachetuner: tools/vcachetuner.cpp tools/objloader.cpp $(LIBRARY)
|
||||
$(CXX) $^ -fopenmp $(CXXFLAGS) -std=c++11 $(LDFLAGS) -o $@
|
||||
|
||||
codecbench: tools/codecbench.cpp $(LIBRARY)
|
||||
$(CXX) $^ $(CXXFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
codecbench.js: tools/codecbench.cpp $(LIBRARY_SOURCES)
|
||||
emcc $^ -O3 -g -DNDEBUG -s TOTAL_MEMORY=268435456 -s SINGLE_FILE=1 -o $@
|
||||
|
||||
codecbench-simd.js: tools/codecbench.cpp $(LIBRARY_SOURCES)
|
||||
emcc $^ -O3 -g -DNDEBUG -s TOTAL_MEMORY=268435456 -s SINGLE_FILE=1 -msimd128 -o $@
|
||||
|
||||
codecbench.wasm: tools/codecbench.cpp $(LIBRARY_SOURCES)
|
||||
$(WASMCC) $^ -fno-exceptions --target=wasm32-wasi --sysroot=$(WASIROOT) -lc++ -lc++abi -O3 -g -DNDEBUG -o $@
|
||||
|
||||
codecbench-simd.wasm: tools/codecbench.cpp $(LIBRARY_SOURCES)
|
||||
$(WASMCC) $^ -fno-exceptions --target=wasm32-wasi --sysroot=$(WASIROOT) -lc++ -lc++abi -O3 -g -DNDEBUG -msimd128 -o $@
|
||||
|
||||
codectest: tools/codectest.cpp $(LIBRARY)
|
||||
$(CXX) $^ $(CXXFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
codecfuzz: tools/codecfuzz.cpp src/vertexcodec.cpp src/indexcodec.cpp src/meshletcodec.cpp
|
||||
$(CXX) $^ -fsanitize=fuzzer,address,undefined -O1 -g -o $@
|
||||
|
||||
clusterfuzz: tools/clusterfuzz.cpp src/clusterizer.cpp src/partition.cpp
|
||||
$(CXX) $^ -fsanitize=fuzzer,address,undefined -O1 -g -o $@
|
||||
|
||||
simplifyfuzz: tools/simplifyfuzz.cpp src/simplifier.cpp
|
||||
$(CXX) $^ -fsanitize=fuzzer,address,undefined -O1 -g -o $@
|
||||
|
||||
$(LIBRARY): $(LIBRARY_OBJECTS)
|
||||
ar rcs $@ $^
|
||||
|
||||
$(BUILD)/amalgamated.so: $(LIBRARY_SOURCES)
|
||||
@mkdir -p $(dir $@)
|
||||
cat $^ | $(CXX) $(CXXFLAGS) -x c++ - -I src/ -o $@ -shared -fPIC
|
||||
|
||||
$(BUILD)/%.cpp.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $< $(CXXFLAGS) -c -MMD -MP -o $@
|
||||
|
||||
$(BUILD)/%.c.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $< $(CFLAGS) -c -MMD -MP -o $@
|
||||
|
||||
-include $(OBJECTS:.o=.d)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
|
||||
.PHONY: all clean format js
|
||||
Reference in New Issue
Block a user