www.xbdev.net
xbdev - software development
Thursday April 30, 2026
Home | Contact | Support | Blender (.py) Scripts... Automating Blender ..
     
 

Blender (.py) Scripts...

Automating Blender ..

 

Jelly Wobbly Water-Like Shapes


Let's swap the word 'GRASS' for 'WATER' - and create a liquid-type shape (jelly) - with caustics and transparency - and those water ripples you see on ocean surfaces (or water). We'll mix in some noise (clouds and displacement) to modify the solid shape and then draw it as a transparent mesh.


Example of what the output looks like when rendered - letters spelling out the word
Example of what the output looks like when rendered - letters spelling out the word 'WATER'.


<?php
import bpy

# Clear existing scene
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

# Create 3D Text
bpy.ops.object.text_add(location=(2.2, -4.2, 0))
text_obj = bpy.context.active_object
text_obj.data.body = "WATER"
text_obj.data.extrude = 0.3
text_obj.data.bevel_depth = 0.04
text_obj.data.align_x = 'CENTER'
text_obj.data.size = 1.5

# Convert Text to Mesh
bpy.ops.object.convert(target='MESH')
bpy.ops.object.shade_smooth()
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)

# Add subdivision for smooth displacement
subd = text_obj.modifiers.new("Subdivision", type='SUBSURF')
subd.levels = 3
subd.render_levels = 3

# Add Displace modifier for ripples
disp = text_obj.modifiers.new("Displace", type='DISPLACE')
tex = bpy.data.textures.new("RippleTex", type='CLOUDS')
tex.noise_scale = 1.0
tex.noise_depth = 4
disp.texture = tex
disp.strength = 0.35
disp.mid_level = 0.0
disp.direction = 'RGB_TO_XYZ' # Important line! so you can't see the undelrying 'letter' edges

# Create Water-Like Material
mat = bpy.data.materials.new(name="WaterSurface")
mat.use_nodes = True
mat.blend_method = 'BLEND'
mat.shadow_method = 'HASHED'
mat.use_screen_refraction = True  # Optional for Eevee

nodes = mat.node_tree.nodes
links = mat.node_tree.links
nodes.clear()

# Add nodes
output = nodes.new(type='ShaderNodeOutputMaterial')
glass = nodes.new(type='ShaderNodeBsdfGlass')
transparent = nodes.new(type='ShaderNodeBsdfTransparent')
mix_shader = nodes.new(type='ShaderNodeMixShader')
layer_weight = nodes.new(type='ShaderNodeLayerWeight')
bump = nodes.new(type='ShaderNodeBump')
noise = nodes.new(type='ShaderNodeTexNoise')
mapping = nodes.new(type='ShaderNodeMapping')
tex_coord = nodes.new(type='ShaderNodeTexCoord')

# Set node properties
glass.inputs['Color'].default_value = (0.1, 0.3, 0.6, 1)
glass.inputs['IOR'].default_value = 1.33  # Water IOR

layer_weight.inputs['Blend'].default_value = 0.2  # Soft transparency at facing angles

noise.inputs['Scale'].default_value = 20
noise.inputs['Detail'].default_value = 6
noise.inputs['Roughness'].default_value = 0.5
bump.inputs['Strength'].default_value = 0.15

# Node layout (optional)
output.location = (500, 0)
glass.location = (0, 0)
transparent.location = (0, -200)
mix_shader.location = (200, 0)
layer_weight.location = (-200, 0)
bump.location = (-200, -200)
noise.location = (-400, -200)
mapping.location = (-600, -200)
tex_coord.location = (-800, -200)

# Link shader nodes
links.new(layer_weight.outputs['Facing'], mix_shader.inputs['Fac'])
links.new(glass.outputs['BSDF'], mix_shader.inputs[1])
links.new(transparent.outputs['BSDF'], mix_shader.inputs[2])
links.new(mix_shader.outputs['Shader'], output.inputs['Surface'])

# Link bump map to glass normal
links.new(tex_coord.outputs['Object'], mapping.inputs['Vector'])
links.new(mapping.outputs['Vector'], noise.inputs['Vector'])
links.new(noise.outputs['Fac'], bump.inputs['Height'])
links.new(bump.outputs['Normal'], glass.inputs['Normal'])

# Assign material
text_obj.data.materials.append(mat)

# Lighting
bpy.ops.object.light_add(type='SUN', location=(6, -6, 6))
sun = bpy.context.active_object
sun.data.energy = 5

bpy.ops.object.light_add(type='AREA', location=(-4, 4, 5))
area_light = bpy.context.active_object
area_light.data.energy = 500
area_light.data.size = 2

# World background
bpy.context.scene.world.use_nodes = True
bg = bpy.context.scene.world.node_tree.nodes.get("Background")
bg.inputs[0].default_value = (0.05, 0.1, 0.2, 1)  # bluish ambient light

# Camera
bpy.ops.object.camera_add(location=(7, -7, 3), rotation=(1.1, 0, 0.8))
cam = bpy.context.active_object
bpy.context.scene.camera = cam

# Render settings
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
scene.cycles.device = 'GPU'
scene.cycles.samples = 256
scene.cycles.max_bounces = 12
scene.cycles.volume_bounces = 4
scene.cycles.caustics_refractive = True
scene.cycles.caustics_reflective = True

print("Water surface 'WATER' with clean transparency created!")







 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2026 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.