From 37244d7f690919566b0f917b06b18b6c26eaae75 Mon Sep 17 00:00:00 2001 From: Andrey Stepanov Date: Sat, 2 Nov 2024 21:24:01 +0500 Subject: [PATCH] transparency --- mapblockrenderer/renderer.go | 83 +++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/mapblockrenderer/renderer.go b/mapblockrenderer/renderer.go index cae4b72..2007348 100644 --- a/mapblockrenderer/renderer.go +++ b/mapblockrenderer/renderer.go @@ -73,6 +73,31 @@ func addColorComponent(c *color.RGBA, value int) *color.RGBA { } } +func clamp_ratio(ratio float32) float32 { + if ratio < 0 { + return 0 + } + + if ratio > 1 { + return 1 + } + + return ratio +} + +func interp_value(min uint8, max uint8, ratio float32) uint8 { + return min + uint8(float32(max-min)*clamp_ratio(ratio)) +} + +func blend_colors(lower color.RGBA, upper color.RGBA) (blended color.RGBA) { + ratio := float32(upper.A) / float32(255) + blended.R = interp_value(lower.R, upper.R, ratio) + blended.G = interp_value(lower.G, upper.G, ratio) + blended.B = interp_value(lower.B, upper.B, ratio) + blended.A = 255 + return +} + func (r *MapBlockRenderer) Render(pos1, pos2 *types.MapBlockCoords) (*image.NRGBA, error) { if pos1.X != pos2.X { return nil, errors.New("x does not line up") @@ -124,6 +149,8 @@ func (r *MapBlockRenderer) Render(pos1, pos2 *types.MapBlockCoords) (*image.NRGB for x := 0; x < 16; x++ { for z := 0; z < 16; z++ { + var colors_stack [15]color.RGBA + var visible_nodes_count uint8 = 0 for y := 15; y >= 0; y-- { if xzOccupationMap[x][z] { break @@ -142,9 +169,6 @@ func (r *MapBlockRenderer) Render(pos1, pos2 *types.MapBlockCoords) (*image.NRGB continue } - // clamp alpha channel to max - c.A = 255 - if r.enableShadow { var left, leftAbove, top, topAbove string @@ -209,35 +233,46 @@ func (r *MapBlockRenderer) Render(pos1, pos2 *types.MapBlockCoords) (*image.NRGB } } - imgX := x * IMG_SCALE - imgY := (15 - z) * IMG_SCALE + colors_stack[visible_nodes_count] = *c + visible_nodes_count++ - r32, g32, b32, a32 := c.RGBA() - r8, g8, b8, a8 := uint8(r32), uint8(g32), uint8(b32), uint8(a32) - for Y := imgY; Y < imgY+IMG_SCALE; Y++ { - ix := (Y*IMG_SIZE + imgX) << 2 - for X := 0; X < IMG_SCALE; X++ { - img.Pix[ix] = r8 - ix++ - img.Pix[ix] = g8 - ix++ - img.Pix[ix] = b8 - ix++ - img.Pix[ix] = a8 - ix++ - } - } - - if c.A != 0xFF || !r.enableTransparency { + if c.A == 0xFF || !r.enableTransparency { //not transparent, mark as rendered foundBlocks++ xzOccupationMap[x][z] = true } + } - if foundBlocks == EXPECTED_BLOCKS_PER_FLAT_MAPBLOCK { - return img, nil + visible_nodes_count-- + result_color := colors_stack[visible_nodes_count] + if visible_nodes_count > 0 { + for layer := visible_nodes_count; layer > 0; layer-- { + result_color = blend_colors(result_color, colors_stack[layer-1]) } } + + imgX := x * IMG_SCALE + imgY := (15 - z) * IMG_SCALE + + r32, g32, b32, a32 := result_color.RGBA() + r8, g8, b8, a8 := uint8(r32), uint8(g32), uint8(b32), uint8(a32) + for Y := imgY; Y < imgY+IMG_SCALE; Y++ { + ix := (Y*IMG_SIZE + imgX) << 2 + for X := 0; X < IMG_SCALE; X++ { + img.Pix[ix] = r8 + ix++ + img.Pix[ix] = g8 + ix++ + img.Pix[ix] = b8 + ix++ + img.Pix[ix] = a8 + ix++ + } + } + + if foundBlocks == EXPECTED_BLOCKS_PER_FLAT_MAPBLOCK { + return img, nil + } } } }