Описание:Генерация планет на лету,генерируются не вся планета сразу,а только та часть которую видет камера
Синтаксис:
Используется javascript
// Based on code from the Procedural Examples project
// Feel free to use this code! (it even works now!)
var heightMap : Texture2D; // determines overal topography
var detailMap : Texture2D; // adds extra detail -- optional
var detailMapScale : float = 10;
var detailMapHeight : float = 0.2;
var material : Material;
var innerRadius : float = 400;
var outerRadius : float = 420; // determines maximum "height"
var patchFocus : Transform; // object whose POV determines portion of mesh to render
var minGridAngle : float = 1.0;
var xRes : int = 32; // mesh budget
var yRes : int = 16; // for rendering
var textureScale : float = 10; // number of times the material will be repeated if not a heightField
var textureIsHeightField : boolean = true; // material simply treated as vertical color bar
var updateOffsetThreshold : float = 2.0; // how far patchFocus has to move to force a redraw (also angular change that will force a redraw)
var showUI : boolean = false; // shows a simple UI to see performance impact
// private (or, it will be once I'm done debugging)
private var mesh : Mesh;
private var xGridSize : float;
private var yGridSize : float;
var gridCenter : Vector3;
var gridAngle : float;
private var gridDirty : boolean = true;
var latitude : float; // center of area
var longitude : float; // we need to render
var latStart : float = -90 * Mathf.Deg2Rad; // area
var latEnd : float = 90 * Mathf.Deg2Rad; // we
var longStart : float = 0; // need
var longEnd : float = 360 * Mathf.Deg2Rad; // to render
private var angularQuantization : float = 0.1; // attempt to "stabilize" angles
// performance
private var worstTime = 0.0;
function Start(){
UpdateGridCenter();
BuildMesh();
GenerateHeightmap();
}
function UpdateGridCenter() {
if(patchFocus){
minGridAngleRadians = minGridAngle * Mathf.Deg2Rad;
var g = patchFocus.position - transform.position;
var r = g.magnitude > outerRadius * 1.05 ? innerRadius / g.magnitude : innerRadius / (outerRadius * 1.05);
var a = Mathf.Acos( r );
g.Normalize();
g = g * innerRadius;
if( (g - gridCenter).magnitude > updateOffsetThreshold || Mathf.Abs(a - gridAngle) > updateOffsetThreshold * Mathf.Deg2Rad ){
gridDirty = true;
gridAngle = Mathf.Round(a / angularQuantization) * angularQuantization;
gridCenter = g;
g.Normalize();
latitude = Mathf.Round(Mathf.Asin(g.y)/angularQuantization) * angularQuantization;
g.y = 0;
g.Normalize();
longitude = g.z < 0 ? Mathf.PI - Mathf.Asin(g.x / g.magnitude) : Mathf.Asin(g.x / g.magnitude);
longitude = Mathf.Round((longitude)/angularQuantization) * angularQuantization;
latStart = Mathf.Clamp(latitude - gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
latEnd = Mathf.Clamp(latitude + gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
if(Mathf.Abs(latitude) + gridAngle > Mathf.PI * 0.5){
longStart = longitude - Mathf.PI;
longEnd = longitude + Mathf.PI;
} else {
longStart = longitude - gridAngle - Mathf.Abs(latitude);
longEnd = longitude + gridAngle + Mathf.Abs(latitude);
}
}
}
}
function OnGUI(){
if( showUI ){
GUI.Label (Rect (10, 10, 250, 20), "Dynamic Planet v0.1 ©2008 Tonio Loewald" );
if( Time.deltaTime > worstTime ){
worstTime = Time.deltaTime;
}
var fps = Mathf.Round(1.0 / worstTime).ToString();
GUI.Label (Rect (10, 30, 100, 20), "Min FPS: " + fps );
if ( GUI.Button (Rect (120, 30, 50, 20), "Reset" ) ){
worstTime = 0;
}
}
}
function Update(){
UpdateGridCenter();
if( gridDirty ){
GenerateHeightmap();
gridDirty = false;
}
}
function BuildMesh(){
// Create the game object containing the renderer
gameObject.AddComponent(MeshFilter);
gameObject.AddComponent("MeshRenderer");
if (material)
renderer.material = material;
else
renderer.material.color = Color.white;
// Retrieve a mesh instance
mesh = GetComponent(MeshFilter).mesh;
}
function GenerateHeightmap() {
// Build vertices and UVs
var vertices = new Vector3[xRes * yRes];
var uv = new Vector2[xRes * yRes];
var tangents = new Vector4[xRes * yRes];
// Cached uv coords (in 0..1)
var sx : float = 0;
var sy : float = 0;
// Cached uv coords (in texture dimension) for texture lookups, etc.
var u : int = 0;
var v : int = 0;
var pixelHeight : float;
var vertex : Vector3;
var vertexL : Vector3;
var vertexR : Vector3;
// array element
var i : int = 0;
var y : int = 0;
var x : int = 0;
var latitude : float;
var latInterval : float = (latEnd - latStart) / (yRes - 1);
var longitude : float;
var longInterval : float = (longEnd - longStart) / (xRes - 1);
var ringRadius : float;
var ringY : float;
var maxHeight : float = outerRadius - innerRadius;
for (y = 0; y < yRes; y++){
latitude = latStart + y * latInterval;
ringRadius = Mathf.Cos(latitude);
ringY = Mathf.Sin(latitude);
sy = latitude / Mathf.PI + 0.5;
for (x = 0; x < xRes; x++){
longitude = longStart + x * longInterval;
i = y * xRes + x;
sx = longitude / Mathf.PI * 0.5 + Mathf.PI * 2.0;
u = Mathf.Floor(sx * heightMap.width) % heightMap.width;
v = Mathf.Floor(sy * heightMap.height) % heightMap.height;
pixelHeight = heightMap.GetPixel(u, v).grayscale;
if( detailMap ){
u = Mathf.Floor(sx * detailMap.width * detailMapScale);
v = Mathf.Floor(sy * detailMap.height * detailMapScale);
pixelHeight += detailMap.GetPixel(u, v).grayscale * detailMapHeight;
}
vertex = Vector3(ringRadius * Mathf.Sin(longitude), ringY, ringRadius * Mathf.Cos(longitude));
vertices[i] = vertex * (innerRadius + pixelHeight * maxHeight); // Vector3.Scale(size, vertex);
if( textureIsHeightField ){
uv[i] = Vector2((sx + sy) * textureScale, pixelHeight);
} else {
uv[i] = Vector2(sx * textureScale, sy * textureScale);
}
}
}
for (y = 0; y < yRes; y++){
for (x = 0; x < xRes; x++){
// Calculate tangent vector: a vector that goes from previous vertex
// to next along X direction. We need tangents if we intend to
// use bumpmap shaders on the mesh.
i = y * xRes + x;
vertexL = x > 0 ? vertices[i-1] : vertices[i];
vertexR = x < xRes - 1 ? vertices[i+1] : vertices[i];
var tan = (vertexR - vertexL).normalized;
tangents[i] = Vector4( tan.x, tan.y, tan.z, 1.0 );
}
}
// Assign them to the mesh
mesh.vertices = vertices;
mesh.uv = uv;
// Build triangle indices: 3 indices into vertex array for each triangle
var triangles = new int[(yRes - 1) * (xRes - 1) * 6];
i = 0;
for (y = 0; y < yRes - 1; y++){
for (x = 0; x < xRes - 1; x++){
// For each grid cell output two triangles
triangles[i++] = (y * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x;
triangles[i++] = (y * xRes) + x;
triangles[i++] = (y * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x;
}
}
// And assign them to the mesh
mesh.triangles = triangles;
mesh.RecalculateBounds(); // fixes the problem
// Auto-calculate vertex normals from the mesh
mesh.RecalculateNormals();
// Assign tangents after recalculating normals
mesh.tangents = tangents;
if(!gameObject.GetComponent(MeshCollider)){
gameObject.AddComponent(MeshCollider);
}
gameObject.GetComponent(MeshCollider).sharedMesh = mesh;
}
// Draws a bounding box around where the terrain will end up.
function OnDrawGizmos (){
Gizmos.color = Color(0, 1, 1, 0.4);
Gizmos.DrawWireSphere (transform.position, innerRadius);
Gizmos.DrawWireSphere (transform.position, outerRadius);
if(patchFocus){
Gizmos.color = Color(1, 0, 0, 0.6);
UpdateGridCenter();
var d = Mathf.Sin( gridAngle ) * innerRadius;
Gizmos.DrawWireSphere (transform.TransformPoint(gridCenter), d);
}
}
// Feel free to use this code! (it even works now!)
var heightMap : Texture2D; // determines overal topography
var detailMap : Texture2D; // adds extra detail -- optional
var detailMapScale : float = 10;
var detailMapHeight : float = 0.2;
var material : Material;
var innerRadius : float = 400;
var outerRadius : float = 420; // determines maximum "height"
var patchFocus : Transform; // object whose POV determines portion of mesh to render
var minGridAngle : float = 1.0;
var xRes : int = 32; // mesh budget
var yRes : int = 16; // for rendering
var textureScale : float = 10; // number of times the material will be repeated if not a heightField
var textureIsHeightField : boolean = true; // material simply treated as vertical color bar
var updateOffsetThreshold : float = 2.0; // how far patchFocus has to move to force a redraw (also angular change that will force a redraw)
var showUI : boolean = false; // shows a simple UI to see performance impact
// private (or, it will be once I'm done debugging)
private var mesh : Mesh;
private var xGridSize : float;
private var yGridSize : float;
var gridCenter : Vector3;
var gridAngle : float;
private var gridDirty : boolean = true;
var latitude : float; // center of area
var longitude : float; // we need to render
var latStart : float = -90 * Mathf.Deg2Rad; // area
var latEnd : float = 90 * Mathf.Deg2Rad; // we
var longStart : float = 0; // need
var longEnd : float = 360 * Mathf.Deg2Rad; // to render
private var angularQuantization : float = 0.1; // attempt to "stabilize" angles
// performance
private var worstTime = 0.0;
function Start(){
UpdateGridCenter();
BuildMesh();
GenerateHeightmap();
}
function UpdateGridCenter() {
if(patchFocus){
minGridAngleRadians = minGridAngle * Mathf.Deg2Rad;
var g = patchFocus.position - transform.position;
var r = g.magnitude > outerRadius * 1.05 ? innerRadius / g.magnitude : innerRadius / (outerRadius * 1.05);
var a = Mathf.Acos( r );
g.Normalize();
g = g * innerRadius;
if( (g - gridCenter).magnitude > updateOffsetThreshold || Mathf.Abs(a - gridAngle) > updateOffsetThreshold * Mathf.Deg2Rad ){
gridDirty = true;
gridAngle = Mathf.Round(a / angularQuantization) * angularQuantization;
gridCenter = g;
g.Normalize();
latitude = Mathf.Round(Mathf.Asin(g.y)/angularQuantization) * angularQuantization;
g.y = 0;
g.Normalize();
longitude = g.z < 0 ? Mathf.PI - Mathf.Asin(g.x / g.magnitude) : Mathf.Asin(g.x / g.magnitude);
longitude = Mathf.Round((longitude)/angularQuantization) * angularQuantization;
latStart = Mathf.Clamp(latitude - gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
latEnd = Mathf.Clamp(latitude + gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
if(Mathf.Abs(latitude) + gridAngle > Mathf.PI * 0.5){
longStart = longitude - Mathf.PI;
longEnd = longitude + Mathf.PI;
} else {
longStart = longitude - gridAngle - Mathf.Abs(latitude);
longEnd = longitude + gridAngle + Mathf.Abs(latitude);
}
}
}
}
function OnGUI(){
if( showUI ){
GUI.Label (Rect (10, 10, 250, 20), "Dynamic Planet v0.1 ©2008 Tonio Loewald" );
if( Time.deltaTime > worstTime ){
worstTime = Time.deltaTime;
}
var fps = Mathf.Round(1.0 / worstTime).ToString();
GUI.Label (Rect (10, 30, 100, 20), "Min FPS: " + fps );
if ( GUI.Button (Rect (120, 30, 50, 20), "Reset" ) ){
worstTime = 0;
}
}
}
function Update(){
UpdateGridCenter();
if( gridDirty ){
GenerateHeightmap();
gridDirty = false;
}
}
function BuildMesh(){
// Create the game object containing the renderer
gameObject.AddComponent(MeshFilter);
gameObject.AddComponent("MeshRenderer");
if (material)
renderer.material = material;
else
renderer.material.color = Color.white;
// Retrieve a mesh instance
mesh = GetComponent(MeshFilter).mesh;
}
function GenerateHeightmap() {
// Build vertices and UVs
var vertices = new Vector3[xRes * yRes];
var uv = new Vector2[xRes * yRes];
var tangents = new Vector4[xRes * yRes];
// Cached uv coords (in 0..1)
var sx : float = 0;
var sy : float = 0;
// Cached uv coords (in texture dimension) for texture lookups, etc.
var u : int = 0;
var v : int = 0;
var pixelHeight : float;
var vertex : Vector3;
var vertexL : Vector3;
var vertexR : Vector3;
// array element
var i : int = 0;
var y : int = 0;
var x : int = 0;
var latitude : float;
var latInterval : float = (latEnd - latStart) / (yRes - 1);
var longitude : float;
var longInterval : float = (longEnd - longStart) / (xRes - 1);
var ringRadius : float;
var ringY : float;
var maxHeight : float = outerRadius - innerRadius;
for (y = 0; y < yRes; y++){
latitude = latStart + y * latInterval;
ringRadius = Mathf.Cos(latitude);
ringY = Mathf.Sin(latitude);
sy = latitude / Mathf.PI + 0.5;
for (x = 0; x < xRes; x++){
longitude = longStart + x * longInterval;
i = y * xRes + x;
sx = longitude / Mathf.PI * 0.5 + Mathf.PI * 2.0;
u = Mathf.Floor(sx * heightMap.width) % heightMap.width;
v = Mathf.Floor(sy * heightMap.height) % heightMap.height;
pixelHeight = heightMap.GetPixel(u, v).grayscale;
if( detailMap ){
u = Mathf.Floor(sx * detailMap.width * detailMapScale);
v = Mathf.Floor(sy * detailMap.height * detailMapScale);
pixelHeight += detailMap.GetPixel(u, v).grayscale * detailMapHeight;
}
vertex = Vector3(ringRadius * Mathf.Sin(longitude), ringY, ringRadius * Mathf.Cos(longitude));
vertices[i] = vertex * (innerRadius + pixelHeight * maxHeight); // Vector3.Scale(size, vertex);
if( textureIsHeightField ){
uv[i] = Vector2((sx + sy) * textureScale, pixelHeight);
} else {
uv[i] = Vector2(sx * textureScale, sy * textureScale);
}
}
}
for (y = 0; y < yRes; y++){
for (x = 0; x < xRes; x++){
// Calculate tangent vector: a vector that goes from previous vertex
// to next along X direction. We need tangents if we intend to
// use bumpmap shaders on the mesh.
i = y * xRes + x;
vertexL = x > 0 ? vertices[i-1] : vertices[i];
vertexR = x < xRes - 1 ? vertices[i+1] : vertices[i];
var tan = (vertexR - vertexL).normalized;
tangents[i] = Vector4( tan.x, tan.y, tan.z, 1.0 );
}
}
// Assign them to the mesh
mesh.vertices = vertices;
mesh.uv = uv;
// Build triangle indices: 3 indices into vertex array for each triangle
var triangles = new int[(yRes - 1) * (xRes - 1) * 6];
i = 0;
for (y = 0; y < yRes - 1; y++){
for (x = 0; x < xRes - 1; x++){
// For each grid cell output two triangles
triangles[i++] = (y * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x;
triangles[i++] = (y * xRes) + x;
triangles[i++] = (y * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x + 1;
triangles[i++] = ((y+1) * xRes) + x;
}
}
// And assign them to the mesh
mesh.triangles = triangles;
mesh.RecalculateBounds(); // fixes the problem
// Auto-calculate vertex normals from the mesh
mesh.RecalculateNormals();
// Assign tangents after recalculating normals
mesh.tangents = tangents;
if(!gameObject.GetComponent(MeshCollider)){
gameObject.AddComponent(MeshCollider);
}
gameObject.GetComponent(MeshCollider).sharedMesh = mesh;
}
// Draws a bounding box around where the terrain will end up.
function OnDrawGizmos (){
Gizmos.color = Color(0, 1, 1, 0.4);
Gizmos.DrawWireSphere (transform.position, innerRadius);
Gizmos.DrawWireSphere (transform.position, outerRadius);
if(patchFocus){
Gizmos.color = Color(1, 0, 0, 0.6);
UpdateGridCenter();
var d = Mathf.Sin( gridAngle ) * innerRadius;
Gizmos.DrawWireSphere (transform.TransformPoint(gridCenter), d);
}
}
HTML код для вашего блога :
Пакадж сценки