Finalizing SDK.

This commit is contained in:
Lubos Lenco 2016-07-10 00:51:39 +02:00
parent d10ac62f06
commit ca373d6bfd
66 changed files with 1956 additions and 1723 deletions

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View file

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View file

@ -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) {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class BoolNode extends Node {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class FloatNode extends Node {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class IntNode extends Node {

View file

@ -1,6 +1,6 @@
package cycles.node;
package armory.node;
import cycles.trait.NodeExecutor;
import armory.trait.internal.NodeExecutor;
class Node {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class ScaleValueNode extends FloatNode {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class SineNode extends FloatNode {

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class StringNode extends Node {

View file

@ -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) {

View file

@ -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;

View file

@ -1,4 +1,4 @@
package cycles.node;
package armory.node;
class VectorNode extends Node {

View file

@ -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) {
}
}

View file

@ -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
}
}

View file

@ -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 {

View file

@ -36,7 +36,7 @@
// #define SEARCHTEX_PITCH SEARCHTEX_WIDTH
// #define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
package cycles.renderpipeline;
package armory.renderpipeline;
class SMAAAreaData {

View file

@ -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);

View file

@ -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;
// }

View file

@ -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) {

View file

@ -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() {

View file

@ -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);
}

View file

@ -1,6 +1,6 @@
package cycles.trait;
package armory.trait;
import lue.Trait;
import iron.Trait;
#if WITH_PHYSICS
import haxebullet.Bullet;
#end

View file

@ -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) {

View file

@ -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
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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);
});
}

Binary file not shown.

View file

@ -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

View file

@ -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')

View file

@ -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)

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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)

View file

@ -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"

View file

@ -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()

View file

@ -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")

View file

@ -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__)

View file

@ -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__)

View file

@ -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())

View file

@ -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() {
// });
}
}
""")

View file

@ -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;

View file

@ -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));
}

View file

@ -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);

View file

@ -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
}

View file

@ -25,6 +25,11 @@
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "backgroundCol",
"link": "_backgroundCol",
"ifdef": ["_EnvCol"]
},
{
"id": "A",
"link": "_hosekA",

View file

@ -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);

View file

@ -19,7 +19,6 @@ precision mediump float;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D snoise;
uniform mat4 invVP;

View file

@ -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.);
}

View file

@ -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;
}

View file

@ -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 cameras near plane, z is the cameras 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;
}

View file

@ -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);
}

View file

@ -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)

View file

@ -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;