Finalizing SDK.
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.4 KiB |
BIN
Assets/noise.png
Before Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
|
@ -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) {
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class BoolNode extends Node {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class FloatNode extends Node {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class IntNode extends Node {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
import cycles.trait.NodeExecutor;
|
||||
import armory.trait.internal.NodeExecutor;
|
||||
|
||||
class Node {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class ScaleValueNode extends FloatNode {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class SineNode extends FloatNode {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class StringNode extends Node {
|
||||
|
|
@ -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) {
|
|
@ -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;
|
|
@ -1,4 +1,4 @@
|
|||
package cycles.node;
|
||||
package armory.node;
|
||||
|
||||
class VectorNode extends Node {
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
// #define SEARCHTEX_PITCH SEARCHTEX_WIDTH
|
||||
// #define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
|
||||
|
||||
package cycles.renderpipeline;
|
||||
package armory.renderpipeline;
|
||||
|
||||
class SMAAAreaData {
|
||||
|
|
@ -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);
|
|
@ -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;
|
||||
// }
|
||||
|
|
@ -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) {
|
|
@ -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() {
|
|
@ -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);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package cycles.trait;
|
||||
package armory.trait;
|
||||
|
||||
import lue.Trait;
|
||||
import iron.Trait;
|
||||
#if WITH_PHYSICS
|
||||
import haxebullet.Bullet;
|
||||
#end
|
|
@ -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) {
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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:Array<Void->Void> = [];
|
||||
|
||||
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);
|
||||
}
|
|
@ -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<Float> {
|
||||
|
@ -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);
|
|
@ -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);
|
|
@ -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) {
|
|
@ -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);
|
||||
});
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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')
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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(
|
||||
"""<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>ArmoryGame</title>
|
||||
<style>
|
||||
html, body, canvas, div {
|
||||
margin:0; padding: 0; width:100%; height:100%;
|
||||
}
|
||||
#khanvas {
|
||||
display:block; border:none; outline:none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id='khanvas' width='""" + str(w) + """' height='""" + str(h) + """'></canvas>
|
||||
<script src='kha.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
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() {
|
||||
// });
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
"id": "invP",
|
||||
"link": "_inverseProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"id": "backgroundCol",
|
||||
"link": "_backgroundCol",
|
||||
"ifdef": ["_EnvCol"]
|
||||
},
|
||||
{
|
||||
"id": "A",
|
||||
"link": "_hosekA",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -19,7 +19,6 @@ precision mediump float;
|
|||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform sampler2D snoise;
|
||||
|
||||
uniform mat4 invVP;
|
||||
|
|
|
@ -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.);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|