38 Commits
main ... e2002e

Author SHA1 Message Date
316441b954 merge upstream 2025-05-20 20:00:31 +00:00
9bf83bc49f Update leenkx/blender/lnx/material/make_mesh.py 2025-04-18 22:52:53 +00:00
d88e1f0f42 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-18 22:52:03 +00:00
96f4e29778 Update leenkx/blender/lnx/material/make_mesh.py 2025-04-12 08:49:04 +00:00
1d705d2ca2 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-12 08:48:33 +00:00
0979cd976f Update leenkx/blender/lnx/write_data.py 2025-04-11 22:20:24 +00:00
db6d786ee4 merge upstream 2025-04-11 22:06:01 +00:00
106e36e30d merge upstream 2025-04-10 17:16:12 +00:00
2bb296028f merge upstream 2025-04-09 17:30:27 +00:00
25d7ba3e72 merge upstream 2025-04-08 06:33:53 +00:00
bf7b4416ec Update leenkx/blender/lnx/make_renderpath.py 2025-04-07 17:29:09 +00:00
a2d03cfe6e Update leenkx/Shaders/std/light.glsl 2025-04-07 17:26:00 +00:00
95f0ecfc54 Update leenkx/Sources/leenkx/system/Starter.hx 2025-04-07 17:07:52 +00:00
07f59224fc Update leenkx/blender/lnx/write_data.py 2025-04-07 16:50:46 +00:00
02259985be Update leenkx/blender/lnx/props.py 2025-04-07 16:46:33 +00:00
6b8585c81a Update leenkx/blender/lnx/props_renderpath.py 2025-04-07 16:43:01 +00:00
5d78eabf94 Update leenkx/blender/lnx/material/cycles_nodes/nodes_texture.py 2025-04-07 16:39:49 +00:00
41c1459c4e Update leenkx/blender/lnx/material/make_voxel.py 2025-04-07 16:34:12 +00:00
304a497565 Update leenkx/blender/lnx/make_renderpath.py 2025-04-07 16:27:25 +00:00
9fa399371a Update leenkx/blender/lnx/material/make_mesh.py 2025-04-07 16:25:06 +00:00
4625fdb6b2 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-07 16:13:16 +00:00
79553927aa Update leenkx/Shaders/water_pass/water_pass.frag.glsl 2025-04-07 16:06:53 +00:00
86661c1012 Update leenkx/Shaders/voxel_light/voxel_light.comp.glsl 2025-04-07 16:04:17 +00:00
03967c7a2b Update leenkx/Sources/leenkx/system/Starter.hx 2025-04-07 15:50:41 +00:00
61fd48a12f Update leenkx/Shaders/ssr_pass/ssr_pass.frag.glsl 2025-04-07 15:47:22 +00:00
519039b8b6 Update leenkx/Shaders/std/light.glsl 2025-04-07 15:45:04 +00:00
5244b1b3e8 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-04-07 15:41:41 +00:00
7ae3bbe496 Update leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx 2025-04-07 15:39:38 +00:00
001be2f8da Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-04-07 15:35:22 +00:00
6a25b3c5d7 Update leenkx/Shaders/deferred_light/deferred_light.frag.glsl 2025-04-07 15:28:46 +00:00
8d4ac7251a Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-04-07 15:22:49 +00:00
ae63b252c6 Update leenkx/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl 2025-04-07 15:19:03 +00:00
ee73823206 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-04-07 15:17:43 +00:00
af2850e20c Update leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl 2025-04-07 14:49:37 +00:00
bc4a31d415 Update leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl 2025-04-07 14:47:58 +00:00
5303ad3ac6 Update leenkx/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl 2025-04-07 14:44:14 +00:00
5153cff790 Update leenkx/Shaders/std/shadows.glsl 2025-04-07 14:41:53 +00:00
abe17870ce Update leenkx/Shaders/std/conetrace.glsl 2025-04-07 14:38:30 +00:00
136 changed files with 1233 additions and 4066 deletions

View File

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

View File

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

View File

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

View File

@ -62,11 +62,8 @@ uniform vec3 PPComp5;
uniform vec3 PPComp6;
uniform vec3 PPComp7;
uniform vec3 PPComp8;
uniform vec3 PPComp11;
uniform vec3 PPComp14;
uniform vec4 PPComp15;
uniform vec4 PPComp16;
uniform vec4 PPComp18;
#endif
// #ifdef _CPos
@ -109,16 +106,6 @@ in vec2 texCoord;
out vec4 fragColor;
#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 float compoFogAmountA = 1.0; // b = 0.01
// const float compoFogAmountB = 1.0; // c = 0.1
@ -131,8 +118,8 @@ out vec4 fragColor;
// }
vec3 applyFog(vec3 rgb, float distance) {
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
float fogAmount = 1.0 - exp(-distance * (FogAmountA / 100));
return mix(rgb, FogColor, fogAmount);
float fogAmount = 1.0 - exp(-distance * (compoFogAmountA / 100));
return mix(rgb, compoFogColor, fogAmount);
}
#endif
@ -144,7 +131,7 @@ float ConvertEV100ToExposure(float EV100) {
return 1/0.8 * exp2(-EV100);
}
float ComputeEV(float avgLuminance) {
const float sqAperture = PPComp1.x * PPComp1.x;
const float sqAperture = PPComp1[0].x * PPComp1.x;
const float shutterTime = 1.0 / PPComp1.y;
const float ISO = PPComp1.z;
const float EC = PPComp2.x;
@ -362,22 +349,16 @@ void main() {
#ifdef _CSharpen
#ifdef _CPostprocess
float strengthSharpen = PPComp14.y;
vec3 SharpenColor = vec3(PPComp16.x, PPComp16.y, PPComp16.z);
float SharpenSize = PPComp16.w;
float strengthSharpen = PPComp14.y;
#else
float strengthSharpen = compoSharpenStrength;
vec3 SharpenColor = compoSharpenColor;
float SharpenSize = compoSharpenSize;
#endif
vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * SharpenSize, 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) * SharpenSize, 0.0).rgb;
vec3 col4 = textureLod(tex, texCo + vec2(texStep.x, texStep.y) * SharpenSize, 0.0).rgb;
vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * 1.5, 0.0).rgb;
vec3 col2 = textureLod(tex, texCo + vec2(texStep.x, -texStep.y) * 1.5, 0.0).rgb;
vec3 col3 = textureLod(tex, texCo + vec2(-texStep.x, texStep.y) * 1.5, 0.0).rgb;
vec3 col4 = textureLod(tex, texCo + vec2(texStep.x, texStep.y) * 1.5, 0.0).rgb;
vec3 colavg = (col1 + col2 + col3 + col4) * 0.25;
float edgeMagnitude = length(fragColor.rgb - colavg);
fragColor.rgb = mix(fragColor.rgb, SharpenColor, min(edgeMagnitude * strengthSharpen * 2.0, 1.0));
fragColor.rgb += (fragColor.rgb - colavg) * strengthSharpen;
#endif
#ifdef _CFog
@ -426,11 +407,7 @@ void main() {
#endif
#ifdef _CExposure
#ifdef _CPostprocess
fragColor.rgb+=fragColor.rgb*PPComp8.x;
#else
fragColor.rgb+= fragColor.rgb*compoExposureStrength;
#endif
fragColor.rgb += fragColor.rgb * compoExposureStrength;
#endif
#ifdef _CPostprocess
@ -438,13 +415,8 @@ void main() {
#endif
#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);
fragColor.rgb *= pow(expo, AEStrength * 2.0);
fragColor.rgb *= pow(expo, autoExposureStrength * 2.0);
#endif
// Clamp color to get rid of INF values that don't work for the tone mapping below
@ -508,7 +480,9 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
} else if (PPComp4.x == 10){
fragColor.rgb = tonemapAgXFull(fragColor.rgb);
} //else { fragColor.rgb = vec3(0,1,0); //ERROR}
} else {
fragColor.rgb = vec3(0,1,0); //ERROR
}
#endif
#else

View File

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

View File

@ -20,7 +20,7 @@ uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
#ifdef _gbuffer2
uniform sampler2D gbuffer2;
//!uniform sampler2D gbuffer2;
#endif
#ifdef _EmissionShaded
uniform sampler2D gbufferEmission;
@ -286,7 +286,7 @@ void main() {
#ifdef _VoxelGI
vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
fragColor.rgb = (indirect_diffuse.rgb * albedo + envl.rgb * (1.0 - indirect_diffuse.a)) * voxelgiDiff;
fragColor.rgb = (indirect_diffuse.rgb + envl.rgb * (1.0 - indirect_diffuse.a)) * albedo * voxelgiDiff;
if(roughness < 1.0 && occspec.y > 0.0)
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
#endif
@ -380,7 +380,7 @@ void main() {
#endif
#ifdef _VoxelShadow
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, g2.rg).r) * voxelgiShad;
#endif
#ifdef _SSRS

View File

@ -2,22 +2,13 @@
#include "compiled.inc"
#ifdef _CPostprocess
uniform vec3 PPComp8;
#endif
uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;
void main() {
#ifdef _CPostprocess
fragColor.a = 0.01 * PPComp8.z;
#else
fragColor.a = 0.01 * autoExposureSpeed;
#endif
fragColor.a = 0.01 * autoExposureSpeed;
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.8, 0.2), 0.0).rgb +

View File

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

View File

@ -92,7 +92,7 @@ void main() {
vec3 viewNormal = V3 * n;
vec3 viewPos = getPosView(viewRay, d, cameraProj);
vec3 reflected = reflect(viewPos, viewNormal);
vec3 reflected = reflect(normalize(viewPos), viewNormal);
hitCoord = viewPos;
#ifdef _CPostprocess

View File

@ -57,14 +57,17 @@ vec4 binarySearch(vec3 dir) {
}
vec4 rayCast(vec3 dir) {
float ddepth;
dir *= ss_refractionRayStep;
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
ddepth = getDeltaDepth(hitCoord);
if (ddepth > 0.0) return binarySearch(dir);
}
return vec4(texCoord, 0.0, 1.0);
float ddepth;
dir *= ss_refractionRayStep;
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
ddepth = getDeltaDepth(hitCoord);
if (ddepth > 0.0)
return binarySearch(dir);
}
// No hit — fallback to projecting the ray to UV space
vec2 fallbackUV = getProjectedCoord(hitCoord);
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
}
void main() {
@ -74,7 +77,7 @@ void main() {
float ior = gr.x;
float opac = gr.y;
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (d == 0.0 || d == 1.0 || opac == 1.0 || ior == 1.0) {
if (d == 0.0 || opac == 1.0 || ior == 1.0) {
fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
return;
}

View File

@ -166,7 +166,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels,
}
vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
vec3 specularDir = reflect(-viewDir, normal);
vec3 specularDir = reflect(normalize(-viewDir), normal);
vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep;
vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -176,9 +176,9 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels,
return amount * voxelgiOcc;
}
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
const float transmittance = 1.0;
vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior);
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity, const float opacity) {
const float transmittance = 1.0 - opacity;
vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior);
vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -328,8 +328,8 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
}
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel) {
vec3 P = origin + dir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep;
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
vec3 P = origin + dir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
amount = clamp(amount, 0.0, 1.0);
return amount * voxelgiOcc;

View File

@ -1,239 +1,242 @@
#ifndef _LIGHT_GLSL_
#define _LIGHT_GLSL_
#include "compiled.inc"
#include "std/brdf.glsl"
#include "std/math.glsl"
#ifdef _ShadowMap
#include "std/shadows.glsl"
#endif
#ifdef _VoxelShadow
#include "std/conetrace.glsl"
//!uniform sampler2D voxels_shadows;
#endif
#ifdef _LTC
#include "std/ltc.glsl"
#endif
#ifdef _LightIES
#include "std/ies.glsl"
#endif
#ifdef _SSRS
#include "std/ssrs.glsl"
#endif
#ifdef _Spot
#include "std/light_common.glsl"
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
#ifndef _LTC
uniform sampler2DShadow shadowMapSpot[1];
uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform samplerCube shadowMapPointTransparent[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas;
//!uniform sampler2D shadowMapAtlasTransparent;
#endif
uniform vec2 lightProj;
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
uniform sampler2D shadowMapAtlasPointTransparent;
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
uniform samplerCube shadowMapPointTransparent[4];
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
uniform sampler2D shadowMapAtlasSpotTransparent;
#endif
#else
uniform sampler2DShadow shadowMapSpot[4];
uniform sampler2D shadowMapSpotTransparent[4];
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#ifdef _LTC
uniform vec3 lightArea0;
uniform vec3 lightArea1;
uniform vec3 lightArea2;
uniform vec3 lightArea3;
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
#ifdef _ShadowMap
#ifndef _Spot
#ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1];
uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#ifdef _Clusters
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow, bool transparent
#endif
#ifdef _Spot
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
#endif
#ifdef _VoxelShadow
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
#endif
#ifdef _MicroShadowing
, float occ
#endif
#ifdef _SSRS
, sampler2D gbufferD, mat4 invVP, vec3 eye
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);
vec3 h = normalize(v + l);
float dotNH = max(0.0, dot(n, h));
float dotVH = max(0.0, dot(v, h));
float dotNL = max(0.0, dot(n, l));
#ifdef _LTC
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
#else
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
#endif
direct *= attenuate(distance(p, lp));
direct *= lightCol;
#ifdef _MicroShadowing
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
#endif
#ifdef _SSRS
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
#endif
#ifdef _VoxelShadow
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
#endif
#ifdef _LTC
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
#endif
}
#endif
return direct;
#endif
#ifdef _Spot
if (isSpot) {
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, lPos.xyz / lPos.w, bias, transparent
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
#endif
#endif
}
#endif
return direct;
}
#endif
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, ld, -l, bias, lightProj, n, index, transparent
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
#endif
#endif
}
#endif
return direct;
}
#endif
#ifndef _LIGHT_GLSL_
#define _LIGHT_GLSL_
#include "compiled.inc"
#include "std/brdf.glsl"
#include "std/math.glsl"
#ifdef _ShadowMap
#include "std/shadows.glsl"
#endif
#ifdef _VoxelShadow
#include "std/conetrace.glsl"
#endif
#ifdef _gbuffer2
uniform sampler2D gbuffer2;
#endif
#ifdef _LTC
#include "std/ltc.glsl"
#endif
#ifdef _LightIES
#include "std/ies.glsl"
#endif
#ifdef _SSRS
#include "std/ssrs.glsl"
#endif
#ifdef _Spot
#include "std/light_common.glsl"
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
#ifndef _LTC
uniform sampler2DShadow shadowMapSpot[1];
uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform samplerCube shadowMapPointTransparent[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas;
//!uniform sampler2D shadowMapAtlasTransparent;
#endif
uniform vec2 lightProj;
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
uniform sampler2D shadowMapAtlasPointTransparent;
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
uniform samplerCube shadowMapPointTransparent[4];
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
uniform sampler2D shadowMapAtlasSpotTransparent;
#endif
#else
uniform sampler2DShadow shadowMapSpot[4];
uniform sampler2D shadowMapSpotTransparent[4];
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#ifdef _LTC
uniform vec3 lightArea0;
uniform vec3 lightArea1;
uniform vec3 lightArea2;
uniform vec3 lightArea3;
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
#ifdef _ShadowMap
#ifndef _Spot
#ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1];
uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#ifdef _Clusters
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow, bool transparent
#endif
#ifdef _Spot
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
#endif
#ifdef _VoxelShadow
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
#endif
#ifdef _MicroShadowing
, float occ
#endif
#ifdef _SSRS
, sampler2D gbufferD, mat4 invVP, vec3 eye
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);
vec3 h = normalize(v + l);
float dotNH = max(0.0, dot(n, h));
float dotVH = max(0.0, dot(v, h));
float dotNL = max(0.0, dot(n, l));
#ifdef _LTC
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
#else
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
#endif
direct *= attenuate(distance(p, lp));
direct *= lightCol;
#ifdef _MicroShadowing
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
#endif
#ifdef _SSRS
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
#endif
#ifdef _VoxelShadow
vec4 g2 = textureLod(gbuffer2, gl_FragCoord.xy, 0.0);
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy, g2.rg).r) * voxelgiShad;
#endif
#ifdef _LTC
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
#endif
}
#endif
return direct;
#endif
#ifdef _Spot
if (isSpot) {
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, lPos.xyz / lPos.w, bias, transparent
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
#endif
#endif
}
#endif
return direct;
}
#endif
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, ld, -l, bias, lightProj, n, index, transparent
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
#endif
#endif
}
#endif
return direct;
}
#endif

View File

@ -87,40 +87,6 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
return zcomp * 0.5 + 0.5;
}
#ifndef _ShadowMapAtlas
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, vec3 lp, vec3 ml, float bias, vec2 lightProj, vec3 n, const bool transparent) {
const float s = shadowmapCubePcfSize;
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20;
#ifdef _InvY
ml.y = -ml.y;
#endif
float shadowFactor = 0.0;
shadowFactor = texture(shadowMapCube, vec4(ml, compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
shadowFactor /= 9.0;
vec3 result = vec3(shadowFactor);
if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb;
}
return result;
}
#endif
#ifdef _ShadowMapAtlas
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const bool transparent) {
const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
@ -149,7 +115,7 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTranspare
return result;
}
#ifdef _ShadowMapAtlas
// transform "out-of-bounds" coordinates to the correct face/coordinate system
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {

View File

@ -11,8 +11,6 @@ vec3 uncharted2Tonemap(const vec3 x) {
vec3 tonemapUncharted2(const vec3 color) {
const float W = 11.2;
const float exposureBias = 2.0;
// TODO - Find out why black world value of 0.0,0.0,0.0 turns to white pixels
if (dot(color, color) < 0.001) return vec3(0.001);
vec3 curr = uncharted2Tonemap(exposureBias * color);
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
return curr * whiteScale;

View File

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

View File

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

View File

@ -33,6 +33,7 @@ uniform layout(r32ui) uimage3D voxelsLight;
#ifdef _ShadowMap
uniform sampler2DShadow shadowMap;
uniform sampler2D shadowMapTransparent;
uniform sampler2DShadow shadowMapSpot;
#ifdef _ShadowMapAtlas
uniform sampler2DShadow shadowMapPoint;
@ -86,53 +87,51 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
void main() {
int res = voxelgiResolution.x;
for (int i = 0; i < 6; i++) {
ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
P = P * 2.0 - 1.0;
ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
dst.y += clipmapLevel * res;
vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
P = P * 2.0 - 1.0;
P *= clipmaps[int(clipmapLevel * 10)];
P *= voxelgiResolution;
P += vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)]);
vec3 visibility;
vec3 lp = lightPos - P;
vec3 l;
if (lightType == 0) { l = lightDir; visibility = vec3(1.0); }
else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); }
float visibility;
vec3 lp = lightPos - P;
vec3 l;
if (lightType == 0) { l = lightDir; visibility = 1.0; }
else { l = normalize(lp); visibility = attenuate(distance(P, lightPos)); }
#ifdef _ShadowMap
if (lightShadow == 1) {
vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr;
}
else if (lightShadow == 2) {
vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
}
else if (lightShadow == 3) {
#ifdef _ShadowMapAtlas
int faceIndex = 0;
const int lightIndex = index * 6;
const vec2 uv = sampleCube(-l, faceIndex);
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
#else
visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
#endif
}
#endif
if (lightShadow == 1) {
vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
}
else if (lightShadow == 2) {
vec4 lightPosition = LVP * vec4(P, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
}
else if (lightShadow == 3) {
#ifdef _ShadowMapAtlas
int faceIndex = 0;
const int lightIndex = index * 6;
const vec2 uv = sampleCube(-l, faceIndex);
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
#else
visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
#endif
}
#endif
vec3 uvw_light = (P - vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)])) / (float(clipmaps[int(clipmapLevel * 10)]) * voxelgiResolution);
uvw_light = (uvw_light * 0.5 + 0.5);
if (any(notEqual(uvw_light, clamp(uvw_light, 0.0, 1.0)))) return;
vec3 writecoords_light = floor(uvw_light * voxelgiResolution);
vec3 light = visibility * lightColor;
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, 0), uint(light.r * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(light.g * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(light.b * 255));
imageAtomicMax(voxelsLight, ivec3(writecoords_light), uint(visibility * lightColor.r * 255));
imageAtomicMax(voxelsLight, ivec3(writecoords_light) + ivec3(0, 0, voxelgiResolution.x), uint(visibility * lightColor.g * 255));
imageAtomicMax(voxelsLight, ivec3(writecoords_light) + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 255));
}
}

View File

@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
uniform sampler3D voxels;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform layout(r8) image2D voxels_ao;
uniform layout(r16) image2D voxels_ao;
uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP;

View File

@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
uniform sampler3D voxels;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform layout(rgba8) image2D voxels_diffuse;
uniform layout(rgba16) image2D voxels_diffuse;
uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP;
@ -46,7 +46,7 @@ void main() {
const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution;
#ifdef _InvY
uv.y = 1.0 - uv.y
uv.y = 1.0 - uv.y;
#endif
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;

View File

@ -34,7 +34,7 @@ uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler3D voxels;
uniform sampler3D voxelsSDF;
uniform layout(rgba8) image2D voxels_specular;
uniform layout(rgba16) image2D voxels_specular;
uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP;
@ -71,7 +71,7 @@ void main() {
vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z, clipmaps, pixel, velocity).rgb;
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z * g0.z, clipmaps, pixel, velocity).rgb;
imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
}

View File

@ -23,8 +23,8 @@ THE SOFTWARE.
#include "compiled.inc"
uniform layout(r16) image3D input_sdf;
uniform layout(r16) image3D output_sdf;
uniform layout(r8) image3D input_sdf;
uniform layout(r8) image3D output_sdf;
uniform float jump_size;
uniform int clipmapLevel;

View File

@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
uniform layout(r32ui) uimage3D voxelsLight;
uniform layout(rgba8) image3D voxelsB;
uniform layout(rgba8) image3D voxelsOut;
uniform layout(r16) image3D SDF;
uniform layout(r8) image3D SDF;
#else
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
uniform layout(r16) image3D SDF;
uniform layout(r8) image3D SDF;
#endif
uniform layout(r32ui) uimage3D voxels;
uniform layout(r16) image3D voxelsB;
uniform layout(r16) image3D voxelsOut;
uniform layout(r8) image3D voxelsB;
uniform layout(r8) image3D voxelsOut;
#endif
#endif
@ -80,7 +80,6 @@ void main() {
light.r = float(imageLoad(voxelsLight, src)) / 255;
light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
light.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
light /= 3;
#endif
for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
@ -125,7 +124,7 @@ void main() {
envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
envl /= 3;
envl *= 100;
//clipmap to world
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
@ -137,7 +136,7 @@ void main() {
radiance = basecol;
vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
radiance.rgb *= light + indirect;
radiance.rgb *= light / PI + indirect;
radiance.rgb += emission.rgb;
#else

View File

@ -75,16 +75,17 @@ vec4 binarySearch(vec3 dir) {
}
vec4 rayCast(vec3 dir) {
#ifdef _CPostprocess
dir *= PPComp9.x;
#else
dir *= ssrRayStep;
#endif
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
}
return vec4(0.0);
float ddepth;
dir *= ss_refractionRayStep;
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
ddepth = getDeltaDepth(hitCoord);
if (ddepth > 0.0)
return binarySearch(dir);
}
// No hit — fallback to projecting the ray to UV space
vec2 fallbackUV = getProjectedCoord(hitCoord);
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
}
#endif //SSR

View File

@ -12,7 +12,6 @@ class App {
static var traitInits: Array<Void->Void> = [];
static var traitUpdates: Array<Void->Void> = [];
static var traitLateUpdates: Array<Void->Void> = [];
static var traitFixedUpdates: Array<Void->Void> = [];
static var traitRenders: Array<kha.graphics4.Graphics->Void> = [];
static var traitRenders2D: Array<kha.graphics2.Graphics->Void> = [];
public static var framebuffer: kha.Framebuffer;
@ -24,8 +23,6 @@ class App {
public static var renderPathTime: Float;
public static var endFrameCallbacks: Array<Void->Void> = [];
#end
static var last = 0.0;
static var time = 0.0;
static var lastw = -1;
static var lasth = -1;
public static var onResize: Void->Void = null;
@ -37,14 +34,13 @@ class App {
function new(done: Void->Void) {
done();
kha.System.notifyOnFrames(render);
kha.Scheduler.addTimeTask(update, 0, iron.system.Time.step);
kha.Scheduler.addTimeTask(update, 0, iron.system.Time.delta);
}
public static function reset() {
traitInits = [];
traitUpdates = [];
traitLateUpdates = [];
traitFixedUpdates = [];
traitRenders = [];
traitRenders2D = [];
if (onResets != null) for (f in onResets) f();
@ -52,8 +48,6 @@ class App {
static function update() {
if (Scene.active == null || !Scene.active.ready) return;
iron.system.Time.update();
if (pauseUpdates) return;
#if lnx_debug
@ -62,14 +56,6 @@ class App {
Scene.active.updateFrame();
time += iron.system.Time.delta;
while (time >= iron.system.Time.fixedStep) {
for (f in traitFixedUpdates) f();
time -= iron.system.Time.fixedStep;
}
var i = 0;
var l = traitUpdates.length;
while (i < l) {
@ -120,7 +106,7 @@ class App {
var frame = frames[0];
framebuffer = frame;
iron.system.Time.render();
iron.system.Time.update();
if (Scene.active == null || !Scene.active.ready) {
render2D(frame);
@ -186,14 +172,6 @@ class App {
traitLateUpdates.remove(f);
}
public static function notifyOnFixedUpdate(f: Void->Void) {
traitFixedUpdates.push(f);
}
public static function removeFixedUpdate(f: Void->Void) {
traitFixedUpdates.remove(f);
}
public static function notifyOnRender(f: kha.graphics4.Graphics->Void) {
traitRenders.push(f);
}

View File

@ -775,7 +775,6 @@ class Scene {
// Attach particle systems
#if lnx_particles
if (o.particle_refs != null) {
cast(object, MeshObject).render_emitter = o.render_emitter;
for (ref in o.particle_refs) cast(object, MeshObject).setupParticleSystem(sceneName, ref);
}
#end

View File

@ -16,7 +16,6 @@ class Trait {
var _remove: Array<Void->Void> = null;
var _update: Array<Void->Void> = null;
var _lateUpdate: Array<Void->Void> = null;
var _fixedUpdate: Array<Void->Void> = null;
var _render: Array<kha.graphics4.Graphics->Void> = null;
var _render2D: Array<kha.graphics2.Graphics->Void> = null;
@ -88,23 +87,6 @@ class Trait {
App.removeLateUpdate(f);
}
/**
Add fixed game logic handler.
**/
public function notifyOnFixedUpdate(f: Void->Void) {
if (_fixedUpdate == null) _fixedUpdate = [];
_fixedUpdate.push(f);
App.notifyOnFixedUpdate(f);
}
/**
Remove fixed game logic handler.
**/
public function removeFixedUpdate(f: Void->Void) {
_fixedUpdate.remove(f);
App.removeFixedUpdate(f);
}
/**
Add render handler.
**/

View File

@ -392,8 +392,6 @@ typedef TParticleData = {
#end
public var name: String;
public var type: Int; // 0 - Emitter, Hair
public var auto_start: Bool;
public var is_unique: Bool;
public var loop: Bool;
public var count: Int;
public var frame_start: FastFloat;

View File

@ -1,50 +0,0 @@
/*
* format - Haxe File Formats
*
* BMP File Format
* Copyright (C) 2007-2009 Trevor McCauley, Baluta Cristian (hx port) & Robert Sköld (format conversion)
*
* Copyright (c) 2009, The Haxe Project Contributors
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package iron.format.bmp;
typedef Data = {
var header : iron.format.bmp.Header;
var pixels : haxe.io.Bytes;
#if (haxe_ver < 4)
var colorTable : Null<haxe.io.Bytes>;
#else
var ?colorTable : haxe.io.Bytes;
#end
}
typedef Header = {
var width : Int; // real width (in pixels)
var height : Int; // real height (in pixels)
var paddedStride : Int; // number of bytes in a stride (including padding)
var topToBottom : Bool; // whether the bitmap is stored top to bottom
var bpp : Int; // bits per pixel
var dataLength : Int; // equal to `paddedStride` * `height`
var compression : Int; // which compression is being used, 0 for no compression
}

View File

@ -1,122 +0,0 @@
/*
* format - Haxe File Formats
*
* BMP File Format
* Copyright (C) 2007-2009 Robert Sköld
*
* Copyright (c) 2009, The Haxe Project Contributors
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package iron.format.bmp;
import iron.format.bmp.Data;
class Reader {
var input : haxe.io.Input;
public function new( i ) {
input = i;
}
/**
* Only supports uncompressed 24bpp bitmaps (the most common format).
*
* The returned bytes in `Data.pixels` will be in BGR order, and with padding (if present).
*
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx
* @see https://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
*/
public function read() : format.bmp.Data {
// Read Header
for (b in ["B".code, "M".code]) {
if (input.readByte() != b) throw "Invalid header";
}
var fileSize = input.readInt32();
input.readInt32(); // Reserved
var offset = input.readInt32();
// Read InfoHeader
var infoHeaderSize = input.readInt32(); // InfoHeader size
if (infoHeaderSize != 40) {
throw 'Info headers with size $infoHeaderSize not supported.';
}
var width = input.readInt32(); // Image width (actual, not padded)
var height = input.readInt32(); // Image height
var numPlanes = input.readInt16(); // Number of planes
var bits = input.readInt16(); // Bits per pixel
var compression = input.readInt32(); // Compression type
var dataLength = input.readInt32(); // Image data size (includes padding!)
input.readInt32(); // Horizontal resolution
input.readInt32(); // Vertical resolution
var colorsUsed = input.readInt32(); // Colors used (0 when uncompressed)
input.readInt32(); // Important colors (0 when uncompressed)
// If there's no compression, the dataLength may be 0
if ( compression == 0 && dataLength == 0 ) dataLength = fileSize - offset;
var bytesRead = 54; // total read above
var colorTable : haxe.io.Bytes = null;
if ( bits <= 8 ) {
if ( colorsUsed == 0 ) {
colorsUsed = Tools.getNumColorsForBitDepth(bits);
}
var colorTableLength = 4 * colorsUsed;
colorTable = haxe.io.Bytes.alloc( colorTableLength );
input.readFullBytes( colorTable, 0, colorTableLength );
bytesRead += colorTableLength;
}
input.read( offset - bytesRead );
var p = haxe.io.Bytes.alloc( dataLength );
// Read Raster Data
var paddedStride = Tools.computePaddedStride(width, bits);
var topToBottom = false;
if ( height < 0 ) { // if bitmap is stored top to bottom
topToBottom = true;
height = -height;
}
input.readFullBytes(p, 0, dataLength);
return {
header: {
width: width,
height: height,
paddedStride: paddedStride,
topToBottom: topToBottom,
bpp: bits,
dataLength: dataLength,
compression: compression
},
pixels: p,
colorTable: colorTable
}
}
}

View File

@ -1,256 +0,0 @@
/*
* format - Haxe File Formats
*
* BMP File Format
* Copyright (C) 2007-2009 Trevor McCauley, Baluta Cristian (hx port) & Robert Sköld (format conversion)
*
* Copyright (c) 2009, The Haxe Project Contributors
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package iron.format.bmp;
class Tools {
// a r g b
static var ARGB_MAP(default, never):Array<Int> = [0, 1, 2, 3];
static var BGRA_MAP(default, never):Array<Int> = [3, 2, 1, 0];
static var COLOR_SIZE(default, never):Int = 4;
/**
Extract BMP pixel data (24bpp in BGR format) and expands it to BGRA, removing any padding in the process.
**/
inline static public function extractBGRA( bmp : iron.format.bmp.Data ) : haxe.io.Bytes {
return _extract32(bmp, BGRA_MAP, 0xFF);
}
/**
Extract BMP pixel data (24bpp in BGR format) and converts it to ARGB.
**/
inline static public function extractARGB( bmp : iron.format.bmp.Data ) : haxe.io.Bytes {
return _extract32(bmp, ARGB_MAP, 0xFF);
}
/**
Creates BMP data from bytes in BGRA format for each pixel.
**/
inline static public function buildFromBGRA( width : Int, height : Int, srcBytes : haxe.io.Bytes, topToBottom : Bool = false ) : Data {
return _buildFrom32(width, height, srcBytes, BGRA_MAP, topToBottom);
}
/**
Creates BMP data from bytes in ARGB format for each pixel.
**/
inline static public function buildFromARGB( width : Int, height : Int, srcBytes : haxe.io.Bytes, topToBottom : Bool = false ) : Data {
return _buildFrom32(width, height, srcBytes, ARGB_MAP, topToBottom);
}
inline static public function computePaddedStride(width:Int, bpp:Int):Int {
return ((((width * bpp) + 31) & ~31) >> 3);
}
/**
* Gets number of colors for indexed palettes
*/
inline static public function getNumColorsForBitDepth(bpp:Int):Int {
return switch (bpp) {
case 1: 2;
case 4: 16;
case 8: 256;
case 16: 65536;
default: throw 'Unsupported bpp $bpp';
}
}
// `channelMap` contains indices to map into ARGB (f.e. the mapping for ARGB is [0,1,2,3], while for BGRA is [3,2,1,0])
static function _extract32( bmp : iron.format.bmp.Data, channelMap : Array<Int>, alpha : Int = 0xFF) : haxe.io.Bytes {
var srcBytes = bmp.pixels;
var dstLen = bmp.header.width * bmp.header.height * 4;
var dstBytes = haxe.io.Bytes.alloc( dstLen );
var srcPaddedStride = bmp.header.paddedStride;
var yDir = -1;
var dstPos = 0;
var srcPos = srcPaddedStride * (bmp.header.height - 1);
if ( bmp.header.topToBottom ) {
yDir = 1;
srcPos = 0;
}
if ( bmp.header.bpp < 8 || bmp.header.bpp == 16 ) {
throw 'bpp ${bmp.header.bpp} not supported';
}
var colorTable:haxe.io.Bytes = null;
if ( bmp.header.bpp <= 8 ) {
var colorTableLength = getNumColorsForBitDepth(bmp.header.bpp);
colorTable = haxe.io.Bytes.alloc(colorTableLength * COLOR_SIZE);
var definedColorTableLength = Std.int( bmp.colorTable.length / COLOR_SIZE );
for( i in 0...definedColorTableLength ) {
var b = bmp.colorTable.get( i * COLOR_SIZE);
var g = bmp.colorTable.get( i * COLOR_SIZE + 1);
var r = bmp.colorTable.get( i * COLOR_SIZE + 2);
colorTable.set(i * COLOR_SIZE + channelMap[0], alpha);
colorTable.set(i * COLOR_SIZE + channelMap[1], r);
colorTable.set(i * COLOR_SIZE + channelMap[2], g);
colorTable.set(i * COLOR_SIZE + channelMap[3], b);
}
// We want to have the table the full length in case indices outside the range are present
colorTable.fill(definedColorTableLength, colorTableLength - definedColorTableLength, 0);
for( i in definedColorTableLength...colorTableLength ) {
colorTable.set(i * COLOR_SIZE + channelMap[0], alpha);
}
}
switch bmp.header.compression {
case 0:
while( dstPos < dstLen ) {
for( i in 0...bmp.header.width ) {
if (bmp.header.bpp == 8) {
var currentSrcPos = srcPos + i;
var index = srcBytes.get(currentSrcPos);
dstBytes.blit( dstPos, colorTable, index * COLOR_SIZE, COLOR_SIZE );
} else if (bmp.header.bpp == 24) {
var currentSrcPos = srcPos + i * 3;
var b = srcBytes.get(currentSrcPos);
var g = srcBytes.get(currentSrcPos + 1);
var r = srcBytes.get(currentSrcPos + 2);
dstBytes.set(dstPos + channelMap[0], alpha);
dstBytes.set(dstPos + channelMap[1], r);
dstBytes.set(dstPos + channelMap[2], g);
dstBytes.set(dstPos + channelMap[3], b);
} else if (bmp.header.bpp == 32) {
var currentSrcPos = srcPos + i * 4;
var b = srcBytes.get(currentSrcPos);
var g = srcBytes.get(currentSrcPos + 1);
var r = srcBytes.get(currentSrcPos + 2);
dstBytes.set(dstPos + channelMap[0], alpha);
dstBytes.set(dstPos + channelMap[1], r);
dstBytes.set(dstPos + channelMap[2], g);
dstBytes.set(dstPos + channelMap[3], b);
}
dstPos += 4;
}
srcPos += yDir * srcPaddedStride;
}
case 1:
srcPos = 0;
var x = 0;
var y = bmp.header.topToBottom ? 0 : bmp.header.height - 1;
while( srcPos < bmp.header.dataLength ) {
var count = srcBytes.get(srcPos++);
var index = srcBytes.get(srcPos++);
if ( count == 0 ) {
if ( index == 0 ) {
x = 0;
y += yDir;
} else if ( index == 1 ) {
break;
} else if ( index == 2 ) {
x += srcBytes.get(srcPos++);
y += srcBytes.get(srcPos++);
} else {
count = index;
for( i in 0...count ) {
index = srcBytes.get(srcPos++);
dstBytes.blit( COLOR_SIZE * ((x+i) + y * bmp.header.width), colorTable, index * COLOR_SIZE, COLOR_SIZE );
}
if (srcPos % 2 != 0) srcPos++;
x += count;
}
} else {
for( i in 0...count ) {
dstBytes.blit( COLOR_SIZE * ((x+i) + y * bmp.header.width), colorTable, index * COLOR_SIZE, COLOR_SIZE );
}
x += count;
}
}
default:
throw 'compression ${bmp.header.compression} not supported';
}
return dstBytes;
}
// `channelMap` contains indices to map into ARGB (f.e. the mapping for ARGB is [0,1,2,3], while for BGRA is [3,2,1,0])
static function _buildFrom32( width : Int, height : Int, srcBytes : haxe.io.Bytes, channelMap : Array<Int>, topToBottom : Bool = false ) : Data {
var bpp = 24;
var paddedStride = computePaddedStride(width, bpp);
var bytesBGR = haxe.io.Bytes.alloc(paddedStride * height);
var topToBottom = topToBottom;
var dataLength = bytesBGR.length;
var dstStride = width * 3;
var srcLen = width * height * 4;
var yDir = -1;
var dstPos = dataLength - paddedStride;
var srcPos = 0;
if ( topToBottom ) {
yDir = 1;
dstPos = 0;
}
while( srcPos < srcLen ) {
var i = dstPos;
while( i < dstPos + dstStride ) {
var r = srcBytes.get(srcPos + channelMap[1]);
var g = srcBytes.get(srcPos + channelMap[2]);
var b = srcBytes.get(srcPos + channelMap[3]);
bytesBGR.set(i++, b);
bytesBGR.set(i++, g);
bytesBGR.set(i++, r);
srcPos += 4;
}
dstPos += yDir * paddedStride;
}
return {
header: {
width: width,
height: height,
paddedStride: paddedStride,
topToBottom: topToBottom,
bpp: bpp,
dataLength: dataLength,
compression: 0
},
pixels: bytesBGR,
colorTable: null
}
}
}

View File

@ -1,74 +0,0 @@
/*
* format - Haxe File Formats
*
* BMP File Format
* Copyright (C) 2007-2009 Robert Sköld
*
* Copyright (c) 2009, The Haxe Project Contributors
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package iron.format.bmp;
import iron.format.bmp.Data;
class Writer {
static var DATA_OFFSET : Int = 0x36;
var output : haxe.io.Output;
public function new(o) {
output = o;
}
/**
* Specs: http://s223767089.online.de/en/file-format-bmp
*/
public function write( bmp : Data ) {
// Write Header (14 bytes)
output.writeString( "BM" ); // Signature
output.writeInt32(bmp.pixels.length + DATA_OFFSET ); // FileSize
output.writeInt32( 0 ); // Reserved
output.writeInt32( DATA_OFFSET ); // Offset
// Write InfoHeader (40 bytes)
output.writeInt32( 40 ); // InfoHeader size
output.writeInt32( bmp.header.width ); // Image width
var height = bmp.header.height;
if (bmp.header.topToBottom) height = -height;
output.writeInt32( height ); // Image height
output.writeInt16( 1 ); // Number of planes
output.writeInt16( 24 ); // Bits per pixel (24bit RGB)
output.writeInt32( 0 ); // Compression type (no compression)
output.writeInt32( bmp.header.dataLength ); // Image data size (0 when uncompressed)
output.writeInt32( 0x2e30 ); // Horizontal resolution
output.writeInt32( 0x2e30 ); // Vertical resolution
output.writeInt32( 0 ); // Colors used (0 when uncompressed)
output.writeInt32( 0 ); // Important colors (0 when uncompressed)
// Write Raster Data
output.write(bmp.pixels);
}
}

View File

@ -159,17 +159,9 @@ class Animation {
if(markerEvents.get(sampler) != null){
for (i in 0...anim.marker_frames.length) {
if (frameIndex == anim.marker_frames[i]) {
var markerAct = markerEvents.get(sampler);
var ar = markerAct.get(anim.marker_names[i]);
var marketAct = markerEvents.get(sampler);
var ar = marketAct.get(anim.marker_names[i]);
if (ar != null) for (f in ar) f();
} else {
for (j in 0...(frameIndex - lastFrameIndex)) {
if (lastFrameIndex + j + 1 == anim.marker_frames[i]) {
var markerAct = markerEvents.get(sampler);
var ar = markerAct.get(anim.marker_names[i]);
if (ar != null) for (f in ar) f();
}
}
}
}
lastFrameIndex = frameIndex;

View File

@ -21,7 +21,6 @@ class MeshObject extends Object {
public var particleChildren: Array<MeshObject> = null;
public var particleOwner: MeshObject = null; // Particle object
public var particleIndex = -1;
public var render_emitter = true;
#end
public var cameraDistance: Float;
public var screenSize = 0.0;
@ -256,11 +255,11 @@ class MeshObject extends Object {
particleSystems[i].update(particleChildren[i], this);
}
}
if (particleSystems != null && particleSystems.length > 0 && !render_emitter) return;
if (particleSystems == null && cullMaterial(context)) return;
#else
if (cullMaterial(context)) return;
if (particleSystems != null && particleSystems.length > 0 && !raw.render_emitter) return;
#end
if (cullMaterial(context)) return;
// Get lod
var mats = materials;
var lod = this;

View File

@ -172,10 +172,6 @@ class Object {
for (f in t._init) App.removeInit(f);
t._init = null;
}
if (t._fixedUpdate != null) {
for (f in t._fixedUpdate) App.removeFixedUpdate(f);
t._fixedUpdate = null;
}
if (t._update != null) {
for (f in t._update) App.removeUpdate(f);
t._update = null;

View File

@ -2,7 +2,6 @@ package iron.object;
#if lnx_particles
import kha.FastFloat;
import kha.graphics4.Usage;
import kha.arrays.Float32Array;
import iron.data.Data;
@ -17,12 +16,10 @@ import iron.math.Vec4;
class ParticleSystem {
public var data: ParticleData;
public var speed = 1.0;
var currentSpeed = 0.0;
var particles: Array<Particle>;
var ready: Bool;
var frameRate = 24;
var lifetime = 0.0;
var looptime = 0.0;
var animtime = 0.0;
var time = 0.0;
var spawnRate = 0.0;
@ -49,13 +46,9 @@ class ParticleSystem {
var ownerLoc = new Vec4();
var ownerRot = new Quat();
var ownerScl = new Vec4();
var random = 0.0;
public function new(sceneName: String, pref: TParticleReference) {
seed = pref.seed;
currentSpeed = speed;
speed = 0;
particles = [];
ready = false;
@ -72,61 +65,33 @@ class ParticleSystem {
gy = 0;
gz = -9.81 * r.weight_gravity;
}
alignx = r.object_align_factor[0];
aligny = r.object_align_factor[1];
alignz = r.object_align_factor[2];
looptime = (r.frame_end - r.frame_start) / frameRate;
alignx = r.object_align_factor[0] / 2;
aligny = r.object_align_factor[1] / 2;
alignz = r.object_align_factor[2] / 2;
lifetime = r.lifetime / frameRate;
animtime = r.loop ? looptime : looptime + lifetime;
animtime = (r.frame_end - r.frame_start) / frameRate;
spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate;
for (i in 0...r.count) {
particles.push(new Particle(i));
var particle = new Particle(i);
particle.sr = 1 - Math.random() * r.size_random;
particles.push(particle);
}
ready = true;
if (r.auto_start){
start();
}
});
}
public function start() {
if (r.is_unique) random = Math.random();
lifetime = r.lifetime / frameRate;
time = 0;
lap = 0;
lapTime = 0;
speed = currentSpeed;
}
public function pause() {
speed = 0;
lifetime = 0;
}
public function resume() {
lifetime = r.lifetime / frameRate;
speed = currentSpeed;
}
// TODO: interrupt smoothly
public function stop() {
end();
}
function end() {
lifetime = 0;
speed = 0;
lap = 0;
}
public function update(object: MeshObject, owner: MeshObject) {
if (!ready || object == null || speed == 0.0) return;
if (iron.App.pauseUpdates) return;
var prevLap = lap;
// Copy owner world transform but discard scale
owner.transform.world.decompose(ownerLoc, ownerRot, ownerScl);
@ -150,21 +115,17 @@ class ParticleSystem {
}
// Animate
time += Time.renderDelta * speed; // realDelta to renderDelta
time += Time.delta * speed;
lap = Std.int(time / animtime);
lapTime = time - lap * animtime;
count = Std.int(lapTime / spawnRate);
if (lap > prevLap && !r.loop) {
end();
}
updateGpu(object, owner);
}
public function getData(): Mat4 {
var hair = r.type == 1;
m._00 = animtime;
m._00 = r.loop ? animtime : -animtime;
m._01 = hair ? 1 / particles.length : spawnRate;
m._02 = hair ? 1 : lifetime;
m._03 = particles.length;
@ -172,9 +133,9 @@ class ParticleSystem {
m._11 = hair ? 0 : aligny;
m._12 = hair ? 0 : alignz;
m._13 = hair ? 0 : r.factor_random;
m._20 = hair ? 0 : gx;
m._21 = hair ? 0 : gy;
m._22 = hair ? 0 : gz;
m._20 = hair ? 0 : gx * r.mass;
m._21 = hair ? 0 : gy * r.mass;
m._22 = hair ? 0 : gz * r.mass;
m._23 = hair ? 0 : r.lifetime_random;
m._30 = tilesx;
m._31 = tilesy;
@ -183,25 +144,13 @@ class ParticleSystem {
return m;
}
public function getSizeRandom(): FastFloat {
return r.size_random;
}
public function getRandom(): FastFloat {
return random;
}
public function getSize(): FastFloat {
return r.particle_size;
}
function updateGpu(object: MeshObject, owner: MeshObject) {
if (!object.data.geom.instanced) setupGeomGpu(object, owner);
// GPU particles transform is attached to owner object
}
function setupGeomGpu(object: MeshObject, owner: MeshObject) {
var instancedData = new Float32Array(particles.length * 3);
var instancedData = new Float32Array(particles.length * 6);
var i = 0;
var normFactor = 1 / 32767; // pa.values are not normalized
@ -220,6 +169,10 @@ class ParticleSystem {
instancedData.set(i, pa.values[j * pa.size ] * normFactor * scaleFactor.x); i++;
instancedData.set(i, pa.values[j * pa.size + 1] * normFactor * scaleFactor.y); i++;
instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
}
case 1: // Face
@ -243,6 +196,10 @@ class ParticleSystem {
instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
instancedData.set(i, pos.z * normFactor * scaleFactor.z); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
}
case 2: // Volume
@ -253,9 +210,13 @@ class ParticleSystem {
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.x); i++;
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); i++;
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
instancedData.set(i, p.sr); i++;
}
}
object.data.geom.setupInstanced(instancedData, 1, Usage.StaticUsage);
object.data.geom.setupInstanced(instancedData, 3, Usage.StaticUsage);
}
function fhash(n: Int): Float {
@ -294,11 +255,10 @@ class ParticleSystem {
class Particle {
public var i: Int;
public var x = 0.0;
public var y = 0.0;
public var z = 0.0;
public var px = 0.0;
public var py = 0.0;
public var pz = 0.0;
public var sr = 1.0; // Size random
public var cameraDistance: Float;
public function new(i: Int) {

View File

@ -80,7 +80,7 @@ class Tilesheet {
function update() {
if (!ready || paused || action.start >= action.end) return;
time += Time.renderDelta;
time += Time.realDelta;
var frameTime = 1 / raw.framerate;
var framesToAdvance = 0;

View File

@ -1109,26 +1109,6 @@ class Uniforms {
case "_texUnpack": {
f = texUnpack != null ? texUnpack : 1.0;
}
#if lnx_particles
case "_particleSizeRandom": {
var mo = cast(object, MeshObject);
if (mo.particleOwner != null && mo.particleOwner.particleSystems != null) {
f = mo.particleOwner.particleSystems[mo.particleIndex].getSizeRandom();
}
}
case "_particleRandom": {
var mo = cast(object, MeshObject);
if (mo.particleOwner != null && mo.particleOwner.particleSystems != null) {
f = mo.particleOwner.particleSystems[mo.particleIndex].getRandom();
}
}
case "_particleSize": {
var mo = cast(object, MeshObject);
if (mo.particleOwner != null && mo.particleOwner.particleSystems != null) {
f = mo.particleOwner.particleSystems[mo.particleIndex].getSize();
}
}
#end
}
if (f == null && externalFloatLinks != null) {

View File

@ -1,58 +1,37 @@
package iron.system;
class Time {
public static var scale = 1.0;
static var frequency: Null<Int> = null;
static function initFrequency() {
frequency = kha.Display.primary != null ? kha.Display.primary.frequency : 60;
}
public static var step(get, never): Float;
static function get_step(): Float {
if (frequency == null) initFrequency();
return 1 / frequency;
}
static var _fixedStep: Null<Float>;
public static var fixedStep(get, never): Float;
static function get_fixedStep(): Float {
return _fixedStep;
}
public static function initFixedStep(value: Float = 1 / 60) {
_fixedStep = value;
}
static var lastTime = 0.0;
static var _delta = 0.0;
public static var scale = 1.0;
public static var delta(get, never): Float;
static function get_delta(): Float {
return _delta;
if (frequency == null) initFrequency();
return (1 / frequency) * scale;
}
static var lastRenderTime = 0.0;
static var _renderDelta = 0.0;
public static var renderDelta(get, never): Float;
static function get_renderDelta(): Float {
return _renderDelta;
}
static var last = 0.0;
public static var realDelta = 0.0;
public static inline function time(): Float {
return kha.Scheduler.time();
}
public static inline function realTime(): Float {
return kha.Scheduler.realTime();
}
public static function update() {
_delta = realTime() - lastTime;
lastTime = realTime();
static var frequency: Null<Int> = null;
static function initFrequency() {
frequency = kha.Display.primary != null ? kha.Display.primary.frequency : 60;
}
public static function render() {
_renderDelta = realTime() - lastRenderTime;
lastRenderTime = realTime();
public static function update() {
realDelta = realTime() - last;
last = realTime();
}
}

View File

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

View File

@ -1,99 +0,0 @@
package leenkx.logicnode;
import iron.data.SceneFormat.TSceneFormat;
import iron.data.Data;
import iron.object.Object;
class AddParticleToObjectNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
#if lnx_particles
if (property0 == 'Scene Active'){
var objFrom: Object = inputs[1].get();
var slot: Int = inputs[2].get();
var objTo: Object = inputs[3].get();
if (objFrom == null || objTo == null) return;
var mobjFrom = cast(objFrom, iron.object.MeshObject);
var psys = mobjFrom.particleSystems != null ? mobjFrom.particleSystems[slot] :
mobjFrom.particleOwner != null && mobjFrom.particleOwner.particleSystems != null ? mobjFrom.particleOwner.particleSystems[slot] : null;
if (psys == null) return;
var mobjTo = cast(objTo, iron.object.MeshObject);
mobjTo.setupParticleSystem(iron.Scene.active.raw.name, {name: 'LnxPS', seed: 0, particle: @:privateAccess psys.r.name});
mobjTo.render_emitter = inputs[4].get();
iron.Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
if (o != null) {
var c: iron.object.MeshObject = cast o;
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
mobjTo.particleChildren.push(c);
c.particleOwner = mobjTo;
c.particleIndex = mobjTo.particleChildren.length - 1;
}
});
var oslot: Int = mobjTo.particleSystems.length-1;
var opsys = mobjTo.particleSystems[oslot];
@:privateAccess opsys.setupGeomGpu(mobjTo.particleChildren[oslot], mobjTo);
} else {
var sceneName: String = inputs[1].get();
var objectName: String = inputs[2].get();
var slot: Int = inputs[3].get();
var mobjTo: Object = inputs[4].get();
var mobjTo = cast(mobjTo, iron.object.MeshObject);
#if lnx_json
sceneName += ".json";
#elseif lnx_compress
sceneName += ".lz4";
#end
Data.getSceneRaw(sceneName, (rawScene: TSceneFormat) -> {
for (obj in rawScene.objects) {
if (obj.name == objectName) {
mobjTo.setupParticleSystem(sceneName, obj.particle_refs[slot]);
mobjTo.render_emitter = inputs[5].get();
iron.Scene.active.spawnObject(rawScene.particle_datas[slot].instance_object, null, function(o: Object) {
if (o != null) {
var c: iron.object.MeshObject = cast o;
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
mobjTo.particleChildren.push(c);
c.particleOwner = mobjTo;
c.particleIndex = mobjTo.particleChildren.length - 1;
}
}, true, rawScene);
var oslot: Int = mobjTo.particleSystems.length-1;
var opsys = mobjTo.particleSystems[oslot];
@:privateAccess opsys.setupGeomGpu(mobjTo.particleChildren[oslot], mobjTo);
break;
}
}
});
}
#end
runOutput(0);
}
}

View File

@ -1,16 +0,0 @@
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

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

View File

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

View File

@ -10,7 +10,6 @@ class ChromaticAberrationSetNode extends LogicNode {
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[2] = inputs[3].get();
runOutput(0);
}

View File

@ -2,9 +2,6 @@ package leenkx.logicnode;
import iron.Scene;
import iron.object.CameraObject;
import iron.math.Vec4;
import iron.math.Quat;
import leenkx.math.Helper;
import leenkx.renderpath.RenderPathCreator;
@ -30,19 +27,11 @@ class DrawCameraTextureNode extends LogicNode {
final c = inputs[2].get();
assert(Error, Std.isOfType(c, CameraObject), "Camera must be a camera object!");
cam = cast(c, CameraObject);
rt = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
kha.graphics4.TextureFormat.RGBA32,
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
rt = kha.Image.createRenderTarget(iron.App.w(), iron.App.h());
assert(Error, mo.materials[matSlot].contexts[0].textures != null, 'Object "${mo.name}" has no diffuse texture to render to');
mo.materials[matSlot].contexts[0].textures[0] = rt; // Override diffuse texture
final n = inputs[5].get();
for (i => node in mo.materials[matSlot].contexts[0].raw.bind_textures){
if (node.name == n){
mo.materials[matSlot].contexts[0].textures[i] = rt; // Override diffuse texture
break;
}
}
tree.notifyOnRender(render);
runOutput(0);
@ -59,20 +48,8 @@ class DrawCameraTextureNode extends LogicNode {
iron.Scene.active.camera = cam;
cam.renderTarget = rt;
#if kha_html5
var q: Quat = new Quat();
q.fromAxisAngle(new Vec4(0, 0, 1, 1), Helper.degToRad(180));
cam.transform.rot.mult(q);
cam.transform.buildMatrix();
#end
cam.renderFrame(g);
#if kha_html5
cam.transform.rot.mult(q);
cam.transform.buildMatrix();
#end
cam.renderTarget = oldRT;
iron.Scene.active.camera = sceneCam;
}

View File

@ -99,6 +99,8 @@ class DrawImageSequenceNode extends LogicNode {
final colorVec = inputs[4].get();
g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
trace(currentImgIdx);
g.drawScaledImage(images[currentImgIdx], inputs[5].get(), inputs[6].get(), inputs[7].get(), inputs[8].get());
}
}

View File

@ -1,59 +0,0 @@
package leenkx.logicnode;
import iron.math.Vec4;
import kha.Image;
import kha.Color;
import leenkx.renderpath.RenderToTexture;
class DrawSubImageNode extends LogicNode {
var img: Image;
var lastImgName = "";
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
RenderToTexture.ensure2DContext("DrawImageNode");
final imgName: String = inputs[1].get();
final colorVec: Vec4 = inputs[2].get();
final anchorH: Int = inputs[3].get();
final anchorV: Int = inputs[4].get();
final x: Float = inputs[5].get();
final y: Float = inputs[6].get();
final width: Float = inputs[7].get();
final height: Float = inputs[8].get();
final sx: Float = inputs[9].get();
final sy: Float = inputs[10].get();
final swidth: Float = inputs[11].get();
final sheight: Float = inputs[12].get();
final angle: Float = inputs[13].get();
final drawx = x - 0.5 * width * anchorH;
final drawy = y - 0.5 * height * anchorV;
final sdrawx = sx - 0.5 * swidth * anchorH;
final sdrawy = sy - 0.5 * sheight * anchorV;
RenderToTexture.g.rotate(angle, x, y);
if (imgName != lastImgName) {
// Load new image
lastImgName = imgName;
iron.data.Data.getImage(imgName, (image: Image) -> {
img = image;
});
}
if (img == null) {
runOutput(0);
return;
}
RenderToTexture.g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
RenderToTexture.g.drawScaledSubImage(img, sdrawx, sdrawy, swidth, sheight, drawx, drawy, width, height);
RenderToTexture.g.rotate(-angle, x, y);
runOutput(0);
}
}

View File

@ -8,7 +8,7 @@ class GetFPSNode extends LogicNode {
override function get(from: Int): Dynamic {
if (from == 0) {
var fps = Math.round(1 / iron.system.Time.renderDelta);
var fps = Math.round(1 / iron.system.Time.realDelta);
if ((fps == Math.POSITIVE_INFINITY) || (fps == Math.NEGATIVE_INFINITY) || (Math.isNaN(fps))) {
return 0;
}

View File

@ -1,72 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
class GetParticleDataNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
var slot: Int = inputs[1].get();
if (object == null) return null;
#if lnx_particles
var mo = cast(object, iron.object.MeshObject);
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null;
if (psys == null) return null;
return switch (from) {
case 0:
@:privateAccess psys.r.name;
case 1:
@:privateAccess psys.r.particle_size;
case 2:
@:privateAccess psys.r.frame_start;
case 3:
@:privateAccess psys.r.frame_end;
case 4:
@:privateAccess psys.lifetime;
case 5:
@:privateAccess psys.r.lifetime;
case 6:
@:privateAccess psys.r.emit_from;
case 7:
@:privateAccess psys.r.auto_start;
case 8:
@:privateAccess psys.r.is_unique;
case 9:
@:privateAccess psys.r.loop;
case 10:
new iron.math.Vec3(@:privateAccess psys.alignx, @:privateAccess psys.aligny, @:privateAccess psys.alignz);
case 11:
@:privateAccess psys.r.factor_random;
case 12:
new iron.math.Vec3(@:privateAccess psys.gx, @:privateAccess psys.gy, @:privateAccess psys.gz);
case 13:
@:privateAccess psys.r.weight_gravity;
case 14:
psys.speed;
case 15:
@:privateAccess psys.time;
case 16:
@:privateAccess psys.lap;
case 17:
@:privateAccess psys.lapTime;
case 18:
@:privateAccess psys.count;
default:
null;
}
#end
return null;
}
}

View File

@ -1,38 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
class GetParticleNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
if (object == null) return null;
#if lnx_particles
var mo = cast(object, iron.object.MeshObject);
switch (from) {
case 0:
var names: Array<String> = [];
if (mo.particleSystems != null)
for (psys in mo.particleSystems)
names.push(@:privateAccess psys.r.name);
return names;
case 1:
return mo.particleSystems != null ? mo.particleSystems.length : 0;
case 2:
return mo.render_emitter;
default:
null;
}
#end
return null;
}
}

View File

@ -1,12 +1,26 @@
package leenkx.logicnode;
import iron.object.Object;
import iron.math.Vec4;
class GetWorldNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
return iron.Scene.active.raw.world_ref;
var object: Object = inputs[0].get();
if (object == null) return null;
return switch (property0) {
case "Right": object.transform.world.right();
case "Look": object.transform.world.look();
case "Up": object.transform.world.up();
default: null;
}
}
}
}

View File

@ -1,26 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
import iron.math.Vec4;
class GetWorldNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
if (object == null) return null;
return switch (property0) {
case "Right": object.transform.world.right();
case "Look": object.transform.world.look();
case "Up": object.transform.world.up();
default: null;
}
}
}

View File

@ -18,6 +18,7 @@ class ProbabilisticOutputNode extends LogicNode {
}
if (sum > 1){
trace(sum);
for (p in 0...probs.length)
probs[p] /= sum;
}

View File

@ -1,64 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
class RemoveParticleFromObjectNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
#if lnx_particles
var object: Object = inputs[1].get();
if (object == null) return;
var mo = cast(object, iron.object.MeshObject);
if (mo.particleSystems == null) return;
if (property0 == 'All'){
mo.particleSystems = null;
for (c in mo.particleChildren) c.remove();
mo.particleChildren = null;
mo.particleOwner = null;
mo.render_emitter = true;
}
else {
var slot: Int = -1;
if (property0 == 'Name'){
var name: String = inputs[2].get();
for (i => psys in mo.particleSystems){
if (@:privateAccess psys.r.name == name){ slot = i; break; }
}
}
else slot = inputs[2].get();
if (mo.particleSystems.length > slot){
for (i in slot+1...mo.particleSystems.length){
var mi = cast(mo.particleChildren[i], iron.object.MeshObject);
mi.particleIndex = mi.particleIndex - 1;
}
mo.particleSystems.splice(slot, 1);
mo.particleChildren[slot].remove();
mo.particleChildren.splice(slot, 1);
}
if (slot == 0){
mo.particleSystems = null;
mo.particleChildren = null;
mo.particleOwner = null;
mo.render_emitter = true;
}
}
#end
runOutput(0);
}
}

View File

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

View File

@ -1,33 +0,0 @@
package leenkx.logicnode;
import kha.graphics4.TextureFilter;
class ResolutionSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
var size: Int = inputs[1].get();
var filter: Int = inputs[2].get();
#if rp_resolution_filter
if (filter == 0)
iron.object.Uniforms.defaultFilter = TextureFilter.LinearFilter;
else
iron.object.Uniforms.defaultFilter = TextureFilter.PointFilter;
leenkx.renderpath.Postprocess.resolution_uniforms[0] = size;
leenkx.renderpath.Postprocess.resolution_uniforms[1] = filter;
var npath = leenkx.renderpath.RenderPathCreator.get();
var world = iron.Scene.active.raw.world_ref;
npath.loadShader("shader_datas/World_" + world + "/World_" + world);
iron.RenderPath.setActive(npath);
#end
runOutput(0);
}
}

View File

@ -20,8 +20,6 @@ class RpConfigNode extends LogicNode {
on ? leenkx.data.Config.raw.rp_ssrefr = true : leenkx.data.Config.raw.rp_ssrefr = false;
case "Bloom":
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":
on ? leenkx.data.Config.raw.rp_gi = true : leenkx.data.Config.raw.rp_gi = false;
case "Motion Blur":

View File

@ -1,55 +0,0 @@
package leenkx.logicnode;
import iron.object.MeshObject;
import iron.data.MaterialData;
class SetMaterialTextureFilterNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: MeshObject = inputs[1].get();
var mat: MaterialData = inputs[2].get();
var slot: Int = inputs[3].get();
var name: String = inputs[4].get();
var filter: Int = inputs[5].get();
if (object == null) return;
if (slot >= object.materials.length) return;
var mo = cast(object, iron.object.MeshObject);
for (i => node in mo.materials[slot].contexts[0].raw.bind_textures)
if (node.name == name){
var moImgt = mo.materials[slot].contexts[0].raw.bind_textures[i];
switch(filter){
case 0: //Linear
moImgt.min_filter = null;
moImgt.mag_filter = null;
moImgt.mipmap_filter = null;
moImgt.generate_mipmaps = null;
case 1: //Closest
moImgt.min_filter = 'point';
moImgt.mag_filter = 'point';
moImgt.mipmap_filter = null;
moImgt.generate_mipmaps = null;
case 2: //Cubic
moImgt.min_filter = null;
moImgt.mag_filter = null;
moImgt.mipmap_filter = 'linear';
moImgt.generate_mipmaps = true;
case 3: //Smart
moImgt.min_filter = 'anisotropic';
moImgt.mag_filter = null;
moImgt.mipmap_filter = 'linear';
moImgt.generate_mipmaps = true;
}
break;
}
runOutput(0);
}
}

View File

@ -1,81 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
class SetParticleDataNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
#if lnx_particles
var object: Object = inputs[1].get();
var slot: Int = inputs[2].get();
if (object == null) return;
var mo = cast(object, iron.object.MeshObject);
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null; if (psys == null) return;
switch (property0) {
case 'Particle Size':
@:privateAccess psys.r.particle_size = inputs[3].get();
case 'Frame Start':
@:privateAccess psys.r.frame_start = inputs[3].get();
@:privateAccess psys.animtime = (@:privateAccess psys.r.frame_end - @:privateAccess psys.r.frame_start) / @:privateAccess psys.frameRate;
@:privateAccess psys.spawnRate = ((@:privateAccess psys.r.frame_end - @:privateAccess psys.r.frame_start) / @:privateAccess psys.count) / @:privateAccess psys.frameRate;
case 'Frame End':
@:privateAccess psys.r.frame_end = inputs[3].get();
@:privateAccess psys.animtime = (@:privateAccess psys.r.frame_end - @:privateAccess psys.r.frame_start) / @:privateAccess psys.frameRate;
@:privateAccess psys.spawnRate = ((@:privateAccess psys.r.frame_end - @:privateAccess psys.r.frame_start) / @:privateAccess psys.count) / @:privateAccess psys.frameRate;
case 'Lifetime':
@:privateAccess psys.lifetime = inputs[3].get() / @:privateAccess psys.frameRate;
case 'Lifetime Random':
@:privateAccess psys.r.lifetime_random = inputs[3].get();
case 'Emit From':
var emit_from: Int = inputs[3].get();
if (emit_from == 0 || emit_from == 1 || emit_from == 2) {
@:privateAccess psys.r.emit_from = emit_from;
@: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':
var vel: iron.math.Vec3 = inputs[3].get();
@:privateAccess psys.alignx = vel.x;
@:privateAccess psys.aligny = vel.y;
@:privateAccess psys.alignz = vel.z;
case 'Velocity Random':
psys.r.factor_random = inputs[3].get();
case 'Weight Gravity':
psys.r.weight_gravity = inputs[3].get();
if (iron.Scene.active.raw.gravity != null) {
@:privateAccess psys.gx = iron.Scene.active.raw.gravity[0] * @:privateAccess psys.r.weight_gravity;
@:privateAccess psys.gy = iron.Scene.active.raw.gravity[1] * @:privateAccess psys.r.weight_gravity;
@:privateAccess psys.gz = iron.Scene.active.raw.gravity[2] * @:privateAccess psys.r.weight_gravity;
}
else {
@:privateAccess psys.gx = 0;
@:privateAccess psys.gy = 0;
@:privateAccess psys.gz = -9.81 * @:privateAccess psys.r.weight_gravity;
}
case 'Speed':
psys.speed = inputs[3].get();
default:
null;
}
#end
runOutput(0);
}
}

View File

@ -1,23 +0,0 @@
package leenkx.logicnode;
import iron.object.Object;
class SetParticleRenderEmitterNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
#if lnx_particles
var object: Object = inputs[1].get();
if (object == null) return;
cast(object, iron.object.MeshObject).render_emitter = inputs[2].get();
#end
runOutput(0);
}
}

View File

@ -11,16 +11,13 @@ class SetParticleSpeedNode extends LogicNode {
override function run(from: Int) {
#if lnx_particles
var object: Object = inputs[1].get();
var slot: Int = inputs[2].get();
var speed: Float = inputs[3].get();
var speed: Float = inputs[2].get();
if (object == null) return;
var mo = cast(object, iron.object.MeshObject);
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null;
if (psys == null) return;
var psys = mo.particleSystems.length > 0 ? mo.particleSystems[0] : null;
if (psys == null) mo.particleOwner.particleSystems[0];
psys.speed = speed;

View File

@ -1,40 +0,0 @@
package leenkx.logicnode;
class SetWorldNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
var world: String = inputs[1].get();
if (world != null){
//check if world shader data exists
var file: String = 'World_'+world+'_data';
#if lnx_json
file += ".json";
#elseif lnx_compress
file += ".lz4";
#else
file += '.lnx';
#end
var exists: Bool = false;
iron.data.Data.getBlob(file, function(b: kha.Blob) {
if (b != null) exists = true;
});
assert(Error, exists == true, "World must be either associated to a scene or have fake user");
iron.Scene.active.raw.world_ref = world;
var npath = leenkx.renderpath.RenderPathCreator.get();
npath.loadShader("shader_datas/World_" + world + "/World_" + world);
iron.RenderPath.setActive(npath);
}
runOutput(0);
}
}

View File

@ -1,17 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,17 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,17 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,105 +0,0 @@
package leenkx.logicnode;
import iron.object.CameraObject;
class WriteImageNode extends LogicNode {
var file: String;
var camera: CameraObject;
var renderTarget: kha.Image;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
// Relative or absolute path to file
file = inputs[1].get();
assert(Error, iron.App.w() % inputs[3].get() == 0 && iron.App.h() % inputs[4].get() == 0, "Aspect ratio must match display resolution ratio");
camera = inputs[2].get();
renderTarget = kha.Image.createRenderTarget(inputs[3].get(), inputs[4].get(),
kha.graphics4.TextureFormat.RGBA32,
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
tree.notifyOnRender(render);
}
function render(g: kha.graphics4.Graphics) {
var ready = false;
final sceneCam = iron.Scene.active.camera;
final oldRT = camera.renderTarget;
iron.Scene.active.camera = camera;
camera.renderTarget = renderTarget;
camera.renderFrame(g);
var tex = camera.renderTarget;
camera.renderTarget = oldRT;
iron.Scene.active.camera = sceneCam;
var pixels = tex.getPixels();
for (i in 0...pixels.length){
if (pixels.get(i) != 0){ ready = true; break; }
}
//wait for getPixels ready
if (ready) {
var tx = inputs[5].get();
var ty = inputs[6].get();
var tw = inputs[7].get();
var th = inputs[8].get();
var bo = new haxe.io.BytesOutput();
var rgb = haxe.io.Bytes.alloc(tw * th * 4);
for (j in ty...ty + th) {
for (i in tx...tx + tw) {
var k = j * tex.width + i;
var m = (j - ty) * tw + i - tx;
#if kha_krom
var l = k;
#elseif kha_html5
var l = (tex.height - j) * tex.width + i;
#end
//ARGB 0xff
rgb.set(m * 4 + 0, pixels.get(l * 4 + 3));
rgb.set(m * 4 + 1, pixels.get(l * 4 + 0));
rgb.set(m * 4 + 2, pixels.get(l * 4 + 1));
rgb.set(m * 4 + 3, pixels.get(l * 4 + 2));
}
}
var imgwriter = new iron.format.bmp.Writer(bo);
imgwriter.write(iron.format.bmp.Tools.buildFromARGB(tw, th, rgb));
#if kha_krom
Krom.fileSaveBytes(Krom.getFilesLocation() + "/" + file, bo.getBytes().getData());
#elseif kha_html5
var blob = new js.html.Blob([bo.getBytes().getData()], {type: "application"});
var url = js.html.URL.createObjectURL(blob);
var a = cast(js.Browser.document.createElement("a"), js.html.AnchorElement);
a.href = url;
a.download = file;
a.click();
js.html.URL.revokeObjectURL(url);
#end
runOutput(0);
tree.removeRender(render);
}
}
}

View File

@ -77,6 +77,9 @@ class Inc {
#if (rp_voxels == "Voxel GI")
static var voxel_sh5:kha.compute.Shader = null;
static var voxel_ta5:kha.compute.TextureUnit;
static var voxel_te5:kha.compute.TextureUnit;
static var voxel_tf5:kha.compute.TextureUnit;
static var voxel_tg5:kha.compute.TextureUnit;
static var voxel_ca5:kha.compute.ConstantLocation;
static var voxel_cb5:kha.compute.ConstantLocation;
static var voxel_cc5:kha.compute.ConstantLocation;
@ -529,29 +532,22 @@ class Inc {
public static function applyConfig() {
#if lnx_config
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
var l = path.light;
if (l != null){
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
var rt = path.renderTargets.get("shadowMap");
if (rt != null) {
rt.unload();
path.renderTargets.remove("shadowMap");
}
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
var rt = path.renderTargets.get("shadowMap");
if (rt != null) {
rt.unload();
path.renderTargets.remove("shadowMap");
}
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
var rt = path.renderTargets.get("shadowMapCube");
if (rt != null) {
rt.unload();
path.renderTargets.remove("shadowMapCube");
}
}
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
var rt = path.renderTargets.get("shadowMapCube");
if (rt != null) {
rt.unload();
path.renderTargets.remove("shadowMapCube");
}
}
if (superSample != config.rp_supersample) {
@ -684,7 +680,7 @@ class Inc {
}
else {
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
t.format = "R16";
t.format = "R8";
t.width = res;
t.height = res * Main.voxelgiClipmapCount;
t.depth = res;
@ -693,7 +689,7 @@ class Inc {
#if (rp_voxels == "Voxel AO")
{
if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
t.format = "R16";
t.format = "R8";
t.width = res * (6 + 16);
t.height = res * Main.voxelgiClipmapCount;
t.depth = res;
@ -785,11 +781,7 @@ class Inc {
public static inline function getDisplayp(): Null<Int> {
#if rp_resolution_filter // Custom resolution set
#if rp_pp
return leenkx.renderpath.Postprocess.resolution_uniforms[0];
#else
return Main.resolutionSize;
#end
#else
return null;
#end
@ -903,7 +895,9 @@ class Inc {
{
voxel_sh5 = path.getComputeShader("voxel_light");
voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
voxel_te5 = voxel_sh5.getTextureUnit("voxels");
voxel_tf5 = voxel_sh5.getTextureUnit("voxelsSampler");
voxel_tg5 = voxel_sh5.getTextureUnit("voxelsSDFSampler");
voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps");
voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
@ -1224,7 +1218,7 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_td4, rts.get("voxelsSDF").image);
kha.compute.Compute.setTexture(voxel_te4, rts.get("voxels_specular").image, kha.compute.Access.Write);
//kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) {
@ -1299,7 +1293,9 @@ class Inc {
kha.compute.Compute.setShader(voxel_sh5);
kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write);
kha.compute.Compute.setTexture(voxel_te5, rts.get("voxels").image, kha.compute.Access.Read);
kha.compute.Compute.setSampledTexture(voxel_tf5, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tg5, rts.get("voxelsSDF").image);
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) {
fa[i * 10] = clipmaps[i].voxelSize;

View File

@ -49,20 +49,15 @@ class Postprocess {
0.01, //4: Fisheye Distortion
1, //5: DoF AutoFocus §§ If true, it ignores the DoF Distance setting
10.0, //6: DoF Distance
50.0, //7: DoF Focal Length mm
160.0, //7: DoF Focal Length mm
128, //8: DoF F-Stop
0, //9: Tonemapping Method
2.0, //10: Distort
2.0, //11: Film Grain
0.25, //12: Sharpen Strength
0.25, //12: Sharpen
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 = [
1.0, //0: Slope
1.0, //1: Toe
@ -107,35 +102,7 @@ class Postprocess {
public static var chromatic_aberration_uniforms = [
2.0, //0: Strength
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 var resolution_uniforms = [
720, //0: Size
0 //1: Filter
32 //1: Samples
];
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
@ -317,11 +284,6 @@ class Postprocess {
v.x = lenstexture_uniforms[2]; //Lum min
v.y = lenstexture_uniforms[3]; //Lum max
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":
v = iron.object.Uniforms.helpVec;
v.x = ssr_uniforms[0]; //Step
@ -335,8 +297,8 @@ class Postprocess {
case "_PPComp11":
v = iron.object.Uniforms.helpVec;
v.x = bloom_uniforms[2]; // Bloom Strength
v.y = volumetric_light_uniforms[2][0]; //Volumetric Light Steps
v.z = volumetric_fog_uniforms[2][0]; //Volumetric Fog Amount B
v.y = 0; // Unused
v.z = 0; // Unused
case "_PPComp12":
v = iron.object.Uniforms.helpVec;
v.x = ssao_uniforms[0]; //SSAO Strength
@ -346,8 +308,7 @@ class Postprocess {
v = iron.object.Uniforms.helpVec;
v.x = chromatic_aberration_uniforms[0]; //CA Strength
v.y = chromatic_aberration_uniforms[1]; //CA Samples
v.z = chromatic_aberration_uniforms[2]; //CA Type
v.w = chromatic_aberration_uniforms[3]; //On/Off
v.z = 0;
case "_PPComp14":
v = iron.object.Uniforms.helpVec;
v.x = camera_uniforms[10]; //Distort
@ -377,24 +338,6 @@ class Postprocess {
v.y = letterbox_uniforms[0][1];
v.z = letterbox_uniforms[0][2];
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;

View File

@ -368,7 +368,7 @@ class RenderPathDeferred {
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);
// holds background depth
// holds background color
var t = new RenderTargetRaw();
t.name = "refr";
t.width = 0;
@ -473,6 +473,13 @@ class RenderPathDeferred {
}
#end
#if rp_ssrefr
{
path.setTarget("gbuffer_refraction");
path.clearTarget(0xffffff00);
}
#end
RenderPathCreator.setTargetMeshes();
#if rp_dynres
@ -837,7 +844,7 @@ class RenderPathDeferred {
{
path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF");
path.bindTarget("gbuffer2", "sveloc");
path.bindTarget("gbuffer2", "gbuffer2");
}
#end

View File

@ -522,6 +522,17 @@ class RenderPathForward {
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF");

View File

@ -41,7 +41,11 @@ class Starter {
try {
#end
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {
#if lnx_render_viewport
visible: false,
#end
mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
iron.App.init(function() {
#if lnx_loadscreen

View File

@ -45,7 +45,7 @@ class DebugDrawHelper {
iron.App.notifyOnRender2D(onRender);
if (debugDrawMode & DrawRayCast != 0) {
iron.App.notifyOnFixedUpdate(function () {
iron.App.notifyOnUpdate(function () {
rayCasts.resize(0);
});
}

View File

@ -101,7 +101,7 @@ class PhysicsWorld extends Trait {
public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, fixedStep = 1 / 60, debugDrawMode: DebugDrawMode = NoDebug) {
public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, debugDrawMode: DebugDrawMode = NoDebug) {
super();
if (nullvec) {
@ -120,7 +120,6 @@ class PhysicsWorld extends Trait {
this.timeScale = timeScale;
this.maxSteps = maxSteps;
this.solverIterations = solverIterations;
Time.initFixedStep(fixedStep);
// First scene
if (active == null) {
@ -137,10 +136,10 @@ class PhysicsWorld extends Trait {
conMap = new Map();
active = this;
// Ensure physics are updated first in the fixedUpdate list
_fixedUpdate = [fixedUpdate];
@:privateAccess iron.App.traitFixedUpdates.insert(0, fixedUpdate);
// Ensure physics are updated first in the lateUpdate list
_lateUpdate = [lateUpdate];
@:privateAccess iron.App.traitLateUpdates.insert(0, lateUpdate);
setDebugDrawMode(debugDrawMode);
iron.Scene.active.notifyOnRemove(function() {
@ -299,8 +298,8 @@ class PhysicsWorld extends Trait {
return rb;
}
function fixedUpdate() {
var t = Time.fixedStep * timeScale * Time.scale;
function lateUpdate() {
var t = Time.delta * timeScale;
if (t == 0.0) return; // Simulation paused
#if lnx_debug
@ -309,10 +308,13 @@ class PhysicsWorld extends Trait {
if (preUpdates != null) for (f in preUpdates) f();
//This condition must be satisfied to not loose time
var currMaxSteps = t < (Time.fixedStep * maxSteps) ? maxSteps : 1;
//Bullet physics fixed timescale
var fixedTime = 1.0 / 60;
world.stepSimulation(t, currMaxSteps, Time.fixedStep);
//This condition must be satisfied to not loose time
var currMaxSteps = t < (fixedTime * maxSteps) ? maxSteps : 1;
world.stepSimulation(t, currMaxSteps, fixedTime);
updateContacts();
for (rb in rbMap) @:privateAccess rb.physicsUpdate();
@ -434,8 +436,8 @@ class PhysicsWorld extends Trait {
from: from,
to: to,
hasHit: rc.hasHit(),
hitPoint: hitPointWorld.clone(),
hitNormal: hitNormalWorld.clone()
hitPoint: hitPointWorld,
hitNormal: hitNormalWorld
});
}

View File

@ -2,13 +2,11 @@ package leenkx.trait.physics.bullet;
#if lnx_bullet
import leenkx.math.Helper;
import iron.data.MeshData;
import iron.math.Vec4;
import iron.math.Quat;
import iron.object.Transform;
import iron.object.MeshObject;
import iron.system.Time;
import iron.data.MeshData;
/**
RigidBody is used to allow objects to interact with Physics in your game including collisions and gravity.
@ -78,14 +76,6 @@ class RigidBody extends iron.Trait {
static var triangleMeshCache = new Map<MeshData, bullet.Bt.TriangleMesh>();
static var usersCache = new Map<MeshData, Int>();
// Interpolation
var interpolate: Bool = false;
var time: Float = 0.0;
var currentPos: bullet.Bt.Vector3 = new bullet.Bt.Vector3(0, 0, 0);
var prevPos: bullet.Bt.Vector3 = new bullet.Bt.Vector3(0, 0, 0);
var currentRot: bullet.Bt.Quaternion = new bullet.Bt.Quaternion(0, 0, 0, 1);
var prevRot: bullet.Bt.Quaternion = new bullet.Bt.Quaternion(0, 0, 0, 1);
public function new(shape = Shape.Box, mass = 1.0, friction = 0.5, restitution = 0.0, group = 1, mask = 1,
params: RigidBodyParams = null, flags: RigidBodyFlags = null) {
super();
@ -95,7 +85,7 @@ class RigidBody extends iron.Trait {
vec1 = new bullet.Bt.Vector3(0, 0, 0);
vec2 = new bullet.Bt.Vector3(0, 0, 0);
vec3 = new bullet.Bt.Vector3(0, 0, 0);
quat1 = new bullet.Bt.Quaternion(0, 0, 0, 1);
quat1 = new bullet.Bt.Quaternion(0, 0, 0, 0);
trans1 = new bullet.Bt.Transform();
trans2 = new bullet.Bt.Transform();
}
@ -127,7 +117,6 @@ class RigidBody extends iron.Trait {
animated: false,
trigger: false,
ccd: false,
interpolate: false,
staticObj: false,
useDeactivation: true
};
@ -142,7 +131,6 @@ class RigidBody extends iron.Trait {
this.animated = flags.animated;
this.trigger = flags.trigger;
this.ccd = flags.ccd;
this.interpolate = flags.interpolate;
this.staticObj = flags.staticObj;
this.useDeactivation = flags.useDeactivation;
@ -165,7 +153,6 @@ class RigidBody extends iron.Trait {
if (!Std.isOfType(object, MeshObject)) return; // No mesh data
transform = object.transform;
transform.buildMatrix();
physics = leenkx.trait.physics.PhysicsWorld.active;
if (shape == Shape.Box) {
@ -257,9 +244,6 @@ class RigidBody extends iron.Trait {
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
trans1.setRotation(quat1);
currentPos.setValue(vec1.x(), vec1.y(), vec1.z());
currentRot.setValue(quat.x, quat.y, quat.z, quat.w);
var centerOfMassOffset = trans2;
centerOfMassOffset.setIdentity();
motionState = new bullet.Bt.DefaultMotionState(trans1, centerOfMassOffset);
@ -323,8 +307,7 @@ class RigidBody extends iron.Trait {
physics.addRigidBody(this);
notifyOnRemove(removeFromWorld);
if (!animated) notifyOnUpdate(update);
if (onReady != null) onReady();
#if js
@ -334,71 +317,26 @@ class RigidBody extends iron.Trait {
#end
}
function update() {
if (interpolate) {
time += Time.delta;
while (time >= Time.fixedStep) {
time -= Time.fixedStep;
}
var t: Float = time / Time.fixedStep;
t = Helper.clamp(t, 0, 1);
var tx: Float = prevPos.x() * (1.0 - t) + currentPos.x() * t;
var ty: Float = prevPos.y() * (1.0 - t) + currentPos.y() * t;
var tz: Float = prevPos.z() * (1.0 - t) + currentPos.z() * t;
var tRot: bullet.Bt.Quaternion = nlerp(prevRot, currentRot, t);
transform.loc.set(tx, ty, tz, 1.0);
transform.rot.set(tRot.x(), tRot.y(), tRot.z(), tRot.w());
} else {
transform.loc.set(currentPos.x(), currentPos.y(), currentPos.z(), 1.0);
transform.rot.set(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
}
if (object.parent != null) {
var ptransform = object.parent.transform;
transform.loc.x -= ptransform.worldx();
transform.loc.y -= ptransform.worldy();
transform.loc.z -= ptransform.worldz();
}
transform.buildMatrix();
}
function nlerp(q1: bullet.Bt.Quaternion, q2: bullet.Bt.Quaternion, t: Float): bullet.Bt.Quaternion {
var dot = q1.x() * q2.x() + q1.y() * q2.y() + q1.z() * q2.z() + q1.w() * q2.w();
var _q2 = dot < 0 ? new bullet.Bt.Quaternion(-q2.x(), -q2.y(), -q2.z(), -q2.w()) : q2;
var x = q1.x() * (1.0 - t) + _q2.x() * t;
var y = q1.y() * (1.0 - t) + _q2.y() * t;
var z = q1.z() * (1.0 - t) + _q2.z() * t;
var w = q1.w() * (1.0 - t) + _q2.w() * t;
var len = Math.sqrt(x * x + y * y + z * z + w * w);
return new bullet.Bt.Quaternion(x / len, y / len, z / len, w / len);
}
function physicsUpdate() {
if (!ready) return;
if (animated) {
syncTransform();
} else {
if (interpolate) {
prevPos.setValue(currentPos.x(), currentPos.y(), currentPos.z());
prevRot.setValue(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
}
}
else {
var trans = body.getWorldTransform();
var p = trans.getOrigin();
var q = trans.getRotation();
transform.clearDelta();
// transform.buildMatrix();
currentPos.setValue(p.x(), p.y(), p.z());
currentRot.setValue(q.x(), q.y(), q.z(), q.w());
transform.loc.set(p.x(), p.y(), p.z());
transform.rot.set(q.x(), q.y(), q.z(), q.w());
if (object.parent != null) {
var ptransform = object.parent.transform;
transform.loc.x -= ptransform.worldx();
transform.loc.y -= ptransform.worldy();
transform.loc.z -= ptransform.worldz();
}
transform.clearDelta();
transform.buildMatrix();
#if hl
p.delete();
@ -751,7 +689,6 @@ typedef RigidBodyFlags = {
var animated: Bool;
var trigger: Bool;
var ccd: Bool;
var interpolate: Bool;
var staticObj: Bool;
var useDeactivation: Bool;
}

View File

@ -540,7 +540,7 @@ class LeenkxExporter:
o['material_refs'].append(lnx.utils.asset_name(material))
def export_particle_system_ref(self, psys: bpy.types.ParticleSystem, out_object):
if psys.settings.instance_object is None or psys.settings.render_type != 'OBJECT' or not psys.settings.instance_object.lnx_export or not bpy.data.objects[out_object['name']].modifiers[psys.name].show_render:
if psys.settings.instance_object is None or psys.settings.render_type != 'OBJECT' or not psys.settings.instance_object.lnx_export:
return
self.particle_system_array[psys.settings] = {"structName": psys.settings.name}
@ -910,8 +910,7 @@ class LeenkxExporter:
out_object['particle_refs'] = []
out_object['render_emitter'] = bobject.show_instancer_for_render
for i in range(num_psys):
if bobject.modifiers[bobject.particle_systems[i].name].show_render:
self.export_particle_system_ref(bobject.particle_systems[i], out_object)
self.export_particle_system_ref(bobject.particle_systems[i], out_object)
aabb = bobject.data.lnx_aabb
if aabb[0] == 0 and aabb[1] == 0 and aabb[2] == 0:
@ -2281,15 +2280,6 @@ class LeenkxExporter:
if len(self.particle_system_array) > 0:
self.output['particle_datas'] = []
for particleRef in self.particle_system_array.items():
padd = False;
for obj in self.output['objects']:
if 'particle_refs' in obj:
for pref in obj['particle_refs']:
if pref['particle'] == particleRef[1]["structName"]:
if bpy.data.objects[obj['name']].modifiers[pref['name']].show_render == True:
padd = True;
if not padd:
continue;
psettings = particleRef[0]
if psettings is None:
@ -2307,8 +2297,6 @@ class LeenkxExporter:
out_particlesys = {
'name': particleRef[1]["structName"],
'type': 0 if psettings.type == 'EMITTER' else 1, # HAIR
'auto_start': psettings.lnx_auto_start,
'is_unique': psettings.lnx_is_unique,
'loop': psettings.lnx_loop,
# Emission
'count': int(psettings.count * psettings.lnx_count_mult),
@ -2825,7 +2813,6 @@ class LeenkxExporter:
body_flags['animated'] = rb.kinematic
body_flags['trigger'] = bobject.lnx_rb_trigger
body_flags['ccd'] = bobject.lnx_rb_ccd
body_flags['interpolate'] = bobject.lnx_rb_interpolate
body_flags['staticObj'] = is_static
body_flags['useDeactivation'] = rb.use_deactivation
x['parameters'].append(lnx.utils.get_haxe_json_string(body_params))
@ -3050,7 +3037,7 @@ class LeenkxExporter:
rbw = self.scene.rigidbody_world
if rbw is not None and rbw.enabled:
out_trait['parameters'] = [str(rbw.time_scale), str(rbw.substeps_per_frame), str(rbw.solver_iterations), str(wrd.lnx_physics_fixed_step)]
out_trait['parameters'] = [str(rbw.time_scale), str(rbw.substeps_per_frame), str(rbw.solver_iterations)]
if phys_pkg == 'bullet' or phys_pkg == 'oimo':
debug_draw_mode = 1 if wrd.lnx_physics_dbg_draw_wireframe else 0

View File

@ -87,7 +87,6 @@ def on_operator_post(operator_id: str) -> None:
target_obj.lnx_rb_trigger = source_obj.lnx_rb_trigger
target_obj.lnx_rb_deactivation_time = source_obj.lnx_rb_deactivation_time
target_obj.lnx_rb_ccd = source_obj.lnx_rb_ccd
target_obj.lnx_rb_interpolate = source_obj.lnx_rb_interpolate
target_obj.lnx_rb_collision_filter_mask = source_obj.lnx_rb_collision_filter_mask
elif operator_id == "NODE_OT_new_node_tree":

View File

@ -191,7 +191,7 @@ def apply_materials(load_atlas=0):
mainNode = outputNode.inputs[0].links[0].from_node.inputs[0].links[0].from_node
if (mainNode.type == "ShaderNodeMix"):
if (mainNode.type == "ShaderNodeMixRGB"):
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
print("Mix RGB shader found")
@ -199,11 +199,9 @@ def apply_materials(load_atlas=0):
#Add all nodes first
#Add lightmap multipliction texture
mixNode = node_tree.nodes.new(type="ShaderNodeMix")
mixNode = node_tree.nodes.new(type="ShaderNodeMixRGB")
mixNode.name = "Lightmap_Multiplication"
mixNode.location = -800, 300
mixNode.data_type = 'RGBA'
mixNode.inputs[0].default_value = 1
if scene.TLM_EngineProperties.tlm_lighting_mode == "indirect" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectAO":
mixNode.blend_type = 'MULTIPLY'
else:
@ -314,8 +312,8 @@ def apply_materials(load_atlas=0):
else:
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[6]) #Connect decode node to mixnode
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[6]) #Connect exposure node to mixnode
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[1]) #Connect decode node to mixnode
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[1]) #Connect exposure node to mixnode
else:
@ -325,10 +323,10 @@ def apply_materials(load_atlas=0):
else:
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[7]) #Connect basecolor to pbr node
mat.node_tree.links.new(mixNode.outputs[2], mainNode.inputs[0]) #Connect mixnode to pbr node
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[2]) #Connect basecolor to pbr node
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
if not scene.TLM_EngineProperties.tlm_target == "vertex":
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
@ -340,11 +338,11 @@ def apply_materials(load_atlas=0):
if(scene.TLM_EngineProperties.tlm_exposure_multiplier > 0):
mat.node_tree.links.new(lightmapNode.outputs[0], ExposureNode.inputs[0]) #Connect lightmap node to mixnode
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
else:
mat.node_tree.links.new(lightmapNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[7]) #Connect basecolor to pbr node
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[2]) #Connect mixnode to pbr node
mat.node_tree.links.new(lightmapNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[2]) #Connect basecolor to pbr node
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
if not scene.TLM_EngineProperties.tlm_target == "vertex":
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
@ -493,9 +491,8 @@ def applyAOPass():
AOMap.image = AOImage
AOMap.location = -800, 0
AOMult = nodes.new(type="ShaderNodeMix")
AOMult = nodes.new(type="ShaderNodeMixRGB")
AOMult.name = "TLM_AOMult"
AOMult.data_type = 'RGBA'
AOMult.blend_type = 'MULTIPLY'
AOMult.inputs[0].default_value = 1.0
AOMult.location = -300, 300

View File

@ -518,7 +518,7 @@ def configure_meshes(self):
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
print("The material group is not supported!")
if (mainNode.type == "ShaderNodeMix"):
if (mainNode.type == "ShaderNodeMixRGB"):
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
print("Mix shader found")
@ -811,7 +811,7 @@ def set_settings():
print(bpy.app.version)
if bpy.app.version[0] == 3 or byp.app.version[0] == 4:
if bpy.app.version[0] == 3:
if cycles.device == "GPU":
scene.cycles.tile_size = 256
else:

View File

@ -28,11 +28,7 @@ class ViewportDraw:
w = 400
h = 200
if bpy.app.version[0] == 3:
self.shader = gpu.shader.from_builtin('2D_IMAGE')
else:
self.shader = gpu.shader.from_builtin('IMAGE')
self.shader = gpu.shader.from_builtin('2D_IMAGE')
self.batch = batch_for_shader(
self.shader, 'TRI_FAN',
{

View File

@ -34,7 +34,7 @@ class Shader_Node_Types:
normal = "ShaderNodeNormalMap"
ao = "ShaderNodeAmbientOcclusion"
uv = "ShaderNodeUVMap"
mix = "ShaderNodeMix"
mix = "ShaderNodeMixRGB"
def select_object(self,obj):
C = bpy.context

View File

@ -47,8 +47,7 @@ def init_categories():
lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion")
lnx_nodes.add_category('Transform', icon='TRANSFORM_ORIGINS', section="motion")
lnx_nodes.add_category('Physics', icon='PHYSICS', section="motion")
lnx_nodes.add_category('Particle', icon='PARTICLE_DATA', section="motion")
lnx_nodes.add_category('Array', icon='MOD_ARRAY', section="values")
lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values")
lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values")

View File

@ -1,22 +1,14 @@
from lnx.logicnode.lnx_nodes import *
class SetParticleSpeedNode(LnxLogicTreeNode):
"""Sets the speed of the given particle source."""
bl_idname = 'LNSetParticleSpeedNode'
bl_label = 'Set Particle Speed'
lnx_version = 2
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 get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.lnx_version not in (0, 1):
raise LookupError()
return NodeReplacement.Identity(self)
from lnx.logicnode.lnx_nodes import *
class SetParticleSpeedNode(LnxLogicTreeNode):
"""Sets the speed of the given particle source."""
bl_idname = 'LNSetParticleSpeedNode'
bl_label = 'Set Particle Speed'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -11,15 +11,14 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
@input Object: Object of which to choose the material in the `Material Slot` input.
@input Material Slot: Index of the material slot of which the diffuse
texture is replaced with the camera's render target.
@input Node: Node name of the Image Texture Node.
@output On Start: Activated after the `Start` input has been activated.
@output On Stop: Activated after the `Stop` input has been activated.
"""
bl_idname = 'LNDrawCameraTextureNode'
bl_label = 'Draw Camera to Texture'
lnx_section = 'draw'
lnx_version = 2
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'Start')
@ -27,13 +26,6 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
self.add_input('LnxNodeSocketObject', 'Camera')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxIntSocket', 'Material Slot')
self.add_input('LnxStringSocket', 'Node')
self.add_output('LnxNodeSocketAction', 'On Start')
self.add_output('LnxNodeSocketAction', 'On Stop')
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

@ -1,44 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class DrawSubImageNode(LnxLogicTreeNode):
"""Draws an image.
@input Draw: Activate to draw the image on this frame. The input must
be (indirectly) called from an `On Render2D` node.
@input Image: The filename of the image.
@input Color: The color that the image's pixels are multiplied with.
@input Left/Center/Right: Horizontal anchor point of the image.
0 = Left, 1 = Center, 2 = Right
@input Top/Middle/Bottom: Vertical anchor point of the image.
0 = Top, 1 = Middle, 2 = Bottom
@input X/Y: Position of the anchor point in pixels.
@input Width/Height: Size of the sub image in pixels.
@input sX/Y: Position of the sub anchor point in pixels.
@input sWidth/Height: Size of the image in pixels.
@input Angle: Rotation angle in radians. Image will be rotated cloclwiswe
at the anchor point.
@output Out: Activated after the image has been drawn.
@see [`kha.graphics2.Graphics.drawImage()`](http://kha.tech/api/kha/graphics2/Graphics.html#drawImage).
"""
bl_idname = 'LNDrawSubImageNode'
bl_label = 'Draw Sub Image'
lnx_section = 'draw'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'Draw')
self.add_input('LnxStringSocket', 'Image File')
self.add_input('LnxColorSocket', 'Color', default_value=[1.0, 1.0, 1.0, 1.0])
self.add_input('LnxIntSocket', '0/1/2 = Left/Center/Right', default_value=0)
self.add_input('LnxIntSocket', '0/1/2 = Top/Middle/Bottom', default_value=0)
self.add_input('LnxFloatSocket', 'X')
self.add_input('LnxFloatSocket', 'Y')
self.add_input('LnxFloatSocket', 'Width')
self.add_input('LnxFloatSocket', 'Height')
self.add_input('LnxFloatSocket', 'sX')
self.add_input('LnxFloatSocket', 'sY')
self.add_input('LnxFloatSocket', 'sWidth')
self.add_input('LnxFloatSocket', 'sHeight')
self.add_input('LnxFloatSocket', 'Angle')
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -1,23 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class SetMaterialTextureFilterNode(LnxLogicTreeNode):
"""Sets texture filter interpolation."""
bl_idname = 'LNSetMaterialTextureFilterNode'
bl_label = 'Set Object Material Texture Filter'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxDynamicSocket', 'Material')
self.add_input('LnxIntSocket', 'Slot')
self.add_input('LnxStringSocket', 'Node')
self.add_input('LnxIntSocket', 'Texture Filter')
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.label(text='Tex Filter 0: Linear')
layout.label(text='Tex Filter 1: Closest')
layout.label(text='Tex Filter 2: Cubic')
layout.label(text='Tex Filter 3: Smart')

View File

@ -5,6 +5,8 @@ class WriteFileNode(LnxLogicTreeNode):
"""Writes the given string content to the given file. If the file
already exists, the existing content of the file is overwritten.
> **This node is currently only implemented on Krom**
@input File: the name of the file, relative to `Krom.getFilesLocation()`
@input Content: the content to write to the file.

View File

@ -1,34 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class WriteImageNode(LnxLogicTreeNode):
"""Writes the given image to the given file. If the image
already exists, the existing content of the image is overwritten.
Aspect ratio must match display resolution ratio.
@input Image File: the name of the image, relative to `Krom.getFilesLocation()`
@input Camera: the render target image of the camera to write to the image file.
@input Width: width of the image file.
@input Height: heigth of the image file.
@input sX: sub position of first x pixel of the sub image (0 for start).
@input sY: sub position of first y pixel of the sub image (0 for start).
@input sWidth: width of the sub image.
@input sHeight: height of the sub image.
@seeNode Read File
"""
bl_idname = 'LNWriteImageNode'
bl_label = 'Write Image'
lnx_section = 'file'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxStringSocket', 'Image File')
self.add_input('LnxNodeSocketObject', 'Camera')
self.add_input('LnxIntSocket', 'Width')
self.add_input('LnxIntSocket', 'Height')
self.add_input('LnxIntSocket', 'sX')
self.add_input('LnxIntSocket', 'sY')
self.add_input('LnxIntSocket', 'sWidth')
self.add_input('LnxIntSocket', 'sHeight')
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -5,6 +5,8 @@ class WriteJsonNode(LnxLogicTreeNode):
"""Writes the given content to the given JSON file. If the file
already exists, the existing content of the file is overwritten.
> **This node is currently only implemented on Krom**
@input File: the name of the file, relative to `Krom.getFilesLocation()`,
including the file extension.
@input Dynamic: the content to write to the file. Can be any type that can

View File

@ -1,41 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class AddParticleToObjectNode(LnxLogicTreeNode):
"""Sets the speed of the given particle source."""
bl_idname = 'LNAddParticleToObjectNode'
bl_label = 'Add Particle To Object'
lnx_version = 1
def remove_extra_inputs(self, context):
while len(self.inputs) > 1:
self.inputs.remove(self.inputs[-1])
if self.property0 == 'Scene':
self.add_input('LnxStringSocket', 'Scene From Name')
self.add_input('LnxStringSocket', 'Object From Name')
else:
self.add_input('LnxNodeSocketObject', 'Object From')
self.add_input('LnxIntSocket', 'Slot')
self.add_input('LnxNodeSocketObject', 'Object To')
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
property0: HaxeEnumProperty(
'property0',
items = [('Scene Active', 'Scene Active', 'Scene Active'),
('Scene', 'Scene', 'Scene')],
name='', default='Scene Active', update=remove_extra_inputs)
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object From')
self.add_input('LnxIntSocket', 'Slot')
self.add_input('LnxNodeSocketObject', 'Object To')
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0')

View File

@ -1,14 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class GetParticleNode(LnxLogicTreeNode):
"""Returns the Particle Systems of an object."""
bl_idname = 'LNGetParticleNode'
bl_label = 'Get Particle'
lnx_version = 1
def lnx_init(self, context):
self.inputs.new('LnxNodeSocketObject', 'Object')
self.outputs.new('LnxNodeSocketArray', 'Names')
self.outputs.new('LnxIntSocket', 'Length')
self.outputs.new('LnxBoolSocket', 'Render Emitter')

View File

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

View File

@ -1,33 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class RemoveParticleFromObjectNode(LnxLogicTreeNode):
"""Remove Particle From Object."""
bl_idname = 'LNRemoveParticleFromObjectNode'
bl_label = 'Remove Particle From Object'
lnx_version = 1
def remove_extra_inputs(self, context):
while len(self.inputs) > 2:
self.inputs.remove(self.inputs[-1])
if self.property0 == 'Slot':
self.add_input('LnxIntSocket', 'Slot')
if self.property0 == 'Name':
self.add_input('LnxStringSocket', 'Name')
property0: HaxeEnumProperty(
'property0',
items = [('Slot', 'Slot', 'Slot'),
('Name', 'Name', 'Name'),
('All', 'All', 'All')],
name='', default='Slot', update=remove_extra_inputs)
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxIntSocket', 'Slot')
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0')

View File

@ -1,67 +0,0 @@
from lnx.logicnode.lnx_nodes import *
class SetParticleDataNode(LnxLogicTreeNode):
"""Sets the parameters of the given particle system."""
bl_idname = 'LNSetParticleDataNode'
bl_label = 'Set Particle Data'
lnx_version = 1
def remove_extra_inputs(self, context):
while len(self.inputs) > 3:
self.inputs.remove(self.inputs[-1])
if self.property0 == 'Particle Size':
self.add_input('LnxFloatSocket', 'Particle Size')
if self.property0 == 'Frame End':
self.add_input('LnxIntSocket', 'Frame End')
if self.property0 == 'Frame Start':
self.add_input('LnxIntSocket', 'Frame Start')
if self.property0 == 'Lifetime':
self.add_input('LnxIntSocket', 'Lifetime')
if self.property0 == 'Lifetime Random':
self.add_input('LnxFloatSocket', 'Lifetime Random')
if self.property0 == 'Emit From':
self.add_input('LnxIntSocket', 'Emit From')
if self.property0 == 'Auto Start':
self.add_input('LnxBoolSocket', 'Auto Start')
if self.property0 == 'Is Unique':
self.add_input('LnxBoolSocket', 'Is Unique')
if self.property0 == 'Loop':
self.add_input('LnxBoolSocket', 'Loop')
if self.property0 == 'Velocity':
self.add_input('LnxVectorSocket', 'Velocity')
if self.property0 == 'Velocity Random':
self.add_input('LnxFloatSocket', 'Velocity Random')
if self.property0 == 'Weight Gravity':
self.add_input('LnxFloatSocket', 'Weight Gravity')
if self.property0 == 'Speed':
self.add_input('LnxFloatSocket', 'Speed')
property0: HaxeEnumProperty(
'property0',
items = [('Particle Size', 'Particle Size', 'for the system'),
('Frame Start', 'Frame Start', 'for the system'),
('Frame End', 'Frame End', 'for the system'),
('Lifetime', 'Lifetime', 'for the instance'),
('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'),
('Is Unique', 'Is Unique', 'for the system'),
('Loop', 'Loop', 'for the system'),
('Velocity', 'Velocity', 'for the instance'),
('Velocity Random', 'Velocity Random', 'for the system'),
('Weight Gravity', 'Weight Gravity', 'for the instance'),
('Speed', 'Speed', 'for the instance')],
name='', default='Speed', update=remove_extra_inputs)
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

@ -1,3 +0,0 @@
from lnx.logicnode.lnx_nodes import add_node_section
add_node_section(name='default', category='Particle')

View File

@ -1,11 +0,0 @@
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,20 +1,11 @@
from lnx.logicnode.lnx_nodes import *
class ChromaticAberrationGetNode(LnxLogicTreeNode):
"""Returns the chromatic aberration post-processing settings.
Type: Simple 0 Spectral 1.
"""
"""Returns the chromatic aberration post-processing settings."""
bl_idname = 'LNChromaticAberrationGetNode'
bl_label = 'Get CA Settings'
lnx_version = 2
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxFloatSocket', 'Strength')
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)

Some files were not shown because too many files have changed in this diff Show More