Dynamic textures are a great feature. They allow you to do everything from blood-splats to tire-skids to, well, building entire image manipulation systems in blender.
In my case I wanted to have a vehicle leave marks in the mud:
This is a preliminary test that just leaves spherical trail-marks. At some point I may expand this to leaving tire-tracks, but I need some more inspiration for that!
The Blend:
TireTest.blend (526 KB)
Hit play and use the arrow keys
Description:
A node texture uses a generated texture map to mix between grass and mud. The same texture is mapped to the height. The location of the sphere is used as the position for the brush of the dynamic texture.
Code:
import bge
import math
IMAGE_SIZE = 512
IMAGE_RGB = b'\x88\x88\x88'
TRACK_SIZE = int(IMAGE_SIZE/8)
TRACK_ALPHA = 1
TRACK_SIGMA = 2.0
BLEND_MODE = bge.texture.IMB_BLEND_MIX
TARGET_OBJ = 'Cube'
def init(cont):
cont.owner['brush'] = generate_brush()
generate_tex(cont)
def generate_tex(cont):
tex = bge.texture.Texture(cont.owner, 0, 0)
tex.source = bge.texture.ImageBuff(IMAGE_SIZE, IMAGE_SIZE, 0)
tex.source.load(IMAGE_RGB * (IMAGE_SIZE**2),IMAGE_SIZE,IMAGE_SIZE)
tex.refresh(False)
cont.owner['tex'] = tex
def generate_brush():
brush = bytearray(TRACK_SIZE*TRACK_SIZE*4)
ro = 2.0*TRACK_SIGMA**2
for y in range(TRACK_SIZE):
for x in range(TRACK_SIZE):
pixel_num = y*TRACK_SIZE*4+x*4
x_distance=abs(x-TRACK_SIZE/2) / TRACK_SIZE
y_distance=abs(y-TRACK_SIZE/2) / TRACK_SIZE
dist = math.sqrt(x_distance**2 + y_distance**2)
alpha=int((255 - min(dist**0.6 * 255 * 2, 255)) * TRACK_ALPHA)
col = [int((1 - math.cos(dist*math.pi * 2))*127)]*3
brush[pixel_num:pixel_num+3] = col
brush[pixel_num+3] = alpha
return brush
def update(cont):
brush = cont.owner['brush']
pos = cont.owner.scene.objects[TARGET_OBJ].worldPosition
x = int(pos.x / cont.owner.worldScale.x * IMAGE_SIZE + IMAGE_SIZE / 2 - TRACK_SIZE / 2)
y = int(pos.y / cont.owner.worldScale.y * IMAGE_SIZE + IMAGE_SIZE / 2 - TRACK_SIZE / 2)
cont.owner['tex'].source.plot(brush,TRACK_SIZE,TRACK_SIZE,x,y,BLEND_MODE)
cont.owner['tex'].refresh(False)