// Galaxy Renderer.lmc // Copyright (c) 2007 by George Moromisato. All Rights Reserved. { name: "Galaxy Renderer 1.0" desc: "Luminous program for rendering galaxies." version: 3 parameters: [ { name: "Mode" param: "renderMode" type: "choice" default: "draft" choices: [["draft", "Draft"], ["highQuality", "High-Quality"]] }, { name: "Width" param: "canvasWidth" type: "integer" default: 256 }, { name: "Height" param: "canvasHeight" type: "integer" default: 256 }, { name: "View Angle" param: "viewAngle" type: "integer" default: 90 }, { name: "View Distance" param: "cameraDistance" type: "integer" default: 120 }, { name: "Nucleus Size" param: "nucleusSize" type: "float" default: "10.0" }, { name: "Disc Size" param: "discSize" type: "float" default: "40.0" }, { name: "No. of Major Arms" param: "armCount" type: "integer" default: 2 }, { name: "Major Arm Length" param: "armLength" type: "float" default: "50.0" }, { name: "Major Arm Width" param: "armWidth" type: "float" default: "10.0" }, { name: "Major Arm Brightness" param: "armBrightness" type: "float" default: "1.0" }, { name: "Major Arm Dust" param: "armDust" type: "float" default: "3.0" }, { name: "No. of Minor Arms" param: "minorArmCount" type: "integer" default: 6 }, { name: "No. of Dark Arms" param: "darkArmCount" type: "integer" default: 7 }, { name: "Nucleus Color" param: "nucleusColor" type: "color" default: [255, 198, 111] }, { name: "Arm Color" param: "armColor" type: "color" default: [210, 247, 255] } ] renderer: Code { var scene; var camera; var PI; function OnInitialize () { var i; // Create the scene and cameras PrepareScene(); // Palette var nucleusPalette = CreatePalette(); AddPaletteColor(nucleusPalette, nucleusColor); AddPaletteGradient(nucleusPalette, Color(255, 255, 255), 32); var armPalette = CreatePalette(); AddPaletteColor(armPalette, armColor); AddPaletteGradient(armPalette, Color(255, 255, 255), 32); // Create some shaders var nucleusShader = CreateObj("CloudShader"); SetObjParam(nucleusShader, "Palette", nucleusPalette); SetObjParam(nucleusShader, "RadialScaling", 0.01); SetObjParam(nucleusShader, "DensityFactor", 2.0); var discShader = CreateObj("TurbulenceShader"); SetObjParam(discShader, "Style", "Plain"); SetObjParam(discShader, "Palette", armPalette); SetObjParam(discShader, "RadialScaling", 0.15); SetObjParam(discShader, "DensityFactor", 1.0); var spiralFilter = CreateObj("SpiralFilter"); SetObjParam(spiralFilter, "Shader", discShader); SetObjParam(spiralFilter, "Pitch", 45); SetObjParam(spiralFilter, "Scale", 1.0); var discStarShader = CreateObj("StarfieldFilter"); SetObjParam(discStarShader, "Shader", spiralFilter); SetObjParam(discStarShader, "Resolution", canvasWidth / 50); // Create nucleus if (nucleusSize > 0.0) { var nucleusSizeAdj = nucleusSize / 10.0; var halo = CreateObj("GlowSphere"); SetObjParam(halo, "Scale", nucleusSizeAdj, nucleusSizeAdj, nucleusSizeAdj * 0.5); SetObjParam(halo, "Diameters", [0.0, 1.5, 10.0, 40.0]); SetObjParam(halo, "Densities", [0.0, 0.05, 0.0125, 0.0]); SetObjParam(halo, "Luminosity", 1.0); SetObjParam(halo, "Shader", nucleusShader); var nucleus2 = CreateObj("GlowSphere"); SetObjParam(nucleus2, "Scale", nucleusSizeAdj, nucleusSizeAdj, nucleusSizeAdj * 0.2); SetObjParam(nucleus2, "Diameters", [0.0, 20.0]); SetObjParam(nucleus2, "Densities", [0.25, 0.0]); SetObjParam(nucleus2, "Luminosity", 1.0); SetObjParam(nucleus2, "Shader", nucleusShader); if (renderMode == "highQuality") { var nucleus3 = CreateObj("GlowSphere"); SetObjParam(nucleus3, "Scale", nucleusSizeAdj, nucleusSizeAdj, nucleusSizeAdj * 0.5); SetObjParam(nucleus3, "Diameters", [0.0, 4.0]); SetObjParam(nucleus3, "Densities", [0.5, 0.0]); SetObjParam(nucleus3, "Luminosity", 2.0); SetObjParam(nucleus3, "Shader", nucleusShader); } } // Create the disc if (discSize > 0.0) { var discSizeAdj = discSize / 40.0; if (renderMode == "highQuality") { var disc = CreateObj("GlowSphere"); SetObjParam(disc, "Scale", discSizeAdj, discSizeAdj, discSizeAdj * 0.15); SetObjParam(disc, "Diameters", [0.0, 4.0, 20.0, 80.0]); SetObjParam(disc, "Densities", [5.0, 2.0, 1.5, 0.0]); SetObjParam(disc, "Luminosity", 1.0); SetObjParam(disc, "Shader", discStarShader); } var disc2 = CreateObj("GlowSphere"); SetObjParam(disc2, "Scale", discSizeAdj, discSizeAdj, discSizeAdj * 0.08); SetObjParam(disc2, "Diameters", [0.0, 4.0, 20.0, 80.0]); SetObjParam(disc2, "Densities", [0.5, 0.1, 0.05, 0.0]); SetObjParam(disc2, "Luminosity", 1.0); SetObjParam(disc2, "Shader", spiralFilter); } // Create spiral arms var armShader = CreateObj("TurbulenceShader"); SetObjParam(armShader, "Style", "Plain"); SetObjParam(armShader, "Palette", armPalette); SetObjParam(armShader, "RadialScaling", 0.5); SetObjParam(armShader, "DensityFactor", 2.0); var starShader = CreateObj("StarfieldFilter"); SetObjParam(starShader, "Shader", armShader); SetObjParam(starShader, "Resolution", canvasWidth / 50); var armShader2 = CreateObj("TurbulenceShader"); SetObjParam(armShader2, "Style", "Plain"); SetObjParam(armShader2, "Palette", armPalette); SetObjParam(armShader2, "RadialScaling", 0.25); SetObjParam(armShader2, "DensityFactor", 0.4 * armBrightness); var armShader3 = CreateObj("TurbulenceShader"); SetObjParam(armShader3, "Style", "Plain"); SetObjParam(armShader3, "Palette", armPalette); SetObjParam(armShader3, "RadialScaling", 0.5); SetObjParam(armShader3, "DensityFactor", 0.3); var dustShaderTexture = CreateObj("TurbulenceShader"); SetObjParam(dustShaderTexture, "Style", "Plain"); SetObjParam(dustShaderTexture, "RadialScaling", 0.3); SetObjParam(dustShaderTexture, "DensityFactor", 0.5 * armDust); SetObjParam(dustShaderTexture, "MinSlice", 0.5); SetObjParam(dustShaderTexture, "MaxSlice", 0.55); var dustShader = CreateObj("SpiralFilter"); SetObjParam(dustShader, "Shader", dustShaderTexture); SetObjParam(dustShader, "Pitch", 45); SetObjParam(dustShader, "Scale", 1.0); var dustShader2 = CreateObj("TurbulenceShader"); SetObjParam(dustShader2, "Style", "Plain"); SetObjParam(dustShader2, "RadialScaling", 1.0); SetObjParam(dustShader2, "DensityFactor", 0.25 * armDust); SetObjParam(dustShader2, "MinSlice", 0.5); SetObjParam(dustShader2, "MaxSlice", 0.6); var dustShader3Texture = CreateObj("TurbulenceShader"); SetObjParam(dustShader3Texture, "Style", "Plain"); SetObjParam(dustShader3Texture, "RadialScaling", 1.0); SetObjParam(dustShader3Texture, "DensityFactor", 0.75 * armDust); SetObjParam(dustShader3Texture, "MinSlice", 0.5); SetObjParam(dustShader3Texture, "MaxSlice", 0.55); var dustShader3 = CreateObj("SpiralFilter"); SetObjParam(dustShader3, "Shader", dustShaderTexture); SetObjParam(dustShader3, "Pitch", 45); SetObjParam(dustShader3, "Scale", 1.0); // Create the major arms i = 0; while (i < armCount) { var angle = 2.0 * i * PI / armCount; var length = floor(10.0 + armLength / 2.0); var widthAdj = armWidth / 10.0; if (renderMode == "highQuality") { var spiral1 = CreateObj("PolyLathe"); SetObjParam(spiral1, "Scale", 1.0, 0.4, 1.0); SetObjParam(spiral1, "Rotation", 90, 0, 0); SetObjParam(spiral1, "Path", GenerateSpiralPath(angle, length + 1)); SetObjParam(spiral1, "Diameters", GenerateDiameters(length + 1, widthAdj * 4.0, widthAdj * 12.0)); SetObjParam(spiral1, "EdgeFade", 3.0); SetObjParam(spiral1, "Shader", starShader); SetObjParam(spiral1, "Luminosity", 1.0); } var spiral2 = CreateObj("PolyLathe"); SetObjParam(spiral2, "Scale", 1.0, 0.3, 1.0); SetObjParam(spiral2, "Rotation", 90, 0, 0); SetObjParam(spiral2, "Path", GenerateSpiralPath(angle, length)); SetObjParam(spiral2, "Diameters", GenerateDiameters(length, widthAdj * 3.0, widthAdj * 8.5)); SetObjParam(spiral2, "EdgeFade", 3.0); SetObjParam(spiral2, "Shader", armShader2); SetObjParam(spiral2, "Luminosity", 1.0); if (renderMode == "highQuality") { var dustLane = CreateObj("PolyLathe"); SetObjParam(dustLane, "Scale", 1.0, 0.25, 1.0); SetObjParam(dustLane, "Rotation", 90, 0, 0); SetObjParam(dustLane, "Path", GenerateSpiralPath(angle, length + 2)); SetObjParam(dustLane, "Diameters", GenerateDiameters(length + 2, widthAdj * 2.0, widthAdj * 6.0)); SetObjParam(dustLane, "EdgeFade", 4.5); SetObjParam(dustLane, "Shader", dustShader); SetObjParam(dustLane, "Luminosity", 0.0); var dustLane2 = CreateObj("PolyLathe"); SetObjParam(dustLane2, "Scale", 1.0, 1.0, 1.0); SetObjParam(dustLane2, "Rotation", 90, 0, 0); SetObjParam(dustLane2, "Path", GenerateSpiralPath(angle, length + 1)); SetObjParam(dustLane2, "Diameters", GenerateDiameters(length + 1, widthAdj * 1.5, widthAdj * 1.5)); SetObjParam(dustLane2, "EdgeFade", 0.25); SetObjParam(dustLane2, "Shader", dustShader3); SetObjParam(dustLane2, "Luminosity", 0.0); } i = i + 1; } // Create some light arms var startAngle = (PI / 17.0); i = 0; while (i < minorArmCount) { angle = startAngle + (2.0 * i * PI / minorArmCount); length = random(29, 35); dustLane = CreateObj("PolyLathe"); SetObjParam(dustLane, "Scale", 1.0, 0.5, 1.0); SetObjParam(dustLane, "Rotation", 90, 0, 0); SetObjParam(dustLane, "Path", GenerateSpiralPath(angle, length)); SetObjParam(dustLane, "Diameters", GenerateDiameters(length, 1.0, 5.5)); SetObjParam(dustLane, "EdgeFade", 4.0); SetObjParam(dustLane, "Shader", armShader3); SetObjParam(dustLane, "Luminosity", 1.0); i = i + 1; } // Create some dark arms startAngle = startAngle + (PI / 11.0); i = 0; while (i < darkArmCount) { angle = startAngle + (2.0 * i * PI / darkArmCount); length = random(30, 35); dustLane = CreateObj("PolyLathe"); SetObjParam(dustLane, "Scale", 1.0, 0.5, 1.0); SetObjParam(dustLane, "Rotation", 90, 0, 0); SetObjParam(dustLane, "Path", GenerateSpiralPath(angle, length)); SetObjParam(dustLane, "Diameters", GenerateDiameters(length, 1.2, 3.5)); SetObjParam(dustLane, "EdgeFade", 2.0); SetObjParam(dustLane, "Shader", dustShader2); SetObjParam(dustLane, "Luminosity", 0.0); i = i + 1; } } function OnRender (frame) { SetCanvasSize(canvasWidth, canvasHeight); FillRect(GetCanvas(frame), 0, 0, canvasWidth, canvasHeight, Color(0, 0, 0)); RayTraceScene(scene, GetCanvas(frame), camera); } function PrepareScene () { PI = 3.14159265; // Create the scene scene = CreateScene(); SetSceneTransparentBackground(True); if (renderMode == "draft") SetSceneParam("MarchStep", 0.05); else SetSceneParam("MarchStep", 0.05); // Position the camera at the appropriate view angle var cameraAngle; if (viewAngle < 0) cameraAngle = 0; else if (viewAngle > 90) cameraAngle = PI / 2.0; else cameraAngle = PI * viewAngle / 180.0; camera = CreateCamera(0, -(cameraDistance * cos(cameraAngle)), (cameraDistance * sin(cameraAngle))); SetObjParam(camera, "LookAt", 0, 0, 0); SetObjParam(camera, "Up", 0, 0, 1); SetObjParam(camera, "ViewAngle", 30); //CreatePointLight(-5, -5, 10, 1.0, Color(255, 255, 255)); } function GenerateDiameters (diamCount, minDiameter, maxDiameter) { var diameters; var midPoint = 3 * diamCount / 4; var taperPoint = diamCount - 3; var range = maxDiameter - minDiameter; var taperDiameter = maxDiameter - (((taperPoint - midPoint) * range) / (diamCount - midPoint)); var i = 0; while (i < diamCount) { if (i <= midPoint) diameters[i] = ((i * maxDiameter) / midPoint); else if (i >= taperPoint) diameters[i] = (diamCount - (i + 1)) * taperDiameter / (diamCount - taperPoint); else diameters[i] = maxDiameter - (((i - midPoint) * range) / (diamCount - midPoint)); i = i + 1; } return diameters; } function GenerateSpiralPath (initialAngle, pathCount) { var path; var angle = initialAngle; var angleInc = 3.14159265 / 10.0; var radius = 0.05; var radiusFactor = 1.18; var vector = [0.0, 0.0, 0.0]; path[0] = vector; var i = 1; while (i < pathCount) { vector = [vector[0] - radius * sin(angle), vector[1], vector[2] + radius * cos(angle)]; path[i] = vector; angle = angle + angleInc; radius = radius * radiusFactor; i = i + 1; } return path; } } }