diff --git a/Assets/envmap_brdf.png b/Assets/brdf.png similarity index 100% rename from Assets/envmap_brdf.png rename to Assets/brdf.png diff --git a/Assets/checker.png b/Assets/checker.png deleted file mode 100644 index 3c865505..00000000 Binary files a/Assets/checker.png and /dev/null differ diff --git a/Assets/checker_r.png b/Assets/checker_r.png deleted file mode 100644 index 072027ef..00000000 Binary files a/Assets/checker_r.png and /dev/null differ diff --git a/Assets/DroidSans.ttf b/Assets/droid_sans.ttf similarity index 100% rename from Assets/DroidSans.ttf rename to Assets/droid_sans.ttf diff --git a/Assets/noise.png b/Assets/noise.png deleted file mode 100644 index 84e0e668..00000000 Binary files a/Assets/noise.png and /dev/null differ diff --git a/Assets/SMAAArea.png b/Assets/smaa_area.png similarity index 100% rename from Assets/SMAAArea.png rename to Assets/smaa_area.png diff --git a/Assets/SMAASearch.png b/Assets/smaa_search.png similarity index 100% rename from Assets/SMAASearch.png rename to Assets/smaa_search.png diff --git a/Sources/cycles/Root.hx b/Sources/armory/Root.hx similarity index 69% rename from Sources/cycles/Root.hx rename to Sources/armory/Root.hx index 3d25e5d8..33f74e40 100644 --- a/Sources/cycles/Root.hx +++ b/Sources/armory/Root.hx @@ -1,12 +1,12 @@ -package cycles; +package armory; -import lue.App; -import lue.Eg; -import lue.node.RootNode; -import lue.node.CameraNode; -import lue.resource.SceneFormat; -import lue.resource.Resource; -import cycles.trait.PhysicsWorld; +import iron.App; +import iron.Eg; +import iron.node.RootNode; +import iron.node.CameraNode; +import iron.resource.SceneFormat; +import iron.resource.Resource; +import armory.trait.internal.PhysicsWorld; class Root { @@ -28,7 +28,7 @@ class Root { physics = new PhysicsWorld(); Eg.addNodeTrait(sceneNode, physics); - App.requestRender(render); + App.notifyOnRender(render); } function render(g:kha.graphics4.Graphics) { diff --git a/Sources/cycles/node/BoolNode.hx b/Sources/armory/node/BoolNode.hx similarity index 90% rename from Sources/cycles/node/BoolNode.hx rename to Sources/armory/node/BoolNode.hx index 1edbb978..d12bde47 100644 --- a/Sources/cycles/node/BoolNode.hx +++ b/Sources/armory/node/BoolNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class BoolNode extends Node { diff --git a/Sources/cycles/node/FloatNode.hx b/Sources/armory/node/FloatNode.hx similarity index 90% rename from Sources/cycles/node/FloatNode.hx rename to Sources/armory/node/FloatNode.hx index cf313c80..223eefce 100644 --- a/Sources/cycles/node/FloatNode.hx +++ b/Sources/armory/node/FloatNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class FloatNode extends Node { diff --git a/Sources/cycles/node/IntNode.hx b/Sources/armory/node/IntNode.hx similarity index 89% rename from Sources/cycles/node/IntNode.hx rename to Sources/armory/node/IntNode.hx index 12028dc6..3e7a8afd 100644 --- a/Sources/cycles/node/IntNode.hx +++ b/Sources/armory/node/IntNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class IntNode extends Node { diff --git a/Sources/cycles/node/Node.hx b/Sources/armory/node/Node.hx similarity index 87% rename from Sources/cycles/node/Node.hx rename to Sources/armory/node/Node.hx index 75a11414..6d30a877 100644 --- a/Sources/cycles/node/Node.hx +++ b/Sources/armory/node/Node.hx @@ -1,6 +1,6 @@ -package cycles.node; +package armory.node; -import cycles.trait.NodeExecutor; +import armory.trait.internal.NodeExecutor; class Node { diff --git a/Sources/cycles/node/ScaleValueNode.hx b/Sources/armory/node/ScaleValueNode.hx similarity index 95% rename from Sources/cycles/node/ScaleValueNode.hx rename to Sources/armory/node/ScaleValueNode.hx index 80ad78fb..76ec72d9 100644 --- a/Sources/cycles/node/ScaleValueNode.hx +++ b/Sources/armory/node/ScaleValueNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class ScaleValueNode extends FloatNode { diff --git a/Sources/cycles/node/SineNode.hx b/Sources/armory/node/SineNode.hx similarity index 94% rename from Sources/cycles/node/SineNode.hx rename to Sources/armory/node/SineNode.hx index 4c0fbb98..2922a57a 100644 --- a/Sources/cycles/node/SineNode.hx +++ b/Sources/armory/node/SineNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class SineNode extends FloatNode { diff --git a/Sources/cycles/node/StringNode.hx b/Sources/armory/node/StringNode.hx similarity index 90% rename from Sources/cycles/node/StringNode.hx rename to Sources/armory/node/StringNode.hx index 5a686e07..c84a5604 100644 --- a/Sources/cycles/node/StringNode.hx +++ b/Sources/armory/node/StringNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class StringNode extends Node { diff --git a/Sources/cycles/node/TimeNode.hx b/Sources/armory/node/TimeNode.hx similarity index 94% rename from Sources/cycles/node/TimeNode.hx rename to Sources/armory/node/TimeNode.hx index 9d3d5310..1833b626 100644 --- a/Sources/cycles/node/TimeNode.hx +++ b/Sources/armory/node/TimeNode.hx @@ -1,6 +1,6 @@ -package cycles.node; +package armory.node; -import cycles.trait.NodeExecutor; +import armory.trait.NodeExecutor; class TimeNode extends FloatNode { @@ -26,7 +26,7 @@ class TimeNode extends FloatNode { function update() { if (inputs[_enabled].b) { - f += lue.sys.Time.delta * inputs[_scale].f; + f += iron.sys.Time.delta * inputs[_scale].f; // Time out if (inputs[_stopTime].f > 0) { diff --git a/Sources/cycles/node/TransformNode.hx b/Sources/armory/node/TransformNode.hx similarity index 92% rename from Sources/cycles/node/TransformNode.hx rename to Sources/armory/node/TransformNode.hx index 723ce7aa..60b5c64e 100644 --- a/Sources/cycles/node/TransformNode.hx +++ b/Sources/armory/node/TransformNode.hx @@ -1,8 +1,8 @@ -package cycles.node; +package armory.node; -import lue.math.Mat4; -import lue.math.Vec4; -import lue.math.Quat; +import iron.math.Mat4; +import iron.math.Vec4; +import iron.math.Quat; class TransformNode extends Node { @@ -10,7 +10,7 @@ class TransformNode extends Node { public static inline var _rotation = 1; // Vector public static inline var _scale = 2; // Vector - public var transform:lue.node.Transform; + public var transform:iron.node.Transform; var matrix:Mat4; var pos:Vec4; diff --git a/Sources/cycles/node/VectorNode.hx b/Sources/armory/node/VectorNode.hx similarity index 95% rename from Sources/cycles/node/VectorNode.hx rename to Sources/armory/node/VectorNode.hx index 26faf1ef..f2298f51 100644 --- a/Sources/cycles/node/VectorNode.hx +++ b/Sources/armory/node/VectorNode.hx @@ -1,4 +1,4 @@ -package cycles.node; +package armory.node; class VectorNode extends Node { diff --git a/Sources/cycles/renderpipeline/FFT.hx b/Sources/armory/renderpipeline/FFT.hx similarity index 80% rename from Sources/cycles/renderpipeline/FFT.hx rename to Sources/armory/renderpipeline/FFT.hx index 43185fe4..b72c1047 100644 --- a/Sources/cycles/renderpipeline/FFT.hx +++ b/Sources/armory/renderpipeline/FFT.hx @@ -1,6 +1,6 @@ -package cycles.renderpipeline; +package armory.renderpipeline; -import lue.node.RenderPipeline; +import iron.node.RenderPath; class FFT { @@ -19,7 +19,7 @@ class FFT { // } // } - public static function run(pipe:RenderPipeline) { + public static function run(path:RenderPath) { } } diff --git a/Sources/cycles/renderpipeline/HosekWilkie.hx b/Sources/armory/renderpipeline/HosekWilkie.hx similarity index 97% rename from Sources/cycles/renderpipeline/HosekWilkie.hx rename to Sources/armory/renderpipeline/HosekWilkie.hx index a17d2101..d31f2d43 100644 --- a/Sources/cycles/renderpipeline/HosekWilkie.hx +++ b/Sources/armory/renderpipeline/HosekWilkie.hx @@ -1,11 +1,11 @@ // An Analytic Model for Full Spectral Sky-Dome Radiance // Lukas Hosek and Alexander Wilkie // Based on https://github.com/ddiakopoulos/sandbox -package cycles.renderpipeline; +package armory.renderpipeline; import kha.math.FastVector3; -import lue.node.RenderPipeline; -import lue.resource.WorldResource; +import iron.node.RenderPath; +import iron.resource.WorldResource; class HosekWilkieRadianceData { @@ -127,7 +127,7 @@ class HosekWilkie { HosekWilkie.recompute(sunPositionX, turbidity, albedo, 1.15); } - public static function run(pipe:RenderPipeline) { + public static function run(path:RenderPath) { // Set uniforms } } diff --git a/Sources/cycles/renderpipeline/HosekWilkieData.hx b/Sources/armory/renderpipeline/HosekWilkieData.hx similarity index 99% rename from Sources/cycles/renderpipeline/HosekWilkieData.hx rename to Sources/armory/renderpipeline/HosekWilkieData.hx index ea5b8e00..ae42ac72 100644 --- a/Sources/cycles/renderpipeline/HosekWilkieData.hx +++ b/Sources/armory/renderpipeline/HosekWilkieData.hx @@ -97,7 +97,7 @@ This file contains the coefficient data for the RGB colour space version of the model. */ -package cycles.renderpipeline; +package armory.renderpipeline; class HosekWilkieData { diff --git a/Sources/cycles/renderpipeline/SMAAData.hx b/Sources/armory/renderpipeline/SMAAData.hx similarity index 99% rename from Sources/cycles/renderpipeline/SMAAData.hx rename to Sources/armory/renderpipeline/SMAAData.hx index 46e12aa0..3621c2dc 100644 --- a/Sources/cycles/renderpipeline/SMAAData.hx +++ b/Sources/armory/renderpipeline/SMAAData.hx @@ -36,7 +36,7 @@ // #define SEARCHTEX_PITCH SEARCHTEX_WIDTH // #define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH) -package cycles.renderpipeline; +package armory.renderpipeline; class SMAAAreaData { diff --git a/Sources/cycles/trait/ArcBallCamera.hx b/Sources/armory/trait/ArcBallCamera.hx similarity index 68% rename from Sources/cycles/trait/ArcBallCamera.hx rename to Sources/armory/trait/ArcBallCamera.hx index 2fec6d1e..11a598dc 100644 --- a/Sources/cycles/trait/ArcBallCamera.hx +++ b/Sources/armory/trait/ArcBallCamera.hx @@ -1,11 +1,11 @@ -package cycles.trait; +package armory.trait; -import lue.Trait; -import lue.sys.Input; -import lue.node.CameraNode; -import lue.node.RootNode; -import lue.math.Vec4; -import lue.math.Quat; +import iron.Trait; +import iron.sys.Input; +import iron.node.CameraNode; +import iron.node.RootNode; +import iron.math.Vec4; +import iron.math.Quat; class ArcBallCamera extends Trait { @@ -19,8 +19,8 @@ class ArcBallCamera extends Trait { origin = new Vec4(); - requestInit(init); - requestUpdate(update); + notifyOnInit(init); + notifyOnUpdate(update); } function init() { @@ -31,13 +31,13 @@ class ArcBallCamera extends Trait { q.inverse(q); var e = q.getEuler(); - pitchRad = lue.math.Math.degToRad(90) - e.x; + pitchRad = iron.math.Math.degToRad(90) - e.x; } function update() { if (Input.touch) { - var dist = lue.math.Math.distance3d(camera.transform.pos, origin); + var dist = iron.math.Math.distance3d(camera.transform.pos, origin); camera.move(camera.look(), dist); camera.rotate(camera.right(), pitchRad); diff --git a/Sources/cycles/trait/FirstPersonController.hx b/Sources/armory/trait/FirstPersonController.hx similarity index 89% rename from Sources/cycles/trait/FirstPersonController.hx rename to Sources/armory/trait/FirstPersonController.hx index 872bdf7b..0e9d60a6 100644 --- a/Sources/cycles/trait/FirstPersonController.hx +++ b/Sources/armory/trait/FirstPersonController.hx @@ -1,13 +1,13 @@ -package cycles.trait; +package armory.trait; -import lue.math.Mat4; -import lue.math.Vec4; -import lue.Trait; -import lue.sys.Input; -import lue.sys.Time; -import lue.node.Transform; -import lue.node.CameraNode; -import cycles.trait.RigidBody; +import iron.math.Mat4; +import iron.math.Vec4; +import iron.Trait; +import iron.sys.Input; +import iron.sys.Time; +import iron.node.Transform; +import iron.node.CameraNode; +import armory.trait.internal.RigidBody; class FirstPersonController extends Trait { @@ -28,15 +28,15 @@ class FirstPersonController extends Trait { public function new() { super(); - requestInit(init); - requestUpdate(update); + notifyOnInit(init); + notifyOnUpdate(update); kha.input.Keyboard.get().notify(onDown, onUp); } function init() { transform = node.transform; body = node.getTrait(RigidBody); - camera = lue.node.RootNode.cameras[0]; + camera = iron.node.RootNode.cameras[0]; } function onDown(key: kha.Key, char: String) { @@ -61,8 +61,8 @@ class FirstPersonController extends Trait { // Unlock // if (locked && - // Input.x > lue.App.w / 2 - 20 && Input.x < lue.App.w / 2 + 20 && - // Input.y > lue.App.h / 2 - 20 && Input.y < lue.App.h / 2 +20) { + // Input.x > iron.App.w / 2 - 20 && Input.x < iron.App.w / 2 + 20 && + // Input.y > iron.App.h / 2 - 20 && Input.y < iron.App.h / 2 +20) { // locked = false; // } diff --git a/Sources/cycles/trait/FlyCamera.hx b/Sources/armory/trait/FlyCamera.hx similarity index 60% rename from Sources/cycles/trait/FlyCamera.hx rename to Sources/armory/trait/FlyCamera.hx index 4e6f646c..3b3d73b0 100644 --- a/Sources/cycles/trait/FlyCamera.hx +++ b/Sources/armory/trait/FlyCamera.hx @@ -1,13 +1,13 @@ -package cycles.trait; +package armory.trait; import kha.Key; -import lue.Trait; -import lue.sys.Input; -import lue.sys.Time; -import lue.node.CameraNode; -import lue.node.RootNode; -import lue.math.Vec4; -import lue.math.Quat; +import iron.Trait; +import iron.sys.Input; +import iron.sys.Time; +import iron.node.CameraNode; +import iron.node.RootNode; +import iron.math.Vec4; +import iron.math.Quat; class FlyCamera extends Trait { @@ -27,9 +27,9 @@ class FlyCamera extends Trait { kha.input.Keyboard.get().notify(onKeyDown, onKeyUp); - requestInit(init); - requestUpdate(update); - requestRemove(removed); + notifyOnInit(init); + notifyOnUpdate(update); + notifyOnRemove(removed); } function removed() { @@ -44,7 +44,7 @@ class FlyCamera extends Trait { q.inverse(q); var e = q.getEuler(); - pitchRad = lue.math.Math.degToRad(90) - e.x; + pitchRad = iron.math.Math.degToRad(90) - e.x; } function update() { @@ -87,18 +87,18 @@ class FlyCamera extends Trait { else if (char == 'q') strafeForward = true; else if (char == 'e') strafeBackward = true; - // if (char == 'r') {lue.node.ModelNode._u1 += 0.01;trace("u1:", lue.node.ModelNode._u1);} - // else if (char == 'f') {lue.node.ModelNode._u1 -= 0.01;trace("u1:", lue.node.ModelNode._u1);} - // else if (char == 't') {lue.node.ModelNode._u2 += 0.01;trace("u2:", lue.node.ModelNode._u2);} - // else if (char == 'g') {lue.node.ModelNode._u2 -= 0.01;trace("u2:", lue.node.ModelNode._u2);} - // else if (char == 'y') {lue.node.ModelNode._u3 += 0.1;trace("u3:", lue.node.ModelNode._u3);} - // else if (char == 'h') {lue.node.ModelNode._u3 -= 0.1;trace("u3:", lue.node.ModelNode._u3);} - // else if (char == 'u') {lue.node.ModelNode._u4 += 0.1;trace("u4:", lue.node.ModelNode._u4);} - // else if (char == 'j') {lue.node.ModelNode._u4 -= 0.1;trace("u4:", lue.node.ModelNode._u4);} - // else if (char == 'i') {lue.node.ModelNode._u5 += 0.1;trace("u5:", lue.node.ModelNode._u5);} - // else if (char == 'k') {lue.node.ModelNode._u5 -= 0.1;trace("u5:", lue.node.ModelNode._u5);} - // else if (char == 'o') {lue.node.ModelNode._u6 += 0.005;trace("u6:", lue.node.ModelNode._u6);} - // else if (char == 'l') {lue.node.ModelNode._u6 -= 0.005;trace("u6:", lue.node.ModelNode._u6);} + // if (char == 'r') {iron.node.ModelNode._u1 += 0.01;trace("u1:", iron.node.ModelNode._u1);} + // else if (char == 'f') {iron.node.ModelNode._u1 -= 0.01;trace("u1:", iron.node.ModelNode._u1);} + // else if (char == 't') {iron.node.ModelNode._u2 += 0.01;trace("u2:", iron.node.ModelNode._u2);} + // else if (char == 'g') {iron.node.ModelNode._u2 -= 0.01;trace("u2:", iron.node.ModelNode._u2);} + // else if (char == 'y') {iron.node.ModelNode._u3 += 0.1;trace("u3:", iron.node.ModelNode._u3);} + // else if (char == 'h') {iron.node.ModelNode._u3 -= 0.1;trace("u3:", iron.node.ModelNode._u3);} + // else if (char == 'u') {iron.node.ModelNode._u4 += 0.1;trace("u4:", iron.node.ModelNode._u4);} + // else if (char == 'j') {iron.node.ModelNode._u4 -= 0.1;trace("u4:", iron.node.ModelNode._u4);} + // else if (char == 'i') {iron.node.ModelNode._u5 += 0.1;trace("u5:", iron.node.ModelNode._u5);} + // else if (char == 'k') {iron.node.ModelNode._u5 -= 0.1;trace("u5:", iron.node.ModelNode._u5);} + // else if (char == 'o') {iron.node.ModelNode._u6 += 0.005;trace("u6:", iron.node.ModelNode._u6);} + // else if (char == 'l') {iron.node.ModelNode._u6 -= 0.005;trace("u6:", iron.node.ModelNode._u6);} } function onKeyUp(key:kha.Key, char:String) { diff --git a/Sources/cycles/trait/PhysicsDrag.hx b/Sources/armory/trait/PhysicsDrag.hx similarity index 95% rename from Sources/cycles/trait/PhysicsDrag.hx rename to Sources/armory/trait/PhysicsDrag.hx index c8764ed6..7f89638a 100644 --- a/Sources/cycles/trait/PhysicsDrag.hx +++ b/Sources/armory/trait/PhysicsDrag.hx @@ -1,7 +1,9 @@ -package cycles.trait; +package armory.trait; -import lue.Trait; -import lue.sys.Input; +import iron.Trait; +import iron.sys.Input; +import armory.trait.internal.RigidBody; +import armory.trait.internal.PhysicsWorld; #if WITH_PHYSICS import haxebullet.Bullet; #end @@ -24,8 +26,8 @@ class PhysicsDrag extends Trait { public function new() { super(); - requestInit(init); - requestUpdate(update); + notifyOnInit(init); + notifyOnUpdate(update); } function init() { diff --git a/Sources/cycles/trait/VehicleBody.hx b/Sources/armory/trait/VehicleBody.hx similarity index 96% rename from Sources/cycles/trait/VehicleBody.hx rename to Sources/armory/trait/VehicleBody.hx index 4ee5e6d1..29880689 100644 --- a/Sources/cycles/trait/VehicleBody.hx +++ b/Sources/armory/trait/VehicleBody.hx @@ -1,10 +1,11 @@ -package cycles.trait; +package armory.trait; -import lue.Eg; -import lue.Trait; -import lue.node.RootNode; -import lue.node.CameraNode; -import lue.node.Transform; +import iron.Eg; +import iron.Trait; +import iron.node.RootNode; +import iron.node.CameraNode; +import iron.node.Transform; +import armory.trait.internal.PhysicsWorld; #if WITH_PHYSICS import haxebullet.Bullet; #end @@ -39,8 +40,8 @@ class VehicleBody extends Trait { wheelNames = [wheelName1, wheelName2, wheelName3, wheelName4]; - requestInit(init); - requestUpdate(update); + notifyOnInit(init); + notifyOnUpdate(update); kha.input.Keyboard.get().notify(onKeyDown, onKeyUp); } diff --git a/Sources/cycles/trait/VehicleWheel.hx b/Sources/armory/trait/VehicleWheel.hx similarity index 97% rename from Sources/cycles/trait/VehicleWheel.hx rename to Sources/armory/trait/VehicleWheel.hx index 310b1391..5ad80710 100644 --- a/Sources/cycles/trait/VehicleWheel.hx +++ b/Sources/armory/trait/VehicleWheel.hx @@ -1,6 +1,6 @@ -package cycles.trait; +package armory.trait; -import lue.Trait; +import iron.Trait; #if WITH_PHYSICS import haxebullet.Bullet; #end diff --git a/Sources/cycles/trait/Animation.hx b/Sources/armory/trait/internal/Animation.hx similarity index 78% rename from Sources/cycles/trait/Animation.hx rename to Sources/armory/trait/internal/Animation.hx index 02f2775c..58ee510d 100644 --- a/Sources/cycles/trait/Animation.hx +++ b/Sources/armory/trait/internal/Animation.hx @@ -1,9 +1,9 @@ -package cycles.trait; +package armory.trait.internal; -import lue.Trait; -import lue.Eg; -import lue.resource.Resource; -import lue.node.ModelNode; +import iron.Trait; +import iron.Eg; +import iron.resource.Resource; +import iron.node.ModelNode; class Animation extends Trait { @@ -22,8 +22,8 @@ class Animation extends Trait { this.starts = starts; this.ends = ends; - requestAdd(add); - requestUpdate(update); + notifyOnAdd(add); + notifyOnUpdate(update); } function add() { @@ -32,7 +32,7 @@ class Animation extends Trait { } function update() { - Eg.setAnimationParams(model, lue.sys.Time.delta); + Eg.setAnimationParams(model, iron.sys.Time.delta); } public function play(trackName:String, loop = true, speed = 1.0, onTrackComplete:Void->Void = null) { diff --git a/Sources/cycles/trait/MovieTexture.hx b/Sources/armory/trait/internal/MovieTexture.hx similarity index 85% rename from Sources/cycles/trait/MovieTexture.hx rename to Sources/armory/trait/internal/MovieTexture.hx index 6621d8d1..138ffca3 100644 --- a/Sources/cycles/trait/MovieTexture.hx +++ b/Sources/armory/trait/internal/MovieTexture.hx @@ -1,10 +1,10 @@ -package cycles.trait; +package armory.trait.internal; import kha.Image; import kha.Video; import kha.Assets; -import lue.Trait; -import lue.node.ModelNode; +import iron.Trait; +import iron.node.ModelNode; class MovieTexture extends Trait { @@ -36,8 +36,8 @@ class MovieTexture extends Trait { if (!created) { created = true; - requestInit(init); - requestRender2D(render); + notifyOnInit(init); + notifyOnRender2D(render); } } @@ -47,7 +47,7 @@ class MovieTexture extends Trait { image = Image.createRenderTarget(getPower2(video.width()), getPower2(video.height())); - var n = cast(node, lue.node.ModelNode); + var n = cast(node, iron.node.ModelNode); n.materials[0].contexts[0].textures[0] = image; // Override diffuse texture } diff --git a/Sources/cycles/trait/NodeExecutor.hx b/Sources/armory/trait/internal/NodeExecutor.hx similarity index 69% rename from Sources/cycles/trait/NodeExecutor.hx rename to Sources/armory/trait/internal/NodeExecutor.hx index 9b359d3e..b633c7d3 100644 --- a/Sources/cycles/trait/NodeExecutor.hx +++ b/Sources/armory/trait/internal/NodeExecutor.hx @@ -1,19 +1,19 @@ -package cycles.trait; +package armory.trait.internal; -import lue.Trait; +import iron.Trait; class NodeExecutor extends Trait { - var baseNode:cycles.node.Node; + var baseNode:armory.node.Node; var nodeUpdates:ArrayVoid> = []; public function new() { super(); - requestUpdate(update); + notifyOnUpdate(update); } - public function start(baseNode:cycles.node.Node) { + public function start(baseNode:armory.node.Node) { this.baseNode = baseNode; baseNode.start(this); } diff --git a/Sources/cycles/trait/PathTracer.hx b/Sources/armory/trait/internal/PathTracer.hx similarity index 92% rename from Sources/cycles/trait/PathTracer.hx rename to Sources/armory/trait/internal/PathTracer.hx index ffad83e1..96573b8a 100644 --- a/Sources/cycles/trait/PathTracer.hx +++ b/Sources/armory/trait/internal/PathTracer.hx @@ -1,13 +1,13 @@ -package cycles.trait; +package armory.trait.internal; -import lue.Eg; -import lue.math.Mat4; -import lue.math.Vec4; -import lue.Trait; -import lue.node.Transform; -import lue.node.RootNode; -import lue.node.ModelNode; -import lue.resource.MaterialResource.MaterialContext; +import iron.Eg; +import iron.math.Mat4; +import iron.math.Vec4; +import iron.Trait; +import iron.node.Transform; +import iron.node.RootNode; +import iron.node.ModelNode; +import iron.resource.MaterialResource.MaterialContext; class PathTracer extends Trait { @@ -23,8 +23,8 @@ class PathTracer extends Trait { public function new() { super(); - requestInit(init); - requestUpdate(update); + notifyOnInit(init); + notifyOnUpdate(update); } function getColorFromNode(node:ModelNode):Array { @@ -149,7 +149,7 @@ class PathTracer extends Trait { // var jitter = Mat4.identity(); // jitter.initTranslate(Math.random() * 2 - 1, Math.random() * 2 - 1, 0); - // jitter.multiplyScalar(1 / lue.App.w); + // jitter.multiplyScalar(1 / iron.App.w); // jitter.multiplyScalar(1 / 400); var mvp = Mat4.identity(); mvp.mult2(camera.V); diff --git a/Sources/cycles/trait/PhysicsWorld.hx b/Sources/armory/trait/internal/PhysicsWorld.hx similarity index 94% rename from Sources/cycles/trait/PhysicsWorld.hx rename to Sources/armory/trait/internal/PhysicsWorld.hx index 6310ede2..dedb67a0 100644 --- a/Sources/cycles/trait/PhysicsWorld.hx +++ b/Sources/armory/trait/internal/PhysicsWorld.hx @@ -1,12 +1,12 @@ -package cycles.trait; +package armory.trait.internal; #if WITH_PHYSICS import haxebullet.Bullet; #end -import lue.Trait; -import lue.sys.Time; -import lue.math.Vec4; -import lue.math.RayCaster; +import iron.Trait; +import iron.sys.Time; +import iron.math.Vec4; +import iron.math.RayCaster; class ContactPair { public var a:Int; @@ -51,7 +51,7 @@ class PhysicsWorld extends Trait { world = BtDiscreteDynamicsWorld.create(dispatcher, broadphase, solver, collisionConfiguration); world.ptr.setGravity(BtVector3.create(0, 0, -9.81).value); - requestUpdate(update); + notifyOnUpdate(update); } public function addRigidBody(body:RigidBody) { @@ -159,12 +159,12 @@ class PhysicsWorld extends Trait { } public function getRayFrom():BtVector3Pointer { - var camera = lue.node.RootNode.cameras[0]; + var camera = iron.node.RootNode.cameras[0]; return BtVector3.create(camera.transform.pos.x, camera.transform.pos.y, camera.transform.pos.z); } public function getRayTo(inputX:Float, inputY:Float):BtVector3Pointer { - var camera = lue.node.RootNode.cameras[0]; + var camera = iron.node.RootNode.cameras[0]; var start = new Vec4(); var end = new Vec4(); RayCaster.getDirection(start, end, inputX, inputY, camera); diff --git a/Sources/cycles/trait/RigidBody.hx b/Sources/armory/trait/internal/RigidBody.hx similarity index 96% rename from Sources/cycles/trait/RigidBody.hx rename to Sources/armory/trait/internal/RigidBody.hx index dc73e639..d93964c9 100644 --- a/Sources/cycles/trait/RigidBody.hx +++ b/Sources/armory/trait/internal/RigidBody.hx @@ -1,14 +1,14 @@ -package cycles.trait; +package armory.trait.internal; #if WITH_PHYSICS import haxebullet.Bullet; #end -import lue.Trait; -import lue.sys.Time; -import lue.math.Vec4; -import lue.node.Transform; -import lue.node.ModelNode; -import cycles.Root; +import iron.Trait; +import iron.sys.Time; +import iron.math.Vec4; +import iron.node.Transform; +import iron.node.ModelNode; +import armory.Root; class RigidBody extends Trait { @@ -51,9 +51,9 @@ class RigidBody extends Trait { this.friction = friction; this.collisionMargin = collisionMargin; - requestInit(init); - requestLateUpdate(lateUpdate); - requestRemove(removeFromWorld); + notifyOnInit(init); + notifyOnLateUpdate(lateUpdate); + notifyOnRemove(removeFromWorld); } inline function withMargin(f:Float) { diff --git a/Sources/cycles/trait/SceneInstance.hx b/Sources/armory/trait/internal/SceneInstance.hx similarity index 59% rename from Sources/cycles/trait/SceneInstance.hx rename to Sources/armory/trait/internal/SceneInstance.hx index 9dc5dc60..0586e264 100644 --- a/Sources/cycles/trait/SceneInstance.hx +++ b/Sources/armory/trait/internal/SceneInstance.hx @@ -1,14 +1,14 @@ -package cycles.trait; +package armory.trait.internal; -import lue.Trait; -import lue.Eg; +import iron.Trait; +import iron.Eg; class SceneInstance extends Trait { public function new(sceneId:String) { super(); - requestInit(function() { + notifyOnInit(function() { Eg.addScene(sceneId, node); }); } diff --git a/blender/data/data.blend b/blender/data/data.blend index 2c974dcd..3585a070 100644 Binary files a/blender/data/data.blend and b/blender/data/data.blend differ diff --git a/blender/exporter.py b/blender/exporter.py index 1775049f..97b6de3b 100644 --- a/blender/exporter.py +++ b/blender/exporter.py @@ -1463,9 +1463,9 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): t1data[i * 2] = vtx.uvs[1].x t1data[i * 2 + 1] = vtx.uvs[1].y if num_colors > 0: - cdata[i * 3] = vtx.cols[0] - cdata[i * 3 + 1] = vtx.cols[1] - cdata[i * 3 + 2] = vtx.cols[2] + cdata[i * 3] = vtx.col[0] + cdata[i * 3 + 1] = vtx.col[1] + cdata[i * 3 + 2] = vtx.col[2] # Output om.vertex_arrays = [] pa = Object() @@ -2102,29 +2102,33 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): x = Object() if t.type_prop == 'Nodes' and t.nodes_name_prop != '': x.type = 'Script' - x.class_name = t.nodes_name_prop.replace('.', '_') + x.class_name = bpy.data.worlds[0].CGProjectPackage + '.node.' + t.nodes_name_prop.replace('.', '_') elif t.type_prop == 'Scene Instance': x.type = 'Script' - x.class_name = 'SceneInstance' + x.class_name = 'armory.trait.internal.SceneInstance' x.parameters = [t.scene_prop.replace('.', '_')] elif t.type_prop == 'Animation': x.type = 'Script' - x.class_name = 'Animation' + x.class_name = 'armory.trait.internal.Animation' names = [] starts = [] ends = [] - for at in node.my_animationtraitlist: + for at in t.my_animationtraitlist: if at.enabled_prop: names.append(at.name) starts.append(at.start_prop) ends.append(at.end_prop) x.parameters = [t.start_track_name_prop, names, starts, ends] else: # Script - x.type = t.type_prop - x.class_name = t.class_name_prop - if len(node.my_paramstraitlist) > 0: + x.type = 'Script' + if t.type_prop == 'Bundled Script': + trait_prefix = 'armory.trait.' + else: + trait_prefix = bpy.data.worlds[0].CGProjectPackage + '.' + x.class_name = trait_prefix + t.class_name_prop + if len(t.my_paramstraitlist) > 0: x.parameters = [] - for pt in node.my_paramstraitlist: # Append parameters + for pt in t.my_paramstraitlist: # Append parameters x.parameters.append(ast.literal_eval(pt.name)) o.traits.append(x) @@ -2153,7 +2157,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): body_mass = rb.mass x = Object() x.type = 'Script' - x.class_name = 'RigidBody' + x.class_name = 'armory.trait.internal.RigidBody' x.parameters = [body_mass, shape, rb.friction] if rb.use_margin: x.parameters.append(rb.collision_margin) @@ -2292,17 +2296,21 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): o.shader = material.custom_shader_name def cb_export_world(self, world, o): - o.brdf = 'envmap_brdf' + o.brdf = 'brdf' o.probes = [] # Main probe - world_generate_radiance = bpy.data.worlds[0].generate_radiance + world_generate_radiance = False + defs = bpy.data.worlds[0].world_defs + if '_EnvTex' in defs: # Radiance only for texture + world_generate_radiance = bpy.data.worlds[0].generate_radiance + generate_irradiance = '_EnvTex' in defs or '_EnvSky' in defs envtex = bpy.data.cameras[0].world_envtex_name.rsplit('.', 1)[0] num_mips = bpy.data.cameras[0].world_envtex_num_mips strength = bpy.data.cameras[0].world_envtex_strength - po = self.make_probe('world', envtex, num_mips, strength, 1.0, [0, 0, 0], [0, 0, 0], world_generate_radiance) + po = self.make_probe('world', envtex, num_mips, strength, 1.0, [0, 0, 0], [0, 0, 0], world_generate_radiance, generate_irradiance) o.probes.append(po) - if '_EnvSky' in bpy.data.worlds[0].world_defs: + if '_EnvSky' in defs: # Sky data for probe po.sun_direction = list(bpy.data.cameras[0].world_envtex_sun_direction) po.turbidity = bpy.data.cameras[0].world_envtex_turbidity @@ -2323,16 +2331,19 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): cam.probe_num_mips = write_probes.write_probes(cam.probe_texture, disable_hdr, cam.probe_num_mips, generate_radiance=generate_radiance) base_name = cam.probe_texture.rsplit('.', 1)[0] - po = self.make_probe(cam.name, base_name, cam.probe_num_mips, cam.probe_strength, cam.probe_blending, volume, volume_center, generate_radiance) + po = self.make_probe(cam.name, base_name, cam.probe_num_mips, cam.probe_strength, cam.probe_blending, volume, volume_center, generate_radiance, generate_irradiance) o.probes.append(po) - def make_probe(self, id, envtex, mipmaps, strength, blending, volume, volume_center, generate_radiance): + def make_probe(self, id, envtex, mipmaps, strength, blending, volume, volume_center, generate_radiance, generate_irradiance): po = Object() po.id = id if generate_radiance: po.radiance = envtex + '_radiance' - po.radiance_mipmaps = mipmaps - po.irradiance = envtex + '_irradiance' + po.radiance_mipmaps = mipmaps + if generate_irradiance: + po.irradiance = envtex + '_irradiance' + else: + po.irradiance = '' # No irradiance data, fallback to default at runtime po.strength = strength po.blending = blending po.volume = volume diff --git a/blender/lib/compile.py b/blender/lib/compile.py deleted file mode 100644 index 29bd4884..00000000 --- a/blender/lib/compile.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python - -# Usage: 'python compile.py' -# Output ../compiled/ - -import make_resources -import make_variants -import os - -os.chdir('./forward') -make_resources.make('forward.shader.json') -make_variants.make('forward.shader.json') - -os.chdir('../deferred') -make_resources.make('deferred.shader.json') -make_variants.make('deferred.shader.json') - -os.chdir('../deferred_light') -make_resources.make('deferred_light.shader.json') -make_variants.make('deferred_light.shader.json') - -os.chdir('../env_map') -make_resources.make('env_map.shader.json') -make_variants.make('env_map.shader.json') - -os.chdir('../fxaa_pass') -make_resources.make('fxaa_pass.shader.json') -make_variants.make('fxaa_pass.shader.json') - -os.chdir('../ssao_pass') -make_resources.make('ssao_pass.shader.json') -make_variants.make('ssao_pass.shader.json') - -os.chdir('../ssdo_pass') -make_resources.make('ssdo_pass.shader.json') -make_variants.make('ssdo_pass.shader.json') - -os.chdir('../blur_pass') -make_resources.make('blur_pass.shader.json') -make_variants.make('blur_pass.shader.json') - -os.chdir('../motion_blur_pass') -make_resources.make('motion_blur_pass.shader.json') -make_variants.make('motion_blur_pass.shader.json') - -os.chdir('../compositor_pass') -make_resources.make('compositor_pass.shader.json') -make_variants.make('compositor_pass.shader.json') - -os.chdir('../bloom_pass') -make_resources.make('bloom_pass.shader.json') -make_variants.make('bloom_pass.shader.json') - -os.chdir('../ssr_pass') -make_resources.make('ssr_pass.shader.json') -make_variants.make('ssr_pass.shader.json') - -os.chdir('../combine_pass') -make_resources.make('combine_pass.shader.json') -make_variants.make('combine_pass.shader.json') - -os.chdir('../sss_pass') -make_resources.make('sss_pass.shader.json') -make_variants.make('sss_pass.shader.json') - -os.chdir('../water_pass') -make_resources.make('water_pass.shader.json') -make_variants.make('water_pass.shader.json') - -os.chdir('../godrays_pass') -make_resources.make('godrays_pass.shader.json') -make_variants.make('godrays_pass.shader.json') - -# os.chdir('../pt_trace_pass') -# make_resources.make('pt_trace_pass.shader.json') -# make_variants.make('pt_trace_pass.shader.json') - -# os.chdir('../pt_final_pass') -# make_resources.make('pt_final_pass.shader.json') -# make_variants.make('pt_final_pass.shader.json') diff --git a/blender/lib/make_resources.py b/blender/lib/make_resources.py index 30e24716..dab52e46 100644 --- a/blender/lib/make_resources.py +++ b/blender/lib/make_resources.py @@ -227,11 +227,11 @@ def saveResource(path, base_name, subset, res, minimize): r.shader_resources = [res.shader_resources[-1]] f.write(r.to_JSON(minimize)) -def make(json_name, minimize=False, defs=None): +def make(json_name, fp, minimize=False, defs=None): base_name = json_name.split('.', 1)[0] # Make out dir - path = '../../../../compiled/ShaderResources/' + base_name + path = fp + '/compiled/ShaderResources/' + base_name if not os.path.exists(path): os.makedirs(path) diff --git a/blender/lib/make_variants.py b/blender/lib/make_variants.py index 763016fa..d1c99189 100644 --- a/blender/lib/make_variants.py +++ b/blender/lib/make_variants.py @@ -22,7 +22,7 @@ def writeFile(path, name, defs, lines): f.write('#define ' + d + '\n') defs_written = True -def make(json_name, defs=None): +def make(json_name, fp, defs=None): vert_shaders = [] frag_shaders = [] shader_names = [] @@ -36,7 +36,7 @@ def make(json_name, defs=None): base_name = json_name.split('.', 1)[0] # Make out dir - path = '../../../../compiled/Shaders/' + base_name + path = fp + '/compiled/Shaders/' + base_name if not os.path.exists(path): os.makedirs(path) diff --git a/blender/lib/server.py b/blender/lib/server.py index 53cc5b53..fc7121d1 100755 --- a/blender/lib/server.py +++ b/blender/lib/server.py @@ -10,7 +10,7 @@ import os def run_server(): Handler = http.server.SimpleHTTPRequestHandler - httpd = socketserver.TCPServer(("", 8080), Handler) + httpd = socketserver.TCPServer(("", 8040), Handler) httpd.serve_forever() run_server() diff --git a/blender/nodes_logic.py b/blender/nodes_logic.py index 24efc18c..b0d746c0 100755 --- a/blender/nodes_logic.py +++ b/blender/nodes_logic.py @@ -232,7 +232,7 @@ def buildNodeTrees(): # Export node scripts for node_group in bpy.data.node_groups: - if node_group.bl_idname == 'CGTreeType': # Build only cycles game trees + if node_group.bl_idname == 'CGTreeType': # Build only game trees node_group.use_fake_user = True # Keep fake references for now buildNodeTree(node_group) @@ -245,8 +245,8 @@ def buildNodeTree(node_group): with open(path + node_group_name + '.hx', 'w') as f: f.write('package ' + bpy.data.worlds[0].CGProjectPackage + '.node;\n\n') - f.write('import cycles.node.*;\n\n') - f.write('class ' + node_group_name + ' extends cycles.trait.NodeExecutor {\n\n') + f.write('import armory.node.*;\n\n') + f.write('class ' + node_group_name + ' extends armory.trait.internal.NodeExecutor {\n\n') f.write('\tpublic function new() { super(); requestAdd(add); }\n\n') f.write('\tfunction add() {\n') # Make sure root node exists diff --git a/blender/nodes_material.py b/blender/nodes_material.py index c4ab2ed3..fe4a316a 100644 --- a/blender/nodes_material.py +++ b/blender/nodes_material.py @@ -114,7 +114,7 @@ def make_texture(self, id, image_node, material): if image.source == 'MOVIE': # Just append movie texture trait for now movie_trait = Object() movie_trait.type = 'Script' - movie_trait.class_name = 'MovieTexture' + movie_trait.class_name = 'armory.trait.internal.MovieTexture' movie_trait.parameters = [tex.name] for o in self.materialToGameObjectDict[material]: o.traits.append(movie_trait) diff --git a/blender/nodes_pipeline.py b/blender/nodes_pipeline.py index b81d967d..c333f9e4 100755 --- a/blender/nodes_pipeline.py +++ b/blender/nodes_pipeline.py @@ -9,448 +9,678 @@ import subprocess import nodes_compositor class CGPipelineTree(NodeTree): - '''Pipeline nodes''' - bl_idname = 'CGPipelineTreeType' - bl_label = 'CG Pipeline Node Tree' - bl_icon = 'GAME' + '''Pipeline nodes''' + bl_idname = 'CGPipelineTreeType' + bl_label = 'CG Pipeline Node Tree' + bl_icon = 'GAME' class CGPipelineTreeNode: - @classmethod - def poll(cls, ntree): - return ntree.bl_idname == 'CGPipelineTreeType' - + @classmethod + def poll(cls, ntree): + return ntree.bl_idname == 'CGPipelineTreeType' + +# Prebuilt +class QuadPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'QuadPassNodeType' + bl_label = 'Quad Pass' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketString', "Shader Context") + self.inputs.new('NodeSocketShader', "Bind 1") + self.inputs.new('NodeSocketString', "Constant") + self.inputs.new('NodeSocketShader', "Bind 2") + self.inputs.new('NodeSocketString', "Constant") + self.inputs.new('NodeSocketShader', "Bind 3") + self.inputs.new('NodeSocketString', "Constant") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class SSAOPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'SSAOPassNodeType' + bl_label = 'SSAO' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Target Temp") + self.inputs.new('NodeSocketShader', "GBufferD") + self.inputs.new('NodeSocketShader', "GBuffer0") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class SSRPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'SSRPassNodeType' + bl_label = 'SSR' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "A") + self.inputs.new('NodeSocketShader', "B") + self.inputs.new('NodeSocketShader', "Color") + self.inputs.new('NodeSocketShader', "GBuffer") + self.inputs.new('NodeSocketShader', "GBuffer1") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class BloomPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'BloomPassNodeType' + bl_label = 'Bloom' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "A") + self.inputs.new('NodeSocketShader', "B") + self.inputs.new('NodeSocketShader', "Color") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class MotionBlurPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'MotionBlurPassNodeType' + bl_label = 'Motion Blur' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Color") + self.inputs.new('NodeSocketShader', "GBufferD") + self.inputs.new('NodeSocketShader', "GBuffer0") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class FXAAPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'FXAAPassNodeType' + bl_label = 'FXAA' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Color") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class SMAAPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'SMAAPassNodeType' + bl_label = 'SMAA' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Edges Target") + self.inputs.new('NodeSocketShader', "Blend Target") + self.inputs.new('NodeSocketShader', "Color") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class SSSPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'SSSPassNodeType' + bl_label = 'SSS' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target In") + self.inputs.new('NodeSocketShader', "Target Out") + self.inputs.new('NodeSocketShader', "Color") + self.inputs.new('NodeSocketShader', "GBufferD") + self.inputs.new('NodeSocketShader', "GBuffer0") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class WaterPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'WaterPassNodeType' + bl_label = 'Water' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Color") + self.inputs.new('NodeSocketShader', "GBufferD") + self.inputs.new('NodeSocketShader', "GBuffer0") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class DeferredLightPassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'DeferredLightPassNodeType' + bl_label = 'Deferred Light' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "GBuffer") + self.inputs.new('NodeSocketShader', "SSAO Map") + self.inputs.new('NodeSocketShader', "Shadow Map") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +class TranslucentResolvePassNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'TranslucentResolvePassNodeType' + bl_label = 'Translucent Resolve' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Translucent GBuffer") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + +# Pipeline class DrawGeometryNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawGeometryNodeType' - bl_label = 'Draw Geometry' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Context") + '''A custom node''' + bl_idname = 'DrawGeometryNodeType' + bl_label = 'Draw Geometry' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Context") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class DrawDecalsNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawDecalsNodeType' - bl_label = 'Draw Decals' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Context") + '''A custom node''' + bl_idname = 'DrawDecalsNodeType' + bl_label = 'Draw Decals' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Context") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class ClearTargetNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'ClearTargetNodeType' - bl_label = 'Clear Target' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketBool', "Color") - self.inputs.new('NodeSocketColor', "Value") - self.inputs.new('NodeSocketBool', "Depth") - self.inputs.new('NodeSocketFloat', "Value") - self.inputs[4].default_value = 1.0 - self.inputs.new('NodeSocketBool', "Stencil") - self.inputs.new('NodeSocketInt', "Value") + '''A custom node''' + bl_idname = 'ClearTargetNodeType' + bl_label = 'Clear Target' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketBool', "Color") + self.inputs.new('NodeSocketColor', "Value") + self.inputs.new('NodeSocketBool', "Depth") + self.inputs.new('NodeSocketFloat', "Value") + self.inputs[4].default_value = 1.0 + self.inputs.new('NodeSocketBool', "Stencil") + self.inputs.new('NodeSocketInt', "Value") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class BeginNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'BeginNodeType' - bl_label = 'Begin' - bl_icon = 'SOUND' - - def init(self, context): - self.outputs.new('NodeSocketShader', "Stage") + '''A custom node''' + bl_idname = 'BeginNodeType' + bl_label = 'Begin' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketString', "ID") + self.inputs.new('NodeSocketString', "Geometry") + self.inputs.new('NodeSocketString', "Shadows") + self.inputs.new('NodeSocketString', "Translucent") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class SetTargetNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'SetTargetNodeType' - bl_label = 'Set Target' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Target") + '''A custom node''' + bl_idname = 'SetTargetNodeType' + bl_label = 'Set Target' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class TargetNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'TargetNodeType' - bl_label = 'Target' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketString', "ID") - self.inputs.new('NodeSocketInt', "Width") - self.inputs.new('NodeSocketInt', "Height") - self.inputs.new('NodeSocketShader', "Depth Buffer") - self.inputs.new('NodeSocketString', "Format") - self.inputs.new('NodeSocketBool', "Ping Pong") + '''A custom node''' + bl_idname = 'TargetNodeType' + bl_label = 'Target' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketString', "ID") + self.inputs.new('NodeSocketInt', "Width") + self.inputs.new('NodeSocketInt', "Height") + self.inputs.new('NodeSocketShader', "Depth Buffer") + self.inputs.new('NodeSocketString', "Format") + self.inputs.new('NodeSocketBool', "Ping Pong") - self.outputs.new('NodeSocketShader', "Target") + self.outputs.new('NodeSocketShader', "Target") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class TargetArrayNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'TargetArrayNodeType' - bl_label = 'Target Array' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Target") - self.inputs.new('NodeSocketInt', "Instances") + '''A custom node''' + bl_idname = 'TargetArrayNodeType' + bl_label = 'Target Array' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketInt', "Instances") - self.outputs.new('NodeSocketShader', "Targets") + self.outputs.new('NodeSocketShader', "Targets") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") -class DebthBufferNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DepthBufferNodeType' - bl_label = 'Depth Buffer' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketString', "ID") - self.inputs.new('NodeSocketBool', "Stencil") - - self.outputs.new('NodeSocketShader', "Target") +class DepthBufferNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'DepthBufferNodeType' + bl_label = 'Depth Buffer' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketString', "ID") + self.inputs.new('NodeSocketBool', "Stencil") + + self.outputs.new('NodeSocketShader', "Target") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class GBufferNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'GBufferNodeType' - bl_label = 'GBuffer' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Target 0") - self.inputs.new('NodeSocketShader', "Target 1") - self.inputs.new('NodeSocketShader', "Target 2") - self.inputs.new('NodeSocketShader', "Target 3") - self.inputs.new('NodeSocketShader', "Target 4") + '''A custom node''' + bl_idname = 'GBufferNodeType' + bl_label = 'GBuffer' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Target 0") + self.inputs.new('NodeSocketShader', "Target 1") + self.inputs.new('NodeSocketShader', "Target 2") + self.inputs.new('NodeSocketShader', "Target 3") + self.inputs.new('NodeSocketShader', "Target 4") - self.outputs.new('NodeSocketShader', "Targets") + self.outputs.new('NodeSocketShader', "Targets") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class FramebufferNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'FramebufferNodeType' - bl_label = 'Framebuffer' - bl_icon = 'SOUND' - - def init(self, context): - self.outputs.new('NodeSocketShader', "Target") + '''A custom node''' + bl_idname = 'FramebufferNodeType' + bl_label = 'Framebuffer' + bl_icon = 'SOUND' + + def init(self, context): + self.outputs.new('NodeSocketShader', "Target") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class BindTargetNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'BindTargetNodeType' - bl_label = 'Bind Target' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Target") - self.inputs.new('NodeSocketString', "Constant") + '''A custom node''' + bl_idname = 'BindTargetNodeType' + bl_label = 'Bind Target' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketString', "Constant") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class DrawMaterialQuadNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawMaterialQuadNodeType' - bl_label = 'Draw Material Quad' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Material Context") + '''A custom node''' + bl_idname = 'DrawMaterialQuadNodeType' + bl_label = 'Draw Material Quad' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Material Context") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class DrawQuadNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawQuadNodeType' - bl_label = 'Draw Quad' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Shader Context") + '''A custom node''' + bl_idname = 'DrawQuadNodeType' + bl_label = 'Draw Quad' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Shader Context") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class CallFunctionNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'CallFunctionNodeType' - bl_label = 'Call Function' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Function") + '''A custom node''' + bl_idname = 'CallFunctionNodeType' + bl_label = 'Call Function' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Function") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class BranchFunctionNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'BranchFunctionNodeType' - bl_label = 'Branch Function' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketString', "Function") + '''A custom node''' + bl_idname = 'BranchFunctionNodeType' + bl_label = 'Branch Function' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketString', "Function") - self.outputs.new('NodeSocketShader', "True") - self.outputs.new('NodeSocketShader', "False") + self.outputs.new('NodeSocketShader', "True") + self.outputs.new('NodeSocketShader', "False") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class MergeStagesNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'MergeStagesNodeType' - bl_label = 'Merge Stages' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Stage") + '''A custom node''' + bl_idname = 'MergeStagesNodeType' + bl_label = 'Merge Stages' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Stage") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class LoopStagesNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'LoopStagesNodeType' - bl_label = 'Loop Stages' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketInt', "From") - self.inputs.new('NodeSocketInt', "To") + '''A custom node''' + bl_idname = 'LoopStagesNodeType' + bl_label = 'Loop Stages' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketInt', "From") + self.inputs.new('NodeSocketInt', "To") - self.outputs.new('NodeSocketShader', "Complete") - self.outputs.new('NodeSocketShader', "Loop") + self.outputs.new('NodeSocketShader', "Complete") + self.outputs.new('NodeSocketShader', "Loop") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + class LoopLightsNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'LoopLightsNodeType' - bl_label = 'Loop Lights' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") + '''A custom node''' + bl_idname = 'LoopLightsNodeType' + bl_label = 'Loop Lights' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") - self.outputs.new('NodeSocketShader', "Complete") - self.outputs.new('NodeSocketShader', "Loop") + self.outputs.new('NodeSocketShader', "Complete") + self.outputs.new('NodeSocketShader', "Loop") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class DrawWorldNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawWorldNodeType' - bl_label = 'Draw World' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Depth") + '''A custom node''' + bl_idname = 'DrawWorldNodeType' + bl_label = 'Draw World' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Depth") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") class DrawCompositorNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'DrawCompositorNodeType' - bl_label = 'Draw Compositor' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Target") - self.inputs.new('NodeSocketShader', "Color") - self.inputs.new('NodeSocketShader', "GBuffer") + '''A custom node''' + bl_idname = 'DrawCompositorNodeType' + bl_label = 'Draw Compositor' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + self.inputs.new('NodeSocketShader', "Target") + self.inputs.new('NodeSocketShader', "Color") + self.inputs.new('NodeSocketShader', "GBuffer") - self.outputs.new('NodeSocketShader', "Stage") + self.outputs.new('NodeSocketShader', "Stage") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") -# Pass nodes -class QuadPassNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'QuadPassNodeType' - bl_label = 'Quad Pass' - bl_icon = 'SOUND' - - def init(self, context): - self.inputs.new('NodeSocketShader', "Stage") - self.inputs.new('NodeSocketShader', "Target") - self.inputs.new('NodeSocketString', "Shader Context") - self.inputs.new('NodeSocketShader', "Bind 1") - self.inputs.new('NodeSocketString', "Constant") - self.inputs.new('NodeSocketShader', "Bind 2") - self.inputs.new('NodeSocketString', "Constant") - self.inputs.new('NodeSocketShader', "Bind 3") - self.inputs.new('NodeSocketString', "Constant") - - self.outputs.new('NodeSocketShader', "Stage") - - def copy(self, node): - print("Copying from node ", node) - - def free(self): - print("Removing node ", self, ", Goodbye!") # Constant nodes class ScreenNode(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'ScreenNodeType' - bl_label = 'Screen' - bl_icon = 'SOUND' - - def init(self, context): - self.outputs.new('NodeSocketInt', "Width") - self.outputs.new('NodeSocketInt', "Height") - self.inputs.new('NodeSocketFloat', "Scale") - self.inputs[0].default_value = 1.0 + '''A custom node''' + bl_idname = 'ScreenNodeType' + bl_label = 'Screen' + bl_icon = 'SOUND' + + def init(self, context): + self.outputs.new('NodeSocketInt', "Width") + self.outputs.new('NodeSocketInt', "Height") + self.inputs.new('NodeSocketFloat', "Scale") + self.inputs[0].default_value = 1.0 - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") - + def free(self): + print("Removing node ", self, ", Goodbye!") + +class BackgroundColorNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'BackgroundColorNodeType' + bl_label = 'Background Color' + bl_icon = 'SOUND' + + def init(self, context): + self.outputs.new('NodeSocketInt', "Color") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") + class LightCount(Node, CGPipelineTreeNode): - '''A custom node''' - bl_idname = 'LightCountNodeType' - bl_label = 'Light Count' - bl_icon = 'SOUND' - - def init(self, context): - self.outputs.new('NodeSocketInt', "Count") + '''A custom node''' + bl_idname = 'LightCountNodeType' + bl_label = 'Light Count' + bl_icon = 'SOUND' + + def init(self, context): + self.outputs.new('NodeSocketInt', "Count") - def copy(self, node): - print("Copying from node ", node) + def copy(self, node): + print("Copying from node ", node) - def free(self): - print("Removing node ", self, ", Goodbye!") + def free(self): + print("Removing node ", self, ", Goodbye!") ### Node Categories ### # Node categories are a python system for automatically @@ -461,65 +691,75 @@ import nodeitems_utils from nodeitems_utils import NodeCategory, NodeItem class MyPipelineNodeCategory(NodeCategory): - @classmethod - def poll(cls, context): - return context.space_data.tree_type == 'CGPipelineTreeType' + @classmethod + def poll(cls, context): + return context.space_data.tree_type == 'CGPipelineTreeType' class MyTargetNodeCategory(NodeCategory): - @classmethod - def poll(cls, context): - return context.space_data.tree_type == 'CGPipelineTreeType' + @classmethod + def poll(cls, context): + return context.space_data.tree_type == 'CGPipelineTreeType' class MyPassNodeCategory(NodeCategory): - @classmethod - def poll(cls, context): - return context.space_data.tree_type == 'CGPipelineTreeType' - + @classmethod + def poll(cls, context): + return context.space_data.tree_type == 'CGPipelineTreeType' + class MyConstantNodeCategory(NodeCategory): - @classmethod - def poll(cls, context): - return context.space_data.tree_type == 'CGPipelineTreeType' + @classmethod + def poll(cls, context): + return context.space_data.tree_type == 'CGPipelineTreeType' class MyLogicNodeCategory(NodeCategory): - @classmethod - def poll(cls, context): - return context.space_data.tree_type == 'CGPipelineTreeType' + @classmethod + def poll(cls, context): + return context.space_data.tree_type == 'CGPipelineTreeType' node_categories = [ - MyPipelineNodeCategory("PIPELINENODES", "Pipeline", items=[ - NodeItem("BeginNodeType"), - NodeItem("DrawGeometryNodeType"), - NodeItem("DrawDecalsNodeType"), - NodeItem("ClearTargetNodeType"), - NodeItem("SetTargetNodeType"), - NodeItem("BindTargetNodeType"), - NodeItem("DrawMaterialQuadNodeType"), - NodeItem("DrawQuadNodeType"), - NodeItem("DrawWorldNodeType"), - NodeItem("DrawCompositorNodeType"), - ]), - MyTargetNodeCategory("TARGETNODES", "Target", items=[ - NodeItem("TargetNodeType"), - NodeItem("TargetArrayNodeType"), - NodeItem("DepthBufferNodeType"), - NodeItem("GBufferNodeType"), - NodeItem("FramebufferNodeType"), - ]), - MyPassNodeCategory("PASSNODES", "Pass", items=[ - NodeItem("QuadPassNodeType"), - # Prebuilt passes here - ]), - MyConstantNodeCategory("CONSTANTNODES", "Constant", items=[ - NodeItem("ScreenNodeType"), - NodeItem("LightCountNodeType"), - ]), - MyLogicNodeCategory("LOGICNODES", "Logic", items=[ - NodeItem("CallFunctionNodeType"), - NodeItem("BranchFunctionNodeType"), - NodeItem("MergeStagesNodeType"), - NodeItem("LoopStagesNodeType"), - NodeItem("LoopLightsNodeType"), - ]), + MyPipelineNodeCategory("PIPELINENODES", "Pipeline", items=[ + NodeItem("BeginNodeType"), + NodeItem("DrawGeometryNodeType"), + NodeItem("DrawDecalsNodeType"), + NodeItem("ClearTargetNodeType"), + NodeItem("SetTargetNodeType"), + NodeItem("BindTargetNodeType"), + NodeItem("DrawMaterialQuadNodeType"), + NodeItem("DrawQuadNodeType"), + NodeItem("DrawWorldNodeType"), + NodeItem("DrawCompositorNodeType"), + ]), + MyTargetNodeCategory("TARGETNODES", "Target", items=[ + NodeItem("TargetNodeType"), + NodeItem("TargetArrayNodeType"), + NodeItem("DepthBufferNodeType"), + NodeItem("GBufferNodeType"), + NodeItem("FramebufferNodeType"), + ]), + MyPassNodeCategory("PREBUILTNODES", "Prebuilt", items=[ + NodeItem("QuadPassNodeType"), + NodeItem("SSAOPassNodeType"), + NodeItem("SSRPassNodeType"), + NodeItem("BloomPassNodeType"), + NodeItem("MotionBlurPassNodeType"), + NodeItem("FXAAPassNodeType"), + NodeItem("SMAAPassNodeType"), + NodeItem("SSSPassNodeType"), + NodeItem("WaterPassNodeType"), + NodeItem("DeferredLightPassNodeType"), + NodeItem("TranslucentResolvePassNodeType"), + ]), + MyConstantNodeCategory("CONSTANTNODES", "Constant", items=[ + NodeItem("ScreenNodeType"), + NodeItem("BackgroundColorNodeType"), + NodeItem("LightCountNodeType"), + ]), + MyLogicNodeCategory("LOGICNODES", "Logic", items=[ + NodeItem("CallFunctionNodeType"), + NodeItem("BranchFunctionNodeType"), + NodeItem("MergeStagesNodeType"), + NodeItem("LoopStagesNodeType"), + NodeItem("LoopLightsNodeType"), + ]), ] @@ -527,472 +767,628 @@ node_categories = [ def reload_blend_data(): - if bpy.data.node_groups.get('forward_pipeline') == None: - load_library() - pass + if bpy.data.node_groups.get('forward_pipeline') == None: + load_library() + pass def load_library(): - haxelib_path = "haxelib" - if platform.system() == 'Darwin': - haxelib_path = "/usr/local/bin/haxelib" + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path + data_path = sdk_path + '/armory/blender/data/data.blend' - output = subprocess.check_output([haxelib_path + " path cyclesgame"], shell=True) - output = str(output).split("\\n")[0].split("'")[1] - data_path = output[:-8] + "blender/data/data.blend" # Remove 'Sources/' from haxelib path - - with bpy.data.libraries.load(data_path, link=False) as (data_from, data_to): - data_to.node_groups = ['forward_pipeline', 'forward_pipeline_noshadow', 'deferred_pipeline', 'pathtrace_pipeline', 'PBR'] - - # TODO: cannot use for loop - # TODO: import pbr group separately, no need for fake user - bpy.data.node_groups['forward_pipeline'].use_fake_user = True - bpy.data.node_groups['forward_pipeline_noshadow'].use_fake_user = True - bpy.data.node_groups['deferred_pipeline'].use_fake_user = True - bpy.data.node_groups['pathtrace_pipeline'].use_fake_user = True - bpy.data.node_groups['PBR'].use_fake_user = True + with bpy.data.libraries.load(data_path, link=False) as (data_from, data_to): + data_to.node_groups = ['forward_pipeline', 'forward_pipeline_low', 'deferred_pipeline', 'deferred_pipeline_low', 'pathtrace_pipeline', 'PBR'] + + # TODO: cannot use for loop + # TODO: import pbr group separately, no need for fake user + bpy.data.node_groups['forward_pipeline'].use_fake_user = True + bpy.data.node_groups['forward_pipeline_low'].use_fake_user = True + bpy.data.node_groups['deferred_pipeline'].use_fake_user = True + bpy.data.node_groups['deferred_pipeline_low'].use_fake_user = True + bpy.data.node_groups['pathtrace_pipeline'].use_fake_user = True + bpy.data.node_groups['PBR'].use_fake_user = True def register(): - bpy.utils.register_module(__name__) - try: - nodeitems_utils.register_node_categories("CG_PIPELINE_NODES", node_categories) - reload_blend_data() - except: - pass + bpy.utils.register_module(__name__) + try: + nodeitems_utils.register_node_categories("CG_PIPELINE_NODES", node_categories) + reload_blend_data() + except: + pass def unregister(): - nodeitems_utils.unregister_node_categories("CG_PIPELINE_NODES") - bpy.utils.unregister_module(__name__) + nodeitems_utils.unregister_node_categories("CG_PIPELINE_NODES") + bpy.utils.unregister_module(__name__) # Generating pipeline resources class Object: - def to_JSON(self): - if bpy.data.worlds[0].CGMinimize == True: - return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':')) - else: - return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + def to_JSON(self): + if bpy.data.worlds[0].CGMinimize == True: + return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':')) + else: + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) -def buildNodeTrees(shader_references, asset_references): - s = bpy.data.filepath.split(os.path.sep) - s.pop() - fp = os.path.sep.join(s) - os.chdir(fp) +def buildNodeTrees(shader_references, asset_references, assets_path): + s = bpy.data.filepath.split(os.path.sep) + s.pop() + fp = os.path.sep.join(s) + os.chdir(fp) - # Make sure Assets dir exists - if not os.path.exists('Assets/generated/pipelines'): - os.makedirs('Assets/generated/pipelines') - - # Export selected pipeline - # node_group.bl_idname == 'CGPipelineTreeType' - node_group = bpy.data.node_groups[bpy.data.cameras[0].pipeline_path] - buildNodeTree(node_group, shader_references, asset_references) + # Make sure Assets dir exists + if not os.path.exists('Assets/generated/pipelines'): + os.makedirs('Assets/generated/pipelines') + + buildNodeTrees.assets_path = assets_path + buildNodeTrees.linked_assets = [] + # Always include + buildNodeTrees.linked_assets.append(buildNodeTrees.assets_path + 'brdf.png') + + # Export selected pipeline + # node_group.bl_idname == 'CGPipelineTreeType' + node_group = bpy.data.node_groups[bpy.data.cameras[0].pipeline_path] + buildNodeTree(node_group, shader_references, asset_references) + + return buildNodeTrees.linked_assets def buildNodeTree(node_group, shader_references, asset_references): - output = Object() - res = Object() - output.pipeline_resources = [res] - - path = 'Assets/generated/pipelines/' - node_group_name = node_group.name.replace('.', '_') - - rn = getRootNode(node_group) - if rn == None: - return - - res.id = node_group_name - res.render_targets, res.depth_buffers = get_render_targets(rn, node_group) - res.stages = [] - - # Used to merge bind target nodes into one stage - last_bind_target = None - - buildNode(res.stages, rn, node_group, last_bind_target, shader_references, asset_references) + output = Object() + res = Object() + output.pipeline_resources = [res] + + path = 'Assets/generated/pipelines/' + node_group_name = node_group.name.replace('.', '_') + + rn = getRootNode(node_group) + if rn == None: + return + + res.id = node_group_name + res.render_targets, res.depth_buffers = get_render_targets(rn, node_group) + res.stages = [] + + buildNode(res.stages, rn, node_group, shader_references, asset_references) - with open(path + node_group_name + '.json', 'w') as f: - f.write(output.to_JSON()) + with open(path + node_group_name + '.json', 'w') as f: + f.write(output.to_JSON()) def make_set_target(stage, node_group, node, currentNode=None, target_index=1): - if currentNode == None: - currentNode = node - - stage.command = 'set_target' - currentNode = findNodeByLink(node_group, currentNode, currentNode.inputs[target_index]) - - if currentNode.bl_idname == 'TargetNodeType': - targetId = currentNode.inputs[0].default_value - stage.params.append(targetId) - - elif currentNode.bl_idname == 'GBufferNodeType': - # Set all linked targets - for i in range(0, 5): - if currentNode.inputs[i].is_linked: - make_set_target(stage, node_group, node, currentNode, target_index=i) - - elif currentNode.bl_idname == 'NodeReroute': - make_set_target(stage, node_group, node, currentNode, target_index=0) - - else: # Framebuffer - targetId = '' - stage.params.append(targetId) + if currentNode == None: + currentNode = node + + stage.command = 'set_target' + currentNode = findNodeByLink(node_group, currentNode, currentNode.inputs[target_index]) + + if currentNode.bl_idname == 'TargetNodeType': + targetId = currentNode.inputs[0].default_value + stage.params.append(targetId) + # Store current target size + buildNode.last_set_target_w = currentNode.inputs[1].default_value + buildNode.last_set_target_h = currentNode.inputs[2].default_value + + elif currentNode.bl_idname == 'GBufferNodeType': + # Set all linked targets + for i in range(0, 5): + if currentNode.inputs[i].is_linked: + make_set_target(stage, node_group, node, currentNode, target_index=i) + + elif currentNode.bl_idname == 'NodeReroute': + make_set_target(stage, node_group, node, currentNode, target_index=0) + + else: # Framebuffer + targetId = '' + stage.params.append(targetId) -def make_clear_target(stage, node_group, node): - stage.command = 'clear_target' - if node.inputs[1].default_value == True: - stage.params.append('color') - val = node.inputs[2].default_value - hex = '#%02x%02x%02x%02x' % (int(val[3] * 255), int(val[0] * 255), int(val[1] * 255), int(val[2] * 255)) - stage.params.append(str(hex)) - if node.inputs[3].default_value == True: - stage.params.append('depth') - val = node.inputs[4].default_value - stage.params.append(str(val)) - if node.inputs[5].default_value == True: - stage.params.append('stencil') - val = node.inputs[6].default_value - stage.params.append(str(val)) +def to_hex(val): + return '#%02x%02x%02x%02x' % (int(val[3] * 255), int(val[0] * 255), int(val[1] * 255), int(val[2] * 255)) + +def make_clear_target(stage, color_val=None, depth_val=None, stencil_val=None): + stage.command = 'clear_target' + if color_val != None: + stage.params.append('color') + stage.params.append(str(to_hex(color_val))) + if depth_val != None: + stage.params.append('depth') + stage.params.append(str(depth_val)) + if stencil_val != None: + stage.params.append('stencil') + stage.params.append(str(stencil_val)) def make_draw_geometry(stage, node_group, node): - stage.command = 'draw_geometry' - stage.params.append(node.inputs[1].default_value) # Context - + stage.command = 'draw_geometry' + context = node.inputs[1].default_value + # Store shadowmap size + if context == bpy.data.cameras[0].shadows_context: + bpy.data.worlds[0].shadowmap_size = 1024 + stage.params.append(context) + def make_draw_decals(stage, node_group, node, shader_references, asset_references): - stage.command = 'draw_decals' - context = node.inputs[1].default_value - stage.params.append(context) # Context - bpy.data.cameras[0].last_decal_context = context + stage.command = 'draw_decals' + context = node.inputs[1].default_value + stage.params.append(context) # Context + bpy.data.cameras[0].last_decal_context = context -def make_bind_target(stage, node_group, node, currentNode=None, target_index=1, constant_index=2, constant_name=None): - if currentNode == None: - currentNode = node - - stage.command = 'bind_target' - - link = findLink(node_group, currentNode, currentNode.inputs[target_index]) - currentNode = link.from_node - - if constant_name == None: - constant_name = node.inputs[constant_index].default_value - - if currentNode.bl_idname == 'NodeReroute': - make_bind_target(stage, node_group, node, currentNode, target_index=0, constant_index=constant_index, constant_name=constant_name) - - elif currentNode.bl_idname == 'GBufferNodeType': - for i in range(0, 5): - if currentNode.inputs[i].is_linked: - targetNode = findNodeByLink(node_group, currentNode, currentNode.inputs[i]) - targetId = targetNode.inputs[0].default_value - # if i == 0 and targetNode.inputs[3].default_value == True: # Depth - if targetNode.inputs[3].is_linked: # Depth - db_node = findNodeByLink(node_group, targetNode, targetNode.inputs[3]) - db_id = db_node.inputs[0].default_value - stage.params.append('_' + db_id) - stage.params.append(constant_name + 'D') - stage.params.append(targetId) # Color buffer - stage.params.append(constant_name + str(i)) - - elif currentNode.bl_idname == 'TargetNodeType': - targetId = currentNode.inputs[0].default_value - stage.params.append(targetId) - stage.params.append(constant_name) - - elif currentNode.bl_idname == 'DepthBufferNodeType': - targetId = '_' + currentNode.inputs[0].default_value - stage.params.append(targetId) - stage.params.append(constant_name) +def make_bind_target(stage, node_group, node, constant_name, currentNode=None, target_index=1): + if currentNode == None: + currentNode = node + + stage.command = 'bind_target' + + link = findLink(node_group, currentNode, currentNode.inputs[target_index]) + currentNode = link.from_node + + if currentNode.bl_idname == 'NodeReroute': + make_bind_target(stage, node_group, node, constant_name, currentNode=currentNode, target_index=0) + + elif currentNode.bl_idname == 'GBufferNodeType': + for i in range(0, 5): + if currentNode.inputs[i].is_linked: + targetNode = findNodeByLink(node_group, currentNode, currentNode.inputs[i]) + targetId = targetNode.inputs[0].default_value + # if i == 0 and targetNode.inputs[3].default_value == True: # Depth + if targetNode.inputs[3].is_linked: # Depth + db_node = findNodeByLink(node_group, targetNode, targetNode.inputs[3]) + db_id = db_node.inputs[0].default_value + stage.params.append('_' + db_id) + stage.params.append(constant_name + 'D') + stage.params.append(targetId) # Color buffer + stage.params.append(constant_name + str(i)) + + elif currentNode.bl_idname == 'TargetNodeType': + targetId = currentNode.inputs[0].default_value + stage.params.append(targetId) + stage.params.append(constant_name) + + elif currentNode.bl_idname == 'DepthBufferNodeType': + targetId = '_' + currentNode.inputs[0].default_value + stage.params.append(targetId) + stage.params.append(constant_name) def make_draw_material_quad(stage, node_group, node, shader_references, asset_references, context_index=1): - stage.command = 'draw_material_quad' - material_context = node.inputs[context_index].default_value - stage.params.append(material_context) - # Include resource and shaders - shader_context = node.inputs[context_index].default_value - scon = shader_context.split('/') - dir_name = scon[2] - # No world defs for material passes - res_name = scon[2] - asset_references.append('compiled/ShaderResources/' + dir_name + '/' + res_name + '.json') - shader_references.append('compiled/Shaders/' + dir_name + '/' + res_name) + stage.command = 'draw_material_quad' + material_context = node.inputs[context_index].default_value + stage.params.append(material_context) + # Include resource and shaders + shader_context = node.inputs[context_index].default_value + scon = shader_context.split('/') + dir_name = scon[2] + # No world defs for material passes + res_name = scon[2] + asset_references.append('compiled/ShaderResources/' + dir_name + '/' + res_name + '.json') + shader_references.append('compiled/Shaders/' + dir_name + '/' + res_name) -def make_draw_quad(stage, node_group, node, shader_references, asset_references, context_index=1): - stage.command = 'draw_shader_quad' - # Append world defs to get proper context - world_defs = bpy.data.worlds[0].world_defs - shader_context = node.inputs[context_index].default_value - scon = shader_context.split('/') - stage.params.append(scon[0] + world_defs + '/' + scon[1] + world_defs + '/' + scon[2]) - # Include resource and shaders - dir_name = scon[0] - # Append world defs - res_name = scon[1] + world_defs - asset_references.append('compiled/ShaderResources/' + dir_name + '/' + res_name + '.json') - shader_references.append('compiled/Shaders/' + dir_name + '/' + res_name) +def make_draw_quad(stage, node_group, node, shader_references, asset_references, context_index=1, shader_context=None): + stage.command = 'draw_shader_quad' + # Append world defs to get proper context + world_defs = bpy.data.worlds[0].world_defs + if shader_context == None: + shader_context = node.inputs[context_index].default_value + scon = shader_context.split('/') + stage.params.append(scon[0] + world_defs + '/' + scon[1] + world_defs + '/' + scon[2]) + # Include resource and shaders + dir_name = scon[0] + # Append world defs + res_name = scon[1] + world_defs + asset_references.append('compiled/ShaderResources/' + dir_name + '/' + res_name + '.json') + shader_references.append('compiled/Shaders/' + dir_name + '/' + res_name) def make_draw_world(stage, node_group, node, shader_references, asset_references): - stage.command = 'draw_material_quad' - wname = bpy.data.worlds[0].name - stage.params.append(wname + '_material/' + wname + '_material/env_map') # Only one world for now + stage.command = 'draw_material_quad' + wname = bpy.data.worlds[0].name + stage.params.append(wname + '_material/' + wname + '_material/env_map') # Only one world for now def make_draw_compositor(stage, node_group, node, shader_references, asset_references): - scon = 'compositor_pass' - world_defs = bpy.data.worlds[0].world_defs - compositor_defs = nodes_compositor.parse_defs(bpy.data.scenes[0].node_tree) # Thrown in scene 0 for now - defs = world_defs + compositor_defs - res_name = scon + defs - - stage.command = 'draw_shader_quad' - stage.params.append(res_name + '/' + res_name + '/' + scon) - # Include resource and shaders - asset_references.append('compiled/ShaderResources/' + scon + '/' + res_name + '.json') - shader_references.append('compiled/Shaders/' + scon + '/' + res_name) + scon = 'compositor_pass' + world_defs = bpy.data.worlds[0].world_defs + compositor_defs = nodes_compositor.parse_defs(bpy.data.scenes[0].node_tree) # Thrown in scene 0 for now + defs = world_defs + compositor_defs + res_name = scon + defs + + stage.command = 'draw_shader_quad' + stage.params.append(res_name + '/' + res_name + '/' + scon) + # Include resource and shaders + asset_references.append('compiled/ShaderResources/' + scon + '/' + res_name + '.json') + shader_references.append('compiled/Shaders/' + scon + '/' + res_name) + # Link assets + buildNodeTrees.linked_assets.append(buildNodeTrees.assets_path + 'noise256.png') def make_call_function(stage, node_group, node): - stage.command = 'call_function' - stage.params.append(node.inputs[1].default_value) + stage.command = 'call_function' + stage.params.append(node.inputs[1].default_value) def make_branch_function(stage, node_group, node): - make_call_function(stage, node_group, node) - -def process_call_function(stage, stages, node, node_group, last_bind_target, shader_references, asset_references): - # Step till merge node - stage.returns_true = [] - if node.outputs[0].is_linked: - stageNode = findNodeByLinkFrom(node_group, node, node.outputs[0]) - buildNode(stage.returns_true, stageNode, node_group, last_bind_target, shader_references, asset_references) - - stage.returns_false = [] - if node.outputs[1].is_linked: - stageNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) - margeNode = buildNode(stage.returns_false, stageNode, node_group, last_bind_target, shader_references, asset_references) - - # Continue using top level stages after merge node - afterMergeNode = findNodeByLinkFrom(node_group, margeNode, margeNode.outputs[0]) - buildNode(stages, afterMergeNode, node_group, last_bind_target, shader_references, asset_references) + make_call_function(stage, node_group, node) + +def process_call_function(stage, stages, node, node_group, shader_references, asset_references): + # Step till merge node + stage.returns_true = [] + if node.outputs[0].is_linked: + stageNode = findNodeByLinkFrom(node_group, node, node.outputs[0]) + buildNode(stage.returns_true, stageNode, node_group, shader_references, asset_references) + + stage.returns_false = [] + if node.outputs[1].is_linked: + stageNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) + margeNode = buildNode(stage.returns_false, stageNode, node_group, shader_references, asset_references) + + # Continue using top level stages after merge node + afterMergeNode = findNodeByLinkFrom(node_group, margeNode, margeNode.outputs[0]) + buildNode(stages, afterMergeNode, node_group, shader_references, asset_references) + +def make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[3, 5, 7], bind_target_constants=None, shader_context=None): + # Set target + if target_index != None and node.inputs[target_index].is_linked: + stage = Object() + stage.params = [] + make_set_target(stage, node_group, node, target_index=target_index) + stages.append(stage) + # Bind targets + stage = Object() + stage.params = [] + buildNode.last_bind_target = stage + bind_target_used = False + for i in range(0, len(bind_target_indices)): + index = bind_target_indices[i] + if node.inputs[index].is_linked: + bind_target_used = True + if bind_target_constants == None: + constant_name = node.inputs[index + 1].default_value + else: + constant_name = bind_target_constants[i] + make_bind_target(stage, node_group, node, constant_name, target_index=index) + if bind_target_used: + stages.append(stage) + stage = Object() + stage.params = [] + # Draw quad + make_draw_quad(stage, node_group, node, shader_references, asset_references, context_index=2, shader_context=shader_context) + stages.append(stage) + +def make_ssao_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[3, 4], bind_target_constants=['gbufferD', 'gbuffer0'], shader_context='ssao_pass/ssao_pass/ssao_pass') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 4], bind_target_constants=['tex', 'gbuffer0'], shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_x') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 4], bind_target_constants=['tex', 'gbuffer0'], shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y') + buildNodeTrees.linked_assets.append(buildNodeTrees.assets_path + 'noise8.png') + +def make_ssr_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[4, 5], bind_target_constants=['tex', 'gbuffer'], shader_context='ssr_pass/ssr_pass/ssr_pass') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=3, bind_target_indices=[2, 6], bind_target_constants=['tex', 'gbuffer1'], shader_context='blur_adaptive_pass/blur_adaptive_pass/blur_adaptive_pass_x') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[3, 6], bind_target_constants=['tex', 'gbuffer1'], shader_context='blur_adaptive_pass/blur_adaptive_pass/blur_adaptive_pass_y2') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[4, 2], bind_target_constants=['tex', 'tex2'], shader_context='combine_pass/combine_pass/combine_pass') + +def make_bloom_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[4], bind_target_constants=['tex'], shader_context='bloom_pass/bloom_pass/bloom_pass') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=3, bind_target_indices=[2], bind_target_constants=['tex'], shader_context='blur_gaus_pass/blur_gaus_pass/blur_gaus_pass_x') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[3], bind_target_constants=['tex'], shader_context='blur_gaus_pass/blur_gaus_pass/blur_gaus_pass_y') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[4, 2], bind_target_constants=['tex', 'tex2'], shader_context='combine_pass/combine_pass/combine_pass') + +def make_motion_blur_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='motion_blur_pass/motion_blur_pass/motion_blur_pass') + +def make_fxaa_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2], bind_target_constants=['tex'], shader_context='fxaa_pass/fxaa_pass/fxaa_pass') + +def make_smaa_pass(stages, node_group, node, shader_references, asset_references): + stage = Object() + stage.params = [] + make_set_target(stage, node_group, node, target_index=2) + stages.append(stage) + + stage = Object() + stage.params = [] + make_clear_target(stage, color_val=[0.0, 0.0, 0.0, 0.0]) + stages.append(stage) + + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=None, bind_target_indices=[4], bind_target_constants=['colorTex'], shader_context='smaa_edge_detect/smaa_edge_detect/smaa_edge_detect') + + stage = Object() + stage.params = [] + make_set_target(stage, node_group, node, target_index=3) + stages.append(stage) + + stage = Object() + stage.params = [] + make_clear_target(stage, color_val=[0.0, 0.0, 0.0, 0.0]) + stages.append(stage) + + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=None, bind_target_indices=[2], bind_target_constants=['edgesTex'], shader_context='smaa_blend_weight/smaa_blend_weight/smaa_blend_weight') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[4, 3], bind_target_constants=['colorTex', 'blendTex'], shader_context='smaa_neighborhood_blend/smaa_neighborhood_blend/smaa_neighborhood_blend') + buildNodeTrees.linked_assets.append(buildNodeTrees.assets_path + 'smaa_area.png') + buildNodeTrees.linked_assets.append(buildNodeTrees.assets_path + 'smaa_search.png') + +def make_sss_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[3, 4, 5], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='sss_pass/sss_pass/sss_pass_x') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[3, 4, 5], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='sss_pass/sss_pass/sss_pass_y') + +def make_water_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='water_pass/water_pass/water_pass') + +def make_deferred_light_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'ssaotex', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light') + +def make_translucent_resolve_pass(stages, node_group, node, shader_references, asset_references): + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2], bind_target_constants=['gbuffer'], shader_context='translucent_resolve/translucent_resolve/translucent_resolve') # Returns merge node -def buildNode(stages, node, node_group, last_bind_target, shader_references, asset_references): - stage = Object() - stage.params = [] - - append_stage = True - - if node.bl_idname == 'MergeStagesNodeType': - return node - - elif node.bl_idname == 'SetTargetNodeType': - last_bind_target = None - make_set_target(stage, node_group, node) +def buildNode(stages, node, node_group, shader_references, asset_references): + stage = Object() + stage.params = [] + + append_stage = True + + if node.bl_idname == 'MergeStagesNodeType': + return node + + elif node.bl_idname == 'SetTargetNodeType': + buildNode.last_bind_target = None + make_set_target(stage, node_group, node) + + elif node.bl_idname == 'ClearTargetNodeType': + color_val = None + depth_val = None + stencil_val = None + if node.inputs[1].default_value == True: + if node.inputs[2].is_linked: # Assume background color node is linked + color_val = bpy.data.cameras[0].world_envtex_color + else: + color_val = node.inputs[2].default_value + if node.inputs[3].default_value == True: + depth_val = node.inputs[4].default_value + if node.inputs[5].default_value == True: + stencil_val = node.inputs[6].default_value + make_clear_target(stage, color_val=color_val, depth_val=depth_val, stencil_val=stencil_val) + + elif node.bl_idname == 'DrawGeometryNodeType': + make_draw_geometry(stage, node_group, node) + + elif node.bl_idname == 'DrawDecalsNodeType': + make_draw_decals(stage, node_group, node, shader_references, asset_references) + + elif node.bl_idname == 'BindTargetNodeType': + if buildNode.last_bind_target is not None: + stage = buildNode.last_bind_target + append_stage = False + buildNode.last_bind_target = stage + constant_name = node.inputs[2].default_value + make_bind_target(stage, node_group, node, constant_name) + + elif node.bl_idname == 'DrawMaterialQuadNodeType': + make_draw_material_quad(stage, node_group, node, shader_references, asset_references) + + elif node.bl_idname == 'DrawQuadNodeType': + make_draw_quad(stage, node_group, node, shader_references, asset_references) + + elif node.bl_idname == 'DrawWorldNodeType': + # Bind depth + if node.inputs[1].is_linked: + stage = Object() + stage.params = [] + buildNode.last_bind_target = stage + if node.inputs[1].is_linked: + make_bind_target(stage, node_group, node, target_index=1, constant_name='gbufferD') + stages.append(stage) + # Draw quad + stage = Object() + stage.params = [] + make_draw_world(stage, node_group, node, shader_references, asset_references) + + elif node.bl_idname == 'DrawCompositorNodeType': + # Set target + if node.inputs[1].is_linked: + make_set_target(stage, node_group, node) + stages.append(stage) + # Bind targets + if node.inputs[2].is_linked or node.inputs[3].is_linked: + stage = Object() + stage.params = [] + buildNode.last_bind_target = stage + if node.inputs[2].is_linked: + make_bind_target(stage, node_group, node, target_index=2, constant_name='tex') + if node.inputs[3].is_linked: + make_bind_target(stage, node_group, node, target_index=3, constant_name='gbuffer') + stages.append(stage) + # Draw quad + stage = Object() + stage.params = [] + make_draw_compositor(stage, node_group, node, shader_references, asset_references) + + elif node.bl_idname == 'BranchFunctionNodeType': + make_branch_function(stage, node_group, node) + stages.append(stage) + process_call_function(stage, stages, node, node_group, shader_references, asset_references) + return + + elif node.bl_idname == 'LoopStagesNodeType': + # Just repeats the commands + append_stage = False + if node.outputs[1].is_linked: + count = node.inputs[2].default_value + for i in range(0, count): + loopNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) + buildNode(stages, loopNode, node_group, shader_references, asset_references) + + elif node.bl_idname == 'LoopLightsNodeType': + append_stage = False + stage.command = 'loop_lights' + stages.append(stage) + stage.returns_true = [] + if node.outputs[1].is_linked: + loopNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) + buildNode(stage.returns_true, loopNode, node_group, shader_references, asset_references) + + elif node.bl_idname == 'CallFunctionNodeType': + make_call_function(stage, node_group, node) + + elif node.bl_idname == 'QuadPassNodeType': + make_quad_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + + elif node.bl_idname == 'SSAOPassNodeType': + make_ssao_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'SSRPassNodeType': + make_ssr_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'BloomPassNodeType': + make_bloom_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'MotionBlurPassNodeType': + make_motion_blur_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'FXAAPassNodeType': + make_fxaa_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'SMAAPassNodeType': + make_smaa_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'SSSPassNodeType': + make_sss_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'WaterPassNodeType': + make_water_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'DeferredLightPassNodeType': + make_deferred_light_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + elif node.bl_idname == 'TranslucentResolvePassNodeType': + make_translucent_resolve_pass(stages, node_group, node, shader_references, asset_references) + append_stage = False + + if append_stage: + stages.append(stage) + + # Build next stage + if node.outputs[0].is_linked: + stageNode = findNodeByLinkFrom(node_group, node, node.outputs[0]) + buildNode(stages, stageNode, node_group, shader_references, asset_references) +# Used to merge bind target nodes into one stage +buildNode.last_bind_target = None +# Used to determine shadowmap size +buildNode.last_set_target_w = 0 +buildNode.last_set_target_h = 0 + - elif node.bl_idname == 'ClearTargetNodeType': - make_clear_target(stage, node_group, node) - - elif node.bl_idname == 'DrawGeometryNodeType': - make_draw_geometry(stage, node_group, node) - - elif node.bl_idname == 'DrawDecalsNodeType': - make_draw_decals(stage, node_group, node, shader_references, asset_references) - - elif node.bl_idname == 'BindTargetNodeType': - if last_bind_target is not None: - stage = last_bind_target - append_stage = False - last_bind_target = stage - make_bind_target(stage, node_group, node) - - elif node.bl_idname == 'DrawMaterialQuadNodeType': - make_draw_material_quad(stage, node_group, node, shader_references, asset_references) - - elif node.bl_idname == 'DrawQuadNodeType': - make_draw_quad(stage, node_group, node, shader_references, asset_references) - - elif node.bl_idname == 'DrawWorldNodeType': - # Bind depth - if node.inputs[1].is_linked: - stage = Object() - stage.params = [] - last_bind_target = stage - if node.inputs[1].is_linked: - make_bind_target(stage, node_group, node, target_index=1, constant_name='gbufferD') - stages.append(stage) - # Draw quad - stage = Object() - stage.params = [] - make_draw_world(stage, node_group, node, shader_references, asset_references) - - elif node.bl_idname == 'DrawCompositorNodeType': - # Set target - if node.inputs[1].is_linked: - make_set_target(stage, node_group, node) - stages.append(stage) - # Bind targets - if node.inputs[2].is_linked or node.inputs[3].is_linked: - stage = Object() - stage.params = [] - last_bind_target = stage - if node.inputs[2].is_linked: - make_bind_target(stage, node_group, node, target_index=2, constant_name='tex') - if node.inputs[3].is_linked: - make_bind_target(stage, node_group, node, target_index=3, constant_name='gbuffer') - stages.append(stage) - # Draw quad - stage = Object() - stage.params = [] - make_draw_compositor(stage, node_group, node, shader_references, asset_references) - - elif node.bl_idname == 'BranchFunctionNodeType': - make_branch_function(stage, node_group, node) - stages.append(stage) - process_call_function(stage, stages, node, node_group, last_bind_target, shader_references, asset_references) - return - - elif node.bl_idname == 'LoopStagesNodeType': - # Just repeats the commands - append_stage = False - if node.outputs[1].is_linked: - count = node.inputs[2].default_value - for i in range(0, count): - loopNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) - buildNode(stages, loopNode, node_group, last_bind_target, shader_references, asset_references) - - elif node.bl_idname == 'LoopLightsNodeType': - append_stage = False - stage.command = 'loop_lights' - stages.append(stage) - stage.returns_true = [] - if node.outputs[1].is_linked: - loopNode = findNodeByLinkFrom(node_group, node, node.outputs[1]) - buildNode(stage.returns_true, loopNode, node_group, last_bind_target, shader_references, asset_references) - - elif node.bl_idname == 'CallFunctionNodeType': - make_call_function(stage, node_group, node) - - elif node.bl_idname == 'QuadPassNodeType': - # Set target - if node.inputs[1].is_linked: - make_set_target(stage, node_group, node) - stages.append(stage) - # Bind targets - stage = Object() - stage.params = [] - last_bind_target = stage - bind_target_used = False - for i in [3, 5, 7]: - if node.inputs[i].is_linked: - bind_target_used = True - make_bind_target(stage, node_group, node, target_index=i, constant_index=(i + 1)) - if bind_target_used: - stages.append(stage) - stage = Object() - stage.params = [] - # Draw quad - make_draw_quad(stage, node_group, node, shader_references, asset_references, context_index=2) - - if append_stage: - stages.append(stage) - - # Build next stage - if node.outputs[0].is_linked: - stageNode = findNodeByLinkFrom(node_group, node, node.outputs[0]) - buildNode(stages, stageNode, node_group, last_bind_target, shader_references, asset_references) - def findNodeByLink(node_group, to_node, inp): - for link in node_group.links: - if link.to_node == to_node and link.to_socket == inp: - return link.from_node + for link in node_group.links: + if link.to_node == to_node and link.to_socket == inp: + return link.from_node def findLink(node_group, to_node, inp): - for link in node_group.links: - if link.to_node == to_node and link.to_socket == inp: - return link - + for link in node_group.links: + if link.to_node == to_node and link.to_socket == inp: + return link + def findNodeByLinkFrom(node_group, from_node, outp): - for link in node_group.links: - if link.from_node == from_node and link.from_socket == outp: - return link.to_node - + for link in node_group.links: + if link.from_node == from_node and link.from_socket == outp: + return link.to_node + def getRootNode(node_group): - # Find first node linked to begin node - for n in node_group.nodes: - if n.bl_idname == 'BeginNodeType': - return findNodeByLinkFrom(node_group, n, n.outputs[0]) + # Find first node linked to begin node + for n in node_group.nodes: + if n.bl_idname == 'BeginNodeType': + # Store contexts + bpy.data.cameras[0].pipeline_id = n.inputs[0].default_value + bpy.data.cameras[0].geometry_context = n.inputs[1].default_value + bpy.data.cameras[0].shadows_context = n.inputs[2].default_value + bpy.data.cameras[0].translucent_context = n.inputs[3].default_value + return findNodeByLinkFrom(node_group, n, n.outputs[0]) def get_render_targets(root_node, node_group): - render_targets = [] - depth_buffers = [] - traverse_for_rt(root_node, node_group, render_targets, depth_buffers) - return render_targets, depth_buffers - + render_targets = [] + depth_buffers = [] + traverse_for_rt(root_node, node_group, render_targets, depth_buffers) + return render_targets, depth_buffers + def traverse_for_rt(node, node_group, render_targets, depth_buffers): - # Collect render targets - if node.bl_idname == 'SetTargetNodeType' or node.bl_idname == 'QuadPassNodeType': - if node.inputs[1].is_linked: - tnode = findNodeByLink(node_group, node, node.inputs[1]) - parse_render_target(tnode, node_group, render_targets, depth_buffers) - - # Traverse loops - if node.bl_idname == 'LoopStagesNodeType' or node.bl_idname == 'LoopLightsNodeType': - if node.outputs[1].is_linked: - loop_node = findNodeByLinkFrom(node_group, node, node.outputs[1]) - traverse_for_rt(loop_node, node_group, render_targets, depth_buffers) - - # Next stage - if node.outputs[0].is_linked: - stagenode = findNodeByLinkFrom(node_group, node, node.outputs[0]) - traverse_for_rt(stagenode, node_group, render_targets, depth_buffers) - + # Collect render targets + if node.bl_idname == 'SetTargetNodeType' or node.bl_idname == 'QuadPassNodeType': + if node.inputs[1].is_linked: + tnode = findNodeByLink(node_group, node, node.inputs[1]) + parse_render_target(tnode, node_group, render_targets, depth_buffers) + + # Traverse loops + elif node.bl_idname == 'LoopStagesNodeType' or node.bl_idname == 'LoopLightsNodeType': + if node.outputs[1].is_linked: + loop_node = findNodeByLinkFrom(node_group, node, node.outputs[1]) + traverse_for_rt(loop_node, node_group, render_targets, depth_buffers) + + # Prebuilt + elif node.bl_idname == 'MotionBlurPassNodeType' or node.bl_idname == 'FXAAPassNodeType' or node.bl_idname == 'WaterPassNodeType' or node.bl_idname == 'DeferredLightPassNodeType' or node.bl_idname == 'TranslucentResolvePassNodeType': + if node.inputs[1].is_linked: + tnode = findNodeByLink(node_group, node, node.inputs[1]) + parse_render_target(tnode, node_group, render_targets, depth_buffers) + elif node.bl_idname == 'SSRPassNodeType' or node.bl_idname == 'BloomPassNodeType' or node.bl_idname == 'SMAAPassNodeType': + for i in range(1, 4): + if node.inputs[i].is_linked: + tnode = findNodeByLink(node_group, node, node.inputs[i]) + parse_render_target(tnode, node_group, render_targets, depth_buffers) + elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'SSSPassNodeType': + for i in range(1, 3): + if node.inputs[i].is_linked: + tnode = findNodeByLink(node_group, node, node.inputs[i]) + parse_render_target(tnode, node_group, render_targets, depth_buffers) + + # Next stage + if node.outputs[0].is_linked: + stagenode = findNodeByLinkFrom(node_group, node, node.outputs[0]) + traverse_for_rt(stagenode, node_group, render_targets, depth_buffers) + def parse_render_target(node, node_group, render_targets, depth_buffers): - if node.bl_idname == 'NodeReroute': - tnode = findNodeByLink(node_group, node, node.inputs[0]) - parse_render_target(tnode, node_group, render_targets, depth_buffers) - - elif node.bl_idname == 'TargetNodeType': - # Target already exists - id = node.inputs[0].default_value - for t in render_targets: - if t.id == id: - return - - depth_buffer_id = None - if node.inputs[3].is_linked: - # Find depth buffer - depth_node = findNodeByLink(node_group, node, node.inputs[3]) - depth_buffer_id = depth_node.inputs[0].default_value - # Append depth buffer - found = False - for db in depth_buffers: - if db.id == depth_buffer_id: - found = True - break - if found == False: - db = Object() - db.id = depth_buffer_id - db.stencil_buffer = depth_node.inputs[1].default_value - depth_buffers.append(db) - # Get scale - scale = 1.0 - if node.inputs[1].is_linked: - size_node = findNodeByLink(node_group, node, node.inputs[1]) - scale = size_node.inputs[0].default_value - - # Append target - target = make_render_target(node, scale, depth_buffer_id=depth_buffer_id) - render_targets.append(target) - - elif node.bl_idname == 'GBufferNodeType': - for i in range(0, 5): - if node.inputs[i].is_linked: - n = findNodeByLink(node_group, node, node.inputs[i]) - parse_render_target(n, node_group, render_targets, depth_buffers) + if node.bl_idname == 'NodeReroute': + tnode = findNodeByLink(node_group, node, node.inputs[0]) + parse_render_target(tnode, node_group, render_targets, depth_buffers) + + elif node.bl_idname == 'TargetNodeType': + # Target already exists + id = node.inputs[0].default_value + for t in render_targets: + if t.id == id: + return + + depth_buffer_id = None + if node.inputs[3].is_linked: + # Find depth buffer + depth_node = findNodeByLink(node_group, node, node.inputs[3]) + depth_buffer_id = depth_node.inputs[0].default_value + # Append depth buffer + found = False + for db in depth_buffers: + if db.id == depth_buffer_id: + found = True + break + if found == False: + db = Object() + db.id = depth_buffer_id + db.stencil_buffer = depth_node.inputs[1].default_value + depth_buffers.append(db) + # Get scale + scale = 1.0 + if node.inputs[1].is_linked: + size_node = findNodeByLink(node_group, node, node.inputs[1]) + scale = size_node.inputs[0].default_value + + # Append target + target = make_render_target(node, scale, depth_buffer_id=depth_buffer_id) + render_targets.append(target) + + elif node.bl_idname == 'GBufferNodeType': + for i in range(0, 5): + if node.inputs[i].is_linked: + n = findNodeByLink(node_group, node, node.inputs[i]) + parse_render_target(n, node_group, render_targets, depth_buffers) def make_render_target(n, scale, depth_buffer_id=None): - target = Object() - target.id = n.inputs[0].default_value - target.width = n.inputs[1].default_value - target.height = n.inputs[2].default_value - target.format = n.inputs[4].default_value - target.ping_pong = n.inputs[5].default_value - if scale != 1.0: - target.scale = scale - if depth_buffer_id != None: - target.depth_buffer = depth_buffer_id - return target - \ No newline at end of file + target = Object() + target.id = n.inputs[0].default_value + target.width = n.inputs[1].default_value + target.height = n.inputs[2].default_value + target.format = n.inputs[4].default_value + target.ping_pong = n.inputs[5].default_value + if scale != 1.0: + target.scale = scale + if depth_buffer_id != None: + target.depth_buffer = depth_buffer_id + return target + \ No newline at end of file diff --git a/blender/nodes_world.py b/blender/nodes_world.py index ad90cc26..77f71274 100755 --- a/blender/nodes_world.py +++ b/blender/nodes_world.py @@ -67,6 +67,11 @@ def buildNodeTree(world_name, node_group, shader_references, asset_references): if output_node != None: parse_world_output(node_group, output_node, context) + # Clear to color if no texture or sky is provided + world_defs = bpy.data.worlds[0].world_defs + if '_EnvSky' not in world_defs and '_EnvTex' not in world_defs: + world_defs += '_EnvCol' + # Enable probes for cam in bpy.data.cameras: if cam.is_probe: @@ -75,7 +80,6 @@ def buildNodeTree(world_name, node_group, shader_references, asset_references): # Add resources to khafie dir_name = 'env_map' # Append world defs - world_defs = bpy.data.worlds[0].world_defs res_name = 'env_map' + world_defs # Reference correct shader context res.shader = res_name + '/' + res_name @@ -94,6 +98,7 @@ def parse_world_output(node_group, node, context): def parse_surface(node_group, node, context): # Extract environment strength if node.type == 'BACKGROUND': + bpy.data.cameras[0].world_envtex_color = node.inputs[0].default_value bpy.data.cameras[0].world_envtex_strength = node.inputs[1].default_value # Strength diff --git a/blender/project.py b/blender/project.py index 942606df..dfa5db99 100755 --- a/blender/project.py +++ b/blender/project.py @@ -6,8 +6,7 @@ import platform import json from bpy.props import * import subprocess -from subprocess import call -import atexit +import threading import webbrowser import write_data import nodes_logic @@ -20,18 +19,48 @@ import lib.make_variants import utils def init_armory_props(): - if not 'CGVersion' in bpy.data.worlds[0]: - wrd = bpy.data.worlds[0] + # First run + wrd = bpy.data.worlds[0] + if wrd.CGVersion == '': + wrd.use_fake_user = True # Store data in worlds[0], add fake user to keep it alive + wrd.CGVersion = '16.7' + wrd.CGProjectTarget = 'HTML5' + # Take blend file name + wrd.CGProjectName = bpy.path.basename(bpy.context.blend_data.filepath).rsplit('.')[0] + wrd.CGProjectPackage = 'game' + wrd.CGProjectWidth = 800 + wrd.CGProjectHeight = 600 wrd.CGProjectScene = bpy.data.scenes[0].name + wrd.CGProjectSamplesPerPixel = 1 + wrd.CGPhysics = 'Bullet' + wrd.CGKhafileConfig = '' + wrd.CGMinimize = True + wrd.CGCacheShaders = True + wrd.CGPlayViewportCamera = False + wrd.CGPlayConsole = False + wrd.CGPlayDeveloperTools = False # Switch to Cycles if bpy.data.scenes[0].render.engine == 'BLENDER_RENDER': for scene in bpy.data.scenes: scene.render.engine = 'CYCLES' + # Use nodes + for w in bpy.data.worlds: + w.use_nodes = True + for s in bpy.data.scenes: + s.use_nodes = True + for l in bpy.data.lamps: + l.use_nodes = True + for m in bpy.data.materials: + m.use_nodes = True + utils.fetch_script_names() # Play button in 3D View panel def draw_play_item(self, context): layout = self.layout - layout.operator("arm.play") + if play_project.playproc == None: + layout.operator("arm.play_in_frame") + else: + layout.operator("arm.stop") # Menu in render region class ArmoryProjectPanel(bpy.types.Panel): @@ -74,6 +103,20 @@ class ArmoryBuildPanel(bpy.types.Panel): layout.prop(wrd, 'CGCacheShaders') layout.label('Armory v' + wrd.CGVersion) +class ArmoryPlayPanel(bpy.types.Panel): + bl_label = "Armory Play" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "render" + + def draw(self, context): + layout = self.layout + wrd = bpy.data.worlds[0] + layout.operator("arm.play") + layout.prop(wrd, 'CGPlayViewportCamera') + layout.prop(wrd, 'CGPlayConsole') + layout.prop(wrd, 'CGPlayDeveloperTools') + def get_export_scene_override(scene): # None for now override = { @@ -87,8 +130,9 @@ def get_export_scene_override(scene): def compile_shader(raw_path, shader_name, defs): os.chdir(raw_path + './' + shader_name) - lib.make_resources.make(shader_name + '.shader.json', minimize=bpy.data.worlds[0].CGMinimize, defs=defs) - lib.make_variants.make(shader_name + '.shader.json', defs) + fp = os.path.relpath(utils.get_fp()) + lib.make_resources.make(shader_name + '.shader.json', fp, minimize=bpy.data.worlds[0].CGMinimize, defs=defs) + lib.make_variants.make(shader_name + '.shader.json', fp, defs) def def_strings_to_array(strdefs): defs = strdefs.split('_') @@ -96,7 +140,10 @@ def def_strings_to_array(strdefs): defs = ['_' + d for d in defs] # Restore _ return defs -def export_game_data(fp, raw_path): +def export_game_data(fp, sdk_path): + raw_path = sdk_path + 'armory/raw/' + assets_path = sdk_path + 'armory/Assets/' + shader_references = [] asset_references = [] @@ -104,7 +151,7 @@ def export_game_data(fp, raw_path): # TODO: cache nodes_logic.buildNodeTrees() nodes_world.buildNodeTrees(shader_references, asset_references) # TODO: Have to build nodes everytime to collect env map resources - nodes_pipeline.buildNodeTrees(shader_references, asset_references) + linked_assets = nodes_pipeline.buildNodeTrees(shader_references, asset_references, assets_path) # TODO: Set armatures to center of world so skin transform is zero armatures = [] @@ -135,12 +182,6 @@ def export_game_data(fp, raw_path): a.armature.location.y = a.y a.armature.location.z = a.z - # Write khafile.js - write_data.write_khafilejs(shader_references, asset_references) - - # Write Main.hx - write_data.write_main() - # Clean compiled variants if cache is disabled if bpy.data.worlds[0].CGCacheShaders == False: if os.path.isdir("compiled"): @@ -161,6 +202,46 @@ def export_game_data(fp, raw_path): else: defs = [] compile_shader(raw_path, shader_name, defs) + # Add linked assets from shader resources + asset_references += linked_assets + # Reset path + os.chdir(fp) + + # Write compiled.glsl + clip_start = bpy.data.cameras[0].clip_start # Same clip values for all cameras for now + clip_end = bpy.data.cameras[0].clip_end + shadowmap_size = bpy.data.worlds[0].shadowmap_size + write_data.write_compiledglsl(clip_start, clip_end, shadowmap_size) + + # Write khafile.js + write_data.write_khafilejs(shader_references, asset_references) + + # Write Main.hx + write_data.write_main() + +def compile_project(self, target_index=None): + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path + + # Set build command + if target_index == None: + target_index = bpy.data.worlds[0]['CGProjectTarget'] + targets = ['html5', 'windows', 'osx', 'linux', 'ios', 'android-native'] + + # Copy ammo.js if necessary + if target_index == 0 and bpy.data.worlds[0].CGPhysics == 'Bullet': + ammojs_path = sdk_path + '/haxebullet/js/ammo/ammo.js' + if not os.path.isfile('build/html5/ammo.js'): + shutil.copy(ammojs_path, 'build/html5') + if not os.path.isfile('build/debug-html5/ammo.js'): + shutil.copy(ammojs_path, 'build/debug-html5') + + node_path = sdk_path + '/nodejs/node-osx' + khamake_path = sdk_path + '/KodeStudio/KodeStudio.app/Contents/Resources/app/extensions/kha/Kha/make' + cmd = [node_path, khamake_path, targets[target_index]] + self.report({'INFO'}, "Building, see console...") + return subprocess.Popen(cmd) def build_project(self): # Save blend @@ -170,7 +251,6 @@ def build_project(self): user_preferences = bpy.context.user_preferences addon_prefs = user_preferences.addons['armory'].preferences sdk_path = addon_prefs.sdk_path - scripts_path = sdk_path + '/armory/blender/' raw_path = sdk_path + '/armory/raw/' # Set dir @@ -186,82 +266,145 @@ def build_project(self): os.makedirs('Sources') if not os.path.exists('Assets'): os.makedirs('Assets') - + if not os.path.isdir('build/html5'): + os.makedirs('build/html5') + if not os.path.isdir('build/debug-html5'): + os.makedirs('build/debug-html5') + # Compile path tracer shaders if len(bpy.data.cameras) > 0 and bpy.data.cameras[0].pipeline_path == 'pathtrace_pipeline': path_tracer.compile(raw_path + 'pt_trace_pass/pt_trace_pass.frag.glsl') # Export data - export_game_data(fp, raw_path) - - # Set build command - target_index = bpy.data.worlds[0]['CGProjectTarget'] - targets = ['html5', 'windows', 'osx', 'linux', 'ios', 'android-native'] + export_game_data(fp, sdk_path) - # Copy ammo.js if necessary - # if target_index == '0': - # if not os.path.isfile('build/html5/ammo.js'): - # ammojs_path = utils.get_fp() + '/../haxebullet/js/ammo/ammo.js' - # shutil.copy(ammojs_path, 'build/html5') +def stop_project(self): + if play_project.playproc != None: + play_project.playproc.terminate() + play_project.playproc = None - node_path = sdk_path + '/nodejs/node-osx' - khamake_path = sdk_path + '/KodeStudio.app/Contents/Resources/app/extensions/kha/Kha/make' - os.system(node_path + ' ' + khamake_path + ' ' + targets[target_index] + ' &') - - self.report({'INFO'}, "Building, see console...") +def watch_play(): + if play_project.playproc == None: + return + if play_project.playproc.poll() == None: + threading.Timer(0.5, watch_play).start() + else: + play_project.playproc = None -def play_project(self): - pass +def watch_compile(): + if play_project.compileproc.poll() == None: + threading.Timer(0.1, watch_compile).start() + else: + play_project.compileproc = None + on_compiled() + +def play_project(self, in_frame): + # Build data + build_project(self) + + if in_frame == False: + # Windowed player + wrd = bpy.data.worlds[0] + x = 0 + y = 0 + w = wrd.CGProjectWidth + h = wrd.CGProjectHeight + winoff = 0 + else: + # Player dimensions + psize = bpy.context.user_preferences.system.pixel_size + x = bpy.context.window.x + (bpy.context.area.x - 5) / psize + y = bpy.context.window.height + 45 - (bpy.context.area.y + bpy.context.area.height) / psize + w = (bpy.context.area.width + 5) / psize + h = (bpy.context.area.height) / psize - 25 + winoff = bpy.context.window.y + bpy.context.window.height + winoff += 22 # Header + + write_data.write_electronjs(x, y, w, h, winoff, in_frame) + write_data.write_indexhtml(w, h, in_frame) + + # Compile + play_project.compileproc = compile_project(self, target_index=0) + watch_compile() + +def on_compiled(): + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path + electron_path = sdk_path + 'KodeStudio/KodeStudio.app/Contents/MacOS/Electron' + electron_app_path = './build/electron.js' + + play_project.playproc = subprocess.Popen([electron_path, electron_app_path]) + watch_play() +play_project.playproc = None +play_project.compileproc = None def clean_project(self): os.chdir(utils.get_fp()) # Remove build data - if os.path.isdir("build"): + if os.path.isdir('build'): shutil.rmtree('build') # Remove generated data - if os.path.isdir("Assets/generated"): + if os.path.isdir('Assets/generated'): shutil.rmtree('Assets/generated') # Remove generated shader variants - if os.path.isdir("compiled"): + if os.path.isdir('compiled'): shutil.rmtree('compiled') # Remove compiled nodes - nodes_path = "Sources/" + bpy.data.worlds[0].CGProjectPackage.replace(".", "/") + "/node/" + nodes_path = 'Sources/' + bpy.data.worlds[0].CGProjectPackage.replace('.', '/') + '/node/' if os.path.isdir(nodes_path): shutil.rmtree(nodes_path) - self.report({'INFO'}, "Done") + self.report({'INFO'}, 'Done') class ArmoryPlayButton(bpy.types.Operator): - bl_idname = "arm.play" - bl_label = "Play" + bl_idname = 'arm.play' + bl_label = 'Play' def execute(self, context): - play_project(self) + play_project(self, False) + return{'FINISHED'} + +class ArmoryPlayInFrameButton(bpy.types.Operator): + bl_idname = 'arm.play_in_frame' + bl_label = 'Play' + + def execute(self, context): + play_project(self, True) + return{'FINISHED'} + +class ArmoryStopButton(bpy.types.Operator): + bl_idname = 'arm.stop' + bl_label = 'Stop' + + def execute(self, context): + stop_project(self) return{'FINISHED'} class ArmoryBuildButton(bpy.types.Operator): - bl_idname = "arm.build" - bl_label = "Build" + bl_idname = 'arm.build' + bl_label = 'Build' def execute(self, context): build_project(self) + compile_project(self) return{'FINISHED'} class ArmoryFolderButton(bpy.types.Operator): - bl_idname = "arm.folder" - bl_label = "Project Folder" + bl_idname = 'arm.folder' + bl_label = 'Project Folder' def execute(self, context): webbrowser.open('file://' + utils.get_fp()) return{'FINISHED'} class ArmoryCleanButton(bpy.types.Operator): - bl_idname = "arm.clean" - bl_label = "Clean Project" + bl_idname = 'arm.clean' + bl_label = 'Clean Project' def execute(self, context): clean_project(self) diff --git a/blender/props.py b/blender/props.py index bbc4e2aa..72d2be0d 100755 --- a/blender/props.py +++ b/blender/props.py @@ -13,7 +13,7 @@ def cb_scene_update(context): def initProperties(): # For project - bpy.types.World.CGVersion = StringProperty(name = "CGVersion", default="16.7") + bpy.types.World.CGVersion = StringProperty(name = "CGVersion", default="") bpy.types.World.CGProjectTarget = EnumProperty( items = [('HTML5', 'HTML5', 'HTML5'), ('Windows', 'Windows', 'Windows'), @@ -33,8 +33,11 @@ def initProperties(): ('Bullet', 'Bullet', 'Bullet')], name = "Physics", default='Bullet') bpy.types.World.CGKhafileConfig = StringProperty(name = "Config") - bpy.types.World.CGMinimize = BoolProperty(name="Minimize", default=True) + bpy.types.World.CGMinimize = BoolProperty(name="Minimize Data", default=True) bpy.types.World.CGCacheShaders = BoolProperty(name="Cache Shaders", default=True) + bpy.types.World.CGPlayViewportCamera = BoolProperty(name="Viewport Camera", default=False) + bpy.types.World.CGPlayConsole = BoolProperty(name="Console", default=False) + bpy.types.World.CGPlayDeveloperTools = BoolProperty(name="Developer Tools", default=False) # For object bpy.types.Object.geometry_cached = bpy.props.BoolProperty(name="Geometry Cached", default=False) # TODO: move to mesh type @@ -63,6 +66,7 @@ def initProperties(): # TODO: move to world bpy.types.Camera.world_envtex_name = bpy.props.StringProperty(name="Environment Texture", default='') bpy.types.Camera.world_envtex_num_mips = bpy.props.IntProperty(name="Number of mips", default=0) + bpy.types.Camera.world_envtex_color = bpy.props.FloatVectorProperty(name="Environment Color", size=4, default=[0,0,0,1]) bpy.types.Camera.world_envtex_strength = bpy.props.FloatProperty(name="Environment Strength", default=1.0) bpy.types.Camera.world_envtex_sun_direction = bpy.props.FloatVectorProperty(name="Sun Direction", size=3, default=[0,0,0]) bpy.types.Camera.world_envtex_turbidity = bpy.props.FloatProperty(name="Turbidity", default=1.0) @@ -70,6 +74,9 @@ def initProperties(): bpy.types.Camera.last_decal_context = bpy.props.StringProperty(name="Decal Context", default='') bpy.types.World.world_defs = bpy.props.StringProperty(name="World Shader Defs", default='') bpy.types.World.generate_radiance = bpy.props.BoolProperty(name="Generate Radiance", default=True) + bpy.types.World.shadowmap_size = bpy.props.IntProperty(name="Shadowmap Size", default=0) + bpy.types.World.scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup) + bpy.types.World.bundled_scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup) # For material bpy.types.Material.receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True) bpy.types.Material.custom_shader = bpy.props.BoolProperty(name="Custom Shader", default=False) @@ -82,7 +89,7 @@ def initProperties(): # Menu in object region class ObjectPropsPanel(bpy.types.Panel): - bl_label = "Cycles Props" + bl_label = "Armory Props" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "object" @@ -101,7 +108,7 @@ class ObjectPropsPanel(bpy.types.Panel): # Menu in data region class DataPropsPanel(bpy.types.Panel): - bl_label = "Cycles Props" + bl_label = "Armory Props" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "data" @@ -117,14 +124,9 @@ class DataPropsPanel(bpy.types.Panel): layout.prop_search(obj.data, "probe_volume", bpy.data, "objects") layout.prop(obj.data, 'probe_strength') layout.prop(obj.data, 'probe_blending') - layout.prop(obj.data, 'frustum_culling') layout.prop(obj.data, 'sort_front_to_back') layout.prop_search(obj.data, "pipeline_path", bpy.data, "node_groups") - layout.prop(obj.data, 'pipeline_id') - layout.prop(obj.data, 'geometry_context') - layout.prop(obj.data, 'shadows_context') - layout.prop(obj.data, 'translucent_context') layout.operator("cg.reset_pipelines") elif obj.type == 'MESH': layout.prop(obj.data, 'static_usage') @@ -159,7 +161,7 @@ class OBJECT_OT_INVALIDATECACHEButton(bpy.types.Operator): # Menu in materials region class MatsPropsPanel(bpy.types.Panel): - bl_label = "Cycles Props" + bl_label = "Armory Props" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "material" @@ -177,7 +179,7 @@ class MatsPropsPanel(bpy.types.Panel): # Menu in world region class WorldPropsPanel(bpy.types.Panel): - bl_label = "Cycles Props" + bl_label = "Armory Props" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "world" diff --git a/blender/start.py b/blender/start.py index 49a0dc96..f5b27c29 100755 --- a/blender/start.py +++ b/blender/start.py @@ -8,7 +8,14 @@ import traits_params import traits import props +import bpy +import utils +import subprocess +import atexit +import os + def register(): + props.register() project.register() nodes_logic.register() nodes_pipeline.register() @@ -17,7 +24,16 @@ def register(): traits_animation.register() traits_params.register() traits.register() - props.register() + + # Start server + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + scripts_path = addon_prefs.sdk_path + '/armory/blender/' + os.chdir(utils.get_fp()) + blender_path = bpy.app.binary_path + blend_path = bpy.data.filepath + register.p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'lib/server.py', '&']) + atexit.register(register.p.terminate) def unregister(): project.unregister() @@ -29,3 +45,6 @@ def unregister(): traits_params.unregister() traits.unregister() props.unregister() + + # Stop server + register.p.terminate() diff --git a/blender/traits.py b/blender/traits.py index 0ced83ed..27cf7563 100755 --- a/blender/traits.py +++ b/blender/traits.py @@ -2,17 +2,20 @@ import shutil import bpy import os import json -from traits_animation import ListAnimationTraitItem -from traits_params import ListParamsTraitItem +from traits_animation import * +from traits_params import * from bpy.types import Menu, Panel, UIList from bpy.props import * +import utils +import write_data +import subprocess class ListTraitItem(bpy.types.PropertyGroup): # Group of properties representing an item in the list name = bpy.props.StringProperty( name="Name", description="A name for this item", - default="Untitled") + default="") enabled_prop = bpy.props.BoolProperty( name="", @@ -21,6 +24,7 @@ class ListTraitItem(bpy.types.PropertyGroup): type_prop = bpy.props.EnumProperty( items = [('Script', 'Script', 'Script'), + ('Bundled Script', 'Bundled Script', 'Bundled Script'), ('Nodes', 'Nodes', 'Nodes'), ('Scene Instance', 'Scene Instance', 'Scene Instance'), ('Animation', 'Animation', 'Animation') @@ -40,7 +44,7 @@ class ListTraitItem(bpy.types.PropertyGroup): class_name_prop = bpy.props.StringProperty( name="Class", description="A name for this item", - default="Untitled") + default="") nodes_name_prop = bpy.props.StringProperty( name="Nodes", @@ -52,6 +56,12 @@ class ListTraitItem(bpy.types.PropertyGroup): description="A name for this item", default="") + my_paramstraitlist = bpy.props.CollectionProperty(type = ListParamsTraitItem) + paramstraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) + + my_animationtraitlist = bpy.props.CollectionProperty(type = ListAnimationTraitItem) + animationtraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) + class MY_UL_TraitList(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): # We could write some code to decide which icon to use here... @@ -152,10 +162,51 @@ class LIST_OT_TraitMoveItem(bpy.types.Operator): return{'CANCELLED'} return{'FINISHED'} +class ArmoryEditScriptButton(bpy.types.Operator): + bl_idname = 'arm.edit_script' + bl_label = 'Edit Script' + + def execute(self, context): + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path + kode_path = sdk_path + '/KodeStudio/KodeStudio.app/Contents/MacOS/Electron' + project_path = utils.get_fp() + item = context.object.my_traitlist[context.object.traitlist_index] + hx_path = project_path + '/Sources/' + bpy.data.worlds[0].CGProjectPackage + '/' + item.class_name_prop + '.hx' + subprocess.call([kode_path + ' -cmd ' + utils.get_fp() + ' ' + hx_path + ' &'], shell=True) + return{'FINISHED'} + +class ArmoryNewScriptDialog(bpy.types.Operator): + bl_idname = "arm.new_script" + bl_label = "New Script" + + class_name = StringProperty(name="Name") + + def execute(self, context): + self.class_name = self.class_name.replace(' ', '') + write_data.write_traithx(self.class_name) + utils.fetch_script_names() + obj = context.object + item = obj.my_traitlist[obj.traitlist_index] + item.class_name_prop = self.class_name + return {'FINISHED'} + + def invoke(self, context, event): + self.class_name = 'MyTrait' + return context.window_manager.invoke_props_dialog(self) + +class ArmoryRefreshScriptsListButton(bpy.types.Operator): + bl_idname = 'arm.refresh_scripts_list' + bl_label = 'Refresh Scripts List' + + def execute(self, context): + utils.fetch_script_names() + return{'FINISHED'} # Menu in tools region class ToolsTraitsPanel(bpy.types.Panel): - bl_label = "Cycles Traits" + bl_label = "Armory Traits" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "object" @@ -188,31 +239,43 @@ class ToolsTraitsPanel(bpy.types.Panel): row.prop(item, "type_prop") # Script - if item.type_prop =='Script': + if item.type_prop == 'Script' or item.type_prop == 'Bundled Script': item.name = item.class_name_prop row = layout.row() - row.prop(item, "class_name_prop") + # row.prop(item, "class_name_prop") + if item.type_prop == 'Script': + row.prop_search(item, "class_name_prop", bpy.data.worlds[0], "scripts_list", "Class") + else: + row.prop_search(item, "class_name_prop", bpy.data.worlds[0], "bundled_scripts_list", "Class") # Params layout.label("Parameters") paramsrow = layout.row() paramsrows = 2 - if len(obj.my_animationtraitlist) > 1: + if len(item.my_paramstraitlist) > 1: paramsrows = 4 row = layout.row() - row.template_list("MY_UL_ParamsTraitList", "The_List", obj, "my_paramstraitlist", obj, "paramstraitlist_index", rows=paramsrows) + row.template_list("MY_UL_ParamsTraitList", "The_List", item, "my_paramstraitlist", item, "paramstraitlist_index", rows=paramsrows) col = row.column(align=True) col.operator("my_paramstraitlist.new_item", icon='ZOOMIN', text="") col.operator("my_paramstraitlist.delete_item", icon='ZOOMOUT', text="") - if len(obj.my_paramstraitlist) > 1: + if len(item.my_paramstraitlist) > 1: col.separator() col.operator("my_paramstraitlist.move_item", icon='TRIA_UP', text="").direction = 'UP' col.operator("my_paramstraitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN' - if obj.paramstraitlist_index >= 0 and len(obj.my_paramstraitlist) > 0: - item = obj.my_paramstraitlist[obj.paramstraitlist_index] + if item.paramstraitlist_index >= 0 and len(item.my_paramstraitlist) > 0: + item = item.my_paramstraitlist[item.paramstraitlist_index] + + if item.type_prop == 'Script': + row = layout.row() + if item.class_name_prop == '': + row.enabled = False + row.operator("arm.edit_script") + layout.operator("arm.new_script") + layout.operator("arm.refresh_scripts_list") # Nodes elif item.type_prop =='Nodes': @@ -231,28 +294,28 @@ class ToolsTraitsPanel(bpy.types.Panel): elif item.type_prop == 'Animation': item.name = item.type_prop row = layout.row() - row.prop_search(item, "start_track_name_prop", obj, "my_animationtraitlist", "Start Track") + row.prop_search(item, "start_track_name_prop", item, "my_animationtraitlist", "Start Track") # Tracks list layout.label("Tracks") animrow = layout.row() animrows = 2 - if len(obj.my_animationtraitlist) > 1: + if len(item.my_animationtraitlist) > 1: animrows = 4 row = layout.row() - row.template_list("MY_UL_AnimationTraitList", "The_List", obj, "my_animationtraitlist", obj, "animationtraitlist_index", rows=animrows) + row.template_list("MY_UL_AnimationTraitList", "The_List", item, "my_animationtraitlist", item, "animationtraitlist_index", rows=animrows) col = row.column(align=True) col.operator("my_animationtraitlist.new_item", icon='ZOOMIN', text="") col.operator("my_animationtraitlist.delete_item", icon='ZOOMOUT', text="") - if len(obj.my_animationtraitlist) > 1: + if len(item.my_animationtraitlist) > 1: col.separator() col.operator("my_animationtraitlist.move_item", icon='TRIA_UP', text="").direction = 'UP' col.operator("my_animationtraitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN' - if obj.animationtraitlist_index >= 0 and len(obj.my_animationtraitlist) > 0: - item = obj.my_animationtraitlist[obj.animationtraitlist_index] + if item.animationtraitlist_index >= 0 and len(item.my_animationtraitlist) > 0: + item = item.my_animationtraitlist[item.animationtraitlist_index] row = layout.row() row.prop(item, "start_prop") diff --git a/blender/traits_animation.py b/blender/traits_animation.py index 28594aeb..1376d923 100755 --- a/blender/traits_animation.py +++ b/blender/traits_animation.py @@ -44,18 +44,15 @@ class MY_UL_AnimationTraitList(bpy.types.UIList): layout.alignment = 'CENTER' layout.label("", icon = custom_icon) -def initObjectProperties(): - bpy.types.Object.my_animationtraitlist = bpy.props.CollectionProperty(type = ListAnimationTraitItem) - bpy.types.Object.animationtraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) - class LIST_OT_AnimationTraitNewItem(bpy.types.Operator): # Add a new item to the list bl_idname = "my_animationtraitlist.new_item" bl_label = "Add a new item" def execute(self, context): - bpy.context.object.my_animationtraitlist.add() - bpy.context.object.animationtraitlist_index += 1 + trait = context.object.my_traitlist[context.object.traitlist_index] + trait.my_animationtraitlist.add() + trait.animationtraitlist_index += 1 return{'FINISHED'} @@ -67,18 +64,20 @@ class LIST_OT_AnimationTraitDeleteItem(bpy.types.Operator): @classmethod def poll(self, context): """ Enable if there's something in the list """ - return len(bpy.context.object.my_animationtraitlist) > 0 + trait = context.object.my_traitlist[context.object.traitlist_index] + return len(trait.my_animationtraitlist) > 0 def execute(self, context): - list = bpy.context.object.my_animationtraitlist - index = bpy.context.object.animationtraitlist_index + trait = context.object.my_traitlist[context.object.traitlist_index] + list = trait.my_animationtraitlist + index = trait.animationtraitlist_index list.remove(index) if index > 0: index = index - 1 - bpy.context.object.animationtraitlist_index = index + trait.animationtraitlist_index = index return{'FINISHED'} @@ -94,13 +93,15 @@ class LIST_OT_AnimationTraitMoveItem(bpy.types.Operator): @classmethod def poll(self, context): """ Enable if there's something in the list. """ - return len(bpy.context.object.my_animationtraitlist) > 0 + trait = context.object.my_traitlist[context.object.traitlist_index] + return len(trait.my_animationtraitlist) > 0 def move_index(self): # Move index of an item render queue while clamping it - index = bpy.context.object.animationtraitlist_index - list_length = len(bpy.context.object.my_animationtraitlist) - 1 + trait = context.object.my_traitlist[context.object.traitlist_index] + index = trait.animationtraitlist_index + list_length = len(trait.my_animationtraitlist) - 1 new_index = 0 if self.direction == 'UP': @@ -113,8 +114,9 @@ class LIST_OT_AnimationTraitMoveItem(bpy.types.Operator): def execute(self, context): - list = bpy.context.object.my_animationtraitlist - index = bpy.context.object.animationtraitlist_index + trait = context.object.my_traitlist[context.object.traitlist_index] + list = trait.my_animationtraitlist + index = trait.animationtraitlist_index if self.direction == 'DOWN': neighbor = index + 1 @@ -131,7 +133,6 @@ class LIST_OT_AnimationTraitMoveItem(bpy.types.Operator): def register(): bpy.utils.register_module(__name__) - initObjectProperties() def unregister(): bpy.utils.unregister_module(__name__) diff --git a/blender/traits_params.py b/blender/traits_params.py index 2a870e12..dafa4145 100755 --- a/blender/traits_params.py +++ b/blender/traits_params.py @@ -11,13 +11,6 @@ class ListParamsTraitItem(bpy.types.PropertyGroup): name="Name", description="A name for this item", default="Untitled") - - # enabled_prop = bpy.props.BoolProperty( - # name="", - # description="A name for this item", - # default=True) - - class MY_UL_ParamsTraitList(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): @@ -34,18 +27,15 @@ class MY_UL_ParamsTraitList(bpy.types.UIList): layout.alignment = 'CENTER' layout.label("", icon = custom_icon) -def initObjectProperties(): - bpy.types.Object.my_paramstraitlist = bpy.props.CollectionProperty(type = ListParamsTraitItem) - bpy.types.Object.paramstraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) - class LIST_OT_ParamsTraitNewItem(bpy.types.Operator): # Add a new item to the list bl_idname = "my_paramstraitlist.new_item" bl_label = "Add a new item" def execute(self, context): - bpy.context.object.my_paramstraitlist.add() - bpy.context.object.paramstraitlist_index += 1 + trait = context.object.my_traitlist[context.object.traitlist_index] + trait.my_paramstraitlist.add() + trait.paramstraitlist_index += 1 return{'FINISHED'} @@ -57,18 +47,20 @@ class LIST_OT_ParamsTraitDeleteItem(bpy.types.Operator): @classmethod def poll(self, context): """ Enable if there's something in the list """ - return len(bpy.context.object.my_paramstraitlist) > 0 + trait = context.object.my_traitlist[context.object.traitlist_index] + return len(trait.my_paramstraitlist) > 0 def execute(self, context): - list = bpy.context.object.my_paramstraitlist - index = bpy.context.object.paramstraitlist_index + trait = context.object.my_traitlist[context.object.traitlist_index] + list = trait.my_paramstraitlist + index = trait.paramstraitlist_index list.remove(index) if index > 0: index = index - 1 - bpy.context.object.paramstraitlist_index = index + trait.paramstraitlist_index = index return{'FINISHED'} @@ -84,13 +76,15 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator): @classmethod def poll(self, context): """ Enable if there's something in the list. """ - return len(bpy.context.object.my_paramstraitlist) > 0 + trait = context.object.my_traitlist[context.object.traitlist_index] + return len(trait.my_paramstraitlist) > 0 def move_index(self): # Move index of an item render queue while clamping it - index = bpy.context.object.paramstraitlist_index - list_length = len(bpy.context.object.my_paramstraitlist) - 1 + trait = context.object.my_traitlist[context.object.traitlist_index] + index = trait.paramstraitlist_index + list_length = len(trait.my_paramstraitlist) - 1 new_index = 0 if self.direction == 'UP': @@ -103,8 +97,9 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator): def execute(self, context): - list = bpy.context.object.my_paramstraitlist - index = bpy.context.object.paramstraitlist_index + trait = context.object.my_traitlist[context.object.traitlist_index] + list = trait.my_paramstraitlist + index = trait.paramstraitlist_index if self.direction == 'DOWN': neighbor = index + 1 @@ -121,7 +116,6 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator): def register(): bpy.utils.register_module(__name__) - initObjectProperties() def unregister(): bpy.utils.unregister_module(__name__) diff --git a/blender/utils.py b/blender/utils.py index 9732a146..548c41c3 100755 --- a/blender/utils.py +++ b/blender/utils.py @@ -1,6 +1,7 @@ import bpy import json import os +import glob class Object: def to_JSON(self): @@ -14,13 +15,19 @@ def get_fp(): s.pop() return os.path.sep.join(s) - -# Start server -# s = bpy.data.filepath.split(os.path.sep) -# s.pop() -# fp = os.path.sep.join(s) -# os.chdir(fp) -# blender_path = bpy.app.binary_path -# blend_path = bpy.data.filepath -# p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'lib/server.py', '&']) -# atexit.register(p.terminate) +def fetch_script_names(): + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path + wrd = bpy.data.worlds[0] + wrd.bundled_scripts_list.clear() + os.chdir(sdk_path + '/armory/Sources/armory/trait') + for file in glob.glob('*.hx'): + wrd.bundled_scripts_list.add().name = file.rsplit('.')[0] + wrd.scripts_list.clear() + sources_path = get_fp() + '/Sources/' + wrd.CGProjectPackage + if os.path.isdir(sources_path): + os.chdir(sources_path) + for file in glob.glob('*.hx'): + wrd.scripts_list.add().name = file.rsplit('.')[0] + os.chdir(get_fp()) diff --git a/blender/write_data.py b/blender/write_data.py index b65d84d5..07132ff3 100644 --- a/blender/write_data.py +++ b/blender/write_data.py @@ -23,7 +23,7 @@ project.addAssets('Assets/**'); """) f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/armory')[2:] + '");\n') - f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/lue')[2:] + '");\n') + f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/iron')[2:] + '");\n') f.write('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/zui')[2:] + '");\n') if bpy.data.worlds[0]['CGPhysics'] != 0: @@ -47,23 +47,23 @@ project.addAssets('Assets/**'); # Write Main.hx def write_main(): + wrd = bpy.data.worlds[0] #if not os.path.isfile('Sources/Main.hx'): with open('Sources/Main.hx', 'w') as f: f.write( """// Auto-generated package ; class Main { - public static inline var projectName = '""" + bpy.data.worlds[0]['CGProjectName'] + """'; - public static inline var projectPackage = '""" + bpy.data.worlds[0]['CGProjectPackage'] + """'; - static inline var projectWidth = """ + str(bpy.data.worlds[0]['CGProjectWidth']) + """; - static inline var projectHeight = """ + str(bpy.data.worlds[0]['CGProjectHeight']) + """; - static inline var projectSamplesPerPixel = """ + str(bpy.data.worlds[0]['CGProjectSamplesPerPixel']) + """; - public static inline var projectScene = '""" + str(bpy.data.worlds[0]['CGProjectScene']) + """'; + public static inline var projectName = '""" + wrd['CGProjectName'] + """'; + public static inline var projectPackage = '""" + wrd['CGProjectPackage'] + """'; + static inline var projectWidth = """ + str(wrd['CGProjectWidth']) + """; + static inline var projectHeight = """ + str(wrd['CGProjectHeight']) + """; + static inline var projectSamplesPerPixel = """ + str(wrd['CGProjectSamplesPerPixel']) + """; + public static inline var projectScene = '""" + str(wrd['CGProjectScene']) + """'; public static function main() { - lue.sys.CompileTime.importPackage('lue.trait'); - lue.sys.CompileTime.importPackage('cycles.trait'); - lue.sys.CompileTime.importPackage('cycles.renderpipeline'); - lue.sys.CompileTime.importPackage('""" + bpy.data.worlds[0]['CGProjectPackage'] + """'); + iron.sys.CompileTime.importPackage('armory.trait'); + iron.sys.CompileTime.importPackage('armory.renderpipeline'); + iron.sys.CompileTime.importPackage('""" + wrd['CGProjectPackage'] + """'); #if (js && WITH_PHYSICS) untyped __js__(" function loadScript(url, callback) { @@ -83,8 +83,114 @@ class Main { } static function start() { kha.System.init({title: projectName, width: projectWidth, height: projectHeight, samplesPerPixel: projectSamplesPerPixel}, function() { - new lue.App(cycles.Root); + new iron.App(armory.Root); }); } } """) + +# Write electron.js +def write_electronjs(x, y, w, h, winoff, in_frame): + wrd = bpy.data.worlds[0] + dev_tools = wrd.CGPlayDeveloperTools + with open('build/electron.js', 'w') as f: + f.write( +"""// Auto-generated +'use strict'; +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; +let mainWindow; + +function createWindow () { """) + + if in_frame: + f.write( +""" + var point = electron.screen.getCursorScreenPoint(); + var targetDisplay = electron.screen.getDisplayNearestPoint(point); + var offY = targetDisplay.workAreaSize.height - """ + str(int(winoff)) + """; + var targetX = targetDisplay.bounds.x + """ + str(int(x)) + """; + var targetY = targetDisplay.bounds.y + """ + str(int(y)) + """ + offY; + mainWindow = new BrowserWindow({x: targetX, y: targetY, width: """ + str(int(w)) + """, height: """ + str(int(h)) + """, frame: false, autoHideMenuBar: true, useContentSize: true, movable: false, resizable: false, transparent: true, enableLargerThanScreen: true}); + mainWindow.setSkipTaskbar(true); + mainWindow.setAlwaysOnTop(true); + app.dock.setBadge(''); +""") + else: + f.write( +""" + mainWindow = new BrowserWindow({width: """ + str(int(w)) + """, height: """ + str(int(h)) + """, autoHideMenuBar: true, useContentSize: true}); +""") + f.write( +""" + //mainWindow.loadURL('file://' + __dirname + '/build/html5/index.html'); + mainWindow.loadURL('http://localhost:8040/build/html5/index.html'); + mainWindow.on('closed', function() { mainWindow = null; });""") + + if dev_tools: + f.write(""" + mainWindow.toggleDevTools();""") + + f.write(""" +} +app.on('ready', createWindow); +app.on('window-all-closed', function () { app.quit(); }); +app.on('activate', function () { if (mainWindow === null) { createWindow(); } }); +""") + +# Write index.html +def write_indexhtml(w, h, in_frame): + with open('build/html5/index.html', 'w') as f: + f.write( +""" + + + + ArmoryGame + + + + + + + +""") + +def write_compiledglsl(clip_start, clip_end, shadowmap_size): + with open('compiled/Shaders/compiled.glsl', 'w') as f: + f.write( +"""const float PI = 3.1415926535; +const float PI2 = PI * 2.0; +const vec2 cameraPlane = vec2(""" + str(int(clip_start * 100) / 100) + """, """ + str(int(clip_end * 100) / 100) + """); +const vec2 shadowmapSize = vec2(""" + str(shadowmap_size) + """, """ + str(shadowmap_size) + """); +""") + +def write_traithx(class_name): + wrd = bpy.data.worlds[0] + with open('Sources/' + wrd.CGProjectPackage + '/' + class_name + '.hx', 'w') as f: + f.write( +"""package """ + wrd.CGProjectPackage + """; + +class """ + class_name + """ extends iron.Trait { + public function new() { + super(); + + // notifyOnInit(function() { + // }); + + // notifyOnUpdate(function() { + // }); + + // notifyOnRemove(function() { + // }); + } +} +""") diff --git a/raw/compositor_pass/compositor_pass.frag.glsl b/raw/compositor_pass/compositor_pass.frag.glsl index 83e6d401..7d0db2e0 100644 --- a/raw/compositor_pass/compositor_pass.frag.glsl +++ b/raw/compositor_pass/compositor_pass.frag.glsl @@ -21,6 +21,8 @@ uniform vec3 light; uniform mat4 VP; #endif +// uniform vec2 cameraPlane; + // #ifdef _Grain // uniform float time; // #endif @@ -189,9 +191,9 @@ vec4 sampleBox(float size) { return color; } -float linearize(float depth, float znear, float zfar) { - return -zfar * znear / (depth * (zfar - znear) - zfar); -} +// float linearize(float depth) { + // return -cameraPlane.y * cameraPlane.x / (depth * (cameraPlane.y - cameraPlane.x) - cameraPlane.y); +// } // Based on lense flare implementation by musk // https://www.shadertoy.com/view/4sX3Rs @@ -302,7 +304,7 @@ void main() { // float lightDistance = distance(eye, light); // vec2 lss = lndc.xy * 0.5 + 0.5; - // float lssdepth = linearize(texture(gbuffer0, lss).a, 0.1, 1000.0); + // float lssdepth = linearize(texture(gbuffer0, lss).a); // if (lssdepth >= lightDistance) { // vec2 lensuv = (texCoord - 0.5) * 2.0; diff --git a/raw/deferred/decals.frag.glsl b/raw/deferred/decals.frag.glsl index dd2cd259..a330ca4e 100644 --- a/raw/deferred/decals.frag.glsl +++ b/raw/deferred/decals.frag.glsl @@ -47,18 +47,6 @@ mat3 cotangentFrame(vec3 nor, vec3 pos, vec2 uv) { return mat3(T * invmax, B * invmax, nor); } -// vec3 getPos(float depth) { -// vec3 vray = normalize(viewRay); -// const float znear = 0.1; -// const float zfar = 1000.0; -// const float projectionA = zfar / (zfar - znear); -// const float projectionB = (-zfar * znear) / (zfar - znear); -// float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA); -// float viewZDist = dot(eyeLook, vray); -// vec3 wposition = eye + vray * (linearDepth / viewZDist); -// return wposition; -// } - vec2 octahedronWrap(vec2 v) { return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0)); } diff --git a/raw/deferred_light/deferred_light.frag.glsl b/raw/deferred_light/deferred_light.frag.glsl index eb799950..6b9db41d 100644 --- a/raw/deferred_light/deferred_light.frag.glsl +++ b/raw/deferred_light/deferred_light.frag.glsl @@ -4,6 +4,8 @@ precision mediump float; #endif +#include "../compiled.glsl" + uniform sampler2D gbufferD; uniform sampler2D gbuffer0; uniform sampler2D gbuffer1; @@ -25,12 +27,6 @@ uniform float envmapStrength; uniform sampler2D ssaotex; uniform sampler2D shadowMap; -const float znear = 0.1; -const float zfar = 1000.0; -const vec2 shadowMapSize = vec2(2048, 2048); -const float PI = 3.1415926535; -const float TwoPI = (2.0 * PI); - // #ifdef _LTC // uniform sampler2D sltcMat; // uniform sampler2D sltcMag; @@ -101,7 +97,7 @@ vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, v vec2 envMapEquirect(vec3 normal) { float phi = acos(normal.z); float theta = atan(-normal.y, normal.x) + PI; - return vec2(theta / TwoPI, phi / PI); + return vec2(theta / PI2, phi / PI); } #ifdef _Rad @@ -172,27 +168,27 @@ float PCF(vec2 uv, float compare) { float result = 0.0; // for (int x = -1; x <= 1; x++){ // for(int y = -1; y <= 1; y++){ - // vec2 off = vec2(x, y) / shadowMapSize; - // result += texture2DShadowLerp(shadowMapSize, uv + off, compare); + // vec2 off = vec2(x, y) / shadowmapSize; + // result += texture2DShadowLerp(shadowmapSize, uv + off, compare); - vec2 off = vec2(-1, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(-1, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(-1, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); + vec2 off = vec2(-1, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(-1, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(-1, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); // } // } return result / 9.0; @@ -232,10 +228,10 @@ float PCF(vec2 uv, float compare) { } void initPoissonSamples(const in vec2 randomSeed) { - const float ANGLE_STEP = TwoPI * float(NUM_RINGS) / float(NUM_SAMPLES); + const float ANGLE_STEP = PI2 * float(NUM_RINGS) / float(NUM_SAMPLES); const float INV_NUM_SAMPLES = 1.0 / float(NUM_SAMPLES); - float angle = rand(randomSeed) * TwoPI; + float angle = rand(randomSeed) * PI2; float radius = INV_NUM_SAMPLES; float radiusStep = radius; @@ -453,8 +449,8 @@ vec3 getPos(float depth) { // return pos.xyz; vec3 vray = normalize(viewRay); - const float projectionA = zfar / (zfar - znear); - const float projectionB = (-zfar * znear) / (zfar - znear); + const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x); + const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x); // float linearDepth = projectionB / (depth - projectionA); float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA); float viewZDist = dot(eyeLook, vray); diff --git a/raw/env_map/env_map.frag.glsl b/raw/env_map/env_map.frag.glsl index 416e424e..4f82f827 100644 --- a/raw/env_map/env_map.frag.glsl +++ b/raw/env_map/env_map.frag.glsl @@ -7,6 +7,9 @@ precision mediump float; const float PI = 3.1415926; const float TwoPI = (2.0 * PI); +#ifdef _EnvCol + uniform vec3 backgroundCol; +#endif #ifdef _EnvSky uniform vec3 A; uniform vec3 B; @@ -48,11 +51,17 @@ void main() { if (texture(gbufferD, texCoord).r/* * 2.0 - 1.0*/ != 1.0) { discard; } - + +#ifdef _EnvCol + gl_FragColor = vec4(backgroundCol, 1.0); + return; +#else vec3 n = normalize(normal); - +#endif + #ifdef _EnvTex gl_FragColor = texture(envmap, envMapEquirect(n)) * envmapStrength; + return; #endif #ifdef _EnvSky @@ -65,7 +74,8 @@ void main() { float gamma_val = acos(cos_gamma); vec3 R = Z * hosekWilkie(cos_theta, gamma_val, cos_gamma) * envmapStrength; - // R = pow(R, vec3(2.2)); + R = pow(R, vec3(2.2)); gl_FragColor = vec4(R, 1.0); + return; #endif } diff --git a/raw/env_map/env_map.shader.json b/raw/env_map/env_map.shader.json index 15cfd1e8..e3a624a7 100755 --- a/raw/env_map/env_map.shader.json +++ b/raw/env_map/env_map.shader.json @@ -25,6 +25,11 @@ "id": "invP", "link": "_inverseProjectionMatrix" }, + { + "id": "backgroundCol", + "link": "_backgroundCol", + "ifdef": ["_EnvCol"] + }, { "id": "A", "link": "_hosekA", diff --git a/raw/motion_blur_pass/motion_blur_pass.frag.glsl b/raw/motion_blur_pass/motion_blur_pass.frag.glsl index 75e7b6cb..83793ec9 100644 --- a/raw/motion_blur_pass/motion_blur_pass.frag.glsl +++ b/raw/motion_blur_pass/motion_blur_pass.frag.glsl @@ -6,9 +6,10 @@ precision mediump float; #endif +#include "../compiled.glsl" + uniform sampler2D gbufferD; uniform sampler2D gbuffer0; -uniform sampler2D gbuffer1; uniform sampler2D tex; uniform mat4 prevVP; @@ -23,10 +24,8 @@ const int samples = 8; vec3 getPos(float depth, vec2 coord) { vec3 vray = normalize(viewRay); - const float znear = 0.1; - const float zfar = 1000.0; - const float projectionA = zfar / (zfar - znear); - const float projectionB = (-zfar * znear) / (zfar - znear); + const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x); + const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x); float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA); float viewZDist = dot(eyeLook, vray); vec3 wposition = eye + vray * (linearDepth / viewZDist); diff --git a/raw/ssao_pass/ssao_pass.frag.glsl b/raw/ssao_pass/ssao_pass.frag.glsl index c825bded..aea9fa65 100644 --- a/raw/ssao_pass/ssao_pass.frag.glsl +++ b/raw/ssao_pass/ssao_pass.frag.glsl @@ -19,7 +19,6 @@ precision mediump float; uniform sampler2D gbufferD; uniform sampler2D gbuffer0; -uniform sampler2D gbuffer1; uniform sampler2D snoise; uniform mat4 invVP; diff --git a/raw/ssao_pass/ssao_pass_st.frag.glsl b/raw/ssao_pass/ssao_pass_st.frag.glsl deleted file mode 100644 index 4efe6c65..00000000 --- a/raw/ssao_pass/ssao_pass_st.frag.glsl +++ /dev/null @@ -1,145 +0,0 @@ -// Based on SSAO by Reinder Nijhoff 2016 @reindernijhoff -// https://www.shadertoy.com/view/ls3GWS - -#version 450 - -#ifdef GL_ES -precision mediump float; -#endif - -#define SAMPLES 8 -#define INTENSITY 3.5 -#define SCALE 3.5 -#define BIAS 0.75 -#define SAMPLE_RAD 0.1 -#define MAX_DISTANCE 0.34 - -#define MOD3 vec3(.1031,.11369,.13787) - -uniform mat4 invP; - -uniform sampler2D gbuffer0; -uniform sampler2D gbuffer1; - -in vec2 texCoord; - -float hash12(vec2 p) -{ - vec3 p3 = fract(vec3(p.xyx) * MOD3); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -// vec3 getPosition(vec2 uv) { -// float fl = texture(iChannel0, vec2(0.)).x; -// float d = texture(iChannel0, uv).w; - -// vec2 p = uv*2.-1.; -// mat3 ca = mat3(1.,0.,0.,0.,1.,0.,0.,0.,-1./1.5); -// vec3 rd = normalize( ca * vec3(p,fl) ); - -// vec3 pos = rd * d; -// return pos; -// } -vec3 getViewPos(vec2 texCoord, float depth) { - float x = texCoord.s * 2.0 - 1.0; - float y = texCoord.t * 2.0 - 1.0; - float z = depth * 2.0 - 1.0; - vec4 posProj = vec4(x, y, z, 1.0); - vec4 posView = invP * posProj; - posView /= posView.w; - return posView.xyz; -} - -float doAmbientOcclusion(vec2 tcoord,vec2 uv, vec3 p, vec3 cnorm) -{ - // vec3 diff = getPosition(tcoord + uv) - p; - float depth = texture(gbuffer0, tcoord + uv).a; - vec3 diff = getViewPos(tcoord + uv, depth) - p; - float l = length(diff); - vec3 v = diff/l; - float d = l*SCALE; - float ao = max(0.0,dot(cnorm,v)-BIAS)*(1.0/(1.0+d)); - ao *= smoothstep(MAX_DISTANCE,MAX_DISTANCE * 0.5, l); - return ao; -} - -float spiralAO(vec2 uv, vec3 p, vec3 n, float rad) -{ - float goldenAngle = 2.4; - float ao = 0.; - float inv = 1. / float(SAMPLES); - float radius = 0.; - - float rotatePhase = hash12( uv*100. ) * 6.28; - float rStep = inv * rad; - vec2 spiralUV; - - // for (int i = 0; i < SAMPLES; i++) { - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - //} - ao *= inv; - return ao; -} - -void main() { - vec4 g0 = texture(gbuffer0, texCoord); - float depth = g0.a; - vec3 n = g0.rgb * 2.0 - 1.0; - vec3 p = getViewPos(texCoord, depth); - - float ao = 0.; - float rad = SAMPLE_RAD/p.z; - - ao = spiralAO(texCoord, p, n, rad); - - ao = 1. - ao * INTENSITY; - - gl_FragColor = vec4(ao,ao,ao,1.); -} diff --git a/raw/ssr_pass/ssr_pass.frag.glsl b/raw/ssr_pass/ssr_pass.frag.glsl index 89e7f61e..a3f94150 100644 --- a/raw/ssr_pass/ssr_pass.frag.glsl +++ b/raw/ssr_pass/ssr_pass.frag.glsl @@ -4,6 +4,8 @@ precision mediump float; #endif +#include "../compiled.glsl" + uniform sampler2D tex; uniform sampler2D gbufferD; uniform sampler2D gbuffer0; // Normal @@ -37,10 +39,8 @@ vec4 getProjectedCoord(vec3 hitCoord) { } vec3 getPos(float depth) { - const float znear = 0.1; - const float zfar = 1000.0; - const float projectionA = zfar / (zfar - znear); - const float projectionB = (-zfar * znear) / (zfar - znear); + const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x); + const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x); float linearDepth = projectionB / (projectionA - depth); return viewRay * linearDepth; } diff --git a/raw/ssr_pass/ssr_pass_kode.frag.glsl b/raw/ssr_pass/ssr_pass_kode.frag.glsl deleted file mode 100644 index f72f38e2..00000000 --- a/raw/ssr_pass/ssr_pass_kode.frag.glsl +++ /dev/null @@ -1,263 +0,0 @@ -// SSR based on implementation by Ben Hopkins -// Work in progress -#version 450 - -#ifdef GL_ES -precision mediump float; -#endif - -uniform sampler2D tex; -uniform sampler2D gbuffer0; // Normal, depth -uniform sampler2D gbuffer1; // Color, roughness -uniform mat4 P; -uniform mat4 invP; -uniform mat4 V; -uniform vec3 eye; - -in vec2 texCoord; -in vec3 cameraRay; - -vec3 ScreenSpaceToViewSpace(vec3 cameraRay, float depth) { - return (cameraRay * depth); -} - -// void swapIfBigger(inout float aa, inout float bb) { -// if( aa > bb) { -// float tmp = aa; -// aa = bb; -// bb = tmp; -// } -// } - -// Projection params: x is 1.0 (or –1.0 if currently rendering with a flipped projection matrix), y is the camera’s near plane, z is the camera’s far plane and w is 1/FarPlane. - -// Linear01Depth: Z buffer to linear 0..1 depth (0 at eye, 1 at far plane) inline float Linear01Depth( float z ) { } // Z buffer to linear depth inline float -float Linear01Depth(float z) { - // return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y); - return z; - // x = 1 - 100/0.1 = -999 - // y = 100/0.1 = 1000 - // 1 / (-999 * 200 + 1000) -} - -// double zc0, zc1; -// // OpenGL would be this: -// // zc0 = (1.0 - m_FarClip / m_NearClip) / 2.0; -// // zc1 = (1.0 + m_FarClip / m_NearClip) / 2.0; -// // D3D is this: -// zc0 = 1.0 - m_FarClip / m_NearClip; -// zc1 = m_FarClip / m_NearClip; -// // now set _ZBufferParams with (zc0, zc1, zc0/m_FarClip, zc1/m_FarClip); - - // // Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt) - // // x = 1-far/near - // // y = far/near - // // z = x/far - // // w = y/far - // uniform float4 _ZBufferParams; - -bool rayIntersectsDepthBF(float zA, float zB, vec2 uv) { - // vec4 uv4 = vec4(uv, 0.0, 0.0); - vec2 uv4 = uv; - float cameraZ = Linear01Depth(texture(gbuffer0, uv4).a) * - 100.0;//_ProjectionParams.z; - float backZ = texture(_BackFaceDepthTex, uv4).r * - 100;//_ProjectionParams.z; - - return zB <= cameraZ && zA >= backZ - _PixelZSize; -} - -float distanceSquared( vec2 a, vec2 b) { a -= b; return dot(a, a); } - - -// Trace a ray in screenspace from rayOrigin (in camera space) pointing in rayDirection (in camera space) -// using jitter to offset the ray based on (jitter * _PixelStride). -// -// Returns true if the ray hits a pixel in the depth buffer -// and outputs the hitPixel (in UV space), the hitPoint (in camera space) and the number -// of iterations it took to get there. -bool traceScreenSpaceRay( vec3 rayOrigin, - vec3 rayDirection, - float jitter, - out vec2 hitPixel, - out vec3 hitPoint, - out float iterationCount, bool debugHalf) { - // Clip to the near plane - float rayLength = ((rayOrigin.z + rayDirection.z * _MaxRayDistance) > -_ProjectionParams.y) ? - (-_ProjectionParams.y - rayOrigin.z) / rayDirection.z : _MaxRayDistance; - vec3 rayEnd = rayOrigin + rayDirection * rayLength; - - // Project into homogeneous clip space - vec4 H0 = P * vec4( rayOrigin, 1.0); - vec4 H1 = P * vec4( rayEnd, 1.0); - - float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w; - - // The interpolated homogeneous version of the camera-space points - vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1; - - // Screen-space endpoints - vec2 P0 = H0.xy * k0, P1 = H1.xy * k1; - - // If the line is degenerate, make it cover at least one pixel - // to avoid handling zero-pixel extent as a special case later - P1 += (distanceSquared(P0, P1) < 0.0001) ? 0.01 : 0.0; - - vec2 delta = P1 - P0; - - // Permute so that the primary iteration is in x to collapse - // all quadrant-specific DDA cases later - bool permute = false; - if (abs(delta.x) < abs(delta.y)) { - // This is a more-vertical line - permute = true; delta = delta.yx; P0 = P0.yx; P1 = P1.yx; - } - - float stepDir = sign(delta.x); - float invdx = stepDir / delta.x; - - // Track the derivatives of Q and k - vec3 dQ = (Q1 - Q0) * invdx; - float dk = (k1 - k0) * invdx; - vec2 dP = vec2(stepDir, delta.y * invdx); - - // Calculate pixel stride based on distance of ray origin from camera. - // Since perspective means distant objects will be smaller in screen space - // we can use this to have higher quality reflections for far away objects - // while still using a large pixel stride for near objects (and increase performance) - // this also helps mitigate artifacts on distant reflections when we use a large - // pixel stride. - float strideScaler = 1.0 - min( 1.0, -rayOrigin.z / _PixelStrideZCuttoff); - float pixelStride = 1.0 + strideScaler * _PixelStride; - - // Scale derivatives by the desired pixel stride and then - // offset the starting values by the jitter fraction - dP *= pixelStride; dQ *= pixelStride; dk *= pixelStride; - P0 += dP * jitter; Q0 += dQ * jitter; k0 += dk * jitter; - - float i, zA = 0.0, zB = 0.0; - - // Track ray step and derivatives in a float4 to parallelize - float4 pqk = float4( P0, Q0.z, k0); - float4 dPQK = float4( dP, dQ.z, dk); - bool intersect = false; - - for( i=0; i<_Iterations && intersect == false; i++) { - pqk += dPQK; - - zA = zB; - zB = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w); - swapIfBigger( zB, zA); - - hitPixel = permute ? pqk.yx : pqk.xy; - hitPixel *= _OneDividedByRenderBufferSize; - - intersect = rayIntersectsDepthBF( zA, zB, hitPixel); - } - - // Binary search refinement - if( pixelStride > 1.0 && intersect) { - pqk -= dPQK; - dPQK /= pixelStride; - - float originalStride = pixelStride * 0.5; - float stride = originalStride; - - zA = pqk.z / pqk.w; - zB = zA; - - for( float j=0; j<_BinarySearchIterations; j++) - { - pqk += dPQK * stride; - - zA = zB; - zB = (dPQK.z * -0.5 + pqk.z) / (dPQK.w * -0.5 + pqk.w); - swapIfBigger( zB, zA); - - hitPixel = permute ? pqk.yx : pqk.xy; - hitPixel *= _OneDividedByRenderBufferSize; - - originalStride *= 0.5; - stride = rayIntersectsDepthBF( zA, zB, hitPixel) ? -originalStride : originalStride; - } - } - - - Q0.xy += dQ.xy * i; - Q0.z = pqk.z; - hitPoint = Q0 / pqk.w; - iterationCount = i; - - return intersect; -} - -float calculateAlphaForIntersection( bool intersect, - float iterationCount, - float specularStrength, - vec2 hitPixel, - vec3 hitPoint, - vec3 vsRayOrigin, - vec3 vsRayDirection) { - float alpha = min( 1.0, specularStrength * 1.0); - - // Fade ray hits that approach the maximum iterations - alpha *= 1.0 - (iterationCount / _Iterations); - - // Fade ray hits that approach the screen edge - float screenFade = _ScreenEdgeFadeStart; - vec2 hitPixelNDC = (hitPixel * 2.0 - 1.0); - float maxDimension = min( 1.0, max( abs( hitPixelNDC.x), abs( hitPixelNDC.y))); - alpha *= 1.0 - (max( 0.0, maxDimension - screenFade) / (1.0 - screenFade)); - - // Fade ray hits base on how much they face the camera - float eyeFadeStart = _EyeFadeStart; - float eyeFadeEnd = _EyeFadeEnd; - swapIfBigger( eyeFadeStart, eyeFadeEnd); - - float eyeDirection = clamp( vsRayDirection.z, eyeFadeStart, eyeFadeEnd); - alpha *= 1.0 - ((eyeDirection - eyeFadeStart) / (eyeFadeEnd - eyeFadeStart)); - - // Fade ray hits based on distance from ray origin - alpha *= 1.0 - clamp( distance( vsRayOrigin, hitPoint) / _MaxRayDistance, 0.0, 1.0); - - alpha *= intersect; - - return alpha; -} - - - -void main() { - - vec4 specRoughPixel = texture(_CameraGBufferTexture1, texCoord); - vec3 specularStrength = specRoughPixel.a; - - float decodedDepth = Linear01Depth(texture(_CameraDepthTexture, texCoord).r); - - vec3 vsRayOrigin = ScreenSpaceToViewSpace(cameraRay, decodedDepth); - - vec3 decodedNormal = (texture( _CameraGBufferTexture2, texCoord)).rgb * 2.0 - 1.0; - decodedNormal = mul( (mat3)_NormalMatrix, decodedNormal); - - vec3 vsRayDirection = normalize( reflect( normalize( vsRayOrigin), normalize(decodedNormal))); - - vec2 hitPixel; - vec3 hitPoint; - float iterationCount; - - vec2 uv2 = texCoord * _RenderBufferSize; - float c = (uv2.x + uv2.y) * 0.25; - float jitter = fmod( c, 1.0); - - bool intersect = traceScreenSpaceRay( vsRayOrigin, vsRayDirection, jitter, hitPixel, hitPoint, iterationCount, texCoord.x > 0.5); - float alpha = calculateAlphaForIntersection( intersect, iterationCount, specularStrength, hitPixel, hitPoint, vsRayOrigin, vsRayDirection); - hitPixel = lerp( texCoord, hitPixel, intersect); - - // Comment out the line below to get faked specular, - // in no way physically correct but will tint based - // on spec. Physically correct handling of spec is coming... - specRoughPixel = vec4( 1.0, 1.0, 1.0, 1.0); - - return vec4( (texture( _MainTex, hitPixel)).rgb * specRoughPixel.rgb, alpha); - - // vec4 texColor = texture(tex, texCoord); - // gl_FragColor = texColor * (1.0 - intensity) + reflCol * intensity; -} diff --git a/raw/ssr_pass/ssr_pass_kode.vert.glsl b/raw/ssr_pass/ssr_pass_kode.vert.glsl deleted file mode 100644 index 4768a333..00000000 --- a/raw/ssr_pass/ssr_pass_kode.vert.glsl +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 - -#ifdef GL_ES -precision highp float; -#endif - -in vec2 pos; - -out vec2 texCoord; -out vec3 cameraRay; - -uniform mat4 invP; - -const vec2 madd = vec2(0.5, 0.5); - -void main() { - // Scale vertex attribute to [0-1] range - texCoord = pos.xy * madd + madd; - - vec4 ray = vec4(texcoord * 2.0 - 1.0, 1.0, 1.0); - ray = invP * ray; - cameraRay = ray.xyz / ray.w; - - gl_Position = vec4(pos.xy, 0.0, 1.0); -} diff --git a/raw/sss_pass/sss_pass.frag.glsl b/raw/sss_pass/sss_pass.frag.glsl index 0091b734..294a0e18 100644 --- a/raw/sss_pass/sss_pass.frag.glsl +++ b/raw/sss_pass/sss_pass.frag.glsl @@ -41,6 +41,8 @@ precision mediump float; #endif +#include "../compiled.glsl" + uniform sampler2D gbufferD; uniform sampler2D gbuffer0; uniform sampler2D tex; @@ -78,10 +80,8 @@ vec4 SSSSBlur(float sssWidth) { // vec4 g0 = texture(gbuffer0, texCoord); // float depth = 1.0 - g0.a; float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0; - const float znear = 0.1; - const float zfar = 1000.0; - const float projectionA = zfar / (zfar - znear); - const float projectionB = (-zfar * znear) / (zfar - znear); + const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x); + const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x); float depthM = projectionB / (depth * 0.5 + 0.5 - projectionA); // Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window) diff --git a/raw/water_pass/water_pass.frag.glsl b/raw/water_pass/water_pass.frag.glsl index 259e112a..876ef392 100644 --- a/raw/water_pass/water_pass.frag.glsl +++ b/raw/water_pass/water_pass.frag.glsl @@ -9,8 +9,7 @@ precision mediump float; #endif -const float PI = 3.1415926535; -const float TwoPI = (2.0 * PI); +#include "../compiled.glsl" uniform sampler2D gbufferD; uniform sampler2D gbuffer0; @@ -57,7 +56,7 @@ const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6); vec2 envMapEquirect(vec3 normal) { float phi = acos(normal.z); float theta = atan(-normal.y, normal.x) + PI; - return vec2(theta / TwoPI, phi / PI); + return vec2(theta / PI2, phi / PI); } float hash( vec2 p ) { @@ -264,10 +263,8 @@ vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) { vec3 getPos(float depth) { vec3 vray = normalize(viewRay); - const float znear = 0.1; - const float zfar = 1000.0; - const float projectionA = zfar / (zfar - znear); - const float projectionB = (-zfar * znear) / (zfar - znear); + const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x); + const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x); float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA); float viewZDist = dot(eyeLook, vray); vec3 wposition = eye + vray * (linearDepth / viewZDist); @@ -288,7 +285,7 @@ vec2 octahedronWrap(vec2 v) { // } vec3 caustic(vec2 uv) { - vec2 p = mod(uv*TwoPI, TwoPI)-250.0; + vec2 p = mod(uv*PI2, PI2)-250.0; float loctime = time * .5+23.0; vec2 i = vec2(p); @@ -323,7 +320,7 @@ vec3 caustic(vec2 uv) { } float causticX(float x, float power, float gtime) { - float p = mod(x*TwoPI, TwoPI)-250.0; + float p = mod(x*PI2, PI2)-250.0; float time = gtime * .5+23.0; float i = p;