Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
316441b954 | |||
9bf83bc49f | |||
d88e1f0f42 | |||
96f4e29778 | |||
1d705d2ca2 | |||
0979cd976f | |||
db6d786ee4 | |||
106e36e30d | |||
2bb296028f | |||
25d7ba3e72 | |||
bf7b4416ec | |||
a2d03cfe6e | |||
95f0ecfc54 | |||
07f59224fc | |||
02259985be | |||
6b8585c81a | |||
5d78eabf94 | |||
41c1459c4e | |||
304a497565 | |||
9fa399371a | |||
4625fdb6b2 | |||
79553927aa | |||
86661c1012 | |||
03967c7a2b | |||
61fd48a12f | |||
519039b8b6 | |||
5244b1b3e8 | |||
7ae3bbe496 | |||
001be2f8da | |||
6a25b3c5d7 | |||
8d4ac7251a | |||
ae63b252c6 | |||
ee73823206 | |||
af2850e20c | |||
bc4a31d415 | |||
5303ad3ac6 | |||
5153cff790 | |||
abe17870ce |
@ -3,10 +3,6 @@
|
|||||||
|
|
||||||
#include "compiled.inc"
|
#include "compiled.inc"
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
|
||||||
uniform vec4 PPComp17;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
uniform vec2 dir;
|
uniform vec2 dir;
|
||||||
uniform vec2 screenSize;
|
uniform vec2 screenSize;
|
||||||
@ -49,12 +45,6 @@ void main() {
|
|||||||
res += factor * col;
|
res += factor * col;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
|
||||||
vec3 AirColor = vec3(PPComp17.x, PPComp17.y, PPComp17.z);
|
|
||||||
#else
|
|
||||||
vec3 AirColor = volumAirColor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
res /= sumfactor;
|
res /= sumfactor;
|
||||||
fragColor = vec4(AirColor * res, 1.0);
|
fragColor = vec4(volumAirColor * res, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,6 @@
|
|||||||
{
|
{
|
||||||
"name": "screenSize",
|
"name": "screenSize",
|
||||||
"link": "_screenSize"
|
"link": "_screenSize"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PPComp17",
|
|
||||||
"link": "_PPComp17",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"texture_params": [],
|
"texture_params": [],
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
#ifdef _CPostprocess
|
||||||
uniform vec4 PPComp13;
|
uniform vec3 PPComp13;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
in vec2 texCoord;
|
in vec2 texCoord;
|
||||||
@ -43,17 +43,13 @@ void main() {
|
|||||||
#ifdef _CPostprocess
|
#ifdef _CPostprocess
|
||||||
float max_distort = PPComp13.x;
|
float max_distort = PPComp13.x;
|
||||||
int num_iter = int(PPComp13.y);
|
int num_iter = int(PPComp13.y);
|
||||||
int CAType = int(PPComp13.z);
|
|
||||||
int on = int(PPComp13.w);
|
|
||||||
#else
|
#else
|
||||||
float max_distort = compoChromaticStrength;
|
float max_distort = compoChromaticStrength;
|
||||||
int num_iter = compoChromaticSamples;
|
int num_iter = compoChromaticSamples;
|
||||||
int CAType = compoChromaticType;
|
|
||||||
int on = 1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Spectral
|
// Spectral
|
||||||
if (CAType == 1) {
|
if (compoChromaticType == 1) {
|
||||||
float reci_num_iter_f = 1.0 / float(num_iter);
|
float reci_num_iter_f = 1.0 / float(num_iter);
|
||||||
|
|
||||||
vec2 resolution = vec2(1,1);
|
vec2 resolution = vec2(1,1);
|
||||||
@ -68,7 +64,7 @@ void main() {
|
|||||||
sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t));
|
sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (on == 1) fragColor = sumcol / sumw; else fragColor = texture(tex, texCoord);
|
fragColor = sumcol / sumw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple
|
// Simple
|
||||||
@ -77,7 +73,6 @@ void main() {
|
|||||||
col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x;
|
col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x;
|
||||||
col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y;
|
col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y;
|
||||||
col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z;
|
col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z;
|
||||||
if (on == 1) fragColor = vec4(col.x, col.y, col.z, fragColor.w);
|
fragColor = vec4(col.x, col.y, col.z, fragColor.w);
|
||||||
else fragColor = texture(tex, texCoord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,8 @@ uniform vec3 PPComp5;
|
|||||||
uniform vec3 PPComp6;
|
uniform vec3 PPComp6;
|
||||||
uniform vec3 PPComp7;
|
uniform vec3 PPComp7;
|
||||||
uniform vec3 PPComp8;
|
uniform vec3 PPComp8;
|
||||||
uniform vec3 PPComp11;
|
|
||||||
uniform vec3 PPComp14;
|
uniform vec3 PPComp14;
|
||||||
uniform vec4 PPComp15;
|
uniform vec4 PPComp15;
|
||||||
uniform vec4 PPComp16;
|
|
||||||
uniform vec4 PPComp18;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #ifdef _CPos
|
// #ifdef _CPos
|
||||||
@ -109,16 +106,6 @@ in vec2 texCoord;
|
|||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
#ifdef _CFog
|
#ifdef _CFog
|
||||||
#ifdef _CPostprocess
|
|
||||||
vec3 FogColor = vec3(PPComp18.x, PPComp18.y, PPComp18.z);
|
|
||||||
float FogAmountA = PPComp18.w;
|
|
||||||
float FogAmountB = PPComp11.z;
|
|
||||||
#else
|
|
||||||
vec3 FogColor = compoFogColor;
|
|
||||||
float FogAmountA = compoFogAmountA;
|
|
||||||
float FogAmountB = compoFogAmountB;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
|
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
|
||||||
// const float compoFogAmountA = 1.0; // b = 0.01
|
// const float compoFogAmountA = 1.0; // b = 0.01
|
||||||
// const float compoFogAmountB = 1.0; // c = 0.1
|
// const float compoFogAmountB = 1.0; // c = 0.1
|
||||||
@ -131,8 +118,8 @@ out vec4 fragColor;
|
|||||||
// }
|
// }
|
||||||
vec3 applyFog(vec3 rgb, float distance) {
|
vec3 applyFog(vec3 rgb, float distance) {
|
||||||
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
|
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
|
||||||
float fogAmount = 1.0 - exp(-distance * (FogAmountA / 100));
|
float fogAmount = 1.0 - exp(-distance * (compoFogAmountA / 100));
|
||||||
return mix(rgb, FogColor, fogAmount);
|
return mix(rgb, compoFogColor, fogAmount);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -144,7 +131,7 @@ float ConvertEV100ToExposure(float EV100) {
|
|||||||
return 1/0.8 * exp2(-EV100);
|
return 1/0.8 * exp2(-EV100);
|
||||||
}
|
}
|
||||||
float ComputeEV(float avgLuminance) {
|
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 shutterTime = 1.0 / PPComp1.y;
|
||||||
const float ISO = PPComp1.z;
|
const float ISO = PPComp1.z;
|
||||||
const float EC = PPComp2.x;
|
const float EC = PPComp2.x;
|
||||||
@ -362,22 +349,16 @@ void main() {
|
|||||||
|
|
||||||
#ifdef _CSharpen
|
#ifdef _CSharpen
|
||||||
#ifdef _CPostprocess
|
#ifdef _CPostprocess
|
||||||
float strengthSharpen = PPComp14.y;
|
float strengthSharpen = PPComp14.y;
|
||||||
vec3 SharpenColor = vec3(PPComp16.x, PPComp16.y, PPComp16.z);
|
|
||||||
float SharpenSize = PPComp16.w;
|
|
||||||
#else
|
#else
|
||||||
float strengthSharpen = compoSharpenStrength;
|
float strengthSharpen = compoSharpenStrength;
|
||||||
vec3 SharpenColor = compoSharpenColor;
|
|
||||||
float SharpenSize = compoSharpenSize;
|
|
||||||
#endif
|
#endif
|
||||||
vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * 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) * SharpenSize, 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) * SharpenSize, 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) * SharpenSize, 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;
|
vec3 colavg = (col1 + col2 + col3 + col4) * 0.25;
|
||||||
|
fragColor.rgb += (fragColor.rgb - colavg) * strengthSharpen;
|
||||||
float edgeMagnitude = length(fragColor.rgb - colavg);
|
|
||||||
fragColor.rgb = mix(fragColor.rgb, SharpenColor, min(edgeMagnitude * strengthSharpen * 2.0, 1.0));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _CFog
|
#ifdef _CFog
|
||||||
@ -426,11 +407,7 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _CExposure
|
#ifdef _CExposure
|
||||||
#ifdef _CPostprocess
|
fragColor.rgb += fragColor.rgb * compoExposureStrength;
|
||||||
fragColor.rgb+=fragColor.rgb*PPComp8.x;
|
|
||||||
#else
|
|
||||||
fragColor.rgb+= fragColor.rgb*compoExposureStrength;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
#ifdef _CPostprocess
|
||||||
@ -438,13 +415,8 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _AutoExposure
|
#ifdef _AutoExposure
|
||||||
#ifdef _CPostprocess
|
|
||||||
float AEStrength = PPComp8.y;
|
|
||||||
#else
|
|
||||||
float AEStrength = autoExposureStrength;
|
|
||||||
#endif
|
|
||||||
float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0);
|
float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0);
|
||||||
fragColor.rgb *= pow(expo, AEStrength * 2.0);
|
fragColor.rgb *= pow(expo, autoExposureStrength * 2.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Clamp color to get rid of INF values that don't work for the tone mapping below
|
// Clamp color to get rid of INF values that don't work for the tone mapping below
|
||||||
@ -508,7 +480,9 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
|
|||||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
||||||
} else if (PPComp4.x == 10){
|
} else if (PPComp4.x == 10){
|
||||||
fragColor.rgb = tonemapAgXFull(fragColor.rgb);
|
fragColor.rgb = tonemapAgXFull(fragColor.rgb);
|
||||||
} //else { fragColor.rgb = vec3(0,1,0); //ERROR}
|
} else {
|
||||||
|
fragColor.rgb = vec3(0,1,0); //ERROR
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -235,16 +235,6 @@
|
|||||||
"name": "PPComp15",
|
"name": "PPComp15",
|
||||||
"link": "_PPComp15",
|
"link": "_PPComp15",
|
||||||
"ifdef": ["_CPostprocess"]
|
"ifdef": ["_CPostprocess"]
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PPComp16",
|
|
||||||
"link": "_PPComp16",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PPComp18",
|
|
||||||
"link": "_PPComp18",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"texture_params": [],
|
"texture_params": [],
|
||||||
|
@ -20,7 +20,7 @@ uniform sampler2D gbuffer0;
|
|||||||
uniform sampler2D gbuffer1;
|
uniform sampler2D gbuffer1;
|
||||||
|
|
||||||
#ifdef _gbuffer2
|
#ifdef _gbuffer2
|
||||||
uniform sampler2D gbuffer2;
|
//!uniform sampler2D gbuffer2;
|
||||||
#endif
|
#endif
|
||||||
#ifdef _EmissionShaded
|
#ifdef _EmissionShaded
|
||||||
uniform sampler2D gbufferEmission;
|
uniform sampler2D gbufferEmission;
|
||||||
@ -286,7 +286,7 @@ void main() {
|
|||||||
|
|
||||||
#ifdef _VoxelGI
|
#ifdef _VoxelGI
|
||||||
vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
|
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)
|
if(roughness < 1.0 && occspec.y > 0.0)
|
||||||
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
|
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
|
||||||
#endif
|
#endif
|
||||||
@ -380,7 +380,7 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _VoxelShadow
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef _SSRS
|
#ifdef _SSRS
|
||||||
|
@ -2,22 +2,13 @@
|
|||||||
|
|
||||||
#include "compiled.inc"
|
#include "compiled.inc"
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
|
||||||
uniform vec3 PPComp8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
|
||||||
in vec2 texCoord;
|
in vec2 texCoord;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
#ifdef _CPostprocess
|
fragColor.a = 0.01 * autoExposureSpeed;
|
||||||
fragColor.a = 0.01 * PPComp8.z;
|
|
||||||
#else
|
|
||||||
fragColor.a = 0.01 * autoExposureSpeed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fragColor.rgb = textureLod(tex, vec2(0.5, 0.5), 0.0).rgb +
|
fragColor.rgb = textureLod(tex, vec2(0.5, 0.5), 0.0).rgb +
|
||||||
textureLod(tex, vec2(0.2, 0.2), 0.0).rgb +
|
textureLod(tex, vec2(0.2, 0.2), 0.0).rgb +
|
||||||
textureLod(tex, vec2(0.8, 0.2), 0.0).rgb +
|
textureLod(tex, vec2(0.8, 0.2), 0.0).rgb +
|
||||||
|
@ -8,13 +8,7 @@
|
|||||||
"blend_source": "source_alpha",
|
"blend_source": "source_alpha",
|
||||||
"blend_destination": "inverse_source_alpha",
|
"blend_destination": "inverse_source_alpha",
|
||||||
"blend_operation": "add",
|
"blend_operation": "add",
|
||||||
"links": [
|
"links": [],
|
||||||
{
|
|
||||||
"name": "PPComp8",
|
|
||||||
"link": "_PPComp8",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"texture_params": [],
|
"texture_params": [],
|
||||||
"vertex_shader": "../include/pass.vert.glsl",
|
"vertex_shader": "../include/pass.vert.glsl",
|
||||||
"fragment_shader": "histogram_pass.frag.glsl"
|
"fragment_shader": "histogram_pass.frag.glsl"
|
||||||
|
@ -92,7 +92,7 @@ void main() {
|
|||||||
|
|
||||||
vec3 viewNormal = V3 * n;
|
vec3 viewNormal = V3 * n;
|
||||||
vec3 viewPos = getPosView(viewRay, d, cameraProj);
|
vec3 viewPos = getPosView(viewRay, d, cameraProj);
|
||||||
vec3 reflected = reflect(viewPos, viewNormal);
|
vec3 reflected = reflect(normalize(viewPos), viewNormal);
|
||||||
hitCoord = viewPos;
|
hitCoord = viewPos;
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
#ifdef _CPostprocess
|
||||||
|
@ -57,14 +57,17 @@ vec4 binarySearch(vec3 dir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec4 rayCast(vec3 dir) {
|
vec4 rayCast(vec3 dir) {
|
||||||
float ddepth;
|
float ddepth;
|
||||||
dir *= ss_refractionRayStep;
|
dir *= ss_refractionRayStep;
|
||||||
for (int i = 0; i < maxSteps; i++) {
|
for (int i = 0; i < maxSteps; i++) {
|
||||||
hitCoord += dir;
|
hitCoord += dir;
|
||||||
ddepth = getDeltaDepth(hitCoord);
|
ddepth = getDeltaDepth(hitCoord);
|
||||||
if (ddepth > 0.0) return binarySearch(dir);
|
if (ddepth > 0.0)
|
||||||
}
|
return binarySearch(dir);
|
||||||
return vec4(texCoord, 0.0, 1.0);
|
}
|
||||||
|
// 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() {
|
void main() {
|
||||||
@ -74,7 +77,7 @@ void main() {
|
|||||||
float ior = gr.x;
|
float ior = gr.x;
|
||||||
float opac = gr.y;
|
float opac = gr.y;
|
||||||
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
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;
|
fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
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;
|
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);
|
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;
|
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) {
|
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;
|
const float transmittance = 1.0 - opacity;
|
||||||
vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior);
|
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;
|
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);
|
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) {
|
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) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep;
|
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);
|
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
|
||||||
amount = clamp(amount, 0.0, 1.0);
|
amount = clamp(amount, 0.0, 1.0);
|
||||||
return amount * voxelgiOcc;
|
return amount * voxelgiOcc;
|
||||||
|
@ -1,239 +1,242 @@
|
|||||||
#ifndef _LIGHT_GLSL_
|
#ifndef _LIGHT_GLSL_
|
||||||
#define _LIGHT_GLSL_
|
#define _LIGHT_GLSL_
|
||||||
|
|
||||||
#include "compiled.inc"
|
#include "compiled.inc"
|
||||||
#include "std/brdf.glsl"
|
#include "std/brdf.glsl"
|
||||||
#include "std/math.glsl"
|
#include "std/math.glsl"
|
||||||
#ifdef _ShadowMap
|
#ifdef _ShadowMap
|
||||||
#include "std/shadows.glsl"
|
#include "std/shadows.glsl"
|
||||||
#endif
|
#endif
|
||||||
#ifdef _VoxelShadow
|
#ifdef _VoxelShadow
|
||||||
#include "std/conetrace.glsl"
|
#include "std/conetrace.glsl"
|
||||||
//!uniform sampler2D voxels_shadows;
|
#endif
|
||||||
#endif
|
#ifdef _gbuffer2
|
||||||
#ifdef _LTC
|
uniform sampler2D gbuffer2;
|
||||||
#include "std/ltc.glsl"
|
#endif
|
||||||
#endif
|
#ifdef _LTC
|
||||||
#ifdef _LightIES
|
#include "std/ltc.glsl"
|
||||||
#include "std/ies.glsl"
|
#endif
|
||||||
#endif
|
#ifdef _LightIES
|
||||||
#ifdef _SSRS
|
#include "std/ies.glsl"
|
||||||
#include "std/ssrs.glsl"
|
#endif
|
||||||
#endif
|
#ifdef _SSRS
|
||||||
#ifdef _Spot
|
#include "std/ssrs.glsl"
|
||||||
#include "std/light_common.glsl"
|
#endif
|
||||||
#endif
|
#ifdef _Spot
|
||||||
|
#include "std/light_common.glsl"
|
||||||
#ifdef _ShadowMap
|
#endif
|
||||||
#ifdef _SinglePoint
|
|
||||||
#ifdef _Spot
|
#ifdef _ShadowMap
|
||||||
#ifndef _LTC
|
#ifdef _SinglePoint
|
||||||
uniform sampler2DShadow shadowMapSpot[1];
|
#ifdef _Spot
|
||||||
uniform sampler2D shadowMapSpotTransparent[1];
|
#ifndef _LTC
|
||||||
uniform mat4 LWVPSpot[1];
|
uniform sampler2DShadow shadowMapSpot[1];
|
||||||
#endif
|
uniform sampler2D shadowMapSpotTransparent[1];
|
||||||
#else
|
uniform mat4 LWVPSpot[1];
|
||||||
uniform samplerCubeShadow shadowMapPoint[1];
|
#endif
|
||||||
uniform samplerCube shadowMapPointTransparent[1];
|
#else
|
||||||
uniform vec2 lightProj;
|
uniform samplerCubeShadow shadowMapPoint[1];
|
||||||
#endif
|
uniform samplerCube shadowMapPointTransparent[1];
|
||||||
#endif
|
uniform vec2 lightProj;
|
||||||
#ifdef _Clusters
|
#endif
|
||||||
#ifdef _SingleAtlas
|
#endif
|
||||||
//!uniform sampler2DShadow shadowMapAtlas;
|
#ifdef _Clusters
|
||||||
//!uniform sampler2D shadowMapAtlasTransparent;
|
#ifdef _SingleAtlas
|
||||||
#endif
|
//!uniform sampler2DShadow shadowMapAtlas;
|
||||||
uniform vec2 lightProj;
|
//!uniform sampler2D shadowMapAtlasTransparent;
|
||||||
#ifdef _ShadowMapAtlas
|
#endif
|
||||||
#ifndef _SingleAtlas
|
uniform vec2 lightProj;
|
||||||
uniform sampler2DShadow shadowMapAtlasPoint;
|
#ifdef _ShadowMapAtlas
|
||||||
uniform sampler2D shadowMapAtlasPointTransparent;
|
#ifndef _SingleAtlas
|
||||||
#endif
|
uniform sampler2DShadow shadowMapAtlasPoint;
|
||||||
#else
|
uniform sampler2D shadowMapAtlasPointTransparent;
|
||||||
uniform samplerCubeShadow shadowMapPoint[4];
|
#endif
|
||||||
uniform samplerCube shadowMapPointTransparent[4];
|
#else
|
||||||
#endif
|
uniform samplerCubeShadow shadowMapPoint[4];
|
||||||
#ifdef _Spot
|
uniform samplerCube shadowMapPointTransparent[4];
|
||||||
#ifdef _ShadowMapAtlas
|
#endif
|
||||||
#ifndef _SingleAtlas
|
#ifdef _Spot
|
||||||
uniform sampler2DShadow shadowMapAtlasSpot;
|
#ifdef _ShadowMapAtlas
|
||||||
uniform sampler2D shadowMapAtlasSpotTransparent;
|
#ifndef _SingleAtlas
|
||||||
#endif
|
uniform sampler2DShadow shadowMapAtlasSpot;
|
||||||
#else
|
uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||||
uniform sampler2DShadow shadowMapSpot[4];
|
#endif
|
||||||
uniform sampler2D shadowMapSpotTransparent[4];
|
#else
|
||||||
#endif
|
uniform sampler2DShadow shadowMapSpot[4];
|
||||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
uniform sampler2D shadowMapSpotTransparent[4];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef _LTC
|
#endif
|
||||||
uniform vec3 lightArea0;
|
|
||||||
uniform vec3 lightArea1;
|
#ifdef _LTC
|
||||||
uniform vec3 lightArea2;
|
uniform vec3 lightArea0;
|
||||||
uniform vec3 lightArea3;
|
uniform vec3 lightArea1;
|
||||||
uniform sampler2D sltcMat;
|
uniform vec3 lightArea2;
|
||||||
uniform sampler2D sltcMag;
|
uniform vec3 lightArea3;
|
||||||
#ifdef _ShadowMap
|
uniform sampler2D sltcMat;
|
||||||
#ifndef _Spot
|
uniform sampler2D sltcMag;
|
||||||
#ifdef _SinglePoint
|
#ifdef _ShadowMap
|
||||||
uniform sampler2DShadow shadowMapSpot[1];
|
#ifndef _Spot
|
||||||
uniform sampler2D shadowMapSpotTransparent[1];
|
#ifdef _SinglePoint
|
||||||
uniform mat4 LWVPSpot[1];
|
uniform sampler2DShadow shadowMapSpot[1];
|
||||||
#endif
|
uniform sampler2D shadowMapSpotTransparent[1];
|
||||||
#ifdef _Clusters
|
uniform mat4 LWVPSpot[1];
|
||||||
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
|
#endif
|
||||||
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
|
#ifdef _Clusters
|
||||||
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
|
||||||
#endif
|
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
|
||||||
#endif
|
uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
#endif
|
||||||
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
|
||||||
#ifdef _ShadowMap
|
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
||||||
, int index, float bias, bool receiveShadow, bool transparent
|
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
||||||
#endif
|
#ifdef _ShadowMap
|
||||||
#ifdef _Spot
|
, int index, float bias, bool receiveShadow, bool transparent
|
||||||
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
#endif
|
||||||
#endif
|
#ifdef _Spot
|
||||||
#ifdef _VoxelShadow
|
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
|
||||||
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
|
#endif
|
||||||
#endif
|
#ifdef _VoxelShadow
|
||||||
#ifdef _MicroShadowing
|
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
|
||||||
, float occ
|
#endif
|
||||||
#endif
|
#ifdef _MicroShadowing
|
||||||
#ifdef _SSRS
|
, float occ
|
||||||
, sampler2D gbufferD, mat4 invVP, vec3 eye
|
#endif
|
||||||
#endif
|
#ifdef _SSRS
|
||||||
) {
|
, sampler2D gbufferD, mat4 invVP, vec3 eye
|
||||||
vec3 ld = lp - p;
|
#endif
|
||||||
vec3 l = normalize(ld);
|
) {
|
||||||
vec3 h = normalize(v + l);
|
vec3 ld = lp - p;
|
||||||
float dotNH = max(0.0, dot(n, h));
|
vec3 l = normalize(ld);
|
||||||
float dotVH = max(0.0, dot(v, h));
|
vec3 h = normalize(v + l);
|
||||||
float dotNL = max(0.0, dot(n, l));
|
float dotNH = max(0.0, dot(n, h));
|
||||||
|
float dotVH = max(0.0, dot(v, h));
|
||||||
#ifdef _LTC
|
float dotNL = max(0.0, dot(n, l));
|
||||||
float theta = acos(dotNV);
|
|
||||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
#ifdef _LTC
|
||||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
float theta = acos(dotNV);
|
||||||
vec4 t = textureLod(sltcMat, tuv, 0.0);
|
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||||
mat3 invM = mat3(
|
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||||
vec3(1.0, 0.0, t.y),
|
vec4 t = textureLod(sltcMat, tuv, 0.0);
|
||||||
vec3(0.0, t.z, 0.0),
|
mat3 invM = mat3(
|
||||||
vec3(t.w, 0.0, t.x));
|
vec3(1.0, 0.0, t.y),
|
||||||
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
|
vec3(0.0, t.z, 0.0),
|
||||||
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
|
vec3(t.w, 0.0, t.x));
|
||||||
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
|
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
|
||||||
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
|
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
|
||||||
#else
|
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
|
||||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
|
||||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
#else
|
||||||
#endif
|
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||||
|
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||||
direct *= attenuate(distance(p, lp));
|
#endif
|
||||||
direct *= lightCol;
|
|
||||||
|
direct *= attenuate(distance(p, lp));
|
||||||
#ifdef _MicroShadowing
|
direct *= lightCol;
|
||||||
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
|
|
||||||
#endif
|
#ifdef _MicroShadowing
|
||||||
|
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
|
||||||
#ifdef _SSRS
|
#endif
|
||||||
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
|
|
||||||
#endif
|
#ifdef _SSRS
|
||||||
|
direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
|
||||||
#ifdef _VoxelShadow
|
#endif
|
||||||
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
|
|
||||||
#endif
|
#ifdef _VoxelShadow
|
||||||
|
vec4 g2 = textureLod(gbuffer2, gl_FragCoord.xy, 0.0);
|
||||||
#ifdef _LTC
|
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy, g2.rg).r) * voxelgiShad;
|
||||||
#ifdef _ShadowMap
|
#endif
|
||||||
if (receiveShadow) {
|
|
||||||
#ifdef _SinglePoint
|
#ifdef _LTC
|
||||||
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
#ifdef _ShadowMap
|
||||||
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
if (receiveShadow) {
|
||||||
#endif
|
#ifdef _SinglePoint
|
||||||
#ifdef _Clusters
|
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
|
||||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
#endif
|
||||||
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
|
#ifdef _Clusters
|
||||||
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
|
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
|
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||||
#endif
|
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);
|
||||||
#endif
|
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
|
||||||
return direct;
|
#endif
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#ifdef _Spot
|
return direct;
|
||||||
if (isSpot) {
|
#endif
|
||||||
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
|
||||||
|
#ifdef _Spot
|
||||||
#ifdef _ShadowMap
|
if (isSpot) {
|
||||||
if (receiveShadow) {
|
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
|
||||||
#ifdef _SinglePoint
|
|
||||||
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
#ifdef _ShadowMap
|
||||||
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
if (receiveShadow) {
|
||||||
#endif
|
#ifdef _SinglePoint
|
||||||
#ifdef _Clusters
|
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
|
||||||
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||||
#ifdef _ShadowMapAtlas
|
#endif
|
||||||
direct *= shadowTest(
|
#ifdef _Clusters
|
||||||
#ifndef _SingleAtlas
|
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
|
||||||
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
#ifdef _ShadowMapAtlas
|
||||||
#else
|
direct *= shadowTest(
|
||||||
shadowMapAtlas, shadowMapAtlasTransparent
|
#ifndef _SingleAtlas
|
||||||
#endif
|
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
|
||||||
, lPos.xyz / lPos.w, bias, transparent
|
#else
|
||||||
);
|
shadowMapAtlas, shadowMapAtlasTransparent
|
||||||
#else
|
#endif
|
||||||
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
, 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
|
||||||
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
|
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
|
||||||
#endif
|
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
|
||||||
#endif
|
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
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return direct;
|
||||||
#ifdef _LightIES
|
}
|
||||||
direct *= iesAttenuation(-l);
|
#endif
|
||||||
#endif
|
|
||||||
|
#ifdef _LightIES
|
||||||
#ifdef _ShadowMap
|
direct *= iesAttenuation(-l);
|
||||||
if (receiveShadow) {
|
#endif
|
||||||
#ifdef _SinglePoint
|
|
||||||
#ifndef _Spot
|
#ifdef _ShadowMap
|
||||||
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
if (receiveShadow) {
|
||||||
#endif
|
#ifdef _SinglePoint
|
||||||
#endif
|
#ifndef _Spot
|
||||||
#ifdef _Clusters
|
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
||||||
#ifdef _ShadowMapAtlas
|
#endif
|
||||||
direct *= PCFFakeCube(
|
#endif
|
||||||
#ifndef _SingleAtlas
|
#ifdef _Clusters
|
||||||
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
#ifdef _ShadowMapAtlas
|
||||||
#else
|
direct *= PCFFakeCube(
|
||||||
shadowMapAtlas, shadowMapAtlasTransparent
|
#ifndef _SingleAtlas
|
||||||
#endif
|
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
|
||||||
, ld, -l, bias, lightProj, n, index, transparent
|
#else
|
||||||
);
|
shadowMapAtlas, shadowMapAtlasTransparent
|
||||||
#else
|
#endif
|
||||||
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
, ld, -l, bias, lightProj, n, index, 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
|
||||||
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
|
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
|
||||||
#endif
|
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
|
||||||
#endif
|
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
|
||||||
|
|
||||||
#endif
|
return direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -87,40 +87,6 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
|
|||||||
return zcomp * 0.5 + 0.5;
|
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) {
|
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...
|
const float s = shadowmapCubePcfSize; // TODO: incorrect...
|
||||||
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
||||||
@ -149,7 +115,7 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTranspare
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _ShadowMapAtlas
|
||||||
// transform "out-of-bounds" coordinates to the correct face/coordinate system
|
// transform "out-of-bounds" coordinates to the correct face/coordinate system
|
||||||
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
|
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
|
||||||
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
|
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
|
||||||
|
@ -11,8 +11,6 @@ vec3 uncharted2Tonemap(const vec3 x) {
|
|||||||
vec3 tonemapUncharted2(const vec3 color) {
|
vec3 tonemapUncharted2(const vec3 color) {
|
||||||
const float W = 11.2;
|
const float W = 11.2;
|
||||||
const float exposureBias = 2.0;
|
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 curr = uncharted2Tonemap(exposureBias * color);
|
||||||
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||||
return curr * whiteScale;
|
return curr * whiteScale;
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
#include "std/light_common.glsl"
|
#include "std/light_common.glsl"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _CPostprocess
|
|
||||||
uniform vec3 PPComp11;
|
|
||||||
uniform vec4 PPComp17;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform sampler2D gbufferD;
|
uniform sampler2D gbufferD;
|
||||||
uniform sampler2D snoise;
|
uniform sampler2D snoise;
|
||||||
|
|
||||||
@ -92,13 +87,7 @@ out float fragColor;
|
|||||||
const float tScat = 0.08;
|
const float tScat = 0.08;
|
||||||
const float tAbs = 0.0;
|
const float tAbs = 0.0;
|
||||||
const float tExt = tScat + tAbs;
|
const float tExt = tScat + tAbs;
|
||||||
#ifdef _CPostprocess
|
const float stepLen = 1.0 / volumSteps;
|
||||||
float stepLen = 1.0 / int(PPComp11.y);
|
|
||||||
float AirTurbidity = PPComp17.w;
|
|
||||||
#else
|
|
||||||
const float stepLen = 1.0 / volumSteps;
|
|
||||||
float AirTurbidity = volumAirTurbidity;
|
|
||||||
#endif
|
|
||||||
const float lighting = 0.4;
|
const float lighting = 0.4;
|
||||||
|
|
||||||
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
|
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
|
||||||
@ -173,5 +162,5 @@ void main() {
|
|||||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||||
}
|
}
|
||||||
|
|
||||||
fragColor = scatteredLightAmount * AirTurbidity;
|
fragColor = scatteredLightAmount * volumAirTurbidity;
|
||||||
}
|
}
|
||||||
|
@ -140,16 +140,6 @@
|
|||||||
"link": "_biasLightWorldViewProjectionMatrixSpot3",
|
"link": "_biasLightWorldViewProjectionMatrixSpot3",
|
||||||
"ifndef": ["_ShadowMapAtlas"],
|
"ifndef": ["_ShadowMapAtlas"],
|
||||||
"ifdef": ["_Spot", "_ShadowMap"]
|
"ifdef": ["_Spot", "_ShadowMap"]
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PPComp11",
|
|
||||||
"link": "_PPComp11",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PPComp17",
|
|
||||||
"link": "_PPComp17",
|
|
||||||
"ifdef": ["_CPostprocess"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"texture_params": [],
|
"texture_params": [],
|
||||||
|
@ -33,6 +33,7 @@ uniform layout(r32ui) uimage3D voxelsLight;
|
|||||||
|
|
||||||
#ifdef _ShadowMap
|
#ifdef _ShadowMap
|
||||||
uniform sampler2DShadow shadowMap;
|
uniform sampler2DShadow shadowMap;
|
||||||
|
uniform sampler2D shadowMapTransparent;
|
||||||
uniform sampler2DShadow shadowMapSpot;
|
uniform sampler2DShadow shadowMapSpot;
|
||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
uniform sampler2DShadow shadowMapPoint;
|
uniform sampler2DShadow shadowMapPoint;
|
||||||
@ -86,53 +87,51 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
int res = voxelgiResolution.x;
|
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);
|
float visibility;
|
||||||
dst.y += clipmapLevel * res;
|
vec3 lp = lightPos - P;
|
||||||
|
vec3 l;
|
||||||
vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
|
if (lightType == 0) { l = lightDir; visibility = 1.0; }
|
||||||
P = P * 2.0 - 1.0;
|
else { l = normalize(lp); visibility = attenuate(distance(P, lightPos)); }
|
||||||
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))); }
|
|
||||||
|
|
||||||
#ifdef _ShadowMap
|
#ifdef _ShadowMap
|
||||||
if (lightShadow == 1) {
|
if (lightShadow == 1) {
|
||||||
vec4 lightPosition = LVP * vec4(P, 1.0);
|
vec4 lightPosition = LVP * vec4(P, 1.0);
|
||||||
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
||||||
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr;
|
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
|
||||||
}
|
}
|
||||||
else if (lightShadow == 2) {
|
else if (lightShadow == 2) {
|
||||||
vec4 lightPosition = LVP * vec4(P, 1.0);
|
vec4 lightPosition = LVP * vec4(P, 1.0);
|
||||||
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
vec3 lPos = lightPosition.xyz / lightPosition.w;
|
||||||
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
|
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
|
||||||
}
|
}
|
||||||
else if (lightShadow == 3) {
|
else if (lightShadow == 3) {
|
||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
int faceIndex = 0;
|
int faceIndex = 0;
|
||||||
const int lightIndex = index * 6;
|
const int lightIndex = index * 6;
|
||||||
const vec2 uv = sampleCube(-l, faceIndex);
|
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
|
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;
|
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
|
||||||
#ifdef _FlipY
|
#ifdef _FlipY
|
||||||
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
|
||||||
#endif
|
#endif
|
||||||
visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
|
visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
|
||||||
#else
|
#else
|
||||||
visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
|
visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#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;
|
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));
|
||||||
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, 0), uint(light.r * 255));
|
imageAtomicMax(voxelsLight, ivec3(writecoords_light) + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 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));
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|||||||
uniform sampler3D voxels;
|
uniform sampler3D voxels;
|
||||||
uniform sampler2D gbufferD;
|
uniform sampler2D gbufferD;
|
||||||
uniform sampler2D gbuffer0;
|
uniform sampler2D gbuffer0;
|
||||||
uniform layout(r8) image2D voxels_ao;
|
uniform layout(r16) image2D voxels_ao;
|
||||||
|
|
||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||||
uniform mat4 InvVP;
|
uniform mat4 InvVP;
|
||||||
|
@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|||||||
uniform sampler3D voxels;
|
uniform sampler3D voxels;
|
||||||
uniform sampler2D gbufferD;
|
uniform sampler2D gbufferD;
|
||||||
uniform sampler2D gbuffer0;
|
uniform sampler2D gbuffer0;
|
||||||
uniform layout(rgba8) image2D voxels_diffuse;
|
uniform layout(rgba16) image2D voxels_diffuse;
|
||||||
|
|
||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||||
uniform mat4 InvVP;
|
uniform mat4 InvVP;
|
||||||
@ -46,7 +46,7 @@ void main() {
|
|||||||
const vec2 pixel = gl_GlobalInvocationID.xy;
|
const vec2 pixel = gl_GlobalInvocationID.xy;
|
||||||
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
vec2 uv = (pixel + 0.5) / postprocess_resolution;
|
||||||
#ifdef _InvY
|
#ifdef _InvY
|
||||||
uv.y = 1.0 - uv.y
|
uv.y = 1.0 - uv.y;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
|
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
|
||||||
|
@ -34,7 +34,7 @@ uniform sampler2D gbufferD;
|
|||||||
uniform sampler2D gbuffer0;
|
uniform sampler2D gbuffer0;
|
||||||
uniform sampler3D voxels;
|
uniform sampler3D voxels;
|
||||||
uniform sampler3D voxelsSDF;
|
uniform sampler3D voxelsSDF;
|
||||||
uniform layout(rgba8) image2D voxels_specular;
|
uniform layout(rgba16) image2D voxels_specular;
|
||||||
|
|
||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
|
uniform float clipmaps[voxelgiClipmapCount * 10];
|
||||||
uniform mat4 InvVP;
|
uniform mat4 InvVP;
|
||||||
@ -71,7 +71,7 @@ void main() {
|
|||||||
|
|
||||||
vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
|
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));
|
imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
#include "compiled.inc"
|
#include "compiled.inc"
|
||||||
|
|
||||||
uniform layout(r16) image3D input_sdf;
|
uniform layout(r8) image3D input_sdf;
|
||||||
uniform layout(r16) image3D output_sdf;
|
uniform layout(r8) image3D output_sdf;
|
||||||
|
|
||||||
uniform float jump_size;
|
uniform float jump_size;
|
||||||
uniform int clipmapLevel;
|
uniform int clipmapLevel;
|
||||||
|
@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
|
|||||||
uniform layout(r32ui) uimage3D voxelsLight;
|
uniform layout(r32ui) uimage3D voxelsLight;
|
||||||
uniform layout(rgba8) image3D voxelsB;
|
uniform layout(rgba8) image3D voxelsB;
|
||||||
uniform layout(rgba8) image3D voxelsOut;
|
uniform layout(rgba8) image3D voxelsOut;
|
||||||
uniform layout(r16) image3D SDF;
|
uniform layout(r8) image3D SDF;
|
||||||
#else
|
#else
|
||||||
#ifdef _VoxelAOvar
|
#ifdef _VoxelAOvar
|
||||||
#ifdef _VoxelShadow
|
#ifdef _VoxelShadow
|
||||||
uniform layout(r16) image3D SDF;
|
uniform layout(r8) image3D SDF;
|
||||||
#endif
|
#endif
|
||||||
uniform layout(r32ui) uimage3D voxels;
|
uniform layout(r32ui) uimage3D voxels;
|
||||||
uniform layout(r16) image3D voxelsB;
|
uniform layout(r8) image3D voxelsB;
|
||||||
uniform layout(r16) image3D voxelsOut;
|
uniform layout(r8) image3D voxelsOut;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -80,7 +80,6 @@ void main() {
|
|||||||
light.r = float(imageLoad(voxelsLight, src)) / 255;
|
light.r = float(imageLoad(voxelsLight, src)) / 255;
|
||||||
light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 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.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
|
||||||
light /= 3;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
|
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.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.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
|
||||||
envl /= 3;
|
envl /= 3;
|
||||||
envl *= 100;
|
|
||||||
|
|
||||||
//clipmap to world
|
//clipmap to world
|
||||||
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
|
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
|
||||||
@ -137,7 +136,7 @@ void main() {
|
|||||||
radiance = basecol;
|
radiance = basecol;
|
||||||
vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
|
vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
|
||||||
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
|
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
|
||||||
radiance.rgb *= light + indirect;
|
radiance.rgb *= light / PI + indirect;
|
||||||
radiance.rgb += emission.rgb;
|
radiance.rgb += emission.rgb;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -75,16 +75,17 @@ vec4 binarySearch(vec3 dir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec4 rayCast(vec3 dir) {
|
vec4 rayCast(vec3 dir) {
|
||||||
#ifdef _CPostprocess
|
float ddepth;
|
||||||
dir *= PPComp9.x;
|
dir *= ss_refractionRayStep;
|
||||||
#else
|
for (int i = 0; i < maxSteps; i++) {
|
||||||
dir *= ssrRayStep;
|
hitCoord += dir;
|
||||||
#endif
|
ddepth = getDeltaDepth(hitCoord);
|
||||||
for (int i = 0; i < maxSteps; i++) {
|
if (ddepth > 0.0)
|
||||||
hitCoord += dir;
|
return binarySearch(dir);
|
||||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
}
|
||||||
}
|
// No hit — fallback to projecting the ray to UV space
|
||||||
return vec4(0.0);
|
vec2 fallbackUV = getProjectedCoord(hitCoord);
|
||||||
|
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
|
||||||
}
|
}
|
||||||
#endif //SSR
|
#endif //SSR
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ class App {
|
|||||||
static var traitInits: Array<Void->Void> = [];
|
static var traitInits: Array<Void->Void> = [];
|
||||||
static var traitUpdates: Array<Void->Void> = [];
|
static var traitUpdates: Array<Void->Void> = [];
|
||||||
static var traitLateUpdates: 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 traitRenders: Array<kha.graphics4.Graphics->Void> = [];
|
||||||
static var traitRenders2D: Array<kha.graphics2.Graphics->Void> = [];
|
static var traitRenders2D: Array<kha.graphics2.Graphics->Void> = [];
|
||||||
public static var framebuffer: kha.Framebuffer;
|
public static var framebuffer: kha.Framebuffer;
|
||||||
@ -24,8 +23,6 @@ class App {
|
|||||||
public static var renderPathTime: Float;
|
public static var renderPathTime: Float;
|
||||||
public static var endFrameCallbacks: Array<Void->Void> = [];
|
public static var endFrameCallbacks: Array<Void->Void> = [];
|
||||||
#end
|
#end
|
||||||
static var last = 0.0;
|
|
||||||
static var time = 0.0;
|
|
||||||
static var lastw = -1;
|
static var lastw = -1;
|
||||||
static var lasth = -1;
|
static var lasth = -1;
|
||||||
public static var onResize: Void->Void = null;
|
public static var onResize: Void->Void = null;
|
||||||
@ -37,14 +34,13 @@ class App {
|
|||||||
function new(done: Void->Void) {
|
function new(done: Void->Void) {
|
||||||
done();
|
done();
|
||||||
kha.System.notifyOnFrames(render);
|
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() {
|
public static function reset() {
|
||||||
traitInits = [];
|
traitInits = [];
|
||||||
traitUpdates = [];
|
traitUpdates = [];
|
||||||
traitLateUpdates = [];
|
traitLateUpdates = [];
|
||||||
traitFixedUpdates = [];
|
|
||||||
traitRenders = [];
|
traitRenders = [];
|
||||||
traitRenders2D = [];
|
traitRenders2D = [];
|
||||||
if (onResets != null) for (f in onResets) f();
|
if (onResets != null) for (f in onResets) f();
|
||||||
@ -52,8 +48,6 @@ class App {
|
|||||||
|
|
||||||
static function update() {
|
static function update() {
|
||||||
if (Scene.active == null || !Scene.active.ready) return;
|
if (Scene.active == null || !Scene.active.ready) return;
|
||||||
|
|
||||||
iron.system.Time.update();
|
|
||||||
if (pauseUpdates) return;
|
if (pauseUpdates) return;
|
||||||
|
|
||||||
#if lnx_debug
|
#if lnx_debug
|
||||||
@ -62,14 +56,6 @@ class App {
|
|||||||
|
|
||||||
Scene.active.updateFrame();
|
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 i = 0;
|
||||||
var l = traitUpdates.length;
|
var l = traitUpdates.length;
|
||||||
while (i < l) {
|
while (i < l) {
|
||||||
@ -120,7 +106,7 @@ class App {
|
|||||||
var frame = frames[0];
|
var frame = frames[0];
|
||||||
framebuffer = frame;
|
framebuffer = frame;
|
||||||
|
|
||||||
iron.system.Time.render();
|
iron.system.Time.update();
|
||||||
|
|
||||||
if (Scene.active == null || !Scene.active.ready) {
|
if (Scene.active == null || !Scene.active.ready) {
|
||||||
render2D(frame);
|
render2D(frame);
|
||||||
@ -186,14 +172,6 @@ class App {
|
|||||||
traitLateUpdates.remove(f);
|
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) {
|
public static function notifyOnRender(f: kha.graphics4.Graphics->Void) {
|
||||||
traitRenders.push(f);
|
traitRenders.push(f);
|
||||||
}
|
}
|
||||||
|
@ -775,7 +775,6 @@ class Scene {
|
|||||||
// Attach particle systems
|
// Attach particle systems
|
||||||
#if lnx_particles
|
#if lnx_particles
|
||||||
if (o.particle_refs != null) {
|
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);
|
for (ref in o.particle_refs) cast(object, MeshObject).setupParticleSystem(sceneName, ref);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@ -783,11 +782,6 @@ class Scene {
|
|||||||
if (o.tilesheet_ref != null) {
|
if (o.tilesheet_ref != null) {
|
||||||
cast(object, MeshObject).setupTilesheet(sceneName, o.tilesheet_ref, o.tilesheet_action_ref);
|
cast(object, MeshObject).setupTilesheet(sceneName, o.tilesheet_ref, o.tilesheet_action_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o.camera_list != null){
|
|
||||||
cast(object, MeshObject).cameraList = o.camera_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
returnObject(object, o, done);
|
returnObject(object, o, done);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ class Trait {
|
|||||||
var _remove: Array<Void->Void> = null;
|
var _remove: Array<Void->Void> = null;
|
||||||
var _update: Array<Void->Void> = null;
|
var _update: Array<Void->Void> = null;
|
||||||
var _lateUpdate: 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 _render: Array<kha.graphics4.Graphics->Void> = null;
|
||||||
var _render2D: Array<kha.graphics2.Graphics->Void> = null;
|
var _render2D: Array<kha.graphics2.Graphics->Void> = null;
|
||||||
|
|
||||||
@ -88,23 +87,6 @@ class Trait {
|
|||||||
App.removeLateUpdate(f);
|
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.
|
Add render handler.
|
||||||
**/
|
**/
|
||||||
|
@ -392,8 +392,6 @@ typedef TParticleData = {
|
|||||||
#end
|
#end
|
||||||
public var name: String;
|
public var name: String;
|
||||||
public var type: Int; // 0 - Emitter, Hair
|
public var type: Int; // 0 - Emitter, Hair
|
||||||
public var auto_start: Bool;
|
|
||||||
public var is_unique: Bool;
|
|
||||||
public var loop: Bool;
|
public var loop: Bool;
|
||||||
public var count: Int;
|
public var count: Int;
|
||||||
public var frame_start: FastFloat;
|
public var frame_start: FastFloat;
|
||||||
@ -441,7 +439,6 @@ typedef TObj = {
|
|||||||
@:optional public var traits: Array<TTrait>;
|
@:optional public var traits: Array<TTrait>;
|
||||||
@:optional public var properties: Array<TProperty>;
|
@:optional public var properties: Array<TProperty>;
|
||||||
@:optional public var vertex_groups: Array<TVertex_groups>;
|
@:optional public var vertex_groups: Array<TVertex_groups>;
|
||||||
@:optional public var camera_list: Array<String>;
|
|
||||||
@:optional public var constraints: Array<TConstraint>;
|
@:optional public var constraints: Array<TConstraint>;
|
||||||
@:optional public var dimensions: Float32Array; // Geometry objects
|
@:optional public var dimensions: Float32Array; // Geometry objects
|
||||||
@:optional public var object_actions: Array<String>;
|
@:optional public var object_actions: Array<String>;
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -159,17 +159,9 @@ class Animation {
|
|||||||
if(markerEvents.get(sampler) != null){
|
if(markerEvents.get(sampler) != null){
|
||||||
for (i in 0...anim.marker_frames.length) {
|
for (i in 0...anim.marker_frames.length) {
|
||||||
if (frameIndex == anim.marker_frames[i]) {
|
if (frameIndex == anim.marker_frames[i]) {
|
||||||
var markerAct = markerEvents.get(sampler);
|
var marketAct = markerEvents.get(sampler);
|
||||||
var ar = markerAct.get(anim.marker_names[i]);
|
var ar = marketAct.get(anim.marker_names[i]);
|
||||||
if (ar != null) for (f in ar) f();
|
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;
|
lastFrameIndex = frameIndex;
|
||||||
|
@ -21,10 +21,8 @@ class MeshObject extends Object {
|
|||||||
public var particleChildren: Array<MeshObject> = null;
|
public var particleChildren: Array<MeshObject> = null;
|
||||||
public var particleOwner: MeshObject = null; // Particle object
|
public var particleOwner: MeshObject = null; // Particle object
|
||||||
public var particleIndex = -1;
|
public var particleIndex = -1;
|
||||||
public var render_emitter = true;
|
|
||||||
#end
|
#end
|
||||||
public var cameraDistance: Float;
|
public var cameraDistance: Float;
|
||||||
public var cameraList: Array<String> = null;
|
|
||||||
public var screenSize = 0.0;
|
public var screenSize = 0.0;
|
||||||
public var frustumCulling = true;
|
public var frustumCulling = true;
|
||||||
public var activeTilesheet: Tilesheet = null;
|
public var activeTilesheet: Tilesheet = null;
|
||||||
@ -236,8 +234,6 @@ class MeshObject extends Object {
|
|||||||
if (cullMesh(context, Scene.active.camera, RenderPath.active.light)) return;
|
if (cullMesh(context, Scene.active.camera, RenderPath.active.light)) return;
|
||||||
var meshContext = raw != null ? context == "mesh" : false;
|
var meshContext = raw != null ? context == "mesh" : false;
|
||||||
|
|
||||||
if (cameraList != null && cameraList.indexOf(Scene.active.camera.name) < 0) return;
|
|
||||||
|
|
||||||
#if lnx_particles
|
#if lnx_particles
|
||||||
if (raw != null && raw.is_particle && particleOwner == null) return; // Instancing not yet set-up by particle system owner
|
if (raw != null && raw.is_particle && particleOwner == null) return; // Instancing not yet set-up by particle system owner
|
||||||
if (particleSystems != null && meshContext) {
|
if (particleSystems != null && meshContext) {
|
||||||
@ -248,7 +244,6 @@ class MeshObject extends Object {
|
|||||||
Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
|
Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
var c: MeshObject = cast o;
|
var c: MeshObject = cast o;
|
||||||
c.cameraList = this.cameraList;
|
|
||||||
particleChildren.push(c);
|
particleChildren.push(c);
|
||||||
c.particleOwner = this;
|
c.particleOwner = this;
|
||||||
c.particleIndex = particleChildren.length - 1;
|
c.particleIndex = particleChildren.length - 1;
|
||||||
@ -260,11 +255,11 @@ class MeshObject extends Object {
|
|||||||
particleSystems[i].update(particleChildren[i], this);
|
particleSystems[i].update(particleChildren[i], this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (particleSystems != null && particleSystems.length > 0 && !render_emitter) return;
|
if (particleSystems != null && particleSystems.length > 0 && !raw.render_emitter) return;
|
||||||
if (particleSystems == null && cullMaterial(context)) return;
|
|
||||||
#else
|
|
||||||
if (cullMaterial(context)) return;
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
if (cullMaterial(context)) return;
|
||||||
|
|
||||||
// Get lod
|
// Get lod
|
||||||
var mats = materials;
|
var mats = materials;
|
||||||
var lod = this;
|
var lod = this;
|
||||||
|
@ -172,10 +172,6 @@ class Object {
|
|||||||
for (f in t._init) App.removeInit(f);
|
for (f in t._init) App.removeInit(f);
|
||||||
t._init = null;
|
t._init = null;
|
||||||
}
|
}
|
||||||
if (t._fixedUpdate != null) {
|
|
||||||
for (f in t._fixedUpdate) App.removeFixedUpdate(f);
|
|
||||||
t._fixedUpdate = null;
|
|
||||||
}
|
|
||||||
if (t._update != null) {
|
if (t._update != null) {
|
||||||
for (f in t._update) App.removeUpdate(f);
|
for (f in t._update) App.removeUpdate(f);
|
||||||
t._update = null;
|
t._update = null;
|
||||||
|
@ -2,7 +2,6 @@ package iron.object;
|
|||||||
|
|
||||||
#if lnx_particles
|
#if lnx_particles
|
||||||
|
|
||||||
import kha.FastFloat;
|
|
||||||
import kha.graphics4.Usage;
|
import kha.graphics4.Usage;
|
||||||
import kha.arrays.Float32Array;
|
import kha.arrays.Float32Array;
|
||||||
import iron.data.Data;
|
import iron.data.Data;
|
||||||
@ -17,12 +16,10 @@ import iron.math.Vec4;
|
|||||||
class ParticleSystem {
|
class ParticleSystem {
|
||||||
public var data: ParticleData;
|
public var data: ParticleData;
|
||||||
public var speed = 1.0;
|
public var speed = 1.0;
|
||||||
var currentSpeed = 0.0;
|
|
||||||
var particles: Array<Particle>;
|
var particles: Array<Particle>;
|
||||||
var ready: Bool;
|
var ready: Bool;
|
||||||
var frameRate = 24;
|
var frameRate = 24;
|
||||||
var lifetime = 0.0;
|
var lifetime = 0.0;
|
||||||
var looptime = 0.0;
|
|
||||||
var animtime = 0.0;
|
var animtime = 0.0;
|
||||||
var time = 0.0;
|
var time = 0.0;
|
||||||
var spawnRate = 0.0;
|
var spawnRate = 0.0;
|
||||||
@ -49,13 +46,9 @@ class ParticleSystem {
|
|||||||
var ownerLoc = new Vec4();
|
var ownerLoc = new Vec4();
|
||||||
var ownerRot = new Quat();
|
var ownerRot = new Quat();
|
||||||
var ownerScl = new Vec4();
|
var ownerScl = new Vec4();
|
||||||
|
|
||||||
var random = 0.0;
|
|
||||||
|
|
||||||
public function new(sceneName: String, pref: TParticleReference) {
|
public function new(sceneName: String, pref: TParticleReference) {
|
||||||
seed = pref.seed;
|
seed = pref.seed;
|
||||||
currentSpeed = speed;
|
|
||||||
speed = 0;
|
|
||||||
particles = [];
|
particles = [];
|
||||||
ready = false;
|
ready = false;
|
||||||
|
|
||||||
@ -72,61 +65,33 @@ class ParticleSystem {
|
|||||||
gy = 0;
|
gy = 0;
|
||||||
gz = -9.81 * r.weight_gravity;
|
gz = -9.81 * r.weight_gravity;
|
||||||
}
|
}
|
||||||
alignx = r.object_align_factor[0];
|
alignx = r.object_align_factor[0] / 2;
|
||||||
aligny = r.object_align_factor[1];
|
aligny = r.object_align_factor[1] / 2;
|
||||||
alignz = r.object_align_factor[2];
|
alignz = r.object_align_factor[2] / 2;
|
||||||
looptime = (r.frame_end - r.frame_start) / frameRate;
|
|
||||||
lifetime = r.lifetime / frameRate;
|
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;
|
spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate;
|
||||||
|
|
||||||
for (i in 0...r.count) {
|
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;
|
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() {
|
public function pause() {
|
||||||
speed = 0;
|
lifetime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resume() {
|
public function resume() {
|
||||||
lifetime = r.lifetime / frameRate;
|
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) {
|
public function update(object: MeshObject, owner: MeshObject) {
|
||||||
if (!ready || object == null || speed == 0.0) return;
|
if (!ready || object == null || speed == 0.0) return;
|
||||||
if (iron.App.pauseUpdates) return;
|
|
||||||
|
|
||||||
var prevLap = lap;
|
|
||||||
|
|
||||||
// Copy owner world transform but discard scale
|
// Copy owner world transform but discard scale
|
||||||
owner.transform.world.decompose(ownerLoc, ownerRot, ownerScl);
|
owner.transform.world.decompose(ownerLoc, ownerRot, ownerScl);
|
||||||
@ -150,21 +115,17 @@ class ParticleSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Animate
|
// Animate
|
||||||
time += Time.renderDelta * speed; // realDelta to renderDelta
|
time += Time.delta * speed;
|
||||||
lap = Std.int(time / animtime);
|
lap = Std.int(time / animtime);
|
||||||
lapTime = time - lap * animtime;
|
lapTime = time - lap * animtime;
|
||||||
count = Std.int(lapTime / spawnRate);
|
count = Std.int(lapTime / spawnRate);
|
||||||
|
|
||||||
if (lap > prevLap && !r.loop) {
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateGpu(object, owner);
|
updateGpu(object, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(): Mat4 {
|
public function getData(): Mat4 {
|
||||||
var hair = r.type == 1;
|
var hair = r.type == 1;
|
||||||
m._00 = animtime;
|
m._00 = r.loop ? animtime : -animtime;
|
||||||
m._01 = hair ? 1 / particles.length : spawnRate;
|
m._01 = hair ? 1 / particles.length : spawnRate;
|
||||||
m._02 = hair ? 1 : lifetime;
|
m._02 = hair ? 1 : lifetime;
|
||||||
m._03 = particles.length;
|
m._03 = particles.length;
|
||||||
@ -172,9 +133,9 @@ class ParticleSystem {
|
|||||||
m._11 = hair ? 0 : aligny;
|
m._11 = hair ? 0 : aligny;
|
||||||
m._12 = hair ? 0 : alignz;
|
m._12 = hair ? 0 : alignz;
|
||||||
m._13 = hair ? 0 : r.factor_random;
|
m._13 = hair ? 0 : r.factor_random;
|
||||||
m._20 = hair ? 0 : gx;
|
m._20 = hair ? 0 : gx * r.mass;
|
||||||
m._21 = hair ? 0 : gy;
|
m._21 = hair ? 0 : gy * r.mass;
|
||||||
m._22 = hair ? 0 : gz;
|
m._22 = hair ? 0 : gz * r.mass;
|
||||||
m._23 = hair ? 0 : r.lifetime_random;
|
m._23 = hair ? 0 : r.lifetime_random;
|
||||||
m._30 = tilesx;
|
m._30 = tilesx;
|
||||||
m._31 = tilesy;
|
m._31 = tilesy;
|
||||||
@ -183,25 +144,13 @@ class ParticleSystem {
|
|||||||
return m;
|
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) {
|
function updateGpu(object: MeshObject, owner: MeshObject) {
|
||||||
if (!object.data.geom.instanced) setupGeomGpu(object, owner);
|
if (!object.data.geom.instanced) setupGeomGpu(object, owner);
|
||||||
// GPU particles transform is attached to owner object
|
// GPU particles transform is attached to owner object
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupGeomGpu(object: MeshObject, owner: MeshObject) {
|
function setupGeomGpu(object: MeshObject, owner: MeshObject) {
|
||||||
var instancedData = new Float32Array(particles.length * 3);
|
var instancedData = new Float32Array(particles.length * 6);
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
var normFactor = 1 / 32767; // pa.values are not normalized
|
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 ] * 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 + 1] * normFactor * scaleFactor.y); i++;
|
||||||
instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); 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
|
case 1: // Face
|
||||||
@ -243,6 +196,10 @@ class ParticleSystem {
|
|||||||
instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
|
instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
|
||||||
instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
|
instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
|
||||||
instancedData.set(i, pos.z * normFactor * scaleFactor.z); 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
|
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.x); i++;
|
||||||
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); 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, (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 {
|
function fhash(n: Int): Float {
|
||||||
@ -294,11 +255,10 @@ class ParticleSystem {
|
|||||||
|
|
||||||
class Particle {
|
class Particle {
|
||||||
public var i: Int;
|
public var i: Int;
|
||||||
|
public var px = 0.0;
|
||||||
public var x = 0.0;
|
public var py = 0.0;
|
||||||
public var y = 0.0;
|
public var pz = 0.0;
|
||||||
public var z = 0.0;
|
public var sr = 1.0; // Size random
|
||||||
|
|
||||||
public var cameraDistance: Float;
|
public var cameraDistance: Float;
|
||||||
|
|
||||||
public function new(i: Int) {
|
public function new(i: Int) {
|
||||||
|
@ -80,7 +80,7 @@ class Tilesheet {
|
|||||||
function update() {
|
function update() {
|
||||||
if (!ready || paused || action.start >= action.end) return;
|
if (!ready || paused || action.start >= action.end) return;
|
||||||
|
|
||||||
time += Time.renderDelta;
|
time += Time.realDelta;
|
||||||
|
|
||||||
var frameTime = 1 / raw.framerate;
|
var frameTime = 1 / raw.framerate;
|
||||||
var framesToAdvance = 0;
|
var framesToAdvance = 0;
|
||||||
|
@ -1109,26 +1109,6 @@ class Uniforms {
|
|||||||
case "_texUnpack": {
|
case "_texUnpack": {
|
||||||
f = texUnpack != null ? texUnpack : 1.0;
|
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) {
|
if (f == null && externalFloatLinks != null) {
|
||||||
|
@ -1,58 +1,37 @@
|
|||||||
package iron.system;
|
package iron.system;
|
||||||
|
|
||||||
class Time {
|
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;
|
public static var step(get, never): Float;
|
||||||
static function get_step(): Float {
|
static function get_step(): Float {
|
||||||
if (frequency == null) initFrequency();
|
if (frequency == null) initFrequency();
|
||||||
return 1 / frequency;
|
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;
|
public static var scale = 1.0;
|
||||||
static var _delta = 0.0;
|
|
||||||
public static var delta(get, never): Float;
|
public static var delta(get, never): Float;
|
||||||
static function get_delta(): Float {
|
static function get_delta(): Float {
|
||||||
return _delta;
|
if (frequency == null) initFrequency();
|
||||||
|
return (1 / frequency) * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
static var lastRenderTime = 0.0;
|
static var last = 0.0;
|
||||||
static var _renderDelta = 0.0;
|
public static var realDelta = 0.0;
|
||||||
public static var renderDelta(get, never): Float;
|
|
||||||
static function get_renderDelta(): Float {
|
|
||||||
return _renderDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static inline function time(): Float {
|
public static inline function time(): Float {
|
||||||
return kha.Scheduler.time();
|
return kha.Scheduler.time();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static inline function realTime(): Float {
|
public static inline function realTime(): Float {
|
||||||
return kha.Scheduler.realTime();
|
return kha.Scheduler.realTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function update() {
|
static var frequency: Null<Int> = null;
|
||||||
_delta = realTime() - lastTime;
|
|
||||||
lastTime = realTime();
|
static function initFrequency() {
|
||||||
|
frequency = kha.Display.primary != null ? kha.Display.primary.frequency : 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function render() {
|
public static function update() {
|
||||||
_renderDelta = realTime() - lastRenderTime;
|
realDelta = realTime() - last;
|
||||||
lastRenderTime = realTime();
|
last = realTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ class Config {
|
|||||||
var path = iron.data.Data.dataPath + "config.lnx";
|
var path = iron.data.Data.dataPath + "config.lnx";
|
||||||
var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(raw));
|
var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(raw));
|
||||||
#if kha_krom
|
#if kha_krom
|
||||||
if (iron.data.Data.dataPath == '') path = Krom.getFilesLocation() + "/config.lnx";
|
|
||||||
Krom.fileSaveBytes(path, bytes.getData());
|
Krom.fileSaveBytes(path, bytes.getData());
|
||||||
#elseif kha_kore
|
#elseif kha_kore
|
||||||
sys.io.File.saveBytes(path, bytes);
|
sys.io.File.saveBytes(path, bytes);
|
||||||
@ -48,7 +47,6 @@ typedef TConfig = {
|
|||||||
@:optional var rp_ssr: Null<Bool>;
|
@:optional var rp_ssr: Null<Bool>;
|
||||||
@:optional var rp_ssrefr: Null<Bool>;
|
@:optional var rp_ssrefr: Null<Bool>;
|
||||||
@:optional var rp_bloom: Null<Bool>;
|
@:optional var rp_bloom: Null<Bool>;
|
||||||
@:optional var rp_chromatic_aberration: Null<Bool>;
|
|
||||||
@:optional var rp_motionblur: Null<Bool>;
|
@:optional var rp_motionblur: Null<Bool>;
|
||||||
@:optional var rp_gi: Null<Bool>; // voxelao
|
@:optional var rp_gi: Null<Bool>; // voxelao
|
||||||
@:optional var rp_dynres: Null<Bool>; // dynamic resolution scaling
|
@:optional var rp_dynres: Null<Bool>; // dynamic resolution scaling
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +1,26 @@
|
|||||||
package leenkx.logicnode;
|
package leenkx.logicnode;
|
||||||
|
|
||||||
class CameraSetNode extends LogicNode {
|
class CameraSetNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String;
|
|
||||||
|
|
||||||
public function new(tree:LogicTree) {
|
public function new(tree:LogicTree) {
|
||||||
super(tree);
|
super(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
override function run(from:Int) {
|
override function run(from:Int) {
|
||||||
|
leenkx.renderpath.Postprocess.camera_uniforms[0] = inputs[1].get();//Camera: F-Number
|
||||||
switch (property0) {
|
leenkx.renderpath.Postprocess.camera_uniforms[1] = inputs[2].get();//Camera: Shutter time
|
||||||
case 'F-stop':
|
leenkx.renderpath.Postprocess.camera_uniforms[2] = inputs[3].get();//Camera: ISO
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[0] = inputs[1].get();//Camera: F-Number
|
leenkx.renderpath.Postprocess.camera_uniforms[3] = inputs[4].get();//Camera: Exposure Compensation
|
||||||
case 'Shutter Time':
|
leenkx.renderpath.Postprocess.camera_uniforms[4] = inputs[5].get();//Fisheye Distortion
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[1] = inputs[1].get();//Camera: Shutter time
|
leenkx.renderpath.Postprocess.camera_uniforms[5] = inputs[6].get();//DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
||||||
case 'ISO':
|
leenkx.renderpath.Postprocess.camera_uniforms[6] = inputs[7].get();//DoF Distance
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[2] = inputs[1].get();//Camera: ISO
|
leenkx.renderpath.Postprocess.camera_uniforms[7] = inputs[8].get();//DoF Focal Length mm
|
||||||
case 'Exposure Compensation':
|
leenkx.renderpath.Postprocess.camera_uniforms[8] = inputs[9].get();//DoF F-Stop
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[3] = inputs[1].get();//Camera: Exposure Compensation
|
leenkx.renderpath.Postprocess.camera_uniforms[9] = inputs[10].get();//Tonemapping Method
|
||||||
case 'Fisheye Distortion':
|
leenkx.renderpath.Postprocess.camera_uniforms[10] = inputs[11].get();//Distort
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[4] = inputs[1].get();//Fisheye Distortion
|
leenkx.renderpath.Postprocess.camera_uniforms[11] = inputs[12].get();//Film Grain
|
||||||
case 'Auto Focus':
|
leenkx.renderpath.Postprocess.camera_uniforms[12] = inputs[13].get();//Sharpen
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[5] = inputs[1].get();//DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
leenkx.renderpath.Postprocess.camera_uniforms[13] = inputs[14].get();//Vignette
|
||||||
case 'DoF Distance':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[6] = inputs[1].get();//DoF Distance
|
|
||||||
case 'DoF Length':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[7] = inputs[1].get();//DoF Focal Length mm
|
|
||||||
case 'DoF F-Stop':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[8] = inputs[1].get();//DoF F-Stop
|
|
||||||
case 'Tonemapping':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[9] = inputs[1].get();//Tonemapping Method
|
|
||||||
case 'Distort':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[10] = inputs[1].get();//Distort
|
|
||||||
case 'Film Grain':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[11] = inputs[1].get();//Film Grain
|
|
||||||
case 'Sharpen':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[12] = inputs[1].get();//Sharpen
|
|
||||||
case 'Vignette':
|
|
||||||
leenkx.renderpath.Postprocess.camera_uniforms[13] = inputs[1].get();//Vignette
|
|
||||||
case 'Exposure':
|
|
||||||
leenkx.renderpath.Postprocess.exposure_uniforms[0] = inputs[1].get();//Exposure
|
|
||||||
default:
|
|
||||||
null;
|
|
||||||
}
|
|
||||||
|
|
||||||
runOutput(0);
|
runOutput(0);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ class ChromaticAberrationGetNode extends LogicNode {
|
|||||||
return switch (from) {
|
return switch (from) {
|
||||||
case 0: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0];
|
case 0: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0];
|
||||||
case 1: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1];
|
case 1: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1];
|
||||||
case 2: leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[2];
|
|
||||||
default: 0.0;
|
default: 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ class ChromaticAberrationSetNode extends LogicNode {
|
|||||||
|
|
||||||
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0] = inputs[1].get();
|
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[0] = inputs[1].get();
|
||||||
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1] = inputs[2].get();
|
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[1] = inputs[2].get();
|
||||||
leenkx.renderpath.Postprocess.chromatic_aberration_uniforms[2] = inputs[3].get();
|
|
||||||
|
|
||||||
runOutput(0);
|
runOutput(0);
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,6 @@ package leenkx.logicnode;
|
|||||||
|
|
||||||
import iron.Scene;
|
import iron.Scene;
|
||||||
import iron.object.CameraObject;
|
import iron.object.CameraObject;
|
||||||
import iron.math.Vec4;
|
|
||||||
import iron.math.Quat;
|
|
||||||
import leenkx.math.Helper;
|
|
||||||
|
|
||||||
import leenkx.renderpath.RenderPathCreator;
|
import leenkx.renderpath.RenderPathCreator;
|
||||||
|
|
||||||
@ -30,19 +27,11 @@ class DrawCameraTextureNode extends LogicNode {
|
|||||||
final c = inputs[2].get();
|
final c = inputs[2].get();
|
||||||
assert(Error, Std.isOfType(c, CameraObject), "Camera must be a camera object!");
|
assert(Error, Std.isOfType(c, CameraObject), "Camera must be a camera object!");
|
||||||
cam = cast(c, CameraObject);
|
cam = cast(c, CameraObject);
|
||||||
rt = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
|
rt = kha.Image.createRenderTarget(iron.App.w(), iron.App.h());
|
||||||
kha.graphics4.TextureFormat.RGBA32,
|
|
||||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
|
|
||||||
|
|
||||||
assert(Error, mo.materials[matSlot].contexts[0].textures != null, 'Object "${mo.name}" has no diffuse texture to render to');
|
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);
|
tree.notifyOnRender(render);
|
||||||
runOutput(0);
|
runOutput(0);
|
||||||
|
|
||||||
@ -59,20 +48,8 @@ class DrawCameraTextureNode extends LogicNode {
|
|||||||
iron.Scene.active.camera = cam;
|
iron.Scene.active.camera = cam;
|
||||||
cam.renderTarget = rt;
|
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);
|
cam.renderFrame(g);
|
||||||
|
|
||||||
#if kha_html5
|
|
||||||
cam.transform.rot.mult(q);
|
|
||||||
cam.transform.buildMatrix();
|
|
||||||
#end
|
|
||||||
|
|
||||||
cam.renderTarget = oldRT;
|
cam.renderTarget = oldRT;
|
||||||
iron.Scene.active.camera = sceneCam;
|
iron.Scene.active.camera = sceneCam;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,8 @@ class DrawImageSequenceNode extends LogicNode {
|
|||||||
final colorVec = inputs[4].get();
|
final colorVec = inputs[4].get();
|
||||||
g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
|
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());
|
g.drawScaledImage(images[currentImgIdx], inputs[5].get(), inputs[6].get(), inputs[7].get(), inputs[8].get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package leenkx.logicnode;
|
|
||||||
|
|
||||||
import iron.object.MeshObject;
|
|
||||||
import iron.object.CameraObject;
|
|
||||||
|
|
||||||
class GetCameraRenderFilterNode extends LogicNode {
|
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
|
||||||
super(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
override function get(from: Int): Dynamic {
|
|
||||||
var mo: MeshObject = cast inputs[0].get();
|
|
||||||
|
|
||||||
if (mo == null) return null;
|
|
||||||
|
|
||||||
return mo.cameraList;
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ class GetFPSNode extends LogicNode {
|
|||||||
|
|
||||||
override function get(from: Int): Dynamic {
|
override function get(from: Int): Dynamic {
|
||||||
if (from == 0) {
|
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))) {
|
if ((fps == Math.POSITIVE_INFINITY) || (fps == Math.NEGATIVE_INFINITY) || (Math.isNaN(fps))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,26 @@
|
|||||||
package leenkx.logicnode;
|
package leenkx.logicnode;
|
||||||
|
|
||||||
|
import iron.object.Object;
|
||||||
|
import iron.math.Vec4;
|
||||||
|
|
||||||
class GetWorldNode extends LogicNode {
|
class GetWorldNode extends LogicNode {
|
||||||
|
|
||||||
|
public var property0: String;
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
super(tree);
|
super(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
override function get(from: Int): Dynamic {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,6 +18,7 @@ class ProbabilisticOutputNode extends LogicNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sum > 1){
|
if (sum > 1){
|
||||||
|
trace(sum);
|
||||||
for (p in 0...probs.length)
|
for (p in 0...probs.length)
|
||||||
probs[p] /= sum;
|
probs[p] /= sum;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,8 +20,6 @@ class RpConfigNode extends LogicNode {
|
|||||||
on ? leenkx.data.Config.raw.rp_ssrefr = true : leenkx.data.Config.raw.rp_ssrefr = false;
|
on ? leenkx.data.Config.raw.rp_ssrefr = true : leenkx.data.Config.raw.rp_ssrefr = false;
|
||||||
case "Bloom":
|
case "Bloom":
|
||||||
on ? leenkx.data.Config.raw.rp_bloom = true : leenkx.data.Config.raw.rp_bloom = false;
|
on ? leenkx.data.Config.raw.rp_bloom = true : leenkx.data.Config.raw.rp_bloom = false;
|
||||||
case "CA":
|
|
||||||
on ? leenkx.data.Config.raw.rp_chromatic_aberration = true : leenkx.data.Config.raw.rp_chromatic_aberration = false;
|
|
||||||
case "GI":
|
case "GI":
|
||||||
on ? leenkx.data.Config.raw.rp_gi = true : leenkx.data.Config.raw.rp_gi = false;
|
on ? leenkx.data.Config.raw.rp_gi = true : leenkx.data.Config.raw.rp_gi = false;
|
||||||
case "Motion Blur":
|
case "Motion Blur":
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
package leenkx.logicnode;
|
|
||||||
|
|
||||||
import iron.object.MeshObject;
|
|
||||||
import iron.object.CameraObject;
|
|
||||||
|
|
||||||
class SetCameraRenderFilterNode extends LogicNode {
|
|
||||||
|
|
||||||
public var property0: String;
|
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
|
||||||
super(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
override function run(from: Int) {
|
|
||||||
var mo: MeshObject = cast inputs[1].get();
|
|
||||||
var camera: CameraObject = inputs[2].get();
|
|
||||||
|
|
||||||
assert(Error, Std.isOfType(camera, CameraObject), "Camera must be a camera object!");
|
|
||||||
|
|
||||||
if (camera == null || mo == null) return;
|
|
||||||
|
|
||||||
if (property0 == 'Add'){
|
|
||||||
if (mo.cameraList == null || mo.cameraList.indexOf(camera.name) == -1){
|
|
||||||
if (mo.cameraList == null) mo.cameraList = [];
|
|
||||||
mo.cameraList.push(camera.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (mo.cameraList != null){
|
|
||||||
mo.cameraList.remove(camera.name);
|
|
||||||
if (mo.cameraList.length == 0)
|
|
||||||
mo.cameraList = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runOutput(0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,16 +11,13 @@ class SetParticleSpeedNode extends LogicNode {
|
|||||||
override function run(from: Int) {
|
override function run(from: Int) {
|
||||||
#if lnx_particles
|
#if lnx_particles
|
||||||
var object: Object = inputs[1].get();
|
var object: Object = inputs[1].get();
|
||||||
var slot: Int = inputs[2].get();
|
var speed: Float = inputs[2].get();
|
||||||
var speed: Float = inputs[3].get();
|
|
||||||
|
|
||||||
if (object == null) return;
|
if (object == null) return;
|
||||||
|
|
||||||
var mo = cast(object, iron.object.MeshObject);
|
var mo = cast(object, iron.object.MeshObject);
|
||||||
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
|
var psys = mo.particleSystems.length > 0 ? mo.particleSystems[0] : null;
|
||||||
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null;
|
if (psys == null) mo.particleOwner.particleSystems[0];
|
||||||
|
|
||||||
if (psys == null) return;
|
|
||||||
|
|
||||||
psys.speed = speed;
|
psys.speed = speed;
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -77,6 +77,9 @@ class Inc {
|
|||||||
#if (rp_voxels == "Voxel GI")
|
#if (rp_voxels == "Voxel GI")
|
||||||
static var voxel_sh5:kha.compute.Shader = null;
|
static var voxel_sh5:kha.compute.Shader = null;
|
||||||
static var voxel_ta5:kha.compute.TextureUnit;
|
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_ca5:kha.compute.ConstantLocation;
|
||||||
static var voxel_cb5:kha.compute.ConstantLocation;
|
static var voxel_cb5:kha.compute.ConstantLocation;
|
||||||
static var voxel_cc5:kha.compute.ConstantLocation;
|
static var voxel_cc5:kha.compute.ConstantLocation;
|
||||||
@ -529,29 +532,22 @@ class Inc {
|
|||||||
public static function applyConfig() {
|
public static function applyConfig() {
|
||||||
#if lnx_config
|
#if lnx_config
|
||||||
var config = leenkx.data.Config.raw;
|
var config = leenkx.data.Config.raw;
|
||||||
|
|
||||||
#if rp_chromatic_aberration
|
|
||||||
Postprocess.chromatic_aberration_uniforms[3] = config.rp_chromatic_aberration == true ? 1 : 0;
|
|
||||||
#end
|
|
||||||
|
|
||||||
// Resize shadow map
|
// Resize shadow map
|
||||||
var l = path.light;
|
var l = path.light;
|
||||||
if (l != null){
|
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
|
||||||
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
|
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
|
||||||
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
|
var rt = path.renderTargets.get("shadowMap");
|
||||||
var rt = path.renderTargets.get("shadowMap");
|
if (rt != null) {
|
||||||
if (rt != null) {
|
rt.unload();
|
||||||
rt.unload();
|
path.renderTargets.remove("shadowMap");
|
||||||
path.renderTargets.remove("shadowMap");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
|
}
|
||||||
l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
|
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
|
||||||
var rt = path.renderTargets.get("shadowMapCube");
|
l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
|
||||||
if (rt != null) {
|
var rt = path.renderTargets.get("shadowMapCube");
|
||||||
rt.unload();
|
if (rt != null) {
|
||||||
path.renderTargets.remove("shadowMapCube");
|
rt.unload();
|
||||||
}
|
path.renderTargets.remove("shadowMapCube");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (superSample != config.rp_supersample) {
|
if (superSample != config.rp_supersample) {
|
||||||
@ -684,7 +680,7 @@ class Inc {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
|
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
|
||||||
t.format = "R16";
|
t.format = "R8";
|
||||||
t.width = res;
|
t.width = res;
|
||||||
t.height = res * Main.voxelgiClipmapCount;
|
t.height = res * Main.voxelgiClipmapCount;
|
||||||
t.depth = res;
|
t.depth = res;
|
||||||
@ -693,7 +689,7 @@ class Inc {
|
|||||||
#if (rp_voxels == "Voxel AO")
|
#if (rp_voxels == "Voxel AO")
|
||||||
{
|
{
|
||||||
if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
|
if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
|
||||||
t.format = "R16";
|
t.format = "R8";
|
||||||
t.width = res * (6 + 16);
|
t.width = res * (6 + 16);
|
||||||
t.height = res * Main.voxelgiClipmapCount;
|
t.height = res * Main.voxelgiClipmapCount;
|
||||||
t.depth = res;
|
t.depth = res;
|
||||||
@ -785,11 +781,7 @@ class Inc {
|
|||||||
|
|
||||||
public static inline function getDisplayp(): Null<Int> {
|
public static inline function getDisplayp(): Null<Int> {
|
||||||
#if rp_resolution_filter // Custom resolution set
|
#if rp_resolution_filter // Custom resolution set
|
||||||
#if rp_pp
|
|
||||||
return leenkx.renderpath.Postprocess.resolution_uniforms[0];
|
|
||||||
#else
|
|
||||||
return Main.resolutionSize;
|
return Main.resolutionSize;
|
||||||
#end
|
|
||||||
#else
|
#else
|
||||||
return null;
|
return null;
|
||||||
#end
|
#end
|
||||||
@ -903,7 +895,9 @@ class Inc {
|
|||||||
{
|
{
|
||||||
voxel_sh5 = path.getComputeShader("voxel_light");
|
voxel_sh5 = path.getComputeShader("voxel_light");
|
||||||
voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
|
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_ca5 = voxel_sh5.getConstantLocation("clipmaps");
|
||||||
voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
|
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.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.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);
|
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||||
for (i in 0...Main.voxelgiClipmapCount) {
|
for (i in 0...Main.voxelgiClipmapCount) {
|
||||||
@ -1299,7 +1293,9 @@ class Inc {
|
|||||||
kha.compute.Compute.setShader(voxel_sh5);
|
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_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);
|
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
|
||||||
for (i in 0...Main.voxelgiClipmapCount) {
|
for (i in 0...Main.voxelgiClipmapCount) {
|
||||||
fa[i * 10] = clipmaps[i].voxelSize;
|
fa[i * 10] = clipmaps[i].voxelSize;
|
||||||
|
@ -49,20 +49,15 @@ class Postprocess {
|
|||||||
0.01, //4: Fisheye Distortion
|
0.01, //4: Fisheye Distortion
|
||||||
1, //5: DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
1, //5: DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
||||||
10.0, //6: DoF Distance
|
10.0, //6: DoF Distance
|
||||||
50.0, //7: DoF Focal Length mm
|
160.0, //7: DoF Focal Length mm
|
||||||
128, //8: DoF F-Stop
|
128, //8: DoF F-Stop
|
||||||
0, //9: Tonemapping Method
|
0, //9: Tonemapping Method
|
||||||
2.0, //10: Distort
|
2.0, //10: Distort
|
||||||
2.0, //11: Film Grain
|
2.0, //11: Film Grain
|
||||||
0.25, //12: Sharpen Strength
|
0.25, //12: Sharpen
|
||||||
0.7 //13: Vignette
|
0.7 //13: Vignette
|
||||||
];
|
];
|
||||||
|
|
||||||
public static var sharpen_uniforms = [
|
|
||||||
[0.0, 0.0, 0.0], //0: Sharpen Color
|
|
||||||
[2.5] //1: Sharpen Size
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var tonemapper_uniforms = [
|
public static var tonemapper_uniforms = [
|
||||||
1.0, //0: Slope
|
1.0, //0: Slope
|
||||||
1.0, //1: Toe
|
1.0, //1: Toe
|
||||||
@ -107,35 +102,7 @@ class Postprocess {
|
|||||||
|
|
||||||
public static var chromatic_aberration_uniforms = [
|
public static var chromatic_aberration_uniforms = [
|
||||||
2.0, //0: Strength
|
2.0, //0: Strength
|
||||||
32, //1: Samples
|
32 //1: Samples
|
||||||
0, //2: Type
|
|
||||||
1 //3: On/Off
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var exposure_uniforms = [
|
|
||||||
1 //0: Exposure
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var auto_exposure_uniforms = [
|
|
||||||
1, //0: Auto Exposure Strength
|
|
||||||
1 //1: Auto Exposure Speed
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var volumetric_light_uniforms = [
|
|
||||||
[1.0, 1.0, 1.0], //0: Volumetric Light Air Color
|
|
||||||
[1.0], //1: Volumetric Light Air Turbidity
|
|
||||||
[20.0] //2: Volumetric Light Steps
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var volumetric_fog_uniforms = [
|
|
||||||
[0.5, 0.6, 0.7], //0: Volumetric Fog Color
|
|
||||||
[0.25], //1: Volumetric Fog Amount A
|
|
||||||
[50.0] //2: Volumetric Fog Amount B
|
|
||||||
];
|
|
||||||
|
|
||||||
public static var resolution_uniforms = [
|
|
||||||
720, //0: Size
|
|
||||||
0 //1: Filter
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
|
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
|
||||||
@ -317,11 +284,6 @@ class Postprocess {
|
|||||||
v.x = lenstexture_uniforms[2]; //Lum min
|
v.x = lenstexture_uniforms[2]; //Lum min
|
||||||
v.y = lenstexture_uniforms[3]; //Lum max
|
v.y = lenstexture_uniforms[3]; //Lum max
|
||||||
v.z = lenstexture_uniforms[4]; //Expo
|
v.z = lenstexture_uniforms[4]; //Expo
|
||||||
case "_PPComp8":
|
|
||||||
v = iron.object.Uniforms.helpVec;
|
|
||||||
v.x = exposure_uniforms[0]; //Exposure
|
|
||||||
v.y = auto_exposure_uniforms[0]; //Auto Exposure Strength
|
|
||||||
v.z = auto_exposure_uniforms[1]; //Auto Exposure Speed
|
|
||||||
case "_PPComp9":
|
case "_PPComp9":
|
||||||
v = iron.object.Uniforms.helpVec;
|
v = iron.object.Uniforms.helpVec;
|
||||||
v.x = ssr_uniforms[0]; //Step
|
v.x = ssr_uniforms[0]; //Step
|
||||||
@ -335,8 +297,8 @@ class Postprocess {
|
|||||||
case "_PPComp11":
|
case "_PPComp11":
|
||||||
v = iron.object.Uniforms.helpVec;
|
v = iron.object.Uniforms.helpVec;
|
||||||
v.x = bloom_uniforms[2]; // Bloom Strength
|
v.x = bloom_uniforms[2]; // Bloom Strength
|
||||||
v.y = volumetric_light_uniforms[2][0]; //Volumetric Light Steps
|
v.y = 0; // Unused
|
||||||
v.z = volumetric_fog_uniforms[2][0]; //Volumetric Fog Amount B
|
v.z = 0; // Unused
|
||||||
case "_PPComp12":
|
case "_PPComp12":
|
||||||
v = iron.object.Uniforms.helpVec;
|
v = iron.object.Uniforms.helpVec;
|
||||||
v.x = ssao_uniforms[0]; //SSAO Strength
|
v.x = ssao_uniforms[0]; //SSAO Strength
|
||||||
@ -346,8 +308,7 @@ class Postprocess {
|
|||||||
v = iron.object.Uniforms.helpVec;
|
v = iron.object.Uniforms.helpVec;
|
||||||
v.x = chromatic_aberration_uniforms[0]; //CA Strength
|
v.x = chromatic_aberration_uniforms[0]; //CA Strength
|
||||||
v.y = chromatic_aberration_uniforms[1]; //CA Samples
|
v.y = chromatic_aberration_uniforms[1]; //CA Samples
|
||||||
v.z = chromatic_aberration_uniforms[2]; //CA Type
|
v.z = 0;
|
||||||
v.w = chromatic_aberration_uniforms[3]; //On/Off
|
|
||||||
case "_PPComp14":
|
case "_PPComp14":
|
||||||
v = iron.object.Uniforms.helpVec;
|
v = iron.object.Uniforms.helpVec;
|
||||||
v.x = camera_uniforms[10]; //Distort
|
v.x = camera_uniforms[10]; //Distort
|
||||||
@ -377,24 +338,6 @@ class Postprocess {
|
|||||||
v.y = letterbox_uniforms[0][1];
|
v.y = letterbox_uniforms[0][1];
|
||||||
v.z = letterbox_uniforms[0][2];
|
v.z = letterbox_uniforms[0][2];
|
||||||
v.w = letterbox_uniforms[1][0]; //Size
|
v.w = letterbox_uniforms[1][0]; //Size
|
||||||
case "_PPComp16":
|
|
||||||
v = iron.object.Uniforms.helpVec;
|
|
||||||
v.x = sharpen_uniforms[0][0]; //Color
|
|
||||||
v.y = sharpen_uniforms[0][1];
|
|
||||||
v.z = sharpen_uniforms[0][2];
|
|
||||||
v.w = sharpen_uniforms[1][0]; //Size
|
|
||||||
case "_PPComp17":
|
|
||||||
v = iron.object.Uniforms.helpVec;
|
|
||||||
v.x = volumetric_light_uniforms[0][0]; //Air Color
|
|
||||||
v.y = volumetric_light_uniforms[0][1];
|
|
||||||
v.z = volumetric_light_uniforms[0][2];
|
|
||||||
v.w = volumetric_light_uniforms[1][0]; //Air Turbidity
|
|
||||||
case "_PPComp18":
|
|
||||||
v = iron.object.Uniforms.helpVec;
|
|
||||||
v.x = volumetric_fog_uniforms[0][0]; //Color
|
|
||||||
v.y = volumetric_fog_uniforms[0][1];
|
|
||||||
v.z = volumetric_fog_uniforms[0][2];
|
|
||||||
v.w = volumetric_fog_uniforms[1][0]; //Amount A
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -368,7 +368,7 @@ class RenderPathDeferred {
|
|||||||
t.scale = Inc.getSuperSampling();
|
t.scale = Inc.getSuperSampling();
|
||||||
path.createRenderTarget(t);
|
path.createRenderTarget(t);
|
||||||
|
|
||||||
// holds background depth
|
// holds background color
|
||||||
var t = new RenderTargetRaw();
|
var t = new RenderTargetRaw();
|
||||||
t.name = "refr";
|
t.name = "refr";
|
||||||
t.width = 0;
|
t.width = 0;
|
||||||
@ -473,6 +473,13 @@ class RenderPathDeferred {
|
|||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
#if rp_ssrefr
|
||||||
|
{
|
||||||
|
path.setTarget("gbuffer_refraction");
|
||||||
|
path.clearTarget(0xffffff00);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
RenderPathCreator.setTargetMeshes();
|
RenderPathCreator.setTargetMeshes();
|
||||||
|
|
||||||
#if rp_dynres
|
#if rp_dynres
|
||||||
@ -837,7 +844,7 @@ class RenderPathDeferred {
|
|||||||
{
|
{
|
||||||
path.bindTarget("voxelsOut", "voxels");
|
path.bindTarget("voxelsOut", "voxels");
|
||||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||||
path.bindTarget("gbuffer2", "sveloc");
|
path.bindTarget("gbuffer2", "gbuffer2");
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -522,6 +522,17 @@ class RenderPathForward {
|
|||||||
|
|
||||||
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
|
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
|
||||||
|
|
||||||
|
#if rp_shadowmap
|
||||||
|
{
|
||||||
|
#if lnx_shadowmap_atlas
|
||||||
|
Inc.bindShadowMapAtlas();
|
||||||
|
#else
|
||||||
|
Inc.bindShadowMap();
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
|
||||||
#if (rp_voxels != "Off")
|
#if (rp_voxels != "Off")
|
||||||
path.bindTarget("voxelsOut", "voxels");
|
path.bindTarget("voxelsOut", "voxels");
|
||||||
path.bindTarget("voxelsSDF", "voxelsSDF");
|
path.bindTarget("voxelsSDF", "voxelsSDF");
|
||||||
|
@ -41,7 +41,11 @@ class Starter {
|
|||||||
try {
|
try {
|
||||||
#end
|
#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() {
|
iron.App.init(function() {
|
||||||
#if lnx_loadscreen
|
#if lnx_loadscreen
|
||||||
|
@ -45,7 +45,7 @@ class DebugDrawHelper {
|
|||||||
|
|
||||||
iron.App.notifyOnRender2D(onRender);
|
iron.App.notifyOnRender2D(onRender);
|
||||||
if (debugDrawMode & DrawRayCast != 0) {
|
if (debugDrawMode & DrawRayCast != 0) {
|
||||||
iron.App.notifyOnFixedUpdate(function () {
|
iron.App.notifyOnUpdate(function () {
|
||||||
rayCasts.resize(0);
|
rayCasts.resize(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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();
|
super();
|
||||||
|
|
||||||
if (nullvec) {
|
if (nullvec) {
|
||||||
@ -120,7 +120,6 @@ class PhysicsWorld extends Trait {
|
|||||||
this.timeScale = timeScale;
|
this.timeScale = timeScale;
|
||||||
this.maxSteps = maxSteps;
|
this.maxSteps = maxSteps;
|
||||||
this.solverIterations = solverIterations;
|
this.solverIterations = solverIterations;
|
||||||
Time.initFixedStep(fixedStep);
|
|
||||||
|
|
||||||
// First scene
|
// First scene
|
||||||
if (active == null) {
|
if (active == null) {
|
||||||
@ -137,10 +136,10 @@ class PhysicsWorld extends Trait {
|
|||||||
conMap = new Map();
|
conMap = new Map();
|
||||||
active = this;
|
active = this;
|
||||||
|
|
||||||
// Ensure physics are updated first in the fixedUpdate list
|
// Ensure physics are updated first in the lateUpdate list
|
||||||
_fixedUpdate = [fixedUpdate];
|
_lateUpdate = [lateUpdate];
|
||||||
@:privateAccess iron.App.traitFixedUpdates.insert(0, fixedUpdate);
|
@:privateAccess iron.App.traitLateUpdates.insert(0, lateUpdate);
|
||||||
|
|
||||||
setDebugDrawMode(debugDrawMode);
|
setDebugDrawMode(debugDrawMode);
|
||||||
|
|
||||||
iron.Scene.active.notifyOnRemove(function() {
|
iron.Scene.active.notifyOnRemove(function() {
|
||||||
@ -299,8 +298,8 @@ class PhysicsWorld extends Trait {
|
|||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixedUpdate() {
|
function lateUpdate() {
|
||||||
var t = Time.fixedStep * timeScale * Time.scale;
|
var t = Time.delta * timeScale;
|
||||||
if (t == 0.0) return; // Simulation paused
|
if (t == 0.0) return; // Simulation paused
|
||||||
|
|
||||||
#if lnx_debug
|
#if lnx_debug
|
||||||
@ -309,10 +308,13 @@ class PhysicsWorld extends Trait {
|
|||||||
|
|
||||||
if (preUpdates != null) for (f in preUpdates) f();
|
if (preUpdates != null) for (f in preUpdates) f();
|
||||||
|
|
||||||
//This condition must be satisfied to not loose time
|
//Bullet physics fixed timescale
|
||||||
var currMaxSteps = t < (Time.fixedStep * maxSteps) ? maxSteps : 1;
|
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();
|
updateContacts();
|
||||||
|
|
||||||
for (rb in rbMap) @:privateAccess rb.physicsUpdate();
|
for (rb in rbMap) @:privateAccess rb.physicsUpdate();
|
||||||
@ -434,8 +436,8 @@ class PhysicsWorld extends Trait {
|
|||||||
from: from,
|
from: from,
|
||||||
to: to,
|
to: to,
|
||||||
hasHit: rc.hasHit(),
|
hasHit: rc.hasHit(),
|
||||||
hitPoint: hitPointWorld.clone(),
|
hitPoint: hitPointWorld,
|
||||||
hitNormal: hitNormalWorld.clone()
|
hitNormal: hitNormalWorld
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,11 @@ package leenkx.trait.physics.bullet;
|
|||||||
|
|
||||||
#if lnx_bullet
|
#if lnx_bullet
|
||||||
|
|
||||||
import leenkx.math.Helper;
|
|
||||||
import iron.data.MeshData;
|
|
||||||
import iron.math.Vec4;
|
import iron.math.Vec4;
|
||||||
import iron.math.Quat;
|
import iron.math.Quat;
|
||||||
import iron.object.Transform;
|
import iron.object.Transform;
|
||||||
import iron.object.MeshObject;
|
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.
|
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 triangleMeshCache = new Map<MeshData, bullet.Bt.TriangleMesh>();
|
||||||
static var usersCache = new Map<MeshData, Int>();
|
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,
|
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) {
|
params: RigidBodyParams = null, flags: RigidBodyFlags = null) {
|
||||||
super();
|
super();
|
||||||
@ -95,7 +85,7 @@ class RigidBody extends iron.Trait {
|
|||||||
vec1 = new bullet.Bt.Vector3(0, 0, 0);
|
vec1 = new bullet.Bt.Vector3(0, 0, 0);
|
||||||
vec2 = new bullet.Bt.Vector3(0, 0, 0);
|
vec2 = new bullet.Bt.Vector3(0, 0, 0);
|
||||||
vec3 = 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();
|
trans1 = new bullet.Bt.Transform();
|
||||||
trans2 = new bullet.Bt.Transform();
|
trans2 = new bullet.Bt.Transform();
|
||||||
}
|
}
|
||||||
@ -127,7 +117,6 @@ class RigidBody extends iron.Trait {
|
|||||||
animated: false,
|
animated: false,
|
||||||
trigger: false,
|
trigger: false,
|
||||||
ccd: false,
|
ccd: false,
|
||||||
interpolate: false,
|
|
||||||
staticObj: false,
|
staticObj: false,
|
||||||
useDeactivation: true
|
useDeactivation: true
|
||||||
};
|
};
|
||||||
@ -142,7 +131,6 @@ class RigidBody extends iron.Trait {
|
|||||||
this.animated = flags.animated;
|
this.animated = flags.animated;
|
||||||
this.trigger = flags.trigger;
|
this.trigger = flags.trigger;
|
||||||
this.ccd = flags.ccd;
|
this.ccd = flags.ccd;
|
||||||
this.interpolate = flags.interpolate;
|
|
||||||
this.staticObj = flags.staticObj;
|
this.staticObj = flags.staticObj;
|
||||||
this.useDeactivation = flags.useDeactivation;
|
this.useDeactivation = flags.useDeactivation;
|
||||||
|
|
||||||
@ -165,7 +153,6 @@ class RigidBody extends iron.Trait {
|
|||||||
if (!Std.isOfType(object, MeshObject)) return; // No mesh data
|
if (!Std.isOfType(object, MeshObject)) return; // No mesh data
|
||||||
|
|
||||||
transform = object.transform;
|
transform = object.transform;
|
||||||
transform.buildMatrix();
|
|
||||||
physics = leenkx.trait.physics.PhysicsWorld.active;
|
physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||||
|
|
||||||
if (shape == Shape.Box) {
|
if (shape == Shape.Box) {
|
||||||
@ -257,9 +244,6 @@ class RigidBody extends iron.Trait {
|
|||||||
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
|
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
|
||||||
trans1.setRotation(quat1);
|
trans1.setRotation(quat1);
|
||||||
|
|
||||||
currentPos.setValue(vec1.x(), vec1.y(), vec1.z());
|
|
||||||
currentRot.setValue(quat.x, quat.y, quat.z, quat.w);
|
|
||||||
|
|
||||||
var centerOfMassOffset = trans2;
|
var centerOfMassOffset = trans2;
|
||||||
centerOfMassOffset.setIdentity();
|
centerOfMassOffset.setIdentity();
|
||||||
motionState = new bullet.Bt.DefaultMotionState(trans1, centerOfMassOffset);
|
motionState = new bullet.Bt.DefaultMotionState(trans1, centerOfMassOffset);
|
||||||
@ -323,8 +307,7 @@ class RigidBody extends iron.Trait {
|
|||||||
|
|
||||||
physics.addRigidBody(this);
|
physics.addRigidBody(this);
|
||||||
notifyOnRemove(removeFromWorld);
|
notifyOnRemove(removeFromWorld);
|
||||||
if (!animated) notifyOnUpdate(update);
|
|
||||||
|
|
||||||
if (onReady != null) onReady();
|
if (onReady != null) onReady();
|
||||||
|
|
||||||
#if js
|
#if js
|
||||||
@ -334,71 +317,26 @@ class RigidBody extends iron.Trait {
|
|||||||
#end
|
#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() {
|
function physicsUpdate() {
|
||||||
if (!ready) return;
|
if (!ready) return;
|
||||||
if (animated) {
|
if (animated) {
|
||||||
syncTransform();
|
syncTransform();
|
||||||
} else {
|
}
|
||||||
if (interpolate) {
|
else {
|
||||||
prevPos.setValue(currentPos.x(), currentPos.y(), currentPos.z());
|
|
||||||
prevRot.setValue(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
|
|
||||||
}
|
|
||||||
var trans = body.getWorldTransform();
|
var trans = body.getWorldTransform();
|
||||||
var p = trans.getOrigin();
|
var p = trans.getOrigin();
|
||||||
var q = trans.getRotation();
|
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
|
#if hl
|
||||||
p.delete();
|
p.delete();
|
||||||
@ -751,7 +689,6 @@ typedef RigidBodyFlags = {
|
|||||||
var animated: Bool;
|
var animated: Bool;
|
||||||
var trigger: Bool;
|
var trigger: Bool;
|
||||||
var ccd: Bool;
|
var ccd: Bool;
|
||||||
var interpolate: Bool;
|
|
||||||
var staticObj: Bool;
|
var staticObj: Bool;
|
||||||
var useDeactivation: Bool;
|
var useDeactivation: Bool;
|
||||||
}
|
}
|
||||||
|
@ -540,7 +540,7 @@ class LeenkxExporter:
|
|||||||
o['material_refs'].append(lnx.utils.asset_name(material))
|
o['material_refs'].append(lnx.utils.asset_name(material))
|
||||||
|
|
||||||
def export_particle_system_ref(self, psys: bpy.types.ParticleSystem, out_object):
|
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
|
return
|
||||||
|
|
||||||
self.particle_system_array[psys.settings] = {"structName": psys.settings.name}
|
self.particle_system_array[psys.settings] = {"structName": psys.settings.name}
|
||||||
@ -835,13 +835,6 @@ class LeenkxExporter:
|
|||||||
}
|
}
|
||||||
out_object['vertex_groups'].append(out_vertex_groups)
|
out_object['vertex_groups'].append(out_vertex_groups)
|
||||||
|
|
||||||
if len(bobject.lnx_camera_list) > 0:
|
|
||||||
out_camera_list = []
|
|
||||||
for camera in bobject.lnx_camera_list:
|
|
||||||
if camera.lnx_camera_object_ptr != None:
|
|
||||||
out_camera_list.append(camera.lnx_camera_object_ptr.name)
|
|
||||||
if len(out_camera_list) > 0:
|
|
||||||
out_object['camera_list'] = out_camera_list
|
|
||||||
|
|
||||||
if len(bobject.lnx_propertylist) > 0:
|
if len(bobject.lnx_propertylist) > 0:
|
||||||
out_object['properties'] = []
|
out_object['properties'] = []
|
||||||
@ -917,8 +910,7 @@ class LeenkxExporter:
|
|||||||
out_object['particle_refs'] = []
|
out_object['particle_refs'] = []
|
||||||
out_object['render_emitter'] = bobject.show_instancer_for_render
|
out_object['render_emitter'] = bobject.show_instancer_for_render
|
||||||
for i in range(num_psys):
|
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
|
aabb = bobject.data.lnx_aabb
|
||||||
if aabb[0] == 0 and aabb[1] == 0 and aabb[2] == 0:
|
if aabb[0] == 0 and aabb[1] == 0 and aabb[2] == 0:
|
||||||
@ -2288,15 +2280,6 @@ class LeenkxExporter:
|
|||||||
if len(self.particle_system_array) > 0:
|
if len(self.particle_system_array) > 0:
|
||||||
self.output['particle_datas'] = []
|
self.output['particle_datas'] = []
|
||||||
for particleRef in self.particle_system_array.items():
|
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]
|
psettings = particleRef[0]
|
||||||
|
|
||||||
if psettings is None:
|
if psettings is None:
|
||||||
@ -2314,8 +2297,6 @@ class LeenkxExporter:
|
|||||||
out_particlesys = {
|
out_particlesys = {
|
||||||
'name': particleRef[1]["structName"],
|
'name': particleRef[1]["structName"],
|
||||||
'type': 0 if psettings.type == 'EMITTER' else 1, # HAIR
|
'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,
|
'loop': psettings.lnx_loop,
|
||||||
# Emission
|
# Emission
|
||||||
'count': int(psettings.count * psettings.lnx_count_mult),
|
'count': int(psettings.count * psettings.lnx_count_mult),
|
||||||
@ -2832,7 +2813,6 @@ class LeenkxExporter:
|
|||||||
body_flags['animated'] = rb.kinematic
|
body_flags['animated'] = rb.kinematic
|
||||||
body_flags['trigger'] = bobject.lnx_rb_trigger
|
body_flags['trigger'] = bobject.lnx_rb_trigger
|
||||||
body_flags['ccd'] = bobject.lnx_rb_ccd
|
body_flags['ccd'] = bobject.lnx_rb_ccd
|
||||||
body_flags['interpolate'] = bobject.lnx_rb_interpolate
|
|
||||||
body_flags['staticObj'] = is_static
|
body_flags['staticObj'] = is_static
|
||||||
body_flags['useDeactivation'] = rb.use_deactivation
|
body_flags['useDeactivation'] = rb.use_deactivation
|
||||||
x['parameters'].append(lnx.utils.get_haxe_json_string(body_params))
|
x['parameters'].append(lnx.utils.get_haxe_json_string(body_params))
|
||||||
@ -3057,7 +3037,7 @@ class LeenkxExporter:
|
|||||||
|
|
||||||
rbw = self.scene.rigidbody_world
|
rbw = self.scene.rigidbody_world
|
||||||
if rbw is not None and rbw.enabled:
|
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':
|
if phys_pkg == 'bullet' or phys_pkg == 'oimo':
|
||||||
debug_draw_mode = 1 if wrd.lnx_physics_dbg_draw_wireframe else 0
|
debug_draw_mode = 1 if wrd.lnx_physics_dbg_draw_wireframe else 0
|
||||||
|
@ -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_trigger = source_obj.lnx_rb_trigger
|
||||||
target_obj.lnx_rb_deactivation_time = source_obj.lnx_rb_deactivation_time
|
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_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
|
target_obj.lnx_rb_collision_filter_mask = source_obj.lnx_rb_collision_filter_mask
|
||||||
|
|
||||||
elif operator_id == "NODE_OT_new_node_tree":
|
elif operator_id == "NODE_OT_new_node_tree":
|
||||||
|
@ -191,7 +191,7 @@ def apply_materials(load_atlas=0):
|
|||||||
|
|
||||||
mainNode = outputNode.inputs[0].links[0].from_node.inputs[0].links[0].from_node
|
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:
|
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||||
print("Mix RGB shader found")
|
print("Mix RGB shader found")
|
||||||
|
|
||||||
@ -199,11 +199,9 @@ def apply_materials(load_atlas=0):
|
|||||||
|
|
||||||
#Add all nodes first
|
#Add all nodes first
|
||||||
#Add lightmap multipliction texture
|
#Add lightmap multipliction texture
|
||||||
mixNode = node_tree.nodes.new(type="ShaderNodeMix")
|
mixNode = node_tree.nodes.new(type="ShaderNodeMixRGB")
|
||||||
mixNode.name = "Lightmap_Multiplication"
|
mixNode.name = "Lightmap_Multiplication"
|
||||||
mixNode.location = -800, 300
|
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":
|
if scene.TLM_EngineProperties.tlm_lighting_mode == "indirect" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectAO":
|
||||||
mixNode.blend_type = 'MULTIPLY'
|
mixNode.blend_type = 'MULTIPLY'
|
||||||
else:
|
else:
|
||||||
@ -314,8 +312,8 @@ def apply_materials(load_atlas=0):
|
|||||||
else:
|
else:
|
||||||
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
|
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(DecodeNode.outputs[0], mixNode.inputs[1]) #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(ExposureNode.outputs[0], mixNode.inputs[1]) #Connect exposure node to mixnode
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@ -325,10 +323,10 @@ def apply_materials(load_atlas=0):
|
|||||||
else:
|
else:
|
||||||
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
|
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(baseColorNode.outputs[0], mixNode.inputs[2]) #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(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
|
||||||
|
|
||||||
if not scene.TLM_EngineProperties.tlm_target == "vertex":
|
if not scene.TLM_EngineProperties.tlm_target == "vertex":
|
||||||
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
|
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):
|
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(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:
|
else:
|
||||||
mat.node_tree.links.new(lightmapNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
|
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[7]) #Connect basecolor 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[2]) #Connect mixnode 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":
|
if not scene.TLM_EngineProperties.tlm_target == "vertex":
|
||||||
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
|
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.image = AOImage
|
||||||
AOMap.location = -800, 0
|
AOMap.location = -800, 0
|
||||||
|
|
||||||
AOMult = nodes.new(type="ShaderNodeMix")
|
AOMult = nodes.new(type="ShaderNodeMixRGB")
|
||||||
AOMult.name = "TLM_AOMult"
|
AOMult.name = "TLM_AOMult"
|
||||||
AOMult.data_type = 'RGBA'
|
|
||||||
AOMult.blend_type = 'MULTIPLY'
|
AOMult.blend_type = 'MULTIPLY'
|
||||||
AOMult.inputs[0].default_value = 1.0
|
AOMult.inputs[0].default_value = 1.0
|
||||||
AOMult.location = -300, 300
|
AOMult.location = -300, 300
|
||||||
|
@ -518,7 +518,7 @@ def configure_meshes(self):
|
|||||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||||
print("The material group is not supported!")
|
print("The material group is not supported!")
|
||||||
|
|
||||||
if (mainNode.type == "ShaderNodeMix"):
|
if (mainNode.type == "ShaderNodeMixRGB"):
|
||||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||||
print("Mix shader found")
|
print("Mix shader found")
|
||||||
|
|
||||||
@ -811,7 +811,7 @@ def set_settings():
|
|||||||
|
|
||||||
print(bpy.app.version)
|
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":
|
if cycles.device == "GPU":
|
||||||
scene.cycles.tile_size = 256
|
scene.cycles.tile_size = 256
|
||||||
else:
|
else:
|
||||||
|
@ -28,11 +28,7 @@ class ViewportDraw:
|
|||||||
w = 400
|
w = 400
|
||||||
h = 200
|
h = 200
|
||||||
|
|
||||||
if bpy.app.version[0] == 3:
|
self.shader = gpu.shader.from_builtin('2D_IMAGE')
|
||||||
self.shader = gpu.shader.from_builtin('2D_IMAGE')
|
|
||||||
else:
|
|
||||||
self.shader = gpu.shader.from_builtin('IMAGE')
|
|
||||||
|
|
||||||
self.batch = batch_for_shader(
|
self.batch = batch_for_shader(
|
||||||
self.shader, 'TRI_FAN',
|
self.shader, 'TRI_FAN',
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ class Shader_Node_Types:
|
|||||||
normal = "ShaderNodeNormalMap"
|
normal = "ShaderNodeNormalMap"
|
||||||
ao = "ShaderNodeAmbientOcclusion"
|
ao = "ShaderNodeAmbientOcclusion"
|
||||||
uv = "ShaderNodeUVMap"
|
uv = "ShaderNodeUVMap"
|
||||||
mix = "ShaderNodeMix"
|
mix = "ShaderNodeMixRGB"
|
||||||
|
|
||||||
def select_object(self,obj):
|
def select_object(self,obj):
|
||||||
C = bpy.context
|
C = bpy.context
|
||||||
|
@ -47,8 +47,7 @@ def init_categories():
|
|||||||
lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion")
|
lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion")
|
||||||
lnx_nodes.add_category('Transform', icon='TRANSFORM_ORIGINS', 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('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('Array', icon='MOD_ARRAY', section="values")
|
||||||
lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values")
|
lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values")
|
||||||
lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values")
|
lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values")
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
from lnx.logicnode.lnx_nodes import *
|
from lnx.logicnode.lnx_nodes import *
|
||||||
|
|
||||||
class SetParticleSpeedNode(LnxLogicTreeNode):
|
class SetParticleSpeedNode(LnxLogicTreeNode):
|
||||||
"""Sets the speed of the given particle source."""
|
"""Sets the speed of the given particle source."""
|
||||||
bl_idname = 'LNSetParticleSpeedNode'
|
bl_idname = 'LNSetParticleSpeedNode'
|
||||||
bl_label = 'Set Particle Speed'
|
bl_label = 'Set Particle Speed'
|
||||||
lnx_version = 2
|
lnx_version = 1
|
||||||
|
|
||||||
def lnx_init(self, context):
|
def lnx_init(self, context):
|
||||||
self.add_input('LnxNodeSocketAction', 'In')
|
self.add_input('LnxNodeSocketAction', 'In')
|
||||||
self.add_input('LnxNodeSocketObject', 'Object')
|
self.add_input('LnxNodeSocketObject', 'Object')
|
||||||
self.add_input('LnxIntSocket', 'Slot')
|
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
|
||||||
|
self.add_output('LnxNodeSocketAction', 'Out')
|
||||||
self.add_output('LnxNodeSocketAction', 'Out')
|
|
||||||
|
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
|
||||||
if self.lnx_version not in (0, 1):
|
|
||||||
raise LookupError()
|
|
||||||
|
|
||||||
return NodeReplacement.Identity(self)
|
|
@ -11,15 +11,14 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
|
|||||||
@input Object: Object of which to choose the material in the `Material Slot` input.
|
@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
|
@input Material Slot: Index of the material slot of which the diffuse
|
||||||
texture is replaced with the camera's render target.
|
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 Start: Activated after the `Start` input has been activated.
|
||||||
@output On Stop: Activated after the `Stop` input has been activated.
|
@output On Stop: Activated after the `Stop` input has been activated.
|
||||||
"""
|
"""
|
||||||
bl_idname = 'LNDrawCameraTextureNode'
|
bl_idname = 'LNDrawCameraTextureNode'
|
||||||
bl_label = 'Draw Camera to Texture'
|
bl_label = 'Draw Camera to Texture'
|
||||||
lnx_section = 'draw'
|
lnx_section = 'draw'
|
||||||
lnx_version = 2
|
lnx_version = 1
|
||||||
|
|
||||||
def lnx_init(self, context):
|
def lnx_init(self, context):
|
||||||
self.add_input('LnxNodeSocketAction', 'Start')
|
self.add_input('LnxNodeSocketAction', 'Start')
|
||||||
@ -27,13 +26,6 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
|
|||||||
self.add_input('LnxNodeSocketObject', 'Camera')
|
self.add_input('LnxNodeSocketObject', 'Camera')
|
||||||
self.add_input('LnxNodeSocketObject', 'Object')
|
self.add_input('LnxNodeSocketObject', 'Object')
|
||||||
self.add_input('LnxIntSocket', 'Material Slot')
|
self.add_input('LnxIntSocket', 'Material Slot')
|
||||||
self.add_input('LnxStringSocket', 'Node')
|
|
||||||
|
|
||||||
self.add_output('LnxNodeSocketAction', 'On Start')
|
self.add_output('LnxNodeSocketAction', 'On Start')
|
||||||
self.add_output('LnxNodeSocketAction', 'On Stop')
|
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)
|
|
@ -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')
|
|
@ -1,15 +0,0 @@
|
|||||||
from lnx.logicnode.lnx_nodes import *
|
|
||||||
|
|
||||||
class GetCameraRenderFilterNode(LnxLogicTreeNode):
|
|
||||||
"""
|
|
||||||
Gets Camera Render Filter array with the names of the cameras
|
|
||||||
that can render the mesh. If null all cameras can render the mesh.
|
|
||||||
"""
|
|
||||||
bl_idname = 'LNGetCameraRenderFilterNode'
|
|
||||||
bl_label = 'Get Object Camera Render Filter'
|
|
||||||
lnx_section = 'camera'
|
|
||||||
lnx_version = 1
|
|
||||||
|
|
||||||
def lnx_init(self, context):
|
|
||||||
self.add_input('LnxNodeSocketObject', 'Object')
|
|
||||||
self.add_output('LnxNodeSocketArray', 'Array')
|
|
@ -1,29 +0,0 @@
|
|||||||
from lnx.logicnode.lnx_nodes import *
|
|
||||||
|
|
||||||
class SetCameraRenderFilterNode(LnxLogicTreeNode):
|
|
||||||
"""
|
|
||||||
Sets Camera Render Filter array with the names of the cameras
|
|
||||||
that can render the mesh. If null all cameras can render the mesh.
|
|
||||||
A camera can be added or removed from the arraw list.
|
|
||||||
"""
|
|
||||||
bl_idname = 'LNSetCameraRenderFilterNode'
|
|
||||||
bl_label = 'Set Object Camera Render Filter'
|
|
||||||
lnx_section = 'camera'
|
|
||||||
lnx_version = 1
|
|
||||||
|
|
||||||
property0: HaxeEnumProperty(
|
|
||||||
'property0',
|
|
||||||
items = [('Add', 'Add', 'Add'),
|
|
||||||
('Remove', 'Remove', 'Remove')],
|
|
||||||
name='', default='Add', update='')
|
|
||||||
|
|
||||||
|
|
||||||
def lnx_init(self, context):
|
|
||||||
self.add_input('LnxNodeSocketAction', 'In')
|
|
||||||
self.add_input('LnxNodeSocketObject', 'Object')
|
|
||||||
self.add_input('LnxNodeSocketObject', 'Camera')
|
|
||||||
|
|
||||||
self.add_output('LnxNodeSocketAction', 'Out')
|
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
|
||||||
layout.prop(self, 'property0')
|
|
@ -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')
|
|
@ -5,6 +5,8 @@ class WriteFileNode(LnxLogicTreeNode):
|
|||||||
"""Writes the given string content to the given file. If the file
|
"""Writes the given string content to the given file. If the file
|
||||||
already exists, the existing content of the file is overwritten.
|
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 File: the name of the file, relative to `Krom.getFilesLocation()`
|
||||||
@input Content: the content to write to the file.
|
@input Content: the content to write to the 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')
|
|
@ -5,6 +5,8 @@ class WriteJsonNode(LnxLogicTreeNode):
|
|||||||
"""Writes the given content to the given JSON file. If the file
|
"""Writes the given content to the given JSON file. If the file
|
||||||
already exists, the existing content of the file is overwritten.
|
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 File: the name of the file, relative to `Krom.getFilesLocation()`,
|
||||||
including the file extension.
|
including the file extension.
|
||||||
@input Dynamic: the content to write to the file. Can be any type that can
|
@input Dynamic: the content to write to the file. Can be any type that can
|
||||||
|
@ -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')
|
|
||||||
|
|
||||||
|
|
@ -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')
|
|
@ -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')
|
|
@ -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')
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user