Spherical harmonics for irradiance probes.

This commit is contained in:
Lubos Lenco 2016-06-13 12:23:59 +02:00
parent e4948d5713
commit 56340d135d
16 changed files with 305 additions and 239 deletions

View file

@ -2154,7 +2154,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
volume_center = [volume_object.location[0], volume_object.location[1], volume_object.location[2]]
disable_hdr = cam.probe_texture.endswith('.jpg')
cam.probe_num_mips = write_probes.write_probes(cam.probe_texture, disable_hdr, cam.probe_num_mips)
cam.probe_num_mips = write_probes.write_probes(cam.probe_texture, disable_hdr, cam.probe_num_mips, generate_radiance=False)
base_name = cam.probe_texture.rsplit('.', 1)[0]
po = self.make_probe(cam.name, base_name, cam.probe_num_mips, cam.probe_strength, cam.probe_blending, volume, volume_center)
o.probes.append(po)

View file

@ -87,11 +87,9 @@ def buildNodeTree(world_name, node_group, shader_references, asset_references):
bpy.data.worlds[0].world_defs += '_EnvSky'
# Enable probes
num_probes = 0
for cam in bpy.data.cameras:
if cam.is_probe:
num_probes += 1
bpy.data.worlds[0].world_defs += '_Probe' + str(num_probes)
bpy.data.worlds[0].world_defs += '_Probes'
with open(path + material_name + '.json', 'w') as f:
f.write(output.to_JSON())

View file

@ -2,19 +2,24 @@ import bpy
import os
import sys
import subprocess
import json
import re
class Object:
def to_JSON(self):
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
# Generate probes from environment map
def write_probes(image_name, disable_hdr, cached_num_mips):
def write_probes(image_name, disable_hdr, cached_num_mips, generate_radiance=True):
if not os.path.exists('Assets/generated/envmaps'):
os.makedirs('Assets/generated/envmaps')
name_split = image_name.rsplit('.', 1)
base_name = name_split[0]
ext_name = name_split[1]
# Assume irradiance has to exist for now
if os.path.exists('Assets/generated/envmaps/' + base_name + '_irradiance.' + ext_name):
if os.path.exists('Assets/generated/envmaps/' + base_name + '_irradiance.json'):
return cached_num_mips
# Get paths
# haxelib_path = "haxelib"
# if platform.system() == 'Darwin':
@ -66,19 +71,36 @@ def write_probes(image_name, disable_hdr, cached_num_mips):
' --outputGammaNumerator 1.0' + \
' --outputGammaDenominator ' + output_gama_numerator
# Irradiance image
# output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance'
# subprocess.call([ \
# cmft_path + 'cmft-osx' + \
# ' --input ' + input_file + \
# ' --filter irradiance' + \
# ' --dstFaceSize ' + dst_face_size + \
# gama_options + \
# ' --outputNum 1' + \
# ' --output0 ' + output_file + \
# ' --output0params hdr,rgbe,latlong'], shell=True)
# generated_files.append(output_file)
# Irradiance spherical harmonics
output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance'
subprocess.call([ \
cmft_path + 'cmft-osx' + \
' --input ' + input_file + \
' --filter irradiance' + \
' --dstFaceSize ' + dst_face_size + \
gama_options + \
' --filter shcoeffs' + \
#gama_options + \
' --outputNum 1' + \
' --output0 ' + output_file + \
' --output0params hdr,rgbe,latlong'], shell=True)
' --output0 ' + output_file], shell=True)
generated_files.append(output_file)
# Generate radiance
sh_to_json(output_file)
# Mip-mapped radiance image
if generate_radiance == False:
return cached_num_mips
output_file = 'Assets/generated/envmaps/' + base_name + '_radiance'
outformat = 'jpg' if disable_hdr else 'hdr'
output = subprocess.check_output([ \
@ -155,4 +177,29 @@ def write_probes(image_name, disable_hdr, cached_num_mips):
mip_count += 5
return mip_count
# Parse sh coefs into json array
def sh_to_json(sh_file):
sh_lines = open(sh_file + '.c').read().splitlines()
band0_line = sh_lines[5]
band1_line = sh_lines[6]
band2_line = sh_lines[7]
irradiance_floats = []
parse_band_floats(irradiance_floats, band0_line)
parse_band_floats(irradiance_floats, band1_line)
parse_band_floats(irradiance_floats, band2_line)
with open(sh_file + '.json', 'w') as f:
sh_json = Object()
sh_json.irradiance = irradiance_floats
f.write(sh_json.to_JSON())
# Clean up .c
os.remove(sh_file + '.c')
def parse_band_floats(irradiance_floats, band_line):
string_floats = re.findall(r'[-+]?\d*\.\d+|\d+', band_line)
string_floats = string_floats[1:] # Remove 'Band 0/1/2' number
for s in string_floats:
irradiance_floats.append(float(s))

View file

@ -28,8 +28,8 @@ vec3 getNor(vec2 enc) {
}
float doBlur(float blurWeight, int pos, vec3 nor) {
vec2 texstep = dir / vec2(800, 600);
vec2 texstep2 = dir / vec2(800, 600);
vec2 texstep = dir / vec2(800.0, 600.0);
vec2 texstep2 = dir / vec2(800.0, 600.0);
vec3 nor2 = getNor(texture(gbuffer0, texCoord + pos * texstep2).rg);
float influenceFactor = step(discardThreshold, dot(nor2, nor));
@ -57,32 +57,41 @@ void main() {
// for (int i = 0; i < 9; i++) {
// float blurWeight = blurWeights[0];
const float radius = 10.0;
const float radius = 20.0;
const float blurWeight = 1.0 / radius;
vec3 col = texture(tex, texCoord).rgb;
result += col * blurWeights[0];
weight += blurWeight;
weight += doBlur(blurWeights[1], 1, nor);
weight += doBlur(blurWeights[2], 2, nor);
weight += doBlur(blurWeights[3], 3, nor);
weight += doBlur(blurWeights[4], 4, nor);
weight += doBlur(blurWeights[5], 5, nor);
weight += doBlur(blurWeights[6], 6, nor);
weight += doBlur(blurWeights[7], 7, nor);
weight += doBlur(blurWeights[8], 8, nor);
weight += doBlur(blurWeights[9], 9, nor);
// weight += doBlur(blurWeight, 1, nor);
// weight += doBlur(blurWeight, 2, nor);
// weight += doBlur(blurWeight, 3, nor);
// weight += doBlur(blurWeight, 4, nor);
// weight += doBlur(blurWeight, 5, nor);
// weight += doBlur(blurWeight, 6, nor);
// weight += doBlur(blurWeight, 7, nor);
// weight += doBlur(blurWeight, 8, nor);
// weight += doBlur(blurWeight, 9, nor);
// weight += doBlur(blurWeight, 10, nor);
// weight += doBlur(blurWeights[1], 1, nor);
// weight += doBlur(blurWeights[2], 2, nor);
// weight += doBlur(blurWeights[3], 3, nor);
// weight += doBlur(blurWeights[4], 4, nor);
// weight += doBlur(blurWeights[5], 5, nor);
// weight += doBlur(blurWeights[6], 6, nor);
// weight += doBlur(blurWeights[7], 7, nor);
// weight += doBlur(blurWeights[8], 8, nor);
// weight += doBlur(blurWeights[9], 9, nor);
weight += doBlur(blurWeight, 1, nor);
weight += doBlur(blurWeight, 2, nor);
weight += doBlur(blurWeight, 3, nor);
weight += doBlur(blurWeight, 4, nor);
weight += doBlur(blurWeight, 5, nor);
weight += doBlur(blurWeight, 6, nor);
weight += doBlur(blurWeight, 7, nor);
weight += doBlur(blurWeight, 8, nor);
weight += doBlur(blurWeight, 9, nor);
weight += doBlur(blurWeight, 10, nor);
weight += doBlur(blurWeight, 11, nor);
weight += doBlur(blurWeight, 12, nor);
weight += doBlur(blurWeight, 13, nor);
weight += doBlur(blurWeight, 14, nor);
weight += doBlur(blurWeight, 15, nor);
weight += doBlur(blurWeight, 16, nor);
weight += doBlur(blurWeight, 17, nor);
weight += doBlur(blurWeight, 18, nor);
weight += doBlur(blurWeight, 19, nor);
// }
result /= weight;

View file

@ -270,7 +270,8 @@ void main() {
else {
uv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
}
vec4 col = texture(tex, uv);
// vec4 col = texture(tex, uv);
vec4 col = texture(tex, texCoord);
// Blur
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
@ -312,7 +313,7 @@ void main() {
// const float grainStrength = 4.0;
// float x = (texCoord.x + 4.0) * (texCoord.y + 4.0 ) * (time * 10.0);
// vec4 grain = vec4(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * grainStrength;
// col += grain;
//col += grain;
// Ice
// vec4 ice = screenSpaceIce(vec3(0.8, 0.9, 1.0));
@ -329,7 +330,7 @@ void main() {
// col.rgb = screenSpaceCameraRain();
// Vignetting
col.rgb *= vignette();
//col.rgb *= vignette();
// Exposure
const float aperture = 16;

View file

@ -28,8 +28,7 @@ uniform sampler2D smm;
uniform float metalness;
#endif
uniform float mask;
#ifdef _Probe1
#ifdef _Probes
uniform int probeID;
uniform vec3 probeVolumeCenter;
uniform vec3 probeVolumeSize;
@ -46,8 +45,7 @@ in mat3 TBN;
#else
in vec3 normal;
#endif
#ifdef _Probe1
#ifdef _Probes
in vec4 mpos;
#endif
@ -62,9 +60,9 @@ vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
#ifdef _Probe1
#ifdef _Probes
float distanceBox(vec3 point, vec3 center, vec3 halfExtents) {
vec3 d = abs(point - center) - halfExtents;
vec3 d = abs(point - center) - halfExtents * 0.75;
return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
}
#endif
@ -85,9 +83,10 @@ void main() {
if(texel.a < 0.4)
discard;
#endif
texel.rgb = pow(texel.rgb, vec3(2.2));
// texel.rgb = pow(texel.rgb, vec3(2.2));
baseColor *= texel.rgb;
#endif
baseColor = pow(baseColor, vec3(2.2));
#ifdef _MMTex
float metalness = texture(smm, texCoord).r;
@ -107,12 +106,17 @@ void main() {
n /= (abs(n.x) + abs(n.y) + abs(n.z));
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
#ifdef _Probe1
float dist = distanceBox(mpos.xyz, probeVolumeCenter, probeVolumeSize);
#ifdef _Probes
float mask_probe = probeID;
if (probeID > 0) {
if (probeID > 0) { // Non-global probe attached
const float eps = 0.00001;
mask_probe += clamp(0.5 + dist * 3.0, 0, 1.0 - eps);
// Distance of vertex located inside probe to probe bounds
float dist = distanceBox(mpos.xyz, probeVolumeCenter, probeVolumeSize);
// Blend local probe with global probe
if (dist > -0.1) {
mask_probe += clamp((0.1 + dist) * (1.0 / 0.1), 0, 1.0 - eps);
}
if (dist > 0) mask_probe = 0;
}
gl_FragData[0] = vec4(n.xy, occlusion, mask_probe);
#else

View file

@ -13,7 +13,7 @@
},
{
"id": "cull_mode",
"value": "counter_clockwise"
"value": "none"
}
],
"links": [
@ -33,30 +33,30 @@
"id": "LMVP",
"link": "_lightModelViewProjectionMatrix"
},
{
"id": "skinBones",
"link": "_skinBones",
"ifdef": ["_Skinning"]
},
{
"id": "probeID",
"link": "_probeID",
"ifdef": ["_Probe1"]
},
{
"id": "M",
"link": "_modelMatrix",
"ifdef": ["_Probe1"]
"ifdef": ["_Probes"]
},
{
"id": "probeVolumeCenter",
"link": "_probeVolumeCenter",
"ifdef": ["_Probe1"]
"ifdef": ["_Probes"]
},
{
{
"id": "probeVolumeSize",
"link": "_probeVolumeSize",
"ifdef": ["_Probe1"]
"ifdef": ["_Probes"]
},
{
"id": "probeID",
"link": "_probeID",
"ifdef": ["_Probes"]
},
{
"id": "skinBones",
"link": "_skinBones",
"ifdef": ["_Skinning"]
}
],
"vertex_shader": "deferred.vert.glsl",
@ -71,7 +71,7 @@
},
{
"id": "compare_mode",
"value": "less"
"value": "less_equal"
},
{
"id": "cull_mode",

View file

@ -36,7 +36,7 @@ uniform vec4 albedo_color;
uniform float skinBones[50 * 12];
#endif
#ifdef _Probe1
#ifdef _Probes
uniform mat4 M;
#endif
@ -53,7 +53,7 @@ out mat3 TBN;
out vec3 normal;
#endif
#ifdef _Probe1
#ifdef _Probes
out vec4 mpos;
#endif
@ -113,7 +113,7 @@ void main() {
//MV[2][0] = 0.0; MV[2][1] = 0.0; MV[2][2] = 1.0;
#endif
#ifdef _Probe1
#ifdef _Probes
mpos = M * sPos;
#endif

View file

@ -9,30 +9,15 @@ uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D senvmapRadiance;
uniform sampler2D senvmapIrradiance;
#ifdef _Probes
uniform float shirr[27 * 20]; // Maximum of 20 SH sets
#else
uniform float shirr[27];
#endif
uniform int envmapNumMipmaps;
uniform float envmapStrength;
uniform sampler2D senvmapBrdf;
#ifdef _Probe1
uniform sampler2D senvmapRadiance_1;
uniform sampler2D senvmapIrradiance_1;
// uniform int envmapNumMipmaps_1;
// uniform float envmapStrength_1;
#endif
#ifdef _Probe2
uniform sampler2D senvmapRadiance_2;
uniform sampler2D senvmapIrradiance_2;
#endif
#ifdef _Probe3
uniform sampler2D senvmapRadiance_3;
uniform sampler2D senvmapIrradiance_3;
#endif
#ifdef _Probe4
uniform sampler2D senvmapRadiance_4;
uniform sampler2D senvmapIrradiance_4;
#endif
// uniform sampler2D giblur; // Path-traced
uniform sampler2D ssaotex;
@ -203,14 +188,14 @@ float PCF(vec2 uv, float compare) {
}
#define _PCSS
// #define _PCSS
#ifdef _PCSS
// Based on ThreeJS PCSS example
const float LIGHT_WORLD_SIZE = 0.45;
const float LIGHT_FRUSTUM_WIDTH = 7.75;
const float LIGHT_WORLD_SIZE = 0.55;
const float LIGHT_FRUSTUM_WIDTH = 12.75;//5.75; //12.75
const float LIGHT_SIZE_UV = (LIGHT_WORLD_SIZE / LIGHT_FRUSTUM_WIDTH);
const float NEAR_PLANE = 3.5;
const int NUM_SAMPLES = 17;
const float NEAR_PLANE = 2.5;
const int NUM_SAMPLES = 17;//17
const int NUM_RINGS = 11;
// vec2 poissonDisk[NUM_SAMPLES];
vec2 poissonDisk0;
@ -434,13 +419,13 @@ float shadowTest(vec4 lPos) {
lPosH.x = (lPosH.x + 1.0) / 2.0;
lPosH.y = (lPosH.y + 1.0) / 2.0;
const float bias = 0.001; // Persp
const float bias = 0.00015; // Persp
// const float bias = 0.01; // Ortho
#ifdef _PCSS
return PCSS(lPosH.xy, lPosH.z - bias);
#else
// return PCF(lPosH.xy, lPosH.z - bias);
return PCF(lPosH.xy, lPosH.z - bias);
#endif
}
@ -662,6 +647,51 @@ float wardSpecular(vec3 N, vec3 H, float dotNL, float dotNV, float dotNH, vec3 f
}
#endif
vec3 shIrradiance(vec3 nor, float scale, int probe) {
const float c1 = 0.429043;
const float c2 = 0.511664;
const float c3 = 0.743125;
const float c4 = 0.886227;
const float c5 = 0.247708;
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
if (probe == 0) {
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
}
else if (probe == 1) {
cl00 = vec3(shirr[27 + 0], shirr[27 + 1], shirr[27 + 2]);
cl1m1 = vec3(shirr[27 + 3], shirr[27 + 4], shirr[27 + 5]);
cl10 = vec3(shirr[27 + 6], shirr[27 + 7], shirr[27 + 8]);
cl11 = vec3(shirr[27 + 9], shirr[27 + 10], shirr[27 + 11]);
cl2m2 = vec3(shirr[27 + 12], shirr[27 + 13], shirr[27 + 14]);
cl2m1 = vec3(shirr[27 + 15], shirr[27 + 16], shirr[27 + 17]);
cl20 = vec3(shirr[27 + 18], shirr[27 + 19], shirr[27 + 20]);
cl21 = vec3(shirr[27 + 21], shirr[27 + 22], shirr[27 + 23]);
cl22 = vec3(shirr[27 + 24], shirr[27 + 25], shirr[27 + 26]);
}
return (
c1 * cl22 * (nor.x * nor.x - (-nor.z) * (-nor.z)) +
c3 * cl20 * nor.y * nor.y +
c4 * cl00 -
c5 * cl20 +
2.0 * c1 * cl2m2 * nor.x * (-nor.z) +
2.0 * c1 * cl21 * nor.x * nor.y +
2.0 * c1 * cl2m1 * (-nor.z) * nor.y +
2.0 * c2 * cl11 * nor.x +
2.0 * c2 * cl1m1 * (-nor.z) +
2.0 * c2 * cl10 * nor.y
) * scale;
}
void main() {
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
// float depth = 1.0 - g0.a;
@ -727,7 +757,7 @@ void main() {
// Indirect
#ifdef _Probe1
#ifdef _Probes
float probeFactor = mask;
float probeID = floor(probeFactor);
float probeFract = fract(probeFactor);
@ -740,54 +770,25 @@ void main() {
vec3 reflectionWorld = reflect(-v, n);
vec2 envCoordRefl = envMapEquirect(reflectionWorld);
prefilteredColor = textureLod(senvmapRadiance, envCoordRefl, lod).rgb;
// Global probe only
if (probeID == 0.0) {
indirectDiffuse = texture(senvmapIrradiance, envCoord).rgb;
prefilteredColor = textureLod(senvmapRadiance, envCoordRefl, lod).rgb;
indirectDiffuse = shIrradiance(n, 2.2, 0) / PI;
}
// fract 0 = local probe, 1 = global probe
else if (probeID == 1.0) {
indirectDiffuse = texture(senvmapIrradiance_1, envCoord).rgb * (1.0 - probeFract);
prefilteredColor = textureLod(senvmapRadiance_1, envCoordRefl, lod).rgb * (1.0 - probeFract);
indirectDiffuse = (shIrradiance(n, 2.2, 1) / PI) * (1.0 - probeFract);
prefilteredColor /= 4.0;
if (probeFract > 0.0) {
indirectDiffuse += texture(senvmapIrradiance, envCoord).rgb * (probeFract);
prefilteredColor += textureLod(senvmapRadiance, envCoordRefl, lod).rgb * (probeFract);
indirectDiffuse += (shIrradiance(n, 2.2, 0) / PI) * (probeFract);
}
}
#ifdef _Probe2
else if (probeID == 2.0) {
indirectDiffuse = texture(senvmapIrradiance_2, envCoord).rgb * (1.0 - probeFract);
prefilteredColor = textureLod(senvmapRadiance_2, envCoordRefl, lod).rgb * (1.0 - probeFract);
if (probeFract > 0.0) {
indirectDiffuse += texture(senvmapIrradiance, envCoord).rgb * (probeFract);
prefilteredColor += textureLod(senvmapRadiance, envCoordRefl, lod).rgb * (probeFract);
}
}
#endif
#ifdef _Probe3
else if (probeID == 3.0) {
indirectDiffuse = texture(senvmapIrradiance_3, envCoord).rgb * (1.0 - probeFract);
prefilteredColor = textureLod(senvmapRadiance_3, envCoordRefl, lod).rgb * (1.0 - probeFract);
if (probeFract > 0.0) {
indirectDiffuse += texture(senvmapIrradiance, envCoord).rgb * (probeFract);
prefilteredColor += textureLod(senvmapRadiance, envCoordRefl, lod).rgb * (probeFract);
}
}
#endif
#ifdef _Probe4
else if (probeID == 4.0) {
indirectDiffuse = texture(senvmapIrradiance_4, envCoord).rgb * (1.0 - probeFract);
prefilteredColor = textureLod(senvmapRadiance_4, envCoordRefl, lod).rgb * (1.0 - probeFract);
if (probeFract > 0.0) {
indirectDiffuse += texture(senvmapIrradiance, envCoord).rgb * (probeFract);
prefilteredColor += textureLod(senvmapRadiance, envCoordRefl, lod).rgb * (probeFract);
}
}
#endif
#else // No probes
vec3 indirectDiffuse = texture(senvmapIrradiance, envMapEquirect(n)).rgb;
// vec3 indirectDiffuse = texture(shirr, envMapEquirect(n)).rgb;
vec3 indirectDiffuse = shIrradiance(n, 2.2, 0) / PI;
vec3 reflectionWorld = reflect(-v, n);
vec3 reflectionWorld = reflect(-v, n);
float lod = getMipLevelFromRoughness(roughness);
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
#endif
@ -797,8 +798,6 @@ void main() {
indirectDiffuse = pow(indirectDiffuse, vec3(2.2));
prefilteredColor = pow(prefilteredColor, vec3(2.2));
#endif
indirectDiffuse = pow(indirectDiffuse, vec3(1.0/2.2));////
prefilteredColor = pow(prefilteredColor, vec3(1.0/2.2));////
indirectDiffuse *= albedo;
@ -811,7 +810,6 @@ void main() {
vec4 outColor = vec4(vec3(direct * visibility + indirect * ao * occlusion), 1.0);
// Path-traced
// vec4 nois = texture(giblur, texCoord);
// nois.rgb = pow(nois.rgb, vec3(1.0 / 2.2));
@ -856,7 +854,6 @@ void main() {
// // outColor.rgb = ltccol * visibility + (indirect / 2.0 * ao);
// outColor = vec4(pow(outColor.rgb, vec3(1.0 / 2.2)), outColor.a);
gl_FragColor = vec4(outColor.rgb, outColor.a);
}

View file

@ -46,7 +46,7 @@
"link": "_lightModelViewProjectionMatrix"
},
{
"id": "senvmapIrradiance",
"id": "shirr",
"link": "_envmapIrradiance"
},
{
@ -65,46 +65,6 @@
"id": "envmapNumMipmaps",
"link": "_envmapNumMipmaps"
},
{
"id": "senvmapIrradiance_1",
"link": "_envmapIrradiance_1",
"ifdef": ["_Probe1"]
},
{
"id": "senvmapRadiance_1",
"link": "_envmapRadiance_1",
"ifdef": ["_Probe1"]
},
{
"id": "senvmapIrradiance_2",
"link": "_envmapIrradiance_2",
"ifdef": ["_Probe2"]
},
{
"id": "senvmapRadiance_2",
"link": "_envmapRadiance_2",
"ifdef": ["_Probe2"]
},
{
"id": "senvmapIrradiance_3",
"link": "_envmapIrradiance_3",
"ifdef": ["_Probe3"]
},
{
"id": "senvmapRadiance_3",
"link": "_envmapRadiance_3",
"ifdef": ["_Probe3"]
},
{
"id": "senvmapIrradiance_4",
"link": "_envmapIrradiance_4",
"ifdef": ["_Probe4"]
},
{
"id": "senvmapRadiance_4",
"link": "_envmapRadiance_4",
"ifdef": ["_Probe4"]
},
{
"id": "sltcMat",
"link": "_ltcMat",

View file

@ -23,6 +23,7 @@ uniform vec3 sunDirection;
uniform sampler2D envmap;
// uniform sampler2D tex;
uniform float envmapStrength;
in vec3 normal;
// in vec2 texCoord;
@ -46,7 +47,7 @@ void main() {
// }
vec3 n = normalize(normal);
gl_FragColor = texture(envmap, envMapEquirect(n));
gl_FragColor = texture(envmap, envMapEquirect(n)) * envmapStrength;
#ifdef _Hosek
vec3 sunDir = vec3(sunDirection.x, -sunDirection.y, sunDirection.z);

View file

@ -25,6 +25,10 @@
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "envmapStrength",
"link": "_envmapStrength"
},
{
"id": "A",
"link": "_hosekA",

View file

@ -0,0 +1,15 @@
{
"material_resources": [
{
"contexts": [
{
"bind_constants": [],
"bind_textures": [],
"id": "pt_trace_pass"
}
],
"id": "pt_material",
"shader": "pt_trace_pass/pt_trace_pass"
}
]
}

View file

@ -28,8 +28,8 @@ const float PI = 3.1415926535;
const vec2 screenSize = vec2(800.0, 600.0);
const vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
const int kernelSize = 12;
const float aoSize = 0.2;
const int kernelSize = 20;//12;
const float aoSize = 0.15;
const float strength = 0.6;//0.7;
in vec2 texCoord;
@ -74,27 +74,41 @@ void main() {
return;
}
vec2 kernel[kernelSize];
// kernel[0] = vec2(1.0, 0.0);
// kernel[1] = vec2(0.7071067, 0.7071067);
// kernel[2] = vec2(0.0, 1.0);
// kernel[3] = vec2(-0.7071067, 0.7071067);
// kernel[4] = vec2(-1.0, 0.0);
// kernel[5] = vec2(-0.7071067, -0.7071067);
// kernel[6] = vec2(0.0, -1.0);
// kernel[7] = vec2(0.7071067, -0.7071067);
kernel[0] = vec2(1.0, 0.0);
kernel[1] = vec2(0.8660254, 0.4999999);
kernel[2] = vec2(0.5, 0.8660254);
kernel[3] = vec2(0.0, 1.0);
kernel[4] = vec2(-0.4999999, 0.8660254);
kernel[5] = vec2(-0.8660254, 0.5);
kernel[6] = vec2(-1.0, 0.0);
kernel[7] = vec2(-0.8660254, -0.4999999);
kernel[8] = vec2(-0.5, -0.8660254);
kernel[9] = vec2(0.0, -1.0);
kernel[10] = vec2(0.4999999, -0.8660254);
kernel[11] = vec2(0.8660254, -0.5);
vec2 kernel[kernelSize];
// kernel[0] = vec2(1.0, 0.0);
// kernel[1] = vec2(0.8660254, 0.4999999);
// kernel[2] = vec2(0.5, 0.8660254);
// kernel[3] = vec2(0.0, 1.0);
// kernel[4] = vec2(-0.4999999, 0.8660254);
// kernel[5] = vec2(-0.8660254, 0.5);
// kernel[6] = vec2(-1.0, 0.0);
// kernel[7] = vec2(-0.8660254, -0.4999999);
// kernel[8] = vec2(-0.5, -0.8660254);
// kernel[9] = vec2(0.0, -1.0);
// kernel[10] = vec2(0.4999999, -0.8660254);
// kernel[11] = vec2(0.8660254, -0.5);
kernel[0] = vec2(1.0,0.0);
kernel[1] = vec2(0.9510565,0.3090169);
kernel[2] = vec2(0.8090169,0.5877852);
kernel[3] = vec2(0.5877852,0.8090169);
kernel[4] = vec2(0.3090169,0.9510565);
kernel[5] = vec2(0.0,1.0);
kernel[6] = vec2(-0.3090169,0.9510565);
kernel[7] = vec2(-0.5877852,0.8090169);
kernel[8] = vec2(-0.8090169,0.5877852);
kernel[9] = vec2(-0.9510565,0.3090169);
kernel[10] = vec2(-1,0);
kernel[11] = vec2(-0.9510565,-0.3090169);
kernel[12] = vec2(-0.8090169,-0.5877852);
kernel[13] = vec2(-0.5877852,-0.8090169);
kernel[14] = vec2(-0.3090169,-0.9510565);
kernel[15] = vec2(0.0,-1.0);
kernel[16] = vec2(0.3090169,-0.9510565);
kernel[17] = vec2(0.5877852,-0.8090169);
kernel[18] = vec2(0.8090169,-0.5877852);
kernel[19] = vec2(0.9510565,-0.3090169);
vec2 enc = texture(gbuffer0, texCoord).rg;
vec3 currentNormal;
@ -120,6 +134,18 @@ void main() {
amount += doAO(kernel[5], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[6], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[7], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[8], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[9], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[10], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[11], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[12], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[13], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[14], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[15], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[16], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[17], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[18], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[19], randomVec, rotMat, currentPos, currentNormal, currentDistance);
// }
amount *= strength / kernelSize;

View file

@ -187,14 +187,13 @@ vec2 unpackFloat(float f) {
}
void main() {
float roughness = unpackFloat(texture(gbuffer1, texCoord).a).x;
float reflectivity = 1.0 - roughness;
if (reflectivity == 0.0) {
if (roughness == 1.0) {
gl_FragColor = texture(tex, texCoord);
return;
// discard;
}
float reflectivity = 1.0 - roughness;
vec4 g0 = texture(gbuffer0, texCoord);
vec2 enc = g0.rg;
@ -229,7 +228,12 @@ void main() {
screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) *
clamp((searchDist - length(viewPos.xyz - hitCoord)) * (1.0 / searchDist), 0.0, 1.0) * coords.w;
vec4 texColor = texture(tex, texCoord);
float brightness = dot(texColor.rgb, vec3(0.2126, 0.7152, 0.0722));
intensity *= min(brightness, 1.0);
vec4 reflCol = vec4(texture(tex, coords.xy).rgb, 1.0);
gl_FragColor = texColor * (1.0 - intensity) + reflCol * intensity;
}

View file

@ -23,39 +23,39 @@ CMFT=./cmft-osx
# --output0params hdr,rgbe,latlong
# Typical parameters for generating spherical harmonics coefficients.
# eval $CMFT $@ --input "test.jpg" \
# --filter shcoeffs \
# --outputNum 1 \
# --output0 "test"
eval $CMFT $@ --input "test.hdr" \
--filter shcoeffs \
--outputNum 1 \
--output0 "test"
# Typical parameters for radiance filter.
eval $CMFT $@ --input "test.jpg" \
::Filter options \
--filter radiance \
--srcFaceSize 64 \
--excludeBase false \
--mipCount 7 \
--glossScale 10 \
--glossBias 3 \
--lightingModel blinnbrdf \
--edgeFixup none \
--dstFaceSize 64 \
::Processing devices \
--numCpuProcessingThreads 4 \
--useOpenCL true \
--clVendor anyGpuVendor \
--deviceType gpu \
--deviceIndex 0 \
::Aditional operations \
--inputGammaNumerator 2.2 \
--inputGammaDenominator 1.0 \
--outputGammaNumerator 1.0 \
--outputGammaDenominator 2.2 \
--generateMipChain true \
::Output \
--outputNum 1 \
--output0 "envmap_rad" \
--output0params hdr,rgbe,latlong \
# eval $CMFT $@ --input "test.jpg" \
# ::Filter options \
# --filter radiance \
# --srcFaceSize 64 \
# --excludeBase false \
# --mipCount 7 \
# --glossScale 10 \
# --glossBias 3 \
# --lightingModel blinnbrdf \
# --edgeFixup none \
# --dstFaceSize 64 \
# ::Processing devices \
# --numCpuProcessingThreads 4 \
# --useOpenCL true \
# --clVendor anyGpuVendor \
# --deviceType gpu \
# --deviceIndex 0 \
# ::Aditional operations \
# --inputGammaNumerator 2.2 \
# --inputGammaDenominator 1.0 \
# --outputGammaNumerator 1.0 \
# --outputGammaDenominator 2.2 \
# --generateMipChain true \
# ::Output \
# --outputNum 1 \
# --output0 "envmap_rad" \
# --output0params hdr,rgbe,latlong \
# --output1 "okretnica_pmrem" \
# --output1params ktx,rgba8,cubemap