forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_depth_buffer.py
More file actions
160 lines (115 loc) · 5.15 KB
/
test_depth_buffer.py
File metadata and controls
160 lines (115 loc) · 5.15 KB
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
155
156
157
158
159
160
from panda3d import core
import pytest
@pytest.fixture(scope='module', params=[32, 24, 16])
def depth_region(request, graphics_pipe):
"""Creates and returns a DisplayRegion with a depth buffer."""
engine = core.GraphicsEngine()
engine.set_threading_model("")
# Vulkan needs no host window.
if graphics_pipe.get_interface_name() != "Vulkan":
host_fbprops = core.FrameBufferProperties()
host_fbprops.force_hardware = True
host = engine.make_output(
graphics_pipe,
'host',
0,
host_fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
)
engine.open_windows()
if host is None:
pytest.skip("GraphicsPipe cannot make offscreen buffers")
host_gsg = host.gsg
else:
host = None
host_gsg = None
fbprops = core.FrameBufferProperties()
fbprops.force_hardware = True
fbprops.depth_bits = request.param
if fbprops.depth_bits >= 32:
fbprops.float_depth = True
buffer = engine.make_output(
graphics_pipe,
'buffer',
0,
fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
host_gsg,
host
)
engine.open_windows()
if buffer is None:
pytest.skip("Cannot make depth buffer")
if buffer.get_fb_properties().depth_bits != request.param:
pytest.skip("Could not make buffer with desired bit count")
yield buffer.make_display_region()
if buffer is not None:
engine.remove_window(buffer)
def render_depth_pixel(region, distance, near, far, clear=None, write=True):
"""Renders a fragment at the specified distance using the specified render
settings, and returns the resulting depth value."""
# Set up the scene with a blank card rendering at specified distance.
scene = core.NodePath("root")
scene.set_attrib(core.DepthTestAttrib.make(core.RenderAttrib.M_always))
scene.set_depth_write(write)
camera = scene.attach_new_node(core.Camera("camera"))
camera.node().get_lens(0).set_near_far(near, far)
camera.node().set_cull_bounds(core.OmniBoundingVolume())
if distance is not None:
cm = core.CardMaker("card")
cm.set_frame(-1, 1, -1, 1)
card = scene.attach_new_node(cm.generate())
card.set_pos(0, distance, 0)
card.set_scale(60)
region.active = True
region.camera = camera
if clear is not None:
region.set_clear_depth_active(True)
region.set_clear_depth(clear)
depth_texture = core.Texture("depth")
region.window.add_render_texture(depth_texture,
core.GraphicsOutput.RTM_copy_ram,
core.GraphicsOutput.RTP_depth)
region.window.engine.render_frame()
region.window.clear_render_textures()
col = core.LColor()
depth_texture.peek().lookup(col, 0.5, 0.5)
return col[0]
def test_depth_clear(depth_region):
assert 1.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=1.0)
assert 0.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=0.0)
def test_depth_write(depth_region):
assert 1.0 == render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=False)
assert 0.99 > render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=True)
def test_depth_far_inf(depth_region):
inf = float("inf")
assert 0.99 > render_depth_pixel(depth_region, 10.0, near=1, far=inf, clear=1.0)
def test_depth_near_inf(depth_region):
inf = float("inf")
assert 0.01 < render_depth_pixel(depth_region, 10.0, near=inf, far=1, clear=0.0)
def test_depth_clipping(depth_region):
# Get the actual depth resulting from the clear value.
clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5)
# We try rendering something at various distances to make sure that the
# resulting depth value matches our expectations.
# Too close; read clear value.
assert clr == render_depth_pixel(depth_region, 0.999, near=1, far=10, clear=0.5)
# Too far; read clear value.
assert clr == render_depth_pixel(depth_region, 10.01, near=1, far=10, clear=0.5)
# Just close enough; read a value close to 0.0.
assert 0.01 > render_depth_pixel(depth_region, 1.001, near=1, far=10, clear=0.5)
# Just far enough; read 1.0.
assert 0.99 < render_depth_pixel(depth_region, 9.999, near=1, far=10, clear=0.5)
def test_inverted_depth_clipping(depth_region):
# Get the actual depth resulting from the clear value.
clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5)
# Too close; read clear value.
assert clr == render_depth_pixel(depth_region, 0.999, near=10, far=1, clear=0.5)
# Too far; read clear value.
assert clr == render_depth_pixel(depth_region, 10.01, near=10, far=1, clear=0.5)
# Just close enough; read a value close to 1.0.
assert 0.99 < render_depth_pixel(depth_region, 1.001, near=10, far=1, clear=0.5)
# Just far enough; read a value close to 0.0.
assert 0.01 > render_depth_pixel(depth_region, 9.999, near=10, far=1, clear=0.5)