From cf8f7186dafda2d04593116d2ba874582c1929ed Mon Sep 17 00:00:00 2001 From: Lubos Lenco Date: Sun, 17 Jul 2016 20:29:53 +0200 Subject: [PATCH] Expose more shader constants. --- Sources/armory/trait/internal/Animation.hx | 6 +- blender/exporter.py | 353 +++++++++++++--- blender/nodes_pipeline.py | 3 +- blender/nodes_world.py | 17 +- blender/project.py | 47 ++- blender/props.py | 47 +++ blender/traits.py | 10 +- blender/write_data.py | 40 +- blender/write_probes.py | 429 ++++++++++---------- raw/deferred/deferred.vert.glsl | 1 + raw/deferred_light/deferred_light.frag.glsl | 44 +- raw/env_map/env_map.frag.glsl | 71 ++-- raw/forward/forward.frag.glsl | 79 ++-- raw/ssao_pass/ssao_pass.frag.glsl | 11 +- raw/water_pass/water_pass.frag.glsl | 378 +++++++++-------- raw/water_pass/water_pass.shader.json | 12 +- raw/water_pass/water_pass.vert.glsl | 7 + 17 files changed, 945 insertions(+), 610 deletions(-) diff --git a/Sources/armory/trait/internal/Animation.hx b/Sources/armory/trait/internal/Animation.hx index 58ee510d..27590159 100644 --- a/Sources/armory/trait/internal/Animation.hx +++ b/Sources/armory/trait/internal/Animation.hx @@ -32,14 +32,14 @@ class Animation extends Trait { } function update() { - Eg.setAnimationParams(model, iron.sys.Time.delta); + Eg.setAnimationParams(model, iron.sys.Time.delta / 10); } public function play(trackName:String, loop = true, speed = 1.0, onTrackComplete:Void->Void = null) { - model.skinning.animation.play(trackName, loop, speed, onTrackComplete); + model.animation.player.play(trackName, loop, speed, onTrackComplete); } public function pause() { - model.skinning.animation.pause(); + model.animation.player.pause(); } } diff --git a/blender/exporter.py b/blender/exporter.py index d5eb0fbc..65c4b01e 100644 --- a/blender/exporter.py +++ b/blender/exporter.py @@ -149,11 +149,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): bl_label = "Export Armory" filename_ext = ".json" - option_export_selection = bpy.props.BoolProperty(name = "Export Selection Only", description = "Export only selected objects", default = False) - option_sample_animation = bpy.props.BoolProperty(name = "Force Sampled Animation", description = "Always export animation as per-frame samples", default = False) - option_geometry_only = bpy.props.BoolProperty(name = "Export Geometry Only", description = "Export only geometry data", default = True) - option_geometry_per_file = bpy.props.BoolProperty(name = "Export Geometry Per File", description = "Export each geometry to individual JSON files", default = False) - option_minimize = bpy.props.BoolProperty(name = "Export Minimized", description = "Export minimized JSON data", default = True) + option_export_selection = bpy.props.BoolProperty(name = "Export Selection Only", description = "Export only selected objects", default=False) + option_sample_animation = bpy.props.BoolProperty(name = "Force Sampled Animation", description = "Always export animation as per-frame samples", default=True) + option_geometry_only = bpy.props.BoolProperty(name = "Export Geometry Only", description = "Export only geometry data", default=True) + option_geometry_per_file = bpy.props.BoolProperty(name = "Export Geometry Per File", description = "Export each geometry to individual JSON files", default=False) + option_minimize = bpy.props.BoolProperty(name = "Export Minimized", description = "Export minimized JSON data", default=True) def WriteMatrix(self, matrix): return [matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3], @@ -622,28 +622,29 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): break if (animationFlag): - o.animation = Object() # TODO: multiple tracks? + o.animation = Object() - o.animation.track = Object() - o.animation.track.target = "transform" + tracko = Object() + tracko.target = "transform" - o.animation.track.time = Object() - o.animation.track.time.values = [] + tracko.time = Object() + tracko.time.values = [] for i in range(self.beginFrame, self.endFrame): - o.animation.track.time.values.append(((i - self.beginFrame) * self.frameTime)) + tracko.time.values.append(((i - self.beginFrame) * self.frameTime)) - o.animation.track.time.values.append((self.endFrame * self.frameTime)) + tracko.time.values.append((self.endFrame * self.frameTime)) - o.animation.track.value = Object() - o.animation.track.value.values = [] + tracko.value = Object() + tracko.value.values = [] for i in range(self.beginFrame, self.endFrame): scene.frame_set(i) - o.animation.track.value.values.append(self.WriteMatrix(node.matrix_local)) + tracko.value.values.append(self.WriteMatrix(node.matrix_local)) scene.frame_set(self.endFrame) - o.animation.track.value.values.append(self.WriteMatrix(node.matrix_local)) + tracko.value.values.append(self.WriteMatrix(node.matrix_local)) + o.animation.tracks = [tracko] scene.frame_set(currentFrame, currentSubframe) @@ -664,37 +665,181 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): if (animationFlag): o.animation = Object() - o.animation.track = Object() - o.animation.track.target = "transform" - o.animation.track.time = Object() - o.animation.track.time.values = [] + tracko = Object() + tracko.target = "transform" + tracko.time = Object() + tracko.time.values = [] for i in range(self.beginFrame, self.endFrame): - o.animation.track.time.values.append(((i - self.beginFrame) * self.frameTime)) + tracko.time.values.append(((i - self.beginFrame) * self.frameTime)) - o.animation.track.time.values.append((self.endFrame * self.frameTime)) + tracko.time.values.append((self.endFrame * self.frameTime)) - o.animation.track.value = Object() - o.animation.track.value.values = [] + tracko.value = Object() + tracko.value.values = [] parent = poseBone.parent if (parent): for i in range(self.beginFrame, self.endFrame): scene.frame_set(i) - o.animation.track.value.values.append(self.WriteMatrix(parent.matrix.inverted() * poseBone.matrix)) + tracko.value.values.append(self.WriteMatrix(parent.matrix.inverted() * poseBone.matrix)) scene.frame_set(self.endFrame) - o.animation.track.value.values.append(self.WriteMatrix(parent.matrix.inverted() * poseBone.matrix)) + tracko.value.values.append(self.WriteMatrix(parent.matrix.inverted() * poseBone.matrix)) else: for i in range(self.beginFrame, self.endFrame): scene.frame_set(i) - o.animation.track.value.values.append(self.WriteMatrix(poseBone.matrix)) + tracko.value.values.append(self.WriteMatrix(poseBone.matrix)) scene.frame_set(self.endFrame) - o.animation.track.value.values.append(self.WriteMatrix(poseBone.matrix)) + tracko.value.values.append(self.WriteMatrix(poseBone.matrix)) + o.animation.tracks = [tracko] scene.frame_set(currentFrame, currentSubframe) + + + def ExportKeyTimes(self, fcurve): + keyo = Object() + # self.IndentWrite(B"Key {float {") + + keyo.values = [] + keyCount = len(fcurve.keyframe_points) + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + time = fcurve.keyframe_points[i].co[0] - self.beginFrame + keyo.values.append(time * self.frameTime) + # self.WriteFloat(time * self.frameTime) + # self.Write(B"}}\n") + return keyo + + def ExportKeyTimeControlPoints(self, fcurve): + keyminuso = Object() + # self.IndentWrite(B"Key (kind = \"-control\") {float {") + + keyminuso.values = [] + keyCount = len(fcurve.keyframe_points) + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + ctrl = fcurve.keyframe_points[i].handle_left[0] - self.beginFrame + keyminuso.values.append(ctrl * self.frameTime) + # self.WriteFloat(ctrl * self.frameTime) + + # self.Write(B"}}\n") + keypluso = Object() + keypluso.values = [] + # self.IndentWrite(B"Key (kind = \"+control\") {float {") + + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + ctrl = fcurve.keyframe_points[i].handle_right[0] - self.beginFrame + keypluso.values.append(ctrl * self.frameTime) + # self.WriteFloat(ctrl * self.frameTime) + + # self.Write(B"}}\n") + return keyminuso, keypluso + + def ExportKeyValues(self, fcurve): + keyo = Object() + keyo.values = [] + # self.IndentWrite(B"Key {float {") + + keyCount = len(fcurve.keyframe_points) + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + value = fcurve.keyframe_points[i].co[1] + keyo.values.append(value) + # self.WriteFloat(value) + + # self.Write(B"}}\n") + return keyo + + def ExportKeyValueControlPoints(self, fcurve): + keyminuso = Object() + keyminuso.values = [] + # self.IndentWrite(B"Key (kind = \"-control\") {float {") + + keyCount = len(fcurve.keyframe_points) + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + ctrl = fcurve.keyframe_points[i].handle_left[1] + keyminuso.values.append(ctrl) + # self.WriteFloat(ctrl) + + # self.Write(B"}}\n") + keypluso = Object() + keypluso.values = [] + # self.IndentWrite(B"Key (kind = \"+control\") {float {") + + for i in range(keyCount): + # if (i > 0): + # self.Write(B", ") + + ctrl = fcurve.keyframe_points[i].handle_right[1] + keypluso.values.append(ctrl) + # self.WriteFloat(ctrl) + + # self.Write(B"}}\n") + return keypluso, keypluso + + def ExportAnimationTrack(self, fcurve, kind, target, newline): + + # This function exports a single animation track. The curve types for the + # Time and Value structures are given by the kind parameter. + + tracko = Object() + tracko.target = target + # self.IndentWrite(B"Track (target = %", 0, newline) + # self.Write(target) + # self.Write(B")\n") + # self.IndentWrite(B"{\n") + # self.indentLevel += 1 + + if (kind != kAnimationBezier): + # self.IndentWrite(B"Time\n") + # self.IndentWrite(B"{\n") + # self.indentLevel += 1 + tracko.time = self.ExportKeyTimes(fcurve) + + # self.IndentWrite(B"}\n\n", -1) + # self.IndentWrite(B"Value\n", -1) + # self.IndentWrite(B"{\n", -1) + tracko.value = self.ExportKeyValues(fcurve) + + # self.indentLevel -= 1 + # self.IndentWrite(B"}\n") + + else: + tracko.curve = 'bezier' + # self.IndentWrite(B"Time (curve = \"bezier\")\n") + # self.IndentWrite(B"{\n") + # self.indentLevel += 1 + tracko.time = self.ExportKeyTimes(fcurve) + tracko.time_control_plus, tracko.time_control_minus = self.ExportKeyTimeControlPoints(fcurve) + + # self.IndentWrite(B"}\n\n", -1) + # self.IndentWrite(B"Value (curve = \"bezier\")\n", -1) + # self.IndentWrite(B"{\n", -1) + tracko.value = self.ExportKeyValues(fcurve) + tracko.value_control_plus, tracko.value_control_minus = self.ExportKeyValueControlPoints(fcurve) + + # self.indentLevel -= 1 + # self.IndentWrite(B"}\n") + + # self.indentLevel -= 1 + # self.IndentWrite(B"}\n") + return tracko + def ExportNodeTransform(self, node, scene, o): posAnimCurve = [None, None, None] rotAnimCurve = [None, None, None] @@ -805,6 +950,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): else: structFlag = False + o.transform = Object() + o.transform.values = self.WriteMatrix(node.matrix_local) + + o.animation_transforms = [] + deltaTranslation = node.delta_location if (deltaPositionAnimated): # When the delta location is animated, write the x, y, and z components separately @@ -812,6 +962,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for i in range(3): pos = deltaTranslation[i] if ((deltaPosAnimated[i]) or (math.fabs(pos) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'translation_' + axisName[i] + animo.name = deltaSubtranslationName[i] + animo.value = pos # self.IndentWrite(B"Translation %", 0, structFlag) # self.Write(deltaSubtranslationName[i]) # self.Write(B" (kind = \"") @@ -825,6 +980,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): structFlag = True elif ((math.fabs(deltaTranslation[0]) > kExportEpsilon) or (math.fabs(deltaTranslation[1]) > kExportEpsilon) or (math.fabs(deltaTranslation[2]) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'translation' + animo.values = self.WriteVector3D(deltaTranslation) # self.IndentWrite(B"Translation\n") # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[3] {", 1) @@ -840,6 +999,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for i in range(3): pos = translation[i] if ((posAnimated[i]) or (math.fabs(pos) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'translation_' + axisName[i] + animo.name = subtranslationName[i] + animo.value = pos # self.IndentWrite(B"Translation %", 0, structFlag) # self.Write(subtranslationName[i]) # self.Write(B" (kind = \"") @@ -853,6 +1017,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): structFlag = True elif ((math.fabs(translation[0]) > kExportEpsilon) or (math.fabs(translation[1]) > kExportEpsilon) or (math.fabs(translation[2]) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'translation' + animo.values = self.WriteVector3D(translation) # self.IndentWrite(B"Translation\n") # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[3] {", 1) @@ -868,6 +1036,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): axis = ord(mode[2 - i]) - 0x58 angle = node.delta_rotation_euler[axis] if ((deltaRotAnimated[axis]) or (math.fabs(angle) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_' + axisName[axis] + animo.name = deltaSubrotationName[axis] + animo.value = angle # self.IndentWrite(B"Rotation %", 0, structFlag) # self.Write(deltaSubrotationName[axis]) # self.Write(B" (kind = \"") @@ -886,6 +1059,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): if (mode == "QUATERNION"): quaternion = node.delta_rotation_quaternion if ((math.fabs(quaternion[0] - 1.0) > kExportEpsilon) or (math.fabs(quaternion[1]) > kExportEpsilon) or (math.fabs(quaternion[2]) > kExportEpsilon) or (math.fabs(quaternion[3]) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_quaternion' + animo.values = self.WriteQuaternion(quaternion) # self.IndentWrite(B"Rotation (kind = \"quaternion\")\n", 0, structFlag) # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[4] {", 1) @@ -899,6 +1076,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): axis = ord(mode[2 - i]) - 0x58 angle = node.delta_rotation_euler[axis] if (math.fabs(angle) > kExportEpsilon): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_' + axisName[axis] + animo.value = angle # self.IndentWrite(B"Rotation (kind = \"", 0, structFlag) # self.Write(axisName[axis]) # self.Write(B"\")\n") @@ -916,6 +1097,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): axis = ord(mode[2 - i]) - 0x58 angle = node.rotation_euler[axis] if ((rotAnimated[axis]) or (math.fabs(angle) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_' + axisName[axis] + animo.name = subrotationName[axis] + animo.value = angle # self.IndentWrite(B"Rotation %", 0, structFlag) # self.Write(subrotationName[axis]) # self.Write(B" (kind = \"") @@ -934,6 +1120,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): if (mode == "QUATERNION"): quaternion = node.rotation_quaternion if ((math.fabs(quaternion[0] - 1.0) > kExportEpsilon) or (math.fabs(quaternion[1]) > kExportEpsilon) or (math.fabs(quaternion[2]) > kExportEpsilon) or (math.fabs(quaternion[3]) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_quaternion' + animo.values = self.WriteQuaternion(quaternion) # self.IndentWrite(B"Rotation (kind = \"quaternion\")\n", 0, structFlag) # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[4] {", 1) @@ -944,6 +1134,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): elif (mode == "AXIS_ANGLE"): if (math.fabs(node.rotation_axis_angle[0]) > kExportEpsilon): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_axis' + animo.values = self.WriteVector4D(node.rotation_axis_angle) # self.IndentWrite(B"Rotation (kind = \"axis\")\n", 0, structFlag) # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[4] {", 1) @@ -957,6 +1151,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): axis = ord(mode[2 - i]) - 0x58 angle = node.rotation_euler[axis] if (math.fabs(angle) > kExportEpsilon): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'rotation_' + axisName[axis] + animo.value = angle # self.IndentWrite(B"Rotation (kind = \"", 0, structFlag) # self.Write(axisName[axis]) # self.Write(B"\")\n") @@ -974,6 +1172,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for i in range(3): scl = deltaScale[i] if ((deltaSclAnimated[i]) or (math.fabs(scl) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'scale_' + axisName[i] + animo.name = deltaSubscaleName[i] + animo.value = scl # self.IndentWrite(B"Scale %", 0, structFlag) # self.Write(deltaSubscaleName[i]) # self.Write(B" (kind = \"") @@ -987,6 +1190,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): structFlag = True elif ((math.fabs(deltaScale[0] - 1.0) > kExportEpsilon) or (math.fabs(deltaScale[1] - 1.0) > kExportEpsilon) or (math.fabs(deltaScale[2] - 1.0) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'scale' + animo.values = self.WriteVector3D(deltaScale) # self.IndentWrite(B"Scale\n", 0, structFlag) # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[3] {", 1) @@ -1002,6 +1209,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for i in range(3): scl = scale[i] if ((sclAnimated[i]) or (math.fabs(scl) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'scale_' + axisName[i] + animo.name = subscaleName[i] + animo.value = scl # self.IndentWrite(B"Scale %", 0, structFlag) # self.Write(subscaleName[i]) # self.Write(B" (kind = \"") @@ -1015,6 +1227,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): structFlag = True elif ((math.fabs(scale[0] - 1.0) > kExportEpsilon) or (math.fabs(scale[1] - 1.0) > kExportEpsilon) or (math.fabs(scale[2] - 1.0) > kExportEpsilon)): + animo = Object() + o.animation_transforms.append(animo) + animo.type = 'scale' + animo.values = self.WriteVector3D(scale) # self.IndentWrite(B"Scale\n", 0, structFlag) # self.IndentWrite(B"{\n") # self.IndentWrite(B"float[3] {", 1) @@ -1024,8 +1240,10 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): structFlag = True # Export the animation tracks. - #o.animation = Object() - + o.animation = Object() + o.animation.begin = (action.frame_range[0] - self.beginFrame) * self.frameTime + o.animation.end = (action.frame_range[1] - self.beginFrame) * self.frameTime + o.animation.tracks = [] # self.IndentWrite(B"Animation (begin = ", 0, True) # self.WriteFloat((action.frame_range[0] - self.beginFrame) * self.frameTime) # self.Write(B", end = ") @@ -1035,41 +1253,47 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): # self.indentLevel += 1 # structFlag = False - # if (positionAnimated): - # for i in range(3): - # if (posAnimated[i]): - # self.ExportAnimationTrack(posAnimCurve[i], posAnimKind[i], subtranslationName[i], structFlag) - # structFlag = True + if (positionAnimated): + for i in range(3): + if (posAnimated[i]): + tracko = self.ExportAnimationTrack(posAnimCurve[i], posAnimKind[i], subtranslationName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True - # if (rotationAnimated): - # for i in range(3): - # if (rotAnimated[i]): - # self.ExportAnimationTrack(rotAnimCurve[i], rotAnimKind[i], subrotationName[i], structFlag) - # structFlag = True + if (rotationAnimated): + for i in range(3): + if (rotAnimated[i]): + tracko = self.ExportAnimationTrack(rotAnimCurve[i], rotAnimKind[i], subrotationName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True - # if (scaleAnimated): - # for i in range(3): - # if (sclAnimated[i]): - # self.ExportAnimationTrack(sclAnimCurve[i], sclAnimKind[i], subscaleName[i], structFlag) - # structFlag = True + if (scaleAnimated): + for i in range(3): + if (sclAnimated[i]): + tracko = self.ExportAnimationTrack(sclAnimCurve[i], sclAnimKind[i], subscaleName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True - # if (deltaPositionAnimated): - # for i in range(3): - # if (deltaPosAnimated[i]): - # self.ExportAnimationTrack(deltaPosAnimCurve[i], deltaPosAnimKind[i], deltaSubtranslationName[i], structFlag) - # structFlag = True + if (deltaPositionAnimated): + for i in range(3): + if (deltaPosAnimated[i]): + tracko = self.ExportAnimationTrack(deltaPosAnimCurve[i], deltaPosAnimKind[i], deltaSubtranslationName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True - # if (deltaRotationAnimated): - # for i in range(3): - # if (deltaRotAnimated[i]): - # self.ExportAnimationTrack(deltaRotAnimCurve[i], deltaRotAnimKind[i], deltaSubrotationName[i], structFlag) - # structFlag = True + if (deltaRotationAnimated): + for i in range(3): + if (deltaRotAnimated[i]): + tracko = self.ExportAnimationTrack(deltaRotAnimCurve[i], deltaRotAnimKind[i], deltaSubrotationName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True - # if (deltaScaleAnimated): - # for i in range(3): - # if (deltaSclAnimated[i]): - # self.ExportAnimationTrack(deltaSclAnimCurve[i], deltaSclAnimKind[i], deltaSubscaleName[i], structFlag) - # structFlag = True + if (deltaScaleAnimated): + for i in range(3): + if (deltaSclAnimated[i]): + tracko = self.ExportAnimationTrack(deltaSclAnimCurve[i], deltaSclAnimKind[i], deltaSubscaleName[i], structFlag) + o.animation.tracks.append(tracko) + structFlag = True def ProcessBone(self, bone): if ((ArmoryExporter.exportAllFlag) or (bone.select)): @@ -1833,6 +2057,8 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): o.type = 'sun' o.cast_shadow = object.cycles.cast_shadow + o.near_plane = object.light_clip_start + o.far_plane = object.light_clip_end # Parse nodes, only emission for now # Merge with nodes_material @@ -2088,7 +2314,12 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for m in node.modifiers: if m.type == 'OCEAN': + # Do not export ocean geometry, just take specified constants export_node = False + wrd = bpy.data.worlds[0] + wrd.generate_ocean = True + # Take position and bounds + wrd.generate_ocean_level = node.location.z elif m.type == 'UV_PROJECT' and m.show_render: self.uvprojectUsersArray.append(node) @@ -2344,7 +2575,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): if world_generate_radiance == False: generate_radiance = False - cam.probe_num_mips = write_probes.write_probes(cam.probe_texture, disable_hdr, cam.probe_num_mips, generate_radiance=generate_radiance) + cam.probe_num_mips = write_probes.write_probes('Assets/' + cam.probe_texture, disable_hdr, cam.probe_num_mips, generate_radiance=generate_radiance) 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, generate_radiance, generate_irradiance) o.probes.append(po) diff --git a/blender/nodes_pipeline.py b/blender/nodes_pipeline.py index 5d6dad6f..19edd0a8 100755 --- a/blender/nodes_pipeline.py +++ b/blender/nodes_pipeline.py @@ -204,7 +204,6 @@ class WaterPassNode(Node, CGPipelineTreeNode): self.inputs.new('NodeSocketShader', "Target") self.inputs.new('NodeSocketShader', "Color") self.inputs.new('NodeSocketShader', "GBufferD") - self.inputs.new('NodeSocketShader', "GBuffer0") self.outputs.new('NodeSocketShader', "Stage") @@ -1129,7 +1128,7 @@ def make_sss_pass(stages, node_group, node, shader_references, asset_references) make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=2, bind_target_indices=[3, 4, 5], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='sss_pass/sss_pass/sss_pass_y') def make_water_pass(stages, node_group, node, shader_references, asset_references): - make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['tex', 'gbufferD', 'gbuffer0'], shader_context='water_pass/water_pass/water_pass') + make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['tex', 'gbufferD'], shader_context='water_pass/water_pass/water_pass') def make_deferred_light_pass(stages, node_group, node, shader_references, asset_references): make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'ssaotex', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light') diff --git a/blender/nodes_world.py b/blender/nodes_world.py index 362548e1..c0da181e 100755 --- a/blender/nodes_world.py +++ b/blender/nodes_world.py @@ -75,6 +75,18 @@ def buildNodeTree(world_name, node_group): bpy.data.cameras[0].world_envtex_name = base_name write_probes.write_color_irradiance(base_name, bpy.data.cameras[0].world_envtex_color) + # Clouds enabled + if bpy.data.worlds[0].generate_clouds: + bpy.data.worlds[0].world_defs += '_EnvClouds' + + # SSAO enabled + if bpy.data.worlds[0].generate_ssao: + bpy.data.worlds[0].world_defs += '_SSAO' + + # Shadows disabled + if bpy.data.worlds[0].generate_shadows == False: + bpy.data.worlds[0].world_defs += '_NoShadows' + # Enable probes for cam in bpy.data.cameras: if cam.is_probe: @@ -134,7 +146,7 @@ def parse_color(node_group, node, context): disable_hdr = image_name.endswith('.jpg') mip_count = bpy.data.cameras[0].world_envtex_num_mips - mip_count = write_probes.write_probes(image_name, disable_hdr, mip_count, generate_radiance=generate_radiance) + mip_count = write_probes.write_probes(node.image.filepath, disable_hdr, mip_count, generate_radiance=generate_radiance) bpy.data.cameras[0].world_envtex_num_mips = mip_count # Append envtex define @@ -149,9 +161,6 @@ def parse_color(node_group, node, context): # Append sky define elif node.type == 'TEX_SKY': bpy.data.worlds[0].world_defs += '_EnvSky' - # Clouds enabled - if bpy.data.worlds[0].generate_clouds: - bpy.data.worlds[0].world_defs += '_EnvClouds' # Append sky properties to material const = Object() const.id = 'sunDirection' diff --git a/blender/project.py b/blender/project.py index afe9bb56..b3422775 100755 --- a/blender/project.py +++ b/blender/project.py @@ -40,6 +40,7 @@ def init_armory_props(): wrd.CGPlayViewportCamera = False wrd.CGPlayConsole = False wrd.CGPlayDeveloperTools = False + wrd.CGPlayRuntime = 'Electron' # Switch to Cycles if bpy.data.scenes[0].render.engine == 'BLENDER_RENDER': for scene in bpy.data.scenes: @@ -63,14 +64,18 @@ def draw_play_item(self, context): else: layout.operator("arm.stop") +# Info panel in header +def draw_info_item(self, context): + layout = self.layout + layout.label(ArmoryProjectPanel.info_text) + # Menu in render region class ArmoryProjectPanel(bpy.types.Panel): bl_label = "Armory Project" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "render" - - bpy.types.VIEW3D_HT_header.append(draw_play_item) + info_text = 'Ready' def draw(self, context): layout = self.layout @@ -103,7 +108,6 @@ class ArmoryBuildPanel(bpy.types.Panel): layout.prop(wrd, 'CGMinimize') layout.prop(wrd, 'CGOptimizeGeometry') layout.prop(wrd, 'CGCacheShaders') - layout.label('Armory v' + wrd.CGVersion) class ArmoryPlayPanel(bpy.types.Panel): bl_label = "Armory Play" @@ -115,6 +119,7 @@ class ArmoryPlayPanel(bpy.types.Panel): layout = self.layout wrd = bpy.data.worlds[0] layout.operator("arm.play") + layout.prop(wrd, 'CGPlayRuntime') layout.prop(wrd, 'CGPlayViewportCamera') layout.prop(wrd, 'CGPlayConsole') layout.prop(wrd, 'CGPlayDeveloperTools') @@ -223,11 +228,29 @@ def export_game_data(fp, sdk_path): # Write Main.hx write_data.write_main() +def print_info(text): + ArmoryProjectPanel.info_text = text + # for area in bpy.context.screen.areas: + # if area.type == 'INFO': + # area.tag_redraw() + def compile_project(self, target_index=None): user_preferences = bpy.context.user_preferences addon_prefs = user_preferences.addons['armory'].preferences sdk_path = addon_prefs.sdk_path + #self.report({'OPERATOR'}, 'Printing report to Info window.') + # run(..., check=True, stdout=PIPE).stdout + + # success = require(path.join(args.kha, 'Tools/khamake/main.js')) + # .run(options, { + # info: function (message) { + # _this.fireEvent(new vscode_debugadapter_1.OutputEvent(message + '\n', 'stdout')); + # }, error: function (message) { + # _this.fireEvent(new vscode_debugadapter_1.OutputEvent(message + '\n', 'stderr')); + # } + # }, function (name) { }); + # Set build command if target_index == None: target_index = bpy.data.worlds[0]['CGProjectTarget'] @@ -244,7 +267,7 @@ def compile_project(self, target_index=None): node_path = sdk_path + '/nodejs/node-osx' khamake_path = sdk_path + '/KodeStudio/KodeStudio.app/Contents/Resources/app/extensions/kha/Kha/make' cmd = [node_path, khamake_path, targets[target_index]] - self.report({'INFO'}, "Building, see console...") + # print_info("Building, see console...") return subprocess.Popen(cmd) def build_project(self): @@ -296,9 +319,11 @@ def watch_play(): play_project.playproc = None def watch_compile(): - if play_project.compileproc.poll() == None: + return_code = play_project.compileproc.poll() + if return_code == None: threading.Timer(0.1, watch_compile).start() else: + print('RETURN CODE:', return_code) play_project.compileproc = None on_compiled() @@ -332,13 +357,15 @@ def play_project(self, in_frame): watch_compile() def on_compiled(): + print_info("Ready") user_preferences = bpy.context.user_preferences addon_prefs = user_preferences.addons['armory'].preferences sdk_path = addon_prefs.sdk_path - electron_path = sdk_path + 'KodeStudio/KodeStudio.app/Contents/MacOS/Electron' + # electron_path = sdk_path + 'KodeStudio/KodeStudio.app/Contents/MacOS/Electron' + electron_path = sdk_path + 'KodeStudio/KodeStudioOld.app/Contents/MacOS/Electron' electron_app_path = './build/electron.js' - play_project.playproc = subprocess.Popen([electron_path, '-chromedebug', electron_app_path]) + play_project.playproc = subprocess.Popen([electron_path, '--chromedebug', '--remote-debugging-port=9222', electron_app_path]) watch_play() play_project.playproc = None play_project.compileproc = None @@ -431,10 +458,14 @@ def register(): km.keymap_items.new(ArmoryPlayInFrameButton.bl_idname, type='B', value='PRESS', ctrl=True, shift=True) km.keymap_items.new(ArmoryPlayButton.bl_idname, type='F5', value='PRESS') arm_keymaps.append(km) + bpy.types.VIEW3D_HT_header.append(draw_play_item) + bpy.types.INFO_HT_header.prepend(draw_info_item) def unregister(): + bpy.types.VIEW3D_HT_header.remove(draw_play_item) + bpy.types.INFO_HT_header.remove(draw_info_item) bpy.utils.unregister_module(__name__) wm = bpy.context.window_manager for km in arm_keymaps: - wm.keyconfigs.addon.kmaps.remove(km) + wm.keyconfigs.addon.keymaps.remove(km) del arm_keymaps[:] diff --git a/blender/props.py b/blender/props.py index 04c3ceb2..c6e4fee9 100755 --- a/blender/props.py +++ b/blender/props.py @@ -39,6 +39,10 @@ def initProperties(): bpy.types.World.CGPlayViewportCamera = BoolProperty(name="Viewport Camera", default=False) bpy.types.World.CGPlayConsole = BoolProperty(name="Debug Console", default=False) bpy.types.World.CGPlayDeveloperTools = BoolProperty(name="Developer Tools", default=False) + bpy.types.World.CGPlayRuntime = EnumProperty( + items = [('Electron', 'Electron', 'Electron'), + ('Krom', 'Krom', 'Krom')], + name = "Runtime", default='Electron') # For object bpy.types.Object.geometry_cached = bpy.props.BoolProperty(name="Geometry Cached", default=False) # TODO: move to mesh type @@ -87,6 +91,20 @@ def initProperties(): bpy.types.World.shadowmap_size = bpy.props.IntProperty(name="Shadowmap Size", default=0) 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) + bpy.types.World.generate_ocean_base_color = bpy.props.FloatVectorProperty(name="Base Color", size=3, default=[0.1, 0.19, 0.37], subtype='COLOR') + bpy.types.World.generate_ocean_water_color = bpy.props.FloatVectorProperty(name="Water Color", size=3, default=[0.6, 0.7, 0.9], subtype='COLOR') + bpy.types.World.generate_ocean_level = bpy.props.FloatProperty(name="Level", default=0.0) + bpy.types.World.generate_ocean_amplitude = bpy.props.FloatProperty(name="Amplitude", default=2.5) + bpy.types.World.generate_ocean_height = bpy.props.FloatProperty(name="Height", default=0.6) + bpy.types.World.generate_ocean_choppy = bpy.props.FloatProperty(name="Choppy", default=4.0) + bpy.types.World.generate_ocean_speed = bpy.props.FloatProperty(name="Speed", default=1.0) + bpy.types.World.generate_ocean_freq = bpy.props.FloatProperty(name="Freq", default=0.16) + bpy.types.World.generate_ssao = bpy.props.BoolProperty(name="Generate SSAO", default=True) + bpy.types.World.generate_ssao_size = bpy.props.FloatProperty(name="Size", default=0.12) + bpy.types.World.generate_ssao_strength = bpy.props.FloatProperty(name="Strength", default=0.55) + bpy.types.World.generate_shadows = bpy.props.BoolProperty(name="Generate Shadows", default=True) + bpy.types.World.generate_shadows_bias = bpy.props.FloatProperty(name="Bias", default=0.00005) # For material bpy.types.Material.receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True) bpy.types.Material.custom_shader = bpy.props.BoolProperty(name="Custom Shader", default=False) @@ -96,6 +114,9 @@ def initProperties(): bpy.types.Material.skip_context = bpy.props.StringProperty(name="Skip Context", default='') # For scene bpy.types.Scene.game_export = bpy.props.BoolProperty(name="Game Export", default=True) + # For light + bpy.types.Lamp.light_clip_start = bpy.props.FloatProperty(name="Clip Start", default=0.1) + bpy.types.Lamp.light_clip_end = bpy.props.FloatProperty(name="Clip End", default=100.0) # Menu in object region class ObjectPropsPanel(bpy.types.Panel): @@ -116,6 +137,22 @@ class ObjectPropsPanel(bpy.types.Panel): if obj.custom_material: layout.prop(obj, 'custom_material_name') +# Menu in modifiers region +class ModifiersPropsPanel(bpy.types.Panel): + bl_label = "Armory Props" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "modifier" + + def draw(self, context): + layout = self.layout + obj = bpy.context.object + + # Assume as first modifier + if len(obj.modifiers) > 0 and obj.modifiers[0].type == 'OCEAN': + layout.prop(bpy.data.worlds[0], 'generate_ocean_base_color') + layout.prop(bpy.data.worlds[0], 'generate_ocean_water_color') + # Menu in data region class DataPropsPanel(bpy.types.Panel): bl_label = "Armory Props" @@ -141,6 +178,9 @@ class DataPropsPanel(bpy.types.Panel): elif obj.type == 'MESH': layout.prop(obj.data, 'static_usage') layout.operator("cg.invalidate_cache") + elif obj.type == 'LAMP': + layout.prop(obj.data, 'light_clip_start') + layout.prop(obj.data, 'light_clip_end') class ScenePropsPanel(bpy.types.Panel): bl_label = "Armory Props" @@ -208,6 +248,13 @@ class WorldPropsPanel(bpy.types.Panel): layout.prop(wrd, 'generate_clouds_secondary') layout.prop(wrd, 'generate_clouds_precipitation') layout.prop(wrd, 'generate_clouds_eccentricity') + layout.prop(wrd, 'generate_ssao') + if wrd.generate_ssao: + layout.prop(wrd, 'generate_ssao_size') + layout.prop(wrd, 'generate_ssao_strength') + layout.prop(wrd, 'generate_shadows') + if wrd.generate_shadows: + layout.prop(wrd, 'generate_shadows_bias') # Registration def register(): diff --git a/blender/traits.py b/blender/traits.py index ebdbc194..90a5a89c 100755 --- a/blender/traits.py +++ b/blender/traits.py @@ -56,11 +56,11 @@ class ListTraitItem(bpy.types.PropertyGroup): description="A name for this item", default="") - my_paramstraitlist = bpy.props.CollectionProperty(type = ListParamsTraitItem) - paramstraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) + my_paramstraitlist = bpy.props.CollectionProperty(type=ListParamsTraitItem) + paramstraitlist_index = bpy.props.IntProperty(name="Index for my_list", default=-1) - my_animationtraitlist = bpy.props.CollectionProperty(type = ListAnimationTraitItem) - animationtraitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) + my_animationtraitlist = bpy.props.CollectionProperty(type=ListAnimationTraitItem) + animationtraitlist_index = bpy.props.IntProperty(name="Index for my_list", default=-1) class MY_UL_TraitList(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): @@ -78,7 +78,7 @@ class MY_UL_TraitList(bpy.types.UIList): def initObjectProperties(): bpy.types.Object.my_traitlist = bpy.props.CollectionProperty(type = ListTraitItem) - bpy.types.Object.traitlist_index = bpy.props.IntProperty(name = "Index for my_list", default = 0) + bpy.types.Object.traitlist_index = bpy.props.IntProperty(name = "Index for my_list", default=-1) class LIST_OT_TraitNewItem(bpy.types.Operator): diff --git a/blender/write_data.py b/blender/write_data.py index 0659fe3f..d5e7de06 100644 --- a/blender/write_data.py +++ b/blender/write_data.py @@ -124,7 +124,7 @@ function createWindow () { """) """) f.write( """ - //mainWindow.loadURL('file://' + __dirname + '/build/html5/index.html'); + //mainWindow.loadURL('file://' + __dirname + '/html5/index.html'); mainWindow.loadURL('http://localhost:8040/build/html5/index.html'); mainWindow.on('closed', function() { mainWindow = null; });""") @@ -170,19 +170,39 @@ def write_compiledglsl(clip_start, clip_end, shadowmap_size): f.write( """const float PI = 3.1415926535; const float PI2 = PI * 2.0; -const vec2 cameraPlane = vec2(""" + str(int(clip_start * 100) / 100) + """, """ + str(int(clip_end * 100) / 100) + """); +const vec2 cameraPlane = vec2(""" + str(round(clip_start * 100) / 100) + """, """ + str(round(clip_end * 100) / 100) + """); const vec2 shadowmapSize = vec2(""" + str(shadowmap_size) + """, """ + str(shadowmap_size) + """); """) if wrd.generate_clouds: f.write( -"""const float cloudsDensity = """ + str(int(wrd.generate_clouds_density * 100) / 100) + """; -const float cloudsSize = """ + str(int(wrd.generate_clouds_size * 100) / 100) + """; -const float cloudsLower = """ + str(int(wrd.generate_clouds_lower * 1000)) + """; -const float cloudsUpper = """ + str(int(wrd.generate_clouds_upper * 1000)) + """; -const vec2 cloudsWind = vec2(""" + str(int(wrd.generate_clouds_wind[0] * 1000) / 1000) + """, """ + str(int(wrd.generate_clouds_wind[1] * 1000) / 1000) + """); -const float cloudsSecondary = """ + str(int(wrd.generate_clouds_secondary * 100) / 100) + """; -const float cloudsPrecipitation = """ + str(int(wrd.generate_clouds_precipitation * 100) / 100) + """; -const float cloudsEccentricity = """ + str(int(wrd.generate_clouds_eccentricity * 100) / 100) + """; +"""const float cloudsDensity = """ + str(round(wrd.generate_clouds_density * 100) / 100) + """; +const float cloudsSize = """ + str(round(wrd.generate_clouds_size * 100) / 100) + """; +const float cloudsLower = """ + str(round(wrd.generate_clouds_lower * 1000)) + """; +const float cloudsUpper = """ + str(round(wrd.generate_clouds_upper * 1000)) + """; +const vec2 cloudsWind = vec2(""" + str(round(wrd.generate_clouds_wind[0] * 1000) / 1000) + """, """ + str(round(wrd.generate_clouds_wind[1] * 1000) / 1000) + """); +const float cloudsSecondary = """ + str(round(wrd.generate_clouds_secondary * 100) / 100) + """; +const float cloudsPrecipitation = """ + str(round(wrd.generate_clouds_precipitation * 100) / 100) + """; +const float cloudsEccentricity = """ + str(round(wrd.generate_clouds_eccentricity * 100) / 100) + """; +""") + if wrd.generate_ocean: + f.write( +"""const float seaLevel = """ + str(round(wrd.generate_ocean_level * 100) / 100) + """; +const float seaMaxAmplitude = """ + str(round(wrd.generate_ocean_amplitude * 100) / 100) + """; +const float seaHeight = """ + str(round(wrd.generate_ocean_height * 100) / 100) + """; +const float seaChoppy = """ + str(round(wrd.generate_ocean_choppy * 100) / 100) + """; +const float seaSpeed = """ + str(round(wrd.generate_ocean_speed * 100) / 100) + """; +const float seaFreq = """ + str(round(wrd.generate_ocean_freq * 100) / 100) + """; +const vec3 seaBaseColor = vec3(""" + str(round(wrd.generate_ocean_base_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_base_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_base_color[2] * 100) / 100) + """); +const vec3 seaWaterColor = vec3(""" + str(round(wrd.generate_ocean_water_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_water_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_water_color[2] * 100) / 100) + """); +""") + if wrd.generate_ssao: + f.write( +"""const float ssaoSize = """ + str(round(wrd.generate_ssao_size * 100) / 100) + """; +const float ssaoStrength = """ + str(round(wrd.generate_ssao_strength * 100) / 100) + """; +""") + if wrd.generate_shadows: + f.write( +"""const float shadowsBias = """ + str(wrd.generate_shadows_bias) + """; """) def write_traithx(class_name): diff --git a/blender/write_probes.py b/blender/write_probes.py index 1cf2dcb5..ceded5a6 100644 --- a/blender/write_probes.py +++ b/blender/write_probes.py @@ -4,234 +4,231 @@ import sys import subprocess import json import re +import utils class Object: - def to_JSON(self): - if bpy.data.worlds[0].CGMinimize == True: - return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':')) - else: - return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + def to_JSON(self): + if bpy.data.worlds[0].CGMinimize == True: + return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':')) + else: + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) # Generate probes from environment map -def write_probes(image_name, disable_hdr, cached_num_mips, generate_radiance=True): - if not os.path.exists('Assets/generated/envmaps'): - os.makedirs('Assets/generated/envmaps') - - name_split = image_name.rsplit('.', 1) - base_name = name_split[0] - # Assume irradiance has to exist for now - if os.path.exists('Assets/generated/envmaps/' + base_name + '_irradiance.json'): - return cached_num_mips - - # Get paths - # haxelib_path = "haxelib" - # if platform.system() == 'Darwin': - # haxelib_path = "/usr/local/bin/haxelib" +def write_probes(image_filepath, disable_hdr, cached_num_mips, generate_radiance=True): + if not os.path.exists('Assets/generated/envmaps'): + os.makedirs('Assets/generated/envmaps') + + base_name = image_filepath.rsplit('/', 1)[1].rsplit('.', 1)[0] # Extract file name without extension + # Assume irradiance has to exist for now + if os.path.exists('Assets/generated/envmaps/' + base_name + '_irradiance.json'): + return cached_num_mips + + # Get paths + user_preferences = bpy.context.user_preferences + addon_prefs = user_preferences.addons['armory'].preferences + sdk_path = addon_prefs.sdk_path - # output = subprocess.check_output([haxelib_path + " path armory"], shell=True) - # output = str(output).split("\\n")[0].split("'")[1] - # cmft_path = output[:-8] + "tools/cmft/" - cmft_path = 'Libraries/armory/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 - - # Irradiance image - # output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' - # subprocess.call([ \ - # cmft_path + 'cmft-osx' + \ - # ' --input ' + input_file + \ - # ' --filter irradiance' + \ - # ' --dstFaceSize ' + dst_face_size + \ - # gama_options + \ - # ' --outputNum 1' + \ - # ' --output0 ' + output_file + \ - # ' --output0params hdr,rgbe,latlong'], shell=True) - # generated_files.append(output_file) - - # Irradiance spherical harmonics - output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' - subprocess.call([ \ - cmft_path + 'cmft-osx' + \ - ' --input ' + input_file + \ - ' --filter shcoeffs' + \ - #gama_options + \ - ' --outputNum 1' + \ - ' --output0 ' + output_file], shell=True) - - sh_to_json(output_file) - - # Mip-mapped radiance image - if generate_radiance == False: - return cached_num_mips - - output_file = 'Assets/generated/envmaps/' + base_name + '_radiance' - outformat = 'jpg' if disable_hdr else 'hdr' - output = subprocess.check_output([ \ - 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 + cmft_path = sdk_path + '/armory/tools/cmft/' + kraffiti_path = sdk_path + '/KodeStudio/KodeStudio.app/Contents/Resources/app/extensions/kha/Kha/Kore/Tools/kraffiti/' + generated_files = [] + output_gama_numerator = '1.0' if disable_hdr else '2.2' + input_file = utils.get_fp() + image_filepath #'Assets/' + 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 + + # Irradiance image + # output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' + # subprocess.call([ \ + # cmft_path + 'cmft-osx' + \ + # ' --input ' + input_file + \ + # ' --filter irradiance' + \ + # ' --dstFaceSize ' + dst_face_size + \ + # gama_options + \ + # ' --outputNum 1' + \ + # ' --output0 ' + output_file + \ + # ' --output0params hdr,rgbe,latlong'], shell=True) + # generated_files.append(output_file) + + # Irradiance spherical harmonics + output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' + subprocess.call([ \ + cmft_path + 'cmft-osx' + \ + ' --input ' + input_file + \ + ' --filter shcoeffs' + \ + #gama_options + \ + ' --outputNum 1' + \ + ' --output0 ' + output_file], shell=True) + + sh_to_json(output_file) + + # Mip-mapped radiance image + if generate_radiance == False: + return cached_num_mips + + output_file = 'Assets/generated/envmaps/' + base_name + '_radiance' + outformat = 'jpg' if disable_hdr else 'hdr' + output = subprocess.check_output([ \ + 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 + # 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 # Parse sh coefs produced by cmft into json array def sh_to_json(sh_file): - sh_lines = open(sh_file + '.c').read().splitlines() - band0_line = sh_lines[5] - band1_line = sh_lines[6] - band2_line = sh_lines[7] - - irradiance_floats = [] - parse_band_floats(irradiance_floats, band0_line) - parse_band_floats(irradiance_floats, band1_line) - parse_band_floats(irradiance_floats, band2_line) - - with open(sh_file + '.json', 'w') as f: - sh_json = Object() - sh_json.irradiance = irradiance_floats - f.write(sh_json.to_JSON()) - - # Clean up .c - os.remove(sh_file + '.c') + sh_lines = open(sh_file + '.c').read().splitlines() + band0_line = sh_lines[5] + band1_line = sh_lines[6] + band2_line = sh_lines[7] + + irradiance_floats = [] + parse_band_floats(irradiance_floats, band0_line) + parse_band_floats(irradiance_floats, band1_line) + parse_band_floats(irradiance_floats, band2_line) + + with open(sh_file + '.json', 'w') as f: + sh_json = Object() + sh_json.irradiance = irradiance_floats + f.write(sh_json.to_JSON()) + + # Clean up .c + os.remove(sh_file + '.c') def parse_band_floats(irradiance_floats, band_line): - string_floats = re.findall(r'[-+]?\d*\.\d+|\d+', band_line) - string_floats = string_floats[1:] # Remove 'Band 0/1/2' number - for s in string_floats: - irradiance_floats.append(float(s)) + string_floats = re.findall(r'[-+]?\d*\.\d+|\d+', band_line) + string_floats = string_floats[1:] # Remove 'Band 0/1/2' number + for s in string_floats: + irradiance_floats.append(float(s)) def write_sky_irradiance(base_name): - # Predefined fake spherical harmonics for now - irradiance_floats = [1.0281457342829743,1.1617608778901902,1.3886220898440544,-0.13044863139637752,-0.2794659158733846,-0.5736106907295643,0.04065421813873111,0.0434367391348577,0.03567450494792305,0.10964557605577738,0.1129839085793664,0.11261660812141877,-0.08271974283263238,-0.08068091195339556,-0.06432614970480094,-0.12517787967665814,-0.11638582546310804,-0.09743696224655113,0.20068697715947176,0.2158788783296805,0.2109374396869599,0.19636637427150455,0.19445523113118082,0.17825330699680575,0.31440860839538637,0.33041120060402407,0.30867788630062676] - - if not os.path.exists('Assets/generated/envmaps'): - os.makedirs('Assets/generated/envmaps') - - output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' - - with open(output_file + '.json', 'w') as f: - sh_json = Object() - sh_json.irradiance = irradiance_floats - f.write(sh_json.to_JSON()) + # Predefined fake spherical harmonics for now + irradiance_floats = [1.0281457342829743,1.1617608778901902,1.3886220898440544,-0.13044863139637752,-0.2794659158733846,-0.5736106907295643,0.04065421813873111,0.0434367391348577,0.03567450494792305,0.10964557605577738,0.1129839085793664,0.11261660812141877,-0.08271974283263238,-0.08068091195339556,-0.06432614970480094,-0.12517787967665814,-0.11638582546310804,-0.09743696224655113,0.20068697715947176,0.2158788783296805,0.2109374396869599,0.19636637427150455,0.19445523113118082,0.17825330699680575,0.31440860839538637,0.33041120060402407,0.30867788630062676] + + if not os.path.exists('Assets/generated/envmaps'): + os.makedirs('Assets/generated/envmaps') + + output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' + + with open(output_file + '.json', 'w') as f: + sh_json = Object() + sh_json.irradiance = irradiance_floats + f.write(sh_json.to_JSON()) def write_color_irradiance(base_name, col): - # Constant color - irradiance_floats = [col[0], col[1], col[2]] - for i in range(0, 24): - irradiance_floats.append(0.0) - - if not os.path.exists('Assets/generated/envmaps'): - os.makedirs('Assets/generated/envmaps') - - output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' - - with open(output_file + '.json', 'w') as f: - sh_json = Object() - sh_json.irradiance = irradiance_floats - f.write(sh_json.to_JSON()) + # Constant color + irradiance_floats = [col[0], col[1], col[2]] + for i in range(0, 24): + irradiance_floats.append(0.0) + + if not os.path.exists('Assets/generated/envmaps'): + os.makedirs('Assets/generated/envmaps') + + output_file = 'Assets/generated/envmaps/' + base_name + '_irradiance' + + with open(output_file + '.json', 'w') as f: + sh_json = Object() + sh_json.irradiance = irradiance_floats + f.write(sh_json.to_JSON()) diff --git a/raw/deferred/deferred.vert.glsl b/raw/deferred/deferred.vert.glsl index ae95608c..1bc5296c 100644 --- a/raw/deferred/deferred.vert.glsl +++ b/raw/deferred/deferred.vert.glsl @@ -145,6 +145,7 @@ void main() { #ifdef _VCols matColor *= col; + // matColor *= pow(col, vec3(2.2)); #endif mvpposition = gl_Position; diff --git a/raw/deferred_light/deferred_light.frag.glsl b/raw/deferred_light/deferred_light.frag.glsl index da756326..1ca46db2 100644 --- a/raw/deferred_light/deferred_light.frag.glsl +++ b/raw/deferred_light/deferred_light.frag.glsl @@ -24,8 +24,12 @@ uniform float envmapStrength; // uniform sampler2D giblur; // Path-traced -uniform sampler2D ssaotex; -uniform sampler2D shadowMap; +#ifdef _SSAO + uniform sampler2D ssaotex; +#endif +#ifndef _NoShadows + uniform sampler2D shadowMap; +#endif // #ifdef _LTC // uniform sampler2D sltcMat; @@ -74,6 +78,7 @@ in vec3 viewRay; // out vec4 outputColor; // Separable SSS Transmittance Function, ref to sss_pass +#ifdef _SSS vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, vec3 worldNormal, vec3 lightDir) { float scale = 8.25 * (1.0 - translucency) / sssWidth; vec4 shrinkedPos = vec4(worldPosition - 0.005 * worldNormal, 1.0); @@ -93,6 +98,7 @@ vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, v vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); return profile * clamp(0.3 + dot(lightDir, -worldNormal), 0.0, 1.0); } +#endif vec2 envMapEquirect(vec3 normal) { float phi = acos(normal.z); @@ -144,11 +150,12 @@ vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, flo return lambert(albedo, nl); } +#ifndef _NoShadows +#ifndef _PCSS float texture2DCompare(vec2 uv, float compare){ float depth = texture(shadowMap, uv).r * 2.0 - 1.0; return step(compare, depth); } - float texture2DShadowLerp(vec2 size, vec2 uv, float compare){ vec2 texelSize = vec2(1.0) / size; vec2 f = fract(uv * size + 0.5); @@ -163,7 +170,6 @@ float texture2DShadowLerp(vec2 size, vec2 uv, float compare){ float c = mix(a, b, f.x); return c; } - float PCF(vec2 uv, float compare) { float result = 0.0; // for (int x = -1; x <= 1; x++){ @@ -193,10 +199,7 @@ float PCF(vec2 uv, float compare) { // } return result / 9.0; } - - -// #define _PCSS -#ifdef _PCSS +#else // Based on ThreeJS PCSS example const float LIGHT_WORLD_SIZE = 3.55; const float LIGHT_FRUSTUM_WIDTH = 4.75;//5.75; //12.75 @@ -400,7 +403,6 @@ float PCF(vec2 uv, float compare) { // } return sum / (2.0 * float(NUM_SAMPLES)); } - float PCSS(vec2 uv, float zReceiver) { initPoissonSamples(uv); @@ -418,24 +420,22 @@ float PCF(vec2 uv, float compare) { return PCF_Filter(uv, zReceiver, filterRadius); } #endif +#endif - - +#ifndef _NoShadows float shadowTest(vec4 lPos) { vec4 lPosH = lPos / lPos.w; lPosH.x = (lPosH.x + 1.0) / 2.0; lPosH.y = (lPosH.y + 1.0) / 2.0; - // const float bias = 0.00005; // Persp - const float bias = 0.00125; // Persp - // const float bias = 0.01; // Ortho - #ifdef _PCSS - return PCSS(lPosH.xy, lPosH.z - bias); + return PCSS(lPosH.xy, lPosH.z - shadowsBias); #else - return PCF(lPosH.xy, lPosH.z - bias); + return PCF(lPosH.xy, lPosH.z - shadowsBias); #endif } +#endif + 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)); @@ -749,12 +749,13 @@ void main() { float dotLV = max(dot(l, v), 0.0); float dotLH = max(dot(l, h), 0.0); - vec4 lPos = LMVP * vec4(vec3(p), 1.0); float visibility = 1.0; +#ifndef _NoShadows + vec4 lPos = LMVP * vec4(vec3(p), 1.0); if (lPos.w > 0.0) { visibility = shadowTest(lPos); - //visibility = 1.0; } +#endif // Direct vec3 direct = diffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH, dotLV) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH, dotLH); @@ -835,8 +836,11 @@ void main() { #endif indirect = indirect * envmapStrength;// * lightColor * lightStrength; float occlusion = g0.b; + indirect = indirect * occlusion; +#ifdef _SSAO float ao = texture(ssaotex, texCoord).r; - indirect = indirect * ao * occlusion; + indirect *= ao; +#endif gl_FragColor = vec4(vec3(direct * visibility + indirect), 1.0); return; } diff --git a/raw/env_map/env_map.frag.glsl b/raw/env_map/env_map.frag.glsl index b4fca889..d68f860c 100644 --- a/raw/env_map/env_map.frag.glsl +++ b/raw/env_map/env_map.frag.glsl @@ -27,7 +27,7 @@ precision mediump float; uniform float time; uniform vec3 eye; const float difference = cloudsUpper - cloudsLower; - const float steps = 60.0; + const float steps = 45.0; #endif #ifdef _EnvTex uniform sampler2D envmap; @@ -47,14 +47,14 @@ vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) { #endif #ifdef _EnvClouds -float hash(vec3 p) { - p = fract(p * vec3(0.16532, 0.17369, 0.15787)); - p += dot(p.xyz, p.zyx + 19.19); - return fract(p.x * p.y * p.z); -} +// float hash(vec3 p) { + // p = fract(p * vec3(0.16532, 0.17369, 0.15787)); + // p += dot(p.xyz, p.zyx + 19.19); + // return fract(p.x * p.y * p.z); +// } float noise(vec3 x) { - vec3 p = floor(x); - vec3 f = fract(x); + vec3 p = floor(x); + vec3 f = fract(x); f = f * f * (3.0 - 2.0 * f); vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy; vec2 rg = texture(snoise, (uv + 0.5) / 256.0).yx; @@ -86,7 +86,7 @@ vec2 traceCloud(vec3 pos, vec3 dir) { float beg = ((cloudsLower - pos.z) / dir.z); float end = ((cloudsUpper - pos.z) / dir.z); traceP = vec3(pos.x + dir.x * beg, pos.y + dir.y * beg, 0.0); - // beg += hash(traceP) * 150.0; + // beg += hash(traceP) * 150.0; // Noisy vec3 add = dir * ((end - beg) / steps); vec2 shadeSum = vec2(0.0); @@ -135,21 +135,21 @@ vec2 traceCloud(vec3 pos, vec3 dir) { shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; - shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; + // shadeSum = doCloudTrace(add, shadeSum); if (shadeSum.y >= 1.0) return shadeSum; return shadeSum; } // GPU PRO 7 - Real-time Volumetric Cloudscapes @@ -157,7 +157,11 @@ vec3 cloudsColor(vec3 R, vec3 pos, vec3 dir) { vec2 traced = traceCloud(pos, dir); float d = traced.x / 200.0 * traced.y + traced.x / 1500.0 * cloudsSecondary; const float g = cloudsEccentricity; +#ifdef _EnvSky float cosAngle = dot(sunDirection, dir); +#else // Predefined sun direction + float cosAngle = dot(vec3(0.0, -1.0, 0.0), dir); +#endif float E = 2.0 * exp(-d * cloudsPrecipitation) * (1.0 - exp(-2.0 * d)) * (0.25 * PI) * ((1.0 - g * g) / pow(1.0 + g * g - 2.0 * g * cosAngle, 3.0 / 2.0)); return mix(vec3(R), vec3(E * 24.0), d * 12.0); } @@ -167,7 +171,7 @@ vec3 cloudsColor(vec3 R, vec3 pos, vec3 dir) { vec2 envMapEquirect(vec3 normal) { float phi = acos(normal.z); float theta = atan(-normal.y, normal.x) + PI; - return vec2(theta / TwoPI, phi / PI); + return vec2(theta / PI2, phi / PI); } #endif @@ -177,18 +181,19 @@ void main() { } #ifdef _EnvCol - gl_FragColor = vec4(backgroundCol, 1.0); - return; -#else + vec3 R = backgroundCol; +#ifdef _EnvClouds vec3 n = normalize(normal); #endif +#endif #ifdef _EnvTex - gl_FragColor = texture(envmap, envMapEquirect(n)) * envmapStrength; - return; + vec3 n = normalize(normal); + vec3 R = texture(envmap, envMapEquirect(n)).rgb * envmapStrength; #endif #ifdef _EnvSky + vec3 n = normalize(normal); vec3 sunDir = vec3(sunDirection.x, -sunDirection.y, sunDirection.z); float phi = acos(n.z); float theta = atan(-n.y, n.x) + PI; @@ -201,12 +206,10 @@ void main() { #ifndef LDR R = pow(R, vec3(2.2)); #endif +#endif #ifdef _EnvClouds if (n.z > 0.0) R = mix(R, cloudsColor(R, eye, n), n.z * 5.0); #endif - - gl_FragColor = vec4(R, 1.0); - return; -#endif + gl_FragColor = vec4(R, 1.0); } diff --git a/raw/forward/forward.frag.glsl b/raw/forward/forward.frag.glsl index 8dd9053e..ddc30d0c 100644 --- a/raw/forward/forward.frag.glsl +++ b/raw/forward/forward.frag.glsl @@ -4,9 +4,7 @@ precision mediump float; #endif -const float PI = 3.1415926535; -const float TwoPI = (2.0 * PI); -const vec2 shadowMapSize = vec2(2048, 2048); +#include "../compiled.glsl" // #ifdef _NMTex // #define _Tex @@ -15,7 +13,9 @@ const vec2 shadowMapSize = vec2(2048, 2048); #ifdef _AMTex uniform sampler2D salbedo; #endif -uniform sampler2D shadowMap; +#ifndef _NoShadows + uniform sampler2D shadowMap; +#endif uniform float shirr[27]; #ifdef _Rad uniform sampler2D senvmapRadiance; @@ -88,10 +88,10 @@ in vec3 eyeDir; in vec3 normal; #endif +#ifndef _NoShadows // float linstep(float low, float high, float v) { // return clamp((v - low) / (high - low), 0.0, 1.0); // } - // float VSM(vec2 uv, float compare) { // vec2 moments = texture(shadowMap, uv).xy; // float p = smoothstep(compare - 0.02, compare, moments.x); @@ -100,12 +100,10 @@ in vec3 eyeDir; // float p_max = linstep(0.2, 1.0, variance / (variance + d * d)); // return clamp(max(p, p_max), 0.0, 1.0); // } - float texture2DCompare(vec2 uv, float compare){ float depth = texture(shadowMap, uv).r * 2.0 - 1.0; return step(compare, depth); } - float texture2DShadowLerp(vec2 size, vec2 uv, float compare){ vec2 texelSize = vec2(1.0) / size; vec2 f = fract(uv * size + 0.5); @@ -120,60 +118,47 @@ float texture2DShadowLerp(vec2 size, vec2 uv, float compare){ float c = mix(a, b, f.x); return c; } - float PCF(vec2 uv, float compare) { float result = 0.0; // for (int x = -1; x <= 1; x++){ // for(int y = -1; y <= 1; y++){ - // vec2 off = vec2(x, y) / shadowMapSize; - // result += texture2DShadowLerp(shadowMapSize, uv + off, compare); + // vec2 off = vec2(x, y) / shadowmapSize; + // result += texture2DShadowLerp(shadowmapSize, uv + off, compare); - vec2 off = vec2(-1, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(-1, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(-1, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(0, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, -1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, 0) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); - off = vec2(1, 1) / shadowMapSize; - result += texture2DShadowLerp(shadowMapSize, uv + off, compare); + vec2 off = vec2(-1, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(-1, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(-1, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(0, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, -1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, 0) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); + off = vec2(1, 1) / shadowmapSize; + result += texture2DShadowLerp(shadowmapSize, uv + off, compare); // } // } return result / 9.0; } - float shadowTest(vec4 lPos) { vec4 lPosH = lPos / lPos.w; lPosH.x = (lPosH.x + 1.0) / 2.0; lPosH.y = (lPosH.y + 1.0) / 2.0; - - // const float bias = 0.00015; // Persp - const float bias = 0.0023; // Persp - // const float bias = 0.01; // Ortho -// #ifdef _PCSS - // return PCSS(lPosH.xy, lPosH.z - bias); -// #else - // return PCF(lPosH.xy, lPosH.z - bias); -// #endif + return PCF(lPosH.xy, lPosH.z - shadowsBias); // return VSM(lPosH.xy, lPosH.z); - - // shadow2DSampler - // return texture(shadowMap, vec3(lPosH.xy, (lPosH.z - 0.005) / lPosH.w)); - // Basic - float distanceFromLight = texture(shadowMap, lPosH.xy).r * 2.0 - 1.0; - return float(distanceFromLight > lPosH.z - bias); + // float distanceFromLight = texture(shadowMap, lPosH.xy).r * 2.0 - 1.0; + // return float(distanceFromLight > lPosH.z - bias); } +#endif vec3 shIrradiance(vec3 nor, float scale) { const float c1 = 0.429043; @@ -208,7 +193,7 @@ vec3 shIrradiance(vec3 nor, float scale) { vec2 envMapEquirect(vec3 normal) { float phi = acos(normal.z); float theta = atan(-normal.y, normal.x) + PI; - return vec2(theta / TwoPI, phi / PI); + return vec2(theta / PI2, phi / PI); } @@ -525,13 +510,13 @@ void main() { float dotNL = max(dot(n, l), 0.0); float visibility = 1.0; +#ifdef _NoShadows if (receiveShadow) { if (lPos.w > 0.0) { visibility = shadowTest(lPos); - // visibility = 1.0; } } - +#endif vec3 baseColor = matColor.rgb; #ifdef _AMTex diff --git a/raw/ssao_pass/ssao_pass.frag.glsl b/raw/ssao_pass/ssao_pass.frag.glsl index aea9fa65..40c7e6e2 100644 --- a/raw/ssao_pass/ssao_pass.frag.glsl +++ b/raw/ssao_pass/ssao_pass.frag.glsl @@ -17,6 +17,8 @@ precision mediump float; #endif +#include "../compiled.glsl" + uniform sampler2D gbufferD; uniform sampler2D gbuffer0; uniform sampler2D snoise; @@ -26,10 +28,9 @@ uniform vec3 eye; uniform vec2 screenSize; uniform vec2 aspectRatio; -const float PI = 3.1415926535; const int kernelSize = 20;//12; -const float aoSize = 0.12; -const float strength = 0.55;//0.7; +// const float ssaoSize = 0.12; +// const float ssaoStrength = 0.55; in vec2 texCoord; @@ -49,7 +50,7 @@ vec3 getPos(float depth, vec2 coord) { float doAO(vec2 kernelVec, vec2 randomVec, mat2 rotMat, vec3 currentPos, vec3 currentNormal, float currentDistance) { kernelVec.xy *= aspectRatio; - float radius = aoSize * randomVec.y; + float radius = ssaoSize * randomVec.y; kernelVec.xy = ((rotMat * kernelVec.xy) / currentDistance) * radius; vec2 coord = texCoord + kernelVec.xy; // float depth = 1.0 - texture(gbuffer0, coord).a; @@ -147,7 +148,7 @@ void main() { amount += doAO(kernel[19], randomVec, rotMat, currentPos, currentNormal, currentDistance); // } - amount *= strength / kernelSize; + amount *= ssaoStrength / kernelSize; amount = 1.0 - amount; amount = max(0.0, amount); gl_FragColor = vec4(vec3(amount), 1.0); diff --git a/raw/water_pass/water_pass.frag.glsl b/raw/water_pass/water_pass.frag.glsl index 876ef392..e8a912de 100644 --- a/raw/water_pass/water_pass.frag.glsl +++ b/raw/water_pass/water_pass.frag.glsl @@ -11,10 +11,11 @@ precision mediump float; #include "../compiled.glsl" -uniform sampler2D gbufferD; -uniform sampler2D gbuffer0; uniform sampler2D tex; -uniform sampler2D senvmapRadiance; +uniform sampler2D gbufferD; +// uniform sampler2D gbuffer0; +// uniform sampler2D senvmapRadiance; +// uniform sampler2D snoise; uniform float time; uniform vec3 eye; @@ -23,121 +24,123 @@ uniform vec3 light; in vec2 texCoord; in vec3 viewRay; +in vec3 vecnormal; -const float timeScale = 1000.0; -const float waterLevel = 0.0; -const float fadeSpeed = 0.15; -const float maxAmplitude = 2.5; -const vec3 sunColor = vec3(1.0, 1.0, 1.0); -const float shoreHardness = 1.0; -const float refractionStrength = 0.0; -const vec3 foamExistence = vec3(0.65, 1.35, 0.5); -const float sunScale = 3.0; -const float shininess = 0.7; -const float specular_intensity = 0.32; -const vec3 depthColour = vec3(0.0078, 0.5176, 0.9); -const vec3 bigDepthColour = vec3(0.0039, 0.00196, 0.345); -const vec3 extinction = vec3(7.0, 30.0, 40.0); // Horizontal -const float visibility = 2.0; -const vec2 scale = vec2(0.005, 0.005); -const float refractionScale = 0.005; -const vec2 wind = vec2(-0.3, 0.7); +// const float seaLevel = 0.0; +// const float seaMaxAmplitude = 2.5; +// const float seaHeight = 0.6; +// const float seaChoppy = 4.0; +// const float seaSpeed = 1.0; +// const float seaFreq = 0.16; +// const vec3 seaBaseColor = vec3(0.1, 0.19, 0.37); +// const vec3 seaWaterColor = vec3(0.6, 0.7, 0.9); +const mat2 octavem = mat2(1.6, 1.2, -1.2, 1.6); +// const float fadeSpeed = 0.15; +// const vec3 sunColor = vec3(1.0, 1.0, 1.0); +// const float shoreHardness = 1.0; +// const vec3 foamExistence = vec3(0.65, 1.35, 0.5); +// const float shininess = 0.7; +// const vec3 depthColour = vec3(0.0078, 0.5176, 0.9); +// const vec3 bigDepthColour = vec3(0.0039, 0.00196, 0.345); +// const vec3 extinction = vec3(7.0, 30.0, 40.0); // Horizontal +// const float visibility = 2.0; +// const float refractionScale = 0.005; +// const vec2 wind = vec2(-0.3, 0.7); -const float SEA_HEIGHT = 0.6; -const float SEA_CHOPPY = 4.0; -const float SEA_SPEED = 1.0; -const float SEA_FREQ = 0.16; -// const vec3 SEA_BASE = vec3(0.1,0.19,0.22); -const vec3 SEA_BASE = vec3(0.1,0.19,0.37); -// const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6); -const vec3 SEA_WATER_COLOR = vec3(0.6,0.7,0.9); -const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6); +// vec2 envMapEquirect(vec3 normal) { + // float phi = acos(normal.z); + // float theta = atan(-normal.y, normal.x) + PI; + // return vec2(theta / PI2, phi / PI); +// } -vec2 envMapEquirect(vec3 normal) { - float phi = acos(normal.z); - float theta = atan(-normal.y, normal.x) + PI; - return vec2(theta / PI2, phi / PI); +float hash(vec2 p) { + float h = dot(p, vec2(127.1, 311.7)); + return fract(sin(h) * 43758.5453123); } - -float hash( vec2 p ) { - float h = dot(p,vec2(127.1,311.7)); - return fract(sin(h)*43758.5453123); -} -float noise( vec2 p ) { - vec2 i = floor( p ); - vec2 f = fract( p ); - vec2 u = f*f*(3.0-2.0*f); - return -1.0+2.0*mix( - mix( hash( i + vec2(0.0,0.0) ), - hash( i + vec2(1.0,0.0) ), u.x), - mix( hash( i + vec2(0.0,1.0) ), - hash( i + vec2(1.0,1.0) ), u.x), u.y); +float noise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + vec2 u = f * f * (3.0 - 2.0 * f); + return -1.0 + 2.0 * mix( + mix(hash(i + vec2(0.0, 0.0)), + hash(i + vec2(1.0, 0.0)), u.x), + mix(hash(i + vec2(0.0, 1.0)), + hash(i + vec2(1.0, 1.0)), u.x), u.y); } +// float noise(vec2 xx) { +// vec3 x = vec3(xx.x * 1.9 + vecnormal.x / 10.0, xx.y * 2.4, time / 1000.0); +// vec3 p = floor(x); +// vec3 f = fract(x); +// f = f * f * (3.0 - 2.0 * f); +// vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy; +// vec2 rg = texture(snoise, (uv + 0.5) / 256.0).yx; +// return mix(rg.x, rg.y, f.z); +// } float sea_octave(vec2 uv, float choppy) { uv += noise(uv); - vec2 wv = 1.0-abs(sin(uv)); + vec2 wv = 1.0 - abs(sin(uv)); vec2 swv = abs(cos(uv)); - wv = mix(wv,swv,wv); - return pow(1.0-pow(wv.x * wv.y,0.65),choppy); + wv = mix(wv, swv, wv); + return pow(1.0 - pow(wv.x * wv.y, 0.65), choppy); } float map(vec3 p) { - float freq = SEA_FREQ; - float amp = SEA_HEIGHT; - float choppy = SEA_CHOPPY; + float freq = seaFreq; + float amp = seaHeight; + float choppy = seaChoppy; vec2 uv = p.xy; uv.x *= 0.75; float d, h = 0.0; // for(int i = 0; i < 2; i++) { - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + d = sea_octave((uv + (time * seaSpeed)) * freq, choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq, choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); // - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + d = sea_octave((uv + (time * seaSpeed)) * freq, choppy); + d += sea_octave((uv-(time * seaSpeed)) * freq, choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); // // } return p.z - h; } float map_detailed(vec3 p) { - float freq = SEA_FREQ; - float amp = SEA_HEIGHT; - float choppy = SEA_CHOPPY; + float freq = seaFreq; + float amp = seaHeight; + float choppy = seaChoppy; vec2 uv = p.xy; uv.x *= 0.75; float d, h = 0.0; // for(int i = 0; i < 4; i++) { - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + d = sea_octave((uv + (time * seaSpeed)) * freq,choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq,choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); // - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + d = sea_octave((uv + (time * seaSpeed)) * freq,choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq,choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + d = sea_octave((uv + (time * seaSpeed)) * freq,choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq,choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + d = sea_octave((uv + (time * seaSpeed)) * freq,choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq,choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); - d = sea_octave((uv+(time * SEA_SPEED))*freq,choppy); - d += sea_octave((uv-(time * SEA_SPEED))*freq,choppy); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + d = sea_octave((uv + (time * seaSpeed)) * freq,choppy); + d += sea_octave((uv - (time * seaSpeed)) * freq,choppy); h += d * amp; - uv *= octave_m; freq *= 1.9; amp *= 0.22; - choppy = mix(choppy,1.0,0.2); + uv *= octavem; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); // } return p.z - h; } @@ -158,54 +161,59 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) { float hm = map_detailed(ori + dir * tm); float tmid = 0.0; // for(int i = 0; i < 5; i++) { - tmid = mix(tm,tx, hm/(hm-hx)); + tmid = mix(tm, tx, hm / (hm - hx)); p = ori + dir * tmid; float hmid = map_detailed(p); - if(hmid < 0.0) { + if (hmid < 0.0) { tx = tmid; hx = hmid; - } else { + } + else { tm = tmid; hm = hmid; } // - tmid = mix(tm,tx, hm/(hm-hx)); + tmid = mix(tm, tx, hm / (hm - hx)); p = ori + dir * tmid; hmid = map_detailed(p); - if(hmid < 0.0) { + if (hmid < 0.0) { tx = tmid; hx = hmid; - } else { + } + else { tm = tmid; hm = hmid; } - tmid = mix(tm,tx, hm/(hm-hx)); + tmid = mix(tm, tx, hm / (hm - hx)); p = ori + dir * tmid; hmid = map_detailed(p); - if(hmid < 0.0) { + if (hmid < 0.0) { tx = tmid; hx = hmid; - } else { + } + else { tm = tmid; hm = hmid; } - tmid = mix(tm,tx, hm/(hm-hx)); + tmid = mix(tm, tx, hm / (hm - hx)); p = ori + dir * tmid; hmid = map_detailed(p); - if(hmid < 0.0) { + if (hmid < 0.0) { tx = tmid; hx = hmid; - } else { + } + else { tm = tmid; hm = hmid; } - tmid = mix(tm,tx, hm/(hm-hx)); + tmid = mix(tm, tx, hm / (hm - hx)); p = ori + dir * tmid; hmid = map_detailed(p); - if(hmid < 0.0) { + if (hmid < 0.0) { tx = tmid; hx = hmid; - } else { + } + else { tm = tmid; hm = hmid; } @@ -213,35 +221,30 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) { return p; } vec3 getSkyColor(vec3 e) { - e.z = max(e.z,0.0); + e.z = max(e.z, 0.0); vec3 ret; - ret.x = pow(1.0-e.z,2.0); - ret.z = 1.0-e.z; - ret.y = 0.6+(1.0-e.z)*0.4; + ret.x = pow(1.0 - e.z, 2.0); + ret.z = 1.0 - e.z; + ret.y = 0.6 + (1.0 - e.z) * 0.4; return ret; } -float diffuse(vec3 n,vec3 l,float p) { - return pow(dot(n,l) * 0.4 + 0.6,p); +float diffuse(vec3 n, vec3 l, float p) { + return pow(dot(n, l) * 0.4 + 0.6, p); } float specular(vec3 n,vec3 l,vec3 e,float s) { float nrm = (s + 8.0) / (3.1415 * 8.0); - return pow(max(dot(reflect(e,n),l),0.0),s) * nrm; + return pow(max(dot(reflect(e, n), l), 0.0), s) * nrm; } vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) { - float fresnel = 1.0 - max(dot(n,-eye),0.0); - fresnel = pow(fresnel,3.0) * 0.65; - - vec3 reflected = getSkyColor(reflect(eye,n)); + float fresnel = 1.0 - max(dot(n, -eye), 0.0); + fresnel = pow(fresnel, 3.0) * 0.65; + vec3 reflected = getSkyColor(reflect(eye, n)); // vec3 reflected = textureLod(senvmapRadiance, envMapEquirect(reflect(eye,n)), 1.0).rgb; - vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12; - - vec3 color = mix(refracted,reflected,fresnel); - + vec3 refracted = seaBaseColor + diffuse(n, l, 80.0) * seaWaterColor * 0.12; + vec3 color = mix(refracted, reflected, fresnel); float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0); - color += SEA_WATER_COLOR * (p.z - SEA_HEIGHT) * 0.18 * atten; - - color += vec3(specular(n,l,eye,60.0)); - + color += seaWaterColor * (p.z - seaHeight) * 0.18 * atten; + color += vec3(specular(n, l, eye, 60.0)); return color; } @@ -271,9 +274,9 @@ vec3 getPos(float depth) { return wposition; } -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)); -} +// 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 getNormal(vec2 tc) { // vec2 enc = texture(gbuffer0, tc).rg; @@ -285,140 +288,133 @@ vec2 octahedronWrap(vec2 v) { // } vec3 caustic(vec2 uv) { - vec2 p = mod(uv*PI2, PI2)-250.0; - float loctime = time * .5+23.0; - + vec2 p = mod(uv * PI2, PI2) - 250.0; + float loctime = time * 0.5 + 23.0; vec2 i = vec2(p); float c = 1.0; - float inten = .005; - + float inten = 0.005; // for (int n = 0; n < MAX_ITER; n++) { - float t = loctime * (1.0 - (3.5 / float(0+1))); + float t = loctime * (1.0 - (3.5 / float(0 + 1))); i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x)); - c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten))); + c += 1.0 / length(vec2(p.x / (sin(i.x + t) / inten), p.y / (cos(i.y + t) / inten))); - t = loctime * (1.0 - (3.5 / float(0+1))); + t = loctime * (1.0 - (3.5 / float(1 + 1))); //0 + 1 i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x)); - c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten))); + c += 1.0 / length(vec2(p.x / (sin(i.x + t) / inten), p.y / (cos(i.y + t) / inten))); - t = loctime * (1.0 - (3.5 / float(0+1))); + t = loctime * (1.0 - (3.5 / float(2 + 1))); i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x)); - c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten))); + c += 1.0 / length(vec2(p.x / (sin(i.x + t) / inten), p.y / (cos(i.y + t) / inten))); - t = loctime * (1.0 - (3.5 / float(0+1))); + t = loctime * (1.0 - (3.5 / float(3 + 1))); i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x)); - c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten))); + c += 1.0 / length(vec2(p.x / (sin(i.x + t) / inten), p.y / (cos(i.y + t) / inten))); // } - c /= float(4); - c = 1.17-pow(c, 1.4); + c /= 4.0; + c = 1.17 - pow(c, 1.4); vec3 color = vec3(pow(abs(c), 8.0)); color = clamp(color + vec3(0.0, 0.35, 0.5), 0.0, 1.0); - color = mix(color, vec3(1.0,1.0,1.0),0.3); + color = mix(color, vec3(1.0), 0.3); return color; } -float causticX(float x, float power, float gtime) -{ - float p = mod(x*PI2, PI2)-250.0; - float time = gtime * .5+23.0; - +float causticX(float x, float power, float gtime) { + float p = mod(x * PI2, PI2) - 250.0; + float time = gtime * 0.5 + 23.0; float i = p; float c = 1.0; - float inten = .005; - + float inten = 0.005; // for (int n = 0; n < MAX_ITER/2; n++) { float t = time * (1.0 - (3.5 / float(0+1))); i = p + cos(t - i) + sin(t + i); - c += 1.0/length(p / (sin(i+t)/inten)); + c += 1.0 / length(p / (sin(i + t) / inten)); t = time * (1.0 - (3.5 / float(1+1))); i = p + cos(t - i) + sin(t + i); - c += 1.0/length(p / (sin(i+t)/inten)); + c += 1.0 / length(p / (sin(i + t) / inten)); // } - c /= float(4); - c = 1.17-pow(c, power); - + c /= 4.0; + c = 1.17 - pow(c, power); return c; } float godRays(vec2 uv) { float light = 0.0; - light += pow(causticX((uv.x+0.08*uv.y)/1.7+0.5, 1.8, time*0.65),10.0)*0.05; - light -= pow((1.0-uv.y)*0.3,2.0)*0.2; - light += pow(causticX(sin(uv.x), 0.3,time*0.7),9.0)*0.4; - light += pow(causticX(cos(uv.x*2.3), 0.3,time*1.3),4.0)*0.1; - light -= pow((1.0-uv.y)*0.3,3.0); - light = clamp(light,0.0,1.0); + light += pow(causticX((uv.x + 0.08 * uv.y) / 1.7 + 0.5, 1.8, time * 0.65), 10.0) * 0.05; + light -= pow((1.0 - uv.y) * 0.3, 2.0) * 0.2; + light += pow(causticX(sin(uv.x), 0.3, time * 0.7), 9.0) * 0.4; + light += pow(causticX(cos(uv.x * 2.3), 0.3, time * 1.3), 4.0) * 0.1; + light -= pow((1.0 - uv.y) * 0.3, 3.0); + light = clamp(light, 0.0, 1.0); return light; } void main() { - // vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, mask - // float gdepth = 1.0 - g0.a; float gdepth = texture(gbufferD, texCoord).r * 2.0 - 1.0; vec4 colorOriginal = texture(tex, texCoord); - if (gdepth == 0.0) { // if (gdepth == 1.0) { - gl_FragColor = colorOriginal; - return; - } + // gl_FragColor = colorOriginal; + // return; + // } vec3 color = colorOriginal.rgb; vec3 position = getPos(gdepth); + + // if (position.z > seaLevel) { + // gl_FragColor = colorOriginal; + // return; + // } // Underwater - if (waterLevel >= eye.z) { + if (seaLevel >= eye.z) { float t = length(eye - position); // color *= caustic(vec2(mix(position.x,position.y,0.2),mix(position.z,position.y,0.2))*1.1); - color = mix(colorOriginal.rgb, vec3(0.0, 0.05, 0.2), 1.0 - exp(-0.3 * pow(t,1.0) )); + color = mix(colorOriginal.rgb, vec3(0.0, 0.05, 0.2), 1.0 - exp(-0.3 * pow(t, 1.0))); const float skyColor = 0.8; - color += godRays(texCoord)*mix(skyColor,1.0,texCoord.y*texCoord.y)*vec3(0.7,1.0,1.0); - gl_FragColor = vec4(color, 1.0); + color += godRays(texCoord) * mix(skyColor, 1.0, texCoord.y * texCoord.y) * vec3(0.7, 1.0, 1.0); + gl_FragColor = vec4(color, 1.0); + // gl_FragData[0] = vec4(color, 1.0); return; } - if (position.z <= waterLevel + maxAmplitude) { - // vec3 ld = normalize(vec3(0.0,0.8,1.0)); - vec3 ld = normalize(vec3(0.3,-0.3,1.0)); + if (position.z <= seaLevel + seaMaxAmplitude) { + // vec3 ld = normalize(vec3(0.0, 0.8, 1.0)); + vec3 ld = normalize(vec3(0.3, -0.3, 1.0)); vec3 lightDir = light - position.xyz; vec3 eyeDir = eye - position.xyz; vec3 l = normalize(lightDir); vec3 v = normalize(eyeDir); vec3 surfacePoint = heightMapTracing(eye, -v); + surfacePoint.z += seaLevel; float depth = length(position - surfacePoint); float depthZ = surfacePoint.z - position.z; // float dist = length(surfacePoint - eye); // float epsx = clamp(dot(dist/2.0,dist/2.0) * 0.001, 0.01, 0.1); - float dist = max(0.1, length(surfacePoint - eye) * 1.2); - float epsx = dot(dist,dist) * 0.0001; - // float epsx = dot(dist,dist) * 0.0008; + float epsx = dot(dist,dist) * 0.00005; // Fade in distance to prevent noise vec3 normal = getNormal(surfacePoint, epsx); - // vec3 normal = getNormal(surfacePoint, 0.1); - float fresnel = 1.0 - max(dot(normal,-v),0.0); - fresnel = pow(fresnel,3.0) * 0.65; - + // float fresnel = 1.0 - max(dot(normal,-v),0.0); + // fresnel = pow(fresnel,3.0) * 0.65; // vec2 texco = texCoord.xy; - // texco.x += sin((time * timeScale) * 0.002 + 3.0 * abs(position.z)) * (refractionScale * min(depthZ, 1.0)); + // texco.x += sin((time) * 0.002 + 3.0 * abs(position.z)) * (refractionScale * min(depthZ, 1.0)); // vec3 refraction = texture(tex, texco).rgb; // vec3 _p = getPos(1.0 - texture(gbuffer0, texco).a); - // if (_p.z > waterLevel) { + // if (_p.z > seaLevel) { // refraction = colorOriginal.rgb; // } // vec3 reflect = textureLod(senvmapRadiance, envMapEquirect(reflect(v,normal)), 2.0).rgb; - // vec3 depthN = vec3(depth * fadeSpeed); - // vec3 waterCol = vec3(clamp(length(sunColor) / sunScale, 0.0, 1.0)); + // vec3 waterCol = vec3(clamp(length(sunColor) / 3.0, 0.0, 1.0)); // refraction = mix(mix(refraction, depthColour * waterCol, clamp(depthN / visibility, 0.0, 1.0)), bigDepthColour * waterCol, clamp(depthZ / extinction, 0.0, 1.0)); // float foam = 0.0; - // // texco = (surfacePoint.xy + v.xy * 0.1) * 0.05 + (time * timeScale) * 0.00001 * wind + sin((time * timeScale) * 0.001 + position.x) * 0.005; - // // vec2 texco2 = (surfacePoint.xy + v.xy * 0.1) * 0.05 + (time * timeScale) * 0.00002 * wind + sin((time * timeScale) * 0.001 + position.y) * 0.005; + // // texco = (surfacePoint.xy + v.xy * 0.1) * 0.05 + (time) * 0.00001 * wind + sin((time) * 0.001 + position.x) * 0.005; + // // vec2 texco2 = (surfacePoint.xy + v.xy * 0.1) * 0.05 + (time) * 0.00002 * wind + sin((time) * 0.001 + position.y) * 0.005; // // if (depthZ < foamExistence.x) { // // foam = (texture(fmap, texco).r + texture(fmap, texco2).r) * 0.5; // // } @@ -426,9 +422,9 @@ void main() { // // foam = mix((texture(fmap, texco).r + texture(fmap, texco2).r) * 0.5, 0.0, // // (depthZ - foamExistence.x) / (foamExistence.y - foamExistence.x)); // // } - // // if (maxAmplitude - foamExistence.z > 0.0001) { + // // if (seaMaxAmplitude - foamExistence.z > 0.0001) { // // foam += (texture(fmap, texco).r + texture(fmap, texco2).r) * 0.5 * - // // clamp((waterLevel - (waterLevel + foamExistence.z)) / (maxAmplitude - foamExistence.z), 0.0, 1.0); + // // clamp((seaLevel - (seaLevel + foamExistence.z)) / (seaMaxAmplitude - foamExistence.z), 0.0, 1.0); // // } // vec3 mirrorEye = (2.0 * dot(v, normal) * normal - v); @@ -438,16 +434,16 @@ void main() { // color = mix(refraction, reflect, fresnel); // color = clamp(color + max(specular, foam * sunColor), 0.0, 1.0); // color = mix(refraction, color, clamp(depth * shoreHardness, 0.0, 1.0)); - - color = getSeaColor(surfacePoint,normal,ld,-v,surfacePoint-eye); + + color = getSeaColor(surfacePoint, normal, ld, -v, surfacePoint - eye); // color = pow(color, vec3(2.2)); color = mix(colorOriginal.rgb, color, clamp(depthZ * 1.8, 0.0, 1.0)); + + // Fade on horizon + vec3 vecn = normalize(vecnormal); + color = mix(color, colorOriginal.rgb, clamp((vecn.z + 0.03) * 10.0, 0.0, 1.0)); } - - // if (position.z > waterLevel) { - // color = colorOriginal.rgb; - // } gl_FragColor.rgb = color; - + // gl_FragData[0].rgb = color; } diff --git a/raw/water_pass/water_pass.shader.json b/raw/water_pass/water_pass.shader.json index 034e0bba..4bd7067e 100755 --- a/raw/water_pass/water_pass.shader.json +++ b/raw/water_pass/water_pass.shader.json @@ -17,6 +17,14 @@ } ], "links": [ + { + "id": "transpV", + "link": "_transposeViewMatrix" + }, + { + "id": "invP", + "link": "_inverseProjectionMatrix" + }, { "id": "eye", "link": "_cameraPosition" @@ -36,10 +44,6 @@ { "id": "time", "link": "_time" - }, - { - "id": "senvmapRadiance", - "link": "_envmapRadiance" } ], "texture_params": [], diff --git a/raw/water_pass/water_pass.vert.glsl b/raw/water_pass/water_pass.vert.glsl index 9775669e..08b1bbe0 100644 --- a/raw/water_pass/water_pass.vert.glsl +++ b/raw/water_pass/water_pass.vert.glsl @@ -4,6 +4,8 @@ precision highp float; #endif +uniform mat4 transpV; +uniform mat4 invP; uniform mat4 invVP; uniform vec3 eye; @@ -11,6 +13,7 @@ in vec2 pos; out vec2 texCoord; out vec3 viewRay; +out vec3 vecnormal; const vec2 madd = vec2(0.5, 0.5); @@ -19,6 +22,10 @@ void main() { texCoord = pos.xy * madd + madd; gl_Position = vec4(pos.xy, 0.0, 1.0); + + vec4 p = vec4(pos.xy, 0.0, 1.0); + vec3 unprojected = (invP * p).xyz; + vecnormal = mat3(transpV) * unprojected; // NDC (at the back of cube) vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);