VGI work
This commit is contained in:
parent
e883227155
commit
0a51699aff
|
@ -14,11 +14,18 @@ precision mediump float;
|
|||
#ifdef _Irr
|
||||
#include "../std/shirr.glsl"
|
||||
#endif
|
||||
#ifdef _VoxelGI
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
#ifdef _VoxelGI
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
//!uniform vec4 shirr[7];
|
||||
|
@ -54,17 +61,38 @@ void main() {
|
|||
|
||||
vec2 metrough = unpackFloat(g0.b);
|
||||
|
||||
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, occlusion
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
||||
|
||||
#ifdef _Rad
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
vec3 p = getPos(eye, eyeLook, viewRay, depth);
|
||||
vec3 v = normalize(eye - p.xyz);
|
||||
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(metrough.y, 1.0 - dotNV)).xy;
|
||||
#endif
|
||||
|
||||
// Indirect
|
||||
#ifdef _VoxelGI
|
||||
vec3 indirectDiffuse = indirectDiffuseLight(n, p / voxelgiDimensions.x);
|
||||
|
||||
vec3 reflectWorld = reflect(-v, n);
|
||||
vec3 indirectSpecular = traceSpecularVoxelCone(p / voxelgiDimensions.x, reflectWorld, n, metrough.y * 10.0);
|
||||
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
|
||||
|
||||
fragColor.rgb = indirectDiffuse * 0.1 * albedo + indirectSpecular;
|
||||
fragColor.rgb *= texture(ssaotex, texCoord).r;
|
||||
|
||||
// if (opacity < 1.0) fragColor.rgb = mix(indirectRefractiveLight(-v), fragColor.rgb); // Transparency
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
vec3 indirect = shIrradiance(n, 2.2) / PI;
|
||||
fragColor.rgb = shIrradiance(n, 2.2) / PI;
|
||||
#else
|
||||
vec3 indirect = vec3(1.0);
|
||||
fragColor.rgb = vec3(1.0);
|
||||
#endif
|
||||
|
||||
#ifdef _Rad
|
||||
|
@ -74,32 +102,22 @@ void main() {
|
|||
#endif
|
||||
|
||||
#ifdef _EnvLDR
|
||||
indirect = pow(indirect, vec3(2.2));
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(2.2));
|
||||
#ifdef _Rad
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, occlusion
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
||||
indirect *= albedo;
|
||||
fragColor.rgb *= albedo;
|
||||
|
||||
#ifdef _Rad
|
||||
// Indirect specular
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
|
||||
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
|
||||
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(metrough.y, 1.0 - dotNV)).xy;
|
||||
indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
|
||||
#ifdef _Rad // Indirect specular
|
||||
fragColor.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
|
||||
#endif
|
||||
|
||||
indirect = indirect * envmapStrength;// * lightColor;
|
||||
indirect = indirect * g1.a; // Occlusion
|
||||
fragColor.rgb = fragColor.rgb * envmapStrength;// * lightColor;
|
||||
fragColor.rgb = fragColor.rgb * g1.a; // Occlusion
|
||||
|
||||
#ifdef _SSAO
|
||||
indirect *= texture(ssaotex, texCoord).r; // SSAO
|
||||
fragColor.rgb *= texture(ssaotex, texCoord).r; // SSAO
|
||||
#endif
|
||||
|
||||
fragColor.rgb = indirect;
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ precision mediump float;
|
|||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
#include "../std/math.glsl"
|
||||
// #ifdef _VoxelGI
|
||||
// #include "../std/conetrace.glsl"
|
||||
// #endif
|
||||
// #ifdef _PolyLight
|
||||
#include "../std/ltc.glsl"
|
||||
// #endif
|
||||
#ifdef _VoxelGI
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
|
@ -26,6 +26,10 @@ precision mediump float;
|
|||
// octahedronWrap()
|
||||
// unpackFloat()
|
||||
|
||||
// #ifdef _VoxelGI
|
||||
//-!uniform sampler3D voxels;
|
||||
// #endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
@ -38,12 +42,6 @@ uniform sampler2D gbuffer1;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
uniform sampler2D ssaotex;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
#ifdef _PolyLight
|
||||
//!uniform sampler2D sltcMat;
|
||||
//!uniform sampler2D sltcMag;
|
||||
|
@ -185,6 +183,14 @@ void main() {
|
|||
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
vec4 lampPos = LWVP * vec4(p, 1.0);
|
||||
if (lampPos.w > 0.0) {
|
||||
visibility = shadowTest(lampPos);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Per-light
|
||||
vec3 l;
|
||||
if (lightType == 0) { // Sun
|
||||
|
@ -192,6 +198,7 @@ void main() {
|
|||
}
|
||||
else { // Point, spot
|
||||
l = normalize(lightPos - p);
|
||||
visibility *= attenuate(distance(p, lightPos));
|
||||
}
|
||||
|
||||
vec3 h = normalize(v + l);
|
||||
|
@ -201,14 +208,6 @@ void main() {
|
|||
// float dotLV = dot(l, v);
|
||||
// float dotLH = dot(l, h);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
vec4 lampPos = LWVP * vec4(p, 1.0);
|
||||
if (lampPos.w > 0.0) {
|
||||
visibility = shadowTest(lampPos);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Direct
|
||||
vec3 direct;
|
||||
|
||||
|
@ -283,40 +282,10 @@ void main() {
|
|||
visibility *= tvis;
|
||||
#endif
|
||||
|
||||
// #ifdef _VoxelGI
|
||||
// if (dotNL > 0.0) visibility *= traceShadowCone(p / voxelgiResolution.x, l, distance(p, lightPos) / voxelgiResolution.x, n);
|
||||
// #endif
|
||||
|
||||
// Direct
|
||||
fragColor = vec4(vec3(direct * visibility), 1.0);
|
||||
|
||||
// Voxels test..
|
||||
#ifdef _VoxelGI
|
||||
vec4 g1a = texture(gbuffer1, texCoord); // Basecolor.rgb, occlusion
|
||||
vec3 albedoa = surfaceAlbedo(g1a.rgb, metrough.x); // g1a.rgb - basecolor
|
||||
|
||||
vec3 tangent = normalize(cross(n, vec3(0.0, 1.0, 0.0)));
|
||||
if (length(tangent) == 0.0) {
|
||||
tangent = normalize(cross(n, vec3(0.0, 0.0, 1.0)));
|
||||
}
|
||||
vec3 bitangent = normalize(cross(n, tangent));
|
||||
mat3 tanToWorld = inverse(transpose(mat3(tangent, bitangent, n)));
|
||||
|
||||
float diffOcclusion = 0.0;
|
||||
vec3 indirectDiffusea = coneTraceIndirect(p, tanToWorld, n, diffOcclusion).rgb * 4.0;
|
||||
indirectDiffusea *= albedoa;
|
||||
diffOcclusion = min(1.0, 1.5 * diffOcclusion);
|
||||
|
||||
vec3 reflectWorld = reflect(-v, n);
|
||||
float specularOcclusion;
|
||||
float lodOffset = 0.0;//getMipFromRoughness(roughness, numMips);
|
||||
vec3 indirectSpecular = coneTrace(p, reflectWorld, n, 0.07 + lodOffset, specularOcclusion).rgb;
|
||||
|
||||
if (metrough.y > 0.0) { // Temp..
|
||||
float dotNVa = max(dot(n, v), 0.0);
|
||||
vec3 f0a = surfaceF0(g1a.rgb, metrough.x);
|
||||
vec2 envBRDFa = texture(senvmapBrdf, vec2(metrough.y, 1.0 - dotNVa)).xy;
|
||||
indirectSpecular *= (f0a * envBRDFa.x + envBRDFa.y);
|
||||
}
|
||||
|
||||
vec3 indirect1 = indirectDiffusea * diffOcclusion + indirectSpecular;
|
||||
indirect1 *= texture(ssaotex, texCoord).r;
|
||||
fragColor.rgb += indirect1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
// http://simonstechblog.blogspot.sk/2013/01/implementing-voxel-cone-tracing.html
|
||||
// http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/
|
||||
// http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
|
||||
// https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
// https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
|
||||
#version 450
|
||||
#extension GL_ARB_shader_image_load_store : enable
|
||||
|
||||
in fragData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
#endif
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
} frag;
|
||||
|
||||
uniform layout(RGBA8) image3D voxels;
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
#endif
|
||||
uniform vec4 baseCol;
|
||||
uniform sampler2D shadowMap;
|
||||
const int voxelDimensions = 512;
|
||||
|
||||
void main() {
|
||||
#ifdef _BaseTex
|
||||
vec4 matCol = texture(sbase, frag.texuv);
|
||||
#else
|
||||
vec4 matCol = baseCol;
|
||||
#endif
|
||||
|
||||
// vec3 lampPos = frag.lampPos.xyz / frag.lampPos.w;
|
||||
// lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
// float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
// const float shadowsBias = 0.0001;
|
||||
// float visibility = float(distanceFromLight > lampPos.z - shadowsBias);
|
||||
float visibility = 1.0;
|
||||
|
||||
ivec3 camPos = ivec3(gl_FragCoord.x, gl_FragCoord.y, voxelDimensions * gl_FragCoord.z);
|
||||
ivec3 texPos;
|
||||
if (frag.axis == 1) {
|
||||
texPos.x = voxelDimensions - camPos.z;
|
||||
texPos.z = camPos.x;
|
||||
texPos.y = camPos.y;
|
||||
}
|
||||
else if (frag.axis == 2) {
|
||||
texPos.z = camPos.y;
|
||||
texPos.y = voxelDimensions - camPos.z;
|
||||
texPos.x = camPos.x;
|
||||
}
|
||||
else {
|
||||
texPos = camPos;
|
||||
}
|
||||
texPos.z = voxelDimensions - texPos.z - 1;
|
||||
imageStore(voxels, texPos, vec4(matCol.rgb * visibility, 1.0));
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
#version 450
|
||||
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
|
||||
in vertData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
#endif
|
||||
vec4 lampPos;
|
||||
} vertices[];
|
||||
|
||||
out fragData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
#endif
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
} frag;
|
||||
|
||||
uniform mat4 PX;
|
||||
uniform mat4 PY;
|
||||
uniform mat4 PZ;
|
||||
|
||||
void main() {
|
||||
vec3 p1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 p2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 absnor = abs(normalize(cross(p1, p2)));
|
||||
|
||||
mat4 P;
|
||||
// Dominant axis
|
||||
if (absnor.x >= absnor.y && absnor.x >= absnor.z) {
|
||||
frag.axis = 1;
|
||||
P = PX;
|
||||
}
|
||||
else if (absnor.y >= absnor.x && absnor.y >= absnor.z) {
|
||||
frag.axis = 2;
|
||||
P = PY;
|
||||
}
|
||||
else {
|
||||
frag.axis = 3;
|
||||
P = PZ;
|
||||
}
|
||||
|
||||
for (int i = 0; i < gl_in.length(); i++) {
|
||||
vec3 middlePos = gl_in[0].gl_Position.xyz / 3.0 + gl_in[1].gl_Position.xyz / 3.0 + gl_in[2].gl_Position.xyz / 3.0;
|
||||
#ifdef _Tex
|
||||
frag.texuv = vertices[i].texuv;
|
||||
#endif
|
||||
frag.lampPos = vertices[i].lampPos;
|
||||
gl_Position = P * gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
EndPrimitive();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#version 450
|
||||
|
||||
in vec3 pos;
|
||||
// in vec3 nor;
|
||||
#ifdef _Tex
|
||||
in vec2 tex;
|
||||
#endif
|
||||
#ifdef _VCols
|
||||
in vec3 col;
|
||||
#endif
|
||||
#ifdef _NorTex
|
||||
in vec3 tan;
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
in vec4 bone;
|
||||
in vec4 weight;
|
||||
#endif
|
||||
#ifdef _Instancing
|
||||
in vec3 off;
|
||||
#endif
|
||||
|
||||
uniform mat4 LWVP;
|
||||
uniform mat4 W;
|
||||
|
||||
out vertData {
|
||||
#ifdef _BaseTex
|
||||
vec2 texuv;
|
||||
#endif
|
||||
vec4 lampPos;
|
||||
} vert;
|
||||
|
||||
void main() {
|
||||
#ifdef _Tex
|
||||
vert.texuv = tex;
|
||||
#endif
|
||||
vert.lampPos = LWVP * vec4(pos, 1.0);
|
||||
gl_Position = W * vec4(pos, 1.0);
|
||||
}
|
|
@ -1,59 +1,137 @@
|
|||
// https://github.com/Friduric/voxel-cone-tracing
|
||||
// https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
// http://simonstechblog.blogspot.com/2013/01/implementing-voxel-cone-tracing.html
|
||||
// http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/
|
||||
// http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
|
||||
// https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
|
||||
uniform sampler3D voxels;
|
||||
const float voxelGridWorldSize = 150.0;
|
||||
const int voxelDimensions = 128;
|
||||
const float maxDist = 30.0;
|
||||
const float alphaThreshold = 0.95;
|
||||
const int numCones = 6;
|
||||
vec3 coneDirections[6] = vec3[](
|
||||
vec3(0, 1, 0),
|
||||
vec3(0, 0.5, 0.866025),
|
||||
vec3(0.823639, 0.5, 0.267617),
|
||||
vec3(0.509037, 0.5, -0.700629),
|
||||
vec3(-0.509037, 0.5, -0.700629),
|
||||
vec3(-0.823639, 0.5, 0.267617));
|
||||
float coneWeights[6] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
|
||||
|
||||
vec4 sampleVoxels(vec3 worldPosition, float lod) {
|
||||
vec3 offset = vec3(1.0 / voxelDimensions, 1.0 / voxelDimensions, 0);
|
||||
vec3 texco = worldPosition / (voxelGridWorldSize * 0.5);
|
||||
texco = texco * 0.5 + 0.5 + offset;
|
||||
return textureLod(voxels, texco, lod);
|
||||
const float VOXEL_SIZE = 1.0 / voxelgiResolution.x;
|
||||
const float MAX_MIPMAP = 5.4;
|
||||
|
||||
vec3 orthogonal(const vec3 u) {
|
||||
// Pass normalized u
|
||||
const vec3 v = vec3(0.99146, 0.11664, 0.05832); // Pick any normalized vector.
|
||||
return abs(dot(u, v)) > 0.99999 ? cross(u, vec3(0.0, 1.0, 0.0)) : cross(u, v);
|
||||
}
|
||||
|
||||
// See https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
vec4 coneTrace(vec3 posWorld, vec3 direction, vec3 norWorld, float tanHalfAngle, out float occlusion) {
|
||||
const float voxelWorldSize = voxelGridWorldSize / voxelDimensions;
|
||||
float dist = voxelWorldSize; // Start one voxel away to avoid self occlusion
|
||||
vec3 startPos = posWorld + norWorld * voxelWorldSize;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
float alpha = 0.0;
|
||||
occlusion = 0.0;
|
||||
while (dist < maxDist && alpha < alphaThreshold) {
|
||||
// Smallest sample diameter possible is the voxel size
|
||||
float diameter = max(voxelWorldSize, 2.0 * tanHalfAngle * dist);
|
||||
float lodLevel = log2(diameter / voxelWorldSize);
|
||||
vec4 voxelColor = sampleVoxels(startPos + dist * direction, lodLevel);
|
||||
// Front-to-back compositing
|
||||
float a = (1.0 - alpha);
|
||||
color += a * voxelColor.rgb;
|
||||
alpha += a * voxelColor.a;
|
||||
occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
|
||||
dist += diameter * 0.5; // * 2.0
|
||||
vec3 traceDiffuseVoxelCone(const vec3 from, vec3 direction) {
|
||||
direction = normalize(direction);
|
||||
const float CONE_SPREAD = 0.325;
|
||||
vec4 acc = vec4(0.0);
|
||||
// Controls bleeding from close surfaces
|
||||
// Low values look rather bad if using shadow cone tracing
|
||||
// Might be a better choice to use shadow maps and lower this value
|
||||
float dist = 0.1953125;
|
||||
const float SQRT2 = 1.414213;
|
||||
while (dist < SQRT2 && acc.a < 1) {
|
||||
vec3 c = vec3(from + dist * direction) * 0.5 + vec3(0.5);
|
||||
float l = (1.0 + CONE_SPREAD * dist / VOXEL_SIZE);
|
||||
float level = log2(l);
|
||||
float ll = (level + 1.0) * (level + 1.0);
|
||||
vec4 voxel = textureLod(voxels, c, min(MAX_MIPMAP, level));
|
||||
acc += 0.075 * ll * voxel * pow(1.0 - voxel.a, 2.0);
|
||||
dist += ll * VOXEL_SIZE * 2.0;
|
||||
}
|
||||
return vec4(color, alpha);
|
||||
return pow(acc.rgb * 2.0, vec3(1.5));
|
||||
}
|
||||
|
||||
vec4 coneTraceIndirect(vec3 posWorld, mat3 tanToWorld, vec3 norWorld, out float occlusion) {
|
||||
vec4 color = vec4(0.0);
|
||||
occlusion = 0.0;
|
||||
vec3 indirectDiffuseLight(const vec3 normal, const vec3 wpos) {
|
||||
const float ANGLE_MIX = 0.5; // Angle mix (1.0f -> orthogonal direction, 0.0f -> direction of normal)
|
||||
const float w[3] = { 1.0, 1.0, 1.0 }; // Cone weights
|
||||
// Find a base for the side cones with the normal as one of its base vectors
|
||||
const vec3 ortho = normalize(orthogonal(normal));
|
||||
const vec3 ortho2 = normalize(cross(ortho, normal));
|
||||
// Find base vectors for the corner cones
|
||||
const vec3 corner = 0.5 * (ortho + ortho2);
|
||||
const vec3 corner2 = 0.5 * (ortho - ortho2);
|
||||
// Find start position of trace (start with a bit of offset)
|
||||
const float ISQRT2 = 0.707106;
|
||||
const vec3 N_OFFSET = normal * (1.0 + 4.0 * ISQRT2) * VOXEL_SIZE;
|
||||
const vec3 C_ORIGIN = wpos + N_OFFSET;
|
||||
|
||||
for (int i = 0; i < numCones; i++) {
|
||||
float coneOcclusion;
|
||||
const float tanangle = tan(30.0);
|
||||
color += coneWeights[i] * coneTrace(posWorld, tanToWorld * coneDirections[i], norWorld, tanangle, coneOcclusion);
|
||||
occlusion += coneWeights[i] * coneOcclusion;
|
||||
// Accumulate indirect diffuse light
|
||||
vec3 acc = vec3(0.0);
|
||||
|
||||
// We offset forward in normal direction, and backward in cone direction
|
||||
// Backward in cone direction improves GI, and forward direction removes artifacts
|
||||
const float CONE_OFFSET = -0.01;
|
||||
// Trace front cone
|
||||
acc += w[0] * traceDiffuseVoxelCone(C_ORIGIN + CONE_OFFSET * normal, normal);
|
||||
|
||||
// Trace 4 side cones
|
||||
const vec3 s1 = mix(normal, ortho, ANGLE_MIX);
|
||||
const vec3 s2 = mix(normal, -ortho, ANGLE_MIX);
|
||||
const vec3 s3 = mix(normal, ortho2, ANGLE_MIX);
|
||||
const vec3 s4 = mix(normal, -ortho2, ANGLE_MIX);
|
||||
acc += w[1] * traceDiffuseVoxelCone(C_ORIGIN + CONE_OFFSET * ortho, s1);
|
||||
acc += w[1] * traceDiffuseVoxelCone(C_ORIGIN - CONE_OFFSET * ortho, s2);
|
||||
acc += w[1] * traceDiffuseVoxelCone(C_ORIGIN + CONE_OFFSET * ortho2, s3);
|
||||
acc += w[1] * traceDiffuseVoxelCone(C_ORIGIN - CONE_OFFSET * ortho2, s4);
|
||||
|
||||
// Trace 4 corner cones
|
||||
const vec3 c1 = mix(normal, corner, ANGLE_MIX);
|
||||
const vec3 c2 = mix(normal, -corner, ANGLE_MIX);
|
||||
const vec3 c3 = mix(normal, corner2, ANGLE_MIX);
|
||||
const vec3 c4 = mix(normal, -corner2, ANGLE_MIX);
|
||||
acc += w[2] * traceDiffuseVoxelCone(C_ORIGIN + CONE_OFFSET * corner, c1);
|
||||
acc += w[2] * traceDiffuseVoxelCone(C_ORIGIN - CONE_OFFSET * corner, c2);
|
||||
acc += w[2] * traceDiffuseVoxelCone(C_ORIGIN + CONE_OFFSET * corner2, c3);
|
||||
acc += w[2] * traceDiffuseVoxelCone(C_ORIGIN - CONE_OFFSET * corner2, c4);
|
||||
|
||||
return acc + vec3(0.001);
|
||||
}
|
||||
|
||||
vec3 traceSpecularVoxelCone(vec3 from, vec3 direction, const vec3 normal, const float specularDiffusion) {
|
||||
direction = normalize(direction);
|
||||
float MAX_DISTANCE = distance(vec3(abs(from)), vec3(-1));
|
||||
|
||||
const float OFFSET = 8 * VOXEL_SIZE;
|
||||
const float STEP = VOXEL_SIZE;
|
||||
from += OFFSET * normal;
|
||||
|
||||
vec4 acc = vec4(0.0);
|
||||
float dist = OFFSET;
|
||||
|
||||
while (dist < MAX_DISTANCE && acc.a < 1.0) {
|
||||
vec3 c = from + dist * direction;
|
||||
if (!isInsideCube(c)) break;
|
||||
c = c * 0.5 + vec3(0.5);
|
||||
|
||||
float level = 0.1 * specularDiffusion * log2(1.0 + dist / VOXEL_SIZE);
|
||||
vec4 voxel = textureLod(voxels, c, min(level, MAX_MIPMAP));
|
||||
float f = 1.0 - acc.a;
|
||||
acc.rgb += 0.25 * (1.0 + specularDiffusion) * voxel.rgb * voxel.a * f;
|
||||
acc.a += 0.25 * voxel.a * f;
|
||||
dist += STEP * (1.0 + 0.125 * level);
|
||||
}
|
||||
occlusion = 1.0 - occlusion;
|
||||
return color;
|
||||
return 1.0 * pow(specularDiffusion + 1, 0.8) * acc.rgb;
|
||||
}
|
||||
|
||||
// vec3 indirectRefractiveLight(const vec3 v, const vec3 normal){
|
||||
// float refractiveIndex = 1.2;
|
||||
// const vec3 refraction = refract(v, normal, 1.0 / refractiveIndex);
|
||||
// const vec3 cmix = mix(specularColor, 0.5 * (specularColor + vec3(1)), transparency);
|
||||
// return cmix * traceSpecularVoxelCone(worldPositionFrag, refraction, 0.1);
|
||||
// }
|
||||
|
||||
float traceShadowCone(vec3 from, vec3 direction, float targetDistance, vec3 normal) {
|
||||
from += normal * 0.0; // Removes artifacts but makes self shadowing for dense meshes meh
|
||||
float acc = 0.0;
|
||||
float dist = 3 * VOXEL_SIZE;
|
||||
// I'm using a pretty big margin here since I use an emissive light ball with a pretty big radius in my demo scenes.
|
||||
const float STOP = targetDistance - 16.0 * VOXEL_SIZE;
|
||||
|
||||
while (dist < STOP && acc < 1.0) {
|
||||
vec3 c = from + dist * direction;
|
||||
if (!isInsideCube(c)) break;
|
||||
c = c * 0.5 + vec3(0.5);
|
||||
float l = pow(dist, 2.0); // Experimenting with inverse square falloff for shadows.
|
||||
float s1 = 0.062 * textureLod(voxels, c, 1.0 + 0.75 * l).a;
|
||||
float s2 = 0.135 * textureLod(voxels, c, 4.5 * l).a;
|
||||
float s = s1 + s2;
|
||||
acc += (1.0 - acc) * s;
|
||||
dist += 0.9 * VOXEL_SIZE * (1.0 + 0.05 * l);
|
||||
}
|
||||
return 1.0 - pow(smoothstep(0.0, 1.0, acc * 1.4), 1.0 / 1.4);
|
||||
}
|
||||
|
|
|
@ -39,4 +39,8 @@ float attenuate(const float dist) {
|
|||
// 1.0 / (quadratic * dist * dist);
|
||||
}
|
||||
|
||||
bool isInsideCube(const vec3 p) {
|
||||
return abs(p.x) < 1 && abs(p.y) < 1 && abs(p.z) < 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Binary file not shown.
|
@ -79,6 +79,18 @@ def make_deferred(cam):
|
|||
nodes['Begin'].inputs[1].default_value = cam.rp_hdr
|
||||
nodes['Screen'].inputs[0].default_value = int(cam.rp_supersampling)
|
||||
|
||||
if cam.rp_voxelgi:
|
||||
links.new(nodes['Begin'].outputs[0], nodes['Set Target Voxels'].inputs[0])
|
||||
links.new(nodes['Generate Mipmaps Voxels'].outputs[0], nodes['Set Target Mesh'].inputs[0])
|
||||
n = nodes['Image 3D Voxels']
|
||||
n.inputs[1].default_value = cam.rp_voxelgi_resolution[0]
|
||||
n.inputs[2].default_value = cam.rp_voxelgi_resolution[1]
|
||||
n.inputs[3].default_value = cam.rp_voxelgi_resolution[2]
|
||||
n = nodes['Set Viewport Voxels']
|
||||
n.inputs[1].default_value = cam.rp_voxelgi_resolution[0]
|
||||
n.inputs[2].default_value = cam.rp_voxelgi_resolution[1]
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Indirect'].inputs[4])
|
||||
|
||||
if cam.rp_shadowmap != 'None':
|
||||
n = nodes['Shadow Map']
|
||||
n.inputs[1].default_value = n.inputs[2].default_value = int(cam.rp_shadowmap)
|
||||
|
|
|
@ -312,7 +312,7 @@ def make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices
|
|||
bind_target_used = False
|
||||
for i in range(0, len(bind_target_indices)):
|
||||
index = bind_target_indices[i]
|
||||
if node.inputs[index].is_linked:
|
||||
if len(node.inputs) > index and node.inputs[index].is_linked:
|
||||
bind_target_used = True
|
||||
if bind_target_constants == None:
|
||||
constant_name = node.inputs[index + 1].default_value
|
||||
|
@ -425,8 +425,7 @@ def make_water_pass(stages, node_group, node):
|
|||
|
||||
def make_deferred_light_pass(stages, node_group, node):
|
||||
# Draw lamp volume - TODO: properly generate stage
|
||||
# make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'shadowMap', 'voxels'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
stages[-1]['command'] = 'draw_lamp_volume'
|
||||
|
||||
def make_volumetric_light_pass(stages, node_group, node):
|
||||
|
@ -438,9 +437,7 @@ def make_volumetric_light_pass(stages, node_group, node):
|
|||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[3, 4], bind_target_constants=['tex', 'gbuffer0'], shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y_blend_add')
|
||||
|
||||
def make_deferred_indirect_pass(stages, node_group, node):
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'ssaotex'], shader_context='deferred_indirect/deferred_indirect/deferred_indirect')
|
||||
# Testing voxels
|
||||
# make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'ssaotex', 'voxels'], shader_context='deferred_indirect/deferred_indirect/deferred_indirect')
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'ssaotex', 'voxels'], shader_context='deferred_indirect/deferred_indirect/deferred_indirect')
|
||||
|
||||
def make_translucent_resolve_pass(stages, node_group, node):
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2], bind_target_constants=['gbuffer'], shader_context='translucent_resolve/translucent_resolve/translucent_resolve')
|
||||
|
|
|
@ -75,17 +75,20 @@ def build_node_tree(world):
|
|||
if wrd.diffuse_model == 'Oren Nayar':
|
||||
wrd.world_defs += '_OrenNayar'
|
||||
|
||||
if wrd.voxelgi:
|
||||
wrd.world_defs += '_VoxelGI'
|
||||
wrd.world_defs += '_Rad' # Always do radiance for voxels
|
||||
wrd.world_defs += '_Irr'
|
||||
|
||||
# Enable probes
|
||||
voxelgi = False
|
||||
for cam in bpy.data.cameras:
|
||||
if cam.is_probe:
|
||||
wrd.world_defs += '_Probes'
|
||||
if cam.rp_shadowmap == 'None':
|
||||
wrd.world_defs += '_NoShadows'
|
||||
if cam.rp_voxelgi:
|
||||
voxelgi = True
|
||||
|
||||
if voxelgi:
|
||||
assets.add_khafile_def('arm_voxelgi')
|
||||
wrd.world_defs += '_VoxelGI'
|
||||
wrd.world_defs += '_Rad' # Always do radiance for voxels
|
||||
wrd.world_defs += '_Irr'
|
||||
|
||||
# Area lamps
|
||||
for lamp in bpy.data.lamps:
|
||||
|
|
|
@ -1029,7 +1029,9 @@ def parse_value(node, socket):
|
|||
return '0.0'
|
||||
|
||||
elif node.type == 'LIGHT_FALLOFF':
|
||||
return '0.0'
|
||||
# Constant, linear, quadratic
|
||||
# Shaders default to quadratic for now
|
||||
return '1.0'
|
||||
|
||||
elif node.type == 'NORMAL':
|
||||
nor = parse_vector_input(node.inputs[0])
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
# http://simonstechblog.blogspot.sk/2013/01/implementing-voxel-cone-tracing.html
|
||||
# http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/
|
||||
# http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
|
||||
# https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
# https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
|
||||
|
||||
import material.cycles as cycles
|
||||
import material.mat_state as mat_state
|
||||
import material.mat_utils as mat_utils
|
||||
|
||||
def make(context_id):
|
||||
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none' })
|
||||
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False })
|
||||
|
||||
vert = con_voxel.make_vert()
|
||||
frag = con_voxel.make_frag()
|
||||
|
@ -20,91 +14,69 @@ def make(context_id):
|
|||
geom.ins = vert.outs
|
||||
frag.ins = geom.outs
|
||||
|
||||
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_uniform('mat4 N', '_normalMatrix')
|
||||
|
||||
vert.add_out('vec4 lampPos')
|
||||
# vert.add_out('vec2 texuv')
|
||||
vert.add_out('vec3 wpositionGeom')
|
||||
vert.add_out('vec3 wnormalGeom')
|
||||
|
||||
# vert.write('texuv = tex;')
|
||||
vert.write('lampPos = LWVP * vec4(pos, 1.0);')
|
||||
vert.write('gl_Position = W * vec4(pos, 1.0);')
|
||||
vert.add_include('../../Shaders/compiled.glsl')
|
||||
|
||||
geom.add_uniform('mat4 PX', '_projectionXMatrix')
|
||||
geom.add_uniform('mat4 PY', '_projectionYMatrix')
|
||||
geom.add_uniform('mat4 PZ', '_projectionZMatrix')
|
||||
if mat_state.data.is_elem('tex'):
|
||||
vert.add_out('vec2 texCoordGeom')
|
||||
vert.write('texCoordGeom = tex;')
|
||||
|
||||
#geom.add_out('vec2 geom_texuv')
|
||||
geom.add_out('flat int geom_axis')
|
||||
geom.add_out('vec4 geom_lampPos')
|
||||
vert.write('wpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiDimensions.x;')
|
||||
vert.write('wnormalGeom = normalize(mat3(N) * nor);')
|
||||
vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
||||
|
||||
geom.write('vec3 p1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;')
|
||||
geom.write('vec3 p2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;')
|
||||
geom.write('vec3 absnor = abs(normalize(cross(p1, p2)));')
|
||||
|
||||
geom.write('mat4 P; // Dominant axis')
|
||||
geom.write('if (absnor.x >= absnor.y && absnor.x >= absnor.z) {')
|
||||
geom.write(' geom_axis = 1;')
|
||||
geom.write(' P = PX;')
|
||||
geom.write('}')
|
||||
geom.write('else if (absnor.y >= absnor.x && absnor.y >= absnor.z) {')
|
||||
geom.write(' geom_axis = 2;')
|
||||
geom.write(' P = PY;')
|
||||
geom.write('}')
|
||||
geom.write('else {')
|
||||
geom.write(' geom_axis = 3;')
|
||||
geom.write(' P = PZ;')
|
||||
geom.write('}')
|
||||
geom.add_out('vec3 wposition')
|
||||
geom.add_out('vec3 wnormal')
|
||||
if mat_state.data.is_elem('tex'):
|
||||
geom.add_out('vec2 texCoord')
|
||||
|
||||
geom.write('for (int i = 0; i < gl_in.length(); i++) {')
|
||||
geom.write(' vec3 middlePos = gl_in[0].gl_Position.xyz / 3.0 + gl_in[1].gl_Position.xyz / 3.0 + gl_in[2].gl_Position.xyz / 3.0;')
|
||||
#geom.write(' geom_texuv = texuv[i];')
|
||||
geom.write(' geom_lampPos = lampPos[i];')
|
||||
geom.write(' gl_Position = P * gl_in[i].gl_Position;')
|
||||
geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p = abs(cross(p1, p2));')
|
||||
geom.write('for (uint i = 0; i < 3; ++i) {')
|
||||
geom.write(' wposition = wpositionGeom[i];')
|
||||
geom.write(' wnormal = wnormalGeom[i];')
|
||||
if mat_state.data.is_elem('tex'):
|
||||
geom.write(' texCoord = texCoordGeom[i];')
|
||||
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
||||
geom.write(' gl_Position = vec4(wposition.x, wposition.y, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' else if (p.x > p.y && p.x > p.z) {')
|
||||
geom.write(' gl_Position = vec4(wposition.y, wposition.z, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' else {')
|
||||
geom.write(' gl_Position = vec4(wposition.x, wposition.z, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' EmitVertex();')
|
||||
geom.write('}')
|
||||
geom.write('EndPrimitive();')
|
||||
|
||||
frag.add_include('../../Shaders/compiled.glsl')
|
||||
frag.add_include('../../Shaders/std/math.glsl')
|
||||
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
|
||||
|
||||
|
||||
frag.add_uniform('layout(RGBA8) image3D voxels')
|
||||
#frag.add_uniform('sampler2D sbase')
|
||||
#frag.add_uniform('vec4 baseCol')
|
||||
#frag.add_uniform('sampler2D shadowMap')
|
||||
|
||||
frag.write('const int voxelDimensions = 128;')
|
||||
frag.add_uniform('vec3 lightPos', '_lampPosition')
|
||||
frag.add_uniform('vec3 lightColor', '_lampColor')
|
||||
|
||||
frag.write('vec3 color = vec3(0.0);')
|
||||
frag.write('if (!isInsideCube(wposition)) return;')
|
||||
|
||||
frag.write('vec3 basecol;')
|
||||
frag.write('float roughness;')
|
||||
frag.write('float metallic;')
|
||||
frag.write('float occlusion;')
|
||||
frag.write('float roughness;') #
|
||||
frag.write('float metallic;') #
|
||||
frag.write('float occlusion;') #
|
||||
frag.write_pre = True
|
||||
frag.write('mat3 TBN = mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);') # TODO: discard, parse basecolor only
|
||||
frag.write_pre = False
|
||||
cycles.parse(mat_state.nodes, vert, frag, geom, tesc, tese, parse_opacity=False, parse_displacement=False)
|
||||
frag.write('vec4 matCol = vec4(basecol, 1.0);')
|
||||
|
||||
# vec3 lampPos = geom_lampPos.xyz / geom_lampPos.w;
|
||||
# lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
# float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
# const float shadowsBias = 0.0001;
|
||||
# float visibility = float(distanceFromLight > lampPos.z - shadowsBias);
|
||||
frag.write('float visibility = 1.0;')
|
||||
|
||||
frag.write('ivec3 camPos = ivec3(gl_FragCoord.x, gl_FragCoord.y, voxelDimensions * gl_FragCoord.z);')
|
||||
frag.write('ivec3 texPos;')
|
||||
frag.write('if (geom_axis == 1) {')
|
||||
frag.write(' texPos.x = voxelDimensions - camPos.z;')
|
||||
frag.write(' texPos.z = camPos.x;')
|
||||
frag.write(' texPos.y = camPos.y;')
|
||||
frag.write('}')
|
||||
frag.write('else if (geom_axis == 2) {')
|
||||
frag.write(' texPos.z = camPos.y;')
|
||||
frag.write(' texPos.y = voxelDimensions - camPos.z;')
|
||||
frag.write(' texPos.x = camPos.x;')
|
||||
frag.write('}')
|
||||
frag.write('else {')
|
||||
frag.write(' texPos = camPos;')
|
||||
frag.write('}')
|
||||
frag.write('texPos.z = voxelDimensions - texPos.z - 1;')
|
||||
frag.write('imageStore(voxels, texPos, vec4(matCol.rgb * visibility, 1.0));')
|
||||
frag.write('color = basecol * lightColor * max(dot(wnormal, normalize(lightPos - wposition * voxelgiDimensions.x)), 0.0) * attenuate(distance(wposition * voxelgiDimensions.x, lightPos));')
|
||||
frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')
|
||||
frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));') # , alpha
|
||||
|
||||
return con_voxel
|
||||
|
|
|
@ -36,7 +36,7 @@ def get_rpasses(material):
|
|||
ar.append('mesh')
|
||||
for con in add_mesh_contexts:
|
||||
ar.append(con)
|
||||
if bpy.data.worlds['Arm'].voxelgi:
|
||||
if bpy.data.cameras[0].rp_voxelgi:
|
||||
ar.append('voxel')
|
||||
|
||||
shadows_enabled = False
|
||||
|
|
|
@ -295,8 +295,6 @@ class DeferredLightPassNode(Node, CGPipelineTreeNode):
|
|||
self.inputs.new('NodeSocketShader', "Target")
|
||||
self.inputs.new('NodeSocketShader', "GBuffer")
|
||||
self.inputs.new('NodeSocketShader', "Shadow Map")
|
||||
# Testing voxels
|
||||
self.inputs.new('NodeSocketShader', "Voxels")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
|
@ -311,8 +309,7 @@ class DeferredIndirectPassNode(Node, CGPipelineTreeNode):
|
|||
self.inputs.new('NodeSocketShader', "Target")
|
||||
self.inputs.new('NodeSocketShader', "GBuffer")
|
||||
self.inputs.new('NodeSocketShader', "SSAO")
|
||||
# Testing voxels
|
||||
# self.inputs.new('NodeSocketShader', "Voxels")
|
||||
self.inputs.new('NodeSocketShader', "Voxels")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
|
|
|
@ -332,6 +332,8 @@ def init_properties():
|
|||
name="Overlays", description="X-Ray pass", default='Auto', update=update_overlays_state)
|
||||
bpy.types.Camera.rp_stereo = bpy.props.BoolProperty(name="Stereo", description="Stereo rendering", default=False, update=update_renderpath)
|
||||
bpy.types.Camera.rp_greasepencil = bpy.props.BoolProperty(name="Grease Pencil", description="Render Grease Pencil data", default=False, update=update_renderpath)
|
||||
bpy.types.Camera.rp_voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=update_renderpath)
|
||||
bpy.types.Camera.rp_voxelgi_resolution = bpy.props.FloatVectorProperty(name="Resolution", description="3D texture resolution", size=3, default=[128, 128, 128], update=update_renderpath)
|
||||
|
||||
# For world
|
||||
bpy.types.World.world_envtex_name = bpy.props.StringProperty(name="Environment Texture", default='')
|
||||
|
@ -432,8 +434,7 @@ def init_properties():
|
|||
items=[('Lambert', 'Lambert', 'Lambert'),
|
||||
('Oren Nayar', 'Oren Nayar', 'Oren Nayar')],
|
||||
name="Diffuse", description="Diffuse model", default='Lambert', update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_dimensions = bpy.props.FloatVectorProperty(name="Dimensions", description="3D texture size", size=3, default=[128, 128, 128], update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.generate_voxelgi_dimensions = bpy.props.FloatVectorProperty(name="Dimensions", description="Voxelization bounds", size=3, default=[16, 16, 16], update=assets.invalidate_shader_cache)
|
||||
# For material
|
||||
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False, update=update_mat_cache)
|
||||
bpy.types.Material.lock_cache = bpy.props.BoolProperty(name="Lock Material Cache", description="Prevent is_cached from updating", default=False)
|
||||
|
|
|
@ -219,6 +219,9 @@ class GenRPDataPropsPanel(bpy.types.Panel):
|
|||
layout.prop(dat, "rp_worldnodes")
|
||||
layout.prop(dat, "rp_stereo")
|
||||
# layout.prop(dat, "rp_greasepencil")
|
||||
layout.prop(dat, 'rp_voxelgi')
|
||||
if dat.rp_voxelgi:
|
||||
layout.prop(dat, 'rp_voxelgi_resolution')
|
||||
|
||||
layout.separator()
|
||||
layout.prop(dat, "rp_render_to_texture")
|
||||
|
@ -261,10 +264,6 @@ class PropsRPDataPropsPanel(bpy.types.Panel):
|
|||
layout.prop(wrd, 'diffuse_model')
|
||||
layout.prop(wrd, 'tessellation_enabled')
|
||||
layout.prop(wrd, 'force_no_culling')
|
||||
layout.prop(wrd, 'voxelgi')
|
||||
if wrd.voxelgi:
|
||||
layout.prop(wrd, 'voxelgi_dimensions')
|
||||
|
||||
|
||||
layout.prop(wrd, 'arm_camera_props_advanced')
|
||||
if wrd.arm_camera_props_advanced:
|
||||
|
@ -318,6 +317,9 @@ class PropsRPDataPropsPanel(bpy.types.Panel):
|
|||
layout.prop(wrd, 'generate_volumetric_light_air_turbidity')
|
||||
layout.prop(wrd, 'generate_volumetric_light_air_color')
|
||||
|
||||
layout.label('Voxel GI')
|
||||
layout.prop(wrd, 'generate_voxelgi_dimensions')
|
||||
|
||||
def register():
|
||||
bpy.utils.register_module(__name__)
|
||||
|
||||
|
|
|
@ -311,6 +311,12 @@ const vec3 compoFogColor = vec3(""" + str(round(wrd.generate_fog_color[0] * 100)
|
|||
"""const float compoDOFDistance = """ + str(round(bpy.data.cameras[0].dof_distance * 100) / 100) + """;
|
||||
const float compoDOFFstop = """ + str(round(bpy.data.cameras[0].gpu_dof.fstop * 100) / 100) + """;
|
||||
const float compoDOFLength = """ + str(round(bpy.data.cameras[0].lens * 100) / 100) + """;
|
||||
""")
|
||||
|
||||
if bpy.data.cameras[0].rp_voxelgi:
|
||||
f.write(
|
||||
"""const vec3 voxelgiResolution = ivec3(""" + str(round(bpy.data.cameras[0].rp_voxelgi_resolution[0])) + """, """ + str(round(bpy.data.cameras[0].rp_voxelgi_resolution[1])) + """, """ + str(round(bpy.data.cameras[0].rp_voxelgi_resolution[2])) + """);
|
||||
const vec3 voxelgiDimensions = ivec3(""" + str(round(wrd.generate_voxelgi_dimensions[0])) + """, """ + str(round(wrd.generate_voxelgi_dimensions[1])) + """, """ + str(round(wrd.generate_voxelgi_dimensions[2])) + """);
|
||||
""")
|
||||
|
||||
# Skinning
|
||||
|
@ -319,7 +325,8 @@ const float compoDOFLength = """ + str(round(bpy.data.cameras[0].lens * 100) / 1
|
|||
"""const int skinMaxBones = """ + str(wrd.generate_gpu_skin_max_bones) + """;
|
||||
""")
|
||||
|
||||
f.write("""#endif // _COMPILED_GLSL_""")
|
||||
f.write("""#endif // _COMPILED_GLSL_
|
||||
""")
|
||||
|
||||
def write_traithx(class_name):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
|
Loading…
Reference in a new issue