• Create Account

# Axiverse

Member Since 02 Mar 2004
Offline Last Active Sep 27 2013 01:06 AM

### Properly rendering a starfield skymap

23 July 2013 - 01:05 AM

I'm trying to render a starfield properly. I'm doing something similar to the new google maps zoomed out where you can see the entire planet and stars. However, right now in my implementation i'm basically drawing a sphere with the stars in the scene. When you zoom in or out the stars get zoomed in or out, but i think the right implementation is that they don't move. How would I properly render that?

basically right now the sky is a sphere(5000), and the earth is a sphere(10) and the camera moves in and out looking at the earth. when i zoom in, a narrower area of the sky is shown, I don't think this is correct, is it? Would I scale the sky inversely to the camera zoom? -> the more the camera is zoomed, the smaller the sky is?

### Space Partitioning on Sphere

01 June 2013 - 01:27 PM

What approaches would be best for space partitioning on a sphere? I'm working with a visualizing data on the surface of the earth.

Some operations that would be relevant

• Find the closest stored point to a given point
• See if a the given point is within a region
• Adding and removing points and regions

Currently, some of the approaches that I've thought of taking are:

• Start with a octahedron and do triangle tessellation, 4 triangles to each parent triangle. I'm not sure how to approach indexing nodes from latitude, longitude. The pros would be that the partitions would be basically equal area.
• Quadtree, with the first level separated by north/south hemisphere (positive/negative y) and then a normal quadtree based on the x, z coordinates. This might be a bit easier to index, but leaves might not be balanced well.

Are there any other common approaches that you guys know of or can think of?

Thanks!

### Finding the area of a geopolygon (made of longitude latitude points)

04 April 2013 - 05:27 AM

How would you go about, or does anyone know of any articles/references on calculating the area of a polygon? (Remember that maps are distorted towards the poles, to the actual area isn't just the polygon area) Or any suggestions on how I might go about calculating this?

### Triangulation with maximum triangle size

18 February 2013 - 11:56 AM

Hey, I'm trying to triangulate a country on the surface on the earth. I want to limit the size of the triangles so that when I convert it from 2d points to 3d points they aren't too long/big so that when I overlay it on the surface of the parent sphere it doesn't get clipped under the surface. Is there any way to do this? The shapes are also concave as well.

### Atmospheric Scattering, Planet Rendering (O'neil)

13 February 2013 - 11:10 PM

I'm trying to implement O'neil's atmospheric scattering shader in WebGL but I'm a little stuck. I've consulted various sources and am trying to get a working implementation running, but unfortunately all I'm getting is a white circle. Is anyone here familiar with it and could possibly see where I'm going wrong? The shaders below are an implementation of the SkyFromSpace shaders.

```scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000)

renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setClearColorHex(0x111111, 1)

\$('div.viewport').append(renderer.domElement)
\$(window).resize ->
camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000)
renderer.setSize( window.innerWidth, window.innerHeight )

vertexSky =
"""
//
//
// Author: Sean O'Neil
//
// Copyright (c) 2004 Sean O'Neil
//

uniform vec3 v3LightPosition;	// The direction vector to the light source
uniform vec3 v3InvWavelength;	// 1 / pow(wavelength, 4) for the red, green, and blue channels
uniform float fCameraHeight;	// The camera's current height
uniform float fCameraHeight2;	// fCameraHeight^2
uniform float fKrESun;			// Kr * ESun
uniform float fKmESun;			// Km * ESun
uniform float fKr4PI;			// Kr * 4 * PI
uniform float fKm4PI;			// Km * 4 * PI
uniform float fScaleDepth;		// The scale depth (i.e. the altitude at which the atmosphere's average density is found)
uniform float fScaleOverScaleDepth;	// fScale / fScaleDepth

const int nSamples = 3;
const float fSamples = 3.0;

varying vec3 v3Direction;
varying vec3 c0;
varying vec3 c1;

float scale(float fCos)
{
float x = 1.0 - fCos;
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}

void main(void)
{
// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
vec3 v3Ray = position - cameraPosition;
float fFar = length(v3Ray);
v3Ray /= fFar;

// Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
float B = 2.0 * dot(cameraPosition, v3Ray);
float C = fCameraHeight2 - fOuterRadius2;
float fDet = max(0.0, B*B - 4.0 * C);
float fNear = 0.5 * (-B - sqrt(fDet));

// Calculate the ray's starting position, then calculate its scattering offset
vec3 v3Start = cameraPosition + v3Ray * fNear;
fFar -= fNear;
float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;
float fStartDepth = exp(-1.0 / fScaleDepth);
float fStartOffset = fStartDepth * scale(fStartAngle);
//c0 = vec3(1.0, 0, 0) * fStartAngle;

// Initialize the scattering loop variables
float fSampleLength = fFar / fSamples;
float fScaledLength = fSampleLength * fScale;
vec3 v3SampleRay = v3Ray * fSampleLength;
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;

//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);

// Now loop through the sample rays
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
for(int i=0; i<nSamples; i++)
{
float fHeight = length(v3SamplePoint);
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
float fLightAngle = dot(v3LightPosition, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));

v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
v3SamplePoint += v3SampleRay;
}

// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
c0 = v3FrontColor * (v3InvWavelength * fKrESun);
c1 = v3FrontColor * fKmESun;
v3Direction = cameraPosition - position;
}
"""

fragmentSky =
"""
//
//
// Author: Sean O'Neil
//
// Copyright (c) 2004 Sean O'Neil
//

uniform vec3 v3LightPos;
uniform float g;
uniform float g2;

varying vec3 v3Direction;
varying vec3 c0;
varying vec3 c1;

// Calculates the Mie phase function
float getMiePhase(float fCos, float fCos2, float g, float g2)
{
return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(1.0 + g2 - 2.0 * g * fCos, 1.5);
}

// Calculates the Rayleigh phase function
float getRayleighPhase(float fCos2)
{
return 0.75 + 0.75 * fCos2;
}

void main (void)
{
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
float fCos2 = fCos * fCos;

vec3 color =	getRayleighPhase(fCos2) * c0 +
getMiePhase(fCos, fCos2, g, g2) * c1;

gl_FragColor = vec4(color, 1.0);
gl_FragColor.a = gl_FragColor.b;
}
"""

atmosphere =
Kr				: 0.0025
Km				: 0.0010
ESun			: 15.0
g				: -0.990
wavelength		: [0.650, 0.570, 0.475]
scaleDepth		: 0.25
mieScaleDepth	:	0.1

uniforms =
v3LightPosition:
type:	"v3"
value:	new THREE.Vector3(1e8, 0, 1e8).normalize()
v3InvWavelength:
type:	"f"
value:	new THREE.Vector3(1 / Math.pow(atmosphere.wavelength[0], 4), 1 / Math.pow(atmosphere.wavelength[1], 4), 1 / Math.pow(atmosphere.wavelength[2], 4))
fCameraHeight:
type:	"f"
value:	0
fCameraHeight2:
type:	"f"
value:	0
type:	"f"
type:	"f"
fKrESun:
type:	"f"
value:	atmosphere.Kr * atmosphere.ESun
fKmESun:
type:	"f"
value:	atmosphere.Km * atmosphere.ESun
fKr4PI:
type:	"f"
value:	atmosphere.Kr * 4.0 * Math.PI
fKm4PI:
type:	"f"
value:	atmosphere.Km * 4.0 * Math.PI
fScale:
type:	"f"
fScaleDepth:
type:	"f"
value:	atmosphere.scaleDepth
fScaleOverScaleDepth:
type:	"f"
g:
type:	"f"
value:	atmosphere.g
g2:
type:	"f"
value:	atmosphere.g * atmosphere.g
nSamples:
type:	"i"
value:	3
fSamples:
type:	"f"
value:	3.0
tDiffuse:
type:	"t"
value:	0
texture: null
tDiffuseNight:
type:	"t"
value:	0
texture: null
tDisplacement:
type:	"t"
value:	0
texture: null
tSkyboxDiffuse:
type:	"t"
value:	0
texture: null

geometry = new THREE.SphereGeometry(atmosphere.outerRadius, 50, 50)
uniforms:		uniforms
sphere = new THREE.Mesh(geometry, material)

c = null
f = 0
g = 0

render = ->
requestAnimationFrame(render)
# material.uniforms.v3LightPos.value.y += 0.01

f += 0.01
g += 0.02

sphere.rotation.z += 0.005;
sphere.rotation.x += 0.001;

cameraHeight = camera.position.length()

material.uniforms.v3LightPosition.value = new THREE.Vector3(0, Math.sin(f), Math.cos(f))
material.uniforms.fCameraHeight.value = cameraHeight
material.uniforms.fCameraHeight2.value = cameraHeight * cameraHeight

renderer.render(scene, camera)

render()

```

What it should look like:

Sources: