curioustorvald/Terrarum

Try this for light calcuation?

curioustorvald opened this issue · 4 comments

* * *
* @ *
* * *

main:
	for all blocks in visible_world call calc_main.

subroutine calc_main(@):
	check all nearby: -- might improve performance over air tiles?
		if (their wall) == non-solid && (their air) == non-solid then skip calc_main.
	for all * call spread(@).

subroutine spread(L):
	recursively do:
		a b c
		d @ #
		f g h
		whereas:
			# is a previous cell of the recursion. (can be any of a..h)
			-- basically we skip over #
		break when {a>=K && b>=K && c>=K && d>=K && f>=K && g>=K && h>=K}.
			a>=b (whereas a and b are cvec4) is true iff a.r>=b.r && a.g>=b.g && a.b>=b.b && a.a>=b.a.
		write to {a,b,c,d,f,g,h} with value K whereas:
			let K be (source_light - attenuation).
			attenuation is a value set onto the block.

Regarding the operator >=: if a>b and b-a is smaller than 2/256 in RGB, then a==b.
To put it simply, break the recursion when the difference is tiny.

Another idea: convert RGBA into YOU-A, where the conversion matrix is:

       [ 3  4  1] [R]   [Y]
.125 * [-2 -2  4] [G] = [O]
       [ 4 -3 -1] [B]   [U]

and subsample O and U in the ratio of 4:2:0. You can also subsample Y in the ratio of 4:2:2 and offset to X position by 1. For the A-channel, it can use either of the methods.

When calculating, subsampled O and U channels will have smaller number of tiles to update. However, custom codes need to be written to handle subsampled channels.

The conversion matrix: use YCoCg-R instead. Wikipedia has optimized implementation that cuts number of computations from 9 to 4.

The new light simulator has been deployed (see branch 'NEWLIGHT2'), closing the issue.