mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Workbench: Hardware raytraced shadows
Implement optional hardware raytraced shadows for the Workbench engine. They can be enabled in the `Preferences > Viewport > Quality` settings. The option will be shown as inactive if the current backend/GPU doesn't support hardware ray queries (only Vulkan is supported ATM). A new `gpu.capabilities.ray_query_support_get()` has been added to the Python API to support this UI functionality. The visual results are the same as the stencil shadows implementation, but it provides a significant performance boost on modern hardware. The raytracing functionality has been implemented in a fragment shader that mimics the output of stencil-based implementation, so the render pipeline stays mostly the same. Co-authored by: Jeroen Bakker Pull Request: https://projects.blender.org/blender/blender/pulls/161047
This commit is contained in:
parent
5cfcffda7b
commit
a6b708c1f2
32 changed files with 310 additions and 83 deletions
|
|
@ -9,6 +9,7 @@ Use this script as `blender --background --python gpu_info.py`.
|
|||
"""
|
||||
import bpy
|
||||
import sys
|
||||
import json
|
||||
|
||||
# Render with workbench to initialize the GPU backend otherwise it would fail when running in
|
||||
# background mode as the GPU backend won't be initialized.
|
||||
|
|
@ -21,9 +22,14 @@ bpy.ops.render.render(animation=False, write_still=False)
|
|||
# Import GPU module only after GPU backend has been initialized.
|
||||
import gpu
|
||||
|
||||
print('GPU_VENDOR:' + gpu.platform.vendor_get())
|
||||
print('GPU_RENDERER:' + gpu.platform.renderer_get())
|
||||
print('GPU_VERSION:' + gpu.platform.version_get())
|
||||
print('GPU_DEVICE_TYPE:' + gpu.platform.device_type_get())
|
||||
print('<GPU_INFO>')
|
||||
print(json.dumps({
|
||||
"VENDOR": gpu.platform.vendor_get(),
|
||||
"RENDERER": gpu.platform.renderer_get(),
|
||||
"VERSION": gpu.platform.version_get(),
|
||||
"DEVICE_TYPE": gpu.platform.device_type_get(),
|
||||
"RAY_QUERY_SUPPORT": gpu.capabilities.ray_query_support_get(),
|
||||
}))
|
||||
print('</GPU_INFO>')
|
||||
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import time
|
|||
import multiprocessing
|
||||
import traceback
|
||||
import re
|
||||
import json
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
|
@ -229,7 +230,7 @@ def diff_output(test, oiiotool, fail_threshold, fail_percent, verbose, update):
|
|||
return test
|
||||
|
||||
|
||||
def get_gpu_device_vendor(blender, gpu_backend):
|
||||
def get_gpu_device_info(blender, gpu_backend):
|
||||
command = [
|
||||
blender,
|
||||
"--background",
|
||||
|
|
@ -239,15 +240,28 @@ def get_gpu_device_vendor(blender, gpu_backend):
|
|||
"--python",
|
||||
str(pathlib.Path(__file__).parent / "gpu_info.py")
|
||||
]
|
||||
try:
|
||||
completed_process = subprocess.run(command, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
for line in completed_process.stdout.splitlines():
|
||||
if line.startswith("GPU_DEVICE_TYPE:"):
|
||||
vendor = line.split(':')[1].upper()
|
||||
return vendor
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
completed_process = subprocess.run(command, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
info = completed_process.stdout.split("<GPU_INFO>")[1].split("</GPU_INFO>")[0]
|
||||
return json.loads(info)
|
||||
|
||||
|
||||
def get_gpu_device_vendor(blender, gpu_backend):
|
||||
return get_gpu_device_info(blender, gpu_backend)["DEVICE_TYPE"]
|
||||
|
||||
|
||||
def get_gpu_device_ray_queries_support(blender, gpu_backend):
|
||||
command = [
|
||||
blender,
|
||||
"--background",
|
||||
"--factory-startup",
|
||||
"--gpu-backend",
|
||||
gpu_backend,
|
||||
"--python-expr",
|
||||
'import gpu; gpu.init(); print("GPU_RAY_QUERIES_SUPPORT:", gpu.capabilities.ray_query_support_get())'
|
||||
]
|
||||
completed_process = subprocess.run(command, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
return "GPU_RAY_QUERIES_SUPPORT: True" in completed_process.stdout
|
||||
|
||||
|
||||
class Report:
|
||||
|
|
|
|||
|
|
@ -37,10 +37,17 @@ BLOCKLIST_AMD_VK = [
|
|||
".*"
|
||||
]
|
||||
|
||||
BLOCKLIST_NON_RT = [
|
||||
"shadows_rt.blend",
|
||||
]
|
||||
|
||||
|
||||
def setup():
|
||||
import bpy
|
||||
|
||||
# The setting will be ignored if the system/backend doesn't support ray queries.
|
||||
bpy.context.preferences.system.use_rt_shadows = not bpy.context.scene.get("Workbench_disable_rt", False)
|
||||
|
||||
for scene in bpy.data.scenes:
|
||||
if scene.get("Workbench_skip_setup", False):
|
||||
continue
|
||||
|
|
@ -113,11 +120,16 @@ def main():
|
|||
if args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_VULKAN
|
||||
|
||||
gpu_vendor = render_report.get_gpu_device_vendor(args.blender, args.gpu_backend)
|
||||
gpu_info = render_report.get_gpu_device_info(args.blender, args.gpu_backend)
|
||||
gpu_vendor = gpu_info["DEVICE_TYPE"]
|
||||
|
||||
if os.getenv("BLENDER_TEST_IGNORE_VENDOR_BLOCKLIST") is None:
|
||||
if gpu_vendor == "AMD" and args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_AMD_VK
|
||||
|
||||
if not gpu_info["RAY_QUERY_SUPPORT"]:
|
||||
blocklist += BLOCKLIST_NON_RT
|
||||
|
||||
report = WorkbenchReport("Workbench", args.outdir, args.oiiotool, variation=args.gpu_backend, blocklist=blocklist)
|
||||
if args.gpu_backend == "vulkan":
|
||||
report.set_compare_engine('workbench', 'opengl')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue