Merge pull request 't3du [ Repe ] - Post process updates - New nodes - Physics - Chromatic AB' (#60) from Onek8/LNXSDK:main into main

Reviewed-on: LeenkxTeam/LNXSDK#60
This commit is contained in:
2025-06-02 20:07:26 +00:00
46 changed files with 716 additions and 180 deletions

View File

@ -3,6 +3,10 @@
#include "compiled.inc" #include "compiled.inc"
#ifdef _CPostprocess
uniform vec4 PPComp17;
#endif
uniform sampler2D tex; uniform sampler2D tex;
uniform vec2 dir; uniform vec2 dir;
uniform vec2 screenSize; uniform vec2 screenSize;
@ -45,6 +49,12 @@ void main() {
res += factor * col; res += factor * col;
} }
#ifdef _CPostprocess
vec3 AirColor = vec3(PPComp17.x, PPComp17.y, PPComp17.z);
#else
vec3 AirColor = volumAirColor;
#endif
res /= sumfactor; res /= sumfactor;
fragColor = vec4(volumAirColor * res, 1.0); fragColor = vec4(AirColor * res, 1.0);
} }

View File

@ -19,6 +19,11 @@
{ {
"name": "screenSize", "name": "screenSize",
"link": "_screenSize" "link": "_screenSize"
},
{
"name": "PPComp17",
"link": "_PPComp17",
"ifdef": ["_CPostprocess"]
} }
], ],
"texture_params": [], "texture_params": [],

View File

@ -5,7 +5,7 @@
uniform sampler2D tex; uniform sampler2D tex;
#ifdef _CPostprocess #ifdef _CPostprocess
uniform vec3 PPComp13; uniform vec4 PPComp13;
#endif #endif
in vec2 texCoord; in vec2 texCoord;
@ -43,13 +43,17 @@ void main() {
#ifdef _CPostprocess #ifdef _CPostprocess
float max_distort = PPComp13.x; float max_distort = PPComp13.x;
int num_iter = int(PPComp13.y); int num_iter = int(PPComp13.y);
int CAType = int(PPComp13.z);
int on = int(PPComp13.w);
#else #else
float max_distort = compoChromaticStrength; float max_distort = compoChromaticStrength;
int num_iter = compoChromaticSamples; int num_iter = compoChromaticSamples;
int CAType = compoChromaticType;
int on = 1;
#endif #endif
// Spectral // Spectral
if (compoChromaticType == 1) { if (CAType == 1) {
float reci_num_iter_f = 1.0 / float(num_iter); float reci_num_iter_f = 1.0 / float(num_iter);
vec2 resolution = vec2(1,1); vec2 resolution = vec2(1,1);
@ -64,7 +68,7 @@ void main() {
sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t)); sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t));
} }
fragColor = sumcol / sumw; if (on == 1) fragColor = sumcol / sumw; else fragColor = texture(tex, texCoord);
} }
// Simple // Simple
@ -73,6 +77,7 @@ void main() {
col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x; col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x;
col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y; col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y;
col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z; col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z;
fragColor = vec4(col.x, col.y, col.z, fragColor.w); if (on == 1) fragColor = vec4(col.x, col.y, col.z, fragColor.w);
else fragColor = texture(tex, texCoord);
} }
} }

View File

@ -62,8 +62,11 @@ uniform vec3 PPComp5;
uniform vec3 PPComp6; uniform vec3 PPComp6;
uniform vec3 PPComp7; uniform vec3 PPComp7;
uniform vec3 PPComp8; uniform vec3 PPComp8;
uniform vec3 PPComp11;
uniform vec3 PPComp14; uniform vec3 PPComp14;
uniform vec4 PPComp15; uniform vec4 PPComp15;
uniform vec4 PPComp16;
uniform vec4 PPComp18;
#endif #endif
// #ifdef _CPos // #ifdef _CPos
@ -106,6 +109,16 @@ in vec2 texCoord;
out vec4 fragColor; out vec4 fragColor;
#ifdef _CFog #ifdef _CFog
#ifdef _CPostprocess
vec3 FogColor = vec3(PPComp18.x, PPComp18.y, PPComp18.z);
float FogAmountA = PPComp18.w;
float FogAmountB = PPComp11.z;
#else
vec3 FogColor = compoFogColor;
float FogAmountA = compoFogAmountA;
float FogAmountB = compoFogAmountB;
#endif
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7); // const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
// const float compoFogAmountA = 1.0; // b = 0.01 // const float compoFogAmountA = 1.0; // b = 0.01
// const float compoFogAmountB = 1.0; // c = 0.1 // const float compoFogAmountB = 1.0; // c = 0.1
@ -118,8 +131,8 @@ out vec4 fragColor;
// } // }
vec3 applyFog(vec3 rgb, float distance) { vec3 applyFog(vec3 rgb, float distance) {
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA); // float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
float fogAmount = 1.0 - exp(-distance * (compoFogAmountA / 100)); float fogAmount = 1.0 - exp(-distance * (FogAmountA / 100));
return mix(rgb, compoFogColor, fogAmount); return mix(rgb, FogColor, fogAmount);
} }
#endif #endif
@ -349,16 +362,22 @@ void main() {
#ifdef _CSharpen #ifdef _CSharpen
#ifdef _CPostprocess #ifdef _CPostprocess
float strengthSharpen = PPComp14.y; float strengthSharpen = PPComp14.y;
vec3 SharpenColor = vec3(PPComp16.x, PPComp16.y, PPComp16.z);
float SharpenSize = PPComp16.w;
#else #else
float strengthSharpen = compoSharpenStrength; float strengthSharpen = compoSharpenStrength;
vec3 SharpenColor = compoSharpenColor;
float SharpenSize = compoSharpenSize;
#endif #endif
vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * 1.5, 0.0).rgb; vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * SharpenSize, 0.0).rgb;
vec3 col2 = textureLod(tex, texCo + vec2(texStep.x, -texStep.y) * 1.5, 0.0).rgb; vec3 col2 = textureLod(tex, texCo + vec2(texStep.x, -texStep.y) * SharpenSize, 0.0).rgb;
vec3 col3 = textureLod(tex, texCo + vec2(-texStep.x, texStep.y) * 1.5, 0.0).rgb; vec3 col3 = textureLod(tex, texCo + vec2(-texStep.x, texStep.y) * SharpenSize, 0.0).rgb;
vec3 col4 = textureLod(tex, texCo + vec2(texStep.x, texStep.y) * 1.5, 0.0).rgb; vec3 col4 = textureLod(tex, texCo + vec2(texStep.x, texStep.y) * SharpenSize, 0.0).rgb;
vec3 colavg = (col1 + col2 + col3 + col4) * 0.25; vec3 colavg = (col1 + col2 + col3 + col4) * 0.25;
fragColor.rgb += (fragColor.rgb - colavg) * strengthSharpen;
float edgeMagnitude = length(fragColor.rgb - colavg);
fragColor.rgb = mix(fragColor.rgb, SharpenColor, min(edgeMagnitude * strengthSharpen * 2.0, 1.0));
#endif #endif
#ifdef _CFog #ifdef _CFog
@ -407,7 +426,11 @@ void main() {
#endif #endif
#ifdef _CExposure #ifdef _CExposure
fragColor.rgb += fragColor.rgb * compoExposureStrength; #ifdef _CPostprocess
fragColor.rgb+=fragColor.rgb*PPComp8.x;
#else
fragColor.rgb+= fragColor.rgb*compoExposureStrength;
#endif
#endif #endif
#ifdef _CPostprocess #ifdef _CPostprocess
@ -415,8 +438,13 @@ void main() {
#endif #endif
#ifdef _AutoExposure #ifdef _AutoExposure
#ifdef _CPostprocess
float AEStrength = PPComp8.y;
#else
float AEStrength = autoExposureStrength;
#endif
float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0); float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0);
fragColor.rgb *= pow(expo, autoExposureStrength * 2.0); fragColor.rgb *= pow(expo, AEStrength * 2.0);
#endif #endif
// Clamp color to get rid of INF values that don't work for the tone mapping below // Clamp color to get rid of INF values that don't work for the tone mapping below

View File

@ -235,6 +235,16 @@
"name": "PPComp15", "name": "PPComp15",
"link": "_PPComp15", "link": "_PPComp15",
"ifdef": ["_CPostprocess"] "ifdef": ["_CPostprocess"]
},
{
"name": "PPComp16",
"link": "_PPComp16",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp18",
"link": "_PPComp18",
"ifdef": ["_CPostprocess"]
} }
], ],
"texture_params": [], "texture_params": [],

View File

@ -2,13 +2,22 @@
#include "compiled.inc" #include "compiled.inc"
#ifdef _CPostprocess
uniform vec3 PPComp8;
#endif
uniform sampler2D tex; uniform sampler2D tex;
in vec2 texCoord; in vec2 texCoord;
out vec4 fragColor; out vec4 fragColor;
void main() { void main() {
fragColor.a = 0.01 * autoExposureSpeed; #ifdef _CPostprocess
fragColor.a = 0.01 * PPComp8.z;
#else
fragColor.a = 0.01 * autoExposureSpeed;
#endif
fragColor.rgb = textureLod(tex, vec2(0.5, 0.5), 0.0).rgb + fragColor.rgb = textureLod(tex, vec2(0.5, 0.5), 0.0).rgb +
textureLod(tex, vec2(0.2, 0.2), 0.0).rgb + textureLod(tex, vec2(0.2, 0.2), 0.0).rgb +
textureLod(tex, vec2(0.8, 0.2), 0.0).rgb + textureLod(tex, vec2(0.8, 0.2), 0.0).rgb +

View File

@ -8,7 +8,13 @@
"blend_source": "source_alpha", "blend_source": "source_alpha",
"blend_destination": "inverse_source_alpha", "blend_destination": "inverse_source_alpha",
"blend_operation": "add", "blend_operation": "add",
"links": [], "links": [
{
"name": "PPComp8",
"link": "_PPComp8",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [], "texture_params": [],
"vertex_shader": "../include/pass.vert.glsl", "vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "histogram_pass.frag.glsl" "fragment_shader": "histogram_pass.frag.glsl"

View File

@ -11,6 +11,11 @@
#include "std/light_common.glsl" #include "std/light_common.glsl"
#endif #endif
#ifdef _CPostprocess
uniform vec3 PPComp11;
uniform vec4 PPComp17;
#endif
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D snoise; uniform sampler2D snoise;
@ -87,7 +92,13 @@ out float fragColor;
const float tScat = 0.08; const float tScat = 0.08;
const float tAbs = 0.0; const float tAbs = 0.0;
const float tExt = tScat + tAbs; const float tExt = tScat + tAbs;
const float stepLen = 1.0 / volumSteps; #ifdef _CPostprocess
float stepLen = 1.0 / int(PPComp11.y);
float AirTurbidity = PPComp17.w;
#else
const float stepLen = 1.0 / volumSteps;
float AirTurbidity = volumAirTurbidity;
#endif
const float lighting = 0.4; const float lighting = 0.4;
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) { void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
@ -162,5 +173,5 @@ void main() {
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm); rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
} }
fragColor = scatteredLightAmount * volumAirTurbidity; fragColor = scatteredLightAmount * AirTurbidity;
} }

View File

@ -140,6 +140,16 @@
"link": "_biasLightWorldViewProjectionMatrixSpot3", "link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifndef": ["_ShadowMapAtlas"], "ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"] "ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "PPComp11",
"link": "_PPComp11",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp17",
"link": "_PPComp17",
"ifdef": ["_CPostprocess"]
} }
], ],
"texture_params": [], "texture_params": [],

View File

@ -20,6 +20,7 @@ class Config {
var path = iron.data.Data.dataPath + "config.lnx"; var path = iron.data.Data.dataPath + "config.lnx";
var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(raw)); var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(raw));
#if kha_krom #if kha_krom
if (iron.data.Data.dataPath == '') path = Krom.getFilesLocation() + "/config.lnx";
Krom.fileSaveBytes(path, bytes.getData()); Krom.fileSaveBytes(path, bytes.getData());
#elseif kha_kore #elseif kha_kore
sys.io.File.saveBytes(path, bytes); sys.io.File.saveBytes(path, bytes);
@ -47,6 +48,7 @@ typedef TConfig = {
@:optional var rp_ssr: Null<Bool>; @:optional var rp_ssr: Null<Bool>;
@:optional var rp_ssrefr: Null<Bool>; @:optional var rp_ssrefr: Null<Bool>;
@:optional var rp_bloom: Null<Bool>; @:optional var rp_bloom: Null<Bool>;
@:optional var rp_chromatic_aberration: Null<Bool>;
@:optional var rp_motionblur: Null<Bool>; @:optional var rp_motionblur: Null<Bool>;
@:optional var rp_gi: Null<Bool>; // voxelao @:optional var rp_gi: Null<Bool>; // voxelao
@:optional var rp_dynres: Null<Bool>; // dynamic resolution scaling @:optional var rp_dynres: Null<Bool>; // dynamic resolution scaling

View File

@ -0,0 +1,16 @@
package leenkx.logicnode;
class AutoExposureGetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return switch (from) {
case 0: leenkx.renderpath.Postprocess.auto_exposure_uniforms[0];
case 1: leenkx.renderpath.Postprocess.auto_exposure_uniforms[1];
default: 0.0;
}
}
}

View File

@ -0,0 +1,15 @@
package leenkx.logicnode;
class AutoExposureSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
leenkx.renderpath.Postprocess.auto_exposure_uniforms[0] = inputs[1].get();
leenkx.renderpath.Postprocess.auto_exposure_uniforms[1] = inputs[2].get();
runOutput(0);
}
}

View File

@ -1,26 +1,49 @@
package leenkx.logicnode; package leenkx.logicnode;
class CameraSetNode extends LogicNode { class CameraSetNode extends LogicNode {
public var property0: String;
public function new(tree:LogicTree) { public function new(tree:LogicTree) {
super(tree); super(tree);
} }
override function run(from:Int) { override function run(from:Int) {
leenkx.renderpath.Postprocess.camera_uniforms[0] = inputs[1].get();//Camera: F-Number
leenkx.renderpath.Postprocess.camera_uniforms[1] = inputs[2].get();//Camera: Shutter time switch (property0) {
leenkx.renderpath.Postprocess.camera_uniforms[2] = inputs[3].get();//Camera: ISO case 'F-stop':
leenkx.renderpath.Postprocess.camera_uniforms[3] = inputs[4].get();//Camera: Exposure Compensation leenkx.renderpath.Postprocess.camera_uniforms[0] = inputs[1].get();//Camera: F-Number
leenkx.renderpath.Postprocess.camera_uniforms[4] = inputs[5].get();//Fisheye Distortion case 'Shutter Time':
leenkx.renderpath.Postprocess.camera_uniforms[5] = inputs[6].get();//DoF AutoFocus §§ If true, it ignores the DoF Distance setting leenkx.renderpath.Postprocess.camera_uniforms[1] = inputs[1].get();//Camera: Shutter time
leenkx.renderpath.Postprocess.camera_uniforms[6] = inputs[7].get();//DoF Distance case 'ISO':
leenkx.renderpath.Postprocess.camera_uniforms[7] = inputs[8].get();//DoF Focal Length mm leenkx.renderpath.Postprocess.camera_uniforms[2] = inputs[1].get();//Camera: ISO
leenkx.renderpath.Postprocess.camera_uniforms[8] = inputs[9].get();//DoF F-Stop case 'Exposure Compensation':
leenkx.renderpath.Postprocess.camera_uniforms[9] = inputs[10].get();//Tonemapping Method leenkx.renderpath.Postprocess.camera_uniforms[3] = inputs[1].get();//Camera: Exposure Compensation
leenkx.renderpath.Postprocess.camera_uniforms[10] = inputs[11].get();//Distort case 'Fisheye Distortion':
leenkx.renderpath.Postprocess.camera_uniforms[11] = inputs[12].get();//Film Grain leenkx.renderpath.Postprocess.camera_uniforms[4] = inputs[1].get();//Fisheye Distortion
leenkx.renderpath.Postprocess.camera_uniforms[12] = inputs[13].get();//Sharpen case 'Auto Focus':
leenkx.renderpath.Postprocess.camera_uniforms[13] = inputs[14].get();//Vignette leenkx.renderpath.Postprocess.camera_uniforms[5] = inputs[1].get();//DoF AutoFocus §§ If true, it ignores the DoF Distance setting
case 'DoF Distance':
leenkx.renderpath.Postprocess.camera_uniforms[6] = inputs[1].get();//DoF Distance
case 'DoF Length':
leenkx.renderpath.Postprocess.camera_uniforms[7] = inputs[1].get();//DoF Focal Length mm
case 'DoF F-Stop':
leenkx.renderpath.Postprocess.camera_uniforms[8] = inputs[1].get();//DoF F-Stop
case 'Tonemapping':
leenkx.renderpath.Postprocess.camera_uniforms[9] = inputs[1].get();//Tonemapping Method
case 'Distort':
leenkx.renderpath.Postprocess.camera_uniforms[10] = inputs[1].get();//Distort
case 'Film Grain':
leenkx.renderpath.Postprocess.camera_uniforms[11] = inputs[1].get();//Film Grain
case 'Sharpen':
leenkx.renderpath.Postprocess.camera_uniforms[12] = inputs[1].get();//Sharpen
case 'Vignette':
leenkx.renderpath.Postprocess.camera_uniforms[13] = inputs[1].get();//Vignette
case 'Exposure':
leenkx.renderpath.Postprocess.exposure_uniforms[0] = inputs[1].get();//Exposure
default:
null;
}
runOutput(0); runOutput(0);
} }

View File

@ -10,6 +10,7 @@ class ChromaticAberrationGetNode extends LogicNode {
return switch (from) { return switch (from) {
case 0: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0]; case 0: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0];
case 1: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1]; case 1: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1];
case 2: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[2];
default: 0.0; default: 0.0;
} }
} }

View File

@ -10,6 +10,7 @@ class ChromaticAberrationSetNode extends LogicNode {
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0] = inputs[1].get(); leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0] = inputs[1].get();
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1] = inputs[2].get(); leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1] = inputs[2].get();
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[2] = inputs[3].get();
runOutput(0); runOutput(0);
} }

View File

@ -39,22 +39,28 @@ class GetParticleDataNode extends LogicNode {
case 6: case 6:
@:privateAccess psys.r.emit_from; @:privateAccess psys.r.emit_from;
case 7: case 7:
new iron.math.Vec3(@:privateAccess psys.alignx*2, @:privateAccess psys.aligny*2, @:privateAccess psys.alignz*2); @:privateAccess psys.r.auto_start;
case 8: case 8:
@:privateAccess psys.r.factor_random; @:privateAccess psys.r.is_unique;
case 9: case 9:
new iron.math.Vec3(@:privateAccess psys.gx, @:privateAccess psys.gy, @:privateAccess psys.gz); @:privateAccess psys.r.loop;
case 10: case 10:
@:privateAccess psys.r.weight_gravity; new iron.math.Vec3(@:privateAccess psys.alignx, @:privateAccess psys.aligny, @:privateAccess psys.alignz);
case 11: case 11:
psys.speed; @:privateAccess psys.r.factor_random;
case 12: case 12:
@:privateAccess psys.time; new iron.math.Vec3(@:privateAccess psys.gx, @:privateAccess psys.gy, @:privateAccess psys.gz);
case 13: case 13:
@:privateAccess psys.lap; @:privateAccess psys.r.weight_gravity;
case 14: case 14:
@:privateAccess psys.lapTime; psys.speed;
case 15: case 15:
@:privateAccess psys.time;
case 16:
@:privateAccess psys.lap;
case 17:
@:privateAccess psys.lapTime;
case 18:
@:privateAccess psys.count; @:privateAccess psys.count;
default: default:
null; null;

View File

@ -20,6 +20,8 @@ class RpConfigNode extends LogicNode {
on ? leenkx.data.Config.raw.rp_ssrefr = true : leenkx.data.Config.raw.rp_ssrefr = false; on ? leenkx.data.Config.raw.rp_ssrefr = true : leenkx.data.Config.raw.rp_ssrefr = false;
case "Bloom": case "Bloom":
on ? leenkx.data.Config.raw.rp_bloom = true : leenkx.data.Config.raw.rp_bloom = false; on ? leenkx.data.Config.raw.rp_bloom = true : leenkx.data.Config.raw.rp_bloom = false;
case "CA":
on ? leenkx.data.Config.raw.rp_chromatic_aberration = true : leenkx.data.Config.raw.rp_chromatic_aberration = false;
case "GI": case "GI":
on ? leenkx.data.Config.raw.rp_gi = true : leenkx.data.Config.raw.rp_gi = false; on ? leenkx.data.Config.raw.rp_gi = true : leenkx.data.Config.raw.rp_gi = false;
case "Motion Blur": case "Motion Blur":

View File

@ -41,13 +41,19 @@ class SetParticleDataNode extends LogicNode {
var emit_from: Int = inputs[3].get(); var emit_from: Int = inputs[3].get();
if (emit_from == 0 || emit_from == 1 || emit_from == 2) { if (emit_from == 0 || emit_from == 1 || emit_from == 2) {
@:privateAccess psys.r.emit_from = emit_from; @:privateAccess psys.r.emit_from = emit_from;
@:privateAccess psys.setupGeomGpu(mo.particleChildren != null ? mo.particleChildren[slot] : cast(iron.Scene.active.getChild(psys.data.raw.instance_object), iron.object.MeshObject), mo); @:privateAccess psys.setupGeomGpu(mo.particleChildren != null ? mo.particleChildren[slot] : cast(iron.Scene.active.getChild(@:privateAccess psys.data.raw.instance_object), iron.object.MeshObject), mo);
} }
case 'Auto Start':
@:privateAccess psys.r.auto_start = inputs[3].get();
case 'Is Unique':
@:privateAccess psys.r.is_unique = inputs[3].get();
case 'Loop':
@:privateAccess psys.r.loop = inputs[3].get();
case 'Velocity': case 'Velocity':
var vel: iron.math.Vec3 = inputs[3].get(); var vel: iron.math.Vec3 = inputs[3].get();
@:privateAccess psys.alignx = vel.x / 2; @:privateAccess psys.alignx = vel.x;
@:privateAccess psys.aligny = vel.y / 2; @:privateAccess psys.aligny = vel.y;
@:privateAccess psys.alignz = vel.z / 2; @:privateAccess psys.alignz = vel.z;
case 'Velocity Random': case 'Velocity Random':
psys.r.factor_random = inputs[3].get(); psys.r.factor_random = inputs[3].get();
case 'Weight Gravity': case 'Weight Gravity':

View File

@ -0,0 +1,17 @@
package leenkx.logicnode;
class SharpenGetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return switch (from) {
case 0: leenkx.renderpath.Postprocess.sharpen_uniforms[0];
case 1: leenkx.renderpath.Postprocess.sharpen_uniforms[1][0];
case 2: leenkx.renderpath.Postprocess.camera_uniforms[12];
default: 0.0;
}
}
}

View File

@ -0,0 +1,18 @@
package leenkx.logicnode;
class SharpenSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
leenkx.renderpath.Postprocess.sharpen_uniforms[0][0] = inputs[1].get().x;
leenkx.renderpath.Postprocess.sharpen_uniforms[0][1] = inputs[1].get().y;
leenkx.renderpath.Postprocess.sharpen_uniforms[0][2] = inputs[1].get().z;
leenkx.renderpath.Postprocess.sharpen_uniforms[1][0] = inputs[2].get();
leenkx.renderpath.Postprocess.camera_uniforms[12] = inputs[3].get();
runOutput(0);
}
}

View File

@ -0,0 +1,17 @@
package leenkx.logicnode;
class VolumetricFogGetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return switch (from) {
case 0: leenkx.renderpath.Postprocess.volumetric_fog_uniforms[0];
case 1: leenkx.renderpath.Postprocess.volumetric_fog_uniforms[1][0];
case 2: leenkx.renderpath.Postprocess.volumetric_fog_uniforms[2][0];
default: 0.0;
}
}
}

View File

@ -0,0 +1,18 @@
package leenkx.logicnode;
class VolumetricFogSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
leenkx.renderpath.Postprocess.volumetric_fog_uniforms[0][0] = inputs[1].get().x;
leenkx.renderpath.Postprocess.volumetric_fog_uniforms[0][1] = inputs[1].get().y;
leenkx.renderpath.Postprocess.volumetric_fog_uniforms[0][2] = inputs[1].get().z;
leenkx.renderpath.Postprocess.volumetric_fog_uniforms[1][0] = inputs[2].get();
leenkx.renderpath.Postprocess.volumetric_fog_uniforms[2][0] = inputs[3].get();
runOutput(0);
}
}

View File

@ -0,0 +1,17 @@
package leenkx.logicnode;
class VolumetricLightGetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return switch (from) {
case 0: leenkx.renderpath.Postprocess.volumetric_light_uniforms[0];
case 1: leenkx.renderpath.Postprocess.volumetric_light_uniforms[1][0];
case 2: leenkx.renderpath.Postprocess.volumetric_light_uniforms[2][0];
default: 0.0;
}
}
}

View File

@ -0,0 +1,18 @@
package leenkx.logicnode;
class VolumetricLightSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
leenkx.renderpath.Postprocess.volumetric_light_uniforms[0][0] = inputs[1].get().x;
leenkx.renderpath.Postprocess.volumetric_light_uniforms[0][1] = inputs[1].get().y;
leenkx.renderpath.Postprocess.volumetric_light_uniforms[0][2] = inputs[1].get().z;
leenkx.renderpath.Postprocess.volumetric_light_uniforms[1][0] = inputs[2].get();
leenkx.renderpath.Postprocess.volumetric_light_uniforms[2][0] = inputs[3].get();
runOutput(0);
}
}

View File

@ -529,22 +529,29 @@ class Inc {
public static function applyConfig() { public static function applyConfig() {
#if lnx_config #if lnx_config
var config = leenkx.data.Config.raw; var config = leenkx.data.Config.raw;
#if rp_chromatic_aberration
Postprocess.chromatic_aberration_uniforms[3] = config.rp_chromatic_aberration == true ? 1 : 0;
#end
// Resize shadow map // Resize shadow map
var l = path.light; var l = path.light;
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) { if (l != null){
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade; if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
var rt = path.renderTargets.get("shadowMap"); l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
if (rt != null) { var rt = path.renderTargets.get("shadowMap");
rt.unload(); if (rt != null) {
path.renderTargets.remove("shadowMap"); rt.unload();
path.renderTargets.remove("shadowMap");
}
} }
} else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) { l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
l.data.raw.shadowmap_size = config.rp_shadowmap_cube; var rt = path.renderTargets.get("shadowMapCube");
var rt = path.renderTargets.get("shadowMapCube"); if (rt != null) {
if (rt != null) { rt.unload();
rt.unload(); path.renderTargets.remove("shadowMapCube");
path.renderTargets.remove("shadowMapCube"); }
} }
} }
if (superSample != config.rp_supersample) { if (superSample != config.rp_supersample) {

View File

@ -54,10 +54,15 @@ class Postprocess {
0, //9: Tonemapping Method 0, //9: Tonemapping Method
2.0, //10: Distort 2.0, //10: Distort
2.0, //11: Film Grain 2.0, //11: Film Grain
0.25, //12: Sharpen 0.25, //12: Sharpen Strength
0.7 //13: Vignette 0.7 //13: Vignette
]; ];
public static var sharpen_uniforms = [
[0.0, 0.0, 0.0], //0: Sharpen Color
[2.5] //1: Sharpen Size
];
public static var tonemapper_uniforms = [ public static var tonemapper_uniforms = [
1.0, //0: Slope 1.0, //0: Slope
1.0, //1: Toe 1.0, //1: Toe
@ -102,7 +107,30 @@ class Postprocess {
public static var chromatic_aberration_uniforms = [ public static var chromatic_aberration_uniforms = [
2.0, //0: Strength 2.0, //0: Strength
32 //1: Samples 32, //1: Samples
0, //2: Type
1 //3: On/Off
];
public static var exposure_uniforms = [
1 //0: Exposure
];
public static var auto_exposure_uniforms = [
1, //0: Auto Exposure Strength
1 //1: Auto Exposure Speed
];
public static var volumetric_light_uniforms = [
[1.0, 1.0, 1.0], //0: Volumetric Light Air Color
[1.0], //1: Volumetric Light Air Turbidity
[20.0] //2: Volumetric Light Steps
];
public static var volumetric_fog_uniforms = [
[0.5, 0.6, 0.7], //0: Volumetric Fog Color
[0.25], //1: Volumetric Fog Amount A
[50.0] //2: Volumetric Fog Amount B
]; ];
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 { public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
@ -284,6 +312,11 @@ class Postprocess {
v.x = lenstexture_uniforms[2]; //Lum min v.x = lenstexture_uniforms[2]; //Lum min
v.y = lenstexture_uniforms[3]; //Lum max v.y = lenstexture_uniforms[3]; //Lum max
v.z = lenstexture_uniforms[4]; //Expo v.z = lenstexture_uniforms[4]; //Expo
case "_PPComp8":
v = iron.object.Uniforms.helpVec;
v.x = exposure_uniforms[0]; //Exposure
v.y = auto_exposure_uniforms[0]; //Auto Exposure Strength
v.z = auto_exposure_uniforms[1]; //Auto Exposure Speed
case "_PPComp9": case "_PPComp9":
v = iron.object.Uniforms.helpVec; v = iron.object.Uniforms.helpVec;
v.x = ssr_uniforms[0]; //Step v.x = ssr_uniforms[0]; //Step
@ -297,8 +330,8 @@ class Postprocess {
case "_PPComp11": case "_PPComp11":
v = iron.object.Uniforms.helpVec; v = iron.object.Uniforms.helpVec;
v.x = bloom_uniforms[2]; // Bloom Strength v.x = bloom_uniforms[2]; // Bloom Strength
v.y = 0; // Unused v.y = volumetric_light_uniforms[2][0]; //Volumetric Light Steps
v.z = 0; // Unused v.z = volumetric_fog_uniforms[2][0]; //Volumetric Fog Amount B
case "_PPComp12": case "_PPComp12":
v = iron.object.Uniforms.helpVec; v = iron.object.Uniforms.helpVec;
v.x = ssao_uniforms[0]; //SSAO Strength v.x = ssao_uniforms[0]; //SSAO Strength
@ -308,7 +341,8 @@ class Postprocess {
v = iron.object.Uniforms.helpVec; v = iron.object.Uniforms.helpVec;
v.x = chromatic_aberration_uniforms[0]; //CA Strength v.x = chromatic_aberration_uniforms[0]; //CA Strength
v.y = chromatic_aberration_uniforms[1]; //CA Samples v.y = chromatic_aberration_uniforms[1]; //CA Samples
v.z = 0; v.z = chromatic_aberration_uniforms[2]; //CA Type
v.w = chromatic_aberration_uniforms[3]; //On/Off
case "_PPComp14": case "_PPComp14":
v = iron.object.Uniforms.helpVec; v = iron.object.Uniforms.helpVec;
v.x = camera_uniforms[10]; //Distort v.x = camera_uniforms[10]; //Distort
@ -338,6 +372,24 @@ class Postprocess {
v.y = letterbox_uniforms[0][1]; v.y = letterbox_uniforms[0][1];
v.z = letterbox_uniforms[0][2]; v.z = letterbox_uniforms[0][2];
v.w = letterbox_uniforms[1][0]; //Size v.w = letterbox_uniforms[1][0]; //Size
case "_PPComp16":
v = iron.object.Uniforms.helpVec;
v.x = sharpen_uniforms[0][0]; //Color
v.y = sharpen_uniforms[0][1];
v.z = sharpen_uniforms[0][2];
v.w = sharpen_uniforms[1][0]; //Size
case "_PPComp17":
v = iron.object.Uniforms.helpVec;
v.x = volumetric_light_uniforms[0][0]; //Air Color
v.y = volumetric_light_uniforms[0][1];
v.z = volumetric_light_uniforms[0][2];
v.w = volumetric_light_uniforms[1][0]; //Air Turbidity
case "_PPComp18":
v = iron.object.Uniforms.helpVec;
v.x = volumetric_fog_uniforms[0][0]; //Color
v.y = volumetric_fog_uniforms[0][1];
v.z = volumetric_fog_uniforms[0][2];
v.w = volumetric_fog_uniforms[1][0]; //Amount A
} }
return v; return v;

View File

@ -1,31 +1,34 @@
from lnx.logicnode.lnx_nodes import * from lnx.logicnode.lnx_nodes import *
class GetParticleDataNode(LnxLogicTreeNode): class GetParticleDataNode(LnxLogicTreeNode):
"""Returns the data of the given Particle System.""" """Returns the data of the given Particle System."""
bl_idname = 'LNGetParticleDataNode' bl_idname = 'LNGetParticleDataNode'
bl_label = 'Get Particle Data' bl_label = 'Get Particle Data'
lnx_version = 1 lnx_version = 1
def lnx_init(self, context): def lnx_init(self, context):
self.inputs.new('LnxNodeSocketObject', 'Object') self.inputs.new('LnxNodeSocketObject', 'Object')
self.inputs.new('LnxIntSocket', 'Slot') self.inputs.new('LnxIntSocket', 'Slot')
self.outputs.new('LnxStringSocket', 'Name') self.outputs.new('LnxStringSocket', 'Name')
self.outputs.new('LnxFloatSocket', 'Particle Size') self.outputs.new('LnxFloatSocket', 'Particle Size')
self.outputs.new('LnxIntSocket', 'Frame Start') self.outputs.new('LnxIntSocket', 'Frame Start')
self.outputs.new('LnxIntSocket', 'Frame End') self.outputs.new('LnxIntSocket', 'Frame End')
self.outputs.new('LnxIntSocket', 'Lifetime') self.outputs.new('LnxIntSocket', 'Lifetime')
self.outputs.new('LnxFloatSocket', 'Lifetime Random') self.outputs.new('LnxFloatSocket', 'Lifetime Random')
self.outputs.new('LnxIntSocket', 'Emit From') self.outputs.new('LnxIntSocket', 'Emit From')
self.outputs.new('LnxBoolSocket', 'Auto Start')
self.outputs.new('LnxVectorSocket', 'Velocity') self.outputs.new('LnxBoolSocket', 'Is Unique')
self.outputs.new('LnxFloatSocket', 'Velocity Random') self.outputs.new('LnxBoolSocket', 'Loop')
self.outputs.new('LnxVectorSocket', 'Gravity')
self.outputs.new('LnxFloatSocket', 'Weight Gravity') self.outputs.new('LnxVectorSocket', 'Velocity')
self.outputs.new('LnxFloatSocket', 'Velocity Random')
self.outputs.new('LnxFloatSocket', 'Speed') self.outputs.new('LnxVectorSocket', 'Gravity')
self.outputs.new('LnxFloatSocket', 'Weight Gravity')
self.outputs.new('LnxFloatSocket', 'Time')
self.outputs.new('LnxFloatSocket', 'Lap') self.outputs.new('LnxFloatSocket', 'Speed')
self.outputs.new('LnxFloatSocket', 'Lap Time')
self.outputs.new('LnxIntSocket', 'Count') self.outputs.new('LnxFloatSocket', 'Time')
self.outputs.new('LnxFloatSocket', 'Lap')
self.outputs.new('LnxFloatSocket', 'Lap Time')
self.outputs.new('LnxIntSocket', 'Count')

View File

@ -1,58 +1,67 @@
from lnx.logicnode.lnx_nodes import * from lnx.logicnode.lnx_nodes import *
class SetParticleDataNode(LnxLogicTreeNode): class SetParticleDataNode(LnxLogicTreeNode):
"""Sets the parameters of the given particle system.""" """Sets the parameters of the given particle system."""
bl_idname = 'LNSetParticleDataNode' bl_idname = 'LNSetParticleDataNode'
bl_label = 'Set Particle Data' bl_label = 'Set Particle Data'
lnx_version = 1 lnx_version = 1
def remove_extra_inputs(self, context): def remove_extra_inputs(self, context):
while len(self.inputs) > 3: while len(self.inputs) > 3:
self.inputs.remove(self.inputs[-1]) self.inputs.remove(self.inputs[-1])
if self.property0 == 'Particle Size': if self.property0 == 'Particle Size':
self.add_input('LnxFloatSocket', 'Particle Size') self.add_input('LnxFloatSocket', 'Particle Size')
if self.property0 == 'Frame End': if self.property0 == 'Frame End':
self.add_input('LnxIntSocket', 'Frame End') self.add_input('LnxIntSocket', 'Frame End')
if self.property0 == 'Frame Start': if self.property0 == 'Frame Start':
self.add_input('LnxIntSocket', 'Frame Start') self.add_input('LnxIntSocket', 'Frame Start')
if self.property0 == 'Lifetime': if self.property0 == 'Lifetime':
self.add_input('LnxIntSocket', 'Lifetime') self.add_input('LnxIntSocket', 'Lifetime')
if self.property0 == 'Lifetime Random': if self.property0 == 'Lifetime Random':
self.add_input('LnxFloatSocket', 'Lifetime Random') self.add_input('LnxFloatSocket', 'Lifetime Random')
if self.property0 == 'Emit From': if self.property0 == 'Emit From':
self.add_input('LnxIntSocket', 'Emit From') self.add_input('LnxIntSocket', 'Emit From')
if self.property0 == 'Velocity': if self.property0 == 'Auto Start':
self.add_input('LnxVectorSocket', 'Velocity') self.add_input('LnxBoolSocket', 'Auto Start')
if self.property0 == 'Velocity Random': if self.property0 == 'Is Unique':
self.add_input('LnxFloatSocket', 'Velocity Random') self.add_input('LnxBoolSocket', 'Is Unique')
if self.property0 == 'Weight Gravity': if self.property0 == 'Loop':
self.add_input('LnxFloatSocket', 'Weight Gravity') self.add_input('LnxBoolSocket', 'Loop')
if self.property0 == 'Speed': if self.property0 == 'Velocity':
self.add_input('LnxFloatSocket', 'Speed') self.add_input('LnxVectorSocket', 'Velocity')
if self.property0 == 'Velocity Random':
self.add_input('LnxFloatSocket', 'Velocity Random')
property0: HaxeEnumProperty( if self.property0 == 'Weight Gravity':
'property0', self.add_input('LnxFloatSocket', 'Weight Gravity')
items = [('Particle Size', 'Particle Size', 'for the system'), if self.property0 == 'Speed':
('Frame Start', 'Frame Start', 'for the system'), self.add_input('LnxFloatSocket', 'Speed')
('Frame End', 'Frame End', 'for the system'),
('Lifetime', 'Lifetime', 'for the instance'),
('Lifetime Random', 'Lifetime Random', 'for the system'), property0: HaxeEnumProperty(
('Emit From', 'Emit From', 'for the system (Vertices:0 Faces:1 Volume: 2)'), 'property0',
('Velocity', 'Velocity', 'for the instance'), items = [('Particle Size', 'Particle Size', 'for the system'),
('Velocity Random', 'Velocity Random', 'for the system'), ('Frame Start', 'Frame Start', 'for the system'),
('Weight Gravity', 'Weight Gravity', 'for the instance'), ('Frame End', 'Frame End', 'for the system'),
('Speed', 'Speed', 'for the instance')], ('Lifetime', 'Lifetime', 'for the instance'),
name='', default='Speed', update=remove_extra_inputs) ('Lifetime Random', 'Lifetime Random', 'for the system'),
('Emit From', 'Emit From', 'for the system (Vertices:0 Faces:1 Volume: 2)'),
('Auto Start', 'Auto Start', 'for the system'),
def lnx_init(self, context): ('Is Unique', 'Is Unique', 'for the system'),
self.add_input('LnxNodeSocketAction', 'In') ('Loop', 'Loop', 'for the system'),
self.add_input('LnxNodeSocketObject', 'Object') ('Velocity', 'Velocity', 'for the instance'),
self.add_input('LnxIntSocket', 'Slot') ('Velocity Random', 'Velocity Random', 'for the system'),
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0) ('Weight Gravity', 'Weight Gravity', 'for the instance'),
('Speed', 'Speed', 'for the instance')],
self.add_output('LnxNodeSocketAction', 'Out') name='', default='Speed', update=remove_extra_inputs)
def draw_buttons(self, context, layout):
layout.prop(self, 'property0') def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxIntSocket', 'Slot')
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0')

View File

@ -0,0 +1,11 @@
from lnx.logicnode.lnx_nodes import *
class AutoExposureGetNode(LnxLogicTreeNode):
"""Returns the auto exposure post-processing settings."""
bl_idname = 'LNAutoExposureGetNode'
bl_label = 'Get Auto Exposure Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxFloatSocket', 'Strength')
self.add_output('LnxFloatSocket', 'Speed')

View File

@ -1,11 +1,20 @@
from lnx.logicnode.lnx_nodes import * from lnx.logicnode.lnx_nodes import *
class ChromaticAberrationGetNode(LnxLogicTreeNode): class ChromaticAberrationGetNode(LnxLogicTreeNode):
"""Returns the chromatic aberration post-processing settings.""" """Returns the chromatic aberration post-processing settings.
Type: Simple 0 Spectral 1.
"""
bl_idname = 'LNChromaticAberrationGetNode' bl_idname = 'LNChromaticAberrationGetNode'
bl_label = 'Get CA Settings' bl_label = 'Get CA Settings'
lnx_version = 1 lnx_version = 2
def lnx_init(self, context): def lnx_init(self, context):
self.add_output('LnxFloatSocket', 'Strength') self.add_output('LnxFloatSocket', 'Strength')
self.add_output('LnxFloatSocket', 'Samples') self.add_output('LnxFloatSocket', 'Samples')
self.add_output('LnxIntSocket', 'Type')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in (0, 1):
raise LookupError()
return NodeReplacement.Identity(self)

View File

@ -21,6 +21,7 @@ class CameraGetNode(LnxLogicTreeNode):
self.add_output('LnxFloatSocket', 'Film Grain')#11 self.add_output('LnxFloatSocket', 'Film Grain')#11
self.add_output('LnxFloatSocket', 'Sharpen')#12 self.add_output('LnxFloatSocket', 'Sharpen')#12
self.add_output('LnxFloatSocket', 'Vignette')#13 self.add_output('LnxFloatSocket', 'Vignette')#13
self.add_output('LnxFloatSocket', 'Exposure')#14
def get_replacement_node(self, node_tree: bpy.types.NodeTree): def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in (0, 3): if self.lnx_version not in (0, 3):

View File

@ -0,0 +1,12 @@
from lnx.logicnode.lnx_nodes import *
class SharpenGetNode(LnxLogicTreeNode):
"""Returns the sharpen post-processing settings."""
bl_idname = 'LNSharpenGetNode'
bl_label = 'Get Sharpen Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxColorSocket', 'Color')
self.add_output('LnxFloatSocket', 'Size')
self.add_output('LnxFloatSocket', 'Strength')

View File

@ -0,0 +1,12 @@
from lnx.logicnode.lnx_nodes import *
class VolumetricFogGetNode(LnxLogicTreeNode):
"""Returns the volumetric fog post-processing settings."""
bl_idname = 'LNVolumetricFogGetNode'
bl_label = 'Get Volumetric Fog Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxColorSocket', 'Color')
self.add_output('LnxFloatSocket', 'Amount A')
self.add_output('LnxFloatSocket', 'Amount B')

View File

@ -0,0 +1,12 @@
from lnx.logicnode.lnx_nodes import *
class VolumetricLightGetNode(LnxLogicTreeNode):
"""Returns the volumetric light post-processing settings."""
bl_idname = 'LNVolumetricLightGetNode'
bl_label = 'Get Volumetric Light Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxColorSocket', 'Air Color')
self.add_output('LnxFloatSocket', 'Air Turbidity')
self.add_output('LnxIntSocket', 'Steps')

View File

@ -0,0 +1,14 @@
from lnx.logicnode.lnx_nodes import *
class AutoExposureSetNode(LnxLogicTreeNode):
"""Set the sharpen post-processing settings."""
bl_idname = 'LNAutoExposureSetNode'
bl_label = 'Set Auto Exposure Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxFloatSocket', 'Strength', default_value=1)
self.add_input('LnxFloatSocket', 'Speed', default_value=1)
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -1,14 +1,23 @@
from lnx.logicnode.lnx_nodes import * from lnx.logicnode.lnx_nodes import *
class ChromaticAberrationSetNode(LnxLogicTreeNode): class ChromaticAberrationSetNode(LnxLogicTreeNode):
"""Set the chromatic aberration post-processing settings.""" """Set the chromatic aberration post-processing settings.
Type: Simple 0 Spectral 1.
"""
bl_idname = 'LNChromaticAberrationSetNode' bl_idname = 'LNChromaticAberrationSetNode'
bl_label = 'Set CA Settings' bl_label = 'Set CA Settings'
lnx_version = 1 lnx_version = 2
def lnx_init(self, context): def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In') self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxFloatSocket', 'Strength', default_value=2.0) self.add_input('LnxFloatSocket', 'Strength', default_value=2.0)
self.add_input('LnxIntSocket', 'Samples', default_value=32) self.add_input('LnxIntSocket', 'Samples', default_value=32)
self.add_input('LnxIntSocket', 'Type', default_value=0)
self.add_output('LnxNodeSocketAction', 'Out') self.add_output('LnxNodeSocketAction', 'Out')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in (0, 1):
raise LookupError()
return NodeReplacement.Identity(self)

View File

@ -4,27 +4,74 @@ class CameraSetNode(LnxLogicTreeNode):
"""Set the post-processing effects of a camera.""" """Set the post-processing effects of a camera."""
bl_idname = 'LNCameraSetNode' bl_idname = 'LNCameraSetNode'
bl_label = 'Set Camera Post Process' bl_label = 'Set Camera Post Process'
lnx_version = 4 lnx_version = 5
def remove_extra_inputs(self, context):
while len(self.inputs) > 1:
self.inputs.remove(self.inputs[-1])
if self.property0 == 'F-stop':
self.add_input('LnxFloatSocket', 'F-stop', default_value=1.0)#0
if self.property0 == 'Shutter Time':
self.add_input('LnxFloatSocket', 'Shutter Time', default_value=2.8333)#1
if self.property0 == 'ISO':
self.add_input('LnxFloatSocket', 'ISO', default_value=100.0)#2
if self.property0 == 'Exposure Compensation':
self.add_input('LnxFloatSocket', 'Exposure Compensation', default_value=0.0)#3
if self.property0 == 'Fisheye Distortion':
self.add_input('LnxFloatSocket', 'Fisheye Distortion', default_value=0.01)#4
if self.property0 == 'Auto Focus':
self.add_input('LnxBoolSocket', 'Auto Focus', default_value=True)#5
if self.property0 == 'DoF Distance':
self.add_input('LnxFloatSocket', 'DoF Distance', default_value=10.0)#6
if self.property0 == 'DoF Length':
self.add_input('LnxFloatSocket', 'DoF Length', default_value=160.0)#7
if self.property0 == 'DoF F-Stop':
self.add_input('LnxFloatSocket', 'DoF F-Stop', default_value=128.0)#8
if self.property0 == 'Tonemapping':
self.add_input('LnxBoolSocket', 'Tonemapping', default_value=False)#9
if self.property0 == 'Distort':
self.add_input('LnxFloatSocket', 'Distort', default_value=2.0)#10
if self.property0 == 'Film Grain':
self.add_input('LnxFloatSocket', 'Film Grain', default_value=2.0)#11
if self.property0 == 'Sharpen':
self.add_input('LnxFloatSocket', 'Sharpen', default_value=0.25)#12
if self.property0 == 'Vignette':
self.add_input('LnxFloatSocket', 'Vignette', default_value=0.7)#13
if self.property0 == 'Exposure':
self.add_input('LnxFloatSocket', 'Exposure', default_value=1)#14
property0: HaxeEnumProperty(
'property0',
items = [('F-stop', 'F-stop', 'F-stop'),
('Shutter Time', 'Shutter Time', 'Shutter Time'),
('ISO', 'ISO', 'ISO'),
('Exposure Compensation', 'Exposure Compensation', 'Exposure Compensation'),
('Fisheye Distortion', 'Fisheye Distortion', 'Fisheye Distortion'),
('Auto Focus', 'Auto Focus', 'Auto Focus'),
('DoF Distance', 'DoF Distance', 'DoF Distance'),
('DoF Length', 'DoF Length', 'DoF Length'),
('DoF F-Stop', 'DoF F-Stop', 'DoF F-Stop'),
('Tonemapping', 'Tonemapping', 'Tonemapping'),
('Distort', 'Distort', 'Distort'),
('Film Grain', 'Film Grain', 'Film Grain'),
('Sharpen', 'Sharpen', 'Sharpen'),
('Vignette', 'Vignette', 'Vignette'),
('Exposure', 'Exposure', 'Exposure')],
name='', default='F-stop', update=remove_extra_inputs)
def lnx_init(self, context): def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In') self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxFloatSocket', 'F-stop', default_value=1.0)#0 self.add_input('LnxFloatSocket', 'F-stop', default_value=1.0)
self.add_input('LnxFloatSocket', 'Shutter Time', default_value=2.8333)#1
self.add_input('LnxFloatSocket', 'ISO', default_value=100.0)#2
self.add_input('LnxFloatSocket', 'Exposure Compensation', default_value=0.0)#3
self.add_input('LnxFloatSocket', 'Fisheye Distortion', default_value=0.01)#4
self.add_input('LnxBoolSocket', 'Auto Focus', default_value=True)#5
self.add_input('LnxFloatSocket', 'DoF Distance', default_value=10.0)#6
self.add_input('LnxFloatSocket', 'DoF Length', default_value=160.0)#7
self.add_input('LnxFloatSocket', 'DoF F-Stop', default_value=128.0)#8
self.add_input('LnxBoolSocket', 'Tonemapping', default_value=False)#9
self.add_input('LnxFloatSocket', 'Distort', default_value=2.0)#10
self.add_input('LnxFloatSocket', 'Film Grain', default_value=2.0)#11
self.add_input('LnxFloatSocket', 'Sharpen', default_value=0.25)#12
self.add_input('LnxFloatSocket', 'Vignette', default_value=0.7)#13
self.add_output('LnxNodeSocketAction', 'Out') self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0')
def get_replacement_node(self, node_tree: bpy.types.NodeTree): def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in range(0, 4): if self.lnx_version not in range(0, 4):
raise LookupError() raise LookupError()

View File

@ -0,0 +1,15 @@
from lnx.logicnode.lnx_nodes import *
class SharpenSetNode(LnxLogicTreeNode):
"""Set the sharpen post-processing settings."""
bl_idname = 'LNSharpenSetNode'
bl_label = 'Set Sharpen Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxColorSocket', 'Color', default_value=[0.0, 0.0, 0.0, 1.0])
self.add_input('LnxFloatSocket', 'Size', default_value=2.5)
self.add_input('LnxFloatSocket', 'Strength', default_value=0.25)
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -0,0 +1,15 @@
from lnx.logicnode.lnx_nodes import *
class VolumetricFogSetNode(LnxLogicTreeNode):
"""Set the volumetric fog post-processing settings."""
bl_idname = 'LNVolumetricFogSetNode'
bl_label = 'Set Volumetric Fog Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxColorSocket', 'Color', default_value=[0.5, 0.6, 0.7, 1.0])
self.add_input('LnxFloatSocket', 'Amount A', default_value=0.25)
self.add_input('LnxFloatSocket', 'Amount B', default_value=0.50)
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -0,0 +1,15 @@
from lnx.logicnode.lnx_nodes import *
class VolumetricLightSetNode(LnxLogicTreeNode):
"""Set the volumetric light post-processing settings."""
bl_idname = 'LNVolumetricLightSetNode'
bl_label = 'Set Volumetric Light Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxColorSocket', 'Air Color', default_value=[1.0, 1.0, 1.0, 1.0])
self.add_input('LnxFloatSocket', 'Air Turbidity', default_value=1)
self.add_input('LnxIntSocket', 'Steps', default_value=20)
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -4,12 +4,13 @@ class RpConfigNode(LnxLogicTreeNode):
"""Sets the post process quality.""" """Sets the post process quality."""
bl_idname = 'LNRpConfigNode' bl_idname = 'LNRpConfigNode'
bl_label = 'Set Post Process Quality' bl_label = 'Set Post Process Quality'
lnx_version = 1 lnx_version = 2
property0: HaxeEnumProperty( property0: HaxeEnumProperty(
'property0', 'property0',
items = [('SSGI', 'SSGI', 'SSGI'), items = [('SSGI', 'SSGI', 'SSGI'),
('SSR', 'SSR', 'SSR'), ('SSR', 'SSR', 'SSR'),
('Bloom', 'Bloom', 'Bloom'), ('Bloom', 'Bloom', 'Bloom'),
('CA', 'CA', 'CA'),
('GI', 'GI', 'GI'), ('GI', 'GI', 'GI'),
('Motion Blur', 'Motion Blur', 'Motion Blur') ('Motion Blur', 'Motion Blur', 'Motion Blur')
], ],
@ -23,3 +24,10 @@ class RpConfigNode(LnxLogicTreeNode):
def draw_buttons(self, context, layout): def draw_buttons(self, context, layout):
layout.prop(self, 'property0') layout.prop(self, 'property0')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in (0, 1):
raise LookupError()
return NodeReplacement.Identity(self)

View File

@ -40,11 +40,11 @@ def add_world_defs():
if rpdat.rp_hdr == False: if rpdat.rp_hdr == False:
wrd.world_defs += '_LDR' wrd.world_defs += '_LDR'
if wrd.lnx_light_ies_texture != '': if lnx.utils.get_active_scene().world.lnx_light_ies_texture == True:
wrd.world_defs += '_LightIES' wrd.world_defs += '_LightIES'
assets.add_embedded_data('iestexture.png') assets.add_embedded_data('iestexture.png')
if wrd.lnx_light_clouds_texture != '': if lnx.utils.get_active_scene().world.lnx_light_clouds_texture == True:
wrd.world_defs += '_LightClouds' wrd.world_defs += '_LightClouds'
assets.add_embedded_data('cloudstexture.png') assets.add_embedded_data('cloudstexture.png')

View File

@ -510,8 +510,9 @@ def init_properties():
bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0) bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0)
bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84) bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84)
bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=1.0) bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=1.0)
bpy.types.World.lnx_light_ies_texture = StringProperty(name="IES Texture", default="") # For world
bpy.types.World.lnx_light_clouds_texture = StringProperty(name="Clouds Texture", default="") bpy.types.World.lnx_light_ies_texture = BoolProperty(name="IES Texture (iestexture.png)", default=False, update=assets.invalidate_compiler_cache)
bpy.types.World.lnx_light_clouds_texture = BoolProperty(name="Clouds Texture (cloudstexture.png)", default=False, update=assets.invalidate_compiler_cache)
bpy.types.World.lnx_rpcache_list = CollectionProperty(type=bpy.types.PropertyGroup) bpy.types.World.lnx_rpcache_list = CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.lnx_scripts_list = CollectionProperty(type=bpy.types.PropertyGroup) bpy.types.World.lnx_scripts_list = CollectionProperty(type=bpy.types.PropertyGroup)

View File

@ -603,6 +603,8 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_grain: BoolProperty(name="Film Grain", default=False, update=assets.invalidate_shader_cache) lnx_grain: BoolProperty(name="Film Grain", default=False, update=assets.invalidate_shader_cache)
lnx_grain_strength: FloatProperty(name="Strength", default=2.0, update=assets.invalidate_shader_cache) lnx_grain_strength: FloatProperty(name="Strength", default=2.0, update=assets.invalidate_shader_cache)
lnx_sharpen: BoolProperty(name="Sharpen", default=False, update=assets.invalidate_shader_cache) lnx_sharpen: BoolProperty(name="Sharpen", default=False, update=assets.invalidate_shader_cache)
lnx_sharpen_color: FloatVectorProperty(name="Color", size=3, default=[0, 0, 0], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
lnx_sharpen_size: FloatProperty(name="Size", default=2.5, update=assets.invalidate_shader_cache)
lnx_sharpen_strength: FloatProperty(name="Strength", default=0.25, update=assets.invalidate_shader_cache) lnx_sharpen_strength: FloatProperty(name="Strength", default=0.25, update=assets.invalidate_shader_cache)
lnx_fog: BoolProperty(name="Volumetric Fog", default=False, update=assets.invalidate_shader_cache) lnx_fog: BoolProperty(name="Volumetric Fog", default=False, update=assets.invalidate_shader_cache)
lnx_fog_color: FloatVectorProperty(name="Color", size=3, subtype='COLOR', default=[0.5, 0.6, 0.7], min=0, max=1, update=assets.invalidate_shader_cache) lnx_fog_color: FloatVectorProperty(name="Color", size=3, subtype='COLOR', default=[0.5, 0.6, 0.7], min=0, max=1, update=assets.invalidate_shader_cache)

View File

@ -306,8 +306,6 @@ class LNX_PT_DataPropsPanel(bpy.types.Panel):
layout.prop(obj.data, 'lnx_clip_end') layout.prop(obj.data, 'lnx_clip_end')
layout.prop(obj.data, 'lnx_fov') layout.prop(obj.data, 'lnx_fov')
layout.prop(obj.data, 'lnx_shadows_bias') layout.prop(obj.data, 'lnx_shadows_bias')
layout.prop(wrd, 'lnx_light_ies_texture')
layout.prop(wrd, 'lnx_light_clouds_texture')
elif obj.type == 'SPEAKER': elif obj.type == 'SPEAKER':
layout.prop(obj.data, 'lnx_play_on_start') layout.prop(obj.data, 'lnx_play_on_start')
layout.prop(obj.data, 'lnx_loop') layout.prop(obj.data, 'lnx_loop')
@ -335,6 +333,8 @@ class LNX_PT_WorldPropsPanel(bpy.types.Panel):
if world is None: if world is None:
return return
layout.prop(world, 'lnx_light_ies_texture')
layout.prop(world, 'lnx_light_clouds_texture')
layout.prop(world, 'lnx_use_clouds') layout.prop(world, 'lnx_use_clouds')
col = layout.column(align=True) col = layout.column(align=True)
col.enabled = world.lnx_use_clouds col.enabled = world.lnx_use_clouds
@ -1992,10 +1992,18 @@ class LNX_PT_RenderPathCompositorPanel(bpy.types.Panel):
col.prop(rpdat, 'lnx_letterbox_size') col.prop(rpdat, 'lnx_letterbox_size')
layout.separator() layout.separator()
col = layout.column()
col.prop(rpdat, 'lnx_sharpen')
col = col.column(align=True)
col.enabled = rpdat.lnx_sharpen
col.prop(rpdat, 'lnx_sharpen_color')
col.prop(rpdat, 'lnx_sharpen_size')
col.prop(rpdat, 'lnx_sharpen_strength')
layout.separator()
col = layout.column() col = layout.column()
draw_conditional_prop(col, 'Distort', rpdat, 'lnx_distort', 'lnx_distort_strength') draw_conditional_prop(col, 'Distort', rpdat, 'lnx_distort', 'lnx_distort_strength')
draw_conditional_prop(col, 'Film Grain', rpdat, 'lnx_grain', 'lnx_grain_strength') draw_conditional_prop(col, 'Film Grain', rpdat, 'lnx_grain', 'lnx_grain_strength')
draw_conditional_prop(col, 'Sharpen', rpdat, 'lnx_sharpen', 'lnx_sharpen_strength')
draw_conditional_prop(col, 'Vignette', rpdat, 'lnx_vignette', 'lnx_vignette_strength') draw_conditional_prop(col, 'Vignette', rpdat, 'lnx_vignette', 'lnx_vignette_strength')
layout.separator() layout.separator()

View File

@ -451,6 +451,7 @@ def write_config(resx, resy):
'rp_ssr': rpdat.rp_ssr != 'Off', 'rp_ssr': rpdat.rp_ssr != 'Off',
'rp_ss_refraction': rpdat.rp_ss_refraction != 'Off', 'rp_ss_refraction': rpdat.rp_ss_refraction != 'Off',
'rp_bloom': rpdat.rp_bloom != 'Off', 'rp_bloom': rpdat.rp_bloom != 'Off',
'rp_chromatic_aberration': rpdat.rp_chromatic_aberration != 'Off',
'rp_motionblur': rpdat.rp_motionblur != 'Off', 'rp_motionblur': rpdat.rp_motionblur != 'Off',
'rp_gi': rpdat.rp_voxels != "Off", 'rp_gi': rpdat.rp_voxels != "Off",
'rp_dynres': rpdat.rp_dynres 'rp_dynres': rpdat.rp_dynres
@ -784,6 +785,8 @@ const vec3 compoLetterboxColor = vec3(""" + str(round(rpdat.lnx_letterbox_color[
if lnx.utils.get_active_scene().view_settings.exposure != 0.0: if lnx.utils.get_active_scene().view_settings.exposure != 0.0:
f.write( f.write(
"""const float compoExposureStrength = """ + str(round(lnx.utils.get_active_scene().view_settings.exposure * 100) / 100) + """; """const float compoExposureStrength = """ + str(round(lnx.utils.get_active_scene().view_settings.exposure * 100) / 100) + """;
const float compoSharpenSize = """ + str(round(rpdat.lnx_sharpen_size * 100) / 100) + """;
const vec3 compoSharpenColor = vec3(""" + str(round(rpdat.lnx_sharpen_color[0] * 100) / 100) + """, """ + str(round(rpdat.lnx_sharpen_color[1] * 100) / 100) + """, """ + str(round(rpdat.lnx_sharpen_color[2] * 100) / 100) + """);
""") """)
if rpdat.lnx_fog: if rpdat.lnx_fog: