mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
Hosek skylight model translated from C to Kotlin
This commit is contained in:
@@ -9,9 +9,9 @@ import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.EMDASH
|
||||
import net.torvald.colourutil.CIEXYZUtil.toColorRaw
|
||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||
import net.torvald.colourutil.CIEYXY
|
||||
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
||||
import net.torvald.parametricsky.datasets.DatasetRGB
|
||||
import net.torvald.parametricsky.datasets.DatasetSpectral
|
||||
import net.torvald.terrarum.inUse
|
||||
import java.awt.Dimension
|
||||
import javax.swing.*
|
||||
@@ -50,7 +50,8 @@ class Application : Game() {
|
||||
private lateinit var testTex: Texture
|
||||
|
||||
var turbidity = 5.0
|
||||
//var thetaOfSun = 0.0
|
||||
var albedo = 0.0
|
||||
var elevation = 0.0
|
||||
|
||||
override fun getScreen(): Screen {
|
||||
return super.getScreen()
|
||||
@@ -63,7 +64,8 @@ class Application : Game() {
|
||||
override fun render() {
|
||||
Gdx.graphics.setTitle("Daylight Model $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
||||
|
||||
genTexLoop(turbidity)
|
||||
|
||||
genTexLoop(ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation))
|
||||
|
||||
|
||||
val tex = Texture(oneScreen)
|
||||
@@ -99,7 +101,7 @@ class Application : Game() {
|
||||
* Generated texture is as if you took the panorama picture of sky: up 70deg to horizon, east-south-west;
|
||||
* with sun not moving (sun is at exact south, sun's height is adjustable)
|
||||
*/
|
||||
private fun genTexLoop(T: Double) {
|
||||
private fun genTexLoop(state: ArHosekSkyModelState) {
|
||||
|
||||
fun normaliseY(y: Double): Float {
|
||||
var v = y.coerceAtLeast(0.0)
|
||||
@@ -109,62 +111,7 @@ class Application : Game() {
|
||||
return v.toFloat()
|
||||
}
|
||||
|
||||
val theta = Math.toRadians(45.0) // of observer
|
||||
|
||||
// loop DAY
|
||||
for (x in 0 until outTexWidth) { // theta_s (time of day)
|
||||
for (y in 0 until outTexHeight) { // gamma
|
||||
val theta_s = Math.toRadians(x * (90.0 / outTexWidth.toDouble()))
|
||||
val gamma = Math.toRadians((outTexHeight - y) * (90.0 / outTexHeight.toDouble())) // of observer
|
||||
|
||||
val Y_z = Model.getAbsoluteZenithLuminance(T, theta_s).coerceAtLeast(0.0) / 88.0
|
||||
val x_z = Model.getZenithChromaX(T, theta_s)
|
||||
val y_z = Model.getZenithChromaY(T, theta_s)
|
||||
|
||||
val Y_p = Y_z * Model.getFforLuma(theta, gamma, T) / Model.getFforLuma(0.0, theta_s, T)
|
||||
val Y_oc = Y_z * (1.0 + 2.0 * Math.cos(theta)) / 3.0
|
||||
val x_p = (x_z * Model.getFforChromaX(theta, gamma, T) / Model.getFforChromaX(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
||||
val y_p = (y_z * Model.getFforChromaY(theta, gamma, T) / Model.getFforChromaY(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
||||
|
||||
val normalisedY = normaliseY(Y_p)
|
||||
|
||||
//println("$Y_p -> $normalisedY, $x_p, $y_p")
|
||||
|
||||
val rgbColour = CIEYXY(normalisedY, x_p.toFloat(), y_p.toFloat()).toXYZ().toColorRaw()
|
||||
|
||||
oneScreen.setColor(rgbColour)
|
||||
oneScreen.drawPixel(x, y)
|
||||
}
|
||||
}
|
||||
// end loop DAY
|
||||
|
||||
// loop NIGHT
|
||||
for (x in outTexWidth until outTexWidth * 2) {
|
||||
for (y in 0 until outTexHeight) {
|
||||
val theta_s = Math.toRadians(90.0 - (x - outTexWidth) * (90.0 / outTexWidth.toDouble())) // 90 downTo 0
|
||||
val theta_sReal = Math.toRadians(120.0)
|
||||
val gamma = Math.toRadians((outTexHeight - y) * (90.0 / outTexHeight.toDouble())) // of observer
|
||||
|
||||
val Y_z = Model.getAbsoluteZenithLuminance(T, theta_sReal)
|
||||
val x_z = Model.getZenithChromaX(T, theta_s)
|
||||
val y_z = Model.getZenithChromaY(T, theta_s)
|
||||
|
||||
val Y_p = Y_z * Model.getFforLuma(theta, gamma, T) / Model.getFforLuma(0.0, theta_sReal, T)
|
||||
val Y_oc = Y_z * (1.0 + 2.0 * Math.cos(theta)) / 3.0
|
||||
val x_p = (x_z * Model.getFforChromaX(theta, gamma, T) / Model.getFforChromaX(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
||||
val y_p = (y_z * Model.getFforChromaY(theta, gamma, T) / Model.getFforChromaY(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
||||
|
||||
val normalisedY = normaliseY(Y_p)
|
||||
|
||||
//println("$Y_p -> $normalisedY, $x_p, $y_p")
|
||||
|
||||
val rgbColour = CIEYXY(normalisedY, x_p.toFloat(), y_p.toFloat()).toXYZ().toColorRaw()
|
||||
|
||||
oneScreen.setColor(rgbColour)
|
||||
oneScreen.drawPixel(x, y)
|
||||
}
|
||||
}
|
||||
// end loop NIGHT
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +177,9 @@ class Application : Game() {
|
||||
|
||||
oneScreen = Pixmap(outTexWidth * 2, outTexHeight, Pixmap.Format.RGBA8888)
|
||||
|
||||
DatasetSpectral
|
||||
DatasetCIEXYZ
|
||||
DatasetRGB
|
||||
|
||||
ApplicationController(this)
|
||||
}
|
||||
@@ -240,32 +190,27 @@ class Application : Game() {
|
||||
|
||||
val mainPanel = JPanel()
|
||||
|
||||
val turbidityControl = JSlider(2, 64, 5)
|
||||
//val theta_sControl = JSlider(0, 15, 0)
|
||||
|
||||
val turbidityValueDisp = JLabel()
|
||||
//val theta_sValueDisp = JLabel()
|
||||
|
||||
//val theta_sValue: Double
|
||||
// get() = theta_sControl.value * (90.0 / theta_sControl.maximum)
|
||||
val turbidityControl = JSpinner(SpinnerNumberModel(5, 1, 10, 1))
|
||||
val albedoControl = JSpinner(SpinnerNumberModel(0.3, 0.0, 1.0, 0.05))
|
||||
val elevationControl = JSpinner(SpinnerNumberModel(45, 0, 90, 5))
|
||||
|
||||
init {
|
||||
val turbidityPanel = JPanel()
|
||||
val theta_sPanel = JPanel()
|
||||
val albedoPanel = JPanel()
|
||||
val elevationPanel = JPanel()
|
||||
|
||||
turbidityPanel.add(JLabel("Turbidity"))
|
||||
turbidityPanel.add(turbidityControl)
|
||||
turbidityPanel.add(turbidityValueDisp)
|
||||
|
||||
turbidityValueDisp.text = turbidityControl.value.toString()
|
||||
//theta_sValueDisp.text = theta_sValue.toString()
|
||||
albedoPanel.add(JLabel("Albedo"))
|
||||
albedoPanel.add(albedoControl)
|
||||
|
||||
//theta_sPanel.add(JLabel("Theta_s"))
|
||||
//theta_sPanel.add(theta_sControl)
|
||||
//theta_sPanel.add(theta_sValueDisp)
|
||||
elevationPanel.add(JLabel("Elevation"))
|
||||
elevationPanel.add(elevationControl)
|
||||
|
||||
mainPanel.add(turbidityPanel)
|
||||
mainPanel.add(theta_sPanel)
|
||||
mainPanel.add(albedoPanel)
|
||||
mainPanel.add(elevationPanel)
|
||||
|
||||
this.isVisible = true
|
||||
this.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
|
||||
@@ -275,14 +220,16 @@ class Application : Game() {
|
||||
|
||||
|
||||
turbidityControl.addChangeListener {
|
||||
turbidityValueDisp.text = turbidityControl.value.toString()
|
||||
app.turbidity = turbidityControl.value.toDouble()
|
||||
app.turbidity = turbidityControl.value as Double
|
||||
}
|
||||
|
||||
//theta_sControl.addChangeListener {
|
||||
// theta_sValueDisp.text = theta_sValue.toString()
|
||||
// app.thetaOfSun = Math.toRadians(theta_sValue)
|
||||
//}
|
||||
albedoControl.addChangeListener {
|
||||
app.albedo = albedoControl.value as Double
|
||||
}
|
||||
|
||||
elevationControl.addChangeListener {
|
||||
app.elevation = Math.toRadians((elevationControl.value as Int).toDouble())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
1276
src/net/torvald/parametricsky/ArHosekSkyModel.kt
Normal file
1276
src/net/torvald/parametricsky/ArHosekSkyModel.kt
Normal file
File diff suppressed because it is too large
Load Diff
137
src/net/torvald/parametricsky/datasets/DatasetCIEXYZ.kt
Normal file
137
src/net/torvald/parametricsky/datasets/DatasetCIEXYZ.kt
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
This source is published under the following 3-clause BSD license.
|
||||
|
||||
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* None of the names of the contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
============================================================================ */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This file contains the coefficient data for the spectral version of the model.
|
||||
|
||||
*/
|
||||
|
||||
// Uses Sep 9 pattern / Aug 23 mean dataset
|
||||
|
||||
package net.torvald.parametricsky.datasets
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
object DatasetCIEXYZ {
|
||||
|
||||
val datasetXYZ1 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZ1.bin")
|
||||
val datasetXYZ2 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZ2.bin")
|
||||
val datasetXYZ3 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZ3.bin")
|
||||
|
||||
val datasetXYZRad1 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZRad1.bin")
|
||||
val datasetXYZRad2 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZRad2.bin")
|
||||
val datasetXYZRad3 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetXYZRad3.bin")
|
||||
|
||||
init {
|
||||
assertEquals(1080, datasetXYZ2.size, "Dataset size mismatch: expected 1080, got ${datasetXYZ2.size}")
|
||||
assertEquals(120, datasetXYZRad2.size, "Dataset size mismatch: expected 120, got ${datasetXYZRad2.size}")
|
||||
|
||||
assertEquals( -1.117001e+000, datasetXYZ1[0], "Dataset not parsed correctly - expected ${-1.117001e+000}, got ${datasetXYZ1[0]}")
|
||||
}
|
||||
|
||||
|
||||
val datasetsXYZ = arrayOf(
|
||||
datasetXYZ1,
|
||||
datasetXYZ2,
|
||||
datasetXYZ3
|
||||
)
|
||||
|
||||
val datasetsXYZRad = arrayOf(
|
||||
datasetXYZRad1,
|
||||
datasetXYZRad2,
|
||||
datasetXYZRad3
|
||||
)
|
||||
}
|
||||
24
src/net/torvald/parametricsky/datasets/DatasetOp.kt
Normal file
24
src/net/torvald/parametricsky/datasets/DatasetOp.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package net.torvald.parametricsky.datasets
|
||||
|
||||
import net.torvald.terrarum.serialise.toLittleLong
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
|
||||
object DatasetOp {
|
||||
|
||||
fun readDatasetFromFile(filepath: String): DoubleArray {
|
||||
val file = File(filepath)
|
||||
val entrysize = file.length().toInt() / 8
|
||||
val fis = FileInputStream(file)
|
||||
|
||||
val ret = DoubleArray(entrysize) {
|
||||
val inputbuf = ByteArray(8)
|
||||
fis.read(inputbuf)
|
||||
val rawnum = inputbuf.toLittleLong()
|
||||
Double.fromBits(rawnum)
|
||||
}
|
||||
|
||||
fis.close()
|
||||
return ret
|
||||
}
|
||||
}
|
||||
136
src/net/torvald/parametricsky/datasets/DatasetRGB.kt
Normal file
136
src/net/torvald/parametricsky/datasets/DatasetRGB.kt
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
This source is published under the following 3-clause BSD license.
|
||||
|
||||
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* None of the names of the contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
============================================================================ */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This file contains the coefficient data for the spectral version of the model.
|
||||
|
||||
*/
|
||||
|
||||
// uses Aug 23 dataset
|
||||
|
||||
package net.torvald.parametricsky.datasets
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
object DatasetRGB {
|
||||
|
||||
val datasetRGB1 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGB1.bin")
|
||||
val datasetRGB2 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGB2.bin")
|
||||
val datasetRGB3 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGB3.bin")
|
||||
|
||||
val datasetRGBRad1 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGBRad1.bin")
|
||||
val datasetRGBRad2 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGBRad2.bin")
|
||||
val datasetRGBRad3 = DatasetOp.readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRGBRad3.bin")
|
||||
|
||||
init {
|
||||
assertEquals(1080, datasetRGB2.size, "Dataset size mismatch: expected 1080, got ${datasetRGB2.size}")
|
||||
assertEquals(120, datasetRGBRad2.size, "Dataset size mismatch: expected 120, got ${datasetRGBRad2.size}")
|
||||
|
||||
assertEquals( -1.099459e+000, datasetRGB1[0], "Dataset not parsed correctly - expected ${-1.099459e+000}, got ${datasetRGB1[0]}")
|
||||
}
|
||||
|
||||
val datasetsRGB = arrayOf(
|
||||
datasetRGB1,
|
||||
datasetRGB2,
|
||||
datasetRGB3
|
||||
)
|
||||
|
||||
val datasetsRGBRad = arrayOf(
|
||||
datasetRGBRad1,
|
||||
datasetRGBRad2,
|
||||
datasetRGBRad3
|
||||
)
|
||||
}
|
||||
232
src/net/torvald/parametricsky/datasets/DatasetSpectral.kt
Normal file
232
src/net/torvald/parametricsky/datasets/DatasetSpectral.kt
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
This source is published under the following 3-clause BSD license.
|
||||
|
||||
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* None of the names of the contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
============================================================================ */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This file contains the coefficient data for the spectral version of the model.
|
||||
|
||||
*/
|
||||
|
||||
// uses Apr 26 dataset
|
||||
|
||||
package net.torvald.parametricsky.datasets
|
||||
|
||||
import net.torvald.parametricsky.datasets.DatasetOp.readDatasetFromFile
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
object DatasetSpectral {
|
||||
|
||||
val dataset320 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset320.bin")
|
||||
val dataset360 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset360.bin")
|
||||
val dataset400 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset400.bin")
|
||||
val dataset440 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset440.bin")
|
||||
val dataset480 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset480.bin")
|
||||
val dataset520 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset520.bin")
|
||||
val dataset560 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset560.bin")
|
||||
val dataset600 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset600.bin")
|
||||
val dataset640 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset640.bin")
|
||||
val dataset680 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset680.bin")
|
||||
val dataset720 = readDatasetFromFile("./work_files/skylight/hosek_model_source/dataset720.bin")
|
||||
|
||||
val datasetRad320 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad320.bin")
|
||||
val datasetRad360 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad360.bin")
|
||||
val datasetRad400 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad400.bin")
|
||||
val datasetRad440 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad440.bin")
|
||||
val datasetRad480 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad480.bin")
|
||||
val datasetRad520 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad520.bin")
|
||||
val datasetRad560 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad560.bin")
|
||||
val datasetRad600 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad600.bin")
|
||||
val datasetRad640 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad640.bin")
|
||||
val datasetRad680 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad680.bin")
|
||||
val datasetRad720 = readDatasetFromFile("./work_files/skylight/hosek_model_source/datasetRad720.bin")
|
||||
|
||||
val solarDataset320 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset320.bin")
|
||||
val solarDataset360 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset360.bin")
|
||||
val solarDataset400 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset400.bin")
|
||||
val solarDataset440 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset440.bin")
|
||||
val solarDataset480 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset480.bin")
|
||||
val solarDataset520 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset520.bin")
|
||||
val solarDataset560 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset560.bin")
|
||||
val solarDataset600 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset600.bin")
|
||||
val solarDataset640 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset640.bin")
|
||||
val solarDataset680 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset680.bin")
|
||||
val solarDataset720 = readDatasetFromFile("./work_files/skylight/hosek_model_source/solarDataset720.bin")
|
||||
|
||||
init {
|
||||
assertEquals(1080, dataset600.size, "Dataset size mismatch - expected 1080, got ${dataset600.size}")
|
||||
assertEquals(120, datasetRad600.size, "Dataset size mismatch - expected 120, got ${datasetRad600.size}")
|
||||
assertEquals(1800, solarDataset600.size, "Dataset size mismatch - expected 1800, got ${solarDataset600.size}")
|
||||
|
||||
assertEquals(-1.341049e+001, dataset320[0], "Dataset not parsed correctly - expected ${-1.341049e+001}, got ${dataset320[0]}")
|
||||
}
|
||||
|
||||
val datasets = arrayOf(
|
||||
dataset320,
|
||||
dataset360,
|
||||
dataset400,
|
||||
dataset440,
|
||||
dataset480,
|
||||
dataset520,
|
||||
dataset560,
|
||||
dataset600,
|
||||
dataset640,
|
||||
dataset680,
|
||||
dataset720
|
||||
)
|
||||
|
||||
val datasetsRad = arrayOf(
|
||||
datasetRad320,
|
||||
datasetRad360,
|
||||
datasetRad400,
|
||||
datasetRad440,
|
||||
datasetRad480,
|
||||
datasetRad520,
|
||||
datasetRad560,
|
||||
datasetRad600,
|
||||
datasetRad640,
|
||||
datasetRad680,
|
||||
datasetRad720
|
||||
)
|
||||
|
||||
val solarDatasets = arrayOf(
|
||||
solarDataset320,
|
||||
solarDataset360,
|
||||
solarDataset400,
|
||||
solarDataset440,
|
||||
solarDataset480,
|
||||
solarDataset520,
|
||||
solarDataset560,
|
||||
solarDataset600,
|
||||
solarDataset640,
|
||||
solarDataset680,
|
||||
solarDataset720
|
||||
)
|
||||
|
||||
val limbDarkeningDataset320 = doubleArrayOf(0.087657, 0.767174, 0.658123, -1.02953, 0.703297, -0.186735)
|
||||
|
||||
val limbDarkeningDataset360 = doubleArrayOf(0.122953, 1.01278, 0.238687, -1.12208, 1.17087, -0.424947)
|
||||
|
||||
val limbDarkeningDataset400 = doubleArrayOf(0.123511, 1.08444, -0.405598, 0.370629, -0.240567, 0.0674778)
|
||||
|
||||
val limbDarkeningDataset440 = doubleArrayOf(0.158489, 1.23346, -0.875754, 0.857812, -0.484919, 0.110895)
|
||||
|
||||
val limbDarkeningDataset480 = doubleArrayOf(0.198587, 1.30507, -1.25998, 1.49727, -1.04047, 0.299516)
|
||||
|
||||
val limbDarkeningDataset520 = doubleArrayOf(0.23695, 1.29927, -1.28034, 1.37760, -0.85054, 0.21706)
|
||||
|
||||
val limbDarkeningDataset560 = doubleArrayOf(0.26892, 1.34319, -1.58427, 1.91271, -1.31350, 0.37295)
|
||||
|
||||
val limbDarkeningDataset600 = doubleArrayOf(0.299804, 1.36718, -1.80884, 2.29294, -1.60595, 0.454874)
|
||||
|
||||
val limbDarkeningDataset640 = doubleArrayOf(0.33551, 1.30791, -1.79382, 2.44646, -1.89082, 0.594769)
|
||||
|
||||
val limbDarkeningDataset680 = doubleArrayOf(0.364007, 1.27316, -1.73824, 2.28535, -1.70203, 0.517758)
|
||||
|
||||
val limbDarkeningDataset720 = doubleArrayOf(0.389704, 1.2448, -1.69708, 2.14061, -1.51803, 0.440004)
|
||||
|
||||
val limbDarkeningDatasets = arrayOf(
|
||||
limbDarkeningDataset320,
|
||||
limbDarkeningDataset360,
|
||||
limbDarkeningDataset400,
|
||||
limbDarkeningDataset440,
|
||||
limbDarkeningDataset480,
|
||||
limbDarkeningDataset520,
|
||||
limbDarkeningDataset560,
|
||||
limbDarkeningDataset600,
|
||||
limbDarkeningDataset640,
|
||||
limbDarkeningDataset680,
|
||||
limbDarkeningDataset720
|
||||
)
|
||||
}
|
||||
BIN
work_files/skylight/HosekWilkie_SkylightModel_SIGGRAPH2012_Preprint_lowres.pdf
LFS
Normal file
BIN
work_files/skylight/HosekWilkie_SkylightModel_SIGGRAPH2012_Preprint_lowres.pdf
LFS
Normal file
Binary file not shown.
816
work_files/skylight/hosek_model_source/ArHosekSkyModel.c
Normal file
816
work_files/skylight/hosek_model_source/ArHosekSkyModel.c
Normal file
@@ -0,0 +1,816 @@
|
||||
/*
|
||||
This source is published under the following 3-clause BSD license.
|
||||
|
||||
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* None of the names of the contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
============================================================================ */
|
||||
|
||||
/*
|
||||
|
||||
All instructions on how to use this code are in the accompanying header file.
|
||||
|
||||
*/
|
||||
|
||||
#include "ArHosekSkyModel.h"
|
||||
#include "ArHosekSkyModelData_Spectral.h"
|
||||
#include "ArHosekSkyModelData_CIEXYZ.h"
|
||||
#include "ArHosekSkyModelData_RGB.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
// Some macro definitions that occur elsewhere in ART, and that have to be
|
||||
// replicated to make this a stand-alone module.
|
||||
|
||||
#ifndef NIL
|
||||
#define NIL 0
|
||||
#endif
|
||||
|
||||
#ifndef MATH_PI
|
||||
#define MATH_PI 3.141592653589793
|
||||
#endif
|
||||
|
||||
#ifndef MATH_DEG_TO_RAD
|
||||
#define MATH_DEG_TO_RAD ( MATH_PI / 180.0 )
|
||||
#endif
|
||||
|
||||
#ifndef MATH_RAD_TO_DEG
|
||||
#define MATH_RAD_TO_DEG ( 180.0 / MATH_PI )
|
||||
#endif
|
||||
|
||||
#ifndef DEGREES
|
||||
#define DEGREES * MATH_DEG_TO_RAD
|
||||
#endif
|
||||
|
||||
#ifndef TERRESTRIAL_SOLAR_RADIUS
|
||||
#define TERRESTRIAL_SOLAR_RADIUS ( ( 0.51 DEGREES ) / 2.0 )
|
||||
#endif
|
||||
|
||||
#ifndef ALLOC
|
||||
#define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct)))
|
||||
#endif
|
||||
|
||||
// internal definitions
|
||||
|
||||
typedef double *ArHosekSkyModel_Dataset;
|
||||
typedef double *ArHosekSkyModel_Radiance_Dataset;
|
||||
|
||||
// internal functions
|
||||
|
||||
void ArHosekSkyModel_CookConfiguration(
|
||||
ArHosekSkyModel_Dataset dataset,
|
||||
ArHosekSkyModelConfiguration config,
|
||||
double turbidity,
|
||||
double albedo,
|
||||
double solar_elevation
|
||||
)
|
||||
{
|
||||
double * elev_matrix;
|
||||
|
||||
int int_turbidity = (int)turbidity;
|
||||
double turbidity_rem = turbidity - (double)int_turbidity;
|
||||
|
||||
solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
|
||||
|
||||
// alb 0 low turb
|
||||
|
||||
elev_matrix = dataset + ( 9 * 6 * (int_turbidity-1) );
|
||||
|
||||
|
||||
for( unsigned int i = 0; i < 9; ++i )
|
||||
{
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
config[i] =
|
||||
(1.0-albedo) * (1.0 - turbidity_rem)
|
||||
* ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
|
||||
5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[i+45]);
|
||||
}
|
||||
|
||||
// alb 1 low turb
|
||||
elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity-1));
|
||||
for(unsigned int i = 0; i < 9; ++i)
|
||||
{
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
config[i] +=
|
||||
(albedo) * (1.0 - turbidity_rem)
|
||||
* ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
|
||||
5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[i+45]);
|
||||
}
|
||||
|
||||
if(int_turbidity == 10)
|
||||
return;
|
||||
|
||||
// alb 0 high turb
|
||||
elev_matrix = dataset + (9*6*(int_turbidity));
|
||||
for(unsigned int i = 0; i < 9; ++i)
|
||||
{
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
config[i] +=
|
||||
(1.0-albedo) * (turbidity_rem)
|
||||
* ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
|
||||
5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[i+45]);
|
||||
}
|
||||
|
||||
// alb 1 high turb
|
||||
elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity));
|
||||
for(unsigned int i = 0; i < 9; ++i)
|
||||
{
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
config[i] +=
|
||||
(albedo) * (turbidity_rem)
|
||||
* ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] +
|
||||
5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[i+45]);
|
||||
}
|
||||
}
|
||||
|
||||
double ArHosekSkyModel_CookRadianceConfiguration(
|
||||
ArHosekSkyModel_Radiance_Dataset dataset,
|
||||
double turbidity,
|
||||
double albedo,
|
||||
double solar_elevation
|
||||
)
|
||||
{
|
||||
double* elev_matrix;
|
||||
|
||||
int int_turbidity = (int)turbidity;
|
||||
double turbidity_rem = turbidity - (double)int_turbidity;
|
||||
double res;
|
||||
solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
|
||||
|
||||
// alb 0 low turb
|
||||
elev_matrix = dataset + (6*(int_turbidity-1));
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
res = (1.0-albedo) * (1.0 - turbidity_rem) *
|
||||
( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
|
||||
5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[5]);
|
||||
|
||||
// alb 1 low turb
|
||||
elev_matrix = dataset + (6*10 + 6*(int_turbidity-1));
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
res += (albedo) * (1.0 - turbidity_rem) *
|
||||
( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
|
||||
5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[5]);
|
||||
if(int_turbidity == 10)
|
||||
return res;
|
||||
|
||||
// alb 0 high turb
|
||||
elev_matrix = dataset + (6*(int_turbidity));
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
res += (1.0-albedo) * (turbidity_rem) *
|
||||
( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
|
||||
5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[5]);
|
||||
|
||||
// alb 1 high turb
|
||||
elev_matrix = dataset + (6*10 + 6*(int_turbidity));
|
||||
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
|
||||
res += (albedo) * (turbidity_rem) *
|
||||
( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] +
|
||||
5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] +
|
||||
10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] +
|
||||
10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] +
|
||||
5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] +
|
||||
pow(solar_elevation, 5.0) * elev_matrix[5]);
|
||||
return res;
|
||||
}
|
||||
|
||||
double ArHosekSkyModel_GetRadianceInternal(
|
||||
ArHosekSkyModelConfiguration configuration,
|
||||
double theta,
|
||||
double gamma
|
||||
)
|
||||
{
|
||||
const double expM = exp(configuration[4] * gamma);
|
||||
const double rayM = cos(gamma)*cos(gamma);
|
||||
const double mieM = (1.0 + cos(gamma)*cos(gamma)) / pow((1.0 + configuration[8]*configuration[8] - 2.0*configuration[8]*cos(gamma)), 1.5);
|
||||
const double zenith = sqrt(cos(theta));
|
||||
|
||||
return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) *
|
||||
(configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith);
|
||||
}
|
||||
|
||||
// spectral version
|
||||
|
||||
ArHosekSkyModelState * arhosekskymodelstate_alloc_init(
|
||||
const double solar_elevation,
|
||||
const double atmospheric_turbidity,
|
||||
const double ground_albedo
|
||||
)
|
||||
{
|
||||
ArHosekSkyModelState * state = ALLOC(ArHosekSkyModelState);
|
||||
|
||||
state->solar_radius = ( 0.51 DEGREES ) / 2.0;
|
||||
state->turbidity = atmospheric_turbidity;
|
||||
state->albedo = ground_albedo;
|
||||
state->elevation = solar_elevation;
|
||||
|
||||
for( unsigned int wl = 0; wl < 11; ++wl )
|
||||
{
|
||||
ArHosekSkyModel_CookConfiguration(
|
||||
datasets[wl],
|
||||
state->configs[wl],
|
||||
atmospheric_turbidity,
|
||||
ground_albedo,
|
||||
solar_elevation
|
||||
);
|
||||
|
||||
state->radiances[wl] =
|
||||
ArHosekSkyModel_CookRadianceConfiguration(
|
||||
datasetsRad[wl],
|
||||
atmospheric_turbidity,
|
||||
ground_albedo,
|
||||
solar_elevation
|
||||
);
|
||||
|
||||
state->emission_correction_factor_sun[wl] = 1.0;
|
||||
state->emission_correction_factor_sky[wl] = 1.0;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
// 'blackbody_scaling_factor'
|
||||
//
|
||||
// Fudge factor, computed in Mathematica, to scale the results of the
|
||||
// following function to match the solar radiance spectrum used in the
|
||||
// original simulation. The scaling is done so their integrals over the
|
||||
// range from 380.0 to 720.0 nanometers match for a blackbody temperature
|
||||
// of 5800 K.
|
||||
// Which leaves the original spectrum being less bright overall than the 5.8k
|
||||
// blackbody radiation curve if the ultra-violet part of the spectrum is
|
||||
// also considered. But the visible brightness should be very similar.
|
||||
|
||||
const double blackbody_scaling_factor = 3.19992 * 10E-11;
|
||||
|
||||
// 'art_blackbody_dd_value()' function
|
||||
//
|
||||
// Blackbody radiance, Planck's formula
|
||||
|
||||
double art_blackbody_dd_value(
|
||||
const double temperature,
|
||||
const double lambda
|
||||
)
|
||||
{
|
||||
double c1 = 3.74177 * 10E-17;
|
||||
double c2 = 0.0143878;
|
||||
double value;
|
||||
|
||||
value = ( c1 / ( pow( lambda, 5.0 ) ) )
|
||||
* ( 1.0 / ( exp( c2 / ( lambda * temperature ) ) - 1.0 ) );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// 'originalSolarRadianceTable[]'
|
||||
//
|
||||
// The solar spectrum incident at the top of the atmosphere, as it was used
|
||||
// in the brute force path tracer that generated the reference results the
|
||||
// model was fitted to. We need this as the yardstick to compare any altered
|
||||
// Blackbody emission spectra for alien world stars to.
|
||||
|
||||
// This is just the data from the Preetham paper, extended into the UV range.
|
||||
|
||||
const double originalSolarRadianceTable[] =
|
||||
{
|
||||
7500.0,
|
||||
12500.0,
|
||||
21127.5,
|
||||
26760.5,
|
||||
30663.7,
|
||||
27825.0,
|
||||
25503.8,
|
||||
25134.2,
|
||||
23212.1,
|
||||
21526.7,
|
||||
19870.8
|
||||
};
|
||||
|
||||
ArHosekSkyModelState * arhosekskymodelstate_alienworld_alloc_init(
|
||||
const double solar_elevation,
|
||||
const double solar_intensity,
|
||||
const double solar_surface_temperature_kelvin,
|
||||
const double atmospheric_turbidity,
|
||||
const double ground_albedo
|
||||
)
|
||||
{
|
||||
ArHosekSkyModelState * state = ALLOC(ArHosekSkyModelState);
|
||||
|
||||
state->turbidity = atmospheric_turbidity;
|
||||
state->albedo = ground_albedo;
|
||||
state->elevation = solar_elevation;
|
||||
|
||||
for( unsigned int wl = 0; wl < 11; ++wl )
|
||||
{
|
||||
// Basic init as for the normal scenario
|
||||
|
||||
ArHosekSkyModel_CookConfiguration(
|
||||
datasets[wl],
|
||||
state->configs[wl],
|
||||
atmospheric_turbidity,
|
||||
ground_albedo,
|
||||
solar_elevation
|
||||
);
|
||||
|
||||
state->radiances[wl] =
|
||||
ArHosekSkyModel_CookRadianceConfiguration(
|
||||
datasetsRad[wl],
|
||||
atmospheric_turbidity,
|
||||
ground_albedo,
|
||||
solar_elevation
|
||||
);
|
||||
|
||||
// The wavelength of this band in nanometers
|
||||
|
||||
double owl = ( 320.0 + 40.0 * wl ) * 10E-10;
|
||||
|
||||
// The original intensity we just computed
|
||||
|
||||
double osr = originalSolarRadianceTable[wl];
|
||||
|
||||
// The intensity of a blackbody with the desired temperature
|
||||
// The fudge factor described above is used to make sure the BB
|
||||
// function matches the used radiance data reasonably well
|
||||
// in magnitude.
|
||||
|
||||
double nsr =
|
||||
art_blackbody_dd_value(solar_surface_temperature_kelvin, owl)
|
||||
* blackbody_scaling_factor;
|
||||
|
||||
// Correction factor for this waveband is simply the ratio of
|
||||
// the two.
|
||||
|
||||
state->emission_correction_factor_sun[wl] = nsr / osr;
|
||||
}
|
||||
|
||||
// We then compute the average correction factor of all wavebands.
|
||||
|
||||
// Theoretically, some weighting to favour wavelengths human vision is
|
||||
// more sensitive to could be introduced here - think V(lambda). But
|
||||
// given that the whole effort is not *that* accurate to begin with (we
|
||||
// are talking about the appearance of alien worlds, after all), simple
|
||||
// averaging over the visible wavelenghts (! - this is why we start at
|
||||
// WL #2, and only use 2-11) seems like a sane first approximation.
|
||||
|
||||
double correctionFactor = 0.0;
|
||||
|
||||
for ( unsigned int i = 2; i < 11; i++ )
|
||||
{
|
||||
correctionFactor +=
|
||||
state->emission_correction_factor_sun[i];
|
||||
}
|
||||
|
||||
// This is the average ratio in emitted energy between our sun, and an
|
||||
// equally large sun with the blackbody spectrum we requested.
|
||||
|
||||
// Division by 9 because we only used 9 of the 11 wavelengths for this
|
||||
// (see above).
|
||||
|
||||
double ratio = correctionFactor / 9.0;
|
||||
|
||||
// This ratio is then used to determine the radius of the alien sun
|
||||
// on the sky dome. The additional factor 'solar_intensity' can be used
|
||||
// to make the alien sun brighter or dimmer compared to our sun.
|
||||
|
||||
state->solar_radius =
|
||||
( sqrt( solar_intensity ) * TERRESTRIAL_SOLAR_RADIUS )
|
||||
/ sqrt( ratio );
|
||||
|
||||
// Finally, we have to reduce the scaling factor of the sky by the
|
||||
// ratio used to scale the solar disc size. The rationale behind this is
|
||||
// that the scaling factors apply to the new blackbody spectrum, which
|
||||
// can be more or less bright than the one our sun emits. However, we
|
||||
// just scaled the size of the alien solar disc so it is roughly as
|
||||
// bright (in terms of energy emitted) as the terrestrial sun. So the sky
|
||||
// dome has to be reduced in brightness appropriately - but not in an
|
||||
// uniform fashion across wavebands. If we did that, the sky colour would
|
||||
// be wrong.
|
||||
|
||||
for ( unsigned int i = 0; i < 11; i++ )
|
||||
{
|
||||
state->emission_correction_factor_sky[i] =
|
||||
solar_intensity
|
||||
* state->emission_correction_factor_sun[i] / ratio;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void arhosekskymodelstate_free(
|
||||
ArHosekSkyModelState * state
|
||||
)
|
||||
{
|
||||
free(state);
|
||||
}
|
||||
|
||||
double arhosekskymodel_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
double wavelength
|
||||
)
|
||||
{
|
||||
int low_wl = (wavelength - 320.0 ) / 40.0;
|
||||
|
||||
if ( low_wl < 0 || low_wl >= 11 )
|
||||
return 0.0f;
|
||||
|
||||
double interp = fmod((wavelength - 320.0 ) / 40.0, 1.0);
|
||||
|
||||
double val_low =
|
||||
ArHosekSkyModel_GetRadianceInternal(
|
||||
state->configs[low_wl],
|
||||
theta,
|
||||
gamma
|
||||
)
|
||||
* state->radiances[low_wl]
|
||||
* state->emission_correction_factor_sky[low_wl];
|
||||
|
||||
if ( interp < 1e-6 )
|
||||
return val_low;
|
||||
|
||||
double result = ( 1.0 - interp ) * val_low;
|
||||
|
||||
if ( low_wl+1 < 11 )
|
||||
{
|
||||
result +=
|
||||
interp
|
||||
* ArHosekSkyModel_GetRadianceInternal(
|
||||
state->configs[low_wl+1],
|
||||
theta,
|
||||
gamma
|
||||
)
|
||||
* state->radiances[low_wl+1]
|
||||
* state->emission_correction_factor_sky[low_wl+1];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// xyz and rgb versions
|
||||
|
||||
ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init(
|
||||
const double turbidity,
|
||||
const double albedo,
|
||||
const double elevation
|
||||
)
|
||||
{
|
||||
ArHosekSkyModelState * state = ALLOC(ArHosekSkyModelState);
|
||||
|
||||
state->solar_radius = TERRESTRIAL_SOLAR_RADIUS;
|
||||
state->turbidity = turbidity;
|
||||
state->albedo = albedo;
|
||||
state->elevation = elevation;
|
||||
|
||||
for( unsigned int channel = 0; channel < 3; ++channel )
|
||||
{
|
||||
ArHosekSkyModel_CookConfiguration(
|
||||
datasetsXYZ[channel],
|
||||
state->configs[channel],
|
||||
turbidity,
|
||||
albedo,
|
||||
elevation
|
||||
);
|
||||
|
||||
state->radiances[channel] =
|
||||
ArHosekSkyModel_CookRadianceConfiguration(
|
||||
datasetsXYZRad[channel],
|
||||
turbidity,
|
||||
albedo,
|
||||
elevation
|
||||
);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
ArHosekSkyModelState * arhosek_rgb_skymodelstate_alloc_init(
|
||||
const double turbidity,
|
||||
const double albedo,
|
||||
const double elevation
|
||||
)
|
||||
{
|
||||
ArHosekSkyModelState* state = ALLOC(ArHosekSkyModelState);
|
||||
|
||||
state->solar_radius = TERRESTRIAL_SOLAR_RADIUS;
|
||||
state->turbidity = turbidity;
|
||||
state->albedo = albedo;
|
||||
state->elevation = elevation;
|
||||
|
||||
for( unsigned int channel = 0; channel < 3; ++channel )
|
||||
{
|
||||
ArHosekSkyModel_CookConfiguration(
|
||||
datasetsRGB[channel],
|
||||
state->configs[channel],
|
||||
turbidity,
|
||||
albedo,
|
||||
elevation
|
||||
);
|
||||
|
||||
state->radiances[channel] =
|
||||
ArHosekSkyModel_CookRadianceConfiguration(
|
||||
datasetsRGBRad[channel],
|
||||
turbidity,
|
||||
albedo,
|
||||
elevation
|
||||
);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
double arhosek_tristim_skymodel_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
int channel
|
||||
)
|
||||
{
|
||||
return
|
||||
ArHosekSkyModel_GetRadianceInternal(
|
||||
state->configs[channel],
|
||||
theta,
|
||||
gamma
|
||||
)
|
||||
* state->radiances[channel];
|
||||
}
|
||||
|
||||
const int pieces = 45;
|
||||
const int order = 4;
|
||||
|
||||
double arhosekskymodel_sr_internal(
|
||||
ArHosekSkyModelState * state,
|
||||
int turbidity,
|
||||
int wl,
|
||||
double elevation
|
||||
)
|
||||
{
|
||||
int pos =
|
||||
(int) (pow(2.0*elevation / MATH_PI, 1.0/3.0) * pieces); // floor
|
||||
|
||||
if ( pos > 44 ) pos = 44;
|
||||
|
||||
const double break_x =
|
||||
pow(((double) pos / (double) pieces), 3.0) * (MATH_PI * 0.5);
|
||||
|
||||
const double * coefs =
|
||||
solarDatasets[wl] + (order * pieces * turbidity + order * (pos+1) - 1);
|
||||
|
||||
double res = 0.0;
|
||||
const double x = elevation - break_x;
|
||||
double x_exp = 1.0;
|
||||
|
||||
for (int i = 0; i < order; ++i)
|
||||
{
|
||||
res += x_exp * *coefs--;
|
||||
x_exp *= x;
|
||||
}
|
||||
|
||||
return res * state->emission_correction_factor_sun[wl];
|
||||
}
|
||||
|
||||
double arhosekskymodel_solar_radiance_internal2(
|
||||
ArHosekSkyModelState * state,
|
||||
double wavelength,
|
||||
double elevation,
|
||||
double gamma
|
||||
)
|
||||
{
|
||||
assert(
|
||||
wavelength >= 320.0
|
||||
&& wavelength <= 720.0
|
||||
&& state->turbidity >= 1.0
|
||||
&& state->turbidity <= 10.0
|
||||
);
|
||||
|
||||
|
||||
int turb_low = (int) state->turbidity - 1;
|
||||
double turb_frac = state->turbidity - (double) (turb_low + 1);
|
||||
|
||||
if ( turb_low == 9 )
|
||||
{
|
||||
turb_low = 8;
|
||||
turb_frac = 1.0;
|
||||
}
|
||||
|
||||
int wl_low = (int) ((wavelength - 320.0) / 40.0);
|
||||
double wl_frac = fmod(wavelength, 40.0) / 40.0;
|
||||
|
||||
if ( wl_low == 10 )
|
||||
{
|
||||
wl_low = 9;
|
||||
wl_frac = 1.0;
|
||||
}
|
||||
|
||||
double direct_radiance =
|
||||
( 1.0 - turb_frac )
|
||||
* ( (1.0 - wl_frac)
|
||||
* arhosekskymodel_sr_internal(
|
||||
state,
|
||||
turb_low,
|
||||
wl_low,
|
||||
elevation
|
||||
)
|
||||
+ wl_frac
|
||||
* arhosekskymodel_sr_internal(
|
||||
state,
|
||||
turb_low,
|
||||
wl_low+1,
|
||||
elevation
|
||||
)
|
||||
)
|
||||
+ turb_frac
|
||||
* ( ( 1.0 - wl_frac )
|
||||
* arhosekskymodel_sr_internal(
|
||||
state,
|
||||
turb_low+1,
|
||||
wl_low,
|
||||
elevation
|
||||
)
|
||||
+ wl_frac
|
||||
* arhosekskymodel_sr_internal(
|
||||
state,
|
||||
turb_low+1,
|
||||
wl_low+1,
|
||||
elevation
|
||||
)
|
||||
);
|
||||
|
||||
double ldCoefficient[6];
|
||||
|
||||
for ( int i = 0; i < 6; i++ )
|
||||
ldCoefficient[i] =
|
||||
(1.0 - wl_frac) * limbDarkeningDatasets[wl_low ][i]
|
||||
+ wl_frac * limbDarkeningDatasets[wl_low+1][i];
|
||||
|
||||
// sun distance to diameter ratio, squared
|
||||
|
||||
const double sol_rad_sin = sin(state->solar_radius);
|
||||
const double ar2 = 1 / ( sol_rad_sin * sol_rad_sin );
|
||||
const double singamma = sin(gamma);
|
||||
double sc2 = 1.0 - ar2 * singamma * singamma;
|
||||
if (sc2 < 0.0 ) sc2 = 0.0;
|
||||
double sampleCosine = sqrt (sc2);
|
||||
|
||||
// The following will be improved in future versions of the model:
|
||||
// here, we directly use fitted 5th order polynomials provided by the
|
||||
// astronomical community for the limb darkening effect. Astronomers need
|
||||
// such accurate fittings for their predictions. However, this sort of
|
||||
// accuracy is not really needed for CG purposes, so an approximated
|
||||
// dataset based on quadratic polynomials will be provided in a future
|
||||
// release.
|
||||
|
||||
double darkeningFactor =
|
||||
ldCoefficient[0]
|
||||
+ ldCoefficient[1] * sampleCosine
|
||||
+ ldCoefficient[2] * pow( sampleCosine, 2.0 )
|
||||
+ ldCoefficient[3] * pow( sampleCosine, 3.0 )
|
||||
+ ldCoefficient[4] * pow( sampleCosine, 4.0 )
|
||||
+ ldCoefficient[5] * pow( sampleCosine, 5.0 );
|
||||
|
||||
direct_radiance *= darkeningFactor;
|
||||
|
||||
return direct_radiance;
|
||||
}
|
||||
|
||||
double arhosekskymodel_solar_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
double wavelength
|
||||
)
|
||||
{
|
||||
double direct_radiance =
|
||||
arhosekskymodel_solar_radiance_internal2(
|
||||
state,
|
||||
wavelength,
|
||||
((MATH_PI/2.0)-theta),
|
||||
gamma
|
||||
);
|
||||
|
||||
double inscattered_radiance =
|
||||
arhosekskymodel_radiance(
|
||||
state,
|
||||
theta,
|
||||
gamma,
|
||||
wavelength
|
||||
);
|
||||
|
||||
return direct_radiance + inscattered_radiance;
|
||||
}
|
||||
|
||||
451
work_files/skylight/hosek_model_source/ArHosekSkyModel.h
Normal file
451
work_files/skylight/hosek_model_source/ArHosekSkyModel.h
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
This source is published under the following 3-clause BSD license.
|
||||
|
||||
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* None of the names of the contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
============================================================================ */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This code is taken from ART, a rendering research system written in a
|
||||
mix of C99 / Objective C. Since ART is not a small system and is intended to
|
||||
be inter-operable with other libraries, and since C does not have namespaces,
|
||||
the structures and functions in ART all have to have somewhat wordy
|
||||
canonical names that begin with Ar.../ar..., like those seen in this example.
|
||||
|
||||
Usage information:
|
||||
==================
|
||||
|
||||
|
||||
Model initialisation
|
||||
--------------------
|
||||
|
||||
A separate ArHosekSkyModelState has to be maintained for each spectral
|
||||
band you want to use the model for. So in a renderer with 'num_channels'
|
||||
bands, you would need something like
|
||||
|
||||
ArHosekSkyModelState * skymodel_state[num_channels];
|
||||
|
||||
You then have to allocate and initialise these states. In the following code
|
||||
snippet, we assume that 'albedo' is defined as
|
||||
|
||||
double albedo[num_channels];
|
||||
|
||||
with a ground albedo value between [0,1] for each channel. The solar elevation
|
||||
is given in radians.
|
||||
|
||||
for ( unsigned int i = 0; i < num_channels; i++ )
|
||||
skymodel_state[i] =
|
||||
arhosekskymodelstate_alloc_init(
|
||||
turbidity,
|
||||
albedo[i],
|
||||
solarElevation
|
||||
);
|
||||
|
||||
Note that starting with version 1.3, there is also a second initialisation
|
||||
function which generates skydome states for different solar emission spectra
|
||||
and solar radii: 'arhosekskymodelstate_alienworld_alloc_init()'.
|
||||
|
||||
See the notes about the "Alien World" functionality provided further down for a
|
||||
discussion of the usefulness and limits of that second initalisation function.
|
||||
Sky model states that have been initialised with either function behave in a
|
||||
completely identical fashion during use and cleanup.
|
||||
|
||||
Using the model to generate skydome samples
|
||||
-------------------------------------------
|
||||
|
||||
Generating a skydome radiance spectrum "skydome_result" for a given location
|
||||
on the skydome determined via the angles theta and gamma works as follows:
|
||||
|
||||
double skydome_result[num_channels];
|
||||
|
||||
for ( unsigned int i = 0; i < num_channels; i++ )
|
||||
skydome_result[i] =
|
||||
arhosekskymodel_radiance(
|
||||
skymodel_state[i],
|
||||
theta,
|
||||
gamma,
|
||||
channel_center[i]
|
||||
);
|
||||
|
||||
The variable "channel_center" is assumed to hold the channel center wavelengths
|
||||
for each of the num_channels samples of the spectrum we are building.
|
||||
|
||||
|
||||
Cleanup after use
|
||||
-----------------
|
||||
|
||||
After rendering is complete, the content of the sky model states should be
|
||||
disposed of via
|
||||
|
||||
for ( unsigned int i = 0; i < num_channels; i++ )
|
||||
arhosekskymodelstate_free( skymodel_state[i] );
|
||||
|
||||
|
||||
CIE XYZ Version of the Model
|
||||
----------------------------
|
||||
|
||||
Usage of the CIE XYZ version of the model is exactly the same, except that
|
||||
num_channels is of course always 3, and that ArHosekTristimSkyModelState and
|
||||
arhosek_tristim_skymodel_radiance() have to be used instead of their spectral
|
||||
counterparts.
|
||||
|
||||
RGB Version of the Model
|
||||
------------------------
|
||||
|
||||
The RGB version uses sRGB primaries with a linear gamma ramp. The same set of
|
||||
functions as with the XYZ data is used, except the model is initialized
|
||||
by calling arhosek_rgb_skymodelstate_alloc_init.
|
||||
|
||||
Solar Radiance Function
|
||||
-----------------------
|
||||
|
||||
For each position on the solar disc, this function returns the entire radiance
|
||||
one sees - direct emission, as well as in-scattered light in the area of the
|
||||
solar disc. The latter is important for low solar elevations - nice images of
|
||||
the setting sun would not be possible without this. This is also the reason why
|
||||
this function, just like the regular sky dome model evaluation function, needs
|
||||
access to the sky dome data structures, as these provide information on
|
||||
in-scattered radiance.
|
||||
|
||||
CAVEAT #1: in this release, this function is only provided in spectral form!
|
||||
RGB/XYZ versions to follow at a later date.
|
||||
|
||||
CAVEAT #2: (fixed from release 1.3 onwards)
|
||||
|
||||
CAVEAT #3: limb darkening renders the brightness of the solar disc
|
||||
inhomogeneous even for high solar elevations - only taking a single
|
||||
sample at the centre of the sun will yield an incorrect power
|
||||
estimate for the solar disc! Always take multiple random samples
|
||||
across the entire solar disc to estimate its power!
|
||||
|
||||
CAVEAT #4: in this version, the limb darkening calculations still use a fairly
|
||||
computationally expensive 5th order polynomial that was directly
|
||||
taken from astronomical literature. For the purposes of Computer
|
||||
Graphics, this is needlessly accurate, though, and will be replaced
|
||||
by a cheaper approximation in a future release.
|
||||
|
||||
"Alien World" functionality
|
||||
---------------------------
|
||||
|
||||
The Hosek sky model can be used to roughly (!) predict the appearance of
|
||||
outdoor scenes on earth-like planets, i.e. planets of a similar size and
|
||||
atmospheric make-up. Since the spectral version of our model predicts sky dome
|
||||
luminance patterns and solar radiance independently for each waveband, and
|
||||
since the intensity of each waveband is solely dependent on the input radiance
|
||||
from the star that the world in question is orbiting, it is trivial to re-scale
|
||||
the wavebands to match a different star radiance.
|
||||
|
||||
At least in theory, the spectral version of the model has always been capable
|
||||
of this sort of thing, and the actual sky dome and solar radiance models were
|
||||
actually not altered at all in this release. All we did was to add some support
|
||||
functionality for doing this more easily with the existing data and functions,
|
||||
and to add some explanations.
|
||||
|
||||
Just use 'arhosekskymodelstate_alienworld_alloc_init()' to initialise the sky
|
||||
model states (you will have to provide values for star temperature and solar
|
||||
intensity compared to the terrestrial sun), and do everything else as you
|
||||
did before.
|
||||
|
||||
CAVEAT #1: we assume the emission of the star that illuminates the alien world
|
||||
to be a perfect blackbody emission spectrum. This is never entirely
|
||||
realistic - real star emission spectra are considerably more complex
|
||||
than this, mainly due to absorption effects in the outer layers of
|
||||
stars. However, blackbody spectra are a reasonable first assumption
|
||||
in a usage scenario like this, where 100% accuracy is simply not
|
||||
necessary: for rendering purposes, there are likely no visible
|
||||
differences between a highly accurate solution based on a more
|
||||
involved simulation, and this approximation.
|
||||
|
||||
CAVEAT #2: we always use limb darkening data from our own sun to provide this
|
||||
"appearance feature", even for suns of strongly different
|
||||
temperature. Which is presumably not very realistic, but (as with
|
||||
the unaltered blackbody spectrum from caveat #1) probably not a bad
|
||||
first guess, either. If you need more accuracy than we provide here,
|
||||
please make inquiries with a friendly astro-physicst of your choice.
|
||||
|
||||
CAVEAT #3: you have to provide a value for the solar intensity of the star
|
||||
which illuminates the alien world. For this, please bear in mind
|
||||
that there is very likely a comparatively tight range of absolute
|
||||
solar irradiance values for which an earth-like planet with an
|
||||
atmosphere like the one we assume in our model can exist in the
|
||||
first place!
|
||||
|
||||
Too much irradiance, and the atmosphere probably boils off into
|
||||
space, too little, it freezes. Which means that stars of
|
||||
considerably different emission colour than our sun will have to be
|
||||
fairly different in size from it, to still provide a reasonable and
|
||||
inhabitable amount of irradiance. Red stars will need to be much
|
||||
larger than our sun, while white or blue stars will have to be
|
||||
comparatively tiny. The initialisation function handles this and
|
||||
computes a plausible solar radius for a given emission spectrum. In
|
||||
terms of absolute radiometric values, you should probably not stray
|
||||
all too far from a solar intensity value of 1.0.
|
||||
|
||||
CAVEAT #4: although we now support different solar radii for the actual solar
|
||||
disc, the sky dome luminance patterns are *not* parameterised by
|
||||
this value - i.e. the patterns stay exactly the same for different
|
||||
solar radii! Which is of course not correct. But in our experience,
|
||||
solar discs up to several degrees in diameter (! - our own sun is
|
||||
half a degree across) do not cause the luminance patterns on the sky
|
||||
to change perceptibly. The reason we know this is that we initially
|
||||
used unrealistically large suns in our brute force path tracer, in
|
||||
order to improve convergence speeds (which in the beginning were
|
||||
abysmal). Later, we managed to do the reference renderings much
|
||||
faster even with realistically small suns, and found that there was
|
||||
no real difference in skydome appearance anyway.
|
||||
Conclusion: changing the solar radius should not be over-done, so
|
||||
close orbits around red supergiants are a no-no. But for the
|
||||
purposes of getting a fairly credible first impression of what an
|
||||
alien world with a reasonably sized sun would look like, what we are
|
||||
doing here is probably still o.k.
|
||||
|
||||
HINT #1: if you want to model the sky of an earth-like planet that orbits
|
||||
a binary star, just super-impose two of these models with solar
|
||||
intensity of ~0.5 each, and closely spaced solar positions. Light is
|
||||
additive, after all. Tattooine, here we come... :-)
|
||||
|
||||
P.S. according to Star Wars canon, Tattooine orbits a binary
|
||||
that is made up of a G and K class star, respectively.
|
||||
So ~5500K and ~4200K should be good first guesses for their
|
||||
temperature. Just in case you were wondering, after reading the
|
||||
previous paragraph.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ARHOSEK_SKYMODEL_H_
|
||||
#define _ARHOSEK_SKYMODEL_H_
|
||||
|
||||
typedef double ArHosekSkyModelConfiguration[9];
|
||||
|
||||
|
||||
// Spectral version of the model
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
ArHosekSkyModelState struct
|
||||
---------------------------
|
||||
|
||||
This struct holds the pre-computation data for one particular albedo value.
|
||||
Most fields are self-explanatory, but users should never directly
|
||||
manipulate any of them anyway. The only consistent way to manipulate such
|
||||
structs is via the functions 'arhosekskymodelstate_alloc_init' and
|
||||
'arhosekskymodelstate_free'.
|
||||
|
||||
'emission_correction_factor_sky'
|
||||
'emission_correction_factor_sun'
|
||||
|
||||
The original model coefficients were fitted against the emission of
|
||||
our local sun. If a different solar emission is desired (i.e. if the
|
||||
model is being used to predict skydome appearance for an earth-like
|
||||
planet that orbits a different star), these correction factors, which
|
||||
are determined during the alloc_init step, are applied to each waveband
|
||||
separately (they default to 1.0 in normal usage). This is the simplest
|
||||
way to retrofit this sort of capability to the existing model. The
|
||||
different factors for sky and sun are needed since the solar disc may
|
||||
be of a different size compared to the terrestrial sun.
|
||||
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct ArHosekSkyModelState
|
||||
{
|
||||
ArHosekSkyModelConfiguration configs[11];
|
||||
double radiances[11];
|
||||
double turbidity;
|
||||
double solar_radius;
|
||||
double emission_correction_factor_sky[11];
|
||||
double emission_correction_factor_sun[11];
|
||||
double albedo;
|
||||
double elevation;
|
||||
}
|
||||
ArHosekSkyModelState;
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
arhosekskymodelstate_alloc_init() function
|
||||
------------------------------------------
|
||||
|
||||
Initialises an ArHosekSkyModelState struct for a terrestrial setting.
|
||||
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
ArHosekSkyModelState * arhosekskymodelstate_alloc_init(
|
||||
const double solar_elevation,
|
||||
const double atmospheric_turbidity,
|
||||
const double ground_albedo
|
||||
);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
arhosekskymodelstate_alienworld_alloc_init() function
|
||||
-----------------------------------------------------
|
||||
|
||||
Initialises an ArHosekSkyModelState struct for an "alien world" setting
|
||||
with a sun of a surface temperature given in 'kelvin'. The parameter
|
||||
'solar_intensity' controls the overall brightness of the sky, relative
|
||||
to the solar irradiance on Earth. A value of 1.0 yields a sky dome that
|
||||
is, on average over the wavelenghts covered in the model (!), as bright
|
||||
as the terrestrial sky in radiometric terms.
|
||||
|
||||
Which means that the solar radius has to be adjusted, since the
|
||||
emissivity of a solar surface with a given temperature is more or less
|
||||
fixed. So hotter suns have to be smaller to be equally bright as the
|
||||
terrestrial sun, while cooler suns have to be larger. Note that there are
|
||||
limits to the validity of the luminance patterns of the underlying model:
|
||||
see the discussion above for more on this. In particular, an alien sun with
|
||||
a surface temperature of only 2000 Kelvin has to be very large if it is
|
||||
to be as bright as the terrestrial sun - so large that the luminance
|
||||
patterns are no longer a really good fit in that case.
|
||||
|
||||
If you need information about the solar radius that the model computes
|
||||
for a given temperature (say, for light source sampling purposes), you
|
||||
have to query the 'solar_radius' variable of the sky model state returned
|
||||
*after* running this function.
|
||||
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
ArHosekSkyModelState * arhosekskymodelstate_alienworld_alloc_init(
|
||||
const double solar_elevation,
|
||||
const double solar_intensity,
|
||||
const double solar_surface_temperature_kelvin,
|
||||
const double atmospheric_turbidity,
|
||||
const double ground_albedo
|
||||
);
|
||||
|
||||
void arhosekskymodelstate_free(
|
||||
ArHosekSkyModelState * state
|
||||
);
|
||||
|
||||
double arhosekskymodel_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
double wavelength
|
||||
);
|
||||
|
||||
// CIE XYZ and RGB versions
|
||||
|
||||
|
||||
ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init(
|
||||
const double turbidity,
|
||||
const double albedo,
|
||||
const double elevation
|
||||
);
|
||||
|
||||
|
||||
ArHosekSkyModelState * arhosek_rgb_skymodelstate_alloc_init(
|
||||
const double turbidity,
|
||||
const double albedo,
|
||||
const double elevation
|
||||
);
|
||||
|
||||
|
||||
double arhosek_tristim_skymodel_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
int channel
|
||||
);
|
||||
|
||||
// Delivers the complete function: sky + sun, including limb darkening.
|
||||
// Please read the above description before using this - there are several
|
||||
// caveats!
|
||||
|
||||
double arhosekskymodel_solar_radiance(
|
||||
ArHosekSkyModelState * state,
|
||||
double theta,
|
||||
double gamma,
|
||||
double wavelength
|
||||
);
|
||||
|
||||
|
||||
#endif // _ARHOSEK_SKYMODEL_H_
|
||||
3863
work_files/skylight/hosek_model_source/ArHosekSkyModelData_CIEXYZ.h
Executable file
3863
work_files/skylight/hosek_model_source/ArHosekSkyModelData_CIEXYZ.h
Executable file
File diff suppressed because it is too large
Load Diff
3861
work_files/skylight/hosek_model_source/ArHosekSkyModelData_RGB.h
Executable file
3861
work_files/skylight/hosek_model_source/ArHosekSkyModelData_RGB.h
Executable file
File diff suppressed because it is too large
Load Diff
33770
work_files/skylight/hosek_model_source/ArHosekSkyModelData_Spectral.h
Executable file
33770
work_files/skylight/hosek_model_source/ArHosekSkyModelData_Spectral.h
Executable file
File diff suppressed because it is too large
Load Diff
76
work_files/skylight/hosek_model_source/README.txt
Normal file
76
work_files/skylight/hosek_model_source/README.txt
Normal file
@@ -0,0 +1,76 @@
|
||||
This file is part of a sample implementation of the analytical skylight and
|
||||
solar radiance models presented in the SIGGRAPH 2012 paper
|
||||
|
||||
|
||||
"An Analytic Model for Full Spectral Sky-Dome Radiance"
|
||||
|
||||
and the 2013 IEEE CG&A paper
|
||||
|
||||
"Adding a Solar Radiance Function to the Hosek Skylight Model"
|
||||
|
||||
both by
|
||||
|
||||
Lukas Hosek and Alexander Wilkie
|
||||
Charles University in Prague, Czech Republic
|
||||
|
||||
|
||||
Version: 1.4a, February 22nd, 2013
|
||||
|
||||
Version history:
|
||||
|
||||
1.4a February 22nd, 2013
|
||||
Removed unnecessary and counter-intuitive solar radius parameters
|
||||
from the interface of the colourspace sky dome initialisation functions.
|
||||
|
||||
1.4 February 11th, 2013
|
||||
Fixed a bug which caused the relative brightness of the solar disc
|
||||
and the sky dome to be off by a factor of about 6. The sun was too
|
||||
bright: this affected both normal and alien sun scenarios. The
|
||||
coefficients of the solar radiance function were changed to fix this.
|
||||
|
||||
1.3 January 21st, 2013 (not released to the public)
|
||||
Added support for solar discs that are not exactly the same size as
|
||||
the terrestrial sun. Also added support for suns with a different
|
||||
emission spectrum ("Alien World" functionality).
|
||||
|
||||
1.2a December 18th, 2012
|
||||
Fixed a mistake and some inaccuracies in the solar radiance function
|
||||
explanations found in ArHosekSkyModel.h. The actual source code is
|
||||
unchanged compared to version 1.2.
|
||||
|
||||
1.2 December 17th, 2012
|
||||
Native RGB data and a solar radiance function that matches the turbidity
|
||||
conditions were added.
|
||||
|
||||
1.1 September 2012
|
||||
The coefficients of the spectral model are now scaled so that the output
|
||||
is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
|
||||
XYZ model is now no longer scaled to the range [0...1]. Instead, it is
|
||||
the result of a simple conversion from spectral data via the CIE 2 degree
|
||||
standard observer matching functions. Therefore, after multiplication
|
||||
with 683 lm / W, the Y channel now corresponds to luminance in lm.
|
||||
|
||||
1.0 May 11th, 2012
|
||||
Initial release.
|
||||
|
||||
|
||||
Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
|
||||
an updated version of this code has been published!
|
||||
|
||||
This archive contains the following files:
|
||||
|
||||
README.txt This file.
|
||||
|
||||
ArHosekSkyModel.h Header file for the reference functions. Their
|
||||
usage is explained there, and sample code for
|
||||
calling them is given.
|
||||
|
||||
ArHosekSkyModel.c Implementation of the functions.
|
||||
|
||||
ArHosekSkyModelData_Spectral.h Spectral coefficient data.
|
||||
ArHosekSkyModelData_CIEXYZ.h CIE XYZ coefficient data.
|
||||
ArHosekSkyModelData_RGB.h RGB coefficient data.
|
||||
|
||||
Please note that the source files are in C99, and you have to set appropriate
|
||||
compiler flags for them to work. For example, when compiling this code with
|
||||
gcc, you have to add the "-std=c99" or "-std=gnu99" flags.
|
||||
@@ -0,0 +1 @@
|
||||
all dataset bins contain double-precision floating point numbers, in LITTLE-ENDIAN.
|
||||
BIN
work_files/skylight/hosek_model_source/datasets.zip
LFS
Normal file
BIN
work_files/skylight/hosek_model_source/datasets.zip
LFS
Normal file
Binary file not shown.
49
work_files/skylight/hosek_model_source/makebin.c
Normal file
49
work_files/skylight/hosek_model_source/makebin.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ArHosekSkyModelData_Spectral.h"
|
||||
#include "ArHosekSkyModelData_CIEXYZ.h"
|
||||
#include "ArHosekSkyModelData_RGB.h"
|
||||
|
||||
double testset[] = {
|
||||
1.0,
|
||||
2.0,
|
||||
3.0,
|
||||
4.0
|
||||
};
|
||||
|
||||
void double_to_char(double a, char outbuf[]) {
|
||||
memcpy(outbuf, &a, sizeof(a));
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
FILE * outfile;
|
||||
|
||||
outfile = fopen("./datasetRGBRad3.bin", "w");
|
||||
|
||||
for (i = 0; i < sizeof(datasetRGBRad3) / sizeof(double); i++) {
|
||||
double test_num = datasetRGBRad3[i];
|
||||
|
||||
char outchars[sizeof(test_num)];
|
||||
|
||||
double_to_char(test_num, outchars);
|
||||
|
||||
int k = 0;
|
||||
for (k = 0; k < sizeof(test_num); k++) {
|
||||
fputc(outchars[k], outfile);
|
||||
printf("%02x ", outchars[k]);
|
||||
}
|
||||
fflush(outfile);
|
||||
printf("\n");
|
||||
printf("Writing entry %d\n", i + 1);
|
||||
}
|
||||
|
||||
fflush(outfile);
|
||||
fclose(outfile);
|
||||
printf("Operation completed successfully.\n");
|
||||
|
||||
/**/
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user