Expose more shader constants.

This commit is contained in:
Lubos Lenco 2016-07-17 20:29:53 +02:00
parent 42516a7566
commit cf8f7186da
17 changed files with 945 additions and 610 deletions

View file

@ -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();
}
}

View file

@ -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)

View file

@ -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')

View file

@ -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'

View file

@ -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[:]

View file

@ -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():

View file

@ -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):

View file

@ -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):

View file

@ -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())

View file

@ -145,6 +145,7 @@ void main() {
#ifdef _VCols
matColor *= col;
// matColor *= pow(col, vec3(2.2));
#endif
mvpposition = gl_Position;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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": [],

View file

@ -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);