fix(render): 修复白屏/黑屏——视图矩阵、UI着色器、网格构建性能与安装目录
- 相机视图矩阵按 R_cam^T·T(-pos) 正确推导(旧布局非正交,非零视角下场景塌缩为灰屏) - UI 片元着色器改为纹理×颜色(旧实现丢弃纹理 RGB,彩色纹理全白) - UI 纹理与图集 mipmap:图集补齐 2 次幂、UI 上传不生成 mipmap(NPOT 不完整纹理采样纯白) - 网格构建持一次读锁(旧实现每格邻居查询各加锁约 40 万次/区块,出生区块迟迟无网格, 玩家透过脚下的洞看到地下横截面——进游戏黑屏主因);脏区块按距离排序优先构建 - 开启背面剔除(CW 正面):区块边界面向未加载邻居的内侧面不再以暗色出现在视野里 - 出生逻辑:等区块加载后定位地表出生,相机略微俯视 - dev 截图测试:-shot 等待玩家所在 5×5 区块网格就绪再拍(48s 兜底),先测试后打包 - 安装器改为按用户安装到 LOCALAPPDATA(Program Files 无写权限导致启动即崩) - dev 截图工具独立成 devshot_gl.go
This commit is contained in:
@@ -32,7 +32,7 @@ const (
|
||||
|
||||
// World 世界实例。
|
||||
type World struct {
|
||||
mu sync.Mutex
|
||||
mu sync.RWMutex
|
||||
chunks map[uint64]*chunk.Chunk
|
||||
states map[uint64]chunkState
|
||||
|
||||
@@ -170,9 +170,31 @@ func (w *World) Block(x, y, z int32) block.State {
|
||||
if y < 0 || y >= chunk.Height {
|
||||
return block.Air
|
||||
}
|
||||
w.mu.Lock()
|
||||
w.mu.RLock()
|
||||
ch := w.chunks[coordKey(coord.ChunkCoord(x), coord.ChunkCoord(z))]
|
||||
w.mu.RUnlock()
|
||||
if ch == nil {
|
||||
return block.Air
|
||||
}
|
||||
return ch.Block(int(coord.LocalCoord(x)), int(y), int(coord.LocalCoord(z)))
|
||||
}
|
||||
|
||||
// WithReadLock 在持有世界读锁期间执行 fn。
|
||||
// 网格构建用它包住整个 Build:邻居查询走 BlockUnlocked,免去每格一次加锁
|
||||
// (旧实现每个面邻居查询各加一次锁,单区块约 40 万次加锁,mesh 构建极慢,
|
||||
// 出生区块迟迟无网格,玩家透过脚下的洞看到相邻区块地下横截面——"进游戏黑屏"主因之一)。
|
||||
func (w *World) WithReadLock(fn func()) {
|
||||
w.mu.RLock()
|
||||
defer w.mu.RUnlock()
|
||||
fn()
|
||||
}
|
||||
|
||||
// BlockUnlocked 无锁读方块(仅在 WithReadLock 回调内调用;未加载区块与世界边界视为空气)。
|
||||
func (w *World) BlockUnlocked(x, y, z int32) block.State {
|
||||
if y < 0 || y >= chunk.Height {
|
||||
return block.Air
|
||||
}
|
||||
ch := w.chunks[coordKey(coord.ChunkCoord(x), coord.ChunkCoord(z))]
|
||||
w.mu.Unlock()
|
||||
if ch == nil {
|
||||
return block.Air
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user