-
Notifications
You must be signed in to change notification settings - Fork 0
/
water_texture.py
154 lines (116 loc) · 4.36 KB
/
water_texture.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Author: Martins Upitis (martinsh) (devlog-martinsh.blogspot.com)
from bge import logic as g
from bge import texture
from mathutils import *
from math import *
import bgl
#import bpy
cont = g.getCurrentController()
own = cont.owner
scene = g.getCurrentScene()
objlist = scene.objects
reflsize = 512 #reflection tex dimensions
refrsize = 512 #refraction tex dimensions
offset = 0.0 #geometry clipping offset
#texture background color
bgR = 0.5
bgG = 0.4
bgB = 0.1
bgA = 1.0
activecam = scene.active_camera
viewer = activecam
#if 'initcam' not in own:
# cam = bpy.data.cameras.new('rendercamera')
# cam_ob = bpy.data.objects.new('watercamera', cam)
# bpy.context.scene.objects.link(cam_ob)
# own['initcam'] = 1
rendercamera = objlist['rendercamera'] #camera used for rendering the textures
#setting lens and projection to rendercamera same as active camera
rendercamera.lens = activecam.lens
rendercamera.projection_matrix = activecam.projection_matrix
#rotation and mirror matrices
m1=Matrix(own.orientation)
m2=Matrix(own.orientation)
m2.invert()
r180 = Matrix.Rotation(radians(180),3,'Y')
unmir = Matrix.Scale(-1,3,Vector([1,0,0]))
#disable visibility for the water surface during texture rendering
own.visible = False
###REFLECTION####################
#initializing camera for reflection pass
pos = (viewer.position - own.position)*m1
pos = own.position + pos*r180*unmir*m2
ori = Matrix(viewer.orientation)
ori.transpose()
ori = ori*m1*r180*unmir*m2
ori.transpose()
#delay reduction using delta offset
if 'oldori' not in own:
own['oldori'] = ori
own['oldpos'] = pos
own['deltaori'] = own['oldori']-ori
own['deltapos'] = own['oldpos']-pos
own['deltaori'] = own['oldori']-ori
own['deltapos'] = own['oldpos']-pos
#orienting and positioning the reflection rendercamera
rendercamera.orientation = ori - own['deltaori']
rendercamera.position = pos - own['deltapos']
#storing the old orientation and position of the camera
own['oldori'] = ori
own['oldpos'] = pos
#culling front faces as the camera is scaled to -1
bgl.glCullFace(bgl.GL_FRONT)
#plane equation
normal = own.getAxisVect((0.0, 0.0, 1.0)) #plane normals Z=front
D = -own.position.project(normal).magnitude #closest distance from center to plane
V = (activecam.position-own.position).normalized().dot(normal) #VdotN to get frontface/backface
#invert normals when backface
if V<0:
normal = -normal
#making a clipping plane buffer
plane = bgl.Buffer(bgl.GL_DOUBLE, [4], [-normal[0], -normal[1], -normal[2], -D+offset])
bgl.glClipPlane(bgl.GL_CLIP_PLANE0,plane)
bgl.glEnable(bgl.GL_CLIP_PLANE0)
#rendering the reflection texture in tex channel 0
if not hasattr(g, 'reflection'):
g.reflection = texture.Texture(own, 0, 0)
g.reflection.source = texture.ImageRender(scene,rendercamera)
g.reflection.source.capsize = [reflsize,reflsize]
g.reflection.source.background = [int(bgR*255),int(bgG*255),int(bgB*255),int(bgA*255)]
g.reflection.refresh(True)
#restoring face culling to normal and disabling the geometry clipping
bgl.glCullFace(bgl.GL_BACK)
bgl.glDisable(bgl.GL_CLIP_PLANE0)
###REFRACTION####################
#initializing camera for refraction pass
pos = viewer.position
ori = Matrix(viewer.orientation)
#delay reduction using delta offset
if 'oldori1' not in own:
own['oldori1'] = own.orientation
own['oldpos1'] = own.position
own['deltaori1'] = own['oldori1']-viewer.orientation
own['deltapos1'] = own['oldpos1']-viewer.position
own['deltaori1'] = own['oldori1']-ori
own['deltapos1'] = own['oldpos1']-pos
#orienting and positioning the refraction rendercamera
rendercamera.orientation = ori - own['deltaori1']
rendercamera.position = pos - own['deltapos1']
#storing the old orientation and position of the camera
own['oldori1'] = ori
own['oldpos1'] = pos
#making another clipping plane buffer
plane = bgl.Buffer(bgl.GL_DOUBLE, [4], [normal[0], normal[1], normal[2], -D+offset])
bgl.glClipPlane(bgl.GL_CLIP_PLANE1,plane)
bgl.glEnable(bgl.GL_CLIP_PLANE1)
#rendering the refraction texture in tex channel 1
if not hasattr(g, 'refraction'):
g.refraction = texture.Texture(own, 0, 1)
g.refraction.source = texture.ImageRender(scene,rendercamera)
g.refraction.source.capsize = [refrsize,refrsize]
g.refraction.source.background = [int(bgR*255),int(bgG*255),int(bgB*255),int(bgA*255)]
g.refraction.refresh(True)
#disabling the geometry clipping
bgl.glDisable(bgl.GL_CLIP_PLANE1)
#restoreing visibility for the water surface
own.visible = True