Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fast OCean - Eevee Branch
# -*- coding: utf-8 -*-
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
"name": "Fast Ocean",
"author": "Laurent Laget",
"version": (0, 9,5),
"blender": (2, 78, 0),
"location": "Add > Mesh",
"description": "Create a dynamic ocean and turn any object easily into a collider",
"warning": "",
"wiki_url": "",
"category": "Add Mesh",
}
import bpy
def main(context):
for ob in context.scene.objects:
print(ob)
#classe fastocean
class fastocean(bpy.types.Operator):
"""Create a dynamic ocean"""
bl_idname = "object.fastocean"
bl_label = "fastocean"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
#Create light probe for irradiance optionnal
bpy.ops.object.lightprobe_add(type='GRID')
bpy.ops.transform.resize(value=(30, 30, 30), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
bpy.context.object.name = "Irradiance probe"
#create reflection probe optionnal
bpy.ops.object.lightprobe_add(type='SPHERE', view_align=False, enter_editmode=False, location=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
#ground creation
bpy.ops.mesh.primitive_plane_add(radius=30, view_align=False, enter_editmode=False, location=(0, 0, -25), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
bpy.context.object.name = "Ground"
bpy.ops.transform.resize(value=(2, 2, 2), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
#creation water plane
bpy.ops.mesh.primitive_plane_add()
#name and creation modifier ocean
bpy.context.object.name = "Ocean"
bpy.ops.object.modifier_add(type='OCEAN')
#setup modifier ocean
bpy.context.object.modifiers["Ocean"].repeat_x = 1
bpy.context.object.modifiers["Ocean"].repeat_y = 1
bpy.context.object.modifiers["Ocean"].resolution = 12
bpy.context.object.modifiers["Ocean"].wave_scale = 2
bpy.context.object.modifiers["Ocean"].use_normals = True
bpy.context.object.modifiers["Ocean"].use_foam = True
bpy.context.object.modifiers["Ocean"].foam_layer_name = "foam_layer"
obj = bpy.context.active_object
#creation material
mat_name = "M_ocean"
materials = bpy.data.materials
mat = materials.get(mat_name) or materials.new(mat_name)
if mat is None:
mat = bpy.data.materials.new(name="M_ocean")
if obj.data.materials:
obj.data.materials[0] = mat
else:
obj.data.materials.append(mat)
###creation shader###
mat.use_nodes = True
nodes = mat.node_tree.nodes
mat = materials.get(mat_name) or materials.new(mat_name)
for node in nodes:
nodes.remove(node)
#node blue water
water_node = nodes.new('ShaderNodeBsdfPrincipled')
water_node.location = (80,50)
#water_node.inputs[0].default_value = (0.11,0.44,0.8,1)
water_node.inputs[4].default_value = (0.465)
water_node.inputs[5].default_value = (0.091)
water_node.inputs[7].default_value = (0.200)
water_node.inputs[14].default_value = (1.33)
water_node.inputs[15].default_value = (0.9)
water_node.label = ('Eevee BSDF')
#emission shader to mix with principled
emission_node = nodes.new('ShaderNodeEmission')
emission_node.inputs[1].default_value = (1.5)
emission_node.location = (80,700)
#mix node 3 to mix principled with emission
mix_node_emission = nodes.new('ShaderNodeMixShader')
mix_node_emission.location = (250,600)
mix_node_emission.label = ('Mix Node Emission')
### nodes for foam, attribute and noise
#foam attribute for both shaders
foam_node = nodes.new('ShaderNodeAttribute')
foam_node.location = (-450,300)
foam_node.attribute_name = ('foam_layer')
foam_node.label = ('Foam Attribute')
### nodes for water, bump and volume
#texture noise for bump
noise_node = nodes.new('ShaderNodeTexNoise')
noise_node.inputs[1].default_value = (5)
noise_node.location = (-700,50)
#gradient water
gradient_water_node = nodes.new(type='ShaderNodeValToRGB')
gradient_water_node.location = (-530,50)
gradient_water_node.color_ramp.elements[0].color = (1, 1, 1, 1)
gradient_water_node.color_ramp.elements[1].color = (0, 0, 0, 1)
#vector bump node
bump_water_node = nodes.new('ShaderNodeBump')
bump_water_node.location = (-250,50)
#mix foam with blue color
mix_node_foam = nodes.new('ShaderNodeMixRGB')
mix_node_foam.inputs[2].default_value = (0, 0.494436, 0.5, 1)
mix_node_foam.location = (-270,300)
#mix foam with blue color 2
mix_node_foam2 = nodes.new('ShaderNodeMixRGB')
mix_node_foam2.inputs[2].default_value = (0.218349, 0.545644, 0.8, 1)
mix_node_foam2.location = (-100,300)
#node output
node_output = nodes.new(type='ShaderNodeOutputMaterial')
node_output.location = 600,100
node_output.label = ('Output Eevee')
###creation of links###
### Links for water ###
#link main shader to output
mat.node_tree.links.new(mix_node_emission.outputs[0], node_output.inputs['Surface'])
#link foam paint attribute to first mix
mat.node_tree.links.new(foam_node.outputs[0], mix_node_foam.inputs[1])
#link foam paint attribute to second mix
mat.node_tree.links.new(foam_node.outputs[0], mix_node_foam2.inputs[0])
#link foam attribute to emission slot of main shader
#mat.node_tree.links.new(foam_node.outputs[0], water_node.inputs[4])
#link foam attribute to emission shader
mat.node_tree.links.new(foam_node.outputs[0], emission_node .inputs[0])
#link foam attribute to mix factor shader
mat.node_tree.links.new(foam_node.outputs[0], mix_node_emission.inputs[0])
#link first mix to second mix
mat.node_tree.links.new(mix_node_foam.outputs[0], mix_node_foam2.inputs[1])
#link second mix to color of main shader
mat.node_tree.links.new(mix_node_foam2.outputs[0], water_node.inputs[0])
#emission to mix shader 3
mat.node_tree.links.new(emission_node.outputs[0], mix_node_emission.inputs[2])
#link principled to mix shader 3
mat.node_tree.links.new(water_node.outputs['BSDF'], mix_node_emission.inputs[1])
#link noise to color ramp
mat.node_tree.links.new(noise_node.outputs[0], gradient_water_node.inputs[0])
#link color ramp to vector bump
mat.node_tree.links.new(gradient_water_node.outputs[0], bump_water_node.inputs[2])
#link vector bump to main shader
mat.node_tree.links.new(bump_water_node.outputs[0], water_node.inputs[17])
bpy.context.object.active_material.blend_method = 'BLEND'
###apply dynamic paint and setup the ocean as a canvas###
bpy.ops.object.modifier_add(type='DYNAMIC_PAINT')
bpy.ops.dpaint.type_toggle(type='CANVAS')
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["Surface"].preview_id = 'WETMAP'
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["Surface"].use_dissolve = True
bpy.ops.dpaint.output_toggle(output='A')
bpy.ops.dpaint.output_toggle(output='B')
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["Surface"].use_antialiasing = True
###apply a second layer of dynamic paint with a wave effect###
bpy.ops.dpaint.surface_slot_add()
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["Surface.001"].name = "onde"
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["onde"].surface_type = 'WAVE'
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["onde"].use_antialiasing = True
bpy.context.object.modifiers["Dynamic Paint"].canvas_settings.canvas_surfaces["onde"].use_wave_open_border = True
return {'FINISHED'}
#classe collider_ocean
class collider_ocean(bpy.types.Operator):
"""Transform the selected object easily into a collider"""
bl_idname = "object.collider_ocean"
bl_label = "collider_ocean"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
#apply dynamic paint, and setup the object as a brush
bpy.ops.object.modifier_add(type='DYNAMIC_PAINT')
bpy.context.object.modifiers["Dynamic Paint"].ui_type = 'BRUSH'
bpy.ops.dpaint.type_toggle(type='BRUSH')
bpy.context.object.modifiers["Dynamic Paint"].brush_settings.paint_source = 'VOLUME_DISTANCE'
bpy.context.object.modifiers["Dynamic Paint"].brush_settings.paint_distance = 4
bpy.context.object.modifiers["Dynamic Paint"].brush_settings.wave_factor = 2
return {'FINISHED'}
def menu_item(self, context):
self.layout.operator(fastocean.bl_idname, text="fast ocean", icon="PLUGIN")
self.layout.operator(collider_ocean.bl_idname, text="Make object collide with ocean", icon="PLUGIN")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_mesh_add.append(menu_item)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_mesh_add.remove(menu_item)
if __name__ == "__main__":
register()
@JohnRWMarchant

This comment has been minimized.

Copy link

commented Aug 15, 2019

I hope we can get an update for Blender 2.8, i get an error when loading it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.