Skip to content

Instantly share code, notes, and snippets.

@ethanaeris
Created March 17, 2018 13:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ethanaeris/6bd114d1e53c08a15b2201c0fbebbf16 to your computer and use it in GitHub Desktop.
Save ethanaeris/6bd114d1e53c08a15b2201c0fbebbf16 to your computer and use it in GitHub Desktop.
Fast Terrain . Terrain plugin for Blender
# -*- 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 terrain",
"author": "Laurent Laget",
"version": (0, 3),
"blender": (2, 78, 0),
"location": "Add > Mesh",
"description": "Create a terrain",
"warning": "",
"wiki_url": "",
"category": "Add Mesh",
}
import bpy
def main(context):
for ob in context.scene.objects:
print(ob)
#classe fastterrain
class fastterrain(bpy.types.Operator):
"""description"""
bl_idname = "object.fastterrain"
bl_label = "fastterrain"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
#Set cycles
bpy.context.scene.render.engine = 'CYCLES'
#creation plane
bpy.ops.mesh.primitive_plane_add(radius=1, 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))
#initial subdivision
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.subdivide(number_cuts=10, smoothness=0)
bpy.ops.object.editmode_toggle()
bpy.ops.object.shade_smooth()
#creation modifier terrain
bpy.ops.object.modifier_add(type='MULTIRES')
bpy.context.object.modifiers["Multires"].subdivision_type = 'SIMPLE'
bpy.ops.object.multires_subdivide(modifier="Multires")
bpy.ops.object.multires_subdivide(modifier="Multires")
bpy.context.object.name = "terrain"
obj = bpy.context.active_object
bpy.ops.sculpt.sculptmode_toggle()
#creation material
mat_name = "M_terrain"
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_terrain")
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)
#geometry and position node
node_geo = nodes.new('ShaderNodeNewGeometry')
node_geo.location = (-1100,100)
#separate xyz node
node_xyz = nodes.new('ShaderNodeSeparateXYZ')
node_xyz.location =(-900,100)
#gradient altitude
gradient_alt = nodes.new(type='ShaderNodeValToRGB')
gradient_alt.location = (-700,0)
gradient_alt.color_ramp.elements[0].color = (1, 1, 1, 1)
gradient_alt.color_ramp.elements[1].color = (0, 0, 0, 1)
#shader low altitude
node = nodes.new('ShaderNodeBsdfDiffuse')
node.location = (50,-200)
node.inputs[0].default_value = (0.05,0.013,0.008,1)
#noise low altitude
noise_node = nodes.new(type='ShaderNodeTexNoise')
noise_node.location = -400,-200
noise_node.inputs[1].default_value = (100)
#gradient low altitude
gradient_node = nodes.new(type='ShaderNodeValToRGB')
gradient_node.location = -230,-200
gradient_node.color_ramp.elements[0].color = (0.04, 0.005, 0.003, 1)
gradient_node.color_ramp.elements[1].color = (0.09, 0.011, 0.007, 1)
#shader high altitude
node_high = nodes.new('ShaderNodeBsdfGlossy')
node_high.location = (-150,150)
node_high.inputs[0].default_value = (0.9,0.9,0.9,1)
#shader green
node_green = nodes.new('ShaderNodeBsdfDiffuse')
node_green.location = (-150,300)
node_green.inputs[0].default_value = (0.06,0.3,0.08,1)
#mix high and green
node_mg = nodes.new('ShaderNodeMixShader')
node_mg.location = (50,225)
#mix low and high
node_mix = nodes.new('ShaderNodeMixShader')
node_mix.location = (250,-30)
#node_divider
node_div = nodes.new('ShaderNodeMath')
node_div.location = (40,0)
node_div.operation = ('DIVIDE')
node_div.inputs[1].default_value = 1.05
#node_bump
node_bump = nodes.new('ShaderNodeBump')
node_bump.location = (-180,-450)
#output
node_output = nodes.new(type='ShaderNodeOutputMaterial')
node_output.location = 500,100
#creation of links
#link low to mix shader
mat.node_tree.links.new(node.outputs['BSDF'], node_mix.inputs[2])
#link high to mix shader
mat.node_tree.links.new(node_high.outputs['BSDF'], node_mg.inputs[2])
#link green to mix shader
mat.node_tree.links.new(node_green.outputs['BSDF'], node_mg.inputs[1])
#link gradient altitude to divide
mat.node_tree.links.new(gradient_alt.outputs[0], node_div.inputs[0])
#link divide to mix
mat.node_tree.links.new(node_div.outputs[0], node_mix.inputs[0])
#link xyz to fac node_mg
mat.node_tree.links.new(node_xyz.outputs[2], node_mg.inputs[0])
#link node_mg to node_mix
mat.node_tree.links.new(node_mg.outputs[0], node_mix.inputs[1])
#link noise to ground gradient
mat.node_tree.links.new(noise_node.outputs[0], gradient_node.inputs[0])
#link ground gradient to color of node
mat.node_tree.links.new(gradient_node.outputs[0], node.inputs[0])
#link the geometry node to z separate
mat.node_tree.links.new(node_geo.outputs[0], node_xyz.inputs[0])
#link the z separate to gradient altitude
mat.node_tree.links.new(node_xyz.outputs[2], gradient_alt.inputs[0])
#link noise to vector bump
mat.node_tree.links.new(noise_node.outputs[0], node_bump.inputs[2])
#link vector bump to shader
mat.node_tree.links.new(node_bump.outputs[0], node.inputs[2])
mat.node_tree.links.new(node_bump.outputs[0], node_high.inputs[2])
#link to output
mat.node_tree.links.new(node_mix.outputs[0], node_output.inputs['Surface'])
return {'FINISHED'}
def menu_item(self, context):
self.layout.operator(fastterrain.bl_idname, text="fast terrain", 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()
@ethanaeris
Copy link
Author

Fast Terrain
Blender plug in

@ethanaeris
Copy link
Author

To use : Shift+a->Mesh-> Fast terrain:
Just use standard sculpt tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment