Compare commits

..

1 commit

Author SHA1 Message Date
luboslenco c56fb4bbf1 Restore old grease pencil code 2019-10-14 21:21:11 +02:00
1263 changed files with 13275 additions and 50001 deletions

View file

@ -1,22 +0,0 @@
name: Krom
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Get Submodules
run: |
git clone https://github.com/armory3d/armory_ci
git clone --recursive https://github.com/armory3d/Kha.git armory_ci/Kha
git clone https://github.com/armory3d/iron.git armory_ci/Libraries/iron
git clone https://github.com/armory3d/armory.git armory_ci/Libraries/armory
git clone https://github.com/armory3d/nodejs_bin.git armory_ci/nodejs_bin
- name: Compile
run: |
cd armory_ci
nodejs_bin/node-linux64 Kha/make.js krom --shaderversion 330

View file

@ -1,6 +1,8 @@
armory
==============
[![Build Status](https://dev.azure.com/luboslenco/armory/_apis/build/status/armory3d.armory?branchName=master)](https://dev.azure.com/luboslenco/armory/_build/latest?definitionId=4&branchName=master)
[armory3d.org](https://armory3d.org) - [Manual](https://github.com/armory3d/armory/wiki) - [Roadmap](https://github.com/armory3d/armory/projects) - [Community](https://armory3d.org/community)
In development! Armory is an open-source 3D game engine with full Blender integration. The engine is currently available in a form of [early preview](http://armory3d.org/download.html).

View file

@ -4,29 +4,16 @@
uniform sampler2D tex;
#ifdef _CPostprocess
uniform vec3 PPComp10;
#endif
in vec2 texCoord;
out vec4 fragColor;
void main() {
vec3 col = textureLod(tex, texCoord, 0.0).rgb;
float brightness = dot(col, vec3(0.2126, 0.7152, 0.0722));
#ifdef _CPostprocess
if (brightness > PPComp10.z) {
fragColor.rgb = col;
}
else {
fragColor.rgb = vec3(0.0);
}
#else
if (brightness > bloomThreshold) {
fragColor.rgb = col;
}
else {
fragColor.rgb = vec3(0.0);
}
#endif
if (brightness > bloomThreshold) {
fragColor.rgb = col;
}
else {
fragColor.rgb = vec3(0.0);
}
}

View file

@ -5,13 +5,7 @@
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"links": [
{
"name": "PPComp10",
"link": "_PPComp10",
"ifdef": ["_CPostprocess"]
}
],
"links": [],
"texture_params": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "bloom_pass.frag.glsl"

View file

@ -7,32 +7,20 @@ uniform sampler2D tex;
uniform vec2 dir;
uniform vec2 screenSize;
#ifdef _CPostprocess
uniform vec3 PPComp11;
#endif
in vec2 texCoord;
out vec4 fragColor;
const float weight[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
void main() {
#ifdef _CPostprocess
vec2 step = (dir / screenSize.xy) * PPComp11.y;
#else
vec2 step = (dir / screenSize.xy) * bloomRadius;
#endif
vec2 step = (dir / screenSize.xy) * bloomRadius;
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb * weight[0];
for (int i = 1; i < 10; i++) {
vec2 s = step * (float(i) + 0.5);
fragColor.rgb += textureLod(tex, texCoord + s, 0.0).rgb * weight[i];
fragColor.rgb += textureLod(tex, texCoord - s, 0.0).rgb * weight[i];
}
#ifdef _CPostprocess
fragColor.rgb *= PPComp11.x / 5;
#else
fragColor.rgb *= bloomStrength / 5;
#endif
fragColor.rgb *= bloomStrength / 5;
fragColor.rgb = min(fragColor.rgb, 64.0);
}

View file

@ -13,11 +13,6 @@
{
"name": "screenSize",
"link": "_windowSize"
},
{
"name": "PPComp11",
"link": "_PPComp11",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],
@ -37,11 +32,6 @@
{
"name": "screenSize",
"link": "_windowSize"
},
{
"name": "PPComp11",
"link": "_PPComp11",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],
@ -64,11 +54,6 @@
{
"name": "screenSize",
"link": "_windowSize"
},
{
"name": "PPComp11",
"link": "_PPComp11",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],

View file

@ -4,10 +4,6 @@
uniform sampler2D tex;
#ifdef _CPostprocess
uniform vec3 PPComp13;
#endif
in vec2 texCoord;
out vec4 fragColor;
@ -40,22 +36,16 @@ vec4 spectrum_offset(float t) {
void main() {
#ifdef _CPostprocess
float max_distort = PPComp13.x;
int num_iter = int(PPComp13.y);
#else
float max_distort = compoChromaticStrength;
int num_iter = compoChromaticSamples;
#endif
float max_distort = compoChromaticStrength;
int num_iter = compoChromaticSamples;
float reci_num_iter_f = 1.0 / float(num_iter);
// Spectral
if (compoChromaticType == 1) {
float reci_num_iter_f = 1.0 / float(num_iter);
vec2 resolution = vec2(1,1);
vec2 uv = (texCoord.xy/resolution.xy);
vec4 sumcol = vec4(0.0);
vec4 sumw = vec4(0.0);
vec4 sumw = vec4(0.0);
for (int i=0; i < num_iter; ++i)
{
float t = float(i) * reci_num_iter_f;
@ -63,16 +53,17 @@ void main() {
sumw += w;
sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t));
}
fragColor = sumcol / sumw;
}
} else {
// Simple
else {
vec3 col = vec3(0.0);
col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x;
col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y;
col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z;
fragColor = vec4(col.x, col.y, col.z, fragColor.w);
}
}
}

View file

@ -6,13 +6,7 @@
"color_write_alpha": false,
"compare_mode": "always",
"cull_mode": "none",
"links": [
{
"name": "PPComp13",
"link": "_PPComp13",
"ifdef": ["_CPostprocess"]
}
],
"links": [],
"texture_params": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "chromatic_aberration_pass.frag.glsl"

View file

@ -1,9 +0,0 @@
#version 450
in vec2 texCoord;
out vec4 fragColor;
void main() {
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
gl_FragDepth = 1.0;
}

View file

@ -1,15 +0,0 @@
{
"contexts": [
{
"name": "clear_color_depth_pass",
"depth_write": true,
"compare_mode": "always",
"cull_mode": "none",
"links": [],
"texture_params": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "clear_color_depth_pass.frag.glsl",
"color_attachments": ["_HDR"]
}
]
}

View file

@ -1,8 +0,0 @@
#version 450
in vec2 texCoord;
out vec4 fragColor;
void main() {
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}

View file

@ -1,15 +0,0 @@
{
"contexts": [
{
"name": "clear_color_pass",
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"links": [],
"texture_params": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "clear_color_pass.frag.glsl",
"color_attachments": ["_HDR"]
}
]
}

View file

@ -1,19 +0,0 @@
{
"contexts": [
{
"name": "clear_depth_pass",
"depth_write": true,
"color_write_red": false,
"color_write_green": false,
"color_write_blue": false,
"color_write_alpha": false,
"compare_mode": "always",
"cull_mode": "none",
"links": [],
"texture_params": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "clear_depth_pass.frag.glsl",
"color_attachments": ["_HDR"]
}
]
}

View file

@ -6,9 +6,6 @@
#ifdef _CDOF
#include "std/dof.glsl"
#endif
#ifdef _CPostprocess
#include "std/colorgrading.glsl"
#endif
uniform sampler2D tex;
#ifdef _CDepth
@ -27,43 +24,6 @@ uniform sampler2D lutTexture;
uniform sampler2D histogram;
#endif
#ifdef _CPostprocess
uniform vec3 globalWeight;
uniform vec3 globalTint;
uniform vec3 globalSaturation;
uniform vec3 globalContrast;
uniform vec3 globalGamma;
uniform vec3 globalGain;
uniform vec3 globalOffset;
uniform vec3 shadowSaturation;
uniform vec3 shadowContrast;
uniform vec3 shadowGamma;
uniform vec3 shadowGain;
uniform vec3 shadowOffset;
uniform vec3 midtoneSaturation;
uniform vec3 midtoneContrast;
uniform vec3 midtoneGamma;
uniform vec3 midtoneGain;
uniform vec3 midtoneOffset;
uniform vec3 highlightSaturation;
uniform vec3 highlightContrast;
uniform vec3 highlightGamma;
uniform vec3 highlightGain;
uniform vec3 highlightOffset;
uniform vec3 PPComp1;
uniform vec3 PPComp2;
uniform vec3 PPComp3;
uniform vec3 PPComp4;
uniform vec3 PPComp5;
uniform vec3 PPComp6;
uniform vec3 PPComp7;
uniform vec3 PPComp8;
#endif
// #ifdef _CPos
// uniform vec3 eye;
// uniform vec3 eyeLook;
@ -117,25 +77,6 @@ vec3 applyFog(vec3 rgb, float distance) {
}
#endif
#ifdef _CPostprocess
float ComputeEV100(const float aperture2, const float shutterTime, const float ISO) {
return log2(aperture2 / shutterTime * 100.0 / ISO);
}
float ConvertEV100ToExposure(float EV100) {
return 1/0.8 * exp2(-EV100);
}
float ComputeEV(float avgLuminance) {
const float sqAperture = PPComp1[0].x * PPComp1.x;
const float shutterTime = 1.0 / PPComp1.y;
const float ISO = PPComp1.z;
const float EC = PPComp2.x;
float EV100 = ComputeEV100(sqAperture, shutterTime, ISO);
return ConvertEV100ToExposure(EV100 - EC) * PI;
}
#endif
vec4 LUTlookup(in vec4 textureColor, in sampler2D lookupTable) {
//Clamp to prevent weird results
@ -213,11 +154,7 @@ void main() {
#endif
#ifdef _CFishEye
#ifdef _CPostprocess
const float fishEyeStrength = -(PPComp2.y);
#else
const float fishEyeStrength = -0.01;
#endif
const float fishEyeStrength = -0.01;
const vec2 m = vec2(0.5, 0.5);
vec2 d = texCo - m;
float r = sqrt(dot(d, d));
@ -288,23 +225,7 @@ void main() {
#else
#ifdef _CDOF
#ifdef _CPostprocess
bool compoAutoFocus = false;
float compoDistance = PPComp3.x;
float compoLength = PPComp3.y;
float compoStop = PPComp3.z;
if (PPComp2.z == 1){
compoAutoFocus = true;
} else {
compoAutoFocus = false;
}
fragColor.rgb = dof(texCo, depth, tex, gbufferD, texStep, cameraProj, compoAutoFocus, compoDistance, compoLength, compoStop);
#else
fragColor.rgb = dof(texCo, depth, tex, gbufferD, texStep, cameraProj, true, compoDOFDistance, compoDOFLength, compoDOFFstop);
#endif
fragColor = vec4(dof(texCo, depth, tex, gbufferD, texStep, cameraProj), 1.0);
#else
fragColor = textureLod(tex, texCo, 0.0);
#endif
@ -350,11 +271,7 @@ void main() {
#ifdef _CGrain
// const float compoGrainStrength = 4.0;
float x = (texCo.x + 4.0) * (texCo.y + 4.0) * (time * 10.0);
#ifdef _CPostprocess
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * PPComp4.y;
#else
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * compoGrainStrength;
#endif
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * compoGrainStrength;
#endif
#ifdef _CGrainStatic
@ -370,96 +287,28 @@ void main() {
fragColor.rgb += fragColor.rgb * compoExposureStrength;
#endif
#ifdef _CPostprocess
fragColor.rgb *= ComputeEV(0.0);
#endif
#ifdef _AutoExposure
float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0);
fragColor.rgb *= pow(expo, autoExposureStrength * 2.0);
#endif
#ifdef _CPostprocess
#ifdef _CToneCustom
fragColor.rgb = clamp((fragColor.rgb * (PPComp4.z * fragColor.rgb + PPComp5.x)) / (fragColor.rgb * (PPComp5.y * fragColor.rgb + PPComp5.z) + PPComp6.x), 0.0, 1.0);
#else
if(PPComp4.x == 0){ //Filmic 1
fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma
} else if (PPComp4.x == 1){ //Filmic 2
fragColor.rgb = acesFilm(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
} else if (PPComp4.x == 2){ //Reinhard
fragColor.rgb = tonemapReinhard(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
} else if (PPComp4.x == 3){ //Uncharted2
fragColor.rgb = tonemapUncharted2(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
fragColor.rgb = clamp(fragColor.rgb, 0.0, 1.0);
} else if (PPComp4.x == 4){ //None
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
} else if (PPComp4.x == 5){ //Non-Gamma / Linear
fragColor.rgb = fragColor.rgb;
} else if (PPComp4.x == 6){ //HDP
vec3 x = fragColor.rgb - 0.004;
//vec3 x = max(0, fragColor.rgb - 0.004);
fragColor.rgb = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
} else if (PPComp4.x == 7){ //Raw
vec4 vh = vec4(fragColor.rgb, 1);
vec4 va = (1.425 * vh) + 0.05;
vec4 vf = ((vh * va + 0.004) / ((vh * (va + 0.55) + 0.0491))) - 0.0821;
fragColor.rgb = vf.rgb / vf.www;
} else if (PPComp4.x == 8){ //False Colors for luminance control
vec4 c = vec4(fragColor.r,fragColor.g,fragColor.b,0); //Linear without gamma
vec3 luminanceVector = vec3(0.2125, 0.7154, 0.0721); //Relative Luminance Vector
float luminance = dot(luminanceVector, c.xyz);
vec3 maxLumColor = vec3(1,0,0); //High values (> 1.0)
//float maxLum = 2.0; Needs to read the highest pixel, but I don't know how to yet
//Probably easier with a histogram too, once it's it in place?
vec3 midLumColor = vec3(0,1,0); //Mid values (< 1.0)
float midLum = 1.0;
vec3 minLumColor = vec3(0,0,1); //Low values (< 1.0)
float minLum = 0.0;
if(luminance < midLum){
fragColor.rgb = mix(minLumColor, midLumColor, luminance);
} else {
fragColor.rgb = mix(midLumColor, maxLumColor, luminance);
}
} else {
fragColor.rgb = vec3(0,1,0); //ERROR
}
#endif
#else
#ifdef _CToneFilmic
fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma
#endif
#ifdef _CToneFilmic2
fragColor.rgb = acesFilm(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
#endif
#ifdef _CToneReinhard
fragColor.rgb = tonemapReinhard(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
#endif
#ifdef _CToneUncharted
fragColor.rgb = tonemapUncharted2(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
fragColor.rgb = clamp(fragColor.rgb, 0.0, 2.2);
#endif
#ifdef _CToneNone
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
#endif
#ifdef _CToneCustom
fragColor.rgb = clamp((fragColor.rgb * (1 * fragColor.rgb + 1)) / (fragColor.rgb * (1 * fragColor.rgb + 1 ) + 1), 0.0, 1.0);
#endif
#ifdef _CToneFilmic
fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma
#endif
#ifdef _CToneFilmic2
fragColor.rgb = acesFilm(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
#endif
#ifdef _CToneReinhard
fragColor.rgb = tonemapReinhard(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
#endif
#ifdef _CToneUncharted
fragColor.rgb = tonemapUncharted2(fragColor.rgb);
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
#endif
#ifdef _CToneNone
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
#endif
#ifdef _CBW
@ -477,83 +326,16 @@ void main() {
// fragColor.rgb += compoBrightness;
// #endif
#ifdef _CPostprocess
//Global Values
float factor = 1;
float colorTempK = globalWeight.x;
vec3 ColorTempRGB = ColorTemperatureToRGB(colorTempK);
float originalLuminance = Luminance(fragColor.rgb);
vec3 blended = mix(fragColor.rgb, fragColor.rgb * ColorTempRGB, factor);
vec3 resultHSL = RGBtoHSL(blended);
vec3 luminancePreservedRGB = HSLtoRGB(vec3(resultHSL.x, resultHSL.y, originalLuminance));
fragColor = vec4(mix(blended, luminancePreservedRGB, LUMINANCE_PRESERVATION), 1.0);
mat3 CCSaturation = mat3 ( //Saturation
globalSaturation.r * shadowSaturation.r, globalSaturation.g * shadowSaturation.g, globalSaturation.b * shadowSaturation.b, //Shadows + Global
globalSaturation.r * midtoneSaturation.r, globalSaturation.g * midtoneSaturation.g, globalSaturation.b * midtoneSaturation.b, //Midtones + Global
globalSaturation.r * highlightSaturation.r, globalSaturation.g * highlightSaturation.g, globalSaturation.b * highlightSaturation.b //Highlights + Global
);
mat3 CCContrast = mat3 (
globalContrast.r * shadowContrast.r, globalContrast.g * shadowContrast.g, globalContrast.b * shadowContrast.b, //Shadows + Global
globalContrast.r * midtoneContrast.r, globalContrast.g * midtoneContrast.g, globalContrast.b * midtoneContrast.b, //Midtones + Global
globalContrast.r * highlightContrast.r, globalContrast.g * highlightContrast.g, globalContrast.b * highlightContrast.b //Highlights + Global
);
mat3 CCGamma = mat3 (
globalGamma.r * shadowGamma.r, globalGamma.g * shadowGamma.g, globalGamma.b * shadowGamma.b, //Shadows + Global
globalGamma.r * midtoneGamma.r, globalGamma.g * midtoneGamma.g, globalGamma.b * midtoneGamma.b, //Midtones + Global
globalGamma.r * highlightGamma.r, globalGamma.g * highlightGamma.g, globalGamma.b * highlightGamma.b //Highlights + Global
);
mat3 CCGain = mat3 (
globalGain.r * shadowGain.r, globalGain.g * shadowGain.g, globalGain.b * shadowGain.b, //Shadows + Global
globalGain.r * midtoneGain.r, globalGain.g * midtoneGain.g, globalGain.b * midtoneGain.b, //Midtones + Global
globalGain.r * highlightGain.r, globalGain.g * highlightGain.g, globalGain.b * highlightGain.b //Highlights + Global
);
mat3 CCOffset = mat3 (
globalOffset.r * shadowOffset.r, globalOffset.g * shadowOffset.g, globalOffset.b * shadowOffset.b, //Shadows + Global
globalOffset.r * midtoneOffset.r, globalOffset.g * midtoneOffset.g, globalOffset.b * midtoneOffset.b, //Midtones + Global
globalOffset.r * highlightOffset.r, globalOffset.g * highlightOffset.g, globalOffset.b * highlightOffset.b //Highlights + Global
);
vec2 ToneWeights = vec2(globalWeight.y, globalWeight.z);
fragColor.rgb = FinalizeColorCorrection(
fragColor.rgb,
CCSaturation,
CCContrast,
CCGamma,
CCGain,
CCOffset,
ToneWeights
);
//Tint
fragColor.rgb *= vec3(globalTint.r,globalTint.g,globalTint.b);
#endif
#ifdef _CLensTex
#ifdef _CLensTexMasking
vec4 scratches = texture(lensTexture, texCo);
vec3 scratchBlend = fragColor.rgb + scratches.rgb;
#ifdef _CPostprocess
float centerMaxClip = PPComp6.y;
float centerMinClip = PPComp6.z;
float luminanceMax = PPComp7.x;
float luminanceMin = PPComp7.y;
float brightnessExp = PPComp7.z;
#else
float centerMaxClip = compoCenterMaxClip;
float centerMinClip = compoCenterMinClip;
float luminanceMax = compoLuminanceMax;
float luminanceMin = compoLuminanceMin;
float brightnessExp = compoBrightnessExponent;
#endif
float centerMaxClip = compoCenterMaxClip;
float centerMinClip = compoCenterMinClip;
float luminanceMax = compoLuminanceMax;
float luminanceMin = compoLuminanceMin;
float brightnessExp = compoBrightnessExponent;
float center = smoothstep(centerMaxClip, centerMinClip, length(texCo - 0.5));
float luminance = dot(fragColor.rgb, vec3(0.299, 0.587, 0.114));

View file

@ -75,156 +75,6 @@
"name": "lutTexture",
"link": "$luttexture.jpg",
"ifdef": ["_CLUT"]
},
{
"name": "globalWeight",
"link": "_globalWeight",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalTint",
"link": "_globalTint",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalSaturation",
"link": "_globalSaturation",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalContrast",
"link": "_globalContrast",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalGamma",
"link": "_globalGamma",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalGain",
"link": "_globalGain",
"ifdef": ["_CPostprocess"]
},
{
"name": "globalOffset",
"link": "_globalOffset",
"ifdef": ["_CPostprocess"]
},
{
"name": "shadowSaturation",
"link": "_shadowSaturation",
"ifdef": ["_CPostprocess"]
},
{
"name": "shadowContrast",
"link": "_shadowContrast",
"ifdef": ["_CPostprocess"]
},
{
"name": "shadowGamma",
"link": "_shadowGamma",
"ifdef": ["_CPostprocess"]
},
{
"name": "shadowGain",
"link": "_shadowGain",
"ifdef": ["_CPostprocess"]
},
{
"name": "shadowOffset",
"link": "_shadowOffset",
"ifdef": ["_CPostprocess"]
},
{
"name": "midtoneSaturation",
"link": "_midtoneSaturation",
"ifdef": ["_CPostprocess"]
},
{
"name": "midtoneContrast",
"link": "_midtoneContrast",
"ifdef": ["_CPostprocess"]
},
{
"name": "midtoneGamma",
"link": "_midtoneGamma",
"ifdef": ["_CPostprocess"]
},
{
"name": "midtoneGain",
"link": "_midtoneGain",
"ifdef": ["_CPostprocess"]
},
{
"name": "midtoneOffset",
"link": "_midtoneOffset",
"ifdef": ["_CPostprocess"]
},
{
"name": "highlightSaturation",
"link": "_highlightSaturation",
"ifdef": ["_CPostprocess"]
},
{
"name": "highlightContrast",
"link": "_highlightContrast",
"ifdef": ["_CPostprocess"]
},
{
"name": "highlightGamma",
"link": "_highlightGamma",
"ifdef": ["_CPostprocess"]
},
{
"name": "highlightGain",
"link": "_highlightGain",
"ifdef": ["_CPostprocess"]
},
{
"name": "highlightOffset",
"link": "_highlightOffset",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp1",
"link": "_PPComp1",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp2",
"link": "_PPComp2",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp3",
"link": "_PPComp3",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp4",
"link": "_PPComp4",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp5",
"link": "_PPComp5",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp6",
"link": "_PPComp6",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp7",
"link": "_PPComp7",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp8",
"link": "_PPComp8",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],

View file

@ -18,7 +18,7 @@ void main() {
// Scale vertex attribute to [0-1] range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif
@ -26,7 +26,7 @@ void main() {
// #ifdef _CPos
// NDC (at the back of cube)
// vec4 v = vec4(pos.xy, 1.0, 1.0);
// vec4 v = vec4(pos.xy, 1.0, 1.0);
// v = vec4(invVP * v);
// v.xyz /= v.w;
// viewRay = v.xyz - eye;

View file

@ -1,31 +0,0 @@
#version 450
// Include functions for gbuffer operations (packFloat2() etc.)
#include "../std/gbuffer.glsl"
// World-space normal from the vertex shader stage
in vec3 wnormal;
// Gbuffer output. Deferred rendering uses the following layout:
// [0]: normal x normal y roughness metallic/matID
// [1]: base color r base color g base color b occlusion/specular
out vec4 fragColor[2];
void main() {
// Pack normals into 2 components to fit into the gbuffer
vec3 n = normalize(wnormal);
n /= (abs(n.x) + abs(n.y) + abs(n.z));
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
// Define PBR material values
vec3 basecol = vec3(1.0);
float roughness = 0.0;
float metallic = 0.0;
float occlusion = 1.0;
float specular = 1.0;
uint materialId = 0;
// Store in gbuffer (see layout table above)
fragColor[0] = vec4(n.xy, roughness, packFloatInt16(metallic, materialId));
fragColor[1] = vec4(basecol.rgb, packFloat2(occlusion, specular));
}

View file

@ -1,20 +0,0 @@
#version 450
// World to view projection matrix to correctly position the vertex on screen
uniform mat4 WVP;
// Matrix to transform normals from local into world space
uniform mat3 N;
// Position and normal vectors of the current vertex in local space
// Armory packs the vertex data to preserve memory, so nor.z values are
// saved in pos.w
in vec4 pos; // pos.xyz, nor.w
in vec2 nor; // nor.xy
// Normal vector in world space
out vec3 wnormal;
void main() {
wnormal = normalize(N * vec3(nor.xy, pos.w));
gl_Position = WVP * vec4(pos.xyz, 1.0);
}

View file

@ -1,9 +0,0 @@
#version 450
// Color of each fragment on the screen
out vec4 fragColor;
void main() {
// Shadeless white color
fragColor = vec4(1.0);
}

View file

@ -1,11 +0,0 @@
#version 450
// World to view projection matrix to correctly position the vertex on screen
uniform mat4 WVP;
// Position vector of the current vertex in local space
in vec3 pos;
void main() {
gl_Position = WVP * vec4(pos, 1.0);
}

View file

@ -3,10 +3,10 @@
in vec3 pos;
in vec3 col;
uniform mat4 ViewProjection;
uniform mat4 VP;
out vec3 color;
void main() {
color = col;
gl_Position = ViewProjection * vec4(pos, 1.0);
gl_Position = VP * vec4(pos, 1.0);
}

View file

@ -2,6 +2,7 @@
#include "compiled.inc"
#include "std/gbuffer.glsl"
#include "std/light.glsl"
#ifdef _Clusters
#include "std/clusters.glsl"
#endif
@ -21,9 +22,6 @@
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
#ifdef _gbuffer2
uniform sampler2D gbuffer2;
#endif
#ifdef _VoxelAOvar
uniform sampler3D voxels;
@ -38,7 +36,7 @@ uniform vec3 eyeSnap;
uniform float envmapStrength;
#ifdef _Irr
uniform vec4 shirr[7];
//!uniform vec4 shirr[7];
#endif
#ifdef _Brdf
uniform sampler2D senvmapBrdf;
@ -82,11 +80,14 @@ uniform mat4 invVP;
#ifdef _ShadowMap
#ifdef _SinglePoint
//!uniform sampler2DShadow shadowMapSpot[1];
//!uniform mat4 LWVPSpot[1];
//!uniform mat4 LWVPSpot0;
#endif
#ifdef _Clusters
//!uniform sampler2DShadow shadowMapSpot[4];
//!uniform mat4 LWVPSpotArray[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;
//!uniform mat4 LWVPSpot3;
#endif
#endif
#endif
@ -96,7 +97,7 @@ uniform vec3 eye;
uniform vec3 eyeLook;
#ifdef _Clusters
uniform vec4 lightsArray[maxLights * 3];
uniform vec4 lightsArray[maxLights * 2];
#ifdef _Spot
uniform vec4 lightsArraySpot[maxLights];
#endif
@ -108,36 +109,21 @@ uniform vec2 cameraPlane;
#ifdef _SinglePoint
#ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[1];
//!uniform mat4 LWVPSpot[1];
//!uniform mat4 LWVPSpot0;
#else
//!uniform samplerCubeShadow shadowMapPoint[1];
//!uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
#ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlas;
#endif
#endif
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasPoint;
#endif
//!uniform vec4 pointLightDataArray[4];
#else
//!uniform samplerCubeShadow shadowMapPoint[4];
#endif
//!uniform samplerCubeShadow shadowMapPoint[4];
//!uniform vec2 lightProj;
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasSpot;
#endif
#else
//!uniform sampler2DShadow shadowMapSpot[4];
#endif
//!uniform mat4 LWVPSpotArray[4];
//!uniform sampler2DShadow shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;
//!uniform mat4 LWVPSpot3;
#endif
#endif
#endif
@ -146,13 +132,7 @@ uniform vec2 cameraPlane;
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun;
#endif
#else
uniform sampler2DShadow shadowMap;
#endif
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
@ -179,15 +159,13 @@ uniform sampler2D texClouds;
uniform float time;
#endif
#include "std/light.glsl"
in vec2 texCoord;
in vec3 viewRay;
out vec4 fragColor;
void main() {
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, metallic/roughness, matid
vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
@ -208,10 +186,6 @@ void main() {
vec3 v = normalize(eye - p);
float dotNV = max(dot(n, v), 0.0);
#ifdef _gbuffer2
vec4 g2 = textureLod(gbuffer2, texCoord, 0.0);
#endif
#ifdef _MicroShadowing
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
#endif
@ -222,19 +196,9 @@ void main() {
// Envmap
#ifdef _Irr
vec3 envl = shIrradiance(n, shirr);
#ifdef _gbuffer2
if (g2.b < 0.5) {
envl = envl;
} else {
envl = vec3(1.0);
}
#endif
vec3 envl = shIrradiance(n);
#ifdef _EnvTex
envl /= PI;
envl /= PI;
#endif
#else
vec3 envl = vec3(1.0);
@ -254,7 +218,7 @@ void main() {
#endif
envl.rgb *= albedo;
#ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5 * occspec.y;
#else
@ -272,7 +236,7 @@ void main() {
#else
vec3 voxpos = p / voxelgiHalfExtents;
#endif
#ifndef _VoxelAONoTrace
#ifdef _VoxelGITemporal
envl.rgb *= 1.0 - (traceAO(voxpos, n, voxels) * voxelBlend +
@ -281,7 +245,7 @@ void main() {
envl.rgb *= 1.0 - traceAO(voxpos, n, voxels);
#endif
#endif
#endif
fragColor.rgb = envl;
@ -295,7 +259,7 @@ void main() {
#endif
#ifdef _Emission
if (matid == 1) {
if (g0.a == 1.0) {
fragColor.rgb += g1.rgb; // materialid
albedo = vec3(0.0);
}
@ -308,7 +272,7 @@ void main() {
// for(uint step = 0; step < 400 && color.a < 0.99f; ++step) {
// vec3 point = origin + 0.005 * step * direction;
// color += (1.0f - color.a) * textureLod(voxels, point * 0.5 + 0.5, 0);
// }
// }
// fragColor.rgb += color.rgb;
// Show SSAO
@ -325,32 +289,10 @@ void main() {
#ifdef _ShadowMap
#ifdef _CSM
svisibility = shadowTestCascade(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
, eye, p + n * shadowsBias * 10, shadowsBias
);
svisibility = shadowTestCascade(shadowMap, eye, p + n * shadowsBias * 10, shadowsBias);
#else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) svisibility = shadowTest(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
, lPos.xyz / lPos.w, shadowsBias
);
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) svisibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias);
#endif
#endif
@ -378,7 +320,7 @@ void main() {
fragColor.rgb += sdirect * svisibility * sunCol;
// #ifdef _Hair // Aniso
// if (matid == 2) {
// if (g0.a == 2.0) {
// const float shinyParallel = roughness;
// const float shinyPerpendicular = 0.1;
// const vec3 v = vec3(0.99146, 0.11664, 0.05832);
@ -388,23 +330,12 @@ void main() {
// #endif
#ifdef _SSS
if (matid == 2) {
if (g0.a == 2.0) {
#ifdef _CSM
int casi, casindex;
mat4 LWVP = getCascadeMat(distance(eye, p), casi, casindex);
#endif
fragColor.rgb += fragColor.rgb * SSSSTransmittance(
LWVP, p, n, sunDir, lightPlane.y,
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
);
fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVP, p, n, sunDir, lightPlane.y, shadowMap);
}
#endif
@ -415,7 +346,7 @@ void main() {
fragColor.rgb += sampleLight(
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
#ifdef _ShadowMap
, 0, pointBias, true
, 0, pointBias
#endif
#ifdef _Spot
, true, spotData.x, spotData.y, spotDir
@ -432,12 +363,12 @@ void main() {
, gbufferD, invVP, eye
#endif
);
#ifdef _Spot
#ifdef _SSS
if (matid == 2) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVPSpot0, p, n, normalize(pointPos - p), lightPlane.y, shadowMapSpot[0]);
#endif
if (g0.a == 2.0) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVPSpot0, p, n, normalize(pointPos - p), lightPlane.y, shadowMapSpot[0]);
#endif
#endif
#endif
@ -462,19 +393,18 @@ void main() {
n,
v,
dotNV,
lightsArray[li * 3].xyz, // lp
lightsArray[li * 3 + 1].xyz, // lightCol
lightsArray[li * 2].xyz, // lp
lightsArray[li * 2 + 1].xyz, // lightCol
albedo,
roughness,
occspec.y,
f0
#ifdef _ShadowMap
// light index, shadow bias, cast_shadows
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0
, li, lightsArray[li * 2].w // bias
#endif
#ifdef _Spot
, lightsArray[li * 3 + 2].y != 0.0
, lightsArray[li * 3 + 2].y // cutoff
, li > numPoints - 1
, lightsArray[li * 2 + 1].w // cutoff
, lightsArraySpot[li].w // cutoff - exponent
, lightsArraySpot[li].xyz // spotDir
#endif

View file

@ -99,7 +99,7 @@
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrixSun",
"link": "_biasLightWorldViewProjectionMatrix",
"ifndef": ["_CSM"],
"ifdef": ["_Sun", "_ShadowMap"]
},
@ -199,43 +199,48 @@
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpotArray",
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
},
{
"name": "pointLightDataArray",
"link": "_pointLightsAtlasArray",
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
},
{
"name": "LWVPSpot[0]",
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[1]",
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[2]",
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot[3]",
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
}
],
"vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "deferred_light.frag.glsl",
"color_attachments": ["RGBA64"]
"fragment_shader": "deferred_light.frag.glsl"
}
]
}

View file

@ -3,6 +3,7 @@
#include "compiled.inc"
#include "std/gbuffer.glsl"
#include "std/math.glsl"
#include "std/light_mobile.glsl"
#ifdef _Clusters
#include "std/clusters.glsl"
#endif
@ -16,7 +17,7 @@ uniform sampler2D gbuffer1;
uniform float envmapStrength;
#ifdef _Irr
uniform vec4 shirr[7];
//!uniform vec4 shirr[7];
#endif
#ifdef _Brdf
uniform sampler2D senvmapBrdf;
@ -29,15 +30,12 @@ uniform int envmapNumMipmaps;
uniform vec3 backgroundCol;
#endif
#ifdef _SMSizeUniform
//!uniform vec2 smSizeUniform;
#endif
uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
#ifdef _Clusters
uniform vec4 lightsArray[maxLights * 3];
uniform vec4 lightsArray[maxLights * 2];
#ifdef _Spot
uniform vec4 lightsArraySpot[maxLights];
#endif
@ -49,36 +47,21 @@ uniform vec2 cameraPlane;
#ifdef _SinglePoint
#ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[1];
//!uniform mat4 LWVPSpot[1];
//!uniform mat4 LWVPSpot0;
#else
//!uniform samplerCubeShadow shadowMapPoint[1];
//!uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
#ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlas;
#endif
#endif
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasPoint;
#endif
//!uniform vec4 pointLightDataArray[4];
#else
//!uniform samplerCubeShadow shadowMapPoint[4];
#endif
//!uniform samplerCubeShadow shadowMapPoint[4];
//!uniform vec2 lightProj;
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasSpot;
#endif
#else
//!uniform sampler2DShadow shadowMapSpot[4];
#endif
//!uniform mat4 LWVPSpotArray[4];
//!uniform sampler2DShadow shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;
//!uniform mat4 LWVPSpot3;
#endif
#endif
#endif
@ -87,13 +70,7 @@ uniform vec2 cameraPlane;
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun;
#endif
#else
uniform sampler2DShadow shadowMap;
#endif
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
@ -113,15 +90,13 @@ uniform float pointBias;
#endif
#endif
#include "std/light_mobile.glsl"
in vec2 texCoord;
in vec3 viewRay;
out vec4 fragColor;
void main() {
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, metallic/roughness, depth
vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
@ -148,7 +123,7 @@ void main() {
// Envmap
#ifdef _Irr
vec3 envl = shIrradiance(n, shirr);
vec3 envl = shIrradiance(n);
#ifdef _EnvTex
envl /= PI;
#endif
@ -170,7 +145,7 @@ void main() {
#endif
envl.rgb *= albedo;
#ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5 * occspec.y;
#else
@ -193,32 +168,10 @@ void main() {
#ifdef _ShadowMap
#ifdef _CSM
svisibility = shadowTestCascade(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
, eye, p + n * shadowsBias * 10, shadowsBias
);
svisibility = shadowTestCascade(shadowMap, eye, p + n * shadowsBias * 10, shadowsBias, shadowmapSize * vec2(shadowmapCascades, 1.0));
#else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) svisibility = shadowTest(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
, lPos.xyz / lPos.w, shadowsBias
);
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) svisibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias, shadowmapSize);
#endif
#endif
@ -229,7 +182,7 @@ void main() {
fragColor.rgb += sampleLight(
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
#ifdef _ShadowMap
, 0, pointBias, true
, 0, pointBias
#endif
#ifdef _Spot
, true, spotData.x, spotData.y, spotDir
@ -258,19 +211,18 @@ void main() {
n,
v,
dotNV,
lightsArray[li * 3].xyz, // lp
lightsArray[li * 3 + 1].xyz, // lightCol
lightsArray[li * 2].xyz, // lp
lightsArray[li * 2 + 1].xyz, // lightCol
albedo,
roughness,
occspec.y,
f0
#ifdef _ShadowMap
// light index, shadow bias, cast_shadows
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0
, li, lightsArray[li * 2].w // bias
#endif
#ifdef _Spot
, lightsArray[li * 3 + 2].y != 0.0
, lightsArray[li * 3 + 2].y // cutoff
, li > numPoints - 1
, lightsArray[li * 2 + 1].w // cutoff
, lightsArraySpot[li].w // cutoff - exponent
, lightsArraySpot[li].xyz // spotDir
#endif

View file

@ -88,7 +88,7 @@
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrixSun",
"link": "_biasLightWorldViewProjectionMatrix",
"ifndef": ["_CSM"],
"ifdef": ["_Sun", "_ShadowMap"]
},
@ -107,11 +107,6 @@
"link": "_viewProjectionMatrix",
"ifdef": ["_SSRS"]
},
{
"name": "smSizeUniform",
"link": "_shadowMapSize",
"ifdef": ["_SMSizeUniform"]
},
{
"name": "lightProj",
"link": "_lightPlaneProj",
@ -143,43 +138,28 @@
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpotArray",
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
},
{
"name": "pointLightDataArray",
"link": "_pointLightsAtlasArray",
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
},
{
"name": "LWVPSpot[0]",
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[1]",
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[2]",
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[3]",
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
"ifdef": ["_Spot", "_ShadowMap"]
}
],
"vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "deferred_light.frag.glsl",
"color_attachments": ["RGBA64"]
"fragment_shader": "deferred_light.frag.glsl"
}
]
}

View file

@ -7,8 +7,7 @@
"cull_mode": "none",
"links": [],
"vertex_shader": "../include/pass.vert.glsl",
"fragment_shader": "deferred_light.frag.glsl",
"color_attachments": ["RGBA64"]
"fragment_shader": "deferred_light.frag.glsl"
}
]
}

View file

@ -1,8 +1,9 @@
#version 450
in vec2 texCoord;
in vec4 color;
out vec4 fragColor;
void main() {
gl_FragDepth = 1.0;
fragColor = color;
}

View file

@ -0,0 +1,25 @@
{
"contexts": [
{
"name": "grease_pencil",
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"blend_source": "source_alpha",
"blend_destination": "inverse_source_alpha",
"blend_operation": "add",
"alpha_blend_source": "source_alpha",
"alpha_blend_destination": "inverse_source_alpha",
"alpha_blend_operation": "add",
"links": [
{
"name": "VP",
"link": "_viewProjectionMatrix"
}
],
"texture_params": [],
"vertex_shader": "grease_pencil.vert.glsl",
"fragment_shader": "grease_pencil.frag.glsl"
}
]
}

View file

@ -0,0 +1,13 @@
#version 450
in vec3 pos;
in vec4 col;
out vec4 color;
uniform mat4 VP;
void main() {
color = col;
gl_Position = VP * vec4(pos.xyz, 1.0);
}

View file

@ -10,7 +10,7 @@ void main() {
// Scale vertex attribute to 0-1 range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif

View file

@ -14,7 +14,7 @@ void main() {
// Scale vertex attribute to [0-1] range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif

View file

@ -13,14 +13,14 @@ void main() {
// Scale vertex attribute to [0-1] range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif
gl_Position = vec4(pos.xy, 0.0, 1.0);
// NDC (at the back of cube)
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
v = vec4(invP * v);
viewRay = vec3(v.xy / v.z, 1.0);
}

View file

@ -18,7 +18,7 @@ in vec3 viewRay;
out vec4 fragColor;
vec2 getVelocity(vec2 coord, float depth) {
#ifdef _InvY
#ifdef HLSL
coord.y = 1.0 - coord.y;
#endif
vec4 currentPos = vec4(coord.xy * 2.0 - 1.0, depth, 1.0);
@ -26,7 +26,7 @@ vec2 getVelocity(vec2 coord, float depth) {
vec4 previousPos = prevVP * worldPos;
previousPos /= previousPos.w;
vec2 velocity = (currentPos - previousPos).xy / 40.0;
#ifdef _InvY
#ifdef HLSL
velocity.y = -velocity.y;
#endif
return velocity;
@ -34,7 +34,7 @@ vec2 getVelocity(vec2 coord, float depth) {
void main() {
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb;
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (depth == 1.0) {
return;
@ -42,7 +42,7 @@ void main() {
float blurScale = motionBlurIntensity * frameScale;
vec2 velocity = getVelocity(texCoord, depth) * blurScale;
vec2 offset = texCoord;
int processed = 1;
for(int i = 0; i < 8; ++i) {

View file

@ -14,11 +14,11 @@ out vec4 fragColor;
void main() {
vec2 velocity = textureLod(sveloc, texCoord, 0.0).rg * motionBlurIntensity * frameScale;
#ifdef _InvY
#ifdef HLSL
velocity.y = -velocity.y;
#endif
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb;
// float speed = length(velocity / texStep);

View file

@ -17,7 +17,7 @@ out vec4 fragColor;
void main() {
vec2 texCoord = wvpposition.xy / wvpposition.w;
texCoord = texCoord * 0.5 + 0.5;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif
@ -46,7 +46,7 @@ void main() {
vec3 v = wp - eye;
vec3 r = reflect(v, n);
#ifdef _InvY
#ifdef HLSL
r.y = -r.y;
#endif
float intensity = clamp((1.0 - roughness) * dot(wp - probep, n), 0.0, 1.0);

View file

@ -17,7 +17,7 @@ out vec4 fragColor;
void main() {
vec2 texCoord = wvpposition.xy / wvpposition.w;
texCoord = texCoord * 0.5 + 0.5;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif
@ -39,7 +39,7 @@ void main() {
vec3 wp = getPos2(invVP, depth, texCoord);
vec4 pp = probeVP * vec4(wp.xyz, 1.0);
vec2 tc = (pp.xy / pp.w) * 0.5 + 0.5;
#ifdef _InvY
#ifdef HLSL
tc.y = 1.0 - tc.y;
#endif

View file

@ -1,6 +1,5 @@
#version 450
#include "compiled.inc"
#define SMAA_MAX_SEARCH_STEPS_DIAG 8
#define SMAA_AREATEX_MAX_DISTANCE 16
#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20
@ -34,7 +33,7 @@ out vec4 fragColor;
vec2 cdw_end;
vec4 textureLodA(sampler2D tex, vec2 coord, float lod) {
#ifdef _InvY
#ifdef HLSL
coord.y = 1.0 - coord.y;
#endif
return textureLod(tex, coord, lod);
@ -105,7 +104,7 @@ vec2 SMAASearchDiag2(vec2 texcoord, vec2 dir) {
return coord.zw;
}
/**
/**
* Similar to SMAAArea, this calculates the area corresponding to a certain
* diagonal distance and crossing edges 'e'.
*/
@ -148,7 +147,7 @@ vec2 SMAACalculateDiagWeights(vec2 texcoord, vec2 e, vec4 subsampleIndices) {
// Fetch the crossing edges:
vec4 coords = mad(vec4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), screenSizeInv.xyxy, texcoord.xyxy);
vec4 c;
c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).rg;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).rg;
c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw);
@ -173,7 +172,7 @@ vec2 SMAACalculateDiagWeights(vec2 texcoord, vec2 e, vec4 subsampleIndices) {
d.yw = SMAASearchDiag2(texcoord, vec2(1.0, 1.0)/*, cdw_end*/);
float dadd = cdw_end.y > 0.9 ? 1.0 : 0.0;
d.y += dadd;
}
}
else {
d.yw = vec2(0.0, 0.0);
}
@ -208,7 +207,7 @@ vec2 SMAACalculateDiagWeights(vec2 texcoord, vec2 e, vec4 subsampleIndices) {
/**
* This allows to determine how much length should we add in the last step
* of the searches. It takes the bilinearly interpolated edge (see
* of the searches. It takes the bilinearly interpolated edge (see
* @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and
* crossing edges are active.
*/
@ -245,7 +244,7 @@ float SMAASearchXLeft(vec2 texcoord, float end) {
* which edges are active from the four fetched ones.
*/
vec2 e = vec2(0.0, 1.0);
while (texcoord.x > end &&
while (texcoord.x > end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e = textureLodA(edgesTex, texcoord, 0.0).rg;
@ -258,20 +257,20 @@ float SMAASearchXLeft(vec2 texcoord, float end) {
float SMAASearchXRight(vec2 texcoord, float end) {
vec2 e = vec2(0.0, 1.0);
while (texcoord.x < end &&
while (texcoord.x < end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e = textureLodA(edgesTex, texcoord, 0.0).rg;
texcoord = mad(vec2(2.0, 0.0), screenSizeInv.xy, texcoord);
}
float offset = mad(-(255.0 / 127.0), SMAASearchLength(e, 0.5), 3.25);
return mad(-screenSizeInv.x, offset, texcoord.x);
}
float SMAASearchYUp(vec2 texcoord, float end) {
vec2 e = vec2(1.0, 0.0);
while (texcoord.y > end &&
while (texcoord.y > end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e = textureLodA(edgesTex, texcoord, 0.0).rg;
@ -283,7 +282,7 @@ float SMAASearchYUp(vec2 texcoord, float end) {
float SMAASearchYDown(vec2 texcoord, float end) {
vec2 e = vec2(1.0, 0.0);
while (texcoord.y < end &&
while (texcoord.y < end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e = textureLodA(edgesTex, texcoord, 0.0).rg;
@ -293,14 +292,14 @@ float SMAASearchYDown(vec2 texcoord, float end) {
return mad(-screenSizeInv.y, offset, texcoord.y);
}
/**
/**
* Ok, we have the distance and both crossing edges. So, what are the areas
* at each side of current edge?
*/
vec2 SMAAArea(vec2 dist, float e1, float e2, float offset) {
// Rounding prevents precision errors of bilinear filtering:
vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * vec2(e1, e2)), dist);
// We do a scale and bias for mapping to texel space:
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
@ -364,7 +363,7 @@ vec4 SMAABlendingWeightCalculationPS(vec2 texcoord, vec2 pixcoord,
// one of the boundaries is enough.
weights.rg = SMAACalculateDiagWeights(texcoord, e, subsampleIndices);
// We give priority to diagonals, so if we find a diagonal we skip
// We give priority to diagonals, so if we find a diagonal we skip
// horizontal/vertical processing.
//SMAA_BRANCH
if (weights.r == -weights.g) { // weights.r + weights.g == 0.0
@ -434,7 +433,7 @@ vec4 SMAABlendingWeightCalculationPS(vec2 texcoord, vec2 pixcoord,
// We want the distances to be in pixel units:
d = abs(round(mad(screenSize.yy, d, -pixcoord.yy)));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically:
vec2 sqrt_d = sqrt(d);

View file

@ -11,7 +11,7 @@ out vec4 offset0;
out vec4 offset1;
out vec4 offset2;
#ifdef _InvY
#ifdef HLSL
#define V_DIR(v) -(v)
#else
#define V_DIR(v) v
@ -21,7 +21,7 @@ void main() {
// Scale vertex attribute to [0-1] range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif

View file

@ -18,7 +18,7 @@ out vec4 fragColor;
// Neighborhood Blending Pixel Shader (Third Pass)
vec4 textureLodA(sampler2D tex, vec2 coords, float lod) {
#ifdef _InvY
#ifdef HLSL
coords.y = 1.0 - coords.y;
#endif
return textureLod(tex, coords, lod);
@ -49,7 +49,7 @@ vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, vec4 offset) {
// Calculate the blending offsets:
vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w);
vec2 blendingWeight = a.yw;
if (h) {
blendingOffset.x = a.x;
blendingOffset.y = 0.0;
@ -58,11 +58,11 @@ vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, vec4 offset) {
blendingWeight.x = a.x;
blendingWeight.y = a.z;
}
blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0));
// Calculate the texture coordinates:
#ifdef _InvY
#ifdef HLSL
vec2 tc = vec2(texcoord.x, 1.0 - texcoord.y);
#else
vec2 tc = texcoord;

View file

@ -9,7 +9,7 @@ uniform vec2 screenSizeInv;
out vec2 texCoord;
out vec4 offset;
#ifdef _InvY
#ifdef HLSL
#define V_DIR(v) -(v)
#else
#define V_DIR(v) v
@ -19,7 +19,7 @@ void main() {
// Scale vertex attribute to [0-1] range
const vec2 madd = vec2(0.5, 0.5);
texCoord = pos.xy * madd + madd;
#ifdef _InvY
#ifdef HLSL
texCoord.y = 1.0 - texCoord.y;
#endif

View file

@ -12,11 +12,6 @@ uniform vec3 eyeLook;
uniform vec2 screenSize;
uniform mat4 invVP;
#ifdef _CPostprocess
uniform vec3 PPComp11;
uniform vec3 PPComp12;
#endif
in vec2 texCoord;
in vec3 viewRay;
out float fragColor;
@ -25,21 +20,17 @@ void main() {
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (depth == 1.0) { fragColor = 1.0; return; }
vec2 enc = textureLod(gbuffer0, texCoord, 0.0).rg;
vec2 enc = textureLod(gbuffer0, texCoord, 0.0).rg;
vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);
vec3 vray = normalize(viewRay);
vec3 currentPos = getPosNoEye(eyeLook, vray, depth, cameraProj);
// vec3 currentPos = getPos2NoEye(eye, invVP, depth, texCoord);
float currentDistance = length(currentPos);
#ifdef _CPostprocess
float currentDistanceA = currentDistance * PPComp12.y * (1.0 / PPComp11.z);
#else
float currentDistanceA = currentDistance * ssaoScale * (1.0 / ssaoRadius);
#endif
float currentDistanceA = currentDistance * ssaoScale * (1.0 / ssaoRadius);
float currentDistanceB = currentDistance * 0.0005;
ivec2 px = ivec2(texCoord * screenSize);
float phi = (3 * px.x ^ px.y + px.x * px.y) * 10;
@ -55,11 +46,7 @@ void main() {
vec3 pos = getPos2NoEye(eye, invVP, depth, texCoord + k) - currentPos;
fragColor += max(0, dot(pos, n) - currentDistanceB) / (dot(pos, pos) + 0.015);
}
#ifdef _CPostprocess
fragColor *= (PPComp12.x * 0.3) / samples;
#else
fragColor *= (ssaoStrength * 0.3) / samples;
#endif
fragColor *= (ssaoStrength * 0.3) / samples;
fragColor = 1.0 - fragColor;
}

View file

@ -25,16 +25,6 @@
{
"name": "screenSize",
"link": "_screenSize"
},
{
"name": "PPComp11",
"link": "_PPComp11",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp12",
"link": "_PPComp12",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],

View file

@ -37,7 +37,7 @@ vec2 getProjectedCoord(vec3 hitCoord) {
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
#ifdef _InvY
#ifdef HLSL
projectedCoord.y = 1.0 - projectedCoord.y;
#endif
return projectedCoord.xy;

View file

@ -12,11 +12,6 @@ uniform mat4 P;
uniform mat3 V3;
uniform vec2 cameraProj;
#ifdef _CPostprocess
uniform vec3 PPComp9;
uniform vec3 PPComp10;
#endif
in vec3 viewRay;
in vec2 texCoord;
out vec4 fragColor;
@ -31,13 +26,13 @@ vec2 getProjectedCoord(const vec3 hit) {
vec4 projectedCoord = P * vec4(hit, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
#ifdef _InvY
#ifdef HLSL
projectedCoord.y = 1.0 - projectedCoord.y;
#endif
return projectedCoord.xy;
}
float getDeltaDepth(const vec3 hit) {
float getDeltaDepth(const vec3 hit) {
depth = textureLod(gbufferD, getProjectedCoord(hit), 0.0).r * 2.0 - 1.0;
vec3 viewPos = getPosView(viewRay, depth, cameraProj);
return viewPos.z - hit.z;
@ -53,20 +48,12 @@ vec4 binarySearch(vec3 dir) {
if (ddepth < 0.0) hitCoord += dir;
}
// Ugly discard of hits too far away
#ifdef _CPostprocess
if (abs(ddepth) > PPComp9.z / 500) return vec4(0.0);
#else
if (abs(ddepth) > ssrSearchDist / 500) return vec4(0.0);
#endif
if (abs(ddepth) > ssrSearchDist / 500) return vec4(0.0);
return vec4(getProjectedCoord(hitCoord), 0.0, 1.0);
}
vec4 rayCast(vec3 dir) {
#ifdef _CPostprocess
dir *= PPComp9.x;
#else
dir *= ssrRayStep;
#endif
dir *= ssrRayStep;
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
@ -76,12 +63,12 @@ vec4 rayCast(vec3 dir) {
void main() {
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0);
float roughness = unpackFloat(g0.b).y;
float roughness = g0.b;
if (roughness == 1.0) { fragColor.rgb = vec3(0.0); return; }
float spec = fract(textureLod(gbuffer1, texCoord, 0.0).a);
if (spec == 0.0) { fragColor.rgb = vec3(0.0); return; }
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (d == 1.0) { fragColor.rgb = vec3(0.0); return; }
@ -90,18 +77,13 @@ void main() {
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);
vec3 viewNormal = V3 * n;
vec3 viewPos = getPosView(viewRay, d, cameraProj);
vec3 reflected = normalize(reflect(viewPos, viewNormal));
hitCoord = viewPos;
#ifdef _CPostprocess
vec3 dir = reflected * (1.0 - rand(texCoord) * PPComp10.y * roughness) * 2.0;
#else
vec3 dir = reflected * (1.0 - rand(texCoord) * ssrJitter * roughness) * 2.0;
#endif
vec3 dir = reflected * (1.0 - rand(texCoord) * ssrJitter * roughness) * 2.0;
// * max(ssrMinRayStep, -viewPos.z)
vec4 coords = rayCast(dir);
@ -109,11 +91,12 @@ void main() {
float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
float reflectivity = 1.0 - roughness;
#ifdef _CPostprocess
float intensity = pow(reflectivity, PPComp10.x) * screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) * clamp((PPComp9.z - length(viewPos - hitCoord)) * (1.0 / PPComp9.z), 0.0, 1.0) * coords.w;
#else
float intensity = pow(reflectivity, ssrFalloffExp) * screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) * clamp((ssrSearchDist - length(viewPos - hitCoord)) * (1.0 / ssrSearchDist), 0.0, 1.0) * coords.w;
#endif
float intensity = pow(reflectivity, ssrFalloffExp) *
screenEdgeFactor *
clamp(-reflected.z, 0.0, 1.0) *
clamp((ssrSearchDist - length(viewPos - hitCoord)) *
(1.0 / ssrSearchDist), 0.0, 1.0) *
coords.w;
intensity = clamp(intensity, 0.0, 1.0);
vec3 reflCol = textureLod(tex, coords.xy, 0.0).rgb;

View file

@ -21,16 +21,6 @@
{
"name": "cameraProj",
"link": "_cameraPlaneProj"
},
{
"name": "PPComp9",
"link": "_PPComp9",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp10",
"link": "_PPComp10",
"ifdef": ["_CPostprocess"]
}
],
"texture_params": [],

View file

@ -1,4 +1,7 @@
const int maxLights = 16;
const int maxLightsCluster = 4; // Ensure fast loop unroll before going higher
const float clusterNear = 3.0;
const vec3 clusterSlices = vec3(16, 16, 16);
int getClusterI(vec2 tc, float viewz, vec2 cameraPlane) {
@ -8,10 +11,6 @@ int getClusterI(vec2 tc, float viewz, vec2 cameraPlane) {
float z = log(viewz - cnear + 1.0) / log(cameraPlane.y - cnear + 1.0);
sliceZ = int(z * (clusterSlices.z - 1)) + 1;
}
// address gap between near plane and cluster near offset
else if (viewz >= cameraPlane.x) {
sliceZ = 1;
}
return int(tc.x * clusterSlices.x) +
int(int(tc.y * clusterSlices.y) * clusterSlices.x) +
int(sliceZ * clusterSlices.x * clusterSlices.y);

View file

@ -1,144 +0,0 @@
// Colorgrading library functions - Inspired by UE4
//No specific license (maybe zlib), but just do whatever
#define LUMINANCE_PRESERVATION 0.75
#define EPSILON 1e-10
#define LUMA1 0.2722287168
#define LUMA2 0.6740817658
#define LUMA3 0.0536895174
float saturate(float v) { return clamp(v, 0.0, 1.0); }
vec2 saturate(vec2 v) { return clamp(v, vec2(0.0), vec2(1.0)); }
vec3 saturate(vec3 v) { return clamp(v, vec3(0.0), vec3(1.0)); }
vec4 saturate(vec4 v) { return clamp(v, vec4(0.0), vec4(1.0)); }
float LumaKey (vec3 color) {
return dot(color, vec3(LUMA1, LUMA2, LUMA3));
}
vec3 ColorTemperatureToRGB(float temperatureInKelvins)
{
vec3 retColor;
temperatureInKelvins = clamp(temperatureInKelvins, 1000.0, 40000.0) / 100.0;
if (temperatureInKelvins <= 66.0)
{
retColor.r = 1.0;
retColor.g = saturate(0.39008157876901960784 * log(temperatureInKelvins) - 0.63184144378862745098);
}
else
{
float t = temperatureInKelvins - 60.0;
retColor.r = saturate(1.29293618606274509804 * pow(t, -0.1332047592));
retColor.g = saturate(1.12989086089529411765 * pow(t, -0.0755148492));
}
if (temperatureInKelvins >= 66.0)
retColor.b = 1.0;
else if(temperatureInKelvins <= 19.0)
retColor.b = 0.0;
else
retColor.b = saturate(0.54320678911019607843 * log(temperatureInKelvins - 10.0) - 1.19625408914);
return retColor;
}
float Luminance(vec3 color)
{
float fmin = min(min(color.r, color.g), color.b);
float fmax = max(max(color.r, color.g), color.b);
return (fmax + fmin) / 2.0;
}
vec3 HUEtoRGB(float H)
{
float R = abs(H * 6.0 - 3.0) - 1.0;
float G = 2.0 - abs(H * 6.0 - 2.0);
float B = 2.0 - abs(H * 6.0 - 4.0);
return saturate(vec3(R,G,B));
}
vec3 HSLtoRGB(in vec3 HSL)
{
vec3 RGB = HUEtoRGB(HSL.x);
float C = (1.0 - abs(2.0 * HSL.z - 1.0)) * HSL.y;
return (RGB - 0.5) * C + vec3(HSL.z);
}
vec3 RGBtoHCV(vec3 RGB)
{
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
float C = Q.x - min(Q.w, Q.y);
float H = abs((Q.w - Q.y) / (6.0 * C + EPSILON) + Q.z);
return vec3(H, C, Q.x);
}
vec3 RGBtoHSL(vec3 RGB)
{
vec3 HCV = RGBtoHCV(RGB);
float L = HCV.z - HCV.y * 0.5;
float S = HCV.y / (1.0 - abs(L * 2.0 - 1.0) + EPSILON);
return vec3(HCV.x, S, L);
}
vec3 ToneColorCorrection(vec3 Color, vec3 ColorSaturation, vec3 ColorContrast, vec3 ColorGamma, vec3 ColorGain, vec3 ColorOffset) {
//First initialize the colorluma key
float ColorLuma = LumaKey(Color);
//Add the saturation with the above key
Color = max(vec3(0,0,0), mix(ColorLuma.xxx, Color, ColorSaturation));
//Contrast with slight color correction (0.18 coefficient)
float ContrastCorrectionCoefficient = 0.18;
Color = pow(Color * (1.0 / ContrastCorrectionCoefficient), ColorContrast) * ContrastCorrectionCoefficient;
//Gamma
Color = pow(Color, 1.0 / ColorGamma);
//Gain and Offset
Color = Color.rgb * ColorGain + (ColorOffset - 1);
//Return the color corrected profile
return Color;
}
vec3 FinalizeColorCorrection(vec3 Color, mat3 ColorSaturation, mat3 ColorContrast, mat3 ColorGamma, mat3 ColorGain, mat3 ColorOffset, vec2 Toneweights) {
float CCShadowsMax = Toneweights.x;
float CCHighlightsMin = Toneweights.y;
//First initialize the colorluma key and set color correction weights
float ColorLuma = LumaKey(Color);
float CCWeightShadows = 1 - smoothstep(0, CCShadowsMax, ColorLuma);
float CCWeightHighlights = smoothstep(CCHighlightsMin, 1, ColorLuma);
float CCWeightMidtones = 1 - CCWeightShadows - CCWeightHighlights;
vec3 CCColorShadows = ToneColorCorrection (
Color,
ColorSaturation[0],
ColorContrast[0],
ColorGamma[0],
ColorGain[0],
ColorOffset[0]
);
vec3 CCColorMidtones = ToneColorCorrection (
Color,
ColorSaturation[1],
ColorContrast[1],
ColorGamma[1],
ColorGain[1],
ColorOffset[1]
);
vec3 CCColorHighlights = ToneColorCorrection (
Color,
ColorSaturation[2],
ColorContrast[2],
ColorGamma[2],
ColorGain[2],
ColorOffset[2]
);
vec3 CombinedCCProfile = CCColorShadows * CCWeightShadows + CCColorMidtones * CCWeightMidtones + CCColorHighlights * CCWeightHighlights;
return vec3(CombinedCCProfile);
}

View file

@ -1,56 +0,0 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright (c) 2018-2019 Michele Morrone
// All rights reserved.
//
// https://michelemorrone.eu - https://BrutPitt.com
//
// me@michelemorrone.eu - brutpitt@gmail.com
// twitter: @BrutPitt - github: BrutPitt
//
// https://github.com/BrutPitt/glslSmartDeNoise/
//
// This software is distributed under the terms of the BSD 2-Clause license
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef _DENOISE_GLSL_
#define _DENOISE_GLSL_
#define INV_SQRT_OF_2PI 0.39894228040143267793994605993439
#define INV_PI 0.31830988618379067153776752674503
vec4 smartDeNoise(sampler2D tex, vec2 uv, float sigma, float kSigma, float threshold) {
float radius = round(kSigma*sigma);
float radQ = radius * radius;
float invSigmaQx2 = .5 / (sigma * sigma); // 1.0 / (sigma^2 * 2.0)
float invSigmaQx2PI = INV_PI * invSigmaQx2; // 1.0 / (sqrt(PI) * sigma)
float invThresholdSqx2 = .5 / (threshold * threshold); // 1.0 / (sigma^2 * 2.0)
float invThresholdSqrt2PI = INV_SQRT_OF_2PI / threshold; // 1.0 / (sqrt(2*PI) * sigma)
vec4 centrPx = texture(tex,uv);
float zBuff = 0.0;
vec4 aBuff = vec4(0.0);
vec2 size = vec2(textureSize(tex, 0));
for(float x=-radius; x <= radius; x++) {
float pt = sqrt(radQ-x*x); // pt = yRadius: have circular trend
for(float y=-pt; y <= pt; y++) {
vec2 d = vec2(x,y)/size;
float blurFactor = exp( -dot(d , d) * invSigmaQx2 ) * invSigmaQx2;
vec4 walkPx = texture(tex,uv+d);
vec4 dC = walkPx-centrPx;
float deltaFactor = exp( -dot(dC, dC) * invThresholdSqx2) * invThresholdSqrt2PI * blurFactor;
zBuff += deltaFactor;
aBuff += deltaFactor*walkPx;
}
}
return aBuff/zBuff;
}
#endif

View file

@ -31,33 +31,17 @@ vec3 color(vec2 coords, const float blur, const sampler2D tex, const vec2 texSte
return col + mix(vec3(0.0), col, thresh * blur);
}
vec3 dof(
const vec2 texCoord,
const float gdepth,
const sampler2D tex,
const sampler2D gbufferD,
const vec2 texStep,
const vec2 cameraProj,
const bool autoFocus,
const float DOFDistance,
const float DOFLength,
const float DOFFStop) {
vec3 dof(const vec2 texCoord, const float gdepth, const sampler2D tex, const sampler2D gbufferD, const vec2 texStep, const vec2 cameraProj) {
float depth = linearize(gdepth, cameraProj);
float fDepth = 0.0;
if(autoFocus) {
fDepth = linearize(textureLod(gbufferD, focus, 0.0).r * 2.0 - 1.0, cameraProj);
} else {
fDepth = DOFDistance;
}
float f = DOFLength; // Focal length in mm
float d = fDepth * 1000.0; // Focal plane in mm
// const float fDepth = compoDOFDistance;
float fDepth = linearize(textureLod(gbufferD, focus, 0.0).r * 2.0 - 1.0, cameraProj); // Autofocus
const float f = compoDOFLength; // Focal length in mm
const float d = fDepth * 1000.0; // Focal plane in mm
float o = depth * 1000.0; // Depth in mm
float a = (o * f) / (o - f);
float b = (d * f) / (d - f);
float c = (d - f) / (d * DOFFStop * coc);
float c = (d - f) / (d * compoDOFFstop * coc);
float blur = abs(a - b) * c;
blur = clamp(blur, 0.0, 1.0);

View file

@ -19,7 +19,7 @@ vec3 getPosView(const vec3 viewRay, const float depth, const vec2 cameraProj) {
return viewRay * linearDepth;
}
vec3 getPos(const vec3 eye, const vec3 eyeLook, const vec3 viewRay, const float depth, const vec2 cameraProj) {
vec3 getPos(const vec3 eye, const vec3 eyeLook, const vec3 viewRay, const float depth, const vec2 cameraProj) {
// eyeLook, viewRay should be normalized
float linearDepth = cameraProj.y / ((depth * 0.5 + 0.5) - cameraProj.x);
float viewZDist = dot(eyeLook, viewRay);
@ -27,7 +27,7 @@ vec3 getPos(const vec3 eye, const vec3 eyeLook, const vec3 viewRay, const float
return wposition;
}
vec3 getPosNoEye(const vec3 eyeLook, const vec3 viewRay, const float depth, const vec2 cameraProj) {
vec3 getPosNoEye(const vec3 eyeLook, const vec3 viewRay, const float depth, const vec2 cameraProj) {
// eyeLook, viewRay should be normalized
float linearDepth = cameraProj.y / ((depth * 0.5 + 0.5) - cameraProj.x);
float viewZDist = dot(eyeLook, viewRay);
@ -35,7 +35,7 @@ vec3 getPosNoEye(const vec3 eyeLook, const vec3 viewRay, const float depth, cons
return wposition;
}
#if defined(HLSL) || defined(METAL)
#ifdef HLSL
vec3 getPos2(const mat4 invVP, const float depth, vec2 coord) {
coord.y = 1.0 - coord.y;
#else
@ -47,7 +47,7 @@ vec3 getPos2(const mat4 invVP, const float depth, const vec2 coord) {
return pos.xyz;
}
#if defined(HLSL) || defined(METAL)
#ifdef HLSL
vec3 getPosView2(const mat4 invP, const float depth, vec2 coord) {
coord.y = 1.0 - coord.y;
#else
@ -59,7 +59,7 @@ vec3 getPosView2(const mat4 invP, const float depth, const vec2 coord) {
return pos.xyz;
}
#if defined(HLSL) || defined(METAL)
#ifdef HLSL
vec3 getPos2NoEye(const vec3 eye, const mat4 invVP, const float depth, vec2 coord) {
coord.y = 1.0 - coord.y;
#else

View file

@ -21,41 +21,27 @@
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
#ifndef _LTC
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot[1];
#endif
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas;
#endif
uniform vec2 lightProj;
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
#endif
#else
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#ifdef _Clusters
uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
#ifdef _LTC
uniform vec3 lightArea0;
@ -65,14 +51,17 @@ uniform vec3 lightArea3;
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
#ifdef _ShadowMap
#ifndef _Spot
#ifndef _Spot
#ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot[1];
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#endif
#ifdef _Clusters
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
uniform mat4 LWVPSpotArray[maxLightsCluster];
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
@ -81,7 +70,7 @@ uniform sampler2D sltcMag;
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow
, int index, float bias
#endif
#ifdef _Spot
, bool isSpot, float spotA, float spotB, vec3 spotDir
@ -141,30 +130,28 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _LTC
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
}
else if (index == 1) {
vec4 lPos = LWVPSpot[1] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot[2] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot[3] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
#endif
return direct;
#endif
@ -177,30 +164,28 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
, lPos.xyz / lPos.w, bias
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
#endif
#endif
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
#endif
return direct;
}
@ -211,30 +196,17 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifndef _SingleAtlas
shadowMapAtlasPoint
#else
shadowMapAtlas
#endif
, ld, -l, bias, lightProj, n, index
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
}
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
return direct;

View file

@ -8,44 +8,32 @@
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot[1];
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas;
#endif
uniform vec2 lightProj;
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
#endif
#else
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#ifdef _Clusters
uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow
, int index, float bias
#endif
#ifdef _Spot
, bool isSpot, float spotA, float spotB, vec3 spotDir
@ -72,61 +60,45 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
, lPos.xyz / lPos.w, bias
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
#endif
#endif
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
#endif
return direct;
}
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifndef _SingleAtlas
shadowMapAtlasPoint
#else
shadowMapAtlas
#endif
, ld, -l, bias, lightProj, n, index
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
}
#ifndef _Spot
#ifdef _SinglePoint
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
#endif
return direct;

View file

@ -1,41 +0,0 @@
/*
https://github.com/JonasFolletete/glsl-triplanar-mapping
MIT License
Copyright (c) 2018 Jonas Folletête
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
vec3 blendNormal(vec3 normal) {
vec3 blending = abs(normal);
blending = normalize(max(blending, 0.00001));
blending /= vec3(blending.x + blending.y + blending.z);
return blending;
}
vec3 triplanarMapping (sampler2D ImageTexture, vec3 normal, vec3 position) {
vec3 normalBlend = blendNormal(normal);
vec3 xColor = texture(ImageTexture, position.yz).rgb;
vec3 yColor = texture(ImageTexture, position.xz).rgb;
vec3 zColor = texture(ImageTexture, position.xy).rgb;
return (xColor * normalBlend.x + yColor * normalBlend.y + zColor * normalBlend.z);
}

View file

@ -20,10 +20,10 @@ float rand(const vec2 co) { // Unreliable
}
vec2 rand2(const vec2 coord) {
const float width = 1100.0;
const float height = 500.0;
const float width = 1100;
const float height = 500;
float noiseX = ((fract(1.0 - coord.s * (width / 2.0)) * 0.25) + (fract(coord.t * (height / 2.0)) * 0.75)) * 2.0 - 1.0;
float noiseY = ((fract(1.0 - coord.s * (width / 2.0)) * 0.75) + (fract(coord.t * (height / 2.0)) * 0.25)) * 2.0 - 1.0;
float noiseY = ((fract(1.0 - coord.s * (width / 2.0)) * 0.75) + (fract(coord.t * (height / 2.0)) * 0.25)) * 2.0 - 1.0;
return vec2(noiseX, noiseY);
}
@ -40,9 +40,4 @@ float attenuate(const float dist) {
// 1.0 / (quadratic * dist * dist);
}
float safe_acos(const float x) {
// acos is undefined if |x| > 1
return acos(clamp(x, -1.0, 1.0));
}
#endif

View file

@ -1,53 +0,0 @@
uniform sampler2D morphDataPos;
uniform sampler2D morphDataNor;
uniform vec2 morphScaleOffset;
uniform vec2 morphDataDim;
uniform vec4 morphWeights[8];
void getMorphedVertex(vec2 uvCoord, inout vec3 A){
for(int i = 0; i<8; i++ )
{
vec4 tempCoordY = vec4( uvCoord.y - (i * 4) * morphDataDim.y,
uvCoord.y - (i * 4 + 1) * morphDataDim.y,
uvCoord.y - (i * 4 + 2) * morphDataDim.y,
uvCoord.y - (i * 4 + 3) * morphDataDim.y);
vec3 morph = texture(morphDataPos, vec2(uvCoord.x, tempCoordY.x)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += morphWeights[i].x * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, tempCoordY.y)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += morphWeights[i].y * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, tempCoordY.z)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += morphWeights[i].z * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, tempCoordY.w)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += morphWeights[i].w * morph;
}
}
void getMorphedNormal(vec2 uvCoord, vec3 oldNor, inout vec3 morphNor){
for(int i = 0; i<8; i++ )
{
vec4 tempCoordY = vec4( uvCoord.y - (i * 4) * morphDataDim.y,
uvCoord.y - (i * 4 + 1) * morphDataDim.y,
uvCoord.y - (i * 4 + 2) * morphDataDim.y,
uvCoord.y - (i * 4 + 3) * morphDataDim.y);
vec3 norm = oldNor + morphWeights[i].x * (texture(morphDataNor, vec2(uvCoord.x, tempCoordY.x)).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + morphWeights[i].y * (texture(morphDataNor, vec2(uvCoord.x, tempCoordY.y)).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + morphWeights[i].z * (texture(morphDataNor, vec2(uvCoord.x, tempCoordY.z)).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + morphWeights[i].w * (texture(morphDataNor, vec2(uvCoord.x, tempCoordY.w)).rgb * 2.0 - 1.0);
morphNor += norm;
}
morphNor = normalize(morphNor);
}

View file

@ -11,50 +11,6 @@ uniform vec4 casData[shadowmapCascades * 4 + 4];
uniform vec2 smSizeUniform;
#endif
#ifdef _ShadowMap
#ifdef _Clusters
#ifdef _ShadowMapAtlas
uniform vec4 pointLightDataArray[maxLightsCluster * 6];
#endif
#endif
#endif
#ifdef _ShadowMapAtlas
// https://www.khronos.org/registry/OpenGL/specs/gl/glspec20.pdf // p:168
// https://www.gamedev.net/forums/topic/687535-implementing-a-cube-map-lookup-function/5337472/
vec2 sampleCube(vec3 dir, out int faceIndex) {
vec3 dirAbs = abs(dir);
float ma;
vec2 uv;
if(dirAbs.z >= dirAbs.x && dirAbs.z >= dirAbs.y) {
faceIndex = dir.z < 0.0 ? 5 : 4;
ma = 0.5 / dirAbs.z;
uv = vec2(dir.z < 0.0 ? -dir.x : dir.x, -dir.y);
}
else if(dirAbs.y >= dirAbs.x) {
faceIndex = dir.y < 0.0 ? 3 : 2;
ma = 0.5 / dirAbs.y;
uv = vec2(dir.x, dir.y < 0.0 ? -dir.z : dir.z);
}
else {
faceIndex = dir.x < 0.0 ? 1 : 0;
ma = 0.5 / dirAbs.x;
uv = vec2(dir.x < 0.0 ? dir.z : -dir.z, -dir.y);
}
// downscale uv a little to hide seams
// transform coordinates from clip space to texture space
#ifndef _FlipY
return uv * 0.9976 * ma + 0.5;
#else
#ifdef HLSL
return uv * 0.9976 * ma + 0.5;
#else
return vec2(uv.x * ma, uv.y * -ma) * 0.9976 + 0.5;
#endif
#endif
}
#endif
float PCF(sampler2DShadow shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
float result = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare));
result += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
@ -79,7 +35,7 @@ float PCFCube(samplerCubeShadow shadowMapCube, const vec3 lp, vec3 ml, const flo
const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20;
#ifdef _InvY
#ifdef HLSL
ml.y = -ml.y;
#endif
float result = texture(shadowMapCube, vec4(ml, compare));
@ -94,186 +50,6 @@ float PCFCube(samplerCubeShadow shadowMapCube, const vec3 lp, vec3 ml, const flo
return result / 9.0;
}
#ifdef _ShadowMapAtlas
// transform "out-of-bounds" coordinates to the correct face/coordinate system
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
if (uv.x < 0.0) {
if (faceIndex == 0) { // X+
newFaceIndex = 4; // Z+
}
else if (faceIndex == 1) { // X-
newFaceIndex = 5; // Z-
}
else if (faceIndex == 2) { // Y+
newFaceIndex = 1; // X-
}
else if (faceIndex == 3) { // Y-
newFaceIndex = 1; // X-
}
else if (faceIndex == 4) { // Z+
newFaceIndex = 1; // X-
}
else { // Z-
newFaceIndex = 0; // X+
}
uv = vec2(1.0 + uv.x, uv.y);
}
else if (uv.x > 1.0) {
if (faceIndex == 0) { // X+
newFaceIndex = 5; // Z-
}
else if (faceIndex == 1) { // X-
newFaceIndex = 4; // Z+
}
else if (faceIndex == 2) { // Y+
newFaceIndex = 0; // X+
}
else if (faceIndex == 3) { // Y-
newFaceIndex = 0; // X+
}
else if (faceIndex == 4) { // Z+
newFaceIndex = 0; // X+
}
else { // Z-
newFaceIndex = 1; // X-
}
uv = vec2(1.0 - uv.x, uv.y);
}
else if (uv.y < 0.0) {
if (faceIndex == 0) { // X+
newFaceIndex = 2; // Y+
}
else if (faceIndex == 1) { // X-
newFaceIndex = 2; // Y+
}
else if (faceIndex == 2) { // Y+
newFaceIndex = 5; // Z-
}
else if (faceIndex == 3) { // Y-
newFaceIndex = 4; // Z+
}
else if (faceIndex == 4) { // Z+
newFaceIndex = 2; // Y+
}
else { // Z-
newFaceIndex = 2; // Y+
}
uv = vec2(uv.x, 1.0 + uv.y);
}
else if (uv.y > 1.0) {
if (faceIndex == 0) { // X+
newFaceIndex = 3; // Y-
}
else if (faceIndex == 1) { // X-
newFaceIndex = 3; // Y-
}
else if (faceIndex == 2) { // Y+
newFaceIndex = 4; // Z+
}
else if (faceIndex == 3) { // Y-
newFaceIndex = 5; // Z-
}
else if (faceIndex == 4) { // Z+
newFaceIndex = 3; // Y-
}
else { // Z-
newFaceIndex = 3; // Y-
}
uv = vec2(uv.x, 1.0 - uv.y);
} else {
newFaceIndex = faceIndex;
}
// cover corner cases too
return uv;
}
float PCFFakeCube(sampler2DShadow shadowMap, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index) {
const vec2 smSize = smSizeUniform; // TODO: incorrect...
const float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20;
int faceIndex = 0;
const int lightIndex = index * 6;
const vec2 uv = sampleCube(ml, faceIndex);
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
float result = texture(shadowMap, vec3(uvtiled, compare));
// soft shadowing
int newFaceIndex = 0;
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 0.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 0.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));
return result / 9.0;
}
#endif
float shadowTest(sampler2DShadow shadowMap, const vec3 lPos, const float shadowsBias) {
#ifdef _SMSizeUniform
vec2 smSize = smSizeUniform;
@ -319,7 +95,7 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
float shadowTestCascade(sampler2DShadow shadowMap, const vec3 eye, const vec3 p, const float shadowsBias) {
#ifdef _SMSizeUniform
vec2 smSize = smSizeUniform;
vec2 smSize = smSizeUniform * vec2(shadowmapCascades, 1.0);
#else
const vec2 smSize = shadowmapSize * vec2(shadowmapCascades, 1.0);
#endif
@ -329,7 +105,7 @@ float shadowTestCascade(sampler2DShadow shadowMap, const vec3 eye, const vec3 p,
int casi;
int casIndex;
mat4 LWVP = getCascadeMat(d, casi, casIndex);
vec4 lPos = LWVP * vec4(p, 1.0);
lPos.xyz /= lPos.w;

View file

@ -1,5 +1,6 @@
uniform vec4 shirr[7];
vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) {
vec3 shIrradiance(const vec3 nor) {
const float c1 = 0.429043;
const float c2 = 0.511664;
const float c3 = 0.743125;

View file

@ -1,155 +0,0 @@
/* Various sky functions
* =====================
*
* Nishita model is based on https://github.com/wwwtyro/glsl-atmosphere (Unlicense License)
*
* Changes to the original implementation:
* - r and pSun parameters of nishita_atmosphere() are already normalized
* - Some original parameters of nishita_atmosphere() are replaced with pre-defined values
* - Implemented air, dust and ozone density node parameters (see Blender source)
* - Replaced the inner integral calculation with a LUT lookup
*
* Reference for the sun's limb darkening and ozone calculations:
* [Hill] Sebastien Hillaire. Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite
* (https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/s2016-pbs-frostbite-sky-clouds-new.pdf)
*
* Cycles code used for reference: blender/intern/sky/source/sky_nishita.cpp
* (https://github.com/blender/blender/blob/4429b4b77ef6754739a3c2b4fabd0537999e9bdc/intern/sky/source/sky_nishita.cpp)
*/
#ifndef _SKY_GLSL_
#define _SKY_GLSL_
#include "std/math.glsl"
uniform sampler2D nishitaLUT;
uniform vec2 nishitaDensity;
#ifndef PI
#define PI 3.141592
#endif
#ifndef HALF_PI
#define HALF_PI 1.570796
#endif
#define nishita_iSteps 16
// These values are taken from Cycles code if they
// exist there, otherwise they are taken from the example
// in the glsl-atmosphere repo
#define nishita_sun_intensity 22.0
#define nishita_atmo_radius 6420e3
#define nishita_rayleigh_scale 8e3
#define nishita_rayleigh_coeff vec3(5.5e-6, 13.0e-6, 22.4e-6)
#define nishita_mie_scale 1.2e3
#define nishita_mie_coeff 2e-5
#define nishita_mie_dir 0.76 // Aerosols anisotropy ("direction")
#define nishita_mie_dir_sq 0.5776 // Squared aerosols anisotropy
// Values from [Hill: 60]
#define sun_limb_darkening_col vec3(0.397, 0.503, 0.652)
vec3 nishita_lookupLUT(const float height, const float sunTheta) {
vec2 coords = vec2(
sqrt(height * (1 / nishita_atmo_radius)),
0.5 + 0.5 * sign(sunTheta - HALF_PI) * sqrt(abs(sunTheta * (1 / HALF_PI) - 1))
);
return textureLod(nishitaLUT, coords, 0.0).rgb;
}
/* See raySphereIntersection() in armory/Sources/renderpath/Nishita.hx */
vec2 nishita_rsi(const vec3 r0, const vec3 rd, const float sr) {
float a = dot(rd, rd);
float b = 2.0 * dot(rd, r0);
float c = dot(r0, r0) - (sr * sr);
float d = (b*b) - 4.0*a*c;
// If d < 0.0 the ray does not intersect the sphere
return (d < 0.0) ? vec2(1e5,-1e5) : vec2((-b - sqrt(d))/(2.0*a), (-b + sqrt(d))/(2.0*a));
}
/*
* r: normalized ray direction
* r0: ray origin
* pSun: normalized sun direction
* rPlanet: planet radius
*/
vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const float rPlanet) {
// Calculate the step size of the primary ray
vec2 p = nishita_rsi(r0, r, nishita_atmo_radius);
if (p.x > p.y) return vec3(0.0);
p.y = min(p.y, nishita_rsi(r0, r, rPlanet).x);
float iStepSize = (p.y - p.x) / float(nishita_iSteps);
// Primary ray time
float iTime = 0.0;
// Accumulators for Rayleigh and Mie scattering.
vec3 totalRlh = vec3(0,0,0);
vec3 totalMie = vec3(0,0,0);
// Optical depth accumulators for the primary ray
float iOdRlh = 0.0;
float iOdMie = 0.0;
// Calculate the Rayleigh and Mie phases
float mu = dot(r, pSun);
float mumu = mu * mu;
float pRlh = 3.0 / (16.0 * PI) * (1.0 + mumu);
float pMie = 3.0 / (8.0 * PI) * ((1.0 - nishita_mie_dir_sq) * (mumu + 1.0)) / (pow(1.0 + nishita_mie_dir_sq - 2.0 * mu * nishita_mie_dir, 1.5) * (2.0 + nishita_mie_dir_sq));
// Sample the primary ray
for (int i = 0; i < nishita_iSteps; i++) {
// Calculate the primary ray sample position and height
vec3 iPos = r0 + r * (iTime + iStepSize * 0.5);
float iHeight = length(iPos) - rPlanet;
// Calculate the optical depth of the Rayleigh and Mie scattering for this step
float odStepRlh = exp(-iHeight / nishita_rayleigh_scale) * nishitaDensity.x * iStepSize;
float odStepMie = exp(-iHeight / nishita_mie_scale) * nishitaDensity.y * iStepSize;
// Accumulate optical depth
iOdRlh += odStepRlh;
iOdMie += odStepMie;
// Idea behind this: "Rotate" everything by iPos (-> iPos is the new zenith) and then all calculations for the
// inner integral only depend on the sample height (iHeight) and sunTheta (angle between sun and new zenith).
float sunTheta = safe_acos(dot(normalize(iPos), normalize(pSun)));
vec3 jAttn = nishita_lookupLUT(iHeight, sunTheta);
// Calculate attenuation
vec3 iAttn = exp(-(
nishita_mie_coeff * iOdMie
+ nishita_rayleigh_coeff * iOdRlh
// + 0 for ozone
));
vec3 attn = iAttn * jAttn;
// Apply dithering to reduce visible banding
attn *= 0.98 + rand(r.xy) * 0.04;
// Accumulate scattering
totalRlh += odStepRlh * attn;
totalMie += odStepMie * attn;
iTime += iStepSize;
}
return nishita_sun_intensity * (pRlh * nishita_rayleigh_coeff * totalRlh + pMie * nishita_mie_coeff * totalMie);
}
vec3 sun_disk(const vec3 n, const vec3 light_dir, const float disk_size, const float intensity) {
// Normalized SDF
float dist = distance(n, light_dir) / disk_size;
// Darken the edges of the sun
// [Hill: 28, 60] (according to [Nec96])
float invDist = 1.0 - dist;
float mu = sqrt(invDist * invDist);
vec3 limb_darkening = 1.0 - (1.0 - pow(vec3(mu), sun_limb_darkening_col));
return 1 + (1.0 - step(1.0, dist)) * nishita_sun_intensity * intensity * limb_darkening;
}
#endif

View file

@ -9,7 +9,7 @@ vec2 getProjectedCoord(vec3 hitCoord) {
vec4 projectedCoord = VP * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
#if defined(HLSL) || defined(METAL)
#ifdef HLSL
projectedCoord.y = 1.0 - projectedCoord.y;
#endif
return projectedCoord.xy;

View file

@ -15,12 +15,12 @@ const float SMAA_REPROJECTION_WEIGHT_SCALE = 30.0;
void main() {
vec4 current = textureLod(tex, texCoord, 0.0);
#ifdef _Veloc
// Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
#ifdef _InvY
#ifdef HLSL
velocity.y = -velocity.y;
#endif

View file

@ -12,7 +12,7 @@ uniform sampler2D gbufferD;
uniform sampler2D snoise;
#ifdef _Clusters
uniform vec4 lightsArray[maxLights * 3];
uniform vec4 lightsArray[maxLights * 2];
#ifdef _Spot
uniform vec4 lightsArraySpot[maxLights];
#endif
@ -24,7 +24,7 @@ uniform vec2 cameraPlane;
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
@ -35,7 +35,10 @@ uniform vec2 cameraPlane;
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot[maxLightsCluster];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
@ -44,15 +47,7 @@ uniform vec2 cameraPlane;
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun;
#else
uniform sampler2DShadow shadowMapAtlas;
#endif
#else
uniform sampler2DShadow shadowMap;
#endif
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
@ -91,42 +86,30 @@ const float lighting = 0.4;
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
curPos += stepLenWorld * viewVecNorm;
const float density = 1.0;
float l1 = lighting * stepLenWorld * tScat * density;
curOpticalDepth *= exp(-tExt * stepLenWorld * density);
float visibility = 0.0;
#ifdef _Sun
#ifdef _CSM
mat4 LWVP = mat4(casData[4], casData[4 + 1], casData[4 + 2], casData[4 + 3]);
mat4 LWVP = mat4(casData[4], casData[4 + 1], casData[4 + 2], casData[4 + 3]);
#endif
vec4 lPos = LWVP * vec4(curPos, 1.0);
lPos.xyz /= lPos.w;
visibility = texture(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun
#else
shadowMapAtlas
#endif
#else
shadowMap
#endif
, vec3(lPos.xy, lPos.z - shadowsBias));
float visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias));
#endif
#ifdef _SinglePoint
#ifdef _Spot
vec4 lPos = LWVPSpot[0] * vec4(curPos, 1.0);
visibility = shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, pointBias);
vec4 lPos = LWVPSpot0 * vec4(curPos, 1.0);
float visibility = shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, pointBias);
float spotEffect = dot(spotDir, normalize(pointPos - curPos)); // lightDir
if (spotEffect < spotData.x) { // x - cutoff, y - cutoff - exponent
visibility *= smoothstep(spotData.y, spotData.x, spotEffect);
}
#else
vec3 ld = pointPos - curPos;
visibility = PCFCube(shadowMapPoint[0], ld, -normalize(ld), pointBias, lightProj, vec3(0.0));
float visibility = PCFCube(shadowMapPoint[0], ld, -normalize(ld), pointBias, lightProj, vec3(0.0));
#endif
#endif

View file

@ -63,7 +63,7 @@
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrixSun",
"link": "_biasLightWorldViewProjectionMatrix",
"ifndef": ["_CSM"],
"ifdef": ["_Sun", "_ShadowMap"]
},
@ -108,32 +108,23 @@
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpotArray",
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
},
{
"name": "LWVPSpot[0]",
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[1]",
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[2]",
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot[3]",
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_Spot", "_ShadowMap"]
}
],

View file

@ -0,0 +1,172 @@
#version 450
#include "compiled.inc"
#ifdef _EnvTex
#include "std/math.glsl"
#endif
#ifdef _EnvCol
uniform vec3 backgroundCol;
#endif
#ifdef _EnvSky
uniform vec3 A;
uniform vec3 B;
uniform vec3 C;
uniform vec3 D;
uniform vec3 E;
uniform vec3 F;
uniform vec3 G;
uniform vec3 H;
uniform vec3 I;
uniform vec3 Z;
uniform vec3 hosekSunDirection;
#endif
#ifdef _EnvClouds
uniform sampler3D scloudsBase;
uniform sampler3D scloudsDetail;
uniform sampler2D scloudsMap;
uniform float time;
#endif
#ifdef _EnvTex
uniform sampler2D envmap;
#endif
#ifdef _EnvImg // Static background
uniform vec2 screenSize;
uniform sampler2D envmap;
#endif
#ifdef _EnvStr
uniform float envmapStrength;
#endif
in vec3 normal;
out vec4 fragColor;
#ifdef _EnvSky
vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) {
vec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5));
return (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta));
}
#endif
#ifdef _EnvClouds
// GPU PRO 7 - Real-time Volumetric Cloudscapes
// https://www.guerrilla-games.com/read/the-real-time-volumetric-cloudscapes-of-horizon-zero-dawn
// https://github.com/sebh/TileableVolumeNoise
float remap(float old_val, float old_min, float old_max, float new_min, float new_max) {
return new_min + (((old_val - old_min) / (old_max - old_min)) * (new_max - new_min));
}
float getDensityHeightGradientForPoint(float height, float cloud_type) {
const vec4 stratusGrad = vec4(0.02f, 0.05f, 0.09f, 0.11f);
const vec4 stratocumulusGrad = vec4(0.02f, 0.2f, 0.48f, 0.625f);
const vec4 cumulusGrad = vec4(0.01f, 0.0625f, 0.78f, 1.0f);
float stratus = 1.0f - clamp(cloud_type * 2.0f, 0, 1);
float stratocumulus = 1.0f - abs(cloud_type - 0.5f) * 2.0f;
float cumulus = clamp(cloud_type - 0.5f, 0, 1) * 2.0f;
vec4 cloudGradient = stratusGrad * stratus + stratocumulusGrad * stratocumulus + cumulusGrad * cumulus;
return smoothstep(cloudGradient.x, cloudGradient.y, height) - smoothstep(cloudGradient.z, cloudGradient.w, height);
}
float sampleCloudDensity(vec3 p) {
float cloud_base = textureLod(scloudsBase, p, 0).r * 40; // Base noise
vec3 weather_data = textureLod(scloudsMap, p.xy, 0).rgb; // Weather map
cloud_base *= getDensityHeightGradientForPoint(p.z, weather_data.b); // Cloud type
cloud_base = remap(cloud_base, weather_data.r, 1.0, 0.0, 1.0); // Coverage
cloud_base *= weather_data.r;
float cloud_detail = textureLod(scloudsDetail, p, 0).r * 2; // Detail noise
float cloud_detail_mod = mix(cloud_detail, 1.0 - cloud_detail, clamp(p.z * 10.0, 0, 1));
cloud_base = remap(cloud_base, cloud_detail_mod * 0.2, 1.0, 0.0, 1.0);
return cloud_base;
}
float cloudRadiance(vec3 p, vec3 dir){
#ifdef _EnvSky
vec3 sun_dir = hosekSunDirection;
#else
vec3 sun_dir = vec3(0, 0, -1);
#endif
const int steps = 8;
float step_size = 0.5 / float(steps);
float d = 0.0;
p += sun_dir * step_size;
for(int i = 0; i < steps; ++i) {
d += sampleCloudDensity(p + sun_dir * float(i) * step_size);
}
return 1.0 - d;
}
vec3 traceClouds(vec3 sky, vec3 dir) {
const float step_size = 0.5 / float(cloudsSteps);
float T = 1.0;
float C = 0.0;
vec2 uv = dir.xy / dir.z * 0.4 * cloudsLower + cloudsWind * time * 0.02;
for (int i = 0; i < cloudsSteps; ++i) {
float h = float(i) / float(cloudsSteps);
vec3 p = vec3(uv * 0.04, h);
float d = sampleCloudDensity(p);
if (d > 0) {
// float radiance = cloudRadiance(p, dir);
C += T * exp(h) * d * step_size * 0.6 * cloudsPrecipitation;
T *= exp(-d * step_size);
if (T < 0.01) break;
}
uv += (dir.xy / dir.z) * step_size * cloudsUpper;
}
return vec3(C) + sky * T;
}
#endif // _EnvClouds
void main() {
#ifdef _EnvCol
fragColor.rgb = backgroundCol;
#ifdef _EnvTransp
return;
#endif
#ifdef _EnvClouds
vec3 n = normalize(normal);
#endif
#endif
#ifndef _EnvSky // Prevent case when sky radiance is enabled
#ifdef _EnvTex
vec3 n = normalize(normal);
fragColor.rgb = texture(envmap, envMapEquirect(n)).rgb * envmapStrength;
#ifdef _EnvLDR
fragColor.rgb = pow(fragColor.rgb, vec3(2.2));
#endif
#endif
#endif
#ifdef _EnvImg // Static background
// Will have to get rid of gl_FragCoord, pass tc from VS
vec2 texco = gl_FragCoord.xy / screenSize;
fragColor.rgb = texture(envmap, vec2(texco.x, 1.0 - texco.y)).rgb * envmapStrength;
#endif
#ifdef _EnvSky
vec3 n = normalize(normal);
float phi = acos(n.z);
float theta = atan(-n.y, n.x) + PI;
float cos_theta = clamp(n.z, 0.0, 1.0);
float cos_gamma = dot(n, hosekSunDirection);
float gamma_val = acos(cos_gamma);
fragColor.rgb = Z * hosekWilkie(cos_theta, gamma_val, cos_gamma) * envmapStrength;
#endif
#ifdef _EnvClouds
if (n.z > 0.0) fragColor.rgb = mix(fragColor.rgb, traceClouds(fragColor.rgb, n), clamp(n.z * 5.0, 0, 1));
#endif
#ifdef _LDR
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
#endif
fragColor.a = 0.0; // Mark as non-opaque
}

View file

@ -0,0 +1,114 @@
{
"contexts": [
{
"name": "world_pass",
"depth_write": false,
"compare_mode": "less",
"cull_mode": "clockwise",
"links": [
{
"name": "SMVP",
"link": "_skydomeMatrix"
},
{
"name": "backgroundCol",
"link": "_backgroundCol",
"ifdef": ["_EnvCol"]
},
{
"name": "A",
"link": "_hosekA",
"ifdef": ["_EnvSky"]
},
{
"name": "B",
"link": "_hosekB",
"ifdef": ["_EnvSky"]
},
{
"name": "C",
"link": "_hosekC",
"ifdef": ["_EnvSky"]
},
{
"name": "D",
"link": "_hosekD",
"ifdef": ["_EnvSky"]
},
{
"name": "E",
"link": "_hosekE",
"ifdef": ["_EnvSky"]
},
{
"name": "F",
"link": "_hosekF",
"ifdef": ["_EnvSky"]
},
{
"name": "G",
"link": "_hosekG",
"ifdef": ["_EnvSky"]
},
{
"name": "H",
"link": "_hosekH",
"ifdef": ["_EnvSky"]
},
{
"name": "I",
"link": "_hosekI",
"ifdef": ["_EnvSky"]
},
{
"name": "Z",
"link": "_hosekZ",
"ifdef": ["_EnvSky"]
},
{
"name": "hosekSunDirection",
"link": "_hosekSunDirection",
"ifdef": ["_EnvSky"]
},
{
"name": "time",
"link": "_time",
"ifdef": ["_EnvClouds"]
},
{
"name": "scloudsBase",
"link": "$clouds_base.raw",
"ifdef": ["_EnvClouds"]
},
{
"name": "scloudsDetail",
"link": "$clouds_detail.raw",
"ifdef": ["_EnvClouds"]
},
{
"name": "scloudsMap",
"link": "$clouds_map.png",
"ifdef": ["_EnvClouds"]
},
{
"name": "screenSize",
"link": "_screenSize",
"ifdef": ["_EnvImg"]
},
{
"name": "envmap",
"link": "_envmap",
"ifdef": ["_EnvTex", "_EnvImg"]
},
{
"name": "envmapStrength",
"link": "_envmapStrength",
"ifdef": ["_EnvStr"]
}
],
"texture_params": [],
"vertex_shader": "world_pass.vert.glsl",
"fragment_shader": "world_pass.frag.glsl"
}
]
}

View file

@ -0,0 +1,14 @@
#version 450
in vec3 pos;
in vec3 nor;
out vec3 normal;
uniform mat4 SMVP;
void main() {
normal = nor;
vec4 position = SMVP * vec4(pos, 1.0);
gl_Position = vec4(position);
}

View file

@ -2,22 +2,22 @@ package armory.data;
class Config {
public static var raw: TConfig = null;
public static var raw:TConfig = null;
public static var configLoaded = false;
public static function load(done: Void->Void) {
public static function load(done:Void->Void) {
try {
iron.data.Data.getBlob("config.arm", function(blob: kha.Blob) {
iron.data.Data.getBlob('config.arm', function(blob:kha.Blob) {
configLoaded = true;
raw = haxe.Json.parse(blob.toString());
done();
});
}
catch (e: Dynamic) { done(); }
catch(e:Dynamic) { done(); }
}
public static function save() {
var path = iron.data.Data.dataPath + "config.arm";
var path = iron.data.Data.dataPath + 'config.arm';
var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(raw));
#if kha_krom
Krom.fileSaveBytes(path, bytes.getData());
@ -30,23 +30,23 @@ class Config {
}
typedef TConfig = {
@:optional var debug_console: Null<Bool>;
@:optional var window_mode: Null<Int>; // window, fullscreen
@:optional var window_w: Null<Int>;
@:optional var window_h: Null<Int>;
@:optional var window_resizable: Null<Bool>;
@:optional var window_maximizable: Null<Bool>;
@:optional var window_minimizable: Null<Bool>;
@:optional var window_vsync: Null<Bool>;
@:optional var window_msaa: Null<Int>;
@:optional var window_scale: Null<Float>;
@:optional var rp_supersample: Null<Float>;
@:optional var rp_shadowmap_cube: Null<Int>; // size
@:optional var rp_shadowmap_cascade: Null<Int>; // size for single cascade
@:optional var rp_ssgi: Null<Bool>;
@:optional var rp_ssr: Null<Bool>;
@:optional var rp_bloom: Null<Bool>;
@:optional var rp_motionblur: Null<Bool>;
@:optional var rp_gi: Null<Bool>; // voxelao
@:optional var rp_dynres: Null<Bool>; // dynamic resolution scaling
@:optional var debug_console:Null<Bool>;
@:optional var window_mode:Null<Int>; // window, fullscreen
@:optional var window_w:Null<Int>;
@:optional var window_h:Null<Int>;
@:optional var window_resizable:Null<Bool>;
@:optional var window_maximizable:Null<Bool>;
@:optional var window_minimizable:Null<Bool>;
@:optional var window_vsync:Null<Bool>;
@:optional var window_msaa:Null<Int>;
@:optional var window_scale:Null<Float>;
@:optional var rp_supersample:Null<Float>;
@:optional var rp_shadowmap_cube:Null<Int>; // size
@:optional var rp_shadowmap_cascade:Null<Int>; // size for single cascade
@:optional var rp_ssgi:Null<Bool>;
@:optional var rp_ssr:Null<Bool>;
@:optional var rp_bloom:Null<Bool>;
@:optional var rp_motionblur:Null<Bool>;
@:optional var rp_gi:Null<Bool>; // voxelao
@:optional var rp_dynres:Null<Bool>; // dynamic resolution scaling
}

View file

@ -0,0 +1,178 @@
package armory.data;
import kha.graphics4.VertexBuffer;
import kha.graphics4.IndexBuffer;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
import kha.graphics4.VertexData;
import kha.graphics4.PipelineState;
import kha.graphics4.CompareMode;
import kha.graphics4.CullMode;
import kha.graphics4.ConstantLocation;
import iron.math.Vec4;
import iron.object.Transform;
import iron.data.SceneFormat;
import iron.data.ShaderData;
import iron.data.ShaderData.ShaderContext;
class GreasePencilData extends Data {
public var name:String;
public var raw:TGreasePencilData;
public var layers:Array<GreasePencilLayer>;
public static var shaderData:ShaderData = null;
public static var structure:VertexStructure = null;
public static var usage:Usage;
public static var frameEnd = 0;
static var first = true;
public function new(raw:TGreasePencilData, done:GreasePencilData->Void) {
super();
this.raw = raw;
this.name = raw.name;
if (structure == null) {
structure = new VertexStructure();
structure.add("pos", VertexData.Float3);
structure.add("col", VertexData.Float4);
usage = Usage.StaticUsage;
}
if (first) {
first = false;
var shaderName:Array<String> = raw.shader.split("/");
Data.getShader(shaderName[0], shaderName[1], null, function(b:ShaderData) {
shaderData = b;
makeLayers(done);
});
}
else makeLayers(done);
}
function makeLayers(done:GreasePencilData->Void) {
layers = [];
for (l in raw.layers) {
layers.push(new GreasePencilLayer(l));
}
done(this);
}
public static function parse(name:String, id:String, done:GreasePencilData->Void) {
Data.getSceneRaw(name, function(format:TSceneFormat) {
var raw:TGreasePencilData = Data.getGreasePencilRawByName(format.grease_pencil_datas, id);
if (raw == null) {
trace('Grease pencil data "$id" not found!');
done(null);
}
new GreasePencilData(raw, done);
});
}
public static function getContext(name:String):ShaderContext {
return shaderData.getContext(name);
}
}
class GreasePencilLayer {
public var name:String;
public var frames:Array<GreasePencilFrame>;
public var currentFrame = 0;
public function new(l:TGreasePencilLayer) {
name = l.name;
frames = [];
for (f in l.frames) {
frames.push(new GreasePencilFrame(f));
}
}
}
class GreasePencilFrame {
public var vertexBuffer:VertexBuffer;
public var vertexStrokeBuffer:VertexBuffer;
public var indexBuffer:IndexBuffer;
public var raw:TGreasePencilFrame;
public var numVertices:Int;
public function new(f:TGreasePencilFrame) {
raw = f;
var va = f.vertex_array.values;
var cola = f.col_array.values;
var colfilla = f.colfill_array.values;
var indices = f.index_array.values;
numVertices = Std.int(va.length / 3);
// Fill
vertexBuffer = new VertexBuffer(numVertices, GreasePencilData.structure, GreasePencilData.usage);
var vertices = vertexBuffer.lock();
var di = -1;
for (i in 0...numVertices) {
vertices.set(++di, va[i * 3]); // Positions
vertices.set(++di, va[i * 3 + 1]);
vertices.set(++di, va[i * 3 + 2]);
vertices.set(++di, colfilla[i * 4]); // Fill color
vertices.set(++di, colfilla[i * 4 + 1]);
vertices.set(++di, colfilla[i * 4 + 2]);
vertices.set(++di, colfilla[i * 4 + 3]);
}
vertexBuffer.unlock();
indexBuffer = new IndexBuffer(indices.length, GreasePencilData.usage);
var indicesA = indexBuffer.lock();
for (i in 0...indicesA.length) indicesA[i] = indices[i];
indexBuffer.unlock();
// Stroke
vertexStrokeBuffer = new VertexBuffer(numVertices, GreasePencilData.structure, GreasePencilData.usage);
vertices = vertexStrokeBuffer.lock();
di = -1;
for (i in 0...numVertices) {
vertices.set(++di, va[i * 3]); // Positions
vertices.set(++di, va[i * 3 + 1]);
vertices.set(++di, va[i * 3 + 2]);
vertices.set(++di, cola[i * 4]); // Stroke color
vertices.set(++di, cola[i * 4 + 1]);
vertices.set(++di, cola[i * 4 + 2]);
vertices.set(++di, cola[i * 4 + 3]);
}
vertexStrokeBuffer.unlock();
// Store max frame number of all layers
if (GreasePencilData.frameEnd < raw.frame_number) {
GreasePencilData.frameEnd = raw.frame_number;
}
}
public function delete() {
vertexBuffer.delete();
}
}
typedef TGreasePencilFormat = {
@:optional var grease_pencil_datas:Array<TGreasePencilData>;
@:optional var grease_pencil_ref:String;
}
typedef TGreasePencilData = {
var name:String;
var layers:Array<TGreasePencilLayer>;
var shader:String;
}
typedef TGreasePencilLayer = {
var name:String;
var opacity:Float;
var frames:Array<TGreasePencilFrame>;
}
typedef TGreasePencilFrame = {
var frame_number:Int;
var vertex_array:TVertexArray;
var col_array:TVertexArray;
var colfill_array:TVertexArray;
var index_array:TIndexArray;
var num_stroke_points:Uint32Array;
}

View file

@ -1 +0,0 @@
import armory.system.Assert.*;

View file

@ -2,9 +2,9 @@ package armory.logicnode;
class ActiveCameraNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic { return iron.Scene.active.camera; }
override function get(from:Int):Dynamic { return iron.Scene.active.camera; }
}

View file

@ -2,9 +2,9 @@ package armory.logicnode;
class ActiveSceneNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic { return iron.Scene.active.raw.name; }
override function get(from:Int):Dynamic { return iron.Scene.active.raw.name; }
}

View file

@ -1,17 +1,15 @@
package armory.logicnode;
import kha.arrays.Float32Array;
class AddGroupNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var groupName: String = inputs[1].get();
override function run(from:Int) {
var groupName:String = inputs[1].get();
var raw = iron.Scene.active.raw;
// Already exists
for (g in raw.groups) {
if (g.name == groupName) {
@ -20,7 +18,7 @@ class AddGroupNode extends LogicNode {
}
}
raw.groups.push({ name: groupName, object_refs: [], instance_offset: new Float32Array(3)});
raw.groups.push({ name: groupName, object_refs: [] });
runOutput(0);
}
}

View file

@ -1,114 +0,0 @@
package armory.logicnode;
import iron.object.Object;
#if arm_physics
import armory.trait.physics.PhysicsConstraint;
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintType;
#end
class AddPhysicsConstraintNode extends LogicNode {
public var property0: String;//Type
public var object: Object;
public var rb1: Object;
public var rb2: Object;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
var pivotObject: Object = inputs[1].get();
rb1 = inputs[2].get();
rb2 = inputs[3].get();
if (pivotObject == null || rb1 == null || rb2 == null) return;
#if arm_physics
var disableCollisions: Bool = inputs[4].get();
var breakable: Bool = inputs[5].get();
var breakingThreshold: Float = inputs[6].get();
var type: ConstraintType = 0;
var con: PhysicsConstraint = pivotObject.getTrait(PhysicsConstraint);
if (con == null) {
switch (property0) {
case "Fixed": type = Fixed;
case "Point": type = Point;
case "Hinge": type = Hinge;
case "Slider": type = Slider;
case "Piston": type = Piston;
case "Generic Spring": type = Generic;
}
if (!breakable) breakingThreshold = 0.0;
if (type != Generic) {
con = new PhysicsConstraint(rb1, rb2, type, disableCollisions, breakingThreshold);
switch (type) {
case Hinge:
var setLimit: Bool = inputs[7].get();
var low: Float = inputs[8].get();
var up: Float = inputs[9].get();
con.setHingeConstraintLimits(setLimit, low, up);
case Slider:
var setLimit: Bool = inputs[7].get();
var low: Float = inputs[8].get();
var up: Float = inputs[9].get();
con.setSliderConstraintLimits(setLimit, low, up);
case Piston:
var setLinLimit: Bool = inputs[7].get();
var linLow: Float = inputs[8].get();
var linUp: Float = inputs[9].get();
var setAngLimit: Bool = inputs[10].get();
var angLow: Float = inputs[11].get();
var angUp: Float = inputs[12].get();
con.setPistonConstraintLimits(setLinLimit, linLow, linUp, setAngLimit, angLow, angUp);
default:
}
}
else {
var spring: Bool = false;
var prop: PhysicsConstraintNode;
for (inp in 7...inputs.length) {
prop = inputs[inp].get();
if (prop == null) continue;
if (prop.isSpring) {
spring = true;
break;
}
}
if (spring) {
con = new PhysicsConstraint(rb1, rb2, GenericSpring, disableCollisions, breakingThreshold);
}
else {
con = new PhysicsConstraint(rb1, rb2, Generic, disableCollisions, breakingThreshold);
}
for (inp in 7...inputs.length) {
prop = inputs[inp].get();
if (prop == null) continue;
if (prop.isSpring) {
con.setSpringParams(prop.isSpring, prop.value1, prop.value2, prop.axis, prop.isAngular);
}
else {
con.setGenericConstraintLimits(true, prop.value1, prop.value2, prop.axis, prop.isAngular);
}
}
}
pivotObject.addTrait(con);
}
#end
runOutput(0);
}
}

View file

@ -1,97 +0,0 @@
package armory.logicnode;
import iron.object.Object;
#if arm_physics
import armory.trait.physics.RigidBody;
import armory.trait.physics.bullet.RigidBody.Shape;
#end
class AddRigidBodyNode extends LogicNode {
public var property0: String; //Shape
public var property1: Bool; //Advanced
public var object: Object;
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
object = inputs[1].get();
if (object == null) return;
#if arm_physics
var mass: Float = inputs[2].get();
var active: Bool = inputs[3].get();
var animated: Bool = inputs[4].get();
var trigger: Bool = inputs[5].get();
var friction: Float = inputs[6].get();
var bounciness: Float = inputs[7].get();
var ccd: Bool = inputs[8].get();
var margin: Bool = false;
var marginLen: Float = 0.0;
var linDamp: Float = 0.0;
var angDamp: Float = 0.0;
var useDeactiv: Bool = false;
var linearVelThreshold: Float = 0.0;
var angVelThreshold: Float = 0.0;
var group: Int = 1;
var mask: Int = 1;
var shape: Shape = 1;
if (property1) {
margin = inputs[9].get();
marginLen = inputs[10].get();
linDamp = inputs[11].get();
angDamp = inputs[12].get();
useDeactiv = inputs[13].get();
linearVelThreshold = inputs[14].get();
angVelThreshold = inputs[15].get();
group = inputs[16].get();
mask = inputs[17].get();
}
var rb: RigidBody = object.getTrait(RigidBody);
if ((group < 0) || (group > 32)) group = 1; //Limiting max groups to 32
if ((mask < 0) || (mask > 32)) mask = 1; //Limiting max masks to 32
if (rb == null) {
switch (property0) {
case "Box": shape = Box;
case "Sphere": shape = Sphere;
case "Capsule": shape = Capsule;
case "Cone": shape = Cone;
case "Cylinder": shape = Cylinder;
case "Convex Hull": shape = ConvexHull;
case "Mesh": shape = Mesh;
}
rb = new RigidBody(shape, mass, friction, bounciness, group, mask);
rb.animated = animated;
rb.staticObj = !active;
rb.isTriggerObject(trigger);
if (property1) {
rb.linearDamping = linDamp;
rb.angularDamping = angDamp;
if (margin) rb.collisionMargin = marginLen;
if (useDeactiv) {
rb.setUpDeactivation(true, linearVelThreshold, angVelThreshold, 0.0);
}
}
object.addTrait(rb);
}
#end
runOutput(0);
}
override function get(from: Int): Object {
return object;
}
}

View file

@ -4,23 +4,16 @@ import iron.object.Object;
class AddTraitNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var traitName: String = inputs[2].get();
override function run(from:Int) {
var object:Object = inputs[1].get();
var trait:Dynamic = inputs[2].get();
if (object == null || trait == null) return;
assert(Error, object != null, "Object should not be null");
assert(Error, traitName != null, "Trait name should not be null");
var cname = Type.resolveClass(Main.projectPackage + "." + traitName);
if (cname == null) cname = Type.resolveClass(Main.projectPackage + ".node." + traitName);
assert(Error, cname != null, 'No trait with the name "$traitName" found, make sure that the trait is exported!');
assert(Warning, object.getTrait(cname) == null, 'Object already has the trait "$traitName" applied');
var trait = Type.createInstance(cname, []);
object.addTrait(trait);
runOutput(0);

View file

@ -4,11 +4,11 @@ class AlternateNode extends LogicNode {
var b = true;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
override function run(from:Int) {
b ? runOutput(0) : runOutput(1);
b = !b;
}

View file

@ -2,19 +2,19 @@ package armory.logicnode;
class AnimActionNode extends LogicNode {
public var value: String;
public var value:String;
public function new(tree: LogicTree, value = "") {
public function new(tree:LogicTree, value = "") {
super(tree);
this.value = value;
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (inputs.length > 0) return inputs[0].get();
return value;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
if (inputs.length > 0) inputs[0].set(value);
else this.value = value;
}

View file

@ -4,24 +4,19 @@ import iron.object.Object;
class AnimationStateNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
override function get(from:Int):Dynamic {
var object:Object = inputs[0].get();
if (object == null) return null;
var animation = object.animation;
if (animation == null) animation = object.getParentArmature(object.name);
return switch (from) {
case 0: animation.action;
case 1: animation.currentFrame();
case 2: animation.paused;
default: null;
}
if (from == 0) return !animation.paused; // is playing
else if (from == 1) return animation.action;
else return animation.currentFrame();
}
}

View file

@ -8,13 +8,13 @@ import armory.trait.physics.RigidBody;
class AppendTransformNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var matrix: Mat4 = inputs[2].get();
override function run(from:Int) {
var object:Object = inputs[1].get();
var matrix:Mat4 = inputs[2].get();
if (object == null || matrix == null) return;

View file

@ -4,34 +4,35 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyForceAtLocationNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var force: Vec4 = inputs[2].get();
var localForce: Bool = inputs.length > 3 ? inputs[3].get() : false;
var location: Vec4 = inputs[4].get();
var localLoc: Bool = inputs.length > 5 ? inputs[5].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var force:Vec4 = inputs[2].get();
var location:Vec4 = inputs[3].get();
var local:Bool = inputs.length > 3 ? inputs[3].get() : false;
if (object == null || force == null || location == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
if (localLoc) {
location.applyQuat(object.transform.rot);
var rb:RigidBody = object.getTrait(RigidBody);
if (!local) {
rb.applyForce(force, location);
}
else {
var look = object.transform.world.look().mult(force.y);
var right = object.transform.world.right().mult(force.x);
var up = object.transform.world.up().mult(force.z);
rb.applyForce(look, location);
rb.applyForce(right, location);
rb.applyForce(up, location);
}
!localForce ? rb.applyForce(force, location) : rb.applyForce(object.transform.worldVecToOrientation(force), location);
#end
runOutput(0);
}
}

View file

@ -4,28 +4,34 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyForceNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var force: Vec4 = inputs[2].get();
var local: Bool = inputs.length > 3 ? inputs[3].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var force:Vec4 = inputs[2].get();
var local:Bool = inputs.length > 3 ? inputs[3].get() : false;
if (object == null || force == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
!local ? rb.applyForce(force) : rb.applyForce(object.transform.worldVecToOrientation(force));
var rb:RigidBody = object.getTrait(RigidBody);
if (!local) {
rb.applyForce(force);
}
else {
var look = object.transform.world.look().mult(force.y);
var right = object.transform.world.right().mult(force.x);
var up = object.transform.world.up().mult(force.z);
rb.applyForce(look);
rb.applyForce(right);
rb.applyForce(up);
}
#end
runOutput(0);
}
}

View file

@ -4,34 +4,34 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyImpulseAtLocationNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var impulse: Vec4 = inputs[2].get();
var localImpulse: Bool = inputs.length > 3 ? inputs[3].get() : false;
var location: Vec4 = inputs[4].get();
var localLoc: Bool = inputs.length > 5 ? inputs[5].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var impulse:Vec4 = inputs[2].get();
var location:Vec4 = inputs[3].get();
var local:Bool = inputs.length > 3 ? inputs[3].get() : false;
if (object == null || impulse == null || location == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
if (localLoc) {
location.applyQuat(object.transform.rot);
var rb:RigidBody = object.getTrait(RigidBody);
if (!local) {
rb.applyImpulse(impulse, location); }
else {
var look = object.transform.world.look().mult(impulse.y);
var right = object.transform.world.right().mult(impulse.x);
var up = object.transform.world.up().mult(impulse.z);
rb.applyImpulse(look, location);
rb.applyImpulse(right, location);
rb.applyImpulse(up, location);
}
!localImpulse ? rb.applyImpulse(impulse, location) : rb.applyImpulse(object.transform.worldVecToOrientation(impulse), location);
#end
runOutput(0);
}
}

View file

@ -4,28 +4,34 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyImpulseNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var impulse: Vec4 = inputs[2].get();
var local: Bool = inputs.length > 3 ? inputs[3].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var impulse:Vec4 = inputs[2].get();
var local:Bool = inputs.length > 3 ? inputs[3].get() : false;
if (object == null || impulse == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
!local ? rb.applyImpulse(impulse) : rb.applyImpulse(object.transform.worldVecToOrientation(impulse));
var rb:RigidBody = object.getTrait(RigidBody);
if (!local) {
rb.applyImpulse(impulse);
}
else {
var look = object.transform.world.look().mult(impulse.y);
var right = object.transform.world.right().mult(impulse.x);
var up = object.transform.world.up().mult(impulse.z);
rb.applyImpulse(look);
rb.applyImpulse(right);
rb.applyImpulse(up);
}
#end
runOutput(0);
}
}

View file

@ -4,28 +4,23 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyTorqueImpulseNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var torque: Vec4 = inputs[2].get();
var local: Bool = inputs.length > 3 ? inputs[3].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var torque:Vec4 = inputs[2].get();
if (object == null || torque == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
!local ? rb.applyTorqueImpulse(torque) : rb.applyTorqueImpulse(object.transform.worldVecToOrientation(torque));
var rb:RigidBody = object.getTrait(RigidBody);
rb.applyTorqueImpulse(torque);
#end
runOutput(0);
}
}

View file

@ -4,28 +4,23 @@ import iron.object.Object;
import iron.math.Vec4;
import armory.trait.physics.RigidBody;
using armory.object.TransformExtension;
class ApplyTorqueNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: Object = inputs[1].get();
var torque: Vec4 = inputs[2].get();
var local: Bool = inputs.length > 3 ? inputs[3].get() : false;
override function run(from:Int) {
var object:Object = inputs[1].get();
var torque:Vec4 = inputs[2].get();
if (object == null || torque == null) return;
#if arm_physics
var rb: RigidBody = object.getTrait(RigidBody);
!local ? rb.applyTorque(torque) : rb.applyTorque(object.transform.worldVecToOrientation(torque));
var rb:RigidBody = object.getTrait(RigidBody);
rb.applyTorque(torque);
#end
runOutput(0);
}
}

View file

@ -2,38 +2,21 @@ package armory.logicnode;
class ArrayAddNode extends LogicNode {
var ar: Array<Dynamic>;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
ar = inputs[1].get();
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
// "Modify Original" == `false` -> Copy the input array
if (!inputs[2].get()) {
ar = ar.copy();
}
if (inputs.length > 4) {
for (i in 4...inputs.length) {
var value: Dynamic = inputs[i].get();
// "Unique Values" options only supports primitive data types
// for now, a custom indexOf() or contains() method would be
// required to compare values of other types
if (!inputs[3].get() || ar.indexOf(value) == -1) {
ar.push(value);
}
if (inputs.length > 2) {
for (i in 2...inputs.length) {
var value:Dynamic = inputs[i].get();
ar.push(value);
}
}
runOutput(0);
}
override function get(from: Int): Dynamic {
return ar;
}
}

View file

@ -0,0 +1,22 @@
package armory.logicnode;
class ArrayAddUniqueNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
if (inputs.length > 2) {
for (i in 2...inputs.length) {
var value:Dynamic = inputs[i].get();
if (ar.indexOf(value) == -1) ar.push(value);
}
}
runOutput(0);
}
}

View file

@ -2,18 +2,18 @@ package armory.logicnode;
class ArrayBooleanNode extends LogicNode {
public var value: Array<Bool> = [];
public var value:Array<Bool> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Bool = inp.get();
var val:Bool = inp.get();
value.push(val);
}
}
@ -21,7 +21,7 @@ class ArrayBooleanNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -4,18 +4,18 @@ import iron.math.Vec4;
class ArrayColorNode extends LogicNode {
public var value: Array<Vec4> = [];
public var value:Array<Vec4> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Vec4 = inp.get();
var val:Vec4 = inp.get();
value.push(val);
}
}
@ -23,7 +23,7 @@ class ArrayColorNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -2,18 +2,18 @@ package armory.logicnode;
class ArrayFloatNode extends LogicNode {
public var value: Array<Float> = [];
public var value:Array<Float> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Float = inp.get();
var val:Float = inp.get();
value.push(val);
}
}
@ -21,7 +21,7 @@ class ArrayFloatNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -2,26 +2,21 @@ package armory.logicnode;
class ArrayGetNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var ar: Array<Dynamic> = inputs[0].get();
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
if (ar == null) return null;
var i: Int = inputs[1].get();
var i:Int = inputs[1].get();
if (i < 0) i = ar.length + i;
if (i < 0 || i > ar.length - 1) {
var className = Type.getClassName(Type.getClass(tree));
var traitName = className.substring(className.lastIndexOf(".") + 1);
var objectName = tree.object.name;
trace('Logic error (object: $objectName, trait: $traitName): Array Get - index out of range');
return null;
}
return ar[i];

View file

@ -2,14 +2,14 @@ package armory.logicnode;
class ArrayInArrayNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var array: Array<Dynamic> = inputs[0].get();
var value: Dynamic = inputs[1].get();
override function get(from:Int):Dynamic {
var array:Array<Dynamic> = inputs[0].get();
var value:Dynamic = inputs[1].get();
return array.indexOf(value) != -1;
return ! (array.indexOf(value) == -1);
}
}

View file

@ -2,18 +2,18 @@ package armory.logicnode;
class ArrayIntegerNode extends LogicNode {
public var value: Array<Int> = [];
public var value:Array<Int> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Int = inp.get();
var val:Int = inp.get();
value.push(val);
}
}
@ -21,7 +21,7 @@ class ArrayIntegerNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -2,12 +2,12 @@ package armory.logicnode;
class ArrayLengthNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var ar: Array<Dynamic> = inputs[0].get();
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
return ar != null ? ar.length : 0;
}
}

View file

@ -2,21 +2,18 @@ package armory.logicnode;
class ArrayLoopNode extends LogicNode {
var value: Dynamic;
var index: Int;
var value:Dynamic;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var ar: Array<Dynamic> = inputs[1].get();
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
index = -1;
for (val in ar) {
value = val;
index++;
runOutput(0);
if (tree.loopBreak) {
@ -24,12 +21,10 @@ class ArrayLoopNode extends LogicNode {
break;
}
}
runOutput(3);
runOutput(2);
}
override function get(from: Int): Dynamic {
if (from == 1)
return value;
return index;
override function get(from:Int):Dynamic {
return value;
}
}

View file

@ -2,18 +2,18 @@ package armory.logicnode;
class ArrayNode extends LogicNode {
public var value: Array<Dynamic> = [];
public var value:Array<Dynamic> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Dynamic = inp.get();
var val:Dynamic = inp.get();
value.push(val);
}
}
@ -21,7 +21,7 @@ class ArrayNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -4,18 +4,18 @@ import iron.object.Object;
class ArrayObjectNode extends LogicNode {
public var value: Array<Object> = [];
public var value:Array<Object> = [];
var initialized = false;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
if (!initialized) {
initialized = true;
for (inp in inputs) {
var val: Object = inp.get();
var val:Object = inp.get();
value.push(val);
}
}
@ -23,7 +23,7 @@ class ArrayObjectNode extends LogicNode {
return from == 0 ? value : value.length;
}
override function set(value: Dynamic) {
override function set(value:Dynamic) {
this.value = value;
}
}

View file

@ -2,14 +2,14 @@ package armory.logicnode;
class ArrayPopNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var ar: Array<Dynamic> = inputs[0].get();
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
if (ar == null) return null;
return ar.pop();
}
}

View file

@ -2,17 +2,17 @@ package armory.logicnode;
class ArrayRemoveNode extends LogicNode {
var removedValue: Dynamic = null;
var removedValue:Dynamic = null;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var ar: Array<Dynamic> = inputs[1].get();
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
var i: Int = inputs[2].get();
var i:Int = inputs[2].get();
if (i < 0) i = ar.length + i;
removedValue = ar[i];
@ -21,7 +21,7 @@ class ArrayRemoveNode extends LogicNode {
runOutput(0);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
return removedValue;
}
}

View file

@ -2,17 +2,17 @@ package armory.logicnode;
class ArrayRemoveValueNode extends LogicNode {
var removedValue: Dynamic = null;
var removedValue:Dynamic = null;
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var ar: Array<Dynamic> = inputs[1].get();
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
var val: Dynamic = inputs[2].get();
var val:Dynamic = inputs[2].get();
removedValue = val;
ar.remove(val);
@ -20,7 +20,7 @@ class ArrayRemoveValueNode extends LogicNode {
runOutput(0);
}
override function get(from: Int): Dynamic {
override function get(from:Int):Dynamic {
return removedValue;
}
}

View file

@ -2,16 +2,16 @@ package armory.logicnode;
class ArraySetNode extends LogicNode {
public function new(tree: LogicTree) {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from: Int) {
var ar: Array<Dynamic> = inputs[1].get();
override function run(from:Int) {
var ar:Array<Dynamic> = inputs[1].get();
if (ar == null) return;
var i: Int = inputs[2].get();
var value: Dynamic = inputs[3].get();
var i:Int = inputs[2].get();
var value:Dynamic = inputs[3].get();
if (i < 0) ar[ar.length + i] = value;
else ar[i] = value;

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