More compositor nodes + clean up.

This commit is contained in:
Lubos Lenco 2016-08-15 23:45:03 +02:00
parent 7ef3d53945
commit 5d1f9e4c66
14 changed files with 367 additions and 655 deletions

View file

@ -16,7 +16,7 @@ class Root {
public function new() {
// Startup scene
var scene = iron.Root.addScene(Main.projectScene);
var sceneNode = iron.Root.addScene(Main.projectScene);
cam = iron.Root.cameras[0];
// Attach world to camera for now
@ -25,9 +25,20 @@ class Root {
// Physics
physics = new PhysicsWorld(resource.gravity);
scene.addTrait(physics);
sceneNode.addTrait(physics);
App.notifyOnRender(render);
// Experimental scene reloading
// App.notifyOnUpdate(function() {
// if (iron.sys.Input.released) {
// // kha.Assets.loadBlob(Main.projectScene + '_arm', function(b:kha.Blob) {
// iron.App.reset();
// iron.resource.Resource.clearSceneData();
// new iron.App(armory.Root);
// // });
// }
// });
}
function render(g:kha.graphics4.Graphics) {

Binary file not shown.

View file

@ -1368,7 +1368,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
pref['particle'] = self.particleSystemArray[psys.settings]["structName"]
o['particle_refs'].append(pref)
def get_viewport_matrix(self):
def get_viewport_view_matrix(self):
screen = bpy.context.window.screen
for area in screen.areas:
if area.type == 'VIEW_3D':
@ -1377,6 +1377,15 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
return space.region_3d.view_matrix
return None
def get_viewport_projection_matrix(self):
screen = bpy.context.window.screen
for area in screen.areas:
if area.type == 'VIEW_3D':
for space in area.spaces:
if space.type == 'VIEW_3D':
return space.region_3d.perspective_matrix
return None
def ExportNode(self, node, scene, poseBone = None, parento = None):
# This function exports a single node in the scene and includes its name,
# object reference, material references (for geometries), and transform.
@ -1463,7 +1472,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
# Viewport Camera - overwrite active camera matrix with viewport matrix
if type == kNodeTypeCamera and bpy.data.worlds[0].ArmPlayViewportCamera:
viewport_matrix = self.get_viewport_matrix()
viewport_matrix = self.get_viewport_view_matrix()
if viewport_matrix != None:
o['transform']['values'] = self.WriteMatrix(viewport_matrix.inverted())
# Do not apply parent matrix
@ -2124,6 +2133,14 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
o['near_plane'] = object.clip_start
o['far_plane'] = object.clip_end
o['fov'] = object.angle
# Viewport Camera - override fov for every camera for now
if bpy.data.worlds[0].ArmPlayViewportCamera:
# Extract fov from projection
# yscale = self.get_viewport_projection_matrix()[1][1]
# fov = math.atan(1.0 / yscale) * 0.9
# o['fov'] = fov
o['fov'] = math.pi / 3.0
if object.type == 'PERSP':
o['type'] = 'perspective'

View file

@ -14,8 +14,76 @@ def unregister():
#bpy.utils.unregister_module(__name__)
def parse_defs(node_group):
defs = ''
rn = get_root_node(node_group)
if rn == None:
return ''
parse_defs.defs = []
build_node(node_group, get_input_node(node_group, rn, 0))
# Always include tonemap for now
add_def('_CompoTonemap')
# To string
s = ''
for d in parse_defs.defs:
s += d
return s
def add_def(s):
# Only push unique
for d in parse_defs.defs:
if d == s:
return
parse_defs.defs.append(s)
def build_node(node_group, node):
# Inputs to follow
inps = []
if node.type == 'RGBTOBW':
add_def('_CompoBW')
inps.append(0)
elif node.type == 'TONEMAP':
add_def('_CompoTonemap')
inps.append(0)
elif node.type == 'LENSDIST':
add_def('_CompoFishEye')
inps.append(0)
elif node.type == 'GLARE':
add_def('_CompoGlare')
inps.append(0)
elif node.type == 'ELLIPSEMASK':
add_def('_CompoVignette')
elif node.type == 'MIX_RGB':
inps.append(1)
inps.append(2)
elif node.type == 'BLUR':
inps.append(0)
# Build next stage
for inp in inps:
if node.inputs[inp].is_linked:
next_node = get_input_node(node_group, node, inp)
build_node(node_group, next_node)
def get_root_node(node_group):
for node in node_group.nodes:
if node.type == 'RGBTOBW':
defs += '_BW'
return defs
if node.type == 'COMPOSITE':
return node
def get_input_node(node_group, to_node, input_index):
for link in node_group.links:
if link.to_node == to_node and link.to_socket == to_node.inputs[input_index]:
if link.from_node.bl_idname == 'NodeReroute': # Step through reroutes
return findNodeByLink(node_group, link.from_node, link.from_node.inputs[0])
return link.from_node
def get_output_node(node_group, from_node, output_index):
for link in node_group.links:
if link.from_node == from_node and link.from_socket == from_node.outputs[output_index]:
if link.to_node.bl_idname == 'NodeReroute': # Step through reroutes
return findNodeByLinkFrom(node_group, link.to_node, link.to_node.inputs[0])
return link.to_node

View file

@ -216,7 +216,7 @@ def buildNodeTree(node_group):
f.write('\tpublic function new() { super(); notifyOnAdd(add); }\n\n')
f.write('\tfunction add() {\n')
# Make sure root node exists
roots = getRootNodes(node_group)
roots = get_root_nodes(node_group)
created_nodes = []
for rn in roots:
name = '_' + rn.name.replace('.', '_').replace(' ', '')
@ -260,7 +260,7 @@ def buildNode(node_group, node, f, created_nodes):
inpname = buildNode(node_group, n, f, created_nodes)
# Not linked - create node with default values
else:
inpname = buildDefaultNode(inp)
inpname = build_default_node(inp)
# Add input
f.write('\t\t' + name + '.inputs.push(' + inpname + ');\n')
@ -274,14 +274,14 @@ def findNodeByLink(node_group, to_node, inp):
return findNodeByLink(node_group, link.from_node, link.from_node.inputs[0])
return link.from_node
def getRootNodes(node_group):
def get_root_nodes(node_group):
roots = []
for n in node_group.nodes:
if len(n.outputs) == 0: # Assume node with no outputs as roots
roots.append(n)
return roots
def buildDefaultNode(inp):
def build_default_node(inp):
inpname = ''
if inp.type == "VECTOR":
inpname = 'VectorNode.create(' + str(inp.default_value[0]) + ', ' + str(inp.default_value[1]) + ", " + str(inp.default_value[2]) + ')'

View file

@ -603,6 +603,7 @@ class DrawCompositorNode(Node, CGPipelineTreeNode):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "Depth")
self.inputs.new('NodeSocketShader', "Normals")
self.outputs.new('NodeSocketShader', "Stage")
@ -617,6 +618,7 @@ class DrawCompositorWithFXAANode(Node, CGPipelineTreeNode):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "Depth")
self.inputs.new('NodeSocketShader', "Normals")
self.outputs.new('NodeSocketShader', "Stage")
@ -808,7 +810,7 @@ def buildNodeTree(node_group, shader_references, asset_references):
path = 'compiled/Assets/pipelines/'
node_group_name = node_group.name.replace('.', '_')
rn = getRootNode(node_group)
rn = get_root_node(node_group)
if rn == None:
return
@ -966,10 +968,32 @@ def make_draw_world(stage, node_group, node, shader_references, asset_references
def make_draw_compositor(stage, node_group, node, shader_references, asset_references, with_fxaa=False):
scon = 'compositor_pass'
world_defs = bpy.data.worlds[0].world_defs
wrd = bpy.data.worlds[0]
world_defs = wrd.world_defs
compositor_defs = nodes_compositor.parse_defs(bpy.data.scenes[0].node_tree) # Thrown in scene 0 for now
# Additional compositor flags
compo_depth = False # Read depth
compo_pos = False # Construct position from depth
if with_fxaa: # FXAA directly in compositor, useful for forward path
compositor_defs += '_CompFXAA'
compositor_defs += '_CompoFXAA'
if wrd.generate_letterbox:
compositor_defs += '_CompoLetterbox'
if wrd.generate_grain:
compositor_defs += '_CompoGrain'
if bpy.data.scenes[0].cycles.film_exposure != 1.0:
compositor_defs += '_CompoExposure'
if wrd.generate_fog:
compositor_defs += '_CompoFog'
compo_pos = True
if bpy.data.cameras[0].cycles.aperture_size > 0.0:
compositor_defs += '_CompoDOF'
compo_depth = True
if compo_pos:
compositor_defs += '_CompoPos'
compo_depth = True
if compo_depth:
compositor_defs += '_CompoDepth'
defs = world_defs + compositor_defs
res_name = scon + defs
@ -1220,7 +1244,9 @@ def buildNode(stages, node, node_group, shader_references, asset_references):
if node.inputs[2].is_linked:
make_bind_target(stage, node_group, node, target_index=2, constant_name='tex')
if node.inputs[3].is_linked:
make_bind_target(stage, node_group, node, target_index=3, constant_name='gbuffer0')
make_bind_target(stage, node_group, node, target_index=3, constant_name='gbufferD')
if node.inputs[4].is_linked:
make_bind_target(stage, node_group, node, target_index=4, constant_name='gbuffer0')
stages.append(stage)
# Draw quad
stage = {}
@ -1358,7 +1384,7 @@ def findNodeByLinkFrom(node_group, from_node, outp):
if link.from_node == from_node and link.from_socket == outp:
return link.to_node
def getRootNode(node_group):
def get_root_node(node_group):
# Find first node linked to begin node
rn = None
for n in node_group.nodes:

View file

@ -67,14 +67,10 @@ class ArmoryProjectPanel(bpy.types.Panel):
def draw(self, context):
layout = self.layout
wrd = bpy.data.worlds[0]
layout.prop_search(wrd, "ArmProjectScene", bpy.data, "scenes", "Scene")
layout.prop(wrd, 'ArmProjectName')
layout.prop(wrd, 'ArmProjectPackage')
layout.prop_search(wrd, "ArmKhafile", bpy.data, "texts", "Khafile")
# row = layout.row()
layout.prop(wrd, 'ArmProjectWidth')
layout.prop(wrd, 'ArmProjectHeight')
layout.prop(wrd, 'ArmProjectSamplesPerPixel')
layout.prop_search(wrd, "ArmProjectScene", bpy.data, "scenes", "Scene")
class ArmoryBuildPanel(bpy.types.Panel):
bl_label = "Armory Build"
@ -87,9 +83,6 @@ class ArmoryBuildPanel(bpy.types.Panel):
wrd = bpy.data.worlds[0]
layout.operator("arm.build")
layout.operator("arm.kode_studio")
# row = layout.row(align=True)
# row.alignment = 'EXPAND'
# row.operator("arm.folder")
layout.operator("arm.clean")
layout.prop(wrd, 'ArmProjectTarget')
layout.prop(wrd, 'ArmPhysics')
@ -98,6 +91,7 @@ class ArmoryBuildPanel(bpy.types.Panel):
layout.prop(wrd, 'ArmOptimizeGeometry')
layout.prop(wrd, 'ArmSampledAnimation')
layout.prop(wrd, 'ArmDeinterleavedBuffers')
layout.prop(wrd, 'ArmProjectSamplesPerPixel')
class ArmoryPlayPanel(bpy.types.Panel):
bl_label = "Armory Play"
@ -345,8 +339,7 @@ def play_project(self, in_viewport):
wrd = bpy.data.worlds[0]
x = 0
y = 0
w = wrd.ArmProjectWidth
h = wrd.ArmProjectHeight
w, h = utils.get_render_resolution()
winoff = 0
else:
# Player dimensions
@ -470,6 +463,7 @@ class ArmoryFolderButton(bpy.types.Operator):
class ArmoryKodeStudioButton(bpy.types.Operator):
bl_idname = 'arm.kode_studio'
bl_label = 'Kode Studio'
bl_description = 'Open Project in Kode Studio'
def execute(self, context):
user_preferences = bpy.context.user_preferences

View file

@ -46,10 +46,8 @@ def initProperties():
name = "Target", default='html5')
bpy.types.World.ArmProjectName = StringProperty(name = "Name", default="ArmoryGame")
bpy.types.World.ArmProjectPackage = StringProperty(name = "Package", default="game")
bpy.types.World.ArmProjectWidth = IntProperty(name = "Width", default=800)
bpy.types.World.ArmProjectHeight = IntProperty(name = "Height", default=600)
bpy.types.World.ArmProjectScene = StringProperty(name = "Scene")
bpy.types.World.ArmProjectSamplesPerPixel = IntProperty(name = "Samples per pixel", default=1)
bpy.types.World.ArmProjectSamplesPerPixel = IntProperty(name = "Samples per Pixel", default=1)
bpy.types.World.ArmPhysics = EnumProperty(
items = [('Disabled', 'Disabled', 'Disabled'),
('Bullet', 'Bullet', 'Bullet')],
@ -122,8 +120,8 @@ def initProperties():
bpy.types.Camera.world_envtex_ground_albedo = bpy.props.FloatProperty(name="Ground Albedo", default=0.0)
bpy.types.Camera.last_decal_context = bpy.props.StringProperty(name="Decal Context", default='')
bpy.types.World.world_defs = bpy.props.StringProperty(name="World Shader Defs", default='')
bpy.types.World.generate_radiance = bpy.props.BoolProperty(name="Generate Radiance", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_clouds = bpy.props.BoolProperty(name="Generate Clouds", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_radiance = bpy.props.BoolProperty(name="Radiance Probes", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_clouds = bpy.props.BoolProperty(name="Clouds", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_clouds_density = bpy.props.FloatProperty(name="Density", default=0.6, min=0.0, max=10.0, update=invalidate_shader_cache)
bpy.types.World.generate_clouds_size = bpy.props.FloatProperty(name="Size", default=1.0, min=0.0, max=10.0, update=invalidate_shader_cache)
bpy.types.World.generate_clouds_lower = bpy.props.FloatProperty(name="Lower", default=2.0, min=1.0, max=10.0, update=invalidate_shader_cache)
@ -135,7 +133,7 @@ def initProperties():
bpy.types.World.shadowmap_size = bpy.props.IntProperty(name="Shadowmap Size", default=0, update=invalidate_shader_cache)
bpy.types.World.scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.bundled_scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.generate_ocean = bpy.props.BoolProperty(name="Generate Ocean", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_ocean = bpy.props.BoolProperty(name="Ocean", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_ocean_base_color = bpy.props.FloatVectorProperty(name="Base Color", size=3, default=[0.1, 0.19, 0.37], subtype='COLOR', update=invalidate_shader_cache)
bpy.types.World.generate_ocean_water_color = bpy.props.FloatVectorProperty(name="Water Color", size=3, default=[0.6, 0.7, 0.9], subtype='COLOR', update=invalidate_shader_cache)
bpy.types.World.generate_ocean_level = bpy.props.FloatProperty(name="Level", default=0.0, update=invalidate_shader_cache)
@ -145,23 +143,31 @@ def initProperties():
bpy.types.World.generate_ocean_speed = bpy.props.FloatProperty(name="Speed", default=1.0, update=invalidate_shader_cache)
bpy.types.World.generate_ocean_freq = bpy.props.FloatProperty(name="Freq", default=0.16, update=invalidate_shader_cache)
bpy.types.World.generate_ocean_fade = bpy.props.FloatProperty(name="Fade", default=1.8, update=invalidate_shader_cache)
bpy.types.World.generate_ssao = bpy.props.BoolProperty(name="Generate SSAO", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_ssao = bpy.props.BoolProperty(name="SSAO", description="Screen-Space Ambient Occlusion", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_ssao_size = bpy.props.FloatProperty(name="Size", default=0.08, update=invalidate_shader_cache)
bpy.types.World.generate_ssao_strength = bpy.props.FloatProperty(name="Strength", default=0.30, update=invalidate_shader_cache)
bpy.types.World.generate_ssao_texture_scale = bpy.props.FloatProperty(name="Texture Scale", default=1.0, min=0.0, max=1.0, update=invalidate_shader_cache)
bpy.types.World.generate_shadows = bpy.props.BoolProperty(name="Generate Shadows", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_bloom = bpy.props.BoolProperty(name="Generate Bloom", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_shadows = bpy.props.BoolProperty(name="Shadows", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_bloom = bpy.props.BoolProperty(name="Bloom", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_bloom_treshold = bpy.props.FloatProperty(name="Treshold", default=3.0, update=invalidate_shader_cache)
bpy.types.World.generate_bloom_strength = bpy.props.FloatProperty(name="Strength", default=0.15, update=invalidate_shader_cache)
bpy.types.World.generate_motion_blur = bpy.props.BoolProperty(name="Generate Motion Blur", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_motion_blur = bpy.props.BoolProperty(name="Motion Blur", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_motion_blur_intensity = bpy.props.FloatProperty(name="Intensity", default=1.0, update=invalidate_shader_cache)
bpy.types.World.generate_ssr = bpy.props.BoolProperty(name="Generate SSR", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_ssr = bpy.props.BoolProperty(name="SSR", description="Screen-Space Reflections", default=True, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_ray_step = bpy.props.FloatProperty(name="Ray Step", default=0.04, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_min_ray_step = bpy.props.FloatProperty(name="Ray Step Min", default=0.05, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_search_dist = bpy.props.FloatProperty(name="Search Dist", default=5.0, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_falloff_exp = bpy.props.FloatProperty(name="Falloff Exp", default=5.0, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_jitter = bpy.props.FloatProperty(name="Jitter", default=0.6, update=invalidate_shader_cache)
bpy.types.World.generate_ssr_texture_scale = bpy.props.FloatProperty(name="Texture Scale", default=0.5, min=0.0, max=1.0, update=invalidate_shader_cache)
bpy.types.World.generate_letterbox = bpy.props.BoolProperty(name="Letterbox", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_letterbox_size = bpy.props.FloatProperty(name="Size", default=0.1, update=invalidate_shader_cache)
bpy.types.World.generate_grain = bpy.props.BoolProperty(name="Film Grain", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_grain_strength = bpy.props.FloatProperty(name="Strength", default=2.0, update=invalidate_shader_cache)
bpy.types.World.generate_fog = bpy.props.BoolProperty(name="Volumetric Fog", default=False, update=invalidate_shader_cache)
bpy.types.World.generate_fog_color = bpy.props.FloatVectorProperty(name="Color", size=3, subtype='COLOR', default=[0.5, 0.6, 0.7], update=invalidate_shader_cache)
bpy.types.World.generate_fog_amounta = bpy.props.FloatProperty(name="Amount A", default=0.5, update=invalidate_shader_cache)
bpy.types.World.generate_fog_amountb = bpy.props.FloatProperty(name="Amount B", default=1.0, update=invalidate_shader_cache)
# For material
bpy.types.Material.receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True)
bpy.types.Material.override_shader = bpy.props.BoolProperty(name="Override Shader", default=False)
@ -360,6 +366,7 @@ class WorldPropsPanel(bpy.types.Panel):
def draw(self, context):
layout = self.layout
wrd = bpy.context.world
layout.prop(wrd, 'generate_shadows')
layout.prop(wrd, 'generate_radiance')
layout.prop(wrd, 'generate_clouds')
if wrd.generate_clouds:
@ -376,7 +383,6 @@ class WorldPropsPanel(bpy.types.Panel):
layout.prop(wrd, 'generate_ssao_size')
layout.prop(wrd, 'generate_ssao_strength')
layout.prop(wrd, 'generate_ssao_texture_scale')
layout.prop(wrd, 'generate_shadows')
layout.prop(wrd, 'generate_bloom')
if wrd.generate_bloom:
layout.prop(wrd, 'generate_bloom_treshold')
@ -392,6 +398,19 @@ class WorldPropsPanel(bpy.types.Panel):
layout.prop(wrd, 'generate_ssr_falloff_exp')
layout.prop(wrd, 'generate_ssr_jitter')
layout.prop(wrd, 'generate_ssr_texture_scale')
layout.label('Compositor')
layout.prop(wrd, 'generate_letterbox')
if wrd.generate_letterbox:
layout.prop(wrd, 'generate_letterbox_size')
layout.prop(wrd, 'generate_grain')
if wrd.generate_grain:
layout.prop(wrd, 'generate_grain_strength')
layout.prop(wrd, 'generate_fog')
if wrd.generate_fog:
layout.prop(wrd, 'generate_fog_color')
layout.prop(wrd, 'generate_fog_amounta')
layout.prop(wrd, 'generate_fog_amountb')
# Registration
def register():

View file

@ -50,3 +50,8 @@ def to_hex(val):
def safe_filename(s):
return s.replace('.', '_').replace('-', '_').replace(' ', '_')
def get_render_resolution(scene_index=0):
render = bpy.data.scenes[scene_index].render
scale = render.resolution_percentage / 100
return int(render.resolution_x * scale), int(render.resolution_y * scale)

View file

@ -77,6 +77,7 @@ project.addAssets('Assets/**');
# Write Main.hx
def write_main():
wrd = bpy.data.worlds[0]
resx, resy = utils.get_render_resolution()
#if not os.path.isfile('Sources/Main.hx'):
with open('Sources/Main.hx', 'w') as f:
f.write(
@ -85,8 +86,8 @@ package ;
class Main {
public static inline var projectName = '""" + wrd.ArmProjectName + """';
public static inline var projectPackage = '""" + wrd.ArmProjectPackage + """';
static inline var projectWidth = """ + str(wrd.ArmProjectWidth) + """;
static inline var projectHeight = """ + str(wrd.ArmProjectHeight) + """;
static inline var projectWidth = """ + str(resx) + """;
static inline var projectHeight = """ + str(resy) + """;
static inline var projectSamplesPerPixel = """ + str(wrd.ArmProjectSamplesPerPixel) + """;
public static inline var projectScene = '""" + str(wrd.ArmProjectScene) + """';
public static function main() {
@ -265,6 +266,34 @@ const float ssrSearchDist = """ + str(round(wrd.generate_ssr_search_dist * 100)
const float ssrFalloffExp = """ + str(round(wrd.generate_ssr_falloff_exp * 100) / 100) + """;
const float ssrJitter = """ + str(round(wrd.generate_ssr_jitter * 100) / 100) + """;
const float ssrTextureScale = """ + str(round(wrd.generate_ssr_texture_scale * 10) / 10) + """;
""")
if wrd.generate_letterbox:
f.write(
"""const float compoLetterboxSize = """ + str(round(wrd.generate_letterbox_size * 100) / 100) + """;
""")
if wrd.generate_grain:
f.write(
"""const float compoGrainStrength = """ + str(round(wrd.generate_grain_strength * 100) / 100) + """;
""")
if bpy.data.scenes[0].cycles.film_exposure != 1.0:
f.write(
"""const float compoExposureStrength = """ + str(round(bpy.data.scenes[0].cycles.film_exposure * 100) / 100) + """;
""")
if wrd.generate_fog:
f.write(
"""const float compoFogAmountA = """ + str(round(wrd.generate_fog_amounta * 100) / 100) + """;
const float compoFogAmountB = """ + str(round(wrd.generate_fog_amountb * 100) / 100) + """;
const vec3 compoFogColor = vec3(""" + str(round(wrd.generate_fog_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_fog_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_fog_color[2] * 100) / 100) + """);
""")
if bpy.data.cameras[0].cycles.aperture_size > 0.0:
f.write(
"""const float compoDOFDistance = """ + str(round(bpy.data.cameras[0].dof_distance * 100) / 100) + """;
const float compoDOFSize = """ + str(round(bpy.data.cameras[0].cycles.aperture_size * 100) / 100) + """;
""")
def write_traithx(class_name):

View file

@ -4,40 +4,37 @@
precision highp float;
#endif
#include "../compiled.glsl"
uniform sampler2D tex;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
// uniform sampler2D noise256;
//#ifdef (_LensFlare || _Fog)
// #ifdef _Fog
// uniform vec3 eye;
// uniform vec3 eyeLook;
// #endif
#ifdef _CompoPos
uniform vec3 eye;
uniform vec3 eyeLook;
#endif
#ifdef _LensFlare
#ifdef _CompoGlare
uniform vec3 light;
uniform mat4 VP;
#endif
#ifdef _CompFXAA
#ifdef _CompoFXAA
uniform vec2 texStep;
#endif
// uniform vec2 cameraPlane;
// #ifdef _Grain
// uniform float time;
// #endif
#ifdef _CompoGrain
uniform float time;
#endif
in vec2 texCoord;
#ifdef _CompoPos
in vec3 viewRay;
#endif
out vec4 outColor;
const float PI = 3.1415926535;
const float fishEyeStrength = -0.01;
const vec2 m = vec2(0.5, 0.5);
const float focus_depth = 0.5;
const float vignout = 1.8; // vignetting outer border
@ -47,158 +44,61 @@ const float fstop = 20; // f-stop value
const float aspectRatio = 800.0 / 600.0;
const vec3 fogColor = vec3(0.5, 0.6, 0.7);
// const float b = 0.01;
// const float c = 0.1;
const float b = 1.0;
const float c = 1.0;
#ifdef _CompoPos
vec3 getPos(float depth) {
vec3 vray = normalize(viewRay);
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
float viewZDist = dot(eyeLook, vray);
vec3 wposition = eye + vray * (linearDepth / viewZDist);
return wposition;
}
#endif
#ifdef _CompoFog
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
// const float compoFogAmountA = 1.0; // b = 0.01
// const float compoFogAmountB = 1.0; // c = 0.1
vec3 applyFog(vec3 rgb, // original color of the pixel
float distance, // camera to point distance
vec3 rayOri, // camera position
vec3 rayDir) { // camera to point vector
float fogAmount = c * exp(-rayOri.y * b) * (1.0 - exp(-distance * rayDir.y * b)) / rayDir.y;
return mix(rgb, fogColor, fogAmount);
float fogAmount = compoFogAmountB * exp(-rayOri.y * compoFogAmountA) * (1.0 - exp(-distance * rayDir.y * compoFogAmountA)) / rayDir.y;
return mix(rgb, compoFogColor, fogAmount);
}
// vec3 applyFog(vec3 rgb, // original color of the pixel
// float distance) { // camera to point distance
// float fogAmount = 1.0 - exp(-distance * b);
// return mix(rgb, fogColor, fogAmount);
// }
// https://www.shadertoy.com/view/ltfGzn
// float unitSin(float t) {
// return 0.5 + 0.5 * sin(t);
// }
// float processFlake(vec3 rayOrigin, vec3 rayDirection, float b, float a2, float a4, float bbSubAC4, float fallSpeed, float r) {
// float sum = 0.0;
// float R = r + sin(PI * r * time * 0.05) / (r * 0.25);
// float delta = bbSubAC4 + a4 * R*R;
// float depth = 100.0;
// if (delta >= 0.0) {
// float t1 = (-b - sqrt(delta))/a2;
// float t2 = (-b + sqrt(delta))/a2;
// vec3 p1 = rayOrigin + t1 * rayDirection;
// vec3 p2 = rayOrigin + t2 * rayDirection;
// if (t1 < depth && t1 > 2.0) {
// float teta = atan(p1.z, p1.x) / (2.0 * PI);
// float fall = (0.5 + 0.5 * unitSin(r)) * fallSpeed * time + cos(r);
// float s = 6.0;
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(0.4 * teta * r, 0.1 * p1.y + fall)).r);
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(0.11 * p1.y + fall, -0.4 * teta * r)).r);
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(-(0.11 * p1.y + fall), 0.4 * teta * r)).r);
// sum += s;
// }
// if (t2 < depth && t2 > 0.0) {
// float teta = atan(p2.z, p2.x) / (2.0 * PI);
// float fall = (0.5 + 0.5 * unitSin(r)) * fallSpeed * time + cos(r);
// float s = 6.0;
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(0.4 * teta * r, 0.1 * p2.y + fall)).r);
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(-(0.11 * p2.y + fall), 0.4 * teta * r)).r);
// s *= smoothstep(0.65, 1.0, texture(noise256, vec2(0.11 * p2.y + fall, -0.4 * teta * r)).r);
// sum += s;
// }
// }
// return sum;
// }
// float flakeVolume() {
// vec3 rayOrigin = eye;
// vec2 p = texCoord.xy * 2.0 - 1.0;
// vec3 rayDirection = normalize(p.x * vec3(1.0,0.0,0.0) + p.y * vec3(0.0,0.0,1.0) + 1.0 * eyeLook);
// float sum = 0.0;
// float fallSpeed = 0.2;
// float a = pow(rayDirection.x, 2.0) + pow(rayDirection.z, 2.0);
// float b = 2.0 * (rayDirection.x * rayOrigin.x + rayDirection.z * rayOrigin.z);
// float c = pow(rayOrigin.x, 2.0) + pow(rayOrigin.z, 2.0);
// float ac4 = 4.0 * a*c;
// float a4 = 4.0 * a;
// float a2 = 2.0 * a;
// float bb = b*b;
// float bbSubAC4 = bb - ac4;
// // for (float r = 1.0; r <= 16.0; r+=0.5) {
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 1.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 2.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 3.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 4.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 5.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 6.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 7.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 8.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 9.0);
// processFlake(rayOrigin, rayDirection, b, a2, a4, bbSubAC4, fallSpeed, 10.0);
// // }
// return sum / 2.0;
// }
// vec4 screenSpaceSnow() {
// float flake = flakeVolume();
// return vec4(1.0, 1.0, 1.0, clamp(flake, 0.0, 1.0));
// }
// vec4 screenSpaceIce(vec3 c) {
// vec2 p = texCoord.xy * 2.0 - 1.0;
// vec2 P = vec2(p.x, 2.0 * p.y);
// float r = length(P);
// return vec4(c.rgb, 0.3 * (pow((abs(p.x) + abs(p.y)) * 0.5, 1.0) + pow(r / 1.6, 2.0)));
// }
// https://www.shadertoy.com/view/XdSGDc
// float processRain(float dis) {
// vec2 q = texCoord;
// float f = pow(dis, 0.45)+0.25;
// vec2 st = f * (q * vec2(1.5, .05)+vec2(-time*.1+q.y*.5, time*.12));
// f = (texture(noise256, st * .5, -99.0).x + texture(noise256, st*.284, -99.0).y);
// f = clamp(pow(abs(f)*.5, 29.0) * 140.0, 0.00, q.y*.4+.05);
// return f*0.5;
// }
// vec3 screenSpaceRain() {
// float dis = 1.0;
// vec3 col = vec3(0.0);
// // for (int i = 0; i < 12; i++) {
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// col += processRain(dis); dis += 3.5;
// // }
// return col;
// }
// https://www.shadertoy.com/view/4dXSzB
// vec3 screenSpaceCameraRain() {
// vec3 raintex = texture(noise256,vec2(texCoord.x*2.0,texCoord.y*0.4+time*0.1)).rgb/30.0;
// vec2 where = (texCoord.xy-raintex.xy);
// return texture(tex,vec2(where.x,where.y)).rgb;
// vec3 applyFog(vec3 rgb, float distance) {
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
// return mix(rgb, compoFogColor, fogAmount);
// }
#endif
float vignette() {
float dist = distance(texCoord, vec2(0.5,0.5));
dist = smoothstep(vignout + (fstop / vignfade), vignin + (fstop / vignfade), dist);
return clamp(dist, 0.0, 1.0);
// float dist = distance(texCoord, vec2(0.5,0.5));
// dist = smoothstep(vignout + (fstop / vignfade), vignin + (fstop / vignfade), dist);
// return clamp(dist, 0.0, 1.0);
// vignetting from iq
// col *= 0.4 + 0.6 * pow(16.0 * texCoord.x * texCoord.y * (1.0-texCoord.x)*(1.0-texCoord.y), 0.2);
return 0.4 + 0.6 * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
}
vec4 sampleBox(float size) {
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
color += texture(tex, vec2(texCoord.x - size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y - size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x - size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x, texCoord.y)) * 0.30;
color += texture(tex, vec2(texCoord.x + size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x - size, texCoord.y + size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y + size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y + size)) * 0.075;
#ifdef _CompoDOF
vec3 sampleBox(float size) {
vec3 color = vec3(texture(tex, vec2(texCoord.x - size, texCoord.y - size)).rgb) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y - size)).rgb * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y - size)).rgb * 0.075;
color += texture(tex, vec2(texCoord.x - size, texCoord.y)).rgb * 0.1;
color += texture(tex, vec2(texCoord.x, texCoord.y)).rgb * 0.30;
color += texture(tex, vec2(texCoord.x + size, texCoord.y)).rgb * 0.1;
color += texture(tex, vec2(texCoord.x - size, texCoord.y + size)).rgb * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y + size)).rgb * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y + size)).rgb * 0.075;
return color;
}
#endif
// float linearize(float depth) {
// return -cameraPlane.y * cameraPlane.x / (depth * (cameraPlane.y - cameraPlane.x) - cameraPlane.y);
// }
float linearize(float depth) {
return -cameraPlane.y * cameraPlane.x / (depth * (cameraPlane.y - cameraPlane.x) - cameraPlane.y);
}
// Based on lense flare implementation by musk
// https://www.shadertoy.com/view/4sX3Rs
@ -230,15 +130,6 @@ vec3 lensflare(vec2 uv, vec2 pos) {
return c;
}
const float MIDDLE_GREY = 0.18;
float getExposure(float aperture, float shutterSpeed, float iso) {
float q = 0.65;
//float l_avg = (1000.0f / 65.0f) * sqrt(aperture) / (iso * shutterSpeed);
float l_avg = (1.0 / q) * sqrt(aperture) / (iso * shutterSpeed);
//float l_avg = sqrt(aperture) / (iso * shutterSpeed);
return MIDDLE_GREY / l_avg;
}
//Based on Filmic Tonemapping Operators http://filmicgames.com/archives/75
vec3 tonemapFilmic(vec3 color) {
vec3 x = max(vec3(0.0), color - 0.004);
@ -265,34 +156,34 @@ vec3 tonemapUncharted2(vec3 color) {
}
void main() {
#ifdef _CompFishEye
// Fish eye
vec2 texCo = texCoord;
#ifdef _CompoFishEye
const float fishEyeStrength = -0.01;
const vec2 m = vec2(0.5, 0.5);
vec2 d = texCoord - m;
float r = sqrt(dot(d, d));
float power = (2.0 * PI / (2.0 * sqrt(dot(m, m)))) * fishEyeStrength;
float bind;
if (power > 0.0) { bind = sqrt(dot(m, m)); }
else { bind = m.x; }
vec2 uv;
if (power > 0.0) {
uv = m + normalize(d) * tan(r * power) * bind / tan(bind * power);
texCo = m + normalize(d) * tan(r * power) * bind / tan(bind * power);
}
else {
uv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
texCo = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
}
// vec4 col = texture(tex, uv);
#endif
#ifdef _CompFXAA
#ifdef _CompoFXAA
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
const float FXAA_SPAN_MAX = 8.0;
vec2 tcrgbNW = (texCoord + vec2(-1.0, -1.0) * texStep);
vec2 tcrgbNE = (texCoord + vec2(1.0, -1.0) * texStep);
vec2 tcrgbSW = (texCoord + vec2(-1.0, 1.0) * texStep);
vec2 tcrgbSE = (texCoord + vec2(1.0, 1.0) * texStep);
vec2 tcrgbM = vec2(texCoord);
vec2 tcrgbNW = (texCo + vec2(-1.0, -1.0) * texStep);
vec2 tcrgbNE = (texCo + vec2(1.0, -1.0) * texStep);
vec2 tcrgbSW = (texCo + vec2(-1.0, 1.0) * texStep);
vec2 tcrgbSE = (texCo + vec2(1.0, 1.0) * texStep);
vec2 tcrgbM = vec2(texCo);
vec3 rgbNW = texture(tex, tcrgbNW).rgb;
vec3 rgbNE = texture(tex, tcrgbNE).rgb;
@ -322,101 +213,85 @@ void main() {
dir * rcpDirMin)) * texStep;
vec3 rgbA = 0.5 * (
texture(tex, texCoord + dir * (1.0 / 3.0 - 0.5)).rgb +
texture(tex, texCoord + dir * (2.0 / 3.0 - 0.5)).rgb);
texture(tex, texCo + dir * (1.0 / 3.0 - 0.5)).rgb +
texture(tex, texCo + dir * (2.0 / 3.0 - 0.5)).rgb);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
texture(tex, texCoord + dir * -0.5).rgb +
texture(tex, texCoord + dir * 0.5).rgb);
texture(tex, texCo + dir * -0.5).rgb +
texture(tex, texCo + dir * 0.5).rgb);
vec4 col;
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax)) col = vec4(rgbA, texColor.a);
else col = vec4(rgbB, texColor.a);
#else
vec4 col = texture(tex, texCoord);
vec4 col = texture(tex, texCo);
#endif
#ifdef _CompoDepth
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
#endif
#ifdef _CompoDOF
float linDepth = linearize(depth);
float blur_amount = abs(linDepth - compoDOFDistance) / cameraPlane.y;
blur_amount = clamp(blur_amount, 0.0, 1.0);
float blurSize = compoDOFSize * 10000.0 * blur_amount;
vec3 blurredColor = 0.75 * sampleBox(blurSize * 0.5) + 0.25 * sampleBox(blurSize * 1.0);
col.rgb *= (1.0 - blur_amount) + blurredColor * blur_amount;
#endif
#ifdef _CompoFog
vec3 pos = getPos(depth);
float dist = distance(pos, eye);
vec3 eyedir = normalize(eye + pos);
col.rgb = applyFog(col.rgb, dist, eye, eyedir);
#endif
#ifdef _CompoGlare
vec4 lndc = VP * vec4(light, 1.0);
lndc.xy /= lndc.w;
float lightDistance = distance(eye, light);
vec2 lss = lndc.xy * 0.5 + 0.5;
float lssdepth = linearize(texture(gbufferD, lss).r * 2.0 - 1.0);
if (lssdepth >= lightDistance) {
vec2 lensuv = (texCoord - 0.5) * 2.0;
lensuv.x *= aspectRatio;
vec3 lensflarecol = vec3(1.4, 1.2, 1.0) * lensflare(lensuv, lndc.xy);
col.rgb += lensflarecol;
}
#endif
#ifdef _CompoGrain
// const float compoGrainStrength = 4.0;
float x = (texCoord.x + 4.0) * (texCoord.y + 4.0) * (time * 10.0);
col.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * compoGrainStrength;
#endif
// Blur
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
// float blur_amount = abs(depth - focus_depth);
// if (depth < depth - focus_depth) {
// blur_amount *= 2.0;
// }
// blur_amount = clamp(blur_amount, 0.0, 1.0);
// vec4 baseColor = col;//texture(tex, texCoord);
// vec4 blurredColor = vec4(0.0, 0.0, 0.0, 0.0);
// float blurSize = 0.005 * blur_amount;
// blurredColor = 0.75 * sampleBox(blurSize * 0.5) + 0.25 * sampleBox(blurSize * 1.0);
// col = baseColor * (1.0 - blur_amount) + blurredColor * blur_amount;
// Fog
// vec3 pos = texture(gbuffer1, texCoord).rgb;
// float dist = distance(pos, eye);
// vec3 dir = eye + pos;
// dir = normalize(dir);
// col.rgb = applyFog(col.rgb, dist, eye, dir);
// col.rgb = applyFog(col.rgb, dist);
// Lens flare
// vec4 lndc = VP * vec4(light, 1.0);
// lndc.xy /= lndc.w;
// float lightDistance = distance(eye, light);
// vec2 lss = lndc.xy * 0.5 + 0.5;
// float lssdepth = linearize(texture(gbuffer0, lss).a);
// if (lssdepth >= lightDistance) {
// vec2 lensuv = (texCoord - 0.5) * 2.0;
// lensuv.x *= aspectRatio;
// vec3 lensflarecol = vec3(1.4, 1.2, 1.0) * lensflare(lensuv, lndc.xy);
// col.rgb += lensflarecol;
// }
// Film grain
// 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;
// Ice
// vec4 ice = screenSpaceIce(vec3(0.8, 0.9, 1.0));
// col.rgb = ice.a * ice.rgb + (1.0 - ice.a) * col.rgb;
// Snow
// vec4 flake = screenSpaceSnow();
// col.rgb = flake.a * flake.rgb + (1.0 - flake.a) * col.rgb;
// Rain
// col.rgb += screenSpaceRain();
// Camera rain
// col.rgb = screenSpaceCameraRain();
// Vignetting
//col.rgb *= vignette();
// Exposure
const float aperture = 16;
const float shutterSpeed = 0.5;
const float iso = 100;
// col.rgb *= getExposure(aperture, shutterSpeed, iso);
// Tonemapping
#ifdef _CompoVignette
col.rgb *= vignette();
#endif
#ifdef _CompoExposure
col.rgb *= compoExposureStrength;
#endif
#ifdef _CompoTonemap
col.rgb = tonemapUncharted2(col.rgb);
// col.rgb = tonemapFilmic(col.rgb); // With gamma
#endif
// To gamma
col.rgb = pow(col.rgb, vec3(1.0 / 2.2));
// Black and white
#ifdef _BW
#ifdef _CompoBW
// 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;
#endif
// Letter box
// const float letterBoxSize = 0.1;
// col.rgb *= 1.0 - step(0.5 - letterBoxSize, abs(0.5 - texCoord.y));
#ifdef _CompoLetterbox
// const float compoLetterboxSize = 0.1;
col.rgb *= 1.0 - step(0.5 - compoLetterboxSize, abs(0.5 - texCoord.y));
#endif
outColor = col;
}

View file

@ -20,32 +20,37 @@
{
"id": "eye",
"link": "_cameraPosition",
"ifdef": ["_LensFlare", "_Fog"]
"ifdef": ["_CompoPos"]
},
{
"id": "eyeLook",
"link": "_cameraLook",
"ifdef": ["_LensFlare", "_Fog"]
"ifdef": ["_CompoPos"]
},
{
"id": "invVP",
"link": "_inverseViewProjectionMatrix",
"ifdef": ["_CompoPos"]
},
{
"id": "light",
"link": "_lightPosition",
"ifdef": ["_LensFlare"]
"ifdef": ["_CompoGlare"]
},
{
"id": "VP",
"link": "_viewProjectionMatrix",
"ifdef": ["_LensFlare"]
"ifdef": ["_CompoGlare"]
},
{
"id": "time",
"link": "_time",
"ifdef": ["_Grain"]
"ifdef": ["_CompoGrain"]
},
{
"id": "texStep",
"link": "_screenSizeInv",
"ifdef": ["_CompFXAA"]
"ifdef": ["_CompoFXAA"]
}
],
"texture_params": [],

View file

@ -4,15 +4,31 @@
precision highp float;
#endif
#ifdef _CompoPos
uniform mat4 invVP;
uniform vec3 eye;
#endif
in vec2 pos;
out vec2 texCoord;
#ifdef _CompoPos
out vec3 viewRay;
#endif
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
gl_Position = vec4(pos.xy, 0.0, 1.0);
#ifdef _CompoPos
// NDC (at the back of cube)
vec4 v = vec4(pos.xy, 1.0, 1.0);
v = vec4(invVP * v);
v.xyz /= v.w;
viewRay = v.xyz - eye;
#endif
}

View file

@ -1,353 +0,0 @@
// Depth of Field by Martins Upitis (devlog-martinsh.blogspot.com)
#version 450
#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.1415653592
uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
const float znear = 0.1;
const float zfar = 100.0;
const float width = 800;
const float height = 600;
const vec2 texel = vec2(1.0 / width, 1.0 / height);
const float focalDepth = 0; // focal distance value in meters
const float focalLength = 50; // focal length in mm 18-200
const float fstop = 20; // f-stop value
const int samples = 3; // samples on the first ring
const int rings = 3; // ring count
const vec2 focus = vec2(0.5,0.5);
const float CoC = 0.03; // circle of confusion size in mm (35mm film = 0.03mm)
const float maxblur = 1.0;
const float threshold = 0.5; // highlight threshold
const float gain = 2.0; // highlight gain
const float bias = 0.5; // bokeh edge bias
const float fringe = 0.7; // bokeh chromatic aberration/fringing
const float namount = 0.0001; // dither amount
const float vignout = 1.3; // vignetting outer border
const float vignin = 0.0; // vignetting inner border
const float vignfade = 90.0; // f-stops till vignete fades
// bool pentagon = false; // Use pentagon as bokeh shape?
// float feather = 0.4; // Pentagon shape feather
// float dbsize = 1.25; // Depth blur size
in vec2 texCoord;
// float penta(vec2 coords) { //pentagonal shape
// float scale = float(rings) - 1.3;
// vec4 HS0 = vec4( 1.0, 0.0, 0.0, 1.0);
// vec4 HS1 = vec4( 0.309016994, 0.951056516, 0.0, 1.0);
// vec4 HS2 = vec4(-0.809016994, 0.587785252, 0.0, 1.0);
// vec4 HS3 = vec4(-0.809016994,-0.587785252, 0.0, 1.0);
// vec4 HS4 = vec4( 0.309016994,-0.951056516, 0.0, 1.0);
// vec4 HS5 = vec4( 0.0 ,0.0 , 1.0, 1.0);
// vec4 one = vec4( 1.0 );
// vec4 P = vec4((coords),vec2(scale, scale));
// vec4 dist = vec4(0.0);
// float inorout = -4.0;
// dist.x = dot( P, HS0 );
// dist.y = dot( P, HS1 );
// dist.z = dot( P, HS2 );
// dist.w = dot( P, HS3 );
// dist = smoothstep( -feather, feather, dist );
// inorout += dot( dist, one );
// dist.x = dot( P, HS4 );
// dist.y = HS5.w - abs( P.z );
// dist = smoothstep( -feather, feather, dist );
// inorout += dist.x;
// return clamp( inorout, 0.0, 1.0 );
// }
// float bdepth(vec2 coords) { //blurring depth
// float d = 0.0;
// float kernel[9];
// vec2 offset[9];
// vec2 wh = vec2(texel.x, texel.y) * dbsize;
// offset[0] = vec2(-wh.x,-wh.y);
// offset[1] = vec2( 0.0, -wh.y);
// offset[2] = vec2( wh.x -wh.y);
// offset[3] = vec2(-wh.x, 0.0);
// offset[4] = vec2( 0.0, 0.0);
// offset[5] = vec2( wh.x, 0.0);
// offset[6] = vec2(-wh.x, wh.y);
// offset[7] = vec2( 0.0, wh.y);
// offset[8] = vec2( wh.x, wh.y);
// kernel[0] = 1.0/16.0; kernel[1] = 2.0/16.0; kernel[2] = 1.0/16.0;
// kernel[3] = 2.0/16.0; kernel[4] = 4.0/16.0; kernel[5] = 2.0/16.0;
// kernel[6] = 1.0/16.0; kernel[7] = 2.0/16.0; kernel[8] = 1.0/16.0;
// for( int i=0; i<9; i++ )
// {
// float tmp = texture2D(bgl_DepthTexture, coords + offset[i]).r;
// d += tmp * kernel[i];
// }
// return d;
// }
vec3 color(vec2 coords, float blur) {
vec3 col = vec3(0.0);
col.r = texture(tex, coords + vec2(0.0,1.0)*texel*fringe*blur).r;
col.g = texture(tex, coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;
col.b = texture(tex, coords + vec2(0.866,-0.5)*texel*fringe*blur).b;
vec3 lumcoeff = vec3(0.299, 0.587, 0.114);
float lum = dot(col.rgb, lumcoeff);
float thresh = max((lum-threshold)*gain, 0.0);
return col+mix(vec3(0.0),col,thresh*blur);
}
vec2 rand(vec2 coord) {
float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;
return vec2(noiseX,noiseY);
// if (noise) {
// noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
// noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
// }
}
float linearize(float depth) {
return -zfar * znear / (depth * (zfar - znear) - zfar);
}
float vignette() {
float dist = distance(texCoord, vec2(0.5,0.5));
dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);
return clamp(dist,0.0,1.0);
}
vec3 debugFocus(vec3 col, float blur, float depth) {
float edge = 0.002*depth; //distance based edge smoothing
float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);
float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);
col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);
col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);
return col;
}
void main() {
float depthbuf = texture(gbuffer0, texCoord).a;
float depth = linearize(depthbuf);
// Blur depth
// depth = linearize(bdepth(texCoord.xy));
float fDepth = focalDepth;
// Autofocus
//fDepth = linearize(texture(gbuffer0, focus).a);
float blur = 0.0;
float f = focalLength; // focal length in mm
float d = fDepth*1000.0; // focal plane in mm
float o = depth*1000.0; // depth in mm
float a = (o*f)/(o-f);
float b = (d*f)/(d-f);
float c = (d-f)/(d*fstop*CoC);
blur = abs(a-b)*c;
blur = clamp(blur,0.0,1.0);
vec2 noise = rand(texCoord)*namount*blur;
float w = (texel.x)*blur*maxblur+noise.x;
float h = (texel.y)*blur*maxblur+noise.y;
vec3 col = vec3(0.0);
if (blur < 0.05) {
col = texture(tex, texCoord).rgb;
}
else {
col = texture(tex, texCoord).rgb;
float s = 1.0;
int ringsamples;
// for (int i = 1; i <= rings; ++i) {
// ringsamples = i * samples;
// for (int j = 0 ; j < ringsamples; ++j) {
// float step = PI*2.0 / float(ringsamples);
// float pw = (cos(float(j)*step)*float(i));
// float ph = (sin(float(j)*step)*float(i));
// float p = 1.0;
// if (pentagon) {
// p = penta(vec2(pw,ph));
// }
// col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
// s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
// }
// }
int i = 1; // i <= rings
ringsamples = i * samples;
int j = 0; // j < ringsamples
float step = PI*2.0 / float(ringsamples);
float pw = (cos(float(j)*step)*float(i));
float ph = (sin(float(j)*step)*float(i));
float p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 1; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 2; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
//------
i = 2; // i <= rings
ringsamples = i * samples;
j = 0; // j < ringsamples
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 1; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 2; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 3; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 4; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 5; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
//------
i = 3; // i <= rings
ringsamples = i * samples;
j = 0; // j < ringsamples
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 1; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 2; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 3; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 4; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 5; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 6; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 7; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
j = 8; //////
step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i));
p = 1.0;
col += color(texCoord + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
//------
col /= s;
}
// Show focus
//col = debugFocus(col, blur, depth);
// Vignetting
col *= vignette();
gl_FragColor = vec4(col, 1.0);
}