Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
c56fb4bbf1 |
22
.github/workflows/krom.yml
vendored
22
.github/workflows/krom.yml
vendored
|
@ -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
|
|
@ -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).
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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": [],
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#version 450
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
|
@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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": [],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#version 450
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = 1.0;
|
||||
fragColor = color;
|
||||
}
|
25
Shaders/grease_pencil/grease_pencil.json
Normal file
25
Shaders/grease_pencil/grease_pencil.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
13
Shaders/grease_pencil/grease_pencil.vert.glsl
Normal file
13
Shaders/grease_pencil/grease_pencil.vert.glsl
Normal 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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -25,16 +25,6 @@
|
|||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
},
|
||||
{
|
||||
"name": "PPComp11",
|
||||
"link": "_PPComp11",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp12",
|
||||
"link": "_PPComp12",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -21,16 +21,6 @@
|
|||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "PPComp9",
|
||||
"link": "_PPComp9",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp10",
|
||||
"link": "_PPComp10",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
],
|
||||
|
|
172
Shaders/world_pass/world_pass.frag.glsl
Normal file
172
Shaders/world_pass/world_pass.frag.glsl
Normal 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
|
||||
}
|
114
Shaders/world_pass/world_pass.json
Normal file
114
Shaders/world_pass/world_pass.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
14
Shaders/world_pass/world_pass.vert.glsl
Normal file
14
Shaders/world_pass/world_pass.vert.glsl
Normal 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);
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
178
Sources/armory/data/GreasePencilData.hx
Normal file
178
Sources/armory/data/GreasePencilData.hx
Normal 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;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
import armory.system.Assert.*;
|
|
@ -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; }
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
22
Sources/armory/logicnode/ArrayAddUniqueNode.hx
Normal file
22
Sources/armory/logicnode/ArrayAddUniqueNode.hx
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue