Skip to content

Instantly share code, notes, and snippets.

@croxis
Created July 31, 2013 23:22
Show Gist options
  • Save croxis/6127131 to your computer and use it in GitHub Desktop.
Save croxis/6127131 to your computer and use it in GitHub Desktop.
Cubic spheres. Or: Rendering nice planets. Code is public domain.
uniform sampler2D p3d_Texture0;
varying vec2 texture_coordinate;
varying vec4 texCoords;
out varying vec4 FragColor;
void main(void)
{
FragColor = gl_Color;
}
from pandac.PandaModules import loadPrcFileData
loadPrcFileData('', 'frame-rate-meter-scale 0.035')
loadPrcFileData('', 'frame-rate-meter-side-margin 0.1')
loadPrcFileData('', 'show-frame-rate-meter 1')
loadPrcFileData('', 'window-title ' + "Vortex")
loadPrcFileData('', "sync-video 0")
loadPrcFileData('', 'basic-shaders-only #f')
import direct.directbase.DirectStart
from panda3d.core import PerlinNoise2, PNMImage, PointLight, Shader, Texture, Vec3, Vec4
from direct.filter.CommonFilters import CommonFilters
from pandac.PandaModules import *
def toggleWireframe():
base.toggleWireframe()
base.accept('w', toggleWireframe)
def myNormalize(myVec):
myVec.normalize()
return myVec
format = GeomVertexFormat.getV3n3c4t2()
vdata = GeomVertexData('quadFace', format, Geom.UHDynamic)
vertex = GeomVertexWriter(vdata, 'vertex')
normal = GeomVertexWriter(vdata, 'normal')
color = GeomVertexWriter(vdata, 'color')
texcoord = GeomVertexWriter(vdata, 'texcoord')
def create_mesh(debug=False):
'''This creates a simple 17x17 grid mesh for the sides of our cube.
The ultimate goal is to use a LOD system, probably based on quadtrees.
If debug is true then we get a color gradiant on our vertexes.'''
x = -1.0
y = -1.0
vertex_count = 0
u = 0.0
v = 1.0
WIDTH_STEP = 2/16.0
while y <= 1.0:
while x <= 1.0:
vertex.addData3f(x, y, 0)
normal.addData3f(myNormalize((Vec3(2*x-1, 2*y-1, 2*0-1))))
if debug:
color.addData4f(1.0, u, v, 1.0)
texcoord.addData2f(u, v)
vertex_count += 1
x += WIDTH_STEP
u += WIDTH_STEP/2.0
x = -1.0
u = 0
y += WIDTH_STEP
v -= WIDTH_STEP/2.0
print vertex_count
triangles = []
for y in range(0, 16):
for x in range(0, 16):
v = 17 * y + x
tri = GeomTriangles(Geom.UHDynamic)
tri.addVertex(v)
tri.addVertex(v+1)
tri.addVertex(v+17)
tri.closePrimitive()
triangles.append(tri)
tri = GeomTriangles(Geom.UHDynamic)
tri.addVertex(v+1)
tri.addVertex(v+18)
tri.addVertex(v+17)
tri.closePrimitive()
triangles.append(tri)
mesh = Geom(vdata)
for t in triangles:
mesh.addPrimitive(t)
mnode = GeomNode('quadface')
mnode.addGeom(mesh)
nodePath = base.render.attachNewNode(mnode)
return nodePath
'''planet is a parent nodepath that the 6 side mesh nodepaths will parent to.
planet can be moved, scale, and rotated with no problems'''
planet = NodePath('planet')
shaders = Shader.load(Shader.SLGLSL, 'vert.glsl', 'frag.glsl')
planet.setShader(shaders)
planet.reparentTo(base.render)
'''The side meshes are rotated here. They are moved to their correct
position in the shader'''
m = create_mesh(True)
m.reparentTo(planet)
m.setHpr(0, 0, 0)
m = create_mesh(True)
m.reparentTo(planet)
m.setHpr(0, 180, 0)
m = create_mesh(True)
m.reparentTo(planet)
m.setHpr(0, -90, 0)
m = create_mesh()
m.reparentTo(planet)
m.setHpr(0, 90, 0)
m = create_mesh(True)
m.reparentTo(planet)
m.setHpr(0, 0, -90)
m = create_mesh(True)
m.reparentTo(planet)
m.setHpr(0, 0, 90)
run()
uniform mat4 p3d_ModelViewProjectionMatrix;
varying vec4 texCoords;
void main(void) {
vec4 test = gl_Vertex;
//By adding 1 to z we move our grid to make a cube.
//We do 1 instead of 0.5 to make all the math easy.
test.z = test.z + 1.0;
//While this simple normalizing works it causes some distortion near the edges
//While less distoration than a standard sphere there are more ideal solutions
//gl_Position = p3d_ModelViewProjectionMatrix * vec4(normalize(test.xyz), test.w);
//The normalization creates almost no edge distortion
//Proof: http://mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html
float x = test.x;
float y = test.y;
float z = test.z;
test.x *= sqrt(1.0 - y * y * 0.5 - z * z * 0.5 + y * y * z * z / 3.0);
test.y *= sqrt(1.0 - z * z * 0.5 - x * x * 0.5 + z * z * x * x / 3.0);
test.z *= sqrt(1.0 - x * x * 0.5 - y * y * 0.5 + x * x * y * y / 3.0);
gl_Position = p3d_ModelViewProjectionMatrix * test;
gl_FrontColor = gl_Color;
texCoords = gl_MultiTexCoord0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment