Skip to content

tt #358

@ali078012427944-lab

Description

@ali078012427944-lab

import bpy
import math
import random
from mathutils import Vector, noise

===========================================

Creative 3D Fluid Prompt with Wow Effect

Hyper-realistic oil & gas cosmic fluid sim

For Blender 3.5+ (Mantaflow)

===========================================

Clear the scene

bpy.ops.wm.read_factory_settings(use_empty=True)

-----------------------------------------------------

1. Scene Setup: Volumetric World & Cosmic Lighting

-----------------------------------------------------

scene = bpy.context.scene
scene.render.engine = 'CYCLES'
scene.render.resolution_x = 3840
scene.render.resolution_y = 2160
scene.render.resolution_percentage = 100
scene.cycles.samples = 1024
scene.cycles.use_denoising = True
scene.view_settings.view_transform = 'Filmic'
scene.view_settings.look = 'Very High Contrast'

World with starry nebula texture

world = bpy.data.worlds.new("CosmicWorld")
world.use_nodes = True
world_nodes = world.node_tree.nodes
world_links = world.node_tree.links
world_nodes.clear()

Background node with procedural stars

tex_coord = world_nodes.new(type='ShaderNodeTexCoord')
mapping = world_nodes.new(type='ShaderNodeMapping')
mapping.vector_type = 'POINT'
mapping.scale[0] = 2.5
mapping.scale[1] = 2.5
mapping.scale[2] = 2.5

noise_tex = world_nodes.new(type='ShaderNodeTexNoise')
noise_tex.inputs['Scale'].default_value = 1.2
noise_tex.inputs['Detail'].default_value = 8.0
noise_tex.inputs['Roughness'].default_value = 0.7

color_ramp = world_nodes.new(type='ShaderNodeValToRGB')
color_ramp.color_ramp.elements[0].position = 0.4
color_ramp.color_ramp.elements[0].color = (0.01, 0.0, 0.05, 1.0) # deep space
color_ramp.color_ramp.elements[1].position = 0.7
color_ramp.color_ramp.elements[1].color = (0.3, 0.1, 0.6, 1.0) # nebulae purple

bg = world_nodes.new(type='ShaderNodeBackground')
bg.inputs['Strength'].default_value = 0.8

output = world_nodes.new(type='ShaderNodeOutputWorld')

Link: mapping -> noise -> color ramp -> background

world_links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])
world_links.new(mapping.outputs['Vector'], noise_tex.inputs['Vector'])
world_links.new(noise_tex.outputs['Fac'], color_ramp.inputs['Fac'])
world_links.new(color_ramp.outputs['Color'], bg.inputs['Color'])
world_links.new(bg.outputs['Background'], output.inputs['Surface'])

bpy.context.scene.world = world

-----------------------------------------------------

2. Camera & Cinematic Composition

-----------------------------------------------------

bpy.ops.object.camera_add(location=(15, -20, 10), rotation=(1.2, 0.0, 0.8))
camera = bpy.context.active_object
camera.data.lens = 35
scene.camera = camera

Empty for depth of field focus

bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 2))
focus_target = bpy.context.active_object
camera.data.dof.use_dof = True
camera.data.dof.focus_object = focus_target
camera.data.dof.aperture_fstop = 1.8

Add lights: cosmic ambient + electric sparks

Main area light (blue tone)

bpy.ops.object.light_add(type='AREA', location=(5, -5, 8), rotation=(0.8, 0.2, 0.5))
light1 = bpy.context.active_object
light1.data.energy = 300
light1.data.color = (0.3, 0.5, 1.0) # electric blue
light1.data.shape = 'DISK'
light1.data.size = 5

Fill light (orange sparks)

bpy.ops.object.light_add(type='POINT', location=(-8, 4, 3))
light2 = bpy.context.active_object
light2.data.energy = 200
light2.data.color = (1.0, 0.5, 0.1) # fiery orange

Back rim light (green gas)

bpy.ops.object.light_add(type='AREA', location=(2, 12, 5), rotation=(-0.5, 0.0, -2.0))
light3 = bpy.context.active_object
light3.data.energy = 250
light3.data.color = (0.2, 0.9, 0.3) # neon green
light3.data.shape = 'RECTANGLE'
light3.data.size = 8
light3.data.size_y = 4

-----------------------------------------------------

3. Fluid Domain and Effectors (Mantaflow)

-----------------------------------------------------

bpy.ops.mesh.primitive_cube_add(size=12, location=(0, 0, 2))
domain_obj = bpy.context.active_object
domain_obj.name = "FluidDomain"
domain_obj.hide_viewport = True
domain_obj.hide_render = True

Add fluid modifier

bpy.ops.object.modifier_add(type='FLUID')
domain_obj.modifiers["Fluid"].fluid_type = 'DOMAIN'
domain_settings = domain_obj.modifiers["Fluid"].domain_settings
domain_settings.resolution_max = 128 # high detail for fluid sim
domain_settings.use_mesh = True
domain_settings.use_speed_vectors = True
domain_settings.cache_type = 'ALL'
domain_settings.cache_frame_start = 1
domain_settings.cache_frame_end = 120
domain_settings.alpha = 0.1 # transparency for volumetric feel

Enable particles (for bubbles/sparks)

domain_settings.use_spray_particles = True
domain_settings.use_bubble_particles = True
domain_settings.use_foam_particles = True
domain_settings.use_tracer_particles = True
domain_settings.particle_max = 8000
domain_settings.particle_bandwidth = 0.3
domain_settings.particle_scale = 0.2
domain_settings.particle_scale_max = 0.5

-----------------------------------------------------

4. Fluid Inflow: OIL (viscous black) & GAS (neon green)

-----------------------------------------------------

---- Oil inflow (thick black ribbons) ----

bpy.ops.mesh.primitive_torus_add(major_radius=0.8, minor_radius=0.2, location=(0, 0, 1.5))
oil_inflow = bpy.context.active_object
oil_inflow.name = "Oil_Inflow"
oil_inflow.rotation_euler = (0.5, 0.2, 0.0)
bpy.ops.object.modifier_add(type='FLUID')
oil_inflow.modifiers["Fluid"].fluid_type = 'FLOW'
flow_oil = oil_inflow.modifiers["Fluid"].flow_settings
flow_oil.flow_behavior = 'INFLOW'
flow_oil.flow_type = 'LIQUID'
flow_oil.flow_source = 'PARTICLES'
flow_oil.use_initial_velocity = True
flow_oil.velocity_factor = 1.8
flow_oil.velocity_normal = 2.0
flow_oil.velocity_random = 0.6
flow_oil.particle_system = None # will be added

Add particle system for oil drip effect

bpy.ops.object.select_all(action='DESELECT')
oil_inflow.select_set(True)
bpy.context.view_layer.objects.active = oil_inflow
bpy.ops.object.particle_system_add()
psys_oil = oil_inflow.particle_systems[0]
psys_oil.name = "OilParticles"
settings_oil = psys_oil.settings
settings_oil.type = 'HAIR'
settings_oil.emit_from = 'VERT'
settings_oil.count = 300
settings_oil.hair_length = 0.8
settings_oil.hair_step = 5
settings_oil.use_hair_dynamics = True
settings_oil.mass = 2.0
settings_oil.brownian_factor = 0.5
settings_oil.use_rotations = True
settings_oil.rotation_mode = 'VELOCITY'
settings_oil.random_rotation = 0.2

Assign material later

---- Gas inflow (neon green, turbulent) ----

bpy.ops.mesh.primitive_uv_sphere_add(radius=0.6, location=(2, 1, 2.5))
gas_inflow = bpy.context.active_object
gas_inflow.name = "Gas_Inflow"
bpy.ops.object.modifier_add(type='FLUID')
gas_inflow.modifiers["Fluid"].fluid_type = 'FLOW'
flow_gas = gas_inflow.modifiers["Fluid"].flow_settings
flow_gas.flow_behavior = 'INFLOW'
flow_gas.flow_type = 'GAS' # smoke / gas
flow_gas.surface_distance = 0.3
flow_gas.flow_source = 'PARTICLES'
flow_gas.velocity_factor = 2.5
flow_gas.velocity_normal = 3.0
flow_gas.velocity_random = 1.2
flow_gas.use_initial_velocity = True

bpy.ops.object.particle_system_add()
psys_gas = gas_inflow.particle_systems[0]
psys_gas.name = "GasParticles"
settings_gas = psys_gas.settings
settings_gas.type = 'EMITTER'
settings_gas.count = 500
settings_gas.frame_start = 1
settings_gas.frame_end = 100
settings_gas.lifetime = 60
settings_gas.emit_from = 'FACE'
settings_gas.distribution = 'JIT'
settings_gas.normal_factor = 2.5
settings_gas.factor_random = 1.0
settings_gas.use_rotations = True
settings_gas.rotation_factor = 0.3

-----------------------------------------------------

5. Effectors: Lightning arcs & vortex force

-----------------------------------------------------

Create electric arcs with simple curves + force field

bpy.ops.object.select_all(action='DESELECT')
for i in range(8):
x = random.uniform(-6, 6)
y = random.uniform(-6, 6)
z = random.uniform(1, 5)
bpy.ops.curve.primitive_bezier_curve_add(location=(x, y, z))
arc = bpy.context.active_object
arc.name = f"LightningArc_{i}"
arc.scale = (0.5, 0.5, 0.5)
arc.data.bevel_depth = 0.03
arc.data.bevel_resolution = 4

# Add turbulence field for electric feel
bpy.ops.object.select_all(action='DESELECT')
arc.select_set(True)
bpy.context.view_layer.objects.active = arc
bpy.ops.object.effector_add(type='TURBULENCE', enter_editmode=False, location=arc.location)
turb = bpy.context.active_object
turb.name = f"Turbulence_{i}"
turb.field.strength = 12.0
turb.field.size = 1.5
turb.field.flow = 0.5
turb.field.noise = 2.0

# Material will be added later

Vortex force for the mesmerizing pull

bpy.ops.object.effector_add(type='VORTEX', location=(0, 0, 4))
vortex = bpy.context.active_object
vortex.name = "CosmicVortex"
vortex.rotation_euler = (0.5, 0.2, 0.0)
vortex.field.strength = 25.0
vortex.field.flow = 0.8
vortex.field.noise = 0.3
vortex.field.distance = 10.0

-----------------------------------------------------

6. Advanced Materials: Iridescence, Oil, Gas, Sparks

-----------------------------------------------------

---- Oil material: viscous black with iridescent sheen ----

oil_mat = bpy.data.materials.new(name="IridescentOil")
oil_mat.use_nodes = True
oil_nodes = oil_mat.node_tree.nodes
oil_links = oil_mat.node_tree.links
oil_nodes.clear()

Mix Shader: glossy + translucent

mix1 = oil_nodes.new(type='ShaderNodeMixShader')
mix2 = oil_nodes.new(type='ShaderNodeMixShader')
glossy = oil_nodes.new(type='ShaderNodeBsdfGlossy')
glossy.inputs['Color'].default_value = (0.02, 0.01, 0.01, 1.0)
glossy.inputs['Roughness'].default_value = 0.15
translucent = oil_nodes.new(type='ShaderNodeBsdfTranslucent')
translucent.inputs['Color'].default_value = (0.05, 0.03, 0.03, 1.0)

Iridescent layer via fresnel + noise

fresnel = oil_nodes.new(type='ShaderNodeFresnel')
fresnel.inputs['IOR'].default_value = 1.8
noise_tex_oil = oil_nodes.new(type='ShaderTexNoise')
noise_tex_oil.inputs['Scale'].default_value = 8.0
noise_tex_oil.inputs['Detail'].default_value = 5.0

color_ramp_oil = oil_nodes.new(type='ShaderNodeValToRGB')
color_ramp_oil.color_ramp.elements[0].color = (0.1, 0.6, 0.7, 1.0) # cyan
color_ramp_oil.color_ramp.elements[1].color = (0.8, 0.2, 0.5, 1.0) # magenta

output_oil = oil_nodes.new(type='ShaderNodeOutputMaterial')

Links

oil_links.new(noise_tex_oil.outputs['Fac'], color_ramp_oil.inputs['Fac'])
oil_links.new(fresnel.outputs['Fac'], mix1.inputs[0])
oil_links.new(color_ramp_oil.outputs['Color'], mix1.inputs[2])
oil_links.new(glossy.outputs['BSDF'], mix1.inputs[1])
oil_links.new(mix1.outputs['Shader'], mix2.inputs[1])
oil_links.new(translucent.outputs['BSDF'], mix2.inputs[2])
oil_links.new(mix2.outputs['Shader'], output_oil.inputs['Surface'])

Assign oil material

oil_inflow.data.materials.append(oil_mat)

---- Gas material: neon green, volumetric, glowing ----

gas_mat = bpy.data.materials.new(name="NeonGas")
gas_mat.use_nodes = True
gas_nodes = gas_mat.node_tree.nodes
gas_links = gas_mat.node_tree.links
gas_nodes.clear()

vol_absorb = gas_nodes.new(type='ShaderNodeVolumeAbsorption')
vol_absorb.inputs['Color'].default_value = (0.1, 0.8, 0.2, 1.0)
vol_absorb.inputs['Density'].default_value = 0.3

vol_scatter = gas_nodes.new(type='ShaderNodeVolumeScatter')
vol_scatter.inputs['Color'].default_value = (0.2, 0.9, 0.2, 1.0)
vol_scatter.inputs['Density'].default_value = 0.2
vol_scatter.inputs['Anisotropy'].default_value = 0.0

mix_vol = gas_nodes.new(type='ShaderNodeMixShader')
emission = gas_nodes.new(type='ShaderNodeEmission')
emission.inputs['Color'].default_value = (0.3, 1.0, 0.4, 1.0)
emission.inputs['Strength'].default_value = 0.8

output_gas = gas_nodes.new(type='ShaderNodeOutputMaterial')

Links

gas_links.new(vol_absorb.outputs['Volume'], mix_vol.inputs[1])
gas_links.new(vol_scatter.outputs['Volume'], mix_vol.inputs[2])
gas_links.new(emission.outputs['Emission'], mix_vol.inputs[2])
gas_links.new(mix_vol.outputs['Shader'], output_gas.inputs['Volume'])

gas_inflow.data.materials.append(gas_mat)

---- Lightning material: electric blue emission ----

lightning_mat = bpy.data.materials.new(name="ElectricBlue")
lightning_mat.use_nodes = True
lightning_nodes = lightning_mat.node_tree.nodes
lightning_links = lightning_mat.node_tree.links
lightning_nodes.clear()

emit = lightning_nodes.new(type='ShaderNodeEmission')
emit.inputs['Color'].default_value = (0.0, 0.5, 1.0, 1.0)
emit.inputs['Strength'].default_value = 15.0
output_light = lightning_nodes.new(type='ShaderNodeOutputMaterial')
lightning_links.new(emit.outputs['Emission'], output_light.inputs['Surface'])

for obj in bpy.data.objects:
if "LightningArc" in obj.name:
obj.data.materials.append(lightning_mat)

---- Bubble material: iridescent, glass-like ----

bubble_mat = bpy.data.materials.new(name="IridescentBubble")
bubble_mat.use_nodes = True
bubble_nodes = bubble_mat.node_tree.nodes
bubble_links = bubble_mat.node_tree.links
bubble_nodes.clear()

glass = bubble_nodes.new(type='ShaderNodeBsdfGlass')
glass.inputs['Color'].default_value = (0.9, 0.9, 1.0, 1.0)
glass.inputs['Roughness'].default_value = 0.05
glass.inputs['IOR'].default_value = 1.33

Add thin film interference (fresnel + noise)

fresnel_bubble = bubble_nodes.new(type='ShaderNodeFresnel')
noise_bubble = bubble_nodes.new(type='ShaderTexNoise')
noise_bubble.inputs['Scale'].default_value = 25.0
color_ramp_bubble = bubble_nodes.new(type='ShaderNodeValToRGB')
color_ramp_bubble.color_ramp.elements[0].color = (0.8, 0.2, 0.6, 1.0)
color_ramp_bubble.color_ramp.elements[1].color = (0.2, 0.9, 0.8, 1.0)

mix_bubble = bubble_nodes.new(type='ShaderNodeMixShader')
output_bubble = bubble_nodes.new(type='ShaderNodeOutputMaterial')

bubble_links.new(noise_bubble.outputs['Fac'], color_ramp_bubble.inputs['Fac'])
bubble_links.new(color_ramp_bubble.outputs['Color'], mix_bubble.inputs[2])
bubble_links.new(fresnel_bubble.outputs['Fac'], mix_bubble.inputs[0])
bubble_links.new(glass.outputs['BSDF'], mix_bubble.inputs[1])
bubble_links.new(mix_bubble.outputs['Shader'], output_bubble.inputs['Surface'])

Assign to fluid particle system later if needed (domain particles inherit material via domain)

---- Spark material: fiery orange ----

spark_mat = bpy.data.materials.new(name="FierySpark")
spark_mat.use_nodes = True
spark_nodes = spark_mat.node_tree.nodes
spark_links = spark_mat.node_tree.links
spark_nodes.clear()

spark_emit = spark_nodes.new(type='ShaderNodeEmission')
spark_emit.inputs['Color'].default_value = (1.0, 0.4, 0.0, 1.0)
spark_emit.inputs['Strength'].default_value = 12.0
spark_output = spark_nodes.new(type='ShaderNodeOutputMaterial')
spark_links.new(spark_emit.outputs['Emission'], spark_output.inputs['Surface'])

-----------------------------------------------------

7. Background Cosmic Nebulae (Distant)

-----------------------------------------------------

bpy.ops.mesh.primitive_uv_sphere_add(radius=30, location=(0, 0, 10))
nebula_sphere = bpy.context.active_object
nebula_sphere.name = "CosmicNebula"
nebula_sphere.scale = (2.0, 2.0, 0.8)
nebula_sphere.hide_viewport = False
nebula_sphere.hide_render = False
nebula_mat = bpy.data.materials.new(name="NebulaBackground")
nebula_mat.use_nodes = True
nebula_nodes = nebula_mat.node_tree.nodes
nebula_links = nebula_mat.node_tree.links
nebula_nodes.clear()

Use volume emission for soft glow

vol_emiss = nebula_nodes.new(type='ShaderNodeVolumeEmission')
vol_emiss.inputs['Color'].default_value = (0.6, 0.2, 0.8, 1.0)
vol_emiss.inputs['Density'].default_value = 0.02

out_vol = nebula_nodes.new(type='ShaderNodeOutputMaterial')
nebula_links.new(vol_emiss.outputs['Volume'], out_vol.inputs['Volume'])

nebula_sphere.data.materials.append(nebula_mat)

-----------------------------------------------------

8. Animation & Baking Setup

-----------------------------------------------------

Set timeline

scene.frame_start = 1
scene.frame_end = 120

Add keyframes for dynamic inflow motion (oil swirl)

oil_inflow.location = (0, 0, 1.5)
oil_inflow.keyframe_insert(data_path="location", frame=1)
oil_inflow.location = (-1, 1, 3)
oil_inflow.keyframe_insert(data_path="location", frame=60)
oil_inflow.location = (1, -0.5, 2)
oil_inflow.keyframe_insert(data_path="location", frame=120)

gas_inflow.location = (2, 1, 2.5)
gas_inflow.keyframe_insert(data_path="location", frame=1)
gas_inflow.location = (3, -1, 4)
gas_inflow.keyframe_insert(data_path="location", frame=90)

Bake fluid simulation (user may need to press 'Bake All' in UI or run this line)

bpy.ops.fluid.bake_all() # uncomment to start baking (takes time)

-----------------------------------------------------

9. Post-processing: Volumetric fog in domain

-----------------------------------------------------

domain_mat = bpy.data.materials.new(name="DomainVolume")
domain_mat.use_nodes = True
domain_nodes = domain_mat.node_tree.nodes
domain_links = domain_mat.node_tree.links
domain_nodes.clear()

domain_vol = domain_nodes.new(type='ShaderNodeVolumeScatter')
domain_vol.inputs['Color'].default_value = (0.4, 0.6, 1.0, 1.0)
domain_vol.inputs['Density'].default_value = 0.02
domain_out = domain_nodes.new(type='ShaderNodeOutputMaterial')
domain_links.new(domain_vol.outputs['Volume'], domain_out.inputs['Volume'])

if domain_obj.data.materials:
domain_obj.data.materials[0] = domain_mat
else:
domain_obj.data.materials.append(domain_mat)

print("=== SCENE READY ===")
print("Fluid simulation and cosmic oil/gas vortex created.")
print("Adjust camera, bake fluid, and render to see the 'wow' effect!")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions