Hybrid path-tracing, blended probes.
This commit is contained in:
parent
6439afb284
commit
0dbe35f27c
|
@ -6,13 +6,12 @@ import lue.math.Vec4;
|
|||
import lue.Trait;
|
||||
import lue.node.Transform;
|
||||
import lue.node.RootNode;
|
||||
import lue.node.ModelNode;
|
||||
import lue.resource.MaterialResource.MaterialContext;
|
||||
|
||||
class PathTracer extends Trait {
|
||||
|
||||
var context:MaterialContext;
|
||||
var eyeLocation:Int;
|
||||
var lightLocation:Int;
|
||||
var ray00Location:Int;
|
||||
var ray01Location:Int;
|
||||
var ray10Location:Int;
|
||||
|
@ -28,25 +27,19 @@ class PathTracer extends Trait {
|
|||
requestUpdate(update);
|
||||
}
|
||||
|
||||
function getColorFromNode(node:ModelNode):Array<Float> {
|
||||
// Hard code for now
|
||||
for (c in node.materials[0].contexts[0].resource.bind_constants) {
|
||||
if (c.id == "albedo_color") {
|
||||
return c.vec4;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function init() {
|
||||
context = Eg.getMaterialResource('pt_material').getContext('pt_trace_pass');
|
||||
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "eye",
|
||||
vec3: [0.0, 0.0, 0.0]
|
||||
}
|
||||
);
|
||||
eyeLocation = context.resource.bind_constants.length - 1;
|
||||
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "light",
|
||||
vec3: [0.9, 0.6, 1.1]
|
||||
}
|
||||
);
|
||||
lightLocation = context.resource.bind_constants.length - 1;
|
||||
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "glossiness",
|
||||
|
@ -89,16 +82,15 @@ class PathTracer extends Trait {
|
|||
objectLocations = [];
|
||||
transformMap = new Map();
|
||||
var sphereNum = 0;
|
||||
var cubeNum = 0;
|
||||
for (n in RootNode.models) {
|
||||
if (n.id.split(".")[0] == "Sphere") {
|
||||
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "sphereCenter" + sphereNum,
|
||||
vec3: [0.0, 0.0, 0.0]
|
||||
}
|
||||
);
|
||||
|
||||
var loc = context.resource.bind_constants.length - 1;
|
||||
objectLocations.push(loc);
|
||||
transformMap.set(loc, n.transform);
|
||||
|
@ -106,12 +98,48 @@ class PathTracer extends Trait {
|
|||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "sphereRadius" + sphereNum,
|
||||
float: 0.288
|
||||
float: n.transform.size.x / 2 - 0.02
|
||||
}
|
||||
);
|
||||
|
||||
var col = getColorFromNode(n);
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "sphereColor" + sphereNum,
|
||||
vec3: [col[0], col[1], col[2]]
|
||||
}
|
||||
);
|
||||
|
||||
sphereNum++;
|
||||
}
|
||||
else if (n.id.split(".")[0] == "Cube") {
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "cubeCenter" + cubeNum,
|
||||
vec3: [0.0, 0.0, 0.0]
|
||||
}
|
||||
);
|
||||
var loc = context.resource.bind_constants.length - 1;
|
||||
objectLocations.push(loc);
|
||||
transformMap.set(loc, n.transform);
|
||||
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "cubeSize" + cubeNum,
|
||||
vec3: [n.transform.size.x / 2, n.transform.size.y / 2, n.transform.size.z / 2]
|
||||
}
|
||||
);
|
||||
|
||||
var col = getColorFromNode(n);
|
||||
context.resource.bind_constants.push(
|
||||
{
|
||||
id: "cubeColor" + cubeNum,
|
||||
vec3: [col[0], col[1], col[2]]
|
||||
}
|
||||
);
|
||||
|
||||
cubeNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,9 +147,10 @@ class PathTracer extends Trait {
|
|||
var camera = RootNode.cameras[0];
|
||||
var eye = camera.transform.pos;
|
||||
|
||||
//var jitter = Mat4.identity();
|
||||
//jitter.initTranslate(Math.random() * 2 - 1, Math.random() * 2 - 1, 0);
|
||||
//jitter.multiplyScalar(1 / lue.App.w);
|
||||
// var jitter = Mat4.identity();
|
||||
// jitter.initTranslate(Math.random() * 2 - 1, Math.random() * 2 - 1, 0);
|
||||
// jitter.multiplyScalar(1 / lue.App.w);
|
||||
// jitter.multiplyScalar(1 / 400);
|
||||
var mvp = Mat4.identity();
|
||||
mvp.mult2(camera.V);
|
||||
mvp.mult2(camera.P);
|
||||
|
@ -131,7 +160,6 @@ class PathTracer extends Trait {
|
|||
var matrix = inverse;
|
||||
|
||||
// Set uniforms
|
||||
context.resource.bind_constants[eyeLocation].vec3 = [eye.x, eye.y, eye.z];
|
||||
|
||||
var v = getEyeRay(matrix, -1, -1, eye);
|
||||
context.resource.bind_constants[ray00Location].vec3 = [v.x, v.y, v.z];
|
||||
|
@ -147,9 +175,11 @@ class PathTracer extends Trait {
|
|||
|
||||
for (loc in objectLocations) {
|
||||
var t:Transform = transformMap.get(loc);
|
||||
context.resource.bind_constants[loc].vec3[0] = t.absx();
|
||||
context.resource.bind_constants[loc].vec3[1] = t.absy();
|
||||
context.resource.bind_constants[loc].vec3[2] = t.absz();
|
||||
t.buildMatrix();
|
||||
var c = context.resource.bind_constants[loc];
|
||||
c.vec3[0] = t.absx();
|
||||
c.vec3[1] = t.absy();
|
||||
c.vec3[2] = t.absz();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import math
|
|||
from mathutils import *
|
||||
import json
|
||||
import ast
|
||||
import write_probes
|
||||
from bpy_extras.io_utils import ExportHelper
|
||||
|
||||
kNodeTypeNode = 0
|
||||
|
@ -1746,16 +1747,9 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
o = Object()
|
||||
# w = worldRef[0]
|
||||
w = worldRef
|
||||
|
||||
# o.id = worldRef[1]["structName"]
|
||||
o.id = w.name
|
||||
envtex = bpy.data.cameras[0].world_envtex_name.rsplit('.', 1)[0]
|
||||
o.radiance = envtex + '_radiance'
|
||||
o.radiance_mipmaps = bpy.data.cameras[0].world_envtex_num_mips
|
||||
o.irradiance = envtex + '_irradiance'
|
||||
o.brdf = 'envmap_brdf'
|
||||
o.strength = bpy.data.cameras[0].world_envtex_strength
|
||||
|
||||
self.cb_export_world(w, o)
|
||||
self.output.world_resources.append(o)
|
||||
|
||||
def ExportObjects(self, scene):
|
||||
|
@ -2140,6 +2134,42 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
|||
else:
|
||||
# TODO: gather defs from vertex data when custom shader is used
|
||||
o.shader = material.custom_shader_name
|
||||
|
||||
def cb_export_world(self, world, o):
|
||||
o.brdf = 'envmap_brdf'
|
||||
o.probes = []
|
||||
# Main probe
|
||||
envtex = bpy.data.cameras[0].world_envtex_name.rsplit('.', 1)[0]
|
||||
num_mips = bpy.data.cameras[0].world_envtex_num_mips
|
||||
strength = bpy.data.cameras[0].world_envtex_strength
|
||||
po = self.make_probe('world', envtex, num_mips, strength, 1.0, [0, 0, 0], [0, 0, 0])
|
||||
o.probes.append(po)
|
||||
|
||||
# Probe cameras attached in scene
|
||||
for cam in bpy.data.cameras:
|
||||
if cam.is_probe:
|
||||
# Generate probe straight here for now
|
||||
volume_object = bpy.data.objects[cam.probe_volume]
|
||||
volume = [volume_object.scale[0], volume_object.scale[1], volume_object.scale[2]]
|
||||
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)
|
||||
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)
|
||||
|
||||
def make_probe(self, id, envtex, mipmaps, strength, blending, volume, volume_center):
|
||||
po = Object()
|
||||
po.id = id
|
||||
po.radiance = envtex + '_radiance'
|
||||
po.radiance_mipmaps = mipmaps
|
||||
po.irradiance = envtex + '_irradiance'
|
||||
po.strength = strength
|
||||
po.blending = blending
|
||||
po.volume = volume
|
||||
po.volume_center = volume_center
|
||||
return po
|
||||
|
||||
def finalize_shader(self, o, defs, pipeline_passes):
|
||||
# Merge duplicates and sort
|
||||
|
|
|
@ -495,14 +495,14 @@ def buildNodeTree(node_group, shader_references, asset_references):
|
|||
path = 'Assets/generated/pipelines/'
|
||||
node_group_name = node_group.name.replace('.', '_')
|
||||
|
||||
res.id = node_group_name
|
||||
res.render_targets, res.depth_buffers = get_render_targets(node_group)
|
||||
res.stages = []
|
||||
|
||||
rn = getRootNode(node_group)
|
||||
if rn == None:
|
||||
return
|
||||
|
||||
res.id = node_group_name
|
||||
res.render_targets, res.depth_buffers = get_render_targets(rn, node_group)
|
||||
res.stages = []
|
||||
|
||||
# Used to merge bind target nodes into one stage
|
||||
last_bind_target = None
|
||||
|
||||
|
@ -602,10 +602,11 @@ def make_draw_material_quad(stage, node_group, node, shader_references, asset_re
|
|||
material_context = node.inputs[context_index].default_value
|
||||
stage.params.append(material_context)
|
||||
# Include resource and shaders
|
||||
shader_context = node.inputs[context_index].default_value
|
||||
scon = shader_context.split('/')
|
||||
dir_name = scon[0]
|
||||
# Append world defs
|
||||
res_name = scon[1]
|
||||
dir_name = scon[2]
|
||||
# No world defs for material passes
|
||||
res_name = scon[2]
|
||||
asset_references.append('compiled/ShaderResources/' + dir_name + '/' + res_name + '.json')
|
||||
shader_references.append('compiled/Shaders/' + dir_name + '/' + res_name)
|
||||
|
||||
|
@ -758,6 +759,57 @@ def getRootNode(node_group):
|
|||
if n.bl_idname == 'BeginNodeType':
|
||||
return findNodeByLinkFrom(node_group, n, n.outputs[0])
|
||||
|
||||
def get_render_targets(root_node, node_group):
|
||||
render_targets = []
|
||||
depth_buffers = []
|
||||
traverse_for_rt(root_node, node_group, render_targets, depth_buffers)
|
||||
return render_targets, depth_buffers
|
||||
|
||||
def traverse_for_rt(node, node_group, render_targets, depth_buffers):
|
||||
# Collect render targets
|
||||
if node.bl_idname == 'SetTargetNodeType':
|
||||
if node.inputs[1].is_linked:
|
||||
tnode = findNodeByLink(node_group, node, node.inputs[1])
|
||||
parse_render_target(tnode, node_group, render_targets, depth_buffers)
|
||||
|
||||
# Next stage
|
||||
if node.outputs[0].is_linked:
|
||||
stagenode = findNodeByLinkFrom(node_group, node, node.outputs[0])
|
||||
traverse_for_rt(stagenode, node_group, render_targets, depth_buffers)
|
||||
|
||||
def parse_render_target(node, node_group, render_targets, depth_buffers):
|
||||
if node.bl_idname == 'TargetNodeType':
|
||||
# Target already exists
|
||||
id = node.inputs[0].default_value
|
||||
for t in render_targets:
|
||||
if t.id == id:
|
||||
return
|
||||
|
||||
depth_buffer_id = None
|
||||
if node.inputs[3].is_linked:
|
||||
# Find depth buffer
|
||||
depth_node = findNodeByLink(node_group, node, node.inputs[3])
|
||||
depth_buffer_id = depth_node.inputs[0].default_value
|
||||
# Append depth buffer
|
||||
found = False
|
||||
for db in depth_buffers:
|
||||
if db.id == depth_buffer_id:
|
||||
found = True
|
||||
break
|
||||
if found == False:
|
||||
db = Object()
|
||||
db.id = depth_buffer_id
|
||||
db.stencil_buffer = depth_node.inputs[1].default_value
|
||||
depth_buffers.append(db)
|
||||
# Append target
|
||||
target = make_render_target(node, depth_buffer_id=depth_buffer_id)
|
||||
render_targets.append(target)
|
||||
elif node.bl_idname == 'GBufferNodeType':
|
||||
for i in range(0, 5):
|
||||
if node.inputs[i].is_linked:
|
||||
n = findNodeByLink(node_group, node, node.inputs[i])
|
||||
parse_render_target(n, node_group, render_targets, depth_buffers)
|
||||
|
||||
def make_render_target(n, depth_buffer_id=None):
|
||||
target = Object()
|
||||
target.id = n.inputs[0].default_value
|
||||
|
@ -768,28 +820,4 @@ def make_render_target(n, depth_buffer_id=None):
|
|||
if depth_buffer_id != None:
|
||||
target.depth_buffer = depth_buffer_id
|
||||
return target
|
||||
|
||||
def get_render_targets(node_group):
|
||||
render_targets = []
|
||||
depth_buffers = []
|
||||
for n in node_group.nodes:
|
||||
if n.bl_idname == 'TargetNodeType':
|
||||
depth_buffer_id = None
|
||||
if n.inputs[3].is_linked:
|
||||
depth_node = findNodeByLink(node_group, n, n.inputs[3])
|
||||
depth_buffer_id = depth_node.inputs[0].default_value
|
||||
# Append depth buffer
|
||||
found = False
|
||||
for db in depth_buffers:
|
||||
if db.id == depth_buffer_id:
|
||||
found = True
|
||||
break
|
||||
if found == False:
|
||||
db = Object()
|
||||
db.id = depth_buffer_id
|
||||
db.stencil_buffer = depth_node.inputs[1].default_value
|
||||
depth_buffers.append(db)
|
||||
# Append target
|
||||
target = make_render_target(n, depth_buffer_id=depth_buffer_id)
|
||||
render_targets.append(target)
|
||||
return render_targets, depth_buffers
|
||||
|
|
@ -2,9 +2,8 @@ import bpy
|
|||
from bpy.types import NodeTree, Node, NodeSocket
|
||||
from bpy.props import *
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
import write_probes
|
||||
|
||||
def register():
|
||||
pass
|
||||
|
@ -62,15 +61,18 @@ def buildNodeTree(world_name, node_group, shader_references, asset_references):
|
|||
for node in node_group.nodes:
|
||||
# Env map included
|
||||
if node.type == 'TEX_ENVIRONMENT': # Just look for env texture for now
|
||||
image_name = node.image.name
|
||||
image_name = node.image.name # With extension
|
||||
texture.name = image_name.rsplit('.', 1)[0] # Remove extension
|
||||
# Add resources to khafie
|
||||
asset_references.append('compiled/ShaderResources/env_map/env_map.json')
|
||||
shader_references.append('compiled/Shaders/env_map/env_map')
|
||||
|
||||
# Generate prefiltered envmaps
|
||||
bpy.data.cameras[0].world_envtex_name = texture.name
|
||||
disable_hdr = image_name.endswith('.jpg')
|
||||
generate_envmaps(image_name, disable_hdr)
|
||||
mip_count = bpy.data.cameras[0].world_envtex_num_mips
|
||||
mip_count = write_probes.write_probes(image_name, disable_hdr, mip_count)
|
||||
bpy.data.cameras[0].world_envtex_num_mips = mip_count
|
||||
|
||||
# Append envtex define
|
||||
bpy.data.worlds[0].world_defs += '_EnvTex'
|
||||
|
@ -83,152 +85,13 @@ def buildNodeTree(world_name, node_group, shader_references, asset_references):
|
|||
bpy.data.cameras[0].world_envtex_strength = node.inputs[1].default_value
|
||||
if node.type == 'TEX_SKY':
|
||||
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)
|
||||
|
||||
with open(path + material_name + '.json', 'w') as f:
|
||||
f.write(output.to_JSON())
|
||||
|
||||
def generate_envmaps(image_name, disable_hdr):
|
||||
if not os.path.exists('Assets/generated/envmaps'):
|
||||
os.makedirs('Assets/generated/envmaps')
|
||||
|
||||
# Get paths
|
||||
# haxelib_path = "haxelib"
|
||||
# if platform.system() == 'Darwin':
|
||||
# haxelib_path = "/usr/local/bin/haxelib"
|
||||
|
||||
# output = subprocess.check_output([haxelib_path + " path cyclesgame"], shell=True)
|
||||
# output = str(output).split("\\n")[0].split("'")[1]
|
||||
# cmft_path = output[:-8] + "tools/cmft/"
|
||||
cmft_path = 'Libraries/cyclesgame/tools/cmft/'
|
||||
kraffiti_path = 'Kha/Kore/Tools/kraffiti/'
|
||||
generated_files = []
|
||||
output_gama_numerator = '1.0' if disable_hdr else '2.2'
|
||||
base_name = image_name.rsplit('.', 1)[0]
|
||||
input_file = 'Assets/textures/' + image_name
|
||||
|
||||
# Get input size
|
||||
output = subprocess.check_output([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + input_file + \
|
||||
' donothing'], shell=True)
|
||||
# #%ix%i
|
||||
image_w = str(output).split("'")[1]
|
||||
image_w = image_w[1:]
|
||||
image_w = image_w.split('x')[0]
|
||||
image_w = int(image_w)
|
||||
image_h = image_w / 2
|
||||
|
||||
# 4096 = 256 face - 6 mips - 1024 latlong
|
||||
# 2048 = 128 face - 5 mips - 512 latlong
|
||||
# 1024 = 64 face - 4 mips
|
||||
# 512 = 32 face - 3 mips
|
||||
# 256 = 16 face - 2 mips
|
||||
# 128 = 8 face - 1 mip
|
||||
mip_count = 1
|
||||
num = 128
|
||||
while num < image_w:
|
||||
num *= 2
|
||||
mip_count += 1
|
||||
|
||||
face_size = image_w / 16
|
||||
src_face_size = str(face_size)
|
||||
dst_face_size = str(face_size)
|
||||
|
||||
# Generate irradiance
|
||||
gama_options = ''
|
||||
if disable_hdr:
|
||||
gama_options = \
|
||||
' --inputGammaNumerator 2.2' + \
|
||||
' --inputGammaDenominator 1.0' + \
|
||||
' --outputGammaNumerator 1.0' + \
|
||||
' --outputGammaDenominator ' + output_gama_numerator
|
||||
|
||||
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)
|
||||
|
||||
# Generate radiance
|
||||
output_file = 'Assets/generated/envmaps/' + base_name + '_radiance'
|
||||
outformat = 'jpg' if disable_hdr else 'hdr'
|
||||
output = subprocess.check_output([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + input_file + \
|
||||
' to=' + output_file + '.' + outformat + \
|
||||
' format=' + outformat + \
|
||||
' scale=0.5'], shell=True)
|
||||
subprocess.call([ \
|
||||
cmft_path + 'cmft-osx' + \
|
||||
' --input ' + input_file + \
|
||||
' --filter radiance' + \
|
||||
' --dstFaceSize ' + dst_face_size + \
|
||||
' --srcFaceSize ' + src_face_size + \
|
||||
' --excludeBase false' + \
|
||||
' --mipCount ' + str(mip_count) + \
|
||||
' --glossScale 7' + \
|
||||
' --glossBias 3' + \
|
||||
' --lightingModel blinnbrdf' + \
|
||||
' --edgeFixup none' + \
|
||||
' --numCpuProcessingThreads 4' + \
|
||||
' --useOpenCL true' + \
|
||||
' --clVendor anyGpuVendor' + \
|
||||
' --deviceType gpu' + \
|
||||
' --deviceIndex 0' + \
|
||||
' --generateMipChain false' + \
|
||||
' --inputGammaNumerator 2.2' + \
|
||||
' --inputGammaDenominator 1.0' + \
|
||||
' --outputGammaNumerator 1.0' + \
|
||||
' --outputGammaDenominator ' + output_gama_numerator + \
|
||||
' --outputNum 1' + \
|
||||
' --output0 ' + output_file + \
|
||||
' --output0params hdr,rgbe,latlong'], shell=True)
|
||||
|
||||
# Remove size extensions in file name
|
||||
mip_w = int(face_size * 4)
|
||||
mip_h = int(face_size * 2)
|
||||
mip_base = output_file + '_'
|
||||
mip_num = 0
|
||||
while mip_w >= 32:
|
||||
mip_name = mip_base + str(mip_num)
|
||||
os.rename(
|
||||
mip_name + '_' + str(mip_w) + 'x' + str(mip_h) + '.hdr',
|
||||
mip_name + '.hdr')
|
||||
mip_w = int(mip_w / 2)
|
||||
mip_h = int(mip_h / 2)
|
||||
mip_num += 1
|
||||
|
||||
# Append mips
|
||||
for i in range(0, mip_count):
|
||||
generated_files.append(output_file + '_' + str(i))
|
||||
|
||||
# Convert to jpgs
|
||||
if disable_hdr is True:
|
||||
for f in generated_files:
|
||||
subprocess.call([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + f + '.hdr' + \
|
||||
' to=' + f + '.jpg' + \
|
||||
' format=jpg'], shell=True)
|
||||
os.remove(f + '.hdr')
|
||||
|
||||
# Scale from (32x16 to 1x1>
|
||||
for i in range (0, 5):
|
||||
last = generated_files[-1]
|
||||
out = output_file + '_' + str(mip_count + i)
|
||||
subprocess.call([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + last + '.' + outformat + \
|
||||
' to=' + out + '.' + outformat + \
|
||||
' scale=0.5' + \
|
||||
' format=' + outformat], shell=True)
|
||||
generated_files.append(out)
|
||||
|
||||
mip_count += 5
|
||||
bpy.data.cameras[0].world_envtex_num_mips = mip_count
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
import bpy
|
||||
import os
|
||||
|
||||
|
||||
bounces = '5'
|
||||
bounces = '2'
|
||||
epsilon = '0.0001'
|
||||
infinity = '10000.0'
|
||||
lightSize = 0.1
|
||||
|
@ -17,12 +16,11 @@ sampleCount = 0
|
|||
MATERIAL_DIFFUSE = 0
|
||||
MATERIAL_MIRROR = 1
|
||||
MATERIAL_GLOSSY = 2
|
||||
material = MATERIAL_MIRROR
|
||||
|
||||
YELLOW_BLUE_CORNELL_BOX = 0
|
||||
RED_GREEN_CORNELL_BOX = 1
|
||||
environment = YELLOW_BLUE_CORNELL_BOX
|
||||
material = MATERIAL_DIFFUSE
|
||||
|
||||
# YELLOW_BLUE_CORNELL_BOX = 0
|
||||
# RED_GREEN_CORNELL_BOX = 1
|
||||
# environment = YELLOW_BLUE_CORNELL_BOX
|
||||
|
||||
def concat(objects, func):
|
||||
text = ''
|
||||
|
@ -30,7 +28,6 @@ def concat(objects, func):
|
|||
text += func(objects[i])
|
||||
return text
|
||||
|
||||
|
||||
tracerFragmentSourceHeader = """
|
||||
#version 450
|
||||
#ifdef GL_ES
|
||||
|
@ -43,15 +40,22 @@ uniform vec3 eye;
|
|||
uniform float timeSinceStart;
|
||||
//uniform sampler2D stexture;
|
||||
uniform float glossiness;
|
||||
vec3 roomCubeMin = vec3(-1.0, -1.0, -1.0);
|
||||
vec3 roomCubeMax = vec3(1.0, 1.0, 1.0);
|
||||
//vec3 roomCubeMin = vec3(0.0, 0.0, 0.0);
|
||||
//vec3 roomCubeMax = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 origin;
|
||||
vec3 ray;
|
||||
vec3 colorMask = vec3(1.0);
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
"""
|
||||
|
||||
|
||||
# compute the near and far intersections of the cube (stored in the x and y components) using the slab method
|
||||
# no intersection means vec.x > vec.y (really tNear > tFar)
|
||||
intersectCubeSource = """
|
||||
vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeMin, vec3 cubeMax) {
|
||||
vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeCenter, vec3 cubeSize) {
|
||||
vec3 cubeMin = cubeCenter - cubeSize;
|
||||
vec3 cubeMax = cubeCenter + cubeSize;
|
||||
vec3 tMin = (cubeMin - origin) / ray;
|
||||
vec3 tMax = (cubeMax - origin) / ray;
|
||||
vec3 t1 = min(tMin, tMax);
|
||||
|
@ -66,14 +70,16 @@ vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeMin, vec3 cubeMax) {
|
|||
# given that hit is a point on the cube, what is the surface normal?
|
||||
# TODO: do this with fewer branches
|
||||
normalForCubeSource = """
|
||||
vec3 normalForCube(vec3 hit, vec3 cubeMin, vec3 cubeMax) {
|
||||
vec3 normalForCube(vec3 hit, vec3 cubeCenter, vec3 cubeSize) {
|
||||
vec3 cubeMin = cubeCenter - cubeSize;
|
||||
vec3 cubeMax = cubeCenter + cubeSize;
|
||||
if (hit.x < cubeMin.x + """ + epsilon + """) return vec3(-1.0, 0.0, 0.0);
|
||||
else if (hit.x > cubeMax.x - """ + epsilon + """) return vec3(1.0, 0.0, 0.0);
|
||||
else if (hit.y < cubeMin.y + """ + epsilon + """) return vec3(0.0, -1.0, 0.0);
|
||||
else if (hit.y > cubeMax.y - """ + epsilon + """) return vec3(0.0, 1.0, 0.0);
|
||||
else if (hit.z < cubeMin.z + """ + epsilon + """) return vec3(0.0, 0.0, -1.0);
|
||||
//else return vec3(0.0, 0.0, 1.0);
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -117,7 +123,7 @@ vec3 cosineWeightedDirection(float seed, vec3 normal) {
|
|||
if (abs(normal.x) < 0.5) {
|
||||
sdir = cross(normal, vec3(1.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
else {
|
||||
sdir = cross(normal, vec3(0.0, 1.0, 0.0));
|
||||
}
|
||||
tdir = cross(normal, sdir);
|
||||
|
@ -129,8 +135,11 @@ vec3 cosineWeightedDirection(float seed, vec3 normal) {
|
|||
# use the fragment position for randomness
|
||||
randomSource = """
|
||||
float random(vec3 scale, float seed) {
|
||||
return fract(sin(dot(texCoord.xyx + seed, scale)) * 43758.5453 + seed);
|
||||
// return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
||||
// return fract(sin(dot(texCoord.xyx + seed, scale)) * 43758.5453 + seed);
|
||||
float d = 43758.5453;
|
||||
float dt = dot(texCoord.xyx + seed,scale);
|
||||
float sn = mod(dt,3.1415926);
|
||||
return fract(sin(sn) * d);
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -182,14 +191,14 @@ newGlossyRay = """
|
|||
specularHighlight = pow(specularHighlight, 3.0);"""
|
||||
|
||||
|
||||
yellowBlueCornellBox = """
|
||||
if (hit.x < -0.9999) surfaceColor = vec3(0.1, 0.5, 1.0); // blue
|
||||
else if (hit.x > 0.9999) surfaceColor = vec3(1.0, 0.9, 0.1); // yellow"""
|
||||
# yellowBlueCornellBox = """
|
||||
# if (hit.x < -0.9999) surfaceColor = vec3(0.1, 0.1, 0.7); // blue
|
||||
# else if (hit.x > 0.9999) surfaceColor = vec3(0.7, 0.1, 0.1); // yellow"""
|
||||
|
||||
|
||||
redGreenCornellBox = """
|
||||
if (hit.x < -0.9999) surfaceColor = vec3(1.0, 0.3, 0.1); // red
|
||||
else if (hit.x > 0.9999) surfaceColor = vec3(0.3, 1.0, 0.1); // green"""
|
||||
# redGreenCornellBox = """
|
||||
# if (hit.x < -0.9999) surfaceColor = vec3(1.0, 0.3, 0.1); // red
|
||||
# else if (hit.x > 0.9999) surfaceColor = vec3(0.3, 1.0, 0.1); // green"""
|
||||
|
||||
|
||||
def _getShadowTestCode(o):
|
||||
|
@ -215,22 +224,14 @@ def _getMinimumIntersectCode(o):
|
|||
def _getNormalCalculationCode(o):
|
||||
return o.getNormalCalculationCode()
|
||||
|
||||
|
||||
def makeCalculateColor(objects):
|
||||
return """
|
||||
vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
||||
vec3 colorMask = vec3(1.0);
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
|
||||
// main raytracing loop
|
||||
for (int bounce = 0; bounce < """ + bounces + """; bounce++) {
|
||||
// compute the intersection with everything
|
||||
vec2 tRoom = intersectCube(origin, ray, roomCubeMin, roomCubeMax);
|
||||
def makeDoBounce(objects):
|
||||
return """
|
||||
int doBounce(float time, vec3 light, int bounce) {
|
||||
// compute the intersection with everything
|
||||
""" + concat(objects, _getIntersectCode) + """
|
||||
|
||||
// find the closest intersection
|
||||
float t = """ + infinity + """;
|
||||
if (tRoom.x < tRoom.y) t = tRoom.y;
|
||||
""" + concat(objects, _getMinimumIntersectCode) + """
|
||||
|
||||
// info about hit
|
||||
|
@ -239,17 +240,12 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
float specularHighlight = 0.0;
|
||||
vec3 normal;
|
||||
|
||||
// calculate the normal (and change wall color)
|
||||
if (t == tRoom.y) {
|
||||
normal = -normalForCube(hit, roomCubeMin, roomCubeMax);
|
||||
""" + [yellowBlueCornellBox, redGreenCornellBox][environment] + """
|
||||
""" + newDiffuseRay + """
|
||||
}
|
||||
else if (t == """ + infinity + """) {
|
||||
break;
|
||||
if (t == """ + infinity + """) {
|
||||
//break;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
int aa = 0;
|
||||
int aa = 0;
|
||||
if (aa == 1) {aa = 0;} // hack to discard the first 'else' in 'else if'
|
||||
""" + concat(objects, _getNormalCalculationCode) + """
|
||||
""" + [newDiffuseRay, newReflectiveRay, newGlossyRay][material] + """
|
||||
|
@ -257,39 +253,75 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
|
||||
// compute diffuse lighting contribution
|
||||
vec3 toLight = light - hit;
|
||||
float diffuse = max(0.0, dot(normalize(toLight), normal));
|
||||
|
||||
// trace a shadow ray to the light
|
||||
float shadowIntensity = shadow(hit + normal * """ + epsilon + """, toLight);
|
||||
//float diffuse = max(0.0, dot(normalize(toLight), normal));
|
||||
float diffuse = max(0.0, dot(normalize(toLight), normal)) / dot(toLight,toLight);
|
||||
|
||||
// do light bounce
|
||||
colorMask *= surfaceColor;
|
||||
accumulatedColor += colorMask * (""" + str(lightVal) + """ * diffuse * shadowIntensity);
|
||||
accumulatedColor += colorMask * specularHighlight * shadowIntensity;
|
||||
//if (bounce > 0) {
|
||||
// trace a shadow ray to the light
|
||||
float shadowIntensity = shadow(hit + normal * """ + epsilon + """, toLight);
|
||||
|
||||
accumulatedColor += colorMask * (""" + str(lightVal) + """ * diffuse * shadowIntensity);
|
||||
accumulatedColor += colorMask * specularHighlight * shadowIntensity;
|
||||
//}
|
||||
|
||||
// calculate next origin
|
||||
origin = hit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
def makeCalculateColor(objects):
|
||||
return """
|
||||
vec3 calculateColor(float time, vec3 _origin, vec3 _ray, vec3 light) {
|
||||
//vec3 colorMask = vec3(1.0);
|
||||
//vec3 accumulatedColor = vec3(0.0);
|
||||
|
||||
origin = _origin;
|
||||
ray = _ray;
|
||||
|
||||
// main raytracing loop
|
||||
//for (int bounce = 0; bounce < """ + bounces + """; bounce++) {
|
||||
int a;
|
||||
a = doBounce(time, light, 0);
|
||||
a = doBounce(time, light, 1);
|
||||
a = doBounce(time, light, 2);
|
||||
//}
|
||||
|
||||
return accumulatedColor;
|
||||
}
|
||||
"""
|
||||
|
||||
def makeDoSamples(num_samples):
|
||||
s = ''
|
||||
for i in range(0, num_samples):
|
||||
s += """newLight = light + uniformlyRandomVector(time - 53.0) * """ + str(lightSize) + """;
|
||||
"""
|
||||
s += """col += calculateColor(time, eye, initialRay, newLight);
|
||||
"""
|
||||
s += """time += 0.35;
|
||||
"""
|
||||
return s
|
||||
|
||||
def makeMain():
|
||||
return """
|
||||
void main() {
|
||||
float time = timeSinceStart;
|
||||
float time = 0.0;//timeSinceStart;
|
||||
//timeSinceStart % 46735.275 ) / 1000;
|
||||
vec3 col = vec3(0.0);
|
||||
const int samples = 1;
|
||||
vec3 newLight;
|
||||
|
||||
for (int i = 0; i < samples; i++) {
|
||||
vec3 newLight = light + uniformlyRandomVector(time - 53.0) * """ + str(lightSize) + """;
|
||||
col += calculateColor(time, eye, initialRay, newLight);
|
||||
time += 0.35;
|
||||
}
|
||||
//for (int i = 0; i < samples; i++) {
|
||||
""" + \
|
||||
makeDoSamples(1) + \
|
||||
"""
|
||||
//}
|
||||
|
||||
gl_FragColor = vec4(vec3(col / samples), 1.0);
|
||||
gl_FragColor.rgb = pow(gl_FragColor.rgb * 0.7, vec3(1.0 / 2.2));
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -310,22 +342,26 @@ def makeTracerFragmentSource(objects):
|
|||
uniformlyRandomDirectionSource + \
|
||||
uniformlyRandomVectorSource + \
|
||||
makeShadow(objects) + \
|
||||
makeDoBounce(objects) + \
|
||||
makeCalculateColor(objects) + \
|
||||
makeMain()
|
||||
|
||||
|
||||
class Sphere:
|
||||
def __init__(self, center, radius, id):
|
||||
def __init__(self, center, radius, color, id):
|
||||
self.center = center;
|
||||
self.radius = radius;
|
||||
self.color = color;
|
||||
self.centerStr = 'sphereCenter' + str(id);
|
||||
self.radiusStr = 'sphereRadius' + str(id);
|
||||
self.colorStr = 'sphereColor' + str(id);
|
||||
self.intersectStr = 'tSphere' + str(id);
|
||||
|
||||
def getGlobalCode(self):
|
||||
return """
|
||||
uniform vec3 """ + self.centerStr + """;
|
||||
uniform float """ + self.radiusStr + """;"""
|
||||
uniform float """ + self.radiusStr + """;
|
||||
uniform vec3 """ + self.colorStr + """;"""
|
||||
|
||||
def getIntersectCode(self):
|
||||
return """
|
||||
|
@ -342,25 +378,28 @@ uniform float """ + self.radiusStr + """;"""
|
|||
|
||||
def getNormalCalculationCode(self):
|
||||
return """
|
||||
else if (t == """ + self.intersectStr + """) normal = normalForSphere(hit, """ + self.centerStr + """, """ + self.radiusStr + """);"""
|
||||
else if (t == """ + self.intersectStr + """) { normal = normalForSphere(hit, """ + self.centerStr + """, """ + self.radiusStr + """); surfaceColor = """ + self.colorStr + """; }"""
|
||||
|
||||
|
||||
class Cube:
|
||||
def __init__(self, minCorner, maxCorner, id):
|
||||
self.minCorner = minCorner;
|
||||
self.maxCorner = maxCorner;
|
||||
self.minStr = 'cubeMin' + str(id);
|
||||
self.maxStr = 'cubeMax' + str(id);
|
||||
def __init__(self, center, size, color, id):
|
||||
self.center = center;
|
||||
self.size = size;
|
||||
self.color = color;
|
||||
self.centerStr = 'cubeCenter' + str(id);
|
||||
self.sizeStr = 'cubeSize' + str(id);
|
||||
self.colorStr = 'cubeColor' + str(id);
|
||||
self.intersectStr = 'tCube' + str(id);
|
||||
|
||||
def getGlobalCode(self):
|
||||
return """
|
||||
uniform vec3 """ + self.minStr + """;
|
||||
uniform vec3 """ + self.maxStr + """;"""
|
||||
uniform vec3 """ + self.centerStr + """;
|
||||
uniform vec3 """ + self.sizeStr + """;
|
||||
uniform vec3 """ + self.colorStr + """;"""
|
||||
|
||||
def getIntersectCode(self):
|
||||
return """
|
||||
vec2 """ + self.intersectStr + """ = intersectCube(origin, ray, """ + self.minStr + """, """ + self.maxStr + """);"""
|
||||
vec2 """ + self.intersectStr + """ = intersectCube(origin, ray, """ + self.centerStr + """, """ + self.sizeStr + """);"""
|
||||
|
||||
def getShadowTestCode(self):
|
||||
return """
|
||||
|
@ -375,7 +414,8 @@ uniform vec3 """ + self.maxStr + """;"""
|
|||
return """
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == """ + self.intersectStr + """.x && """ + self.intersectStr + """.x < """ + self.intersectStr + """.y) normal = normalForCube(hit, """ + self.minStr + """, """ + self.maxStr + """);"""
|
||||
else if (t == """ + self.intersectStr + """.x) { if (""" + self.intersectStr + """.x < """ + self.intersectStr + """.y) normal = normalForCube(hit, """ + self.centerStr + """, """ + self.sizeStr + """); surfaceColor = """ + self.colorStr + """; }"""
|
||||
#else if (t == """ + self.intersectStr + """.x && """ + self.intersectStr + """.x < """ + self.intersectStr + """.y) normal = normalForCube(hit, """ + self.centerStr + """, """ + self.sizeStr + """);"""
|
||||
|
||||
|
||||
class Light:
|
||||
|
@ -399,16 +439,20 @@ class Light:
|
|||
|
||||
|
||||
def initObjects():
|
||||
nextObjectId = 0
|
||||
objects = []
|
||||
objects.append(Light())
|
||||
|
||||
for o in bpy.context.scene.objects:
|
||||
if o.name.split('.', 1)[0] == 'Sphere':
|
||||
objects.append(Sphere([0, 0, 0], 0, nextObjectId))
|
||||
nextObjectId += 1
|
||||
|
||||
return objects
|
||||
nextSphereId = 0
|
||||
nextCubeId = 0
|
||||
objects = []
|
||||
objects.append(Light())
|
||||
|
||||
for o in bpy.context.scene.objects:
|
||||
if o.name.split('.', 1)[0] == 'Sphere':
|
||||
objects.append(Sphere([0, 0, 0], 0, [0.8, 0.8, 0.8], nextSphereId))
|
||||
nextSphereId += 1
|
||||
elif o.name.split('.', 1)[0] == 'Cube':
|
||||
objects.append(Cube([0, 0, 0], [0, 0, 0], [0.8, 0.8, 0.8], nextCubeId))
|
||||
nextCubeId += 1
|
||||
|
||||
return objects
|
||||
|
||||
objects = initObjects()
|
||||
|
||||
|
|
|
@ -29,6 +29,12 @@ def initProperties():
|
|||
bpy.types.Camera.geometry_context = bpy.props.StringProperty(name="Geometry", default="deferred")
|
||||
bpy.types.Camera.shadows_context = bpy.props.StringProperty(name="Shadows", default="shadowmap")
|
||||
bpy.types.Camera.translucent_context = bpy.props.StringProperty(name="Translucent", default="translucent")
|
||||
bpy.types.Camera.is_probe = bpy.props.BoolProperty(name="Probe", default=False)
|
||||
bpy.types.Camera.probe_texture = bpy.props.StringProperty(name="Texture", default="")
|
||||
bpy.types.Camera.probe_num_mips = bpy.props.IntProperty(name="Number of mips", default=0)
|
||||
bpy.types.Camera.probe_volume = bpy.props.StringProperty(name="Volume", default="")
|
||||
bpy.types.Camera.probe_strength = bpy.props.FloatProperty(name="Strength", default=1.0)
|
||||
bpy.types.Camera.probe_blending = bpy.props.FloatProperty(name="Blending", default=0.0)
|
||||
# TODO: move to world
|
||||
bpy.types.Camera.world_envtex_name = bpy.props.StringProperty(name="Environment Texture", default='')
|
||||
bpy.types.Camera.world_envtex_num_mips = bpy.props.IntProperty(name="Number of mips", default=0)
|
||||
|
@ -74,6 +80,13 @@ class DataPropsPanel(bpy.types.Panel):
|
|||
obj = bpy.context.object
|
||||
|
||||
if obj.type == 'CAMERA':
|
||||
layout.prop(obj.data, 'is_probe')
|
||||
if obj.data.is_probe == True:
|
||||
layout.prop(obj.data, 'probe_texture')
|
||||
layout.prop_search(obj.data, "probe_volume", bpy.data, "objects")
|
||||
layout.prop(obj.data, 'probe_strength')
|
||||
layout.prop(obj.data, 'probe_blending')
|
||||
|
||||
layout.prop(obj.data, 'frustum_culling')
|
||||
layout.prop(obj.data, 'sort_front_to_back')
|
||||
layout.prop_search(obj.data, "pipeline_path", bpy.data, "node_groups")
|
||||
|
|
158
blender/write_probes.py
Normal file
158
blender/write_probes.py
Normal file
|
@ -0,0 +1,158 @@
|
|||
import bpy
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# Generate probes from environment map
|
||||
def write_probes(image_name, disable_hdr, cached_num_mips):
|
||||
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):
|
||||
return cached_num_mips
|
||||
|
||||
# Get paths
|
||||
# haxelib_path = "haxelib"
|
||||
# if platform.system() == 'Darwin':
|
||||
# haxelib_path = "/usr/local/bin/haxelib"
|
||||
|
||||
# output = subprocess.check_output([haxelib_path + " path cyclesgame"], shell=True)
|
||||
# output = str(output).split("\\n")[0].split("'")[1]
|
||||
# cmft_path = output[:-8] + "tools/cmft/"
|
||||
cmft_path = 'Libraries/cyclesgame/tools/cmft/'
|
||||
kraffiti_path = 'Kha/Kore/Tools/kraffiti/'
|
||||
generated_files = []
|
||||
output_gama_numerator = '1.0' if disable_hdr else '2.2'
|
||||
input_file = 'Assets/textures/' + image_name
|
||||
|
||||
# Get input size
|
||||
output = subprocess.check_output([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + input_file + \
|
||||
' donothing'], shell=True)
|
||||
# #%ix%i
|
||||
image_w = str(output).split("'")[1]
|
||||
image_w = image_w[1:]
|
||||
image_w = image_w.split('x')[0]
|
||||
image_w = int(image_w)
|
||||
image_h = image_w / 2
|
||||
|
||||
# 4096 = 256 face - 6 mips - 1024 latlong
|
||||
# 2048 = 128 face - 5 mips - 512 latlong
|
||||
# 1024 = 64 face - 4 mips
|
||||
# 512 = 32 face - 3 mips
|
||||
# 256 = 16 face - 2 mips
|
||||
# 128 = 8 face - 1 mip
|
||||
mip_count = 1
|
||||
num = 128
|
||||
while num < image_w:
|
||||
num *= 2
|
||||
mip_count += 1
|
||||
|
||||
face_size = image_w / 16
|
||||
src_face_size = str(face_size)
|
||||
dst_face_size = str(face_size)
|
||||
|
||||
# Generate irradiance
|
||||
gama_options = ''
|
||||
if disable_hdr:
|
||||
gama_options = \
|
||||
' --inputGammaNumerator 2.2' + \
|
||||
' --inputGammaDenominator 1.0' + \
|
||||
' --outputGammaNumerator 1.0' + \
|
||||
' --outputGammaDenominator ' + output_gama_numerator
|
||||
|
||||
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)
|
||||
|
||||
# Generate radiance
|
||||
output_file = 'Assets/generated/envmaps/' + base_name + '_radiance'
|
||||
outformat = 'jpg' if disable_hdr else 'hdr'
|
||||
output = subprocess.check_output([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + input_file + \
|
||||
' to=' + output_file + '.' + outformat + \
|
||||
' format=' + outformat + \
|
||||
' scale=0.5'], shell=True)
|
||||
subprocess.call([ \
|
||||
cmft_path + 'cmft-osx' + \
|
||||
' --input ' + input_file + \
|
||||
' --filter radiance' + \
|
||||
' --dstFaceSize ' + dst_face_size + \
|
||||
' --srcFaceSize ' + src_face_size + \
|
||||
' --excludeBase false' + \
|
||||
' --mipCount ' + str(mip_count) + \
|
||||
' --glossScale 7' + \
|
||||
' --glossBias 3' + \
|
||||
' --lightingModel blinnbrdf' + \
|
||||
' --edgeFixup none' + \
|
||||
' --numCpuProcessingThreads 4' + \
|
||||
' --useOpenCL true' + \
|
||||
' --clVendor anyGpuVendor' + \
|
||||
' --deviceType gpu' + \
|
||||
' --deviceIndex 0' + \
|
||||
' --generateMipChain false' + \
|
||||
' --inputGammaNumerator 2.2' + \
|
||||
' --inputGammaDenominator 1.0' + \
|
||||
' --outputGammaNumerator 1.0' + \
|
||||
' --outputGammaDenominator ' + output_gama_numerator + \
|
||||
' --outputNum 1' + \
|
||||
' --output0 ' + output_file + \
|
||||
' --output0params hdr,rgbe,latlong'], shell=True)
|
||||
|
||||
# Remove size extensions in file name
|
||||
mip_w = int(face_size * 4)
|
||||
mip_h = int(face_size * 2)
|
||||
mip_base = output_file + '_'
|
||||
mip_num = 0
|
||||
while mip_w >= 32:
|
||||
mip_name = mip_base + str(mip_num)
|
||||
os.rename(
|
||||
mip_name + '_' + str(mip_w) + 'x' + str(mip_h) + '.hdr',
|
||||
mip_name + '.hdr')
|
||||
mip_w = int(mip_w / 2)
|
||||
mip_h = int(mip_h / 2)
|
||||
mip_num += 1
|
||||
|
||||
# Append mips
|
||||
for i in range(0, mip_count):
|
||||
generated_files.append(output_file + '_' + str(i))
|
||||
|
||||
# Convert to jpgs
|
||||
if disable_hdr is True:
|
||||
for f in generated_files:
|
||||
subprocess.call([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + f + '.hdr' + \
|
||||
' to=' + f + '.jpg' + \
|
||||
' format=jpg'], shell=True)
|
||||
os.remove(f + '.hdr')
|
||||
|
||||
# Scale from (32x16 to 1x1>
|
||||
for i in range (0, 5):
|
||||
last = generated_files[-1]
|
||||
out = output_file + '_' + str(mip_count + i)
|
||||
subprocess.call([ \
|
||||
kraffiti_path + 'kraffiti-osx' + \
|
||||
' from=' + last + '.' + outformat + \
|
||||
' to=' + out + '.' + outformat + \
|
||||
' scale=0.5' + \
|
||||
' format=' + outformat], shell=True)
|
||||
generated_files.append(out)
|
||||
|
||||
mip_count += 5
|
||||
return mip_count
|
||||
|
90
raw/blur_edge_pass/blur_edge_pass.frag.glsl
Normal file
90
raw/blur_edge_pass/blur_edge_pass.frag.glsl
Normal file
|
@ -0,0 +1,90 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform vec2 dir;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
const float blurWeights[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
const float discardThreshold = 0.95;
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
vec3 getNor(vec2 enc) {
|
||||
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);
|
||||
return n;
|
||||
}
|
||||
|
||||
float doBlur(float blurWeight, int pos, vec3 nor) {
|
||||
vec2 texstep = dir / vec2(800, 600);
|
||||
vec2 texstep2 = dir / vec2(800, 600);
|
||||
|
||||
vec3 nor2 = getNor(texture(gbuffer0, texCoord + pos * texstep2).rg);
|
||||
float influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
vec3 col = texture(tex, texCoord + pos * texstep).rgb;
|
||||
result += col * blurWeight * influenceFactor;
|
||||
float weight = blurWeight * influenceFactor;
|
||||
|
||||
nor2 = getNor(texture(gbuffer0, texCoord - pos * texstep2).rg);
|
||||
influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
col = texture(tex, texCoord - pos * texstep).rgb;
|
||||
result += col * blurWeight * influenceFactor;
|
||||
weight += blurWeight * influenceFactor;
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texstep = dir / vec2(800, 600);
|
||||
vec2 texstep2 = dir / vec2(800, 600);
|
||||
|
||||
vec3 nor = getNor(texture(gbuffer0, texCoord).rg);
|
||||
|
||||
float weight = 0.0;
|
||||
|
||||
// for (int i = 0; i < 9; i++) {
|
||||
// float blurWeight = blurWeights[0];
|
||||
const float radius = 10.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);
|
||||
// }
|
||||
|
||||
result /= weight;
|
||||
gl_FragColor = vec4(result.rgb, 1.0);
|
||||
}
|
60
raw/blur_edge_pass/blur_edge_pass.shader.json
Executable file
60
raw/blur_edge_pass/blur_edge_pass.shader.json
Executable file
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"contexts": [
|
||||
{
|
||||
"id": "blur_edge_pass_x",
|
||||
"params": [
|
||||
{
|
||||
"id": "depth_write",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"id": "compare_mode",
|
||||
"value": "always"
|
||||
},
|
||||
{
|
||||
"id": "cull_mode",
|
||||
"value": "none"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"id": "dir",
|
||||
"link": "_vec2x"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_edge_pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"id": "blur_edge_pass_y",
|
||||
"params": [
|
||||
{
|
||||
"id": "depth_write",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"id": "compare_mode",
|
||||
"value": "always"
|
||||
},
|
||||
{
|
||||
"id": "cull_mode",
|
||||
"value": "none"
|
||||
},
|
||||
{
|
||||
"id": "dir",
|
||||
"link": "_vec2y"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"id": "dir",
|
||||
"link": "_vec2y"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_edge_pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
18
raw/blur_edge_pass/blur_edge_pass.vert.glsl
Normal file
18
raw/blur_edge_pass/blur_edge_pass.vert.glsl
Normal file
|
@ -0,0 +1,18 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
|
@ -9,21 +9,40 @@ uniform vec2 dir;
|
|||
|
||||
in vec2 texCoord;
|
||||
|
||||
const vec2 screenSize = vec2(1920, 1080);
|
||||
const vec2 screenSize = vec2(800, 600);
|
||||
|
||||
void main() {
|
||||
vec2 step = dir / screenSize;
|
||||
|
||||
float result = texture(tex, texCoord + (step * 4.0)).r;
|
||||
result += texture(tex, texCoord + (step * 3.0)).r;
|
||||
result += texture(tex, texCoord + (step * 2.0)).r;
|
||||
result += texture(tex, texCoord + step).r;
|
||||
result += texture(tex, texCoord).r;
|
||||
result += texture(tex, texCoord - step).r;
|
||||
result += texture(tex, texCoord - (step * 2.0)).r;
|
||||
result += texture(tex, texCoord - (step * 3.0)).r;
|
||||
result += texture(tex, texCoord - (step * 4.0)).r;
|
||||
result /= 9.0;
|
||||
vec3 result = texture(tex, texCoord + (step * 4.0)).rgb;
|
||||
result += texture(tex, texCoord + (step * 3.0)).rgb;
|
||||
result += texture(tex, texCoord + (step * 2.0)).rgb;
|
||||
result += texture(tex, texCoord + step).rgb;
|
||||
result += texture(tex, texCoord).rgb;
|
||||
result += texture(tex, texCoord - step).rgb;
|
||||
result += texture(tex, texCoord - (step * 2.0)).rgb;
|
||||
result += texture(tex, texCoord - (step * 3.0)).rgb;
|
||||
result += texture(tex, texCoord - (step * 4.0)).rgb;
|
||||
result /= vec3(9.0);
|
||||
|
||||
// vec3 result = texture(tex, texCoord + (step * 8.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 7.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 6.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 5.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 4.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 3.0)).rgb;
|
||||
// result += texture(tex, texCoord + (step * 2.0)).rgb;
|
||||
// result += texture(tex, texCoord + step).rgb;
|
||||
// result += texture(tex, texCoord).rgb;
|
||||
// result += texture(tex, texCoord - step).rgb;
|
||||
// result += texture(tex, texCoord - (step * 2.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 3.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 4.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 5.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 6.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 7.0)).rgb;
|
||||
// result += texture(tex, texCoord - (step * 8.0)).rgb;
|
||||
// result /= vec3(17.0);
|
||||
|
||||
gl_FragColor.rgb = vec3(result);
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
// uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform vec2 dir;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 pixelStep = dir / vec2(800, 600);
|
||||
vec3 blurredResult = vec3( 0.0, 0.0, 0.0 );
|
||||
|
||||
float depth = texture(gbuffer0, texCoord).a;
|
||||
float weight = 0.0;
|
||||
|
||||
// for (float i = -3.0; i <= 3.0; i += 1.0) {
|
||||
// float pixelDepth = texture(gbuffer0, texCoord + i * pixelStep).a;
|
||||
// float pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
// weight += pixelWeight;
|
||||
// blurredResult += texture(tex, texCoord + i * pixelStep).rgb * pixelWeight;
|
||||
|
||||
float pixelDepth = texture(gbuffer0, texCoord + pixelStep * -3).a;
|
||||
float pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * -3).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * -2).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * -2).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * -1).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * -1).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 0).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * 0).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 1).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * 1).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 2).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * 2).rgb * pixelWeight;
|
||||
|
||||
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 3).a;
|
||||
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
|
||||
weight += pixelWeight;
|
||||
blurredResult += texture(tex, texCoord + pixelStep * 3).rgb * pixelWeight;
|
||||
// }
|
||||
|
||||
blurredResult /= weight;
|
||||
gl_FragColor = vec4(vec3(blurredResult), 1.0);
|
||||
}
|
|
@ -348,5 +348,9 @@ void main() {
|
|||
// col.rgb = vec3(clamp(dot(col.rgb, col.rgb), 0.0, 1.0));
|
||||
// col.rgb = vec3((col.r * 0.3 + col.g * 0.59 + col.b * 0.11) / 3.0) * 2.5;
|
||||
|
||||
// Letter box
|
||||
// const float letterBoxSize = 0.1;
|
||||
// col.rgb *= 1.0 - step(0.5 - letterBoxSize, abs(0.5 - texCoord.y));
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ uniform float metalness;
|
|||
#endif
|
||||
uniform float mask;
|
||||
|
||||
#ifdef _Probe1
|
||||
uniform int probeID;
|
||||
uniform vec3 probeVolumeCenter;
|
||||
uniform vec3 probeVolumeSize;
|
||||
#endif
|
||||
|
||||
in vec4 mvpposition;
|
||||
#ifdef _AMTex
|
||||
in vec2 texCoord;
|
||||
|
@ -41,6 +47,10 @@ in mat3 TBN;
|
|||
in vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Probe1
|
||||
in vec4 mpos;
|
||||
#endif
|
||||
|
||||
float packFloat(float f1, float f2) {
|
||||
int index = int(f1 * 1000);
|
||||
float alpha = f2 == 0.0 ? f2 : (f2 - 0.0001);
|
||||
|
@ -52,6 +62,13 @@ 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
|
||||
float distanceBox(vec3 point, vec3 center, vec3 halfExtents) {
|
||||
vec3 d = abs(point - center) - halfExtents;
|
||||
return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _NMTex
|
||||
|
@ -90,6 +107,16 @@ 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);
|
||||
float mask_probe = probeID;
|
||||
if (probeID > 0) {
|
||||
const float eps = 0.00001;
|
||||
mask_probe += clamp(0.5 + dist * 3.0, 0, 1.0 - eps);
|
||||
}
|
||||
gl_FragData[0] = vec4(n.xy, occlusion, mask_probe);
|
||||
#else
|
||||
gl_FragData[0] = vec4(n.xy, occlusion, mask);
|
||||
#endif
|
||||
gl_FragData[1] = vec4(baseColor.rgb, packFloat(roughness, metalness));
|
||||
}
|
||||
|
|
|
@ -37,6 +37,26 @@
|
|||
"id": "skinBones",
|
||||
"link": "_skinBones",
|
||||
"ifdef": ["_Skinning"]
|
||||
},
|
||||
{
|
||||
"id": "probeID",
|
||||
"link": "_probeID",
|
||||
"ifdef": ["_Probe1"]
|
||||
},
|
||||
{
|
||||
"id": "M",
|
||||
"link": "_modelMatrix",
|
||||
"ifdef": ["_Probe1"]
|
||||
},
|
||||
{
|
||||
"id": "probeVolumeCenter",
|
||||
"link": "_probeVolumeCenter",
|
||||
"ifdef": ["_Probe1"]
|
||||
},
|
||||
{
|
||||
"id": "probeVolumeSize",
|
||||
"link": "_probeVolumeSize",
|
||||
"ifdef": ["_Probe1"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "deferred.vert.glsl",
|
||||
|
|
|
@ -36,6 +36,11 @@ uniform vec4 albedo_color;
|
|||
uniform float skinBones[50 * 12];
|
||||
#endif
|
||||
|
||||
#ifdef _Probe1
|
||||
uniform mat4 M;
|
||||
#endif
|
||||
|
||||
|
||||
out vec4 mvpposition;
|
||||
#ifdef _AMTex
|
||||
out vec2 texCoord;
|
||||
|
@ -48,6 +53,10 @@ out mat3 TBN;
|
|||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Probe1
|
||||
out vec4 mpos;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
mat4 getBoneMat(const int boneIndex) {
|
||||
vec4 v0 = vec4(skinBones[boneIndex * 12 + 0],
|
||||
|
@ -104,6 +113,10 @@ void main() {
|
|||
//MV[2][0] = 0.0; MV[2][1] = 0.0; MV[2][2] = 1.0;
|
||||
#endif
|
||||
|
||||
#ifdef _Probe1
|
||||
mpos = M * sPos;
|
||||
#endif
|
||||
|
||||
gl_Position = P * MV * sPos;
|
||||
|
||||
#ifdef _AMTex
|
||||
|
|
|
@ -9,19 +9,42 @@ precision mediump float;
|
|||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
uniform sampler2D ssaotex;
|
||||
|
||||
uniform sampler2D shadowMap;
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapIrradiance;
|
||||
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;
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
// #ifdef _LTC
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
|
||||
uniform float envmapStrength;
|
||||
uniform int envmapNumMipmaps;
|
||||
// #endif
|
||||
|
||||
// uniform mat4 invVP;
|
||||
uniform mat4 LMVP;
|
||||
|
@ -185,7 +208,7 @@ float shadowTest(vec4 lPos) {
|
|||
lPosH.x = (lPosH.x + 1.0) / 2.0;
|
||||
lPosH.y = 1.0 - ((-lPosH.y + 1.0) / (2.0));
|
||||
|
||||
const float bias = 0.0029;
|
||||
const float bias = 0.012;
|
||||
// const float bias = 0.01;
|
||||
return PCF(vec2(2048, 2048), lPosH.st, lPosH.z - bias);
|
||||
}
|
||||
|
@ -408,6 +431,10 @@ float wardSpecular(vec3 N, vec3 H, float dotNL, float dotNV, float dotNH, vec3 f
|
|||
}
|
||||
#endif
|
||||
|
||||
vec4 gaussian(vec4 x, vec4 m, float s) {
|
||||
return exp(-(x-m)*(x-m)/(s*s));
|
||||
}
|
||||
|
||||
void main() {
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
// float depth = 1.0 - g0.a;
|
||||
|
@ -453,6 +480,8 @@ void main() {
|
|||
// visibility = 1.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Direct
|
||||
vec3 direct = diffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH, dotLV) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH, dotLH);
|
||||
// Aniso spec
|
||||
|
@ -463,32 +492,103 @@ void main() {
|
|||
direct = direct * lightColor * lightStrength;
|
||||
|
||||
// SSS only masked objects
|
||||
if (texture(gbuffer0, texCoord).a == 2.0) {
|
||||
float mask = g0.a;
|
||||
if (mask == 2.0) {
|
||||
direct.rgb = direct.rgb * SSSSTransmittance(1.0, 0.005, p, n, lightDir);
|
||||
}
|
||||
|
||||
|
||||
// Indirect
|
||||
vec3 indirectDiffuse = texture(senvmapIrradiance, envMapEquirect(n)).rgb;
|
||||
#ifdef _LDR
|
||||
indirectDiffuse = pow(indirectDiffuse, vec3(2.2));
|
||||
#ifdef _Probe1
|
||||
float probeFactor = mask;
|
||||
float probeID = floor(probeFactor);
|
||||
float probeFract = fract(probeFactor);
|
||||
|
||||
vec3 indirectDiffuse;
|
||||
vec3 prefilteredColor;
|
||||
vec2 envCoord = envMapEquirect(n);
|
||||
|
||||
float lod = getMipLevelFromRoughness(roughness);
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
vec2 envCoordRefl = envMapEquirect(reflectionWorld);
|
||||
|
||||
// Global probe only
|
||||
if (probeID == 0.0) {
|
||||
indirectDiffuse = texture(senvmapIrradiance, envCoord).rgb;
|
||||
prefilteredColor = textureLod(senvmapRadiance, envCoordRefl, lod).rgb;
|
||||
}
|
||||
// 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);
|
||||
if (probeFract > 0.0) {
|
||||
indirectDiffuse += texture(senvmapIrradiance, envCoord).rgb * (probeFract);
|
||||
prefilteredColor += textureLod(senvmapRadiance, envCoordRefl, lod).rgb * (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
|
||||
indirectDiffuse *= albedo;
|
||||
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
#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 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _LDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LDR
|
||||
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.02.2));////
|
||||
indirectDiffuse *= albedo;
|
||||
|
||||
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
|
||||
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
|
||||
vec3 indirect = indirectDiffuse + indirectSpecular;
|
||||
indirect = indirect * lightColor * lightStrength * envmapStrength;
|
||||
float occlusion = g0.b;
|
||||
|
||||
vec4 outColor = vec4(vec3(direct * visibility + indirect * ao * occlusion), 1.0);
|
||||
|
||||
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));
|
||||
// indirect = nois.rgb;
|
||||
// vec4 outColor = vec4(vec3(direct * visibility + indirect * 3.0 * ao * occlusion), 1.0);
|
||||
|
||||
|
||||
// LTC
|
||||
|
|
|
@ -65,6 +65,46 @@
|
|||
"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",
|
||||
|
|
|
@ -10,70 +10,71 @@ uniform vec3 eye;
|
|||
uniform float timeSinceStart;
|
||||
//uniform sampler2D stexture;
|
||||
uniform float glossiness;
|
||||
vec3 roomCubeMin = vec3(-1.0, -1.0, -1.0);
|
||||
vec3 roomCubeMax = vec3(1.0, 1.0, 1.0);
|
||||
//vec3 roomCubeMin = vec3(0.0, 0.0, 0.0);
|
||||
//vec3 roomCubeMax = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 origin;
|
||||
vec3 ray;
|
||||
vec3 colorMask = vec3(1.0);
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
uniform vec3 light;
|
||||
uniform vec3 sphereCenter0;
|
||||
uniform float sphereRadius0;
|
||||
uniform vec3 sphereColor0;
|
||||
uniform vec3 sphereCenter1;
|
||||
uniform float sphereRadius1;
|
||||
uniform vec3 sphereColor1;
|
||||
uniform vec3 sphereCenter2;
|
||||
uniform float sphereRadius2;
|
||||
uniform vec3 sphereColor2;
|
||||
uniform vec3 sphereCenter3;
|
||||
uniform float sphereRadius3;
|
||||
uniform vec3 sphereColor3;
|
||||
uniform vec3 sphereCenter4;
|
||||
uniform float sphereRadius4;
|
||||
uniform vec3 sphereColor4;
|
||||
uniform vec3 sphereCenter5;
|
||||
uniform float sphereRadius5;
|
||||
uniform vec3 sphereColor5;
|
||||
uniform vec3 sphereCenter6;
|
||||
uniform float sphereRadius6;
|
||||
uniform vec3 sphereColor6;
|
||||
uniform vec3 sphereCenter7;
|
||||
uniform float sphereRadius7;
|
||||
uniform vec3 sphereColor7;
|
||||
uniform vec3 sphereCenter8;
|
||||
uniform float sphereRadius8;
|
||||
uniform vec3 sphereColor8;
|
||||
uniform vec3 sphereCenter9;
|
||||
uniform float sphereRadius9;
|
||||
uniform vec3 sphereColor9;
|
||||
uniform vec3 sphereCenter10;
|
||||
uniform float sphereRadius10;
|
||||
uniform vec3 sphereColor10;
|
||||
uniform vec3 cubeCenter0;
|
||||
uniform vec3 cubeSize0;
|
||||
uniform vec3 cubeColor0;
|
||||
uniform vec3 cubeCenter1;
|
||||
uniform vec3 cubeSize1;
|
||||
uniform vec3 cubeColor1;
|
||||
uniform vec3 cubeCenter2;
|
||||
uniform vec3 cubeSize2;
|
||||
uniform vec3 cubeColor2;
|
||||
uniform vec3 cubeCenter3;
|
||||
uniform vec3 cubeSize3;
|
||||
uniform vec3 cubeColor3;
|
||||
uniform vec3 cubeCenter4;
|
||||
uniform vec3 cubeSize4;
|
||||
uniform vec3 cubeColor4;
|
||||
uniform vec3 cubeCenter5;
|
||||
uniform vec3 cubeSize5;
|
||||
uniform vec3 cubeColor5;
|
||||
uniform vec3 sphereCenter11;
|
||||
uniform float sphereRadius11;
|
||||
uniform vec3 sphereCenter12;
|
||||
uniform float sphereRadius12;
|
||||
uniform vec3 sphereCenter13;
|
||||
uniform float sphereRadius13;
|
||||
uniform vec3 sphereCenter14;
|
||||
uniform float sphereRadius14;
|
||||
uniform vec3 sphereCenter15;
|
||||
uniform float sphereRadius15;
|
||||
uniform vec3 sphereCenter16;
|
||||
uniform float sphereRadius16;
|
||||
uniform vec3 sphereCenter17;
|
||||
uniform float sphereRadius17;
|
||||
uniform vec3 sphereCenter18;
|
||||
uniform float sphereRadius18;
|
||||
uniform vec3 sphereCenter19;
|
||||
uniform float sphereRadius19;
|
||||
uniform vec3 sphereCenter20;
|
||||
uniform float sphereRadius20;
|
||||
uniform vec3 sphereCenter21;
|
||||
uniform float sphereRadius21;
|
||||
uniform vec3 sphereCenter22;
|
||||
uniform float sphereRadius22;
|
||||
uniform vec3 sphereCenter23;
|
||||
uniform float sphereRadius23;
|
||||
uniform vec3 sphereCenter24;
|
||||
uniform float sphereRadius24;
|
||||
uniform vec3 sphereCenter25;
|
||||
uniform float sphereRadius25;
|
||||
uniform vec3 sphereCenter26;
|
||||
uniform float sphereRadius26;
|
||||
uniform vec3 sphereCenter27;
|
||||
uniform float sphereRadius27;
|
||||
uniform vec3 sphereCenter28;
|
||||
uniform float sphereRadius28;
|
||||
uniform vec3 sphereCenter29;
|
||||
uniform float sphereRadius29;
|
||||
vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeMin, vec3 cubeMax) {
|
||||
uniform vec3 sphereColor11;
|
||||
vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeCenter, vec3 cubeSize) {
|
||||
vec3 cubeMin = cubeCenter - cubeSize;
|
||||
vec3 cubeMax = cubeCenter + cubeSize;
|
||||
vec3 tMin = (cubeMin - origin) / ray;
|
||||
vec3 tMax = (cubeMax - origin) / ray;
|
||||
vec3 t1 = min(tMin, tMax);
|
||||
|
@ -83,14 +84,16 @@ vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeMin, vec3 cubeMax) {
|
|||
return vec2(tNear, tFar);
|
||||
}
|
||||
|
||||
vec3 normalForCube(vec3 hit, vec3 cubeMin, vec3 cubeMax) {
|
||||
vec3 normalForCube(vec3 hit, vec3 cubeCenter, vec3 cubeSize) {
|
||||
vec3 cubeMin = cubeCenter - cubeSize;
|
||||
vec3 cubeMax = cubeCenter + cubeSize;
|
||||
if (hit.x < cubeMin.x + 0.0001) return vec3(-1.0, 0.0, 0.0);
|
||||
else if (hit.x > cubeMax.x - 0.0001) return vec3(1.0, 0.0, 0.0);
|
||||
else if (hit.y < cubeMin.y + 0.0001) return vec3(0.0, -1.0, 0.0);
|
||||
else if (hit.y > cubeMax.y - 0.0001) return vec3(0.0, 1.0, 0.0);
|
||||
else if (hit.z < cubeMin.z + 0.0001) return vec3(0.0, 0.0, -1.0);
|
||||
//else return vec3(0.0, 0.0, 1.0);
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float intersectSphere(vec3 origin, vec3 ray, vec3 sphereCenter, float sphereRadius) {
|
||||
|
@ -111,8 +114,11 @@ vec3 normalForSphere(vec3 hit, vec3 sphereCenter, float sphereRadius) {
|
|||
}
|
||||
|
||||
float random(vec3 scale, float seed) {
|
||||
return fract(sin(dot(texCoord.xyx + seed, scale)) * 43758.5453 + seed);
|
||||
// return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
||||
// return fract(sin(dot(texCoord.xyx + seed, scale)) * 43758.5453 + seed);
|
||||
float d = 43758.5453;
|
||||
float dt = dot(texCoord.xyx + seed,scale);
|
||||
float sn = mod(dt,3.1415926);
|
||||
return fract(sin(sn) * d);
|
||||
}
|
||||
|
||||
vec3 cosineWeightedDirection(float seed, vec3 normal) {
|
||||
|
@ -125,7 +131,7 @@ vec3 cosineWeightedDirection(float seed, vec3 normal) {
|
|||
if (abs(normal.x) < 0.5) {
|
||||
sdir = cross(normal, vec3(1.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
else {
|
||||
sdir = cross(normal, vec3(0.0, 1.0, 0.0));
|
||||
}
|
||||
tdir = cross(normal, sdir);
|
||||
|
@ -181,72 +187,30 @@ float shadow(vec3 origin, vec3 ray) {
|
|||
float tSphere10 = intersectSphere(origin, ray, sphereCenter10, sphereRadius10);
|
||||
if (tSphere10 < 1.0) return 0.0;
|
||||
|
||||
vec2 tCube0 = intersectCube(origin, ray, cubeCenter0, cubeSize0);
|
||||
if (tCube0.x > 0.0 && tCube0.x < 1.0 && tCube0.x < tCube0.y) return 0.0;
|
||||
|
||||
vec2 tCube1 = intersectCube(origin, ray, cubeCenter1, cubeSize1);
|
||||
if (tCube1.x > 0.0 && tCube1.x < 1.0 && tCube1.x < tCube1.y) return 0.0;
|
||||
|
||||
vec2 tCube2 = intersectCube(origin, ray, cubeCenter2, cubeSize2);
|
||||
if (tCube2.x > 0.0 && tCube2.x < 1.0 && tCube2.x < tCube2.y) return 0.0;
|
||||
|
||||
vec2 tCube3 = intersectCube(origin, ray, cubeCenter3, cubeSize3);
|
||||
if (tCube3.x > 0.0 && tCube3.x < 1.0 && tCube3.x < tCube3.y) return 0.0;
|
||||
|
||||
vec2 tCube4 = intersectCube(origin, ray, cubeCenter4, cubeSize4);
|
||||
if (tCube4.x > 0.0 && tCube4.x < 1.0 && tCube4.x < tCube4.y) return 0.0;
|
||||
|
||||
vec2 tCube5 = intersectCube(origin, ray, cubeCenter5, cubeSize5);
|
||||
if (tCube5.x > 0.0 && tCube5.x < 1.0 && tCube5.x < tCube5.y) return 0.0;
|
||||
|
||||
float tSphere11 = intersectSphere(origin, ray, sphereCenter11, sphereRadius11);
|
||||
if (tSphere11 < 1.0) return 0.0;
|
||||
|
||||
float tSphere12 = intersectSphere(origin, ray, sphereCenter12, sphereRadius12);
|
||||
if (tSphere12 < 1.0) return 0.0;
|
||||
|
||||
float tSphere13 = intersectSphere(origin, ray, sphereCenter13, sphereRadius13);
|
||||
if (tSphere13 < 1.0) return 0.0;
|
||||
|
||||
float tSphere14 = intersectSphere(origin, ray, sphereCenter14, sphereRadius14);
|
||||
if (tSphere14 < 1.0) return 0.0;
|
||||
|
||||
float tSphere15 = intersectSphere(origin, ray, sphereCenter15, sphereRadius15);
|
||||
if (tSphere15 < 1.0) return 0.0;
|
||||
|
||||
float tSphere16 = intersectSphere(origin, ray, sphereCenter16, sphereRadius16);
|
||||
if (tSphere16 < 1.0) return 0.0;
|
||||
|
||||
float tSphere17 = intersectSphere(origin, ray, sphereCenter17, sphereRadius17);
|
||||
if (tSphere17 < 1.0) return 0.0;
|
||||
|
||||
float tSphere18 = intersectSphere(origin, ray, sphereCenter18, sphereRadius18);
|
||||
if (tSphere18 < 1.0) return 0.0;
|
||||
|
||||
float tSphere19 = intersectSphere(origin, ray, sphereCenter19, sphereRadius19);
|
||||
if (tSphere19 < 1.0) return 0.0;
|
||||
|
||||
float tSphere20 = intersectSphere(origin, ray, sphereCenter20, sphereRadius20);
|
||||
if (tSphere20 < 1.0) return 0.0;
|
||||
|
||||
float tSphere21 = intersectSphere(origin, ray, sphereCenter21, sphereRadius21);
|
||||
if (tSphere21 < 1.0) return 0.0;
|
||||
|
||||
float tSphere22 = intersectSphere(origin, ray, sphereCenter22, sphereRadius22);
|
||||
if (tSphere22 < 1.0) return 0.0;
|
||||
|
||||
float tSphere23 = intersectSphere(origin, ray, sphereCenter23, sphereRadius23);
|
||||
if (tSphere23 < 1.0) return 0.0;
|
||||
|
||||
float tSphere24 = intersectSphere(origin, ray, sphereCenter24, sphereRadius24);
|
||||
if (tSphere24 < 1.0) return 0.0;
|
||||
|
||||
float tSphere25 = intersectSphere(origin, ray, sphereCenter25, sphereRadius25);
|
||||
if (tSphere25 < 1.0) return 0.0;
|
||||
|
||||
float tSphere26 = intersectSphere(origin, ray, sphereCenter26, sphereRadius26);
|
||||
if (tSphere26 < 1.0) return 0.0;
|
||||
|
||||
float tSphere27 = intersectSphere(origin, ray, sphereCenter27, sphereRadius27);
|
||||
if (tSphere27 < 1.0) return 0.0;
|
||||
|
||||
float tSphere28 = intersectSphere(origin, ray, sphereCenter28, sphereRadius28);
|
||||
if (tSphere28 < 1.0) return 0.0;
|
||||
|
||||
float tSphere29 = intersectSphere(origin, ray, sphereCenter29, sphereRadius29);
|
||||
if (tSphere29 < 1.0) return 0.0;
|
||||
return 1.0;
|
||||
}
|
||||
vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
||||
vec3 colorMask = vec3(1.0);
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
|
||||
// main raytracing loop
|
||||
for (int bounce = 0; bounce < 5; bounce++) {
|
||||
// compute the intersection with everything
|
||||
vec2 tRoom = intersectCube(origin, ray, roomCubeMin, roomCubeMax);
|
||||
int doBounce(float time, vec3 light, int bounce) {
|
||||
// compute the intersection with everything
|
||||
|
||||
float tSphere0 = intersectSphere(origin, ray, sphereCenter0, sphereRadius0);
|
||||
float tSphere1 = intersectSphere(origin, ray, sphereCenter1, sphereRadius1);
|
||||
|
@ -259,29 +223,16 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
float tSphere8 = intersectSphere(origin, ray, sphereCenter8, sphereRadius8);
|
||||
float tSphere9 = intersectSphere(origin, ray, sphereCenter9, sphereRadius9);
|
||||
float tSphere10 = intersectSphere(origin, ray, sphereCenter10, sphereRadius10);
|
||||
vec2 tCube0 = intersectCube(origin, ray, cubeCenter0, cubeSize0);
|
||||
vec2 tCube1 = intersectCube(origin, ray, cubeCenter1, cubeSize1);
|
||||
vec2 tCube2 = intersectCube(origin, ray, cubeCenter2, cubeSize2);
|
||||
vec2 tCube3 = intersectCube(origin, ray, cubeCenter3, cubeSize3);
|
||||
vec2 tCube4 = intersectCube(origin, ray, cubeCenter4, cubeSize4);
|
||||
vec2 tCube5 = intersectCube(origin, ray, cubeCenter5, cubeSize5);
|
||||
float tSphere11 = intersectSphere(origin, ray, sphereCenter11, sphereRadius11);
|
||||
float tSphere12 = intersectSphere(origin, ray, sphereCenter12, sphereRadius12);
|
||||
float tSphere13 = intersectSphere(origin, ray, sphereCenter13, sphereRadius13);
|
||||
float tSphere14 = intersectSphere(origin, ray, sphereCenter14, sphereRadius14);
|
||||
float tSphere15 = intersectSphere(origin, ray, sphereCenter15, sphereRadius15);
|
||||
float tSphere16 = intersectSphere(origin, ray, sphereCenter16, sphereRadius16);
|
||||
float tSphere17 = intersectSphere(origin, ray, sphereCenter17, sphereRadius17);
|
||||
float tSphere18 = intersectSphere(origin, ray, sphereCenter18, sphereRadius18);
|
||||
float tSphere19 = intersectSphere(origin, ray, sphereCenter19, sphereRadius19);
|
||||
float tSphere20 = intersectSphere(origin, ray, sphereCenter20, sphereRadius20);
|
||||
float tSphere21 = intersectSphere(origin, ray, sphereCenter21, sphereRadius21);
|
||||
float tSphere22 = intersectSphere(origin, ray, sphereCenter22, sphereRadius22);
|
||||
float tSphere23 = intersectSphere(origin, ray, sphereCenter23, sphereRadius23);
|
||||
float tSphere24 = intersectSphere(origin, ray, sphereCenter24, sphereRadius24);
|
||||
float tSphere25 = intersectSphere(origin, ray, sphereCenter25, sphereRadius25);
|
||||
float tSphere26 = intersectSphere(origin, ray, sphereCenter26, sphereRadius26);
|
||||
float tSphere27 = intersectSphere(origin, ray, sphereCenter27, sphereRadius27);
|
||||
float tSphere28 = intersectSphere(origin, ray, sphereCenter28, sphereRadius28);
|
||||
float tSphere29 = intersectSphere(origin, ray, sphereCenter29, sphereRadius29);
|
||||
|
||||
// find the closest intersection
|
||||
float t = 10000.0;
|
||||
if (tRoom.x < tRoom.y) t = tRoom.y;
|
||||
|
||||
if (tSphere0 < t) t = tSphere0;
|
||||
if (tSphere1 < t) t = tSphere1;
|
||||
|
@ -294,25 +245,13 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
if (tSphere8 < t) t = tSphere8;
|
||||
if (tSphere9 < t) t = tSphere9;
|
||||
if (tSphere10 < t) t = tSphere10;
|
||||
if (tCube0.x > 0.0 && tCube0.x < tCube0.y && tCube0.x < t) t = tCube0.x;
|
||||
if (tCube1.x > 0.0 && tCube1.x < tCube1.y && tCube1.x < t) t = tCube1.x;
|
||||
if (tCube2.x > 0.0 && tCube2.x < tCube2.y && tCube2.x < t) t = tCube2.x;
|
||||
if (tCube3.x > 0.0 && tCube3.x < tCube3.y && tCube3.x < t) t = tCube3.x;
|
||||
if (tCube4.x > 0.0 && tCube4.x < tCube4.y && tCube4.x < t) t = tCube4.x;
|
||||
if (tCube5.x > 0.0 && tCube5.x < tCube5.y && tCube5.x < t) t = tCube5.x;
|
||||
if (tSphere11 < t) t = tSphere11;
|
||||
if (tSphere12 < t) t = tSphere12;
|
||||
if (tSphere13 < t) t = tSphere13;
|
||||
if (tSphere14 < t) t = tSphere14;
|
||||
if (tSphere15 < t) t = tSphere15;
|
||||
if (tSphere16 < t) t = tSphere16;
|
||||
if (tSphere17 < t) t = tSphere17;
|
||||
if (tSphere18 < t) t = tSphere18;
|
||||
if (tSphere19 < t) t = tSphere19;
|
||||
if (tSphere20 < t) t = tSphere20;
|
||||
if (tSphere21 < t) t = tSphere21;
|
||||
if (tSphere22 < t) t = tSphere22;
|
||||
if (tSphere23 < t) t = tSphere23;
|
||||
if (tSphere24 < t) t = tSphere24;
|
||||
if (tSphere25 < t) t = tSphere25;
|
||||
if (tSphere26 < t) t = tSphere26;
|
||||
if (tSphere27 < t) t = tSphere27;
|
||||
if (tSphere28 < t) t = tSphere28;
|
||||
if (tSphere29 < t) t = tSphere29;
|
||||
|
||||
// info about hit
|
||||
vec3 hit = origin + ray * t;
|
||||
|
@ -320,52 +259,44 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
float specularHighlight = 0.0;
|
||||
vec3 normal;
|
||||
|
||||
// calculate the normal (and change wall color)
|
||||
if (t == tRoom.y) {
|
||||
normal = -normalForCube(hit, roomCubeMin, roomCubeMax);
|
||||
|
||||
if (hit.x < -0.9999) surfaceColor = vec3(0.1, 0.5, 1.0); // blue
|
||||
else if (hit.x > 0.9999) surfaceColor = vec3(1.0, 0.9, 0.1); // yellow
|
||||
|
||||
ray = cosineWeightedDirection(time + float(bounce), normal);
|
||||
}
|
||||
else if (t == 10000.0) {
|
||||
break;
|
||||
if (t == 10000.0) {
|
||||
//break;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
int aa = 0;
|
||||
int aa = 0;
|
||||
if (aa == 1) {aa = 0;} // hack to discard the first 'else' in 'else if'
|
||||
|
||||
else if (t == tSphere0) normal = normalForSphere(hit, sphereCenter0, sphereRadius0);
|
||||
else if (t == tSphere1) normal = normalForSphere(hit, sphereCenter1, sphereRadius1);
|
||||
else if (t == tSphere2) normal = normalForSphere(hit, sphereCenter2, sphereRadius2);
|
||||
else if (t == tSphere3) normal = normalForSphere(hit, sphereCenter3, sphereRadius3);
|
||||
else if (t == tSphere4) normal = normalForSphere(hit, sphereCenter4, sphereRadius4);
|
||||
else if (t == tSphere5) normal = normalForSphere(hit, sphereCenter5, sphereRadius5);
|
||||
else if (t == tSphere6) normal = normalForSphere(hit, sphereCenter6, sphereRadius6);
|
||||
else if (t == tSphere7) normal = normalForSphere(hit, sphereCenter7, sphereRadius7);
|
||||
else if (t == tSphere8) normal = normalForSphere(hit, sphereCenter8, sphereRadius8);
|
||||
else if (t == tSphere9) normal = normalForSphere(hit, sphereCenter9, sphereRadius9);
|
||||
else if (t == tSphere10) normal = normalForSphere(hit, sphereCenter10, sphereRadius10);
|
||||
else if (t == tSphere11) normal = normalForSphere(hit, sphereCenter11, sphereRadius11);
|
||||
else if (t == tSphere12) normal = normalForSphere(hit, sphereCenter12, sphereRadius12);
|
||||
else if (t == tSphere13) normal = normalForSphere(hit, sphereCenter13, sphereRadius13);
|
||||
else if (t == tSphere14) normal = normalForSphere(hit, sphereCenter14, sphereRadius14);
|
||||
else if (t == tSphere15) normal = normalForSphere(hit, sphereCenter15, sphereRadius15);
|
||||
else if (t == tSphere16) normal = normalForSphere(hit, sphereCenter16, sphereRadius16);
|
||||
else if (t == tSphere17) normal = normalForSphere(hit, sphereCenter17, sphereRadius17);
|
||||
else if (t == tSphere18) normal = normalForSphere(hit, sphereCenter18, sphereRadius18);
|
||||
else if (t == tSphere19) normal = normalForSphere(hit, sphereCenter19, sphereRadius19);
|
||||
else if (t == tSphere20) normal = normalForSphere(hit, sphereCenter20, sphereRadius20);
|
||||
else if (t == tSphere21) normal = normalForSphere(hit, sphereCenter21, sphereRadius21);
|
||||
else if (t == tSphere22) normal = normalForSphere(hit, sphereCenter22, sphereRadius22);
|
||||
else if (t == tSphere23) normal = normalForSphere(hit, sphereCenter23, sphereRadius23);
|
||||
else if (t == tSphere24) normal = normalForSphere(hit, sphereCenter24, sphereRadius24);
|
||||
else if (t == tSphere25) normal = normalForSphere(hit, sphereCenter25, sphereRadius25);
|
||||
else if (t == tSphere26) normal = normalForSphere(hit, sphereCenter26, sphereRadius26);
|
||||
else if (t == tSphere27) normal = normalForSphere(hit, sphereCenter27, sphereRadius27);
|
||||
else if (t == tSphere28) normal = normalForSphere(hit, sphereCenter28, sphereRadius28);
|
||||
else if (t == tSphere29) normal = normalForSphere(hit, sphereCenter29, sphereRadius29);
|
||||
else if (t == tSphere0) { normal = normalForSphere(hit, sphereCenter0, sphereRadius0); surfaceColor = sphereColor0; }
|
||||
else if (t == tSphere1) { normal = normalForSphere(hit, sphereCenter1, sphereRadius1); surfaceColor = sphereColor1; }
|
||||
else if (t == tSphere2) { normal = normalForSphere(hit, sphereCenter2, sphereRadius2); surfaceColor = sphereColor2; }
|
||||
else if (t == tSphere3) { normal = normalForSphere(hit, sphereCenter3, sphereRadius3); surfaceColor = sphereColor3; }
|
||||
else if (t == tSphere4) { normal = normalForSphere(hit, sphereCenter4, sphereRadius4); surfaceColor = sphereColor4; }
|
||||
else if (t == tSphere5) { normal = normalForSphere(hit, sphereCenter5, sphereRadius5); surfaceColor = sphereColor5; }
|
||||
else if (t == tSphere6) { normal = normalForSphere(hit, sphereCenter6, sphereRadius6); surfaceColor = sphereColor6; }
|
||||
else if (t == tSphere7) { normal = normalForSphere(hit, sphereCenter7, sphereRadius7); surfaceColor = sphereColor7; }
|
||||
else if (t == tSphere8) { normal = normalForSphere(hit, sphereCenter8, sphereRadius8); surfaceColor = sphereColor8; }
|
||||
else if (t == tSphere9) { normal = normalForSphere(hit, sphereCenter9, sphereRadius9); surfaceColor = sphereColor9; }
|
||||
else if (t == tSphere10) { normal = normalForSphere(hit, sphereCenter10, sphereRadius10); surfaceColor = sphereColor10; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube0.x) { if (tCube0.x < tCube0.y) normal = normalForCube(hit, cubeCenter0, cubeSize0); surfaceColor = cubeColor0; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube1.x) { if (tCube1.x < tCube1.y) normal = normalForCube(hit, cubeCenter1, cubeSize1); surfaceColor = cubeColor1; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube2.x) { if (tCube2.x < tCube2.y) normal = normalForCube(hit, cubeCenter2, cubeSize2); surfaceColor = cubeColor2; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube3.x) { if (tCube3.x < tCube3.y) normal = normalForCube(hit, cubeCenter3, cubeSize3); surfaceColor = cubeColor3; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube4.x) { if (tCube4.x < tCube4.y) normal = normalForCube(hit, cubeCenter4, cubeSize4); surfaceColor = cubeColor4; }
|
||||
// have to compare intersectStr.x < intersectStr.y otherwise two coplanar
|
||||
// cubes will look wrong (one cube will "steal" the hit from the other)
|
||||
else if (t == tCube5.x) { if (tCube5.x < tCube5.y) normal = normalForCube(hit, cubeCenter5, cubeSize5); surfaceColor = cubeColor5; }
|
||||
else if (t == tSphere11) { normal = normalForSphere(hit, sphereCenter11, sphereRadius11); surfaceColor = sphereColor11; }
|
||||
|
||||
ray = reflect(ray, normal);
|
||||
|
||||
|
@ -376,33 +307,57 @@ vec3 calculateColor(float time, vec3 origin, vec3 ray, vec3 light) {
|
|||
|
||||
// compute diffuse lighting contribution
|
||||
vec3 toLight = light - hit;
|
||||
float diffuse = max(0.0, dot(normalize(toLight), normal));
|
||||
|
||||
// trace a shadow ray to the light
|
||||
float shadowIntensity = shadow(hit + normal * 0.0001, toLight);
|
||||
//float diffuse = max(0.0, dot(normalize(toLight), normal));
|
||||
float diffuse = max(0.0, dot(normalize(toLight), normal)) / dot(toLight,toLight);
|
||||
|
||||
// do light bounce
|
||||
colorMask *= surfaceColor;
|
||||
accumulatedColor += colorMask * (0.5 * diffuse * shadowIntensity);
|
||||
accumulatedColor += colorMask * specularHighlight * shadowIntensity;
|
||||
//if (bounce > 0) {
|
||||
// trace a shadow ray to the light
|
||||
float shadowIntensity = 1.0;//shadow(hit + normal * 0.0001, toLight);
|
||||
|
||||
accumulatedColor += colorMask * (0.5 * diffuse * shadowIntensity);
|
||||
accumulatedColor += colorMask * specularHighlight * shadowIntensity;
|
||||
//}
|
||||
|
||||
// calculate next origin
|
||||
origin = hit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec3 calculateColor(float time, vec3 _origin, vec3 _ray, vec3 light) {
|
||||
//vec3 colorMask = vec3(1.0);
|
||||
//vec3 accumulatedColor = vec3(0.0);
|
||||
|
||||
origin = _origin;
|
||||
ray = _ray;
|
||||
|
||||
// main raytracing loop
|
||||
//for (int bounce = 0; bounce < 2; bounce++) {
|
||||
int a;
|
||||
a = doBounce(time, light, 0);
|
||||
a = doBounce(time, light, 1);
|
||||
a = doBounce(time, light, 2);
|
||||
//}
|
||||
|
||||
return accumulatedColor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float time = timeSinceStart;
|
||||
float time = 0.0;//timeSinceStart;
|
||||
//timeSinceStart % 46735.275 ) / 1000;
|
||||
vec3 col = vec3(0.0);
|
||||
const int samples = 1;
|
||||
vec3 newLight;
|
||||
|
||||
for (int i = 0; i < samples; i++) {
|
||||
vec3 newLight = light + uniformlyRandomVector(time - 53.0) * 0.1;
|
||||
col += calculateColor(time, eye, initialRay, newLight);
|
||||
time += 0.35;
|
||||
}
|
||||
//for (int i = 0; i < samples; i++) {
|
||||
newLight = light + uniformlyRandomVector(time - 53.0) * 0.1;
|
||||
col += calculateColor(time, eye, initialRay, newLight);
|
||||
time += 0.35;
|
||||
|
||||
//}
|
||||
|
||||
gl_FragColor = vec4(vec3(col / samples), 1.0);
|
||||
gl_FragColor.rgb = pow(gl_FragColor.rgb * 0.7, vec3(1.0 / 2.2));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
{
|
||||
"id": "timeSinceStart",
|
||||
"link": "_time"
|
||||
},
|
||||
{
|
||||
"id": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"id": "light",
|
||||
"link": "_lightPosition"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
|
|
Loading…
Reference in a new issue