From cce75f185961ebb6433c098e512b5ba8a63d8fc7 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 21 May 2020 10:20:19 +0000 Subject: [PATCH] Add shaders re-implemented in HLSL These were written against the shaders at revision eddd724e7. There have been changes made since then, which will need to be mirrored. See `data/hlsl/README.md` for the current status of each sample. --- data/hlsl/README.md | 100 +++++++ data/hlsl/base/textoverlay.frag | 10 + data/hlsl/base/textoverlay.vert | 21 ++ data/hlsl/base/uioverlay.frag | 15 + data/hlsl/base/uioverlay.vert | 33 +++ data/hlsl/bloom/colorpass.frag | 15 + data/hlsl/bloom/colorpass.vert | 31 ++ data/hlsl/bloom/gaussblur.frag | 43 +++ data/hlsl/bloom/gaussblur.vert | 15 + data/hlsl/bloom/phongpass.frag | 32 +++ data/hlsl/bloom/phongpass.vert | 42 +++ data/hlsl/bloom/skybox.frag | 9 + data/hlsl/bloom/skybox.vert | 22 ++ data/hlsl/compile.py | 73 +++++ data/hlsl/computecloth/cloth.comp | 154 ++++++++++ data/hlsl/computecloth/cloth.frag | 24 ++ data/hlsl/computecloth/cloth.vert | 43 +++ data/hlsl/computecloth/sphere.frag | 20 ++ data/hlsl/computecloth/sphere.vert | 41 +++ data/hlsl/computecullandlod/cull.comp | 115 ++++++++ data/hlsl/computecullandlod/indirectdraw.frag | 18 ++ data/hlsl/computecullandlod/indirectdraw.vert | 46 +++ data/hlsl/computeheadless/headless.comp | 28 ++ data/hlsl/computenbody/particle.frag | 21 ++ data/hlsl/computenbody/particle.vert | 41 +++ .../hlsl/computenbody/particle_calculate.comp | 70 +++++ .../hlsl/computenbody/particle_integrate.comp | 28 ++ data/hlsl/computeparticles/particle.comp | 74 +++++ data/hlsl/computeparticles/particle.frag | 22 ++ data/hlsl/computeparticles/particle.vert | 35 +++ data/hlsl/computeraytracing/raytracing.comp | 272 ++++++++++++++++++ data/hlsl/computeraytracing/texture.frag | 9 + data/hlsl/computeraytracing/texture.vert | 15 + data/hlsl/computeshader/edgedetect.comp | 40 +++ data/hlsl/computeshader/emboss.comp | 40 +++ data/hlsl/computeshader/sharpen.comp | 49 ++++ data/hlsl/computeshader/texture.frag | 9 + data/hlsl/computeshader/texture.vert | 29 ++ data/hlsl/conditionalrender/model.frag | 21 ++ data/hlsl/conditionalrender/model.vert | 57 ++++ data/hlsl/conservativeraster/fullscreen.frag | 9 + data/hlsl/conservativeraster/fullscreen.vert | 15 + data/hlsl/conservativeraster/triangle.frag | 6 + data/hlsl/conservativeraster/triangle.vert | 29 ++ .../conservativeraster/triangleoverlay.frag | 6 + data/hlsl/debugmarker/colorpass.frag | 6 + data/hlsl/debugmarker/colorpass.vert | 29 ++ data/hlsl/debugmarker/postprocess.frag | 36 +++ data/hlsl/debugmarker/postprocess.vert | 15 + data/hlsl/debugmarker/toon.frag | 37 +++ data/hlsl/debugmarker/toon.vert | 44 +++ data/hlsl/deferred/debug.frag | 22 ++ data/hlsl/deferred/debug.vert | 30 ++ data/hlsl/deferred/deferred.frag | 73 +++++ data/hlsl/deferred/deferred.vert | 15 + data/hlsl/deferred/mrt.frag | 40 +++ data/hlsl/deferred/mrt.vert | 54 ++++ data/hlsl/deferredmultisampling/debug.frag | 53 ++++ data/hlsl/deferredmultisampling/debug.vert | 23 ++ data/hlsl/deferredmultisampling/deferred.frag | 104 +++++++ data/hlsl/deferredmultisampling/deferred.vert | 23 ++ data/hlsl/deferredmultisampling/mrt.frag | 40 +++ data/hlsl/deferredmultisampling/mrt.vert | 54 ++++ data/hlsl/deferredshadows/debug.frag | 26 ++ data/hlsl/deferredshadows/debug.vert | 32 +++ data/hlsl/deferredshadows/deferred.frag | 146 ++++++++++ data/hlsl/deferredshadows/deferred.vert | 29 ++ data/hlsl/deferredshadows/mrt.frag | 39 +++ data/hlsl/deferredshadows/mrt.vert | 52 ++++ data/hlsl/deferredshadows/shadow.geom | 39 +++ data/hlsl/deferredshadows/shadow.vert | 15 + data/hlsl/descriptorsets/cube.frag | 16 ++ data/hlsl/descriptorsets/cube.vert | 35 +++ data/hlsl/displacement/base.frag | 26 ++ data/hlsl/displacement/base.vert | 24 ++ data/hlsl/displacement/displacement.tesc | 53 ++++ data/hlsl/displacement/displacement.tese | 54 ++++ data/hlsl/distancefieldfonts/bitmap.frag | 9 + data/hlsl/distancefieldfonts/bitmap.vert | 29 ++ data/hlsl/distancefieldfonts/sdf.frag | 30 ++ data/hlsl/distancefieldfonts/sdf.vert | 29 ++ data/hlsl/dynamicuniformbuffer/base.frag | 6 + data/hlsl/dynamicuniformbuffer/base.vert | 36 +++ data/hlsl/gears/gears.frag | 22 ++ data/hlsl/gears/gears.vert | 42 +++ data/hlsl/geometryshader/base.frag | 6 + data/hlsl/geometryshader/base.vert | 21 ++ data/hlsl/geometryshader/mesh.frag | 21 ++ data/hlsl/geometryshader/mesh.vert | 40 +++ data/hlsl/geometryshader/normaldebug.geom | 43 +++ data/hlsl/hdr/bloom.frag | 62 ++++ data/hlsl/hdr/bloom.vert | 15 + data/hlsl/hdr/composition.frag | 11 + data/hlsl/hdr/composition.vert | 15 + data/hlsl/hdr/gbuffer.frag | 108 +++++++ data/hlsl/hdr/gbuffer.vert | 51 ++++ data/hlsl/imgui/scene.frag | 20 ++ data/hlsl/imgui/scene.vert | 41 +++ data/hlsl/imgui/ui.frag | 15 + data/hlsl/imgui/ui.vert | 33 +++ data/hlsl/indirectdraw/ground.frag | 27 ++ data/hlsl/indirectdraw/ground.vert | 45 +++ data/hlsl/indirectdraw/indirectdraw.frag | 29 ++ data/hlsl/indirectdraw/indirectdraw.vert | 82 ++++++ data/hlsl/indirectdraw/skysphere.frag | 11 + data/hlsl/indirectdraw/skysphere.vert | 30 ++ data/hlsl/inlineuniformblocks/pbr.frag | 119 ++++++++ data/hlsl/inlineuniformblocks/pbr.vert | 38 +++ .../hlsl/inputattachments/attachmentread.frag | 35 +++ .../hlsl/inputattachments/attachmentread.vert | 6 + .../inputattachments/attachmentwrite.frag | 24 ++ .../inputattachments/attachmentwrite.vert | 36 +++ data/hlsl/instancing/instancing.frag | 25 ++ data/hlsl/instancing/instancing.vert | 89 ++++++ data/hlsl/instancing/planet.frag | 25 ++ data/hlsl/instancing/planet.vert | 43 +++ data/hlsl/instancing/starfield.frag | 30 ++ data/hlsl/instancing/starfield.vert | 15 + data/hlsl/mesh/mesh.frag | 26 ++ data/hlsl/mesh/mesh.vert | 44 +++ data/hlsl/multithreading/phong.frag | 20 ++ data/hlsl/multithreading/phong.vert | 49 ++++ data/hlsl/multithreading/starsphere.frag | 35 +++ data/hlsl/multithreading/starsphere.vert | 21 ++ data/hlsl/multiview/multiview.frag | 21 ++ data/hlsl/multiview/multiview.vert | 43 +++ data/hlsl/multiview/viewdisplay.frag | 25 ++ data/hlsl/multiview/viewdisplay.vert | 15 + data/hlsl/negativeviewportheight/quad.frag | 9 + data/hlsl/negativeviewportheight/quad.vert | 21 ++ .../nv_ray_tracing_basic/closesthit.rchit | 18 ++ data/hlsl/nv_ray_tracing_basic/miss.rmiss | 12 + data/hlsl/nv_ray_tracing_basic/raygen.rgen | 39 +++ .../closesthit.rchit | 68 +++++ .../nv_ray_tracing_reflections/miss.rmiss | 25 ++ .../nv_ray_tracing_reflections/raygen.rgen | 64 +++++ .../nv_ray_tracing_shadows/closesthit.rchit | 78 +++++ data/hlsl/nv_ray_tracing_shadows/miss.rmiss | 7 + data/hlsl/nv_ray_tracing_shadows/raygen.rgen | 40 +++ data/hlsl/nv_ray_tracing_shadows/shadow.rmiss | 7 + data/hlsl/occlusionquery/mesh.frag | 28 ++ data/hlsl/occlusionquery/mesh.vert | 44 +++ data/hlsl/occlusionquery/occluder.frag | 6 + data/hlsl/occlusionquery/occluder.vert | 31 ++ data/hlsl/occlusionquery/simple.frag | 6 + data/hlsl/occlusionquery/simple.vert | 23 ++ data/hlsl/offscreen/mirror.frag | 42 +++ data/hlsl/offscreen/mirror.vert | 31 ++ data/hlsl/offscreen/phong.frag | 26 ++ data/hlsl/offscreen/phong.vert | 42 +++ data/hlsl/offscreen/quad.frag | 9 + data/hlsl/offscreen/quad.vert | 28 ++ data/hlsl/parallaxmapping/parallax.frag | 148 ++++++++++ data/hlsl/parallaxmapping/parallax.vert | 48 ++++ data/hlsl/particlefire/normalmap.frag | 44 +++ data/hlsl/particlefire/normalmap.vert | 60 ++++ data/hlsl/particlefire/particle.frag | 52 ++++ data/hlsl/particlefire/particle.vert | 54 ++++ data/hlsl/pbrbasic/pbr.frag | 133 +++++++++ data/hlsl/pbrbasic/pbr.vert | 39 +++ data/hlsl/pbribl/filtercube.vert | 25 ++ data/hlsl/pbribl/genbrdflut.frag | 88 ++++++ data/hlsl/pbribl/genbrdflut.vert | 15 + data/hlsl/pbribl/irradiancecube.frag | 35 +++ data/hlsl/pbribl/pbribl.frag | 170 +++++++++++ data/hlsl/pbribl/pbribl.vert | 43 +++ data/hlsl/pbribl/prefilterenvmap.frag | 106 +++++++ data/hlsl/pbribl/skybox.frag | 37 +++ data/hlsl/pbribl/skybox.vert | 30 ++ data/hlsl/pbrtexture/filtercube.vert | 25 ++ data/hlsl/pbrtexture/genbrdflut.frag | 88 ++++++ data/hlsl/pbrtexture/genbrdflut.vert | 15 + data/hlsl/pbrtexture/irradiancecube.frag | 35 +++ data/hlsl/pbrtexture/pbrtexture.frag | 189 ++++++++++++ data/hlsl/pbrtexture/pbrtexture.vert | 38 +++ data/hlsl/pbrtexture/prefilterenvmap.frag | 106 +++++++ data/hlsl/pbrtexture/skybox.frag | 37 +++ data/hlsl/pbrtexture/skybox.vert | 30 ++ data/hlsl/pipelines/phong.frag | 29 ++ data/hlsl/pipelines/phong.vert | 44 +++ data/hlsl/pipelines/toon.frag | 37 +++ data/hlsl/pipelines/toon.vert | 44 +++ data/hlsl/pipelines/wireframe.frag | 6 + data/hlsl/pipelines/wireframe.vert | 29 ++ data/hlsl/pipelinestatistics/scene.frag | 20 ++ data/hlsl/pipelinestatistics/scene.tesc | 52 ++++ data/hlsl/pipelinestatistics/scene.tese | 39 +++ data/hlsl/pipelinestatistics/scene.vert | 48 ++++ data/hlsl/pushconstants/lights.frag | 37 +++ data/hlsl/pushconstants/lights.vert | 50 ++++ data/hlsl/pushdescriptors/cube.frag | 16 ++ data/hlsl/pushdescriptors/cube.vert | 38 +++ data/hlsl/radialblur/colorpass.frag | 23 ++ data/hlsl/radialblur/colorpass.vert | 32 +++ data/hlsl/radialblur/phongpass.frag | 35 +++ data/hlsl/radialblur/phongpass.vert | 40 +++ data/hlsl/radialblur/radialblur.frag | 35 +++ data/hlsl/radialblur/radialblur.vert | 15 + data/hlsl/renderheadless/triangle.frag | 6 + data/hlsl/renderheadless/triangle.vert | 26 ++ data/hlsl/scenerendering/scene.frag | 34 +++ data/hlsl/scenerendering/scene.vert | 47 +++ data/hlsl/screenshot/mesh.frag | 21 ++ data/hlsl/screenshot/mesh.vert | 41 +++ data/hlsl/shadowmapomni/cubemapdisplay.frag | 53 ++++ data/hlsl/shadowmapomni/cubemapdisplay.vert | 25 ++ data/hlsl/shadowmapomni/offscreen.frag | 14 + data/hlsl/shadowmapomni/offscreen.vert | 34 +++ data/hlsl/shadowmapomni/scene.frag | 43 +++ data/hlsl/shadowmapomni/scene.vert | 45 +++ data/hlsl/shadowmapping/offscreen.frag | 6 + data/hlsl/shadowmapping/offscreen.vert | 13 + data/hlsl/shadowmapping/quad.frag | 18 ++ data/hlsl/shadowmapping/quad.vert | 15 + data/hlsl/shadowmapping/scene.frag | 68 +++++ data/hlsl/shadowmapping/scene.vert | 54 ++++ .../shadowmappingcascade/debugshadowmap.frag | 16 ++ .../shadowmappingcascade/debugshadowmap.vert | 23 ++ data/hlsl/shadowmappingcascade/depthpass.frag | 12 + data/hlsl/shadowmappingcascade/depthpass.vert | 36 +++ data/hlsl/shadowmappingcascade/scene.frag | 131 +++++++++ data/hlsl/shadowmappingcascade/scene.vert | 47 +++ data/hlsl/skeletalanimation/mesh.frag | 26 ++ data/hlsl/skeletalanimation/mesh.vert | 55 ++++ data/hlsl/skeletalanimation/texture.frag | 31 ++ data/hlsl/skeletalanimation/texture.vert | 42 +++ data/hlsl/specializationconstants/uber.frag | 73 +++++ data/hlsl/specializationconstants/uber.vert | 44 +++ data/hlsl/sphericalenvmapping/sem.frag | 21 ++ data/hlsl/sphericalenvmapping/sem.vert | 42 +++ data/hlsl/ssao/blur.frag | 24 ++ data/hlsl/ssao/composition.frag | 56 ++++ data/hlsl/ssao/fullscreen.vert | 15 + data/hlsl/ssao/gbuffer.frag | 34 +++ data/hlsl/ssao/gbuffer.vert | 45 +++ data/hlsl/ssao/ssao.frag | 73 +++++ data/hlsl/stencilbuffer/outline.frag | 6 + data/hlsl/stencilbuffer/outline.vert | 24 ++ data/hlsl/stencilbuffer/toon.frag | 32 +++ data/hlsl/stencilbuffer/toon.vert | 37 +++ data/hlsl/subpasses/composition.frag | 69 +++++ data/hlsl/subpasses/composition.vert | 15 + data/hlsl/subpasses/gbuffer.frag | 45 +++ data/hlsl/subpasses/gbuffer.vert | 44 +++ data/hlsl/subpasses/transparent.frag | 33 +++ data/hlsl/subpasses/transparent.vert | 35 +++ data/hlsl/terraintessellation/skysphere.frag | 10 + data/hlsl/terraintessellation/skysphere.vert | 29 ++ data/hlsl/terraintessellation/terrain.frag | 65 +++++ data/hlsl/terraintessellation/terrain.tesc | 141 +++++++++ data/hlsl/terraintessellation/terrain.tese | 71 +++++ data/hlsl/terraintessellation/terrain.vert | 24 ++ data/hlsl/tessellation/base.frag | 20 ++ data/hlsl/tessellation/base.vert | 24 ++ data/hlsl/tessellation/passthrough.tesc | 46 +++ data/hlsl/tessellation/passthrough.tese | 44 +++ data/hlsl/tessellation/pntriangles.tesc | 128 +++++++++ data/hlsl/tessellation/pntriangles.tese | 126 ++++++++ data/hlsl/textoverlay/mesh.frag | 20 ++ data/hlsl/textoverlay/mesh.vert | 41 +++ data/hlsl/textoverlay/text.frag | 10 + data/hlsl/textoverlay/text.vert | 21 ++ data/hlsl/texture/texture.frag | 27 ++ data/hlsl/texture/texture.vert | 47 +++ data/hlsl/texture3d/texture3d.frag | 27 ++ data/hlsl/texture3d/texture3d.vert | 46 +++ data/hlsl/texturearray/instancing.frag | 9 + data/hlsl/texturearray/instancing.vert | 37 +++ data/hlsl/texturecubemap/reflect.frag | 31 ++ data/hlsl/texturecubemap/reflect.vert | 43 +++ data/hlsl/texturecubemap/skybox.frag | 9 + data/hlsl/texturecubemap/skybox.vert | 25 ++ data/hlsl/texturemipmapgen/texture.frag | 27 ++ data/hlsl/texturemipmapgen/texture.vert | 49 ++++ .../sparseresidency.frag | 36 +++ .../sparseresidency.vert | 45 +++ data/hlsl/triangle/triangle.frag | 6 + data/hlsl/triangle/triangle.vert | 30 ++ data/hlsl/viewportarray/multiview.geom | 56 ++++ data/hlsl/viewportarray/scene.frag | 21 ++ data/hlsl/viewportarray/scene.vert | 24 ++ data/hlsl/vulkanscene/logo.frag | 22 ++ data/hlsl/vulkanscene/logo.vert | 45 +++ data/hlsl/vulkanscene/mesh.frag | 48 ++++ data/hlsl/vulkanscene/mesh.vert | 45 +++ data/hlsl/vulkanscene/skybox.frag | 9 + data/hlsl/vulkanscene/skybox.vert | 23 ++ 287 files changed, 11263 insertions(+) create mode 100644 data/hlsl/README.md create mode 100644 data/hlsl/base/textoverlay.frag create mode 100644 data/hlsl/base/textoverlay.vert create mode 100644 data/hlsl/base/uioverlay.frag create mode 100644 data/hlsl/base/uioverlay.vert create mode 100644 data/hlsl/bloom/colorpass.frag create mode 100644 data/hlsl/bloom/colorpass.vert create mode 100644 data/hlsl/bloom/gaussblur.frag create mode 100644 data/hlsl/bloom/gaussblur.vert create mode 100644 data/hlsl/bloom/phongpass.frag create mode 100644 data/hlsl/bloom/phongpass.vert create mode 100644 data/hlsl/bloom/skybox.frag create mode 100644 data/hlsl/bloom/skybox.vert create mode 100644 data/hlsl/compile.py create mode 100644 data/hlsl/computecloth/cloth.comp create mode 100644 data/hlsl/computecloth/cloth.frag create mode 100644 data/hlsl/computecloth/cloth.vert create mode 100644 data/hlsl/computecloth/sphere.frag create mode 100644 data/hlsl/computecloth/sphere.vert create mode 100644 data/hlsl/computecullandlod/cull.comp create mode 100644 data/hlsl/computecullandlod/indirectdraw.frag create mode 100644 data/hlsl/computecullandlod/indirectdraw.vert create mode 100644 data/hlsl/computeheadless/headless.comp create mode 100644 data/hlsl/computenbody/particle.frag create mode 100644 data/hlsl/computenbody/particle.vert create mode 100644 data/hlsl/computenbody/particle_calculate.comp create mode 100644 data/hlsl/computenbody/particle_integrate.comp create mode 100644 data/hlsl/computeparticles/particle.comp create mode 100644 data/hlsl/computeparticles/particle.frag create mode 100644 data/hlsl/computeparticles/particle.vert create mode 100644 data/hlsl/computeraytracing/raytracing.comp create mode 100644 data/hlsl/computeraytracing/texture.frag create mode 100644 data/hlsl/computeraytracing/texture.vert create mode 100644 data/hlsl/computeshader/edgedetect.comp create mode 100644 data/hlsl/computeshader/emboss.comp create mode 100644 data/hlsl/computeshader/sharpen.comp create mode 100644 data/hlsl/computeshader/texture.frag create mode 100644 data/hlsl/computeshader/texture.vert create mode 100644 data/hlsl/conditionalrender/model.frag create mode 100644 data/hlsl/conditionalrender/model.vert create mode 100644 data/hlsl/conservativeraster/fullscreen.frag create mode 100644 data/hlsl/conservativeraster/fullscreen.vert create mode 100644 data/hlsl/conservativeraster/triangle.frag create mode 100644 data/hlsl/conservativeraster/triangle.vert create mode 100644 data/hlsl/conservativeraster/triangleoverlay.frag create mode 100644 data/hlsl/debugmarker/colorpass.frag create mode 100644 data/hlsl/debugmarker/colorpass.vert create mode 100644 data/hlsl/debugmarker/postprocess.frag create mode 100644 data/hlsl/debugmarker/postprocess.vert create mode 100644 data/hlsl/debugmarker/toon.frag create mode 100644 data/hlsl/debugmarker/toon.vert create mode 100644 data/hlsl/deferred/debug.frag create mode 100644 data/hlsl/deferred/debug.vert create mode 100644 data/hlsl/deferred/deferred.frag create mode 100644 data/hlsl/deferred/deferred.vert create mode 100644 data/hlsl/deferred/mrt.frag create mode 100644 data/hlsl/deferred/mrt.vert create mode 100644 data/hlsl/deferredmultisampling/debug.frag create mode 100644 data/hlsl/deferredmultisampling/debug.vert create mode 100644 data/hlsl/deferredmultisampling/deferred.frag create mode 100644 data/hlsl/deferredmultisampling/deferred.vert create mode 100644 data/hlsl/deferredmultisampling/mrt.frag create mode 100644 data/hlsl/deferredmultisampling/mrt.vert create mode 100644 data/hlsl/deferredshadows/debug.frag create mode 100644 data/hlsl/deferredshadows/debug.vert create mode 100644 data/hlsl/deferredshadows/deferred.frag create mode 100644 data/hlsl/deferredshadows/deferred.vert create mode 100644 data/hlsl/deferredshadows/mrt.frag create mode 100644 data/hlsl/deferredshadows/mrt.vert create mode 100644 data/hlsl/deferredshadows/shadow.geom create mode 100644 data/hlsl/deferredshadows/shadow.vert create mode 100644 data/hlsl/descriptorsets/cube.frag create mode 100644 data/hlsl/descriptorsets/cube.vert create mode 100644 data/hlsl/displacement/base.frag create mode 100644 data/hlsl/displacement/base.vert create mode 100644 data/hlsl/displacement/displacement.tesc create mode 100644 data/hlsl/displacement/displacement.tese create mode 100644 data/hlsl/distancefieldfonts/bitmap.frag create mode 100644 data/hlsl/distancefieldfonts/bitmap.vert create mode 100644 data/hlsl/distancefieldfonts/sdf.frag create mode 100644 data/hlsl/distancefieldfonts/sdf.vert create mode 100644 data/hlsl/dynamicuniformbuffer/base.frag create mode 100644 data/hlsl/dynamicuniformbuffer/base.vert create mode 100644 data/hlsl/gears/gears.frag create mode 100644 data/hlsl/gears/gears.vert create mode 100644 data/hlsl/geometryshader/base.frag create mode 100644 data/hlsl/geometryshader/base.vert create mode 100644 data/hlsl/geometryshader/mesh.frag create mode 100644 data/hlsl/geometryshader/mesh.vert create mode 100644 data/hlsl/geometryshader/normaldebug.geom create mode 100644 data/hlsl/hdr/bloom.frag create mode 100644 data/hlsl/hdr/bloom.vert create mode 100644 data/hlsl/hdr/composition.frag create mode 100644 data/hlsl/hdr/composition.vert create mode 100644 data/hlsl/hdr/gbuffer.frag create mode 100644 data/hlsl/hdr/gbuffer.vert create mode 100644 data/hlsl/imgui/scene.frag create mode 100644 data/hlsl/imgui/scene.vert create mode 100644 data/hlsl/imgui/ui.frag create mode 100644 data/hlsl/imgui/ui.vert create mode 100644 data/hlsl/indirectdraw/ground.frag create mode 100644 data/hlsl/indirectdraw/ground.vert create mode 100644 data/hlsl/indirectdraw/indirectdraw.frag create mode 100644 data/hlsl/indirectdraw/indirectdraw.vert create mode 100644 data/hlsl/indirectdraw/skysphere.frag create mode 100644 data/hlsl/indirectdraw/skysphere.vert create mode 100644 data/hlsl/inlineuniformblocks/pbr.frag create mode 100644 data/hlsl/inlineuniformblocks/pbr.vert create mode 100644 data/hlsl/inputattachments/attachmentread.frag create mode 100644 data/hlsl/inputattachments/attachmentread.vert create mode 100644 data/hlsl/inputattachments/attachmentwrite.frag create mode 100644 data/hlsl/inputattachments/attachmentwrite.vert create mode 100644 data/hlsl/instancing/instancing.frag create mode 100644 data/hlsl/instancing/instancing.vert create mode 100644 data/hlsl/instancing/planet.frag create mode 100644 data/hlsl/instancing/planet.vert create mode 100644 data/hlsl/instancing/starfield.frag create mode 100644 data/hlsl/instancing/starfield.vert create mode 100644 data/hlsl/mesh/mesh.frag create mode 100644 data/hlsl/mesh/mesh.vert create mode 100644 data/hlsl/multithreading/phong.frag create mode 100644 data/hlsl/multithreading/phong.vert create mode 100644 data/hlsl/multithreading/starsphere.frag create mode 100644 data/hlsl/multithreading/starsphere.vert create mode 100644 data/hlsl/multiview/multiview.frag create mode 100644 data/hlsl/multiview/multiview.vert create mode 100644 data/hlsl/multiview/viewdisplay.frag create mode 100644 data/hlsl/multiview/viewdisplay.vert create mode 100644 data/hlsl/negativeviewportheight/quad.frag create mode 100644 data/hlsl/negativeviewportheight/quad.vert create mode 100644 data/hlsl/nv_ray_tracing_basic/closesthit.rchit create mode 100644 data/hlsl/nv_ray_tracing_basic/miss.rmiss create mode 100644 data/hlsl/nv_ray_tracing_basic/raygen.rgen create mode 100644 data/hlsl/nv_ray_tracing_reflections/closesthit.rchit create mode 100644 data/hlsl/nv_ray_tracing_reflections/miss.rmiss create mode 100644 data/hlsl/nv_ray_tracing_reflections/raygen.rgen create mode 100644 data/hlsl/nv_ray_tracing_shadows/closesthit.rchit create mode 100644 data/hlsl/nv_ray_tracing_shadows/miss.rmiss create mode 100644 data/hlsl/nv_ray_tracing_shadows/raygen.rgen create mode 100644 data/hlsl/nv_ray_tracing_shadows/shadow.rmiss create mode 100644 data/hlsl/occlusionquery/mesh.frag create mode 100644 data/hlsl/occlusionquery/mesh.vert create mode 100644 data/hlsl/occlusionquery/occluder.frag create mode 100644 data/hlsl/occlusionquery/occluder.vert create mode 100644 data/hlsl/occlusionquery/simple.frag create mode 100644 data/hlsl/occlusionquery/simple.vert create mode 100644 data/hlsl/offscreen/mirror.frag create mode 100644 data/hlsl/offscreen/mirror.vert create mode 100644 data/hlsl/offscreen/phong.frag create mode 100644 data/hlsl/offscreen/phong.vert create mode 100644 data/hlsl/offscreen/quad.frag create mode 100644 data/hlsl/offscreen/quad.vert create mode 100644 data/hlsl/parallaxmapping/parallax.frag create mode 100644 data/hlsl/parallaxmapping/parallax.vert create mode 100644 data/hlsl/particlefire/normalmap.frag create mode 100644 data/hlsl/particlefire/normalmap.vert create mode 100644 data/hlsl/particlefire/particle.frag create mode 100644 data/hlsl/particlefire/particle.vert create mode 100644 data/hlsl/pbrbasic/pbr.frag create mode 100644 data/hlsl/pbrbasic/pbr.vert create mode 100644 data/hlsl/pbribl/filtercube.vert create mode 100644 data/hlsl/pbribl/genbrdflut.frag create mode 100644 data/hlsl/pbribl/genbrdflut.vert create mode 100644 data/hlsl/pbribl/irradiancecube.frag create mode 100644 data/hlsl/pbribl/pbribl.frag create mode 100644 data/hlsl/pbribl/pbribl.vert create mode 100644 data/hlsl/pbribl/prefilterenvmap.frag create mode 100644 data/hlsl/pbribl/skybox.frag create mode 100644 data/hlsl/pbribl/skybox.vert create mode 100644 data/hlsl/pbrtexture/filtercube.vert create mode 100644 data/hlsl/pbrtexture/genbrdflut.frag create mode 100644 data/hlsl/pbrtexture/genbrdflut.vert create mode 100644 data/hlsl/pbrtexture/irradiancecube.frag create mode 100644 data/hlsl/pbrtexture/pbrtexture.frag create mode 100644 data/hlsl/pbrtexture/pbrtexture.vert create mode 100644 data/hlsl/pbrtexture/prefilterenvmap.frag create mode 100644 data/hlsl/pbrtexture/skybox.frag create mode 100644 data/hlsl/pbrtexture/skybox.vert create mode 100644 data/hlsl/pipelines/phong.frag create mode 100644 data/hlsl/pipelines/phong.vert create mode 100644 data/hlsl/pipelines/toon.frag create mode 100644 data/hlsl/pipelines/toon.vert create mode 100644 data/hlsl/pipelines/wireframe.frag create mode 100644 data/hlsl/pipelines/wireframe.vert create mode 100644 data/hlsl/pipelinestatistics/scene.frag create mode 100644 data/hlsl/pipelinestatistics/scene.tesc create mode 100644 data/hlsl/pipelinestatistics/scene.tese create mode 100644 data/hlsl/pipelinestatistics/scene.vert create mode 100644 data/hlsl/pushconstants/lights.frag create mode 100644 data/hlsl/pushconstants/lights.vert create mode 100644 data/hlsl/pushdescriptors/cube.frag create mode 100644 data/hlsl/pushdescriptors/cube.vert create mode 100644 data/hlsl/radialblur/colorpass.frag create mode 100644 data/hlsl/radialblur/colorpass.vert create mode 100644 data/hlsl/radialblur/phongpass.frag create mode 100644 data/hlsl/radialblur/phongpass.vert create mode 100644 data/hlsl/radialblur/radialblur.frag create mode 100644 data/hlsl/radialblur/radialblur.vert create mode 100644 data/hlsl/renderheadless/triangle.frag create mode 100644 data/hlsl/renderheadless/triangle.vert create mode 100644 data/hlsl/scenerendering/scene.frag create mode 100644 data/hlsl/scenerendering/scene.vert create mode 100644 data/hlsl/screenshot/mesh.frag create mode 100644 data/hlsl/screenshot/mesh.vert create mode 100644 data/hlsl/shadowmapomni/cubemapdisplay.frag create mode 100644 data/hlsl/shadowmapomni/cubemapdisplay.vert create mode 100644 data/hlsl/shadowmapomni/offscreen.frag create mode 100644 data/hlsl/shadowmapomni/offscreen.vert create mode 100644 data/hlsl/shadowmapomni/scene.frag create mode 100644 data/hlsl/shadowmapomni/scene.vert create mode 100644 data/hlsl/shadowmapping/offscreen.frag create mode 100644 data/hlsl/shadowmapping/offscreen.vert create mode 100644 data/hlsl/shadowmapping/quad.frag create mode 100644 data/hlsl/shadowmapping/quad.vert create mode 100644 data/hlsl/shadowmapping/scene.frag create mode 100644 data/hlsl/shadowmapping/scene.vert create mode 100644 data/hlsl/shadowmappingcascade/debugshadowmap.frag create mode 100644 data/hlsl/shadowmappingcascade/debugshadowmap.vert create mode 100644 data/hlsl/shadowmappingcascade/depthpass.frag create mode 100644 data/hlsl/shadowmappingcascade/depthpass.vert create mode 100644 data/hlsl/shadowmappingcascade/scene.frag create mode 100644 data/hlsl/shadowmappingcascade/scene.vert create mode 100644 data/hlsl/skeletalanimation/mesh.frag create mode 100644 data/hlsl/skeletalanimation/mesh.vert create mode 100644 data/hlsl/skeletalanimation/texture.frag create mode 100644 data/hlsl/skeletalanimation/texture.vert create mode 100644 data/hlsl/specializationconstants/uber.frag create mode 100644 data/hlsl/specializationconstants/uber.vert create mode 100644 data/hlsl/sphericalenvmapping/sem.frag create mode 100644 data/hlsl/sphericalenvmapping/sem.vert create mode 100644 data/hlsl/ssao/blur.frag create mode 100644 data/hlsl/ssao/composition.frag create mode 100644 data/hlsl/ssao/fullscreen.vert create mode 100644 data/hlsl/ssao/gbuffer.frag create mode 100644 data/hlsl/ssao/gbuffer.vert create mode 100644 data/hlsl/ssao/ssao.frag create mode 100644 data/hlsl/stencilbuffer/outline.frag create mode 100644 data/hlsl/stencilbuffer/outline.vert create mode 100644 data/hlsl/stencilbuffer/toon.frag create mode 100644 data/hlsl/stencilbuffer/toon.vert create mode 100644 data/hlsl/subpasses/composition.frag create mode 100644 data/hlsl/subpasses/composition.vert create mode 100644 data/hlsl/subpasses/gbuffer.frag create mode 100644 data/hlsl/subpasses/gbuffer.vert create mode 100644 data/hlsl/subpasses/transparent.frag create mode 100644 data/hlsl/subpasses/transparent.vert create mode 100644 data/hlsl/terraintessellation/skysphere.frag create mode 100644 data/hlsl/terraintessellation/skysphere.vert create mode 100644 data/hlsl/terraintessellation/terrain.frag create mode 100644 data/hlsl/terraintessellation/terrain.tesc create mode 100644 data/hlsl/terraintessellation/terrain.tese create mode 100644 data/hlsl/terraintessellation/terrain.vert create mode 100644 data/hlsl/tessellation/base.frag create mode 100644 data/hlsl/tessellation/base.vert create mode 100644 data/hlsl/tessellation/passthrough.tesc create mode 100644 data/hlsl/tessellation/passthrough.tese create mode 100644 data/hlsl/tessellation/pntriangles.tesc create mode 100644 data/hlsl/tessellation/pntriangles.tese create mode 100644 data/hlsl/textoverlay/mesh.frag create mode 100644 data/hlsl/textoverlay/mesh.vert create mode 100644 data/hlsl/textoverlay/text.frag create mode 100644 data/hlsl/textoverlay/text.vert create mode 100644 data/hlsl/texture/texture.frag create mode 100644 data/hlsl/texture/texture.vert create mode 100644 data/hlsl/texture3d/texture3d.frag create mode 100644 data/hlsl/texture3d/texture3d.vert create mode 100644 data/hlsl/texturearray/instancing.frag create mode 100644 data/hlsl/texturearray/instancing.vert create mode 100644 data/hlsl/texturecubemap/reflect.frag create mode 100644 data/hlsl/texturecubemap/reflect.vert create mode 100644 data/hlsl/texturecubemap/skybox.frag create mode 100644 data/hlsl/texturecubemap/skybox.vert create mode 100644 data/hlsl/texturemipmapgen/texture.frag create mode 100644 data/hlsl/texturemipmapgen/texture.vert create mode 100644 data/hlsl/texturesparseresidency/sparseresidency.frag create mode 100644 data/hlsl/texturesparseresidency/sparseresidency.vert create mode 100644 data/hlsl/triangle/triangle.frag create mode 100644 data/hlsl/triangle/triangle.vert create mode 100644 data/hlsl/viewportarray/multiview.geom create mode 100644 data/hlsl/viewportarray/scene.frag create mode 100644 data/hlsl/viewportarray/scene.vert create mode 100644 data/hlsl/vulkanscene/logo.frag create mode 100644 data/hlsl/vulkanscene/logo.vert create mode 100644 data/hlsl/vulkanscene/mesh.frag create mode 100644 data/hlsl/vulkanscene/mesh.vert create mode 100644 data/hlsl/vulkanscene/skybox.frag create mode 100644 data/hlsl/vulkanscene/skybox.vert diff --git a/data/hlsl/README.md b/data/hlsl/README.md new file mode 100644 index 00000000..e11a70bf --- /dev/null +++ b/data/hlsl/README.md @@ -0,0 +1,100 @@ +## HLSL Shaders + +This directory contains a fork of the shaders found in [data/shaders](https://github.com/SaschaWillems/Vulkan/tree/master/data/shaders), re-written in HLSL. +These can be compiled with [DXC](https://github.com/microsoft/DirectXShaderCompiler) using the `compile.py` script. + +### Status + +Tested on Ubuntu 18.04 + GeForce RTX 2080 Ti + + +Shaders written to mirror the GLSL versions at `eddd724`. There have been changes made to the GLSL shaders since then, which will need to be updated. + + +| Name | GLSL @`eddd724e7` | HLSL @`eddd724e7` | GLSL @`10a1ecaf7` | HLSL @`eddd724e7` +|----------------------------|-------------------|-------------------|-------------------|------------------- +| bloom | ☑ | ☑ | ☑ | ☑ +| computecloth | ☑ | ☑ | ☑ | ☑ +| computecullandlod | ☑ | ☑ | ☑ | ☑ +| computeheadless | ☑ | ☑ | ☑ | ☑ +| computenbody | ☑ | ☑ | ☑ | ☑ +| computeparticles | ☑ | ❌ | ☑ | ❌ +| computeraytracing | ☑ | ☑ | ☑ | ☑ +| computeshader | ☑ | ☑ | ☑ | ☑ +| conditionalrender | ☑ | ☑ | ☑ | ☑ +| conservativeraster | ☑ | ☑ | ☑ | ☑ +| debugmarker | ☑ | ☑ | ☑ | ☑ +| deferred | ☑ | ☑ | ☑ | ☑ +| deferredmultisampling | ☑ | ☑ | ☑ | ☑ +| deferredshadows | ☑ | ☑ | ☑ | ☑ +| descriptorsets | ☑ | ☑ | ☑ | ☑ +| displacement | ☑ | ☑ | ☑ | ☑ +| distancefieldfonts | ☑ | ☑ | ☑ | ☑ +| dynamicuniformbuffer | ☑ | ☑ | ☑ | ☑ +| gears | ☑ | ☑ | ☑ | ☑ +| geometryshader | ☑ | ☑ | ☑ | ☑ +| gltfscene | - | - | ☑ | ❌ +| hdr | ☑ | ❌ | ☑ | ❌ +| imgui | ☑ | ☑ | ☑ | ☑ +| indirectdraw | ☑ | ☑ | ☑ | ☑ +| inlineuniformblocks | ☑ | ☑ | ☑ | ☑ +| inputattachments | ☑ | ☑ | ☑ | ☑ +| instancing | ☑ | ☑ | ☑ | ☑ +| mesh | ☑ | ☑ | ❌ | ☑ +| multisampling | ☑ | ☑ | ☑ | ❌ +| multithreading | ☑ | ☑ | ☑ | ☑ +| multiview | ☑ | ☑ | ☑ | ☑ +| negativeviewportheight | ☑ | ☑ | ☑ | ☑ +| nv_ray_tracing_basic | ☑ | ☑ | ☑ | ☑ +| nv_ray_tracing_reflections | ☑ | ☑ | ☑ | ☑ +| nv_ray_tracing_shadows | ☑ | ☑ | ☑ | ☑ +| occlusionquery | ☑ | ☑ | ☑ | ☑ +| offscreen | ☑ | ☑ | ☑ | ❌ +| parallaxmapping | ☑ | ☑ | ☑ | ☑ +| particlefire | ☑ | ☑ | ☑ | ☑ +| pbrbasic | ☑ | ☑ | ☑ | ☑ +| pbribl | ☑ | ☑ | ☑ | ☑ +| pbrtexture | ☑ | ☑ | ☑ | ☑ +| pipelines | ☑ | ☑ | ☑ | ☑ +| pipelinestatistics | ☑ | ☑ | ☑ | ☑ +| pushconstants | ☑ | ☑ | ☑ | ☑ +| pushdescriptors | ☑ | ☑ | ☑ | ☑ +| radialblur | ☑ | ☑ | ☑ | ☑ +| renderheadless | ☑ | ☑ | ☑ | ☑ +| scenerendering | ☑ | ☑ | ☑ | ☑ +| screenshot | ☑ | ☑ | ☑ | ☑ +| shadowmapping | ☑ | ☑ | ☑ | ☑ +| shadowmappingcascade | ☑ | ☑ | ☑ | ☑ +| shadowmappingomni | ☑ | ☑ | ☑ | ☑ +| skeletalanimation | ☑ | ☑ | ☑ | ❌ +| specializationconstants | ☑ | ☑ | ☑ | ☑ +| sphericalenvmapping | ☑ | ☑ | ☑ | ☑ +| ssao | ☑ | ☑ | ☑ | ☑ +| stencilbuffer | ☑ | ☑ | ☑ | ☑ +| subpasses | ☑ | ☑ | ☑ | ☑ +| terraintessellation | ☑ | ☑ | ☑ | ☑ +| tessellation | ☑ | ☑ | ☑ | ☑ +| textoverlay | ☑ | ☑ | ☑ | ☑ +| texture | ☑ | ☑ | ☑ | ☑ +| texture3d | ☑ | ☑ | ☑ | ☑ +| texturearray | ☑ | ☑ | ☑ | ☑ +| texturecubemap | ☑ | ❌ | ☑ | ❌ +| texturemipmapgen | ☑ | ☑ | ☑ | ☑ +| texturesparseresidency | ☑ | ☑ | ☑ | ☑ +| triangle | ☑ | ☑ | ☑ | ☑ +| viewportarray | ☑ | ☑ | ☑ | ☑ +| vulkanscene | ☑ | ☑ | ☑ | ☑ + +### Known issues + +- specialization constants can't be used to specify array size. +- `gl_PointCoord` not supported. HLSL has no equivalent. We changed the shaders to calulate the PointCoord manually in the shader. (`computenbody`, `computeparticles`, `particlefire` examples). +- HLSL doesn't have inverse operation (`deferred`, `hdr`, `instancing`, `skeletalanimation` & `texturecubemap` examples). +- `modf` causes compilation to fail without errors or warnings. (`modf` not used by any examples, easily confused with fmod) +- In `specializationconstants` example, shader compilation fails with error: + ``` + --- Error msg: fatal error: failed to optimize SPIR-V: Id 10 is defined more than once + ``` + When multiple constant ids are defined and have different types. We work around this problem by making all constant ids the same type, then use `asfloat`, `asint` or `asuint` to get the original value in the shader. +- `gl_RayTmaxNV` not supported. (`nv_ray_tracing_*` examples) +- HLSL interface for sparse residency textures is different from GLSL interface. After translating from HLSL to GLSL the shaders behave slightly different. Most important parts do behave identically though. \ No newline at end of file diff --git a/data/hlsl/base/textoverlay.frag b/data/hlsl/base/textoverlay.frag new file mode 100644 index 00000000..e9d9ba76 --- /dev/null +++ b/data/hlsl/base/textoverlay.frag @@ -0,0 +1,10 @@ +// Copyright 2020 Google LLC + +Texture2D textureFont : register(t0); +SamplerState samplerFont : register(s0); + +float4 main([[vk::location(0)]]float2 inUV : TEXCOORD0) : SV_TARGET +{ + float color = textureFont.Sample(samplerFont, inUV).r; + return float4(color.xxx, 1.0); +} diff --git a/data/hlsl/base/textoverlay.vert b/data/hlsl/base/textoverlay.vert new file mode 100644 index 00000000..a040eaaa --- /dev/null +++ b/data/hlsl/base/textoverlay.vert @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ + [[vk::location(0)]]float2 Pos : POSITION0; + [[vk::location(1)]]float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]]float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos, 0.0, 1.0); + output.UV = input.UV; + return output; +} diff --git a/data/hlsl/base/uioverlay.frag b/data/hlsl/base/uioverlay.frag new file mode 100644 index 00000000..9bec808d --- /dev/null +++ b/data/hlsl/base/uioverlay.frag @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +Texture2D fontTexture : register(t0); +SamplerState fontSampler : register(s0); + +struct VSOutput +{ + [[vk::location(0)]]float2 UV : TEXCOORD0; + [[vk::location(1)]]float4 Color : COLOR0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return input.Color * fontTexture.Sample(fontSampler, input.UV); +} \ No newline at end of file diff --git a/data/hlsl/base/uioverlay.vert b/data/hlsl/base/uioverlay.vert new file mode 100644 index 00000000..be30fd74 --- /dev/null +++ b/data/hlsl/base/uioverlay.vert @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ + [[vk::location(0)]]float2 Pos : POSITION0; + [[vk::location(1)]]float2 UV : TEXCOORD0; + [[vk::location(2)]]float4 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]]float2 UV : TEXCOORD0; + [[vk::location(1)]]float4 Color : COLOR0; +}; + +struct PushConstants +{ + float2 scale; + float2 translate; +}; + +[[vk::push_constant]] +PushConstants pushConstants; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos * pushConstants.scale + pushConstants.translate, 0.0, 1.0); + output.UV = input.UV; + output.Color = input.Color; + return output; +} \ No newline at end of file diff --git a/data/hlsl/bloom/colorpass.frag b/data/hlsl/bloom/colorpass.frag new file mode 100644 index 00000000..9949fd3f --- /dev/null +++ b/data/hlsl/bloom/colorpass.frag @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +Texture2D colorMapTexture : register(t1); +SamplerState colorMapSampler : register(s1); + +struct VSOutput +{ + [[vk::location(0)]]float3 Color : COLOR0; + [[vk::location(1)]]float2 UV : TEXCOORD0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return float4(input.Color, 1); +} \ No newline at end of file diff --git a/data/hlsl/bloom/colorpass.vert b/data/hlsl/bloom/colorpass.vert new file mode 100644 index 00000000..53dad1b2 --- /dev/null +++ b/data/hlsl/bloom/colorpass.vert @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ + [[vk::location(0)]]float4 Pos : POSITION0; + [[vk::location(1)]]float2 UV : TEXCOORD0; + [[vk::location(2)]]float3 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]]float3 Color : COLOR0; + [[vk::location(1)]]float2 UV : TEXCOORD0; +}; + +cbuffer UBO : register(b0) +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Color = input.Color; + output.Pos = mul(projection, mul(view, mul(model, input.Pos))); + return output; +} diff --git a/data/hlsl/bloom/gaussblur.frag b/data/hlsl/bloom/gaussblur.frag new file mode 100644 index 00000000..5da50569 --- /dev/null +++ b/data/hlsl/bloom/gaussblur.frag @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +cbuffer UBO : register(b0) +{ + float blurScale; + float blurStrength; +}; + +[[vk::constant_id(0)]] const int blurdirection = 0; + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float weight[5]; + weight[0] = 0.227027; + weight[1] = 0.1945946; + weight[2] = 0.1216216; + weight[3] = 0.054054; + weight[4] = 0.016216; + + float2 textureSize; + textureColor.GetDimensions(textureSize.x, textureSize.y); + float2 tex_offset = 1.0 / textureSize * blurScale; // gets size of single texel + float3 result = textureColor.Sample(samplerColor, inUV).rgb * weight[0]; // current fragment's contribution + for(int i = 1; i < 5; ++i) + { + if (blurdirection == 1) + { + // H + result += textureColor.Sample(samplerColor, inUV + float2(tex_offset.x * i, 0.0)).rgb * weight[i] * blurStrength; + result += textureColor.Sample(samplerColor, inUV - float2(tex_offset.x * i, 0.0)).rgb * weight[i] * blurStrength; + } + else + { + // V + result += textureColor.Sample(samplerColor, inUV + float2(0.0, tex_offset.y * i)).rgb * weight[i] * blurStrength; + result += textureColor.Sample(samplerColor, inUV - float2(0.0, tex_offset.y * i)).rgb * weight[i] * blurStrength; + } + } + return float4(result, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/bloom/gaussblur.vert b/data/hlsl/bloom/gaussblur.vert new file mode 100644 index 00000000..a9c3d551 --- /dev/null +++ b/data/hlsl/bloom/gaussblur.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/bloom/phongpass.frag b/data/hlsl/bloom/phongpass.frag new file mode 100644 index 00000000..3daed2c2 --- /dev/null +++ b/data/hlsl/bloom/phongpass.frag @@ -0,0 +1,32 @@ +// Copyright 2020 Google LLC + +Texture2D colorMapTexture : register(t1); +SamplerState colorMapSampler : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 ambient = float3(0.0f, 0.0f, 0.0f); + + // Adjust light calculations for glow color + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + ambient = input.Color * 0.25; + } + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75f, 0.75f, 0.75f); + return float4(ambient + diffuse + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/bloom/phongpass.vert b/data/hlsl/bloom/phongpass.vert new file mode 100644 index 00000000..198c77c6 --- /dev/null +++ b/data/hlsl/bloom/phongpass.vert @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +cbuffer UBO : register(b0) +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(projection, mul(view, mul(model, input.Pos))); + + float3 lightPos = float3(-5.0, -5.0, 0.0); + float4 pos = mul(view, mul(model, input.Pos)); + output.Normal = mul((float4x3)mul(view, model), input.Normal).xyz; + output.LightVec = lightPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/bloom/skybox.frag b/data/hlsl/bloom/skybox.frag new file mode 100644 index 00000000..18460ed9 --- /dev/null +++ b/data/hlsl/bloom/skybox.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +TextureCube textureCubeMap : register(t1); +SamplerState samplerCubeMap : register(s1); + +float4 main([[vk::location(0)]] float3 inUVW : NORMAL0) : SV_TARGET +{ + return textureCubeMap.Sample(samplerCubeMap, inUVW); +} \ No newline at end of file diff --git a/data/hlsl/bloom/skybox.vert b/data/hlsl/bloom/skybox.vert new file mode 100644 index 00000000..212e404f --- /dev/null +++ b/data/hlsl/bloom/skybox.vert @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC + +cbuffer UBO : register(b0) +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float3 UVW : NORMAL0; +}; + +VSOutput main([[vk::location(0)]] float3 inPos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.UVW = inPos; + output.Pos = mul(projection, mul(view, mul(model, float4(inPos.xyz, 1.0)))); + return output; +} diff --git a/data/hlsl/compile.py b/data/hlsl/compile.py new file mode 100644 index 00000000..bad1f59b --- /dev/null +++ b/data/hlsl/compile.py @@ -0,0 +1,73 @@ +# Copyright 2020 Google LLC + +import argparse +import fileinput +import os +import subprocess +import sys + +parser = argparse.ArgumentParser(description='Compile all .hlsl shaders') +parser.add_argument('--dxc', type=str, help='path to DXC executable') +args = parser.parse_args() + +def findDXC(): + def isExe(path): + return os.path.isfile(path) and os.access(path, os.X_OK) + + if args.dxc != None and isExe(args.dxc): + return args.dxc + + exe_name = "dxc" + if os.name == "nt": + exe_name += ".exe" + + for exe_dir in os.environ["PATH"].split(os.pathsep): + full_path = os.path.join(exe_dir, exe_name) + if isExe(full_path): + return full_path + + sys.exit("Could not find DXC executable on PATH, and was not specified with --dxc") + +dxc_path = findDXC() +dir_path = os.path.dirname(os.path.realpath(__file__)) +dir_path = dir_path.replace('\\', '/') +for root, dirs, files in os.walk(dir_path): + for file in files: + if file.endswith(".vert") or file.endswith(".frag") or file.endswith(".comp") or file.endswith(".geom") or file.endswith(".tesc") or file.endswith(".tese") or file.endswith(".rgen") or file.endswith(".rchit") or file.endswith(".rmiss"): + hlsl_file = os.path.join(root, file) + + spv_out = os.path.abspath(os.path.join(dir_path, "..", "shaders", os.path.relpath(hlsl_file, dir_path) + ".spv")) + + # Make the spv directory if it does not already exist + spv_dir = os.path.dirname(spv_out) + if not os.path.exists(spv_dir): + os.makedirs(spv_dir) + + profile = '' + if(hlsl_file.find('.vert') != -1): + profile = 'vs_6_1' + elif(hlsl_file.find('.frag') != -1): + profile = 'ps_6_1' + elif(hlsl_file.find('.comp') != -1): + profile = 'cs_6_1' + elif(hlsl_file.find('.geom') != -1): + profile = 'gs_6_1' + elif(hlsl_file.find('.tesc') != -1): + profile = 'hs_6_1' + elif(hlsl_file.find('.tese') != -1): + profile = 'ds_6_1' + elif(hlsl_file.find('.rgen') != -1 or + hlsl_file.find('.rchit') != -1 or + hlsl_file.find('.rmiss') != -1): + profile = 'lib_6_3' + + print('Compiling %s' % (hlsl_file)) + subprocess.check_output([ + dxc_path, + '-spirv', + '-T', profile, + '-E', 'main', + '-fspv-extension=SPV_NV_ray_tracing', + '-fspv-extension=SPV_KHR_multiview', + hlsl_file, + '-Fo', spv_out]) diff --git a/data/hlsl/computecloth/cloth.comp b/data/hlsl/computecloth/cloth.comp new file mode 100644 index 00000000..2ef2b880 --- /dev/null +++ b/data/hlsl/computecloth/cloth.comp @@ -0,0 +1,154 @@ +// Copyright 2020 Google LLC + +struct Particle { + float4 pos; + float4 vel; + float4 uv; + float4 normal; + float pinned; +}; + +[[vk::binding(0)]] +StructuredBuffer particleIn; +[[vk::binding(1)]] +RWStructuredBuffer particleOut; + +struct UBO +{ + float deltaT; + float particleMass; + float springStiffness; + float damping; + float restDistH; + float restDistV; + float restDistD; + float sphereRadius; + float4 spherePos; + float4 gravity; + int2 particleCount; +}; + +cbuffer ubo : register(b2) +{ + UBO params; +}; + +struct PushConstants +{ + uint calculateNormals; +}; + +[[vk::push_constant]] +PushConstants pushConstants; + +float3 springForce(float3 p0, float3 p1, float restDist) +{ + float3 dist = p0 - p1; + return normalize(dist) * params.springStiffness * (length(dist) - restDist); +} + +[numthreads(10, 10, 1)] +void main(uint3 id : SV_DispatchThreadID) +{ + uint index = id.y * params.particleCount.x + id.x; + if (index > params.particleCount.x * params.particleCount.y) + return; + + // Pinned? + if (particleIn[index].pinned == 1.0) { + particleOut[index].pos = particleOut[index].pos; + particleOut[index].vel = float4(0, 0, 0, 0); + return; + } + + // Initial force from gravity + float3 force = params.gravity.xyz * params.particleMass; + + float3 pos = particleIn[index].pos.xyz; + float3 vel = particleIn[index].vel.xyz; + + // Spring forces from neighboring particles + // left + if (id.x > 0) { + force += springForce(particleIn[index-1].pos.xyz, pos, params.restDistH); + } + // right + if (id.x < params.particleCount.x - 1) { + force += springForce(particleIn[index + 1].pos.xyz, pos, params.restDistH); + } + // upper + if (id.y < params.particleCount.y - 1) { + force += springForce(particleIn[index + params.particleCount.x].pos.xyz, pos, params.restDistV); + } + // lower + if (id.y > 0) { + force += springForce(particleIn[index - params.particleCount.x].pos.xyz, pos, params.restDistV); + } + // upper-left + if ((id.x > 0) && (id.y < params.particleCount.y - 1)) { + force += springForce(particleIn[index + params.particleCount.x - 1].pos.xyz, pos, params.restDistD); + } + // lower-left + if ((id.x > 0) && (id.y > 0)) { + force += springForce(particleIn[index - params.particleCount.x - 1].pos.xyz, pos, params.restDistD); + } + // upper-right + if ((id.x < params.particleCount.x - 1) && (id.y < params.particleCount.y - 1)) { + force += springForce(particleIn[index + params.particleCount.x + 1].pos.xyz, pos, params.restDistD); + } + // lower-right + if ((id.x < params.particleCount.x - 1) && (id.y > 0)) { + force += springForce(particleIn[index - params.particleCount.x + 1].pos.xyz, pos, params.restDistD); + } + + force += (-params.damping * vel); + + // Integrate + float3 f = force * (1.0 / params.particleMass); + particleOut[index].pos = float4(pos + vel * params.deltaT + 0.5 * f * params.deltaT * params.deltaT, 1.0); + particleOut[index].vel = float4(vel + f * params.deltaT, 0.0); + + // Sphere collision + float3 sphereDist = particleOut[index].pos.xyz - params.spherePos.xyz; + if (length(sphereDist) < params.sphereRadius + 0.01) { + // If the particle is inside the sphere, push it to the outer radius + particleOut[index].pos.xyz = params.spherePos.xyz + normalize(sphereDist) * (params.sphereRadius + 0.01); + // Cancel out velocity + particleOut[index].vel = float4(0, 0, 0, 0); + } + + // Normals + if (pushConstants.calculateNormals == 1) { + float3 normal = float3(0, 0, 0); + float3 a, b, c; + if (id.y > 0) { + if (id.x > 0) { + a = particleIn[index - 1].pos.xyz - pos; + b = particleIn[index - params.particleCount.x - 1].pos.xyz - pos; + c = particleIn[index - params.particleCount.x].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + if (id.x < params.particleCount.x - 1) { + a = particleIn[index - params.particleCount.x].pos.xyz - pos; + b = particleIn[index - params.particleCount.x + 1].pos.xyz - pos; + c = particleIn[index + 1].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + } + if (id.y < params.particleCount.y - 1) { + if (id.x > 0) { + a = particleIn[index + params.particleCount.x].pos.xyz - pos; + b = particleIn[index + params.particleCount.x - 1].pos.xyz - pos; + c = particleIn[index - 1].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + if (id.x < params.particleCount.x - 1) { + a = particleIn[index + 1].pos.xyz - pos; + b = particleIn[index + params.particleCount.x + 1].pos.xyz - pos; + c = particleIn[index + params.particleCount.x].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + } + particleOut[index].normal = float4(normalize(normal), 0.0f); + } +} \ No newline at end of file diff --git a/data/hlsl/computecloth/cloth.frag b/data/hlsl/computecloth/cloth.frag new file mode 100644 index 00000000..46612dc3 --- /dev/null +++ b/data/hlsl/computecloth/cloth.frag @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]]float2 UV : TEXCOORD0; +[[vk::location(1)]]float3 Normal : NORMAL0; +[[vk::location(2)]]float3 ViewVec : TEXCOORD1; +[[vk::location(3)]]float3 LightVec : TEXCOORD2; +}; + +float4 main (VSOutput input) : SV_TARGET +{ + float3 color = textureColor.Sample(samplerColor, input.UV).rgb; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.15) * float3(1, 1, 1); + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.2, 0.2, 0.2); + return float4(diffuse * color.rgb + specular, 1.0); +} diff --git a/data/hlsl/computecloth/cloth.vert b/data/hlsl/computecloth/cloth.vert new file mode 100644 index 00000000..00d46927 --- /dev/null +++ b/data/hlsl/computecloth/cloth.vert @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) +{ + UBO ubo; +}; + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Normal = input.Normal.xyz; + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + output.Pos = mul(ubo.projection, eyePos); + float4 pos = float4(input.Pos, 1.0); + float3 lPos = ubo.lightPos.xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/computecloth/sphere.frag b/data/hlsl/computecloth/sphere.frag new file mode 100644 index 00000000..207db7aa --- /dev/null +++ b/data/hlsl/computecloth/sphere.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 ViewVec : TEXCOORD0; +[[vk::location(2)]] float3 LightVec : TEXCOORD1; +}; + +float4 main (VSOutput input) : SV_TARGET +{ + float3 color = float3(0.5, 0.5, 0.5); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.15); + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + return float4(diffuse * color.rgb + specular, 1.0); +} diff --git a/data/hlsl/computecloth/sphere.vert b/data/hlsl/computecloth/sphere.vert new file mode 100644 index 00000000..8414cb58 --- /dev/null +++ b/data/hlsl/computecloth/sphere.vert @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]]float3 Pos : POSITION0; +[[vk::location(2)]]float3 Normal : NORMAL0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 ViewVec : TEXCOORD0; +[[vk::location(2)]] float3 LightVec : TEXCOORD1; +}; + + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) +{ + UBO ubo; +}; + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + output.Pos = mul(ubo.projection, eyePos); + float4 pos = float4(input.Pos, 1.0); + float3 lPos = ubo.lightPos.xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + output.Normal = input.Normal; + return output; +} \ No newline at end of file diff --git a/data/hlsl/computecullandlod/cull.comp b/data/hlsl/computecullandlod/cull.comp new file mode 100644 index 00000000..39d70c74 --- /dev/null +++ b/data/hlsl/computecullandlod/cull.comp @@ -0,0 +1,115 @@ +// Copyright 2020 Google LLC + +#define MAX_LOD_LEVEL_COUNT 6 +[[vk::constant_id(0)]] const int MAX_LOD_LEVEL = 5; + +struct InstanceData +{ + float3 pos; + float scale; +}; + +StructuredBuffer instances : register(t0); + +// Same layout as VkDrawIndexedIndirectCommand +struct IndexedIndirectCommand +{ + uint indexCount; + uint instanceCount; + uint firstIndex; + uint vertexOffset; + uint firstInstance; +}; + +RWStructuredBuffer indirectDraws : register(u1); + +// Binding 2: Uniform block object with matrices +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 cameraPos; + float4 frustumPlanes[6]; +}; + +cbuffer ubo : register(b2) { UBO ubo; } + +// Binding 3: Indirect draw stats +struct UBOOut +{ + uint drawCount; + uint lodCount[MAX_LOD_LEVEL_COUNT]; +}; +RWStructuredBuffer uboOut : register(u3); + +// Binding 4: level-of-detail information +struct LOD +{ + uint firstIndex; + uint indexCount; + float distance; + float _pad0; +}; + +StructuredBuffer lods : register(t4); + +[numthreads(16, 1, 1)] +bool frustumCheck(float4 pos, float radius) +{ + // Check sphere against frustum planes + for (int i = 0; i < 6; i++) + { + if (dot(pos, ubo.frustumPlanes[i]) + radius < 0.0) + { + return false; + } + } + return true; +} + +[numthreads(16, 1, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID ) +{ + uint idx = GlobalInvocationID.x; + uint temp; + + // Clear stats on first invocation + if (idx == 0) + { + InterlockedExchange(uboOut[0].drawCount, 0, temp); + for (uint i = 0; i < MAX_LOD_LEVEL + 1; i++) + { + InterlockedExchange(uboOut[0].lodCount[i], 0, temp); + } + } + + float4 pos = float4(instances[idx].pos.xyz, 1.0); + + // Check if object is within current viewing frustum + if (frustumCheck(pos, 1.0)) + { + indirectDraws[idx].instanceCount = 1; + + // Increase number of indirect draw counts + InterlockedAdd(uboOut[0].drawCount, 1, temp); + + // Select appropriate LOD level based on distance to camera + uint lodLevel = MAX_LOD_LEVEL; + for (uint i = 0; i < MAX_LOD_LEVEL; i++) + { + if (distance(instances[idx].pos.xyz, ubo.cameraPos.xyz) < lods[i].distance) + { + lodLevel = i; + break; + } + } + indirectDraws[idx].firstIndex = lods[lodLevel].firstIndex; + indirectDraws[idx].indexCount = lods[lodLevel].indexCount; + // Update stats + InterlockedAdd(uboOut[0].lodCount[lodLevel], 1, temp); + } + else + { + indirectDraws[idx].instanceCount = 0; + } +} \ No newline at end of file diff --git a/data/hlsl/computecullandlod/indirectdraw.frag b/data/hlsl/computecullandlod/indirectdraw.frag new file mode 100644 index 00000000..f4f49dab --- /dev/null +++ b/data/hlsl/computecullandlod/indirectdraw.frag @@ -0,0 +1,18 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.25, 0.25, 0.25); + float3 diffuse = max(dot(N, L), 0.0).xxx; + return float4((ambient + diffuse) * input.Color, 1.0); +} diff --git a/data/hlsl/computecullandlod/indirectdraw.vert b/data/hlsl/computecullandlod/indirectdraw.vert new file mode 100644 index 00000000..9893ba84 --- /dev/null +++ b/data/hlsl/computecullandlod/indirectdraw.vert @@ -0,0 +1,46 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +// Instanced attributes +[[vk::location(4)]] float3 instancePos : TEXCOORD0; +[[vk::location(5)]] float instanceScale : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + + output.Normal = input.Normal; + + float4 pos = float4((input.Pos.xyz * input.instanceScale) + input.instancePos, 1.0); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + float4 wPos = mul(ubo.modelview, float4(pos.xyz, 1.0)); + float4 lPos = float4(0.0, 10.0, 50.0, 1.0); + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/computeheadless/headless.comp b/data/hlsl/computeheadless/headless.comp new file mode 100644 index 00000000..827f9159 --- /dev/null +++ b/data/hlsl/computeheadless/headless.comp @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC + +RWStructuredBuffer values : register(u0); +[[vk::constant_id(0)]] const uint BUFFER_ELEMENTS = 32; + +uint fibonacci(uint n) { + if(n <= 1){ + return n; + } + uint curr = 1; + uint prev = 1; + for(uint i = 2; i < n; ++i) { + uint temp = curr; + curr += prev; + prev = temp; + } + return curr; +} + +[numthreads(1, 1, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + uint index = GlobalInvocationID.x; + if (index >= BUFFER_ELEMENTS) + return; + values[index] = fibonacci(values[index]); +} + diff --git a/data/hlsl/computenbody/particle.frag b/data/hlsl/computenbody/particle.frag new file mode 100644 index 00000000..dd7bd3b8 --- /dev/null +++ b/data/hlsl/computenbody/particle.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t0); +SamplerState samplerColorMap : register(s0); +Texture2D textureGradientRamp : register(t1); +SamplerState samplerGradientRamp : register(s1); + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float GradientPos : POSITION0; +[[vk::location(1)]] float2 CenterPos : POSITION1; +[[vk::location(2)]] float PointSize : TEXCOORD0; +}; + +float4 main (VSOutput input) : SV_TARGET +{ + float3 color = textureGradientRamp.Sample(samplerGradientRamp, float2(input.GradientPos, 0.0)).rgb; + float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5; + return float4(textureColorMap.Sample(samplerColorMap, PointCoord).rgb * color, 1); +} diff --git a/data/hlsl/computenbody/particle.vert b/data/hlsl/computenbody/particle.vert new file mode 100644 index 00000000..b2a76596 --- /dev/null +++ b/data/hlsl/computenbody/particle.vert @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float4 Vel : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float GradientPos : POSITION0; +[[vk::location(1)]] float2 CenterPos : POSITION1; +[[vk::builtin("PointSize")]] float PSize : PSIZE; +[[vk::location(2)]] float PointSize : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float2 screendim; +}; + +cbuffer ubo : register(b2) { UBO ubo; } + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + const float spriteSize = 0.005 * input.Pos.w; // Point size influenced by mass (stored in input.Pos.w); + + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + float4 projectedCorner = mul(ubo.projection, float4(0.5 * spriteSize, 0.5 * spriteSize, eyePos.z, eyePos.w)); + output.PSize = output.PointSize = clamp(ubo.screendim.x * projectedCorner.x / projectedCorner.w, 1.0, 128.0); + + output.Pos = mul(ubo.projection, eyePos); + output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * ubo.screendim; + + output.GradientPos = input.Vel.w; + return output; +} \ No newline at end of file diff --git a/data/hlsl/computenbody/particle_calculate.comp b/data/hlsl/computenbody/particle_calculate.comp new file mode 100644 index 00000000..3a4e8bbc --- /dev/null +++ b/data/hlsl/computenbody/particle_calculate.comp @@ -0,0 +1,70 @@ +// Copyright 2020 Google LLC + +struct Particle +{ + float4 pos; + float4 vel; +}; + +// Binding 0 : Position storage buffer +RWStructuredBuffer particles : register(u0); + +struct UBO +{ + float deltaT; + int particleCount; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +#define MAX_SHARED_DATA_SIZE 1024 +[[vk::constant_id(0)]] const int SHARED_DATA_SIZE = 512; +[[vk::constant_id(1)]] const float GRAVITY = 0.002; +[[vk::constant_id(2)]] const float POWER = 0.75; +[[vk::constant_id(3)]] const float SOFTEN = 0.0075; + +// Share data between computer shader invocations to speed up caluclations +groupshared float4 sharedData[MAX_SHARED_DATA_SIZE]; + +[numthreads(256, 1, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID, uint3 LocalInvocationID : SV_GroupThreadID) +{ + // Current SSBO index + uint index = GlobalInvocationID.x; + if (index >= ubo.particleCount) + return; + + float4 position = particles[index].pos; + float4 velocity = particles[index].vel; + float4 acceleration = float4(0, 0, 0, 0); + + for (int i = 0; i < ubo.particleCount; i += SHARED_DATA_SIZE) + { + if (i + LocalInvocationID.x < ubo.particleCount) + { + sharedData[LocalInvocationID.x] = particles[i + LocalInvocationID.x].pos; + } + else + { + sharedData[LocalInvocationID.x] = float4(0, 0, 0, 0); + } + + GroupMemoryBarrierWithGroupSync(); + + for (int j = 0; j < 256; j++) + { + float4 other = sharedData[j]; + float3 len = other.xyz - position.xyz; + acceleration.xyz += GRAVITY * len * other.w / pow(dot(len, len) + SOFTEN, POWER); + } + + GroupMemoryBarrierWithGroupSync(); + } + + particles[index].vel.xyz += ubo.deltaT * acceleration.xyz; + + // Gradient texture position + particles[index].vel.w += 0.1 * ubo.deltaT; + if (particles[index].vel.w > 1.0) + particles[index].vel.w -= 1.0; +} \ No newline at end of file diff --git a/data/hlsl/computenbody/particle_integrate.comp b/data/hlsl/computenbody/particle_integrate.comp new file mode 100644 index 00000000..90065a5b --- /dev/null +++ b/data/hlsl/computenbody/particle_integrate.comp @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC + +struct Particle +{ + float4 pos; + float4 vel; +}; + +// Binding 0 : Position storage buffer +RWStructuredBuffer particles : register(u0); + +struct UBO +{ + float deltaT; + int particleCount; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +[numthreads(256, 1, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + int index = int(GlobalInvocationID.x); + float4 position = particles[index].pos; + float4 velocity = particles[index].vel; + position += ubo.deltaT * velocity; + particles[index].pos = position; +} \ No newline at end of file diff --git a/data/hlsl/computeparticles/particle.comp b/data/hlsl/computeparticles/particle.comp new file mode 100644 index 00000000..940faffb --- /dev/null +++ b/data/hlsl/computeparticles/particle.comp @@ -0,0 +1,74 @@ +// Copyright 2020 Google LLC + +struct Particle +{ + float2 pos; + float2 vel; + float4 gradientPos; +}; + +// Binding 0 : Position storage buffer +RWStructuredBuffer particles : register(u0); + +struct UBO +{ + float deltaT; + float destX; + float destY; + int particleCount; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +float2 attraction(float2 pos, float2 attractPos) +{ + float2 delta = attractPos - pos; + const float damp = 0.5; + float dDampedDot = dot(delta, delta) + damp; + float invDist = 1.0f / sqrt(dDampedDot); + float invDistCubed = invDist*invDist*invDist; + return delta * invDistCubed * 0.0035; +} + +float2 repulsion(float2 pos, float2 attractPos) +{ + float2 delta = attractPos - pos; + float targetDistance = sqrt(dot(delta, delta)); + return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035; +} + +[numthreads(256, 1, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + // Current SSBO index + uint index = GlobalInvocationID.x; + // Don't try to write beyond particle count + if (index >= ubo.particleCount) + return; + + // Read position and velocity + float2 vVel = particles[index].vel.xy; + float2 vPos = particles[index].pos.xy; + + float2 destPos = float2(ubo.destX, ubo.destY); + + float2 delta = destPos - vPos; + float targetDistance = sqrt(dot(delta, delta)); + vVel += repulsion(vPos, destPos.xy) * 0.05; + + // Move by velocity + vPos += vVel * ubo.deltaT; + + // collide with boundary + if ((vPos.x < -1.0) || (vPos.x > 1.0) || (vPos.y < -1.0) || (vPos.y > 1.0)) + vVel = (-vVel * 0.1) + attraction(vPos, destPos) * 12; + else + particles[index].pos.xy = vPos; + + // Write back + particles[index].vel.xy = vVel; + particles[index].gradientPos.x += 0.02 * ubo.deltaT; + if (particles[index].gradientPos.x > 1.0) + particles[index].gradientPos.x -= 1.0; +} + diff --git a/data/hlsl/computeparticles/particle.frag b/data/hlsl/computeparticles/particle.frag new file mode 100644 index 00000000..f3c386f8 --- /dev/null +++ b/data/hlsl/computeparticles/particle.frag @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t0); +SamplerState samplerColorMap : register(s0); +Texture2D textureGradientRamp : register(t1); +SamplerState samplerGradientRamp : register(s1); + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float4 Color : COLOR0; +[[vk::location(1)]] float GradientPos : POSITION0; +[[vk::location(2)]] float2 CenterPos : POSITION1; +[[vk::location(3)]] float PointSize : TEXCOORD0; +}; + +float4 main (VSOutput input) : SV_TARGET +{ + float3 color = textureGradientRamp.Sample(samplerGradientRamp, float2(input.GradientPos, 0.0)).rgb; + float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5; + return float4(textureColorMap.Sample(samplerColorMap, PointCoord).rgb * color, 1.0); +} diff --git a/data/hlsl/computeparticles/particle.vert b/data/hlsl/computeparticles/particle.vert new file mode 100644 index 00000000..a19c5990 --- /dev/null +++ b/data/hlsl/computeparticles/particle.vert @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float2 Pos : POSITION0; +[[vk::location(1)]] float4 GradientPos : POSITION1; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::builtin("PointSize")]] float PSize : PSIZE; +[[vk::location(0)]] float4 Color : COLOR0; +[[vk::location(1)]] float GradientPos : POSITION0; +[[vk::location(2)]] float2 CenterPos : POSITION1; +[[vk::location(3)]] float PointSize : TEXCOORD0; +}; + +struct PushConsts +{ + float2 screendim; +}; + +[[vk::push_constant]] PushConsts pushConstants; + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + output.PSize = output.PointSize = 8.0; + output.Color = float4(0.035, 0.035, 0.035, 0.035); + output.GradientPos = input.GradientPos.x; + output.Pos = float4(input.Pos.xy, 1.0, 1.0); + output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * pushConstants.screendim; + return output; +} \ No newline at end of file diff --git a/data/hlsl/computeraytracing/raytracing.comp b/data/hlsl/computeraytracing/raytracing.comp new file mode 100644 index 00000000..9f53c7dc --- /dev/null +++ b/data/hlsl/computeraytracing/raytracing.comp @@ -0,0 +1,272 @@ +// Copyright 2020 Google LLC + +// Shader is looseley based on the ray tracing coding session by Inigo Quilez (www.iquilezles.org) + +RWTexture2D resultImage : register(u0); + +#define EPSILON 0.0001 +#define MAXLEN 1000.0 +#define SHADOW 0.5 +#define RAYBOUNCES 2 +#define REFLECTIONS true +#define REFLECTIONSTRENGTH 0.4 +#define REFLECTIONFALLOFF 0.5 + +struct Camera +{ + float3 pos; + float3 lookat; + float fov; +}; + +struct UBO +{ + float3 lightPos; + float aspectRatio; + float4 fogColor; + Camera camera; + float4x4 rotMat; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +struct Sphere +{ + float3 pos; + float radius; + float3 diffuse; + float specular; + int id; +}; + +struct Plane +{ + float3 normal; + float distance; + float3 diffuse; + float specular; + int id; +}; + +StructuredBuffer spheres : register(t2); +StructuredBuffer planes : register(t3); + +void reflectRay(inout float3 rayD, in float3 mormal) +{ + rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal; +} + +// Lighting ========================================================= + +float lightDiffuse(float3 normal, float3 lightDir) +{ + return clamp(dot(normal, lightDir), 0.1, 1.0); +} + +float lightSpecular(float3 normal, float3 lightDir, float specularFactor) +{ + float3 viewVec = normalize(ubo.camera.pos); + float3 halfVec = normalize(lightDir + viewVec); + return pow(clamp(dot(normal, halfVec), 0.0, 1.0), specularFactor); +} + +// Sphere =========================================================== + +float sphereIntersect(in float3 rayO, in float3 rayD, in Sphere sphere) +{ + float3 oc = rayO - sphere.pos; + float b = 2.0 * dot(oc, rayD); + float c = dot(oc, oc) - sphere.radius*sphere.radius; + float h = b*b - 4.0*c; + if (h < 0.0) + { + return -1.0; + } + float t = (-b - sqrt(h)) / 2.0; + + return t; +} + +float3 sphereNormal(in float3 pos, in Sphere sphere) +{ + return (pos - sphere.pos) / sphere.radius; +} + +// Plane =========================================================== + +float planeIntersect(float3 rayO, float3 rayD, Plane plane) +{ + float d = dot(rayD, plane.normal); + + if (d == 0.0) + return 0.0; + + float t = -(plane.distance + dot(rayO, plane.normal)) / d; + + if (t < 0.0) + return 0.0; + + return t; +} + + +int intersect(in float3 rayO, in float3 rayD, inout float resT) +{ + int id = -1; + + uint spheresLength; + uint spheresStride; + spheres.GetDimensions(spheresLength, spheresStride); + + int i; + for (i = 0; i < spheresLength; i++) + { + float tSphere = sphereIntersect(rayO, rayD, spheres[i]); + if ((tSphere > EPSILON) && (tSphere < resT)) + { + id = spheres[i].id; + resT = tSphere; + } + } + + uint planesLength; + uint planesStride; + planes.GetDimensions(planesLength, planesStride); + + for (i = 0; i < planesLength; i++) + { + float tplane = planeIntersect(rayO, rayD, planes[i]); + if ((tplane > EPSILON) && (tplane < resT)) + { + id = planes[i].id; + resT = tplane; + } + } + + return id; +} + +float calcShadow(in float3 rayO, in float3 rayD, in int objectId, inout float t) +{ + uint spheresLength; + uint spheresStride; + spheres.GetDimensions(spheresLength, spheresStride); + + for (int i = 0; i < spheresLength; i++) + { + if (spheres[i].id == objectId) + continue; + float tSphere = sphereIntersect(rayO, rayD, spheres[i]); + if ((tSphere > EPSILON) && (tSphere < t)) + { + t = tSphere; + return SHADOW; + } + } + return 1.0; +} + +float3 fog(in float t, in float3 color) +{ + return lerp(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0)); +} + +float3 renderScene(inout float3 rayO, inout float3 rayD, inout int id) +{ + float3 color = float3(0, 0, 0); + float t = MAXLEN; + + // Get intersected object ID + int objectID = intersect(rayO, rayD, t); + + if (objectID == -1) + { + return color; + } + + float3 pos = rayO + t * rayD; + float3 lightVec = normalize(ubo.lightPos - pos); + float3 normal; + + // Planes + + // Spheres + + uint planesLength; + uint planesStride; + planes.GetDimensions(planesLength, planesStride); + + int i; + for (i = 0; i < planesLength; i++) + { + if (objectID == planes[i].id) + { + normal = planes[i].normal; + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec, planes[i].specular); + color = diffuse * planes[i].diffuse + specular; + } + } + + uint spheresLength; + uint spheresStride; + spheres.GetDimensions(spheresLength, spheresStride); + + for (i = 0; i < spheresLength; i++) + { + if (objectID == spheres[i].id) + { + normal = sphereNormal(pos, spheres[i]); + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec, spheres[i].specular); + color = diffuse * spheres[i].diffuse + specular; + } + } + + if (id == -1) + return color; + + id = objectID; + + // Shadows + t = length(ubo.lightPos - pos); + color *= calcShadow(pos, lightVec, id, t); + + // Fog + color = fog(t, color); + + // Reflect ray for next render pass + reflectRay(rayD, normal); + rayO = pos; + + return color; +} + +[numthreads(16, 16, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + int2 dim; + resultImage.GetDimensions(dim.x, dim.y); + float2 uv = float2(GlobalInvocationID.xy) / dim; + + float3 rayO = ubo.camera.pos; + float3 rayD = normalize(float3((-1.0 + 2.0 * uv) * float2(ubo.aspectRatio, 1.0), -1.0)); + + // Basic color path + int id = 0; + float3 finalColor = renderScene(rayO, rayD, id); + + // Reflection + if (REFLECTIONS) + { + float reflectionStrength = REFLECTIONSTRENGTH; + for (int i = 0; i < RAYBOUNCES; i++) + { + float3 reflectionColor = renderScene(rayO, rayD, id); + finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * lerp(reflectionColor, finalColor, 1.0 - reflectionStrength); + reflectionStrength *= REFLECTIONFALLOFF; + } + } + + resultImage[int2(GlobalInvocationID.xy)] = float4(finalColor, 0.0); +} \ No newline at end of file diff --git a/data/hlsl/computeraytracing/texture.frag b/data/hlsl/computeraytracing/texture.frag new file mode 100644 index 00000000..99e548ad --- /dev/null +++ b/data/hlsl/computeraytracing/texture.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t0); +SamplerState samplerColor : register(s0); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, float2(inUV.x, 1.0 - inUV.y)); +} \ No newline at end of file diff --git a/data/hlsl/computeraytracing/texture.vert b/data/hlsl/computeraytracing/texture.vert new file mode 100644 index 00000000..36d824cb --- /dev/null +++ b/data/hlsl/computeraytracing/texture.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f + -1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/computeshader/edgedetect.comp b/data/hlsl/computeshader/edgedetect.comp new file mode 100644 index 00000000..f3e0d425 --- /dev/null +++ b/data/hlsl/computeshader/edgedetect.comp @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +Texture2D inputImage : register(t0); +RWTexture2D resultImage : register(u1); + +float conv(float kernel[9], in float data[9], in float denom, in float offset) +{ + float res = 0.0; + for (int i=0; i<9; ++i) + { + res += kernel[i] * data[i]; + } + return saturate(res/denom + offset); +} + +[numthreads(16, 16, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float imageData[9]; + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0; + } + } + + float kernel[9]; + kernel[0] = -1.0/8.0; kernel[1] = -1.0/8.0; kernel[2] = -1.0/8.0; + kernel[3] = -1.0/8.0; kernel[4] = 1.0; kernel[5] = -1.0/8.0; + kernel[6] = -1.0/8.0; kernel[7] = -1.0/8.0; kernel[8] = -1.0/8.0; + + float4 res = float4(conv(kernel, imageData, 0.1, 0.0).xxx, 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} diff --git a/data/hlsl/computeshader/emboss.comp b/data/hlsl/computeshader/emboss.comp new file mode 100644 index 00000000..f2a07027 --- /dev/null +++ b/data/hlsl/computeshader/emboss.comp @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +Texture2D inputImage : register(t0); +RWTexture2D resultImage : register(u1); + +float conv(in float kernel[9], in float data[9], in float denom, in float offset) +{ + float res = 0.0; + for (int i=0; i<9; ++i) + { + res += kernel[i] * data[i]; + } + return saturate(res/denom + offset); +} + +[numthreads(16, 16, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float imageData[9]; + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0; + } + } + + float kernel[9]; + kernel[0] = -1.0; kernel[1] = 0.0; kernel[2] = 0.0; + kernel[3] = 0.0; kernel[4] = -1.0; kernel[5] = 0.0; + kernel[6] = 0.0; kernel[7] = 0.0; kernel[8] = 2.0; + + float4 res = float4(conv(kernel, imageData, 1.0, 0.50).xxx, 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} \ No newline at end of file diff --git a/data/hlsl/computeshader/sharpen.comp b/data/hlsl/computeshader/sharpen.comp new file mode 100644 index 00000000..90a58266 --- /dev/null +++ b/data/hlsl/computeshader/sharpen.comp @@ -0,0 +1,49 @@ +// Copyright 2020 Google LLC + +Texture2D inputImage : register(t0); +RWTexture2D resultImage : register(u1); + +float conv(in float kernel[9], in float data[9], in float denom, in float offset) +{ + float res = 0.0; + for (int i=0; i<9; ++i) + { + res += kernel[i] * data[i]; + } + return saturate(res/denom + offset); +} + +[numthreads(16, 16, 1)] +void main(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float r[9]; + float g[9]; + float b[9]; + + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + r[n] = rgb.r; + g[n] = rgb.g; + b[n] = rgb.b; + } + } + + float kernel[9]; + kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0; + kernel[3] = -1.0; kernel[4] = 9.0; kernel[5] = -1.0; + kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0; + + float4 res = float4( + conv(kernel, r, 1.0, 0.0), + conv(kernel, g, 1.0, 0.0), + conv(kernel, b, 1.0, 0.0), + 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} \ No newline at end of file diff --git a/data/hlsl/computeshader/texture.frag b/data/hlsl/computeshader/texture.frag new file mode 100644 index 00000000..997a9419 --- /dev/null +++ b/data/hlsl/computeshader/texture.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, inUV); +} \ No newline at end of file diff --git a/data/hlsl/computeshader/texture.vert b/data/hlsl/computeshader/texture.vert new file mode 100644 index 00000000..8021fe95 --- /dev/null +++ b/data/hlsl/computeshader/texture.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/conditionalrender/model.frag b/data/hlsl/conditionalrender/model.frag new file mode 100644 index 00000000..2c14be89 --- /dev/null +++ b/data/hlsl/conditionalrender/model.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/conditionalrender/model.vert b/data/hlsl/conditionalrender/model.vert new file mode 100644 index 00000000..929321e1 --- /dev/null +++ b/data/hlsl/conditionalrender/model.vert @@ -0,0 +1,57 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct Node +{ + float4x4 transform; +}; + +cbuffer NodeBuf : register(b0, space1) { Node node; } + +struct PushConstant +{ + float4 baseColorFactor; +}; + +[[vk::push_constant]] PushConstant material; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = material.baseColorFactor.rgb; + float4 pos = float4(input.Pos, 1.0); + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, mul(node.transform, pos)))); + + output.Normal = mul((float4x3)mul(ubo.view, mul(ubo.model, node.transform)), input.Normal).xyz; + + float4 localpos = mul(ubo.view, mul(ubo.model, mul(node.transform, pos))); + float3 lightPos = float3(10.0f, -10.0f, 10.0f); + output.LightVec = lightPos.xyz - localpos.xyz; + output.ViewVec = -localpos.xyz; + return output; +} diff --git a/data/hlsl/conservativeraster/fullscreen.frag b/data/hlsl/conservativeraster/fullscreen.frag new file mode 100644 index 00000000..661ddf44 --- /dev/null +++ b/data/hlsl/conservativeraster/fullscreen.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, inUV); +} \ No newline at end of file diff --git a/data/hlsl/conservativeraster/fullscreen.vert b/data/hlsl/conservativeraster/fullscreen.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/conservativeraster/fullscreen.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/conservativeraster/triangle.frag b/data/hlsl/conservativeraster/triangle.frag new file mode 100644 index 00000000..2387dd14 --- /dev/null +++ b/data/hlsl/conservativeraster/triangle.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1); +} \ No newline at end of file diff --git a/data/hlsl/conservativeraster/triangle.vert b/data/hlsl/conservativeraster/triangle.vert new file mode 100644 index 00000000..e7c529be --- /dev/null +++ b/data/hlsl/conservativeraster/triangle.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} diff --git a/data/hlsl/conservativeraster/triangleoverlay.frag b/data/hlsl/conservativeraster/triangleoverlay.frag new file mode 100644 index 00000000..9892e709 --- /dev/null +++ b/data/hlsl/conservativeraster/triangleoverlay.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main() : SV_TARGET +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/debugmarker/colorpass.frag b/data/hlsl/debugmarker/colorpass.frag new file mode 100644 index 00000000..2387dd14 --- /dev/null +++ b/data/hlsl/debugmarker/colorpass.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1); +} \ No newline at end of file diff --git a/data/hlsl/debugmarker/colorpass.vert b/data/hlsl/debugmarker/colorpass.vert new file mode 100644 index 00000000..089cd426 --- /dev/null +++ b/data/hlsl/debugmarker/colorpass.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + return output; +} diff --git a/data/hlsl/debugmarker/postprocess.frag b/data/hlsl/debugmarker/postprocess.frag new file mode 100644 index 00000000..32bef01b --- /dev/null +++ b/data/hlsl/debugmarker/postprocess.frag @@ -0,0 +1,36 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + // Single pass gauss blur + + const float2 texOffset = float2(0.01, 0.01); + + float2 tc0 = inUV + float2(-texOffset.x, -texOffset.y); + float2 tc1 = inUV + float2( 0.0, -texOffset.y); + float2 tc2 = inUV + float2(+texOffset.x, -texOffset.y); + float2 tc3 = inUV + float2(-texOffset.x, 0.0); + float2 tc4 = inUV + float2( 0.0, 0.0); + float2 tc5 = inUV + float2(+texOffset.x, 0.0); + float2 tc6 = inUV + float2(-texOffset.x, +texOffset.y); + float2 tc7 = inUV + float2( 0.0, +texOffset.y); + float2 tc8 = inUV + float2(+texOffset.x, +texOffset.y); + + float4 col0 = textureColor.Sample(samplerColor, tc0); + float4 col1 = textureColor.Sample(samplerColor, tc1); + float4 col2 = textureColor.Sample(samplerColor, tc2); + float4 col3 = textureColor.Sample(samplerColor, tc3); + float4 col4 = textureColor.Sample(samplerColor, tc4); + float4 col5 = textureColor.Sample(samplerColor, tc5); + float4 col6 = textureColor.Sample(samplerColor, tc6); + float4 col7 = textureColor.Sample(samplerColor, tc7); + float4 col8 = textureColor.Sample(samplerColor, tc8); + + float4 sum = (1.0 * col0 + 2.0 * col1 + 1.0 * col2 + + 2.0 * col3 + 4.0 * col4 + 2.0 * col5 + + 1.0 * col6 + 2.0 * col7 + 1.0 * col8) / 16.0; + return float4(sum.rgb, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/debugmarker/postprocess.vert b/data/hlsl/debugmarker/postprocess.vert new file mode 100644 index 00000000..fca6ef51 --- /dev/null +++ b/data/hlsl/debugmarker/postprocess.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * float2(2.0f, 2.0f) + float2(-1.0f, -1.0f), 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/hlsl/debugmarker/toon.frag b/data/hlsl/debugmarker/toon.frag new file mode 100644 index 00000000..fa2e7a35 --- /dev/null +++ b/data/hlsl/debugmarker/toon.frag @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Desaturate color + float3 color = float3(lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65)); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + + float intensity = dot(N,L); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); +} \ No newline at end of file diff --git a/data/hlsl/debugmarker/toon.vert b/data/hlsl/debugmarker/toon.vert new file mode 100644 index 00000000..3755608d --- /dev/null +++ b/data/hlsl/debugmarker/toon.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/deferred/debug.frag b/data/hlsl/deferred/debug.frag new file mode 100644 index 00000000..0c3520db --- /dev/null +++ b/data/hlsl/deferred/debug.frag @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC + +Texture2D texturePosition : register(t1); +SamplerState samplerPosition : register(s1); +Texture2D textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2D textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); + +float4 main([[vk::location(0)]] float3 inUV : TEXCOORD0) : SV_TARGET +{ + float3 components[3]; + components[0] = texturePosition.Sample(samplerPosition, inUV.xy).rgb; + components[1] = textureNormal.Sample(samplerNormal, inUV.xy).rgb; + components[2] = textureAlbedo.Sample(samplerAlbedo, inUV.xy).rgb; + // Uncomment to display specular component + //components[2] = float3(textureAlbedo.Sample(samplerAlbedo, inUV.st).a); + + // Select component depending on z coordinate of quad + int index = int(inUV.z); + return float4(components[index], 1); +} \ No newline at end of file diff --git a/data/hlsl/deferred/debug.vert b/data/hlsl/deferred/debug.vert new file mode 100644 index 00000000..1cc167bf --- /dev/null +++ b/data/hlsl/deferred/debug.vert @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = float3(input.UV.xy, input.Normal.z); + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/deferred/deferred.frag b/data/hlsl/deferred/deferred.frag new file mode 100644 index 00000000..24c62201 --- /dev/null +++ b/data/hlsl/deferred/deferred.frag @@ -0,0 +1,73 @@ +// Copyright 2020 Google LLC + +Texture2D textureposition : register(t1); +SamplerState samplerposition : register(s1); +Texture2D textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2D textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); + +struct Light { + float4 position; + float3 color; + float radius; +}; + +struct UBO +{ + Light lights[6]; + float4 viewPos; +}; + +cbuffer ubo : register(b4) { UBO ubo; } + + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + // Get G-Buffer values + float3 fragPos = textureposition.Sample(samplerposition, inUV).rgb; + float3 normal = textureNormal.Sample(samplerNormal, inUV).rgb; + float4 albedo = textureAlbedo.Sample(samplerAlbedo, inUV); + + #define lightCount 6 + #define ambient 0.0 + + // Ambient part + float3 fragcolor = albedo.rgb * ambient; + + for(int i = 0; i < lightCount; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + //if(dist < ubo.lights[i].radius) + { + // Light to fragment + L = normalize(L); + + // Attenuation + float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0); + + // Diffuse part + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten; + + // Specular part + // Specular map values are stored in alpha of albedo mrt + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 16.0) * atten; + + fragcolor += diff + spec; + } + } + + return float4(fragcolor, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/deferred/deferred.vert b/data/hlsl/deferred/deferred.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/deferred/deferred.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/deferred/mrt.frag b/data/hlsl/deferred/mrt.frag new file mode 100644 index 00000000..264e7224 --- /dev/null +++ b/data/hlsl/deferred/mrt.frag @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); +Texture2D textureNormalMap : register(t2); +SamplerState samplerNormalMap : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + N.y = -N.y; + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(textureNormalMap.Sample(samplerNormalMap, input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = textureColor.Sample(samplerColor, input.UV); + return output; +} \ No newline at end of file diff --git a/data/hlsl/deferred/mrt.vert b/data/hlsl/deferred/mrt.vert new file mode 100644 index 00000000..06c25cc6 --- /dev/null +++ b/data/hlsl/deferred/mrt.vert @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +VSOutput main(VSInput input, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + output.UV.y = 1.0 - output.UV.y; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + // GL to Vulkan coord space + output.WorldPos.y = -output.WorldPos.y; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} diff --git a/data/hlsl/deferredmultisampling/debug.frag b/data/hlsl/deferredmultisampling/debug.frag new file mode 100644 index 00000000..f8b3135f --- /dev/null +++ b/data/hlsl/deferredmultisampling/debug.frag @@ -0,0 +1,53 @@ +// Copyright 2020 Google LLC + +Texture2DMS texturePosition : register(t1); +SamplerState samplerPosition : register(s1); +Texture2DMS textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2DMS textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); + +[[vk::constant_id(0)]] const int NUM_SAMPLES = 8; + +float4 resolve(Texture2DMS tex, int2 uv) +{ + float4 result = float4(0.0, 0.0, 0.0, 0.0); + int count = 0; + for (int i = 0; i < NUM_SAMPLES; i++) + { + uint status = 0; + float4 val = tex.Load(uv, i, int2(0, 0), status); + result += val; + count++; + } + return result / float(NUM_SAMPLES); +} + +float4 main([[vk::location(0)]] float3 inUV : TEXCOORD0) : SV_TARGET +{ + int2 attDim; int sampleCount; + texturePosition.GetDimensions(attDim.x, attDim.y, sampleCount); + int2 UV = int2(inUV.xy * attDim * 2.0); + + int index = 0; + if (inUV.x > 0.5) + { + index = 1; + UV.x -= attDim.x; + } + if (inUV.y > 0.5) + { + index = 2; + UV.y -= attDim.y; + } + + float3 components[3]; + components[0] = resolve(texturePosition, UV).rgb; + components[1] = resolve(textureNormal, UV).rgb; + components[2] = resolve(textureAlbedo, UV).rgb; + // Uncomment to display specular component + //components[2] = float3(textureAlbedo.Sample(samplerAlbedo, inUV.xt).a); + + // Select component depending on UV + return float4(components[index], 1); +} \ No newline at end of file diff --git a/data/hlsl/deferredmultisampling/debug.vert b/data/hlsl/deferredmultisampling/debug.vert new file mode 100644 index 00000000..bc833b69 --- /dev/null +++ b/data/hlsl/deferredmultisampling/debug.vert @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float3((VertexIndex << 1) & 2, VertexIndex & 2, 0.0); + output.Pos = float4(output.UV.xy * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/deferredmultisampling/deferred.frag b/data/hlsl/deferredmultisampling/deferred.frag new file mode 100644 index 00000000..e758cac1 --- /dev/null +++ b/data/hlsl/deferredmultisampling/deferred.frag @@ -0,0 +1,104 @@ +// Copyright 2020 Google LLC + +Texture2DMS texturePosition : register(t1); +SamplerState samplerPosition : register(s1); +Texture2DMS textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2DMS textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); + +struct Light { + float4 position; + float3 color; + float radius; +}; + +struct UBO +{ + Light lights[6]; + float4 viewPos; + int2 windowSize; +}; + +cbuffer ubo : register(b4) { UBO ubo; } + +[[vk::constant_id(0)]] const int NUM_SAMPLES = 8; + +#define NUM_LIGHTS 6 + +// Manual resolve for MSAA samples +float4 resolve(Texture2DMS tex, int2 uv) +{ + float4 result = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < NUM_SAMPLES; i++) + { + uint status = 0; + float4 val = tex.Load(uv, i, int2(0, 0), status); + result += val; + } + // Average resolved samples + return result / float(NUM_SAMPLES); +} + +float3 calculateLighting(float3 pos, float3 normal, float4 albedo) +{ + float3 result = float3(0.0, 0.0, 0.0); + + for(int i = 0; i < NUM_LIGHTS; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - pos; + // Distance from light to fragment position + float dist = length(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - pos; + V = normalize(V); + + // Light to fragment + L = normalize(L); + + // Attenuation + float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0); + + // Diffuse part + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten; + + // Specular part + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 8.0) * atten; + + result += diff + spec; + } + return result; +} + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + int2 attDim; int sampleCount; + texturePosition.GetDimensions(attDim.x, attDim.y, sampleCount); + int2 UV = int2(inUV * attDim); + + #define ambient 0.15 + + // Ambient part + float4 alb = resolve(textureAlbedo, UV); + float3 fragColor = float3(0.0, 0.0, 0.0); + + // Calualte lighting for every MSAA sample + for (int i = 0; i < NUM_SAMPLES; i++) + { + uint status = 0; + float3 pos = texturePosition.Load(UV, i, int2(0, 0), status).rgb; + float3 normal = textureNormal.Load(UV, i, int2(0, 0), status).rgb; + float4 albedo = textureAlbedo.Load(UV, i, int2(0, 0), status); + fragColor += calculateLighting(pos, normal, albedo); + } + + fragColor = (alb.rgb * ambient) + fragColor / float(NUM_SAMPLES); + + return float4(fragColor, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/deferredmultisampling/deferred.vert b/data/hlsl/deferredmultisampling/deferred.vert new file mode 100644 index 00000000..93fadbaa --- /dev/null +++ b/data/hlsl/deferredmultisampling/deferred.vert @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/deferredmultisampling/mrt.frag b/data/hlsl/deferredmultisampling/mrt.frag new file mode 100644 index 00000000..264e7224 --- /dev/null +++ b/data/hlsl/deferredmultisampling/mrt.frag @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); +Texture2D textureNormalMap : register(t2); +SamplerState samplerNormalMap : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + N.y = -N.y; + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(textureNormalMap.Sample(samplerNormalMap, input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = textureColor.Sample(samplerColor, input.UV); + return output; +} \ No newline at end of file diff --git a/data/hlsl/deferredmultisampling/mrt.vert b/data/hlsl/deferredmultisampling/mrt.vert new file mode 100644 index 00000000..06c25cc6 --- /dev/null +++ b/data/hlsl/deferredmultisampling/mrt.vert @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +VSOutput main(VSInput input, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + output.UV.y = 1.0 - output.UV.y; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + // GL to Vulkan coord space + output.WorldPos.y = -output.WorldPos.y; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} diff --git a/data/hlsl/deferredshadows/debug.frag b/data/hlsl/deferredshadows/debug.frag new file mode 100644 index 00000000..0aae5d87 --- /dev/null +++ b/data/hlsl/deferredshadows/debug.frag @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +Texture2D texturePosition : register(t1); +SamplerState samplerPosition : register(s1); +Texture2D textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2D textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); +Texture2DArray textureDepth : register(t5); +SamplerState samplerDepth : register(s5); + +float LinearizeDepth(float depth) +{ + float n = 0.1; // camera z near + float f = 64.0; // camera z far + float z = depth; + return (2.0 * n) / (f + n - z * (f - n)); +} + +float4 main([[vk::location(0)]] float3 inUV : TEXCOORD0) : SV_TARGET +{ + // Display depth from light's point-of-view + // inUV.w = number of light source + float depth = textureDepth.Sample(samplerDepth, float3(inUV)).r; + return float4((1.0 - LinearizeDepth(depth)).xxx, 0.0); +} \ No newline at end of file diff --git a/data/hlsl/deferredshadows/debug.vert b/data/hlsl/deferredshadows/debug.vert new file mode 100644 index 00000000..f6ddeda6 --- /dev/null +++ b/data/hlsl/deferredshadows/debug.vert @@ -0,0 +1,32 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + output.UV = float3(input.UV.xy, InstanceIndex); + float4 tmpPos = float4(input.Pos, 1.0); + tmpPos.y += InstanceIndex; + tmpPos.xy *= float2(1.0/4.0, 1.0/3.0); + output.Pos = mul(ubo.projection, mul(ubo.modelview, tmpPos)); + return output; +} diff --git a/data/hlsl/deferredshadows/deferred.frag b/data/hlsl/deferredshadows/deferred.frag new file mode 100644 index 00000000..3ee86330 --- /dev/null +++ b/data/hlsl/deferredshadows/deferred.frag @@ -0,0 +1,146 @@ +// Copyright 2020 Google LLC + +Texture2D textureposition : register(t1); +SamplerState samplerposition : register(s1); +Texture2D textureNormal : register(t2); +SamplerState samplerNormal : register(s2); +Texture2D textureAlbedo : register(t3); +SamplerState samplerAlbedo : register(s3); +// Depth from the light's point of view +//layout (binding = 5) uniform sampler2DShadow samplerShadowMap; +Texture2DArray textureShadowMap : register(t5); +SamplerState samplerShadowMap : register(s5); + +#define LIGHT_COUNT 3 +#define SHADOW_FACTOR 0.25 +#define AMBIENT_LIGHT 0.1 +#define USE_PCF + +struct Light +{ + float4 position; + float4 target; + float4 color; + float4x4 viewMatrix; +}; + +struct UBO +{ + float4 viewPos; + Light lights[LIGHT_COUNT]; + int useShadows; +}; + +cbuffer ubo : register(b4) { UBO ubo; } + +float textureProj(float4 P, float layer, float2 offset) +{ + float shadow = 1.0; + float4 shadowCoord = P / P.w; + shadowCoord.xy = shadowCoord.xy * 0.5 + 0.5; + + if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0) + { + float dist = textureShadowMap.Sample(samplerShadowMap, float3(shadowCoord.xy + offset, layer)).r; + if (shadowCoord.w > 0.0 && dist < shadowCoord.z) + { + shadow = SHADOW_FACTOR; + } + } + return shadow; +} + +float filterPCF(float4 sc, float layer) +{ + int2 texDim; int elements; int levels; + textureShadowMap.GetDimensions(0, texDim.x, texDim.y, elements, levels); + float scale = 1.5; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + shadowFactor += textureProj(sc, layer, float2(dx*x, dy*y)); + count++; + } + + } + return shadowFactor / count; +} + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + // Get G-Buffer values + float3 fragPos = textureposition.Sample(samplerposition, inUV).rgb; + float3 normal = textureNormal.Sample(samplerNormal, inUV).rgb; + float4 albedo = textureAlbedo.Sample(samplerAlbedo, inUV); + + // Ambient part + float3 fragcolor = albedo.rgb * AMBIENT_LIGHT; + + float3 N = normalize(normal); + + float shadow = 0.0; + + for(int i = 0; i < LIGHT_COUNT; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + L = normalize(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + float lightCosInnerAngle = cos(radians(15.0)); + float lightCosOuterAngle = cos(radians(25.0)); + float lightRange = 100.0; + + // Direction vector from source to target + float3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz); + + // Dual cone spot light with smooth transition between inner and outer angle + float cosDir = dot(L, dir); + float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir); + float heightAttenuation = smoothstep(lightRange, 0.0f, dist); + + // Diffuse lighting + float NdotL = max(0.0, dot(N, L)); + float3 diff = NdotL.xxx; + + // Specular lighting + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = (pow(NdotR, 16.0) * albedo.a * 2.5).xxx; + + fragcolor += float3((diff + spec) * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb * albedo.rgb; + } + + // Shadow calculations in a separate pass + if (ubo.useShadows > 0) + { + for(int i = 0; i < LIGHT_COUNT; ++i) + { + float4 shadowClip = mul(ubo.lights[i].viewMatrix, float4(fragPos, 1.0)); + + float shadowFactor; + #ifdef USE_PCF + shadowFactor= filterPCF(shadowClip, i); + #else + shadowFactor = textureProj(shadowClip, i, float2(0.0, 0.0)); + #endif + + fragcolor *= shadowFactor; + } + } + + return float4(fragcolor, 1); +} \ No newline at end of file diff --git a/data/hlsl/deferredshadows/deferred.vert b/data/hlsl/deferredshadows/deferred.vert new file mode 100644 index 00000000..37d5bf2a --- /dev/null +++ b/data/hlsl/deferredshadows/deferred.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/deferredshadows/mrt.frag b/data/hlsl/deferredshadows/mrt.frag new file mode 100644 index 00000000..7b899821 --- /dev/null +++ b/data/hlsl/deferredshadows/mrt.frag @@ -0,0 +1,39 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); +Texture2D textureNormalMap : register(t2); +SamplerState samplerNormalMap : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(textureNormalMap.Sample(samplerNormalMap, input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = textureColor.Sample(samplerColor, input.UV); + return output; +} \ No newline at end of file diff --git a/data/hlsl/deferredshadows/mrt.vert b/data/hlsl/deferredshadows/mrt.vert new file mode 100644 index 00000000..c19ff218 --- /dev/null +++ b/data/hlsl/deferredshadows/mrt.vert @@ -0,0 +1,52 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float3 Tangent : TEXCOORD1; +}; + +VSOutput main(VSInput input, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + output.UV.y = 1.0 - output.UV.y; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} diff --git a/data/hlsl/deferredshadows/shadow.geom b/data/hlsl/deferredshadows/shadow.geom new file mode 100644 index 00000000..e8321771 --- /dev/null +++ b/data/hlsl/deferredshadows/shadow.geom @@ -0,0 +1,39 @@ +// Copyright 2020 Google LLC + +#define LIGHT_COUNT 3 + +struct UBO +{ + float4x4 mvp[LIGHT_COUNT]; + float4 instancePos[3]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] int InstanceIndex : TEXCOORD0; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; + int Layer : SV_RenderTargetArrayIndex; +}; + +[maxvertexcount(3)] +[instance(3)] +void main(triangle VSOutput input[3], uint InvocationID : SV_GSInstanceID, inout TriangleStream outStream) +{ + float4 instancedPos = ubo.instancePos[input[0].InstanceIndex]; + for (int i = 0; i < 3; i++) + { + float4 tmpPos = input[i].Pos + instancedPos; + GSOutput output = (GSOutput)0; + output.Pos = mul(ubo.mvp[InvocationID], tmpPos); + output.Layer = InvocationID; + outStream.Append( output ); + } + outStream.RestartStrip(); +} \ No newline at end of file diff --git a/data/hlsl/deferredshadows/shadow.vert b/data/hlsl/deferredshadows/shadow.vert new file mode 100644 index 00000000..f08ec8c7 --- /dev/null +++ b/data/hlsl/deferredshadows/shadow.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] int InstanceIndex : TEXCOORD0; +}; + +VSOutput main([[vk::location(0)]] float4 Pos : POSITION0, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + output.InstanceIndex = InstanceIndex; + output.Pos = Pos; + return output; +} \ No newline at end of file diff --git a/data/hlsl/descriptorsets/cube.frag b/data/hlsl/descriptorsets/cube.frag new file mode 100644 index 00000000..854726c3 --- /dev/null +++ b/data/hlsl/descriptorsets/cube.frag @@ -0,0 +1,16 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/descriptorsets/cube.vert b/data/hlsl/descriptorsets/cube.vert new file mode 100644 index 00000000..68f4df3e --- /dev/null +++ b/data/hlsl/descriptorsets/cube.vert @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBOMatrices { + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +cbuffer uboMatrices : register(b0) { UBOMatrices uboMatrices; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(uboMatrices.projection, mul(uboMatrices.view, mul(uboMatrices.model, float4(input.Pos.xyz, 1.0)))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/displacement/base.frag b/data/hlsl/displacement/base.frag new file mode 100644 index 00000000..c62eec65 --- /dev/null +++ b/data/hlsl/displacement/base.frag @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t2); +SamplerState samplerColorMap : register(s2); + +struct DSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(DSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(float3(1.0, 1.0, 1.0)); + + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(0.0, 0.0, 0.0, 1.0); + float4 IDiffuse = float4(1.0, 1.0, 1.0, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + + return float4((IAmbient + IDiffuse) * float4(textureColorMap.Sample(samplerColorMap, input.UV).rgb, 1.0)); +} \ No newline at end of file diff --git a/data/hlsl/displacement/base.vert b/data/hlsl/displacement/base.vert new file mode 100644 index 00000000..439c5bb1 --- /dev/null +++ b/data/hlsl/displacement/base.vert @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ +[[vk::location(2)]] float4 Pos : POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos.xyz, 1.0); + output.UV = input.UV * 3.0; + output.Normal = input.Normal; + return output; +} \ No newline at end of file diff --git a/data/hlsl/displacement/displacement.tesc b/data/hlsl/displacement/displacement.tesc new file mode 100644 index 00000000..2973e726 --- /dev/null +++ b/data/hlsl/displacement/displacement.tesc @@ -0,0 +1,53 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float tessLevel; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ +[[vk::location(2)]] float4 Pos : POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct HSOutput +{ +[[vk::location(2)]] float4 Pos : POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +ConstantsHSOutput ConstantsHS(InputPatch patch, uint InvocationID : SV_PrimitiveID) +{ + ConstantsHSOutput output = (ConstantsHSOutput)0; + output.TessLevelInner = ubo.tessLevel; + output.TessLevelOuter[0] = ubo.tessLevel; + output.TessLevelOuter[1] = ubo.tessLevel; + output.TessLevelOuter[2] = ubo.tessLevel; + return output; +} + +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput main(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output = (HSOutput)0; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} diff --git a/data/hlsl/displacement/displacement.tese b/data/hlsl/displacement/displacement.tese new file mode 100644 index 00000000..0732c345 --- /dev/null +++ b/data/hlsl/displacement/displacement.tese @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; + float tessAlpha; + float tessStrength; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +Texture2D textureDisplacementMap : register(t2); +SamplerState samplerDisplacementMap : register(s2); + +struct HSOutput +{ +[[vk::location(2)]] float4 Pos : POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 EyesPos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD1; +}; + +[domain("tri")] +DSOutput main(ConstantsHSOutput input, float3 TessCoord : SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output = (DSOutput)0; + output.Pos = (TessCoord.x * patch[0].Pos) + (TessCoord.y * patch[1].Pos) + (TessCoord.z * patch[2].Pos); + output.UV = mul(TessCoord.x, patch[0].UV) + mul(TessCoord.y, patch[1].UV) + mul(TessCoord.z, patch[2].UV); + output.Normal = TessCoord.x * patch[0].Normal + TessCoord.y * patch[1].Normal + TessCoord.z * patch[2].Normal; + + output.Pos.xyz += normalize(output.Normal) * (max(textureDisplacementMap.SampleLevel(samplerDisplacementMap, output.UV.xy, 0).a, 0.0) * ubo.tessStrength); + + output.EyesPos = output.Pos.xyz; + output.LightVec = normalize(ubo.lightPos.xyz - output.EyesPos); + + output.Pos = mul(ubo.projection, mul(ubo.model, output.Pos)); + return output; +} \ No newline at end of file diff --git a/data/hlsl/distancefieldfonts/bitmap.frag b/data/hlsl/distancefieldfonts/bitmap.frag new file mode 100644 index 00000000..456bfe86 --- /dev/null +++ b/data/hlsl/distancefieldfonts/bitmap.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, inUV).aaaa; +} \ No newline at end of file diff --git a/data/hlsl/distancefieldfonts/bitmap.vert b/data/hlsl/distancefieldfonts/bitmap.vert new file mode 100644 index 00000000..379daee9 --- /dev/null +++ b/data/hlsl/distancefieldfonts/bitmap.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/distancefieldfonts/sdf.frag b/data/hlsl/distancefieldfonts/sdf.frag new file mode 100644 index 00000000..104284a9 --- /dev/null +++ b/data/hlsl/distancefieldfonts/sdf.frag @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct UBO +{ + float4 outlineColor; + float outlineWidth; + float outline; +}; + +cbuffer ubo : register(b2) { UBO ubo; } + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float dist = textureColor.Sample(samplerColor, inUV).a; + float smoothWidth = fwidth(dist); + float alpha = smoothstep(0.5 - smoothWidth, 0.5 + smoothWidth, dist); + float3 rgb = alpha.xxx; + + if (ubo.outline > 0.0) + { + float w = 1.0 - ubo.outlineWidth; + alpha = smoothstep(w - smoothWidth, w + smoothWidth, dist); + rgb += lerp(alpha.xxx, ubo.outlineColor.rgb, alpha); + } + + return float4(rgb, alpha); +} \ No newline at end of file diff --git a/data/hlsl/distancefieldfonts/sdf.vert b/data/hlsl/distancefieldfonts/sdf.vert new file mode 100644 index 00000000..379daee9 --- /dev/null +++ b/data/hlsl/distancefieldfonts/sdf.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/dynamicuniformbuffer/base.frag b/data/hlsl/dynamicuniformbuffer/base.frag new file mode 100644 index 00000000..b800903c --- /dev/null +++ b/data/hlsl/dynamicuniformbuffer/base.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/dynamicuniformbuffer/base.vert b/data/hlsl/dynamicuniformbuffer/base.vert new file mode 100644 index 00000000..7cb43933 --- /dev/null +++ b/data/hlsl/dynamicuniformbuffer/base.vert @@ -0,0 +1,36 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +struct UboView +{ + float4x4 projection; + float4x4 view; +}; +cbuffer uboView : register(b0) { UboView uboView; }; + +struct UboInstance +{ + float4x4 model; +}; +cbuffer uboInstance : register(b1) { UboInstance uboInstance; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + float4x4 modelView = mul(uboView.view, uboInstance.model); + float3 worldPos = mul(modelView, float4(input.Pos, 1.0)).xyz; + output.Pos = mul(uboView.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/gears/gears.frag b/data/hlsl/gears/gears.frag new file mode 100644 index 00000000..276b830a --- /dev/null +++ b/data/hlsl/gears/gears.frag @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(0.2, 0.2, 0.2, 1.0); + float4 IDiffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float specular = 0.25; + float4 ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 0.8) * specular; + + return float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); +} \ No newline at end of file diff --git a/data/hlsl/gears/gears.vert b/data/hlsl/gears/gears.vert new file mode 100644 index 00000000..68dd4a2e --- /dev/null +++ b/data/hlsl/gears/gears.vert @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + float3 lightpos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = normalize(mul((float4x3)ubo.normal, input.Normal).xyz); + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model); + float4 pos = mul(modelView, input.Pos); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(float4(ubo.lightpos, 1.0), modelView); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + output.Pos = mul(ubo.projection, pos); + return output; +} \ No newline at end of file diff --git a/data/hlsl/geometryshader/base.frag b/data/hlsl/geometryshader/base.frag new file mode 100644 index 00000000..b800903c --- /dev/null +++ b/data/hlsl/geometryshader/base.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/geometryshader/base.vert b/data/hlsl/geometryshader/base.vert new file mode 100644 index 00000000..8179b490 --- /dev/null +++ b/data/hlsl/geometryshader/base.vert @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct VSOutput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Pos = float4(input.Pos.xyz, 1.0); + return output; +} \ No newline at end of file diff --git a/data/hlsl/geometryshader/mesh.frag b/data/hlsl/geometryshader/mesh.frag new file mode 100644 index 00000000..189e9955 --- /dev/null +++ b/data/hlsl/geometryshader/mesh.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct GSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(GSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/geometryshader/mesh.vert b/data/hlsl/geometryshader/mesh.vert new file mode 100644 index 00000000..cfa1dcf9 --- /dev/null +++ b/data/hlsl/geometryshader/mesh.vert @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + + float4 pos = mul(ubo.model, float4(input.Pos.xyz, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + + float3 lightPos = float3(1.0f, -1.0f, 1.0f); + output.LightVec = lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/geometryshader/normaldebug.geom b/data/hlsl/geometryshader/normaldebug.geom new file mode 100644 index 00000000..7fba0fcd --- /dev/null +++ b/data/hlsl/geometryshader/normaldebug.geom @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +struct VSOutput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +[maxvertexcount(6)] +void main(triangle VSOutput input[3], inout LineStream outStream) +{ + float normalLength = 0.02; + for(int i=0; i<3; i++) + { + float3 pos = input[i].Pos.xyz; + float3 normal = input[i].Normal.xyz; + + GSOutput output = (GSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(pos, 1.0))); + output.Color = float3(1.0, 0.0, 0.0); + outStream.Append( output ); + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(pos + normal * normalLength, 1.0))); + output.Color = float3(0.0, 0.0, 1.0); + outStream.Append( output ); + + outStream.RestartStrip(); + } +} \ No newline at end of file diff --git a/data/hlsl/hdr/bloom.frag b/data/hlsl/hdr/bloom.frag new file mode 100644 index 00000000..13c5e14a --- /dev/null +++ b/data/hlsl/hdr/bloom.frag @@ -0,0 +1,62 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor0 : register(t0); +SamplerState samplerColor0 : register(s0); +Texture2D textureColor1 : register(t1); +SamplerState samplerColor1 : register(s1); + +[[vk::constant_id(0)]] const int dir = 0; + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + // From the OpenGL Super bible + const float weights[] = { 0.0024499299678342, + 0.0043538453346397, + 0.0073599963704157, + 0.0118349786570722, + 0.0181026699707781, + 0.0263392293891488, + 0.0364543006660986, + 0.0479932050577658, + 0.0601029809166942, + 0.0715974486241365, + 0.0811305381519717, + 0.0874493212267511, + 0.0896631113333857, + 0.0874493212267511, + 0.0811305381519717, + 0.0715974486241365, + 0.0601029809166942, + 0.0479932050577658, + 0.0364543006660986, + 0.0263392293891488, + 0.0181026699707781, + 0.0118349786570722, + 0.0073599963704157, + 0.0043538453346397, + 0.0024499299678342}; + + + const float blurScale = 0.003; + const float blurStrength = 1.0; + + float ar = 1.0; + // Aspect ratio for vertical blur pass + if (dir == 1) + { + float2 ts; + textureColor1.GetDimensions(ts.x, ts.y); + ar = ts.y / ts.x; + } + + float2 P = inUV.yx - float2(0, (25 >> 1) * ar * blurScale); + + float4 color = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < 25; i++) + { + float2 dv = float2(0.0, i * blurScale) * ar; + color += textureColor1.Sample(samplerColor1, P + dv) * weights[i] * blurStrength; + } + + return color; +} \ No newline at end of file diff --git a/data/hlsl/hdr/bloom.vert b/data/hlsl/hdr/bloom.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/hdr/bloom.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/hdr/composition.frag b/data/hlsl/hdr/composition.frag new file mode 100644 index 00000000..41c9be65 --- /dev/null +++ b/data/hlsl/hdr/composition.frag @@ -0,0 +1,11 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor0 : register(t0); +SamplerState samplerColor0 : register(s0); +Texture2D textureColor1 : register(t1); +SamplerState samplerColor1 : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor0.Sample(samplerColor0, inUV); +} \ No newline at end of file diff --git a/data/hlsl/hdr/composition.vert b/data/hlsl/hdr/composition.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/hdr/composition.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/hdr/gbuffer.frag b/data/hlsl/hdr/gbuffer.frag new file mode 100644 index 00000000..4e412a75 --- /dev/null +++ b/data/hlsl/hdr/gbuffer.frag @@ -0,0 +1,108 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnvMap : register(t1); +SamplerState samplerEnvMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 UVW : TEXCOORD0; +[[vk::location(1)]] float3 Pos : POSITION0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +struct FSOutput +{ + float4 Color0 : SV_TARGET0; + float4 Color1 : SV_TARGET1; +}; + +[[vk::constant_id(0)]] const int type = 0; + +#define PI 3.1415926 +#define TwoPI (2.0 * PI) + +struct UBO { + float4x4 projection; + float4x4 modelview; + float4x4 inverseModelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +cbuffer Exposure : register(b2) +{ + float exposure; +} + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + float4 color; + float3 wcNormal; + + switch (type) { + case 0: // Skybox + { + float3 normal = normalize(input.UVW); + color = textureEnvMap.Sample(samplerEnvMap, normal); + } + break; + + case 1: // Reflect + { + float3 wViewVec = mul((float4x3)ubo.inverseModelview, normalize(input.ViewVec)).xyz; + float3 normal = normalize(input.Normal); + float3 wNormal = mul((float4x3)ubo.inverseModelview, normal).xyz; + + float NdotL = max(dot(normal, input.LightVec), 0.0); + + float3 eyeDir = normalize(input.ViewVec); + float3 halfVec = normalize(input.LightVec + eyeDir); + float NdotH = max(dot(normal, halfVec), 0.0); + float NdotV = max(dot(normal, eyeDir), 0.0); + float VdotH = max(dot(eyeDir, halfVec), 0.0); + + // Geometric attenuation + float NH2 = 2.0 * NdotH; + float g1 = (NH2 * NdotV) / VdotH; + float g2 = (NH2 * NdotL) / VdotH; + float geoAtt = min(1.0, min(g1, g2)); + + const float F0 = 0.6; + const float k = 0.2; + + // Fresnel (schlick approximation) + float fresnel = pow(1.0 - VdotH, 5.0); + fresnel *= (1.0 - F0); + fresnel += F0; + + float spec = (fresnel * geoAtt) / (NdotV * NdotL * 3.14); + + color = textureEnvMap.Sample(samplerEnvMap, reflect(-wViewVec, wNormal)); + + color = float4(color.rgb * NdotL * (k + spec * (1.0 - k)), 1.0); + } + break; + + case 2: // Refract + { + float3 wViewVec = mul((float4x3)ubo.inverseModelview, normalize(input.ViewVec)).xyz; + float3 wNormal = mul((float4x3)ubo.inverseModelview, input.Normal).xyz; + color = textureEnvMap.Sample(samplerEnvMap, refract(-wViewVec, wNormal, 1.0/1.6)); + } + break; + } + + + // Color with manual exposure into attachment 0 + output.Color0.rgb = float3(1.0, 1.0, 1.0) - exp(-color.rgb * exposure); + + // Bright parts for bloom into attachment 1 + float l = dot(output.Color0.rgb, float3(0.2126, 0.7152, 0.0722)); + float threshold = 0.75; + output.Color1.rgb = (l > threshold) ? output.Color0.rgb : float3(0.0, 0.0, 0.0); + output.Color1.a = 1.0; + return output; +} \ No newline at end of file diff --git a/data/hlsl/hdr/gbuffer.vert b/data/hlsl/hdr/gbuffer.vert new file mode 100644 index 00000000..c833a812 --- /dev/null +++ b/data/hlsl/hdr/gbuffer.vert @@ -0,0 +1,51 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +[[vk::constant_id(0)]] const int type = 0; + +struct UBO { + float4x4 projection; + float4x4 modelview; + float4x4 inverseModelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +[[vk::location(1)]] float3 WorldPos : POSITION0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UVW = input.Pos; + + switch(type) { + case 0: // Skybox + output.WorldPos = mul((float4x3)ubo.modelview, input.Pos).xyz; + output.Pos = mul(ubo.projection, float4(output.WorldPos, 1.0)); + break; + case 1: // Object + output.WorldPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + break; + } + output.WorldPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + output.Normal = mul((float4x3)ubo.modelview, input.Normal).xyz; + + float3 lightPos = float3(0.0f, -5.0f, 5.0f); + output.LightVec = lightPos.xyz - output.WorldPos.xyz; + output.ViewVec = -output.WorldPos.xyz; + return output; +} diff --git a/data/hlsl/imgui/scene.frag b/data/hlsl/imgui/scene.frag new file mode 100644 index 00000000..cdb2d089 --- /dev/null +++ b/data/hlsl/imgui/scene.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float diffuse = max(dot(N, L), 0.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * input.Color + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/imgui/scene.vert b/data/hlsl/imgui/scene.vert new file mode 100644 index 00000000..f7a59099 --- /dev/null +++ b/data/hlsl/imgui/scene.vert @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/imgui/ui.frag b/data/hlsl/imgui/ui.frag new file mode 100644 index 00000000..562acfe4 --- /dev/null +++ b/data/hlsl/imgui/ui.frag @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +Texture2D fontTexture : register(t0); +SamplerState fontSampler : register(s0); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float4 Color : COLOR0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return input.Color * fontTexture.Sample(fontSampler, input.UV); +} \ No newline at end of file diff --git a/data/hlsl/imgui/ui.vert b/data/hlsl/imgui/ui.vert new file mode 100644 index 00000000..df4e48eb --- /dev/null +++ b/data/hlsl/imgui/ui.vert @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float2 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float4 Color : COLOR0; +}; + +struct PushConstants +{ + float2 scale; + float2 translate; +}; + +[[vk::push_constant]] +PushConstants pushConstants; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float4 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Color = input.Color; + output.Pos = float4(input.Pos * pushConstants.scale + pushConstants.translate, 0.0, 1.0); + return output; +} \ No newline at end of file diff --git a/data/hlsl/indirectdraw/ground.frag b/data/hlsl/indirectdraw/ground.frag new file mode 100644 index 00000000..435309e9 --- /dev/null +++ b/data/hlsl/indirectdraw/ground.frag @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t2); +SamplerState samplerColor : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Last array layer is terrain tex + float4 color = textureColor.Sample(samplerColor, input.UV); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.65, 0.65, 0.65); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.1, 0.1, 0.1); + return float4((ambient + diffuse) * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/indirectdraw/ground.vert b/data/hlsl/indirectdraw/ground.vert new file mode 100644 index 00000000..52500dd3 --- /dev/null +++ b/data/hlsl/indirectdraw/ground.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = input.UV * 32.0; + output.Normal = input.Normal; + + float4 pos = float4(input.Pos.xyz, 1.0); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + float4 wPos = mul(ubo.modelview, float4(pos.xyz, 1.0)); + float4 lPos = float4(0.0, -5.0, 0.0, 1.0); + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/indirectdraw/indirectdraw.frag b/data/hlsl/indirectdraw/indirectdraw.frag new file mode 100644 index 00000000..395a5a2b --- /dev/null +++ b/data/hlsl/indirectdraw/indirectdraw.frag @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +Texture2DArray textureArray : register(t1); +SamplerState samplerArray : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureArray.Sample(samplerArray, input.UV); + + if (color.a < 0.5) + { + clip(-1); + } + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.65, 0.65, 0.65); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + return float4((ambient + diffuse) * color.rgb, 1.0); +} diff --git a/data/hlsl/indirectdraw/indirectdraw.vert b/data/hlsl/indirectdraw/indirectdraw.vert new file mode 100644 index 00000000..135bd612 --- /dev/null +++ b/data/hlsl/indirectdraw/indirectdraw.vert @@ -0,0 +1,82 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +[[vk::location(4)]] float3 instancePos : POSITION1; +[[vk::location(5)]] float3 instanceRot : TEXCOORD1; +[[vk::location(6)]] float instanceScale : TEXCOORD2; +[[vk::location(7)]] int instanceTexIndex : TEXCOORD3; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = float3(input.UV, input.instanceTexIndex); + output.UV.y = 1.0 - output.UV.y; + + float4x4 mx, my, mz; + + // rotate around x + float s = sin(input.instanceRot.x); + float c = cos(input.instanceRot.x); + + mx[0] = float4(c, s, 0.0, 0.0); + mx[1] = float4(-s, c, 0.0, 0.0); + mx[2] = float4(0.0, 0.0, 1.0, 0.0); + mx[3] = float4(0.0, 0.0, 0.0, 1.0); + + // rotate around y + s = sin(input.instanceRot.y); + c = cos(input.instanceRot.y); + + my[0] = float4(c, 0.0, s, 0.0); + my[1] = float4(0.0, 1.0, 0.0, 0.0); + my[2] = float4(-s, 0.0, c, 0.0); + my[3] = float4(0.0, 0.0, 0.0, 1.0); + + // rot around z + s = sin(input.instanceRot.z); + c = cos(input.instanceRot.z); + + mz[0] = float4(1.0, 0.0, 0.0, 0.0); + mz[1] = float4(0.0, c, s, 0.0); + mz[2] = float4(0.0, -s, c, 0.0); + mz[3] = float4(0.0, 0.0, 0.0, 1.0); + + float4x4 rotMat = mul(mz, mul(my, mx)); + + output.Normal = mul((float4x3)rotMat, input.Normal).xyz; + + float4 pos = mul(rotMat, float4((input.Pos.xyz * input.instanceScale) + input.instancePos, 1.0)); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + float4 wPos = mul(ubo.modelview, float4(pos.xyz, 1.0)); + float4 lPos = float4(0.0, -5.0, 0.0, 1.0); + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/indirectdraw/skysphere.frag b/data/hlsl/indirectdraw/skysphere.frag new file mode 100644 index 00000000..f6fbfa89 --- /dev/null +++ b/data/hlsl/indirectdraw/skysphere.frag @@ -0,0 +1,11 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t2); +SamplerState samplerColor : register(s2); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + const float4 gradientStart = float4(0.93, 0.9, 0.81, 1.0); + const float4 gradientEnd = float4(0.35, 0.5, 1.0, 1.0); + return lerp(gradientStart, gradientEnd, min(0.5 - inUV.y, 0.5)/0.15 + 0.5); +} \ No newline at end of file diff --git a/data/hlsl/indirectdraw/skysphere.vert b/data/hlsl/indirectdraw/skysphere.vert new file mode 100644 index 00000000..c16dd3f2 --- /dev/null +++ b/data/hlsl/indirectdraw/skysphere.vert @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = float2(input.UV.x, 1.0-input.UV.y); + // Skysphere always at center, only use rotation part of modelview matrix + output.Pos = mul(ubo.projection, float4(mul((float3x3)ubo.modelview, input.Pos.xyz), 1)); + return output; +} diff --git a/data/hlsl/inlineuniformblocks/pbr.frag b/data/hlsl/inlineuniformblocks/pbr.frag new file mode 100644 index 00000000..ad1bf284 --- /dev/null +++ b/data/hlsl/inlineuniformblocks/pbr.frag @@ -0,0 +1,119 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +// Inline uniform block +struct UniformInline { + float roughness; + float metallic; + float r; + float g; + float b; + float ambient; +}; +cbuffer material : register(b0, space1) { UniformInline material; }; + +#define PI 3.14159265359 + +float3 materialcolor() +{ + return float3(material.r, material.g, material.b); +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float metallic) +{ + float3 F0 = lerp(float3(0.04, 0.04, 0.04), materialcolor(), metallic); // * material.specular + float3 F = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); + return F; +} + +// Specular BRDF composition -------------------------------------------- + +float3 BRDF(float3 L, float3 V, float3 N, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + float dotLH = clamp(dot(L, H), 0.0, 1.0); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) + { + float rroughness = max(0.05, roughness); + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, rroughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, rroughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, metallic); + + float3 spec = D * F * G / (4.0 * dotNL * dotNV); + + color += spec * dotNL * lightColor; + } + + return color; +} + +// ---------------------------------------------------------------------------- +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + + float roughness = material.roughness; + + // Specular contribution + float3 lightPos = float3(0.0f, 0.0f, 10.0f); + float3 Lo = float3(0.0, 0.0, 0.0); + float3 L = normalize(lightPos.xyz - input.WorldPos); + Lo += BRDF(L, V, N, material.metallic, roughness); + + // Combine with ambient + float3 color = materialcolor() * material.ambient; + color += Lo; + + // Gamma correct + color = pow(color, float3(0.4545, 0.4545, 0.4545)); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/inlineuniformblocks/pbr.vert b/data/hlsl/inlineuniformblocks/pbr.vert new file mode 100644 index 00000000..b9f5c1b3 --- /dev/null +++ b/data/hlsl/inlineuniformblocks/pbr.vert @@ -0,0 +1,38 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct PushConsts { + float3 objPos; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + pushConsts.objPos; + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} diff --git a/data/hlsl/inputattachments/attachmentread.frag b/data/hlsl/inputattachments/attachmentread.frag new file mode 100644 index 00000000..28ef33ed --- /dev/null +++ b/data/hlsl/inputattachments/attachmentread.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +[[vk::input_attachment_index(0)]][[vk::binding(0)]] SubpassInput inputColor; +[[vk::input_attachment_index(1)]][[vk::binding(1)]] SubpassInput inputDepth; + +struct UBO { + float2 brightnessContrast; + float2 range; + int attachmentIndex; +}; + +cbuffer ubo : register(b2) { UBO ubo; } + +float3 brightnessContrast(float3 color, float brightness, float contrast) { + return (color - 0.5) * contrast + 0.5 + brightness; +} + +float4 main() : SV_TARGET +{ + // Apply brightness and contrast filer to color input + if (ubo.attachmentIndex == 0) { + // Read color from previous color input attachment + float3 color = inputColor.SubpassLoad().rgb; + return float4(brightnessContrast(color, ubo.brightnessContrast[0], ubo.brightnessContrast[1]), 1); + } + + // Visualize depth input range + if (ubo.attachmentIndex == 1) { + // Read depth from previous depth input attachment + float depth = inputDepth.SubpassLoad().r; + return float4((depth - ubo.range[0]) * 1.0 / (ubo.range[1] - ubo.range[0]).xxx, 1); + } + + return 0.xxxx; +} \ No newline at end of file diff --git a/data/hlsl/inputattachments/attachmentread.vert b/data/hlsl/inputattachments/attachmentread.vert new file mode 100644 index 00000000..fa447fcf --- /dev/null +++ b/data/hlsl/inputattachments/attachmentread.vert @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main(uint VertexIndex : SV_VertexID) : SV_POSITION +{ + return float4(float2((VertexIndex << 1) & 2, VertexIndex & 2) * 2.0f - 1.0f, 0.0f, 1.0f); +} \ No newline at end of file diff --git a/data/hlsl/inputattachments/attachmentwrite.frag b/data/hlsl/inputattachments/attachmentwrite.frag new file mode 100644 index 00000000..35ea3f3a --- /dev/null +++ b/data/hlsl/inputattachments/attachmentwrite.frag @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Toon shading color attachment output + float intensity = dot(normalize(input.Normal), normalize(input.LightVec)); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); + + // Depth attachment does not need to be explicitly written +} \ No newline at end of file diff --git a/data/hlsl/inputattachments/attachmentwrite.vert b/data/hlsl/inputattachments/attachmentwrite.vert new file mode 100644 index 00000000..eff5642a --- /dev/null +++ b/data/hlsl/inputattachments/attachmentwrite.vert @@ -0,0 +1,36 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO { + float4x4 projection; + float4x4 model; + float4x4 view; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos, 1.0)))); + output.Color = input.Color; + output.Normal = input.Normal; + output.LightVec = float3(0.0f, 5.0f, 15.0f) - input.Pos; + output.ViewVec = -input.Pos.xyz; + return output; +} diff --git a/data/hlsl/instancing/instancing.frag b/data/hlsl/instancing/instancing.frag new file mode 100644 index 00000000..1e3a0b78 --- /dev/null +++ b/data/hlsl/instancing/instancing.frag @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +Texture2DArray textureArray : register(t1); +SamplerState samplerArray : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureArray.Sample(samplerArray, input.UV) * float4(input.Color, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.1) * input.Color; + float3 specular = (dot(N,L) > 0.0) ? pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75) * color.r : float3(0.0, 0.0, 0.0); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/instancing/instancing.vert b/data/hlsl/instancing/instancing.vert new file mode 100644 index 00000000..62e41234 --- /dev/null +++ b/data/hlsl/instancing/instancing.vert @@ -0,0 +1,89 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; + +// Instanced attributes +[[vk::location(4)]] float3 instancePos : POSITION1; +[[vk::location(5)]] float3 instanceRot : TEXCOORD1; +[[vk::location(6)]] float instanceScale : TEXCOORD2; +[[vk::location(7)]] int instanceTexIndex : TEXCOORD3; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float locSpeed; + float globSpeed; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = float3(input.UV, input.instanceTexIndex); + + // rotate around x + float s = sin(input.instanceRot.x + ubo.locSpeed); + float c = cos(input.instanceRot.x + ubo.locSpeed); + + float3x3 mx = { c, -s, 0.0, + s, c, 0.0, + 0.0, 0.0, 1.0 }; + + // rotate around y + s = sin(input.instanceRot.y + ubo.locSpeed); + c = cos(input.instanceRot.y + ubo.locSpeed); + + float3x3 my = { c, 0.0, -s, + 0.0, 1.0, 0.0, + s, 0.0, c }; + + // rot around z + s = sin(input.instanceRot.z + ubo.locSpeed); + c = cos(input.instanceRot.z + ubo.locSpeed); + + float3x3 mz = { 1.0, 0.0, 0.0, + 0.0, c, -s, + 0.0, s, c }; + + float3x3 rotMat = mul(mz, mul(my, mx)); + + float4x4 gRotMat; + s = sin(input.instanceRot.y + ubo.globSpeed); + c = cos(input.instanceRot.y + ubo.globSpeed); + gRotMat[0] = float4(c, 0.0, -s, 0.0); + gRotMat[1] = float4(0.0, 1.0, 0.0, 0.0); + gRotMat[2] = float4(s, 0.0, c, 0.0); + gRotMat[3] = float4(0.0, 0.0, 0.0, 1.0); + + float4 locPos = float4(mul(rotMat, input.Pos.xyz), 1.0); + float4 pos = float4((locPos.xyz * input.instanceScale) + input.instancePos, 1.0); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, mul(gRotMat, pos))); + output.Normal = mul((float3x3)mul(ubo.modelview, gRotMat), mul(rotMat, input.Normal)); + + pos = mul(ubo.modelview, float4(input.Pos.xyz + input.instancePos, 1.0)); + float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/instancing/planet.frag b/data/hlsl/instancing/planet.frag new file mode 100644 index 00000000..8fca3642 --- /dev/null +++ b/data/hlsl/instancing/planet.frag @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0) * 1.5; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 4.0) * float3(0.5, 0.5, 0.5) * color.r; + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/instancing/planet.vert b/data/hlsl/instancing/planet.vert new file mode 100644 index 00000000..a2ed98df --- /dev/null +++ b/data/hlsl/instancing/planet.vert @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = input.UV * float2(10.0, 6.0); + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.modelview, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.modelview, input.Normal); + float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/instancing/starfield.frag b/data/hlsl/instancing/starfield.frag new file mode 100644 index 00000000..a32fbaae --- /dev/null +++ b/data/hlsl/instancing/starfield.frag @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +#define HASHSCALE3 float3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(float3 p3) +{ + p3 = frac(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz+float3(19.19, 19.19, 19.19)); + return frac((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x); +} + +float3 starField(float3 pos) +{ + float3 color = float3(0.0, 0.0, 0.0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0); + color += starCol.xxx; + } + return color; +} + +float4 main([[vk::location(0)]] float3 inUVW : TEXCOORD0) : SV_TARGET +{ + return float4(starField(inUVW), 1.0); +} \ No newline at end of file diff --git a/data/hlsl/instancing/starfield.vert b/data/hlsl/instancing/starfield.vert new file mode 100644 index 00000000..cb7a40d2 --- /dev/null +++ b/data/hlsl/instancing/starfield.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UVW = float3((VertexIndex << 1) & 2, VertexIndex & 2, VertexIndex & 2); + output.Pos = float4(output.UVW.xy * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/hlsl/mesh/mesh.frag b/data/hlsl/mesh/mesh.frag new file mode 100644 index 00000000..2bc0a9c2 --- /dev/null +++ b/data/hlsl/mesh/mesh.frag @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/mesh/mesh.vert b/data/hlsl/mesh/mesh.vert new file mode 100644 index 00000000..2ea7b03b --- /dev/null +++ b/data/hlsl/mesh/mesh.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/multithreading/phong.frag b/data/hlsl/multithreading/phong.frag new file mode 100644 index 00000000..5212cd15 --- /dev/null +++ b/data/hlsl/multithreading/phong.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/multithreading/phong.vert b/data/hlsl/multithreading/phong.vert new file mode 100644 index 00000000..1487ba17 --- /dev/null +++ b/data/hlsl/multithreading/phong.vert @@ -0,0 +1,49 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct PushConsts +{ + float4x4 mvp; + float3 color; +}; +[[vk::push_constant]]PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + + if ( (input.Color.r == 1.0) && (input.Color.g == 0.0) && (input.Color.b == 0.0)) + { + output.Color = pushConsts.color; + } + else + { + output.Color = input.Color; + } + + output.Pos = mul(pushConsts.mvp, float4(input.Pos.xyz, 1.0)); + + float4 pos = mul(pushConsts.mvp, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)pushConsts.mvp, input.Normal); +// float3 lPos = ubo.lightPos.xyz; +float3 lPos = float3(0.0, 0.0, 0.0); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/multithreading/starsphere.frag b/data/hlsl/multithreading/starsphere.frag new file mode 100644 index 00000000..e516740e --- /dev/null +++ b/data/hlsl/multithreading/starsphere.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +#define HASHSCALE3 float3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(float3 p3) +{ + p3 = frac(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz+float3(19.19, 19.19, 19.19)); + return frac((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x); +} + +float3 starField(float3 pos) +{ + float3 color = float3(0.0, 0.0, 0.0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0); + color += starCol.xxx; + } + return color; +} + +float4 main([[vk::location(0)]] float3 inUVW : TEXCOORD0) : SV_TARGET +{ + // Fake atmosphere at the bottom + float3 atmosphere = clamp(float3(0.1, 0.15, 0.4) * (inUVW.y - 5.0), 0.0, 1.0); + + float3 color = starField(inUVW) + atmosphere; + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/multithreading/starsphere.vert b/data/hlsl/multithreading/starsphere.vert new file mode 100644 index 00000000..13e48cb2 --- /dev/null +++ b/data/hlsl/multithreading/starsphere.vert @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct PushConsts +{ + float4x4 mvp; +}; +[[vk::push_constant]]PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main([[vk::location(0)]] float3 Pos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.UVW = Pos; + output.Pos = mul(pushConsts.mvp, float4(Pos.xyz, 1.0)); + return output; +} diff --git a/data/hlsl/multiview/multiview.frag b/data/hlsl/multiview/multiview.frag new file mode 100644 index 00000000..2c14be89 --- /dev/null +++ b/data/hlsl/multiview/multiview.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/multiview/multiview.vert b/data/hlsl/multiview/multiview.vert new file mode 100644 index 00000000..214db9cf --- /dev/null +++ b/data/hlsl/multiview/multiview.vert @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct UBO +{ + float4x4 projection[2]; + float4x4 modelview[2]; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +VSOutput main(VSInput input, uint ViewIndex : SV_ViewID) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = mul((float3x3)ubo.modelview[ViewIndex], input.Normal); + + float4 pos = float4(input.Pos.xyz, 1.0); + float4 worldPos = mul(ubo.modelview[ViewIndex], pos); + + float3 lPos = mul(ubo.modelview[ViewIndex], ubo.lightPos).xyz; + output.LightVec = lPos - worldPos.xyz; + output.ViewVec = -worldPos.xyz; + + output.Pos = mul(ubo.projection[ViewIndex], worldPos); + return output; +} diff --git a/data/hlsl/multiview/viewdisplay.frag b/data/hlsl/multiview/viewdisplay.frag new file mode 100644 index 00000000..da365d00 --- /dev/null +++ b/data/hlsl/multiview/viewdisplay.frag @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +Texture2DArray textureView : register(t1); +SamplerState samplerView : register(s1); + +struct UBO +{ + [[vk::offset(272)]] float distortionAlpha; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +[[vk::constant_id(0)]] const float VIEW_LAYER = 0.0f; + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + const float alpha = ubo.distortionAlpha; + + float2 p1 = float2(2.0 * inUV - 1.0); + float2 p2 = p1 / (1.0 - alpha * length(p1)); + p2 = (p2 + 1.0) * 0.5; + + bool inside = ((p2.x >= 0.0) && (p2.x <= 1.0) && (p2.y >= 0.0 ) && (p2.y <= 1.0)); + return inside ? textureView.Sample(samplerView, float3(p2, VIEW_LAYER)) : float4(0.0, 0.0, 0.0, 0.0); +} \ No newline at end of file diff --git a/data/hlsl/multiview/viewdisplay.vert b/data/hlsl/multiview/viewdisplay.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/multiview/viewdisplay.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/negativeviewportheight/quad.frag b/data/hlsl/negativeviewportheight/quad.frag new file mode 100644 index 00000000..8236872c --- /dev/null +++ b/data/hlsl/negativeviewportheight/quad.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t0); +SamplerState samplerColor : register(s0); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, inUV); +} \ No newline at end of file diff --git a/data/hlsl/negativeviewportheight/quad.vert b/data/hlsl/negativeviewportheight/quad.vert new file mode 100644 index 00000000..1864c0be --- /dev/null +++ b/data/hlsl/negativeviewportheight/quad.vert @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = float4(input.Pos, 1.0f); + return output; +} diff --git a/data/hlsl/nv_ray_tracing_basic/closesthit.rchit b/data/hlsl/nv_ray_tracing_basic/closesthit.rchit new file mode 100644 index 00000000..ace73d3d --- /dev/null +++ b/data/hlsl/nv_ray_tracing_basic/closesthit.rchit @@ -0,0 +1,18 @@ +// Copyright 2020 Google LLC + +struct Attribute +{ + float2 attribs; +}; + +struct Payload +{ +[[vk::location(0)]] float3 hitValue; +}; + +[shader("closesthit")] +void main(inout Payload p, in float3 attribs) +{ + const float3 barycentricCoords = float3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y); + p.hitValue = barycentricCoords; +} diff --git a/data/hlsl/nv_ray_tracing_basic/miss.rmiss b/data/hlsl/nv_ray_tracing_basic/miss.rmiss new file mode 100644 index 00000000..d9e274c0 --- /dev/null +++ b/data/hlsl/nv_ray_tracing_basic/miss.rmiss @@ -0,0 +1,12 @@ +// Copyright 2020 Google LLC + +struct Payload +{ +[[vk::location(0)]] float3 hitValue; +}; + +[shader("miss")] +void main(inout Payload p) +{ + p.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file diff --git a/data/hlsl/nv_ray_tracing_basic/raygen.rgen b/data/hlsl/nv_ray_tracing_basic/raygen.rgen new file mode 100644 index 00000000..d30bb92e --- /dev/null +++ b/data/hlsl/nv_ray_tracing_basic/raygen.rgen @@ -0,0 +1,39 @@ +// Copyright 2020 Google LLC + +RaytracingAccelerationStructure rs : register(t0); +RWTexture2D image : register(u1); + +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + +struct Payload +{ +[[vk::location(0)]] float3 hitValue; +}; + +[shader("raygeneration")] +void main() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(rs, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} diff --git a/data/hlsl/nv_ray_tracing_reflections/closesthit.rchit b/data/hlsl/nv_ray_tracing_reflections/closesthit.rchit new file mode 100644 index 00000000..8c8358a6 --- /dev/null +++ b/data/hlsl/nv_ray_tracing_reflections/closesthit.rchit @@ -0,0 +1,68 @@ +// Copyright 2020 Google LLC + +struct RayPayload +{ + float3 color; + float distance; + float3 normal; + float reflector; +}; + +RaytracingAccelerationStructure topLevelAS : register(t0); +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + +StructuredBuffer vertices : register(t3); +StructuredBuffer indices : register(t4); + +struct Vertex +{ + float3 pos; + float3 normal; + float3 color; + float2 uv; + float _pad0; +}; + +Vertex unpack(uint index) +{ + float4 d0 = vertices[3 * index + 0]; + float4 d1 = vertices[3 * index + 1]; + float4 d2 = vertices[3 * index + 2]; + + Vertex v; + v.pos = d0.xyz; + v.normal = float3(d0.w, d1.x, d1.y); + v.color = float3(d1.z, d1.w, d2.x); + return v; +} + +[shader("closesthit")] +void main(inout RayPayload rayPayload, in float3 attribs) +{ + uint PrimitiveID = PrimitiveIndex(); + int3 index = int3(indices[3 * PrimitiveID], indices[3 * PrimitiveID + 1], indices[3 * PrimitiveID + 2]); + + Vertex v0 = unpack(index.x); + Vertex v1 = unpack(index.y); + Vertex v2 = unpack(index.z); + + // Interpolate normal + const float3 barycentricCoords = float3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y); + float3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z); + + // Basic lighting + float3 lightVector = normalize(cam.lightPos.xyz); + float dot_product = max(dot(lightVector, normal), 0.6); + rayPayload.color = v0.color * dot_product; + rayPayload.distance = RayTCurrent(); + rayPayload.normal = normal; + + // Objects with full white vertex color are treated as reflectors + rayPayload.reflector = ((v0.color.r == 1.0f) && (v0.color.g == 1.0f) && (v0.color.b == 1.0f)) ? 1.0f : 0.0f; +} diff --git a/data/hlsl/nv_ray_tracing_reflections/miss.rmiss b/data/hlsl/nv_ray_tracing_reflections/miss.rmiss new file mode 100644 index 00000000..8f75824a --- /dev/null +++ b/data/hlsl/nv_ray_tracing_reflections/miss.rmiss @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +struct RayPayload { + float3 color; + float distance; + float3 normal; + float reflector; +}; + +[shader("miss")] +void main(inout RayPayload rayPayload) +{ + float3 worldRayDirection = WorldRayDirection(); + + // View-independent background gradient to simulate a basic sky background + const float3 gradientStart = float3(0.5, 0.6, 1.0); + const float3 gradientEnd = float3(1.0, 1.0, 1.0); + float3 unitDir = normalize(worldRayDirection); + float t = 0.5 * (unitDir.y + 1.0); + rayPayload.color = (1.0-t) * gradientStart + t * gradientEnd; + + rayPayload.distance = -1.0f; + rayPayload.normal = float3(0, 0, 0); + rayPayload.reflector = 0.0f; +} \ No newline at end of file diff --git a/data/hlsl/nv_ray_tracing_reflections/raygen.rgen b/data/hlsl/nv_ray_tracing_reflections/raygen.rgen new file mode 100644 index 00000000..23d2cea8 --- /dev/null +++ b/data/hlsl/nv_ray_tracing_reflections/raygen.rgen @@ -0,0 +1,64 @@ +// Copyright 2020 Google LLC + +RaytracingAccelerationStructure rs : register(t0); +RWTexture2D image : register(u1); + +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + + +struct RayPayload { + float3 color; + float distance; + float3 normal; + float reflector; +}; + +// Max. number of recursion is passed via a specialization constant +[[vk::constant_id(0)]] const int MAX_RECURSION = 0; + +[shader("raygeneration")] +void main() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + float3 color = float3(0.0, 0.0, 0.0); + + for (int i = 0; i < MAX_RECURSION; i++) { + RayPayload rayPayload; + TraceRay(rs, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, rayPayload); + float3 hitColor = rayPayload.color; + + if (rayPayload.distance < 0.0f) { + color += hitColor; + break; + } else if (rayPayload.reflector == 1.0f) { + const float3 hitPos = rayDesc.Origin + rayDesc.Direction * rayPayload.distance; + rayDesc.Origin = hitPos + rayPayload.normal * 0.001f; + rayDesc.Direction = reflect(rayDesc.Direction, rayPayload.normal); + } else { + color += hitColor; + break; + } + + } + + image[int2(LaunchID.xy)] = float4(color, 0.0); +} diff --git a/data/hlsl/nv_ray_tracing_shadows/closesthit.rchit b/data/hlsl/nv_ray_tracing_shadows/closesthit.rchit new file mode 100644 index 00000000..6b990519 --- /dev/null +++ b/data/hlsl/nv_ray_tracing_shadows/closesthit.rchit @@ -0,0 +1,78 @@ +// Copyright 2020 Google LLC + +struct InPayload +{ + [[vk::location(0)]] float3 hitValue; +}; + +struct InOutPayload +{ + [[vk::location(2)]] bool shadowed; +}; + +RaytracingAccelerationStructure topLevelAS : register(t0); +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + +StructuredBuffer vertices : register(t3); +StructuredBuffer indices : register(t4); + +struct Vertex +{ + float3 pos; + float3 normal; + float3 color; + float2 uv; + float _pad0; +}; + +Vertex unpack(uint index) +{ + float4 d0 = vertices[3 * index + 0]; + float4 d1 = vertices[3 * index + 1]; + float4 d2 = vertices[3 * index + 2]; + + Vertex v; + v.pos = d0.xyz; + v.normal = float3(d0.w, d1.x, d1.y); + v.color = float3(d1.z, d1.w, d2.x); + return v; +} + +[shader("closesthit")] +void main(in InPayload inPayload, inout InOutPayload inOutPayload, in float3 attribs) +{ + uint PrimitiveID = PrimitiveIndex(); + int3 index = int3(indices[3 * PrimitiveID], indices[3 * PrimitiveID + 1], indices[3 * PrimitiveID + 2]); + + Vertex v0 = unpack(index.x); + Vertex v1 = unpack(index.y); + Vertex v2 = unpack(index.z); + + // Interpolate normal + const float3 barycentricCoords = float3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y); + float3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z); + + // Basic lighting + float3 lightVector = normalize(cam.lightPos.xyz); + float dot_product = max(dot(lightVector, normal), 0.2); + inPayload.hitValue = v0.color * dot_product; + + RayDesc rayDesc; + rayDesc.Origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent(); + rayDesc.Direction = lightVector; + rayDesc.TMin = 0.001; + rayDesc.TMax = 100.0; + + inOutPayload.shadowed = true; + // Offset indices to match shadow hit/miss index + TraceRay(topLevelAS, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER, 0xff, 1, 0, 1, rayDesc, inOutPayload); + if (inOutPayload.shadowed) { + inPayload.hitValue *= 0.3; + } +} diff --git a/data/hlsl/nv_ray_tracing_shadows/miss.rmiss b/data/hlsl/nv_ray_tracing_shadows/miss.rmiss new file mode 100644 index 00000000..b142967a --- /dev/null +++ b/data/hlsl/nv_ray_tracing_shadows/miss.rmiss @@ -0,0 +1,7 @@ +// Copyright 2020 Google LLC + +[shader("miss")] +void main([[vk::location(0)]] in float3 hitValue) +{ + hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file diff --git a/data/hlsl/nv_ray_tracing_shadows/raygen.rgen b/data/hlsl/nv_ray_tracing_shadows/raygen.rgen new file mode 100644 index 00000000..0ccf0e44 --- /dev/null +++ b/data/hlsl/nv_ray_tracing_shadows/raygen.rgen @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +RaytracingAccelerationStructure rs : register(t0); +RWTexture2D image : register(u1); + +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + +struct Payload +{ + [[vk::location(0)]] float3 hitValue; +}; + +[shader("raygeneration")] +void main() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(rs, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} diff --git a/data/hlsl/nv_ray_tracing_shadows/shadow.rmiss b/data/hlsl/nv_ray_tracing_shadows/shadow.rmiss new file mode 100644 index 00000000..7a104b6b --- /dev/null +++ b/data/hlsl/nv_ray_tracing_shadows/shadow.rmiss @@ -0,0 +1,7 @@ +// Copyright 2020 Google LLC + +[shader("miss")] +void main([[vk::location(2)]] in bool shadowed) +{ + shadowed = false; +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/mesh.frag b/data/hlsl/occlusionquery/mesh.frag new file mode 100644 index 00000000..9347ed10 --- /dev/null +++ b/data/hlsl/occlusionquery/mesh.frag @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float Visible : TEXCOORD3; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + if (input.Visible > 0.0) + { + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse + specular, 1.0); + } + else + { + return float4(float3(0.1, 0.1, 0.1), 1.0); + } +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/mesh.vert b/data/hlsl/occlusionquery/mesh.vert new file mode 100644 index 00000000..4b20662a --- /dev/null +++ b/data/hlsl/occlusionquery/mesh.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float visible; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float Visible : TEXCOORD3; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.Visible = ubo.visible; + + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.modelview, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.modelview, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/occluder.frag b/data/hlsl/occlusionquery/occluder.frag new file mode 100644 index 00000000..e18b7b33 --- /dev/null +++ b/data/hlsl/occlusionquery/occluder.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 0.5); +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/occluder.vert b/data/hlsl/occlusionquery/occluder.vert new file mode 100644 index 00000000..dce12c8a --- /dev/null +++ b/data/hlsl/occlusionquery/occluder.vert @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/simple.frag b/data/hlsl/occlusionquery/simple.frag new file mode 100644 index 00000000..a898835c --- /dev/null +++ b/data/hlsl/occlusionquery/simple.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/occlusionquery/simple.vert b/data/hlsl/occlusionquery/simple.vert new file mode 100644 index 00000000..1618e05b --- /dev/null +++ b/data/hlsl/occlusionquery/simple.vert @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main([[vk::location(0)]] float3 Pos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(Pos.xyz, 1.0))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/offscreen/mirror.frag b/data/hlsl/offscreen/mirror.frag new file mode 100644 index 00000000..b9c68b7e --- /dev/null +++ b/data/hlsl/offscreen/mirror.frag @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float4 ProjCoord : POSITION0; +}; + +float4 main(VSOutput input, bool FrontFacing : SV_IsFrontFace) : SV_TARGET +{ + float4 tmp = (1.0 / input.ProjCoord.w).xxxx; + float4 projCoord = input.ProjCoord * tmp; + + // Scale and bias + projCoord += float4(1.0, 1.0, 1.0, 1.0); + projCoord *= float4(0.5, 0.5, 0.5, 0.5); + + // Slow single pass blur + // For demonstration purposes only + const float blurSize = 1.0 / 512.0; + + float4 color = float4(float3(0.0, 0.0, 0.0), 1.); + + if (FrontFacing) + { + // Only render mirrored scene on front facing (upper) side of mirror surface + float4 reflection = float4(0.0, 0.0, 0.0, 0.0); + for (int x = -3; x <= 3; x++) + { + for (int y = -3; y <= 3; y++) + { + reflection += textureColor.Sample(samplerColor, float2(projCoord.x + x * blurSize, projCoord.y + y * blurSize)) / 49.0; + } + } + color += reflection; + } + + return color; +} \ No newline at end of file diff --git a/data/hlsl/offscreen/mirror.vert b/data/hlsl/offscreen/mirror.vert new file mode 100644 index 00000000..8793d02b --- /dev/null +++ b/data/hlsl/offscreen/mirror.vert @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float4 ProjCoord : POSITION0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.ProjCoord = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + output.Pos = output.ProjCoord; + return output; +} diff --git a/data/hlsl/offscreen/phong.frag b/data/hlsl/offscreen/phong.frag new file mode 100644 index 00000000..62c69695 --- /dev/null +++ b/data/hlsl/offscreen/phong.frag @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(0.1, 0.1, 0.1, 1.0); + float4 IDiffuse = max(dot(input.Normal, input.LightVec), 0.0).xxxx; + float specular = 0.75; + float4 ISpecular = float4(0.0, 0.0, 0.0, 0.0); + if (dot(input.EyePos, input.Normal) < 0.0) + { + ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 16.0) * specular; + } + + return float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); +} \ No newline at end of file diff --git a/data/hlsl/offscreen/phong.vert b/data/hlsl/offscreen/phong.vert new file mode 100644 index 00000000..792eb7c5 --- /dev/null +++ b/data/hlsl/offscreen/phong.vert @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float ClipDistance : SV_ClipDistance0; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + output.EyePos = mul(ubo.model, input.Pos).xyz; + output.LightVec = normalize(ubo.lightPos.xyz - output.EyePos); + + // Clip against reflection plane + float4 clipPlane = float4(0.0, -1.0, 0.0, 1.5); + output.ClipDistance = dot(input.Pos, clipPlane); + return output; +} diff --git a/data/hlsl/offscreen/quad.frag b/data/hlsl/offscreen/quad.frag new file mode 100644 index 00000000..997a9419 --- /dev/null +++ b/data/hlsl/offscreen/quad.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return textureColor.Sample(samplerColor, inUV); +} \ No newline at end of file diff --git a/data/hlsl/offscreen/quad.vert b/data/hlsl/offscreen/quad.vert new file mode 100644 index 00000000..b8833fd7 --- /dev/null +++ b/data/hlsl/offscreen/quad.vert @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/parallaxmapping/parallax.frag b/data/hlsl/parallaxmapping/parallax.frag new file mode 100644 index 00000000..dc0d86b6 --- /dev/null +++ b/data/hlsl/parallaxmapping/parallax.frag @@ -0,0 +1,148 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); +Texture2D textureNormalHeightMap : register(t2); +SamplerState samplerNormalHeightMap : register(s2); + +struct UBO +{ + float heightScale; + float parallaxBias; + float numLayers; + int mappingMode; +}; + +cbuffer ubo : register(b3) { UBO ubo; } + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 TangentLightPos : TEXCOORD1; +[[vk::location(2)]] float3 TangentViewPos : TEXCOORD2; +[[vk::location(3)]] float3 TangentFragPos : TEXCOORD3; +}; + +float2 parallax_uv(float2 uv, float3 view_dir, int type) +{ + if (type == 2) { + // Parallax mapping + float depth = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, uv, 0.0).a; + float2 p = view_dir.xy * (depth * (ubo.heightScale * 0.5) + ubo.parallaxBias) / view_dir.z; + return uv - p; + } else { + float layer_depth = 1.0 / ubo.numLayers; + float cur_layer_depth = 0.0; + float2 delta_uv = view_dir.xy * ubo.heightScale / (view_dir.z * ubo.numLayers); + float2 cur_uv = uv; + + float depth_from_tex = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, cur_uv, 0.0).a; + + for (int i = 0; i < 32; i++) { + cur_layer_depth += layer_depth; + cur_uv -= delta_uv; + depth_from_tex = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, cur_uv, 0.0).a; + if (depth_from_tex < cur_layer_depth) { + break; + } + } + + if (type == 3) { + // Steep parallax mapping + return cur_uv; + } else { + // Parallax occlusion mapping + float2 prev_uv = cur_uv + delta_uv; + float next = depth_from_tex - cur_layer_depth; + float prev = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, prev_uv, 0.0).a - cur_layer_depth + layer_depth; + float weight = next / (next - prev); + return lerp(cur_uv, prev_uv, weight); + } + } +} + +float2 parallaxMapping(float2 uv, float3 viewDir) +{ + float height = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, uv, 0.0).a; + float2 p = viewDir.xy * (height * (ubo.heightScale * 0.5) + ubo.parallaxBias) / viewDir.z; + return uv - p; +} + +float2 steepParallaxMapping(float2 uv, float3 viewDir) +{ + float layerDepth = 1.0 / ubo.numLayers; + float currLayerDepth = 0.0; + float2 deltaUV = viewDir.xy * ubo.heightScale / (viewDir.z * ubo.numLayers); + float2 currUV = uv; + float height = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, currUV, 0.0).a; + for (int i = 0; i < ubo.numLayers; i++) { + currLayerDepth += layerDepth; + currUV -= deltaUV; + height = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, currUV, 0.0).a; + if (height < currLayerDepth) { + break; + } + } + return currUV; +} + +float2 parallaxOcclusionMapping(float2 uv, float3 viewDir) +{ + float layerDepth = 1.0 / ubo.numLayers; + float currLayerDepth = 0.0; + float2 deltaUV = viewDir.xy * ubo.heightScale / (viewDir.z * ubo.numLayers); + float2 currUV = uv; + float height = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, currUV, 0.0).a; + for (int i = 0; i < ubo.numLayers; i++) { + currLayerDepth += layerDepth; + currUV -= deltaUV; + height = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, currUV, 0.0).a; + if (height < currLayerDepth) { + break; + } + } + float2 prevUV = currUV + deltaUV; + float nextDepth = height - currLayerDepth; + float prevDepth = 1.0 - textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, prevUV, 0.0).a - currLayerDepth + layerDepth; + return lerp(currUV, prevUV, nextDepth / (nextDepth - prevDepth)); +} + +float4 main(VSOutput input) : SV_TARGET +{ + float3 V = normalize(input.TangentViewPos - input.TangentFragPos); + float2 uv = input.UV; + + if (ubo.mappingMode == 0) { + // Color only + return textureColorMap.Sample(samplerColorMap, input.UV); + } else { + switch(ubo.mappingMode) { + case 2: + uv = parallaxMapping(input.UV, V); + break; + case 3: + uv = steepParallaxMapping(input.UV, V); + break; + case 4: + uv = parallaxOcclusionMapping(input.UV, V); + break; + } + + // Discard fragments at texture border + if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { + clip(-1); + } + + float3 N = normalize(textureNormalHeightMap.SampleLevel(samplerNormalHeightMap, uv, 0.0).rgb * 2.0 - 1.0); + float3 L = normalize(input.TangentLightPos - input.TangentFragPos); + float3 R = reflect(-L, N); + float3 H = normalize(L + V); + + float3 color = textureColorMap.Sample(samplerColorMap, uv).rgb; + float3 ambient = 0.2 * color; + float3 diffuse = max(dot(L, N), 0.0) * color; + float3 specular = float3(0.15, 0.15, 0.15) * pow(max(dot(N, H), 0.0), 32.0); + + return float4(ambient + diffuse + specular, 1.0f); + } +} diff --git a/data/hlsl/parallaxmapping/parallax.vert b/data/hlsl/parallaxmapping/parallax.vert new file mode 100644 index 00000000..e124e70f --- /dev/null +++ b/data/hlsl/parallaxmapping/parallax.vert @@ -0,0 +1,48 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 Tangent : TEXCOORD1; +[[vk::location(4)]] float3 BiTangent : TEXCOORD2; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; + float4 cameraPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 TangentLightPos : TEXCOORD1; +[[vk::location(2)]] float3 TangentViewPos : TEXCOORD2; +[[vk::location(3)]] float3 TangentFragPos : TEXCOORD3; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos, 1.0f)))); + output.TangentFragPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.UV = input.UV; + + float3 T = normalize(mul((float3x3)ubo.model, input.Tangent)); + float3 B = normalize(mul((float3x3)ubo.model, input.BiTangent)); + float3 N = normalize(mul((float3x3)ubo.model, input.Normal)); + float3x3 TBN = transpose(float3x3(T, B, N)); + + output.TangentLightPos = mul(TBN, ubo.lightPos.xyz); + output.TangentViewPos = mul(TBN, ubo.cameraPos.xyz); + output.TangentFragPos = mul(TBN, output.TangentFragPos); + return output; +} diff --git a/data/hlsl/particlefire/normalmap.frag b/data/hlsl/particlefire/normalmap.frag new file mode 100644 index 00000000..40ff7358 --- /dev/null +++ b/data/hlsl/particlefire/normalmap.frag @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); +Texture2D textureNormalHeightMap : register(t2); +SamplerState samplerNormalHeightMap : register(s2); + +#define lightRadius 45.0 + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 LightVec : TEXCOORD2; +[[vk::location(2)]] float3 LightVecB : TEXCOORD3; +[[vk::location(3)]] float3 LightDir : TEXCOORD4; +[[vk::location(4)]] float3 ViewVec : TEXCOORD1; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 specularColor = float3(0.85, 0.5, 0.0); + + float invRadius = 1.0/lightRadius; + float ambient = 0.25; + + float3 rgb, normal; + + rgb = textureColorMap.Sample(samplerColorMap, input.UV).rgb; + normal = normalize((textureNormalHeightMap.Sample(samplerNormalHeightMap, input.UV).rgb - 0.5) * 2.0); + + float distSqr = dot(input.LightVecB, input.LightVecB); + float3 lVec = input.LightVecB * rsqrt(distSqr); + + float atten = max(clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0), ambient); + float diffuse = clamp(dot(lVec, normal), 0.0, 1.0); + + float3 light = normalize(-input.LightVec); + float3 view = normalize(input.ViewVec); + float3 reflectDir = reflect(-light, normal); + + float specular = pow(max(dot(view, reflectDir), 0.0), 4.0); + + return float4((rgb * atten + (diffuse * rgb + 0.5 * specular * specularColor.rgb)) * atten, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/particlefire/normalmap.vert b/data/hlsl/particlefire/normalmap.vert new file mode 100644 index 00000000..33beddb7 --- /dev/null +++ b/data/hlsl/particlefire/normalmap.vert @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 Tangent : TEXCOORD1; +[[vk::location(4)]] float3 BiTangent : TEXCOORD2; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 LightVec : TEXCOORD2; +[[vk::location(2)]] float3 LightVecB : TEXCOORD3; +[[vk::location(3)]] float3 LightDir : TEXCOORD4; +[[vk::location(4)]] float3 ViewVec : TEXCOORD1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float3 vertexPosition = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.LightDir = normalize(ubo.lightPos.xyz - vertexPosition); + + // Setup (t)angent-(b)inormal-(n)ormal matrix for converting + // object coordinates into tangent space + float3x3 tbnMatrix; + tbnMatrix[0] = mul((float3x3)ubo.normal, input.Tangent); + tbnMatrix[1] = mul((float3x3)ubo.normal, input.BiTangent); + tbnMatrix[2] = mul((float3x3)ubo.normal, input.Normal); + + output.LightVec.xyz = mul(float3(ubo.lightPos.xyz - vertexPosition), tbnMatrix); + + float3 lightDist = ubo.lightPos.xyz - input.Pos; + output.LightVecB.x = dot(input.Tangent, lightDist); + output.LightVecB.y = dot(input.BiTangent, lightDist); + output.LightVecB.z = dot(input.Normal, lightDist); + + output.ViewVec.x = dot(input.Tangent, input.Pos); + output.ViewVec.y = dot(input.BiTangent, input.Pos); + output.ViewVec.z = dot(input.Normal, input.Pos); + + output.UV = input.UV; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/particlefire/particle.frag b/data/hlsl/particlefire/particle.frag new file mode 100644 index 00000000..f2a7d375 --- /dev/null +++ b/data/hlsl/particlefire/particle.frag @@ -0,0 +1,52 @@ +// Copyright 2020 Google LLC + +Texture2D textureSmoke : register(t1); +SamplerState samplerSmoke : register(s1); +Texture2D textureFire : register(t2); +SamplerState samplerFire : register(s2); + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float4 Color : COLOR0; +[[vk::location(1)]] float Alpha : TEXCOODR0; +[[vk::location(2)]] int Type : TEXCOODR1; +[[vk::location(3)]] float Rotation : TEXCOODR2; +[[vk::location(4)]] float2 CenterPos : POSITION1; +[[vk::location(5)]] float PointSize : TEXCOORD3; +}; + +float4 main (VSOutput input) : SV_TARGET +{ + float4 color; + float alpha = (input.Alpha <= 1.0) ? input.Alpha : 2.0 - input.Alpha; + + // Rotate texture coordinates + // Rotate UV + float rotCenter = 0.5; + float rotCos = cos(input.Rotation); + float rotSin = sin(input.Rotation); + + float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5; + + float2 rotUV = float2( + rotCos * (PointCoord.x - rotCenter) + rotSin * (PointCoord.y - rotCenter) + rotCenter, + rotCos * (PointCoord.y - rotCenter) - rotSin * (PointCoord.x - rotCenter) + rotCenter); + + float4 outFragColor; + if (input.Type == 0) + { + // Flame + color = textureFire.Sample(samplerFire, rotUV); + outFragColor.a = 0.0; + } + else + { + // Smoke + color = textureSmoke.Sample(samplerSmoke, rotUV); + outFragColor.a = color.a * alpha; + } + + outFragColor.rgb = color.rgb * input.Color.rgb * alpha; + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/particlefire/particle.vert b/data/hlsl/particlefire/particle.vert new file mode 100644 index 00000000..30794139 --- /dev/null +++ b/data/hlsl/particlefire/particle.vert @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float4 Color : COLOR0; +[[vk::location(2)]] float Alpha : TEXCOORD0; +[[vk::location(3)]] float Size : TEXCOORD1; +[[vk::location(4)]] float Rotation : TEXCOORD2; +[[vk::location(5)]] int Type : TEXCOORD3; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::builtin("PointSize")]] float PSize : PSIZE; +[[vk::location(0)]] float4 Color : COLOR0; +[[vk::location(1)]] float Alpha : TEXCOORD0; +[[vk::location(2)]] int Type : TEXCOORD1; +[[vk::location(3)]] float Rotation : TEXCOORD2; +[[vk::location(4)]] float2 CenterPos : POSITION1; +[[vk::location(5)]] float PointSize : TEXCOORD3; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float2 viewportDim; + float pointSize; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Alpha = input.Alpha; + output.Type = input.Type; + output.Rotation = input.Rotation; + + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + + // Base size of the point sprites + float spriteSize = 8.0 * input.Size; + + // Scale particle size depending on camera projection + float4 eyePos = mul(ubo.modelview, float4(input.Pos.xyz, 1.0)); + float4 projectedCorner = mul(ubo.projection, float4(0.5 * spriteSize, 0.5 * spriteSize, eyePos.z, eyePos.w)); + output.PointSize = output.PSize = ubo.viewportDim.x * projectedCorner.x / projectedCorner.w; + output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * ubo.viewportDim; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pbrbasic/pbr.frag b/data/hlsl/pbrbasic/pbr.frag new file mode 100644 index 00000000..51914df3 --- /dev/null +++ b/data/hlsl/pbrbasic/pbr.frag @@ -0,0 +1,133 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct UBOShared { + float4 lights[4]; +}; + +cbuffer uboParams : register(b1) { UBOShared uboParams; }; + +struct PushConsts { +[[vk::offset(12)]] float roughness; +[[vk::offset(16)]] float metallic; +[[vk::offset(20)]] float r; +[[vk::offset(24)]] float g; +[[vk::offset(28)]] float b; +}; + +[[vk::push_constant]] PushConsts material; + +static const float PI = 3.14159265359; + +//#define ROUGHNESS_PATTERN 1 + +float3 materialcolor() +{ + return float3(material.r, material.g, material.b); +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float metallic) +{ + float3 F0 = lerp(float3(0.04, 0.04, 0.04), materialcolor(), metallic); // * material.specular + float3 F = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); + return F; +} + +// Specular BRDF composition -------------------------------------------- + +float3 BRDF(float3 L, float3 V, float3 N, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + float dotLH = clamp(dot(L, H), 0.0, 1.0); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) + { + float rroughness = max(0.05, roughness); + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, metallic); + + float3 spec = D * F * G / (4.0 * dotNL * dotNV); + + color += spec * dotNL * lightColor; + } + + return color; +} + +// ---------------------------------------------------------------------------- +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + + float roughness = material.roughness; + + // Add striped pattern to roughness based on vertex position +#ifdef ROUGHNESS_PATTERN + roughness = max(roughness, step(frac(input.WorldPos.y * 2.02), 0.5)); +#endif + + // Specular contribution + float3 Lo = float3(0.0, 0.0, 0.0); + for (int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += BRDF(L, V, N, material.metallic, roughness); + }; + + // Combine with ambient + float3 color = materialcolor() * 0.02; + color += Lo; + + // Gamma correct + color = pow(color, float3(0.4545, 0.4545, 0.4545)); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbrbasic/pbr.vert b/data/hlsl/pbrbasic/pbr.vert new file mode 100644 index 00000000..c53e7dbb --- /dev/null +++ b/data/hlsl/pbrbasic/pbr.vert @@ -0,0 +1,39 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct PushConsts { + float3 objPos; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + pushConsts.objPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/pbribl/filtercube.vert b/data/hlsl/pbribl/filtercube.vert new file mode 100644 index 00000000..514b4dd2 --- /dev/null +++ b/data/hlsl/pbribl/filtercube.vert @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +}; + +struct PushConsts { +[[vk::offset(0)]] float4x4 mvp; +}; +[[vk::push_constant]] PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UVW = input.Pos; + output.Pos = mul(pushConsts.mvp, float4(input.Pos.xyz, 1.0)); + return output; +} diff --git a/data/hlsl/pbribl/genbrdflut.frag b/data/hlsl/pbribl/genbrdflut.frag new file mode 100644 index 00000000..ca18d842 --- /dev/null +++ b/data/hlsl/pbribl/genbrdflut.frag @@ -0,0 +1,88 @@ +// Copyright 2020 Google LLC + +[[vk::constant_id(0)]] const uint NUM_SAMPLES = 1024u; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +float2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const float3 N = float3(0.0, 0.0, 1.0); + float3 V = float3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + float2 LUT = float2(0.0, 0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + float2 Xi = hammersley2d(i, NUM_SAMPLES); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += float2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return float4(BRDF(inUV.x, 1.0-inUV.y), 0.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbribl/genbrdflut.vert b/data/hlsl/pbribl/genbrdflut.vert new file mode 100644 index 00000000..188b7298 --- /dev/null +++ b/data/hlsl/pbribl/genbrdflut.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/hlsl/pbribl/irradiancecube.frag b/data/hlsl/pbribl/irradiancecube.frag new file mode 100644 index 00000000..66d63bf6 --- /dev/null +++ b/data/hlsl/pbribl/irradiancecube.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t0); +SamplerState samplerEnv : register(s0); + +struct PushConsts { +[[vk::offset(64)]] float deltaPhi; +[[vk::offset(68)]] float deltaTheta; +}; +[[vk::push_constant]]PushConsts consts; + +#define PI 3.1415926535897932384626433832795 + +float4 main([[vk::location(0)]] float3 inPos : TEXCOORD0) : SV_TARGET +{ + float3 N = normalize(inPos); + float3 up = float3(0.0, 1.0, 0.0); + float3 right = normalize(cross(up, N)); + up = cross(N, right); + + const float TWO_PI = PI * 2.0; + const float HALF_PI = PI * 0.5; + + float3 color = float3(0.0, 0.0, 0.0); + uint sampleCount = 0u; + for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) { + for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) { + float3 tempVec = cos(phi) * right + sin(phi) * up; + float3 sampleVector = cos(theta) * N + sin(theta) * tempVec; + color += textureEnv.Sample(samplerEnv, sampleVector).rgb * cos(theta) * sin(theta); + sampleCount++; + } + } + return float4(PI * color / float(sampleCount), 1.0); +} diff --git a/data/hlsl/pbribl/pbribl.frag b/data/hlsl/pbribl/pbribl.frag new file mode 100644 index 00000000..4f135c4d --- /dev/null +++ b/data/hlsl/pbribl/pbribl.frag @@ -0,0 +1,170 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO { + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +cbuffer uboParams : register(b1) { UBOParams uboParams; }; + +struct PushConsts { +[[vk::offset(12)]] float roughness; +[[vk::offset(16)]] float metallic; +[[vk::offset(20)]] float specular; +[[vk::offset(24)]] float r; +[[vk::offset(28)]] float g; +[[vk::offset(32)]] float b; +}; +[[vk::push_constant]] PushConsts material; + +TextureCube textureIrradiance : register(t2); +SamplerState samplerIrradiance : register(s2); +Texture2D textureBRDFLUT : register(t3); +SamplerState samplerBRDFLUT : register(s3); +TextureCube prefilteredMapTexture : register(t4); +SamplerState prefilteredMapSampler : register(s4); + +#define PI 3.1415926535897932384626433832795 +#define ALBEDO float3(material.r, material.g, material.b) + +// From http://filmicgames.com/archives/75 +float3 Uncharted2Tonemap(float3 x) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float3 F0) +{ + return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); +} +float3 F_SchlickR(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max((1.0 - roughness).xxx, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 prefilteredReflection(float3 R, float roughness) +{ + const float MAX_REFLECTION_LOD = 9.0; // todo: param/const + float lod = roughness * MAX_REFLECTION_LOD; + float lodf = floor(lod); + float lodc = ceil(lod); + float3 a = prefilteredMapTexture.SampleLevel(prefilteredMapSampler, R, lodf).rgb; + float3 b = prefilteredMapTexture.SampleLevel(prefilteredMapSampler, R, lodc).rgb; + return lerp(a, b, lod - lodf); +} + +float3 specularContribution(float3 L, float3 V, float3 N, float3 F0, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) { + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, F0); + float3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001); + float3 kD = (float3(1.0, 1.0, 1.0) - F) * (1.0 - metallic); + color += (kD * ALBEDO / PI + spec) * dotNL; + } + + return color; +} + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + float3 R = reflect(-V, N); + + float metallic = material.metallic; + float roughness = material.roughness; + + float3 F0 = float3(0.04, 0.04, 0.04); + F0 = lerp(F0, ALBEDO, metallic); + + float3 Lo = float3(0.0, 0.0, 0.0); + for(int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += specularContribution(L, V, N, F0, metallic, roughness); + } + + float2 brdf = textureBRDFLUT.Sample(samplerBRDFLUT, float2(max(dot(N, V), 0.0), roughness)).rg; + float3 reflection = prefilteredReflection(R, roughness).rgb; + float3 irradiance = textureIrradiance.Sample(samplerIrradiance, N).rgb; + + // Diffuse based on irradiance + float3 diffuse = irradiance * ALBEDO; + + float3 F = F_SchlickR(max(dot(N, V), 0.0), F0, roughness); + + // Specular reflectance + float3 specular = reflection * (F * brdf.x + brdf.y); + + // Ambient part + float3 kD = 1.0 - F; + kD *= 1.0 - metallic; + float3 ambient = (kD * diffuse + specular); + + float3 color = ambient + Lo; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbribl/pbribl.vert b/data/hlsl/pbribl/pbribl.vert new file mode 100644 index 00000000..12d2e6e7 --- /dev/null +++ b/data/hlsl/pbribl/pbribl.vert @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct PushConsts { + float3 objPos; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + pushConsts.objPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.UV = input.UV; + output.UV.y = 1.0 - input.UV.y; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} diff --git a/data/hlsl/pbribl/prefilterenvmap.frag b/data/hlsl/pbribl/prefilterenvmap.frag new file mode 100644 index 00000000..1f605d04 --- /dev/null +++ b/data/hlsl/pbribl/prefilterenvmap.frag @@ -0,0 +1,106 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t0); +SamplerState samplerEnv : register(s0); + +struct PushConsts { +[[vk::offset(64)]] float roughness; +[[vk::offset(68)]] uint numSamples; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Normal Distribution function +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +float3 prefilterEnvMap(float3 R, float roughness) +{ + float3 N = R; + float3 V = R; + float3 color = float3(0.0, 0.0, 0.0); + float totalWeight = 0.0; + int2 envMapDims; + textureEnv.GetDimensions(envMapDims.x, envMapDims.y); + float envMapDim = float(envMapDims.x); + for(uint i = 0u; i < consts.numSamples; i++) { + float2 Xi = hammersley2d(i, consts.numSamples); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + float dotNL = clamp(dot(N, L), 0.0, 1.0); + if(dotNL > 0.0) { + // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ + + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotVH = clamp(dot(V, H), 0.0, 1.0); + + // Probability Distribution Function + float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; + // Slid angle of current smple + float omegaS = 1.0 / (float(consts.numSamples) * pdf); + // Solid angle of 1 pixel across all cube faces + float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); + // Biased (+1.0) mip level for better result + float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + color += textureEnv.SampleLevel(samplerEnv, L, mipLevel).rgb * dotNL; + totalWeight += dotNL; + + } + } + return (color / totalWeight); +} + + +float4 main([[vk::location(0)]] float3 inPos : POSITION0) : SV_TARGET +{ + float3 N = normalize(inPos); + return float4(prefilterEnvMap(N, consts.roughness), 1.0); +} diff --git a/data/hlsl/pbribl/skybox.frag b/data/hlsl/pbribl/skybox.frag new file mode 100644 index 00000000..439c6287 --- /dev/null +++ b/data/hlsl/pbribl/skybox.frag @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t2); +SamplerState samplerEnv : register(s2); + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +cbuffer uboParams : register(b1) { UBOParams uboParams; }; + +// From http://filmicworlds.com/blog/filmic-tonemapping-operators/ +float3 Uncharted2Tonemap(float3 color) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; +} + +float4 main([[vk::location(0)]] float3 inUVW : POSITION0) : SV_TARGET +{ + float3 color = textureEnv.Sample(samplerEnv, inUVW).rgb; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbribl/skybox.vert b/data/hlsl/pbribl/skybox.vert new file mode 100644 index 00000000..26e3fb6d --- /dev/null +++ b/data/hlsl/pbribl/skybox.vert @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/pbrtexture/filtercube.vert b/data/hlsl/pbrtexture/filtercube.vert new file mode 100644 index 00000000..514b4dd2 --- /dev/null +++ b/data/hlsl/pbrtexture/filtercube.vert @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +}; + +struct PushConsts { +[[vk::offset(0)]] float4x4 mvp; +}; +[[vk::push_constant]] PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UVW = input.Pos; + output.Pos = mul(pushConsts.mvp, float4(input.Pos.xyz, 1.0)); + return output; +} diff --git a/data/hlsl/pbrtexture/genbrdflut.frag b/data/hlsl/pbrtexture/genbrdflut.frag new file mode 100644 index 00000000..ca18d842 --- /dev/null +++ b/data/hlsl/pbrtexture/genbrdflut.frag @@ -0,0 +1,88 @@ +// Copyright 2020 Google LLC + +[[vk::constant_id(0)]] const uint NUM_SAMPLES = 1024u; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +float2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const float3 N = float3(0.0, 0.0, 1.0); + float3 V = float3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + float2 LUT = float2(0.0, 0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + float2 Xi = hammersley2d(i, NUM_SAMPLES); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += float2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + return float4(BRDF(inUV.x, 1.0-inUV.y), 0.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbrtexture/genbrdflut.vert b/data/hlsl/pbrtexture/genbrdflut.vert new file mode 100644 index 00000000..188b7298 --- /dev/null +++ b/data/hlsl/pbrtexture/genbrdflut.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/hlsl/pbrtexture/irradiancecube.frag b/data/hlsl/pbrtexture/irradiancecube.frag new file mode 100644 index 00000000..66d63bf6 --- /dev/null +++ b/data/hlsl/pbrtexture/irradiancecube.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t0); +SamplerState samplerEnv : register(s0); + +struct PushConsts { +[[vk::offset(64)]] float deltaPhi; +[[vk::offset(68)]] float deltaTheta; +}; +[[vk::push_constant]]PushConsts consts; + +#define PI 3.1415926535897932384626433832795 + +float4 main([[vk::location(0)]] float3 inPos : TEXCOORD0) : SV_TARGET +{ + float3 N = normalize(inPos); + float3 up = float3(0.0, 1.0, 0.0); + float3 right = normalize(cross(up, N)); + up = cross(N, right); + + const float TWO_PI = PI * 2.0; + const float HALF_PI = PI * 0.5; + + float3 color = float3(0.0, 0.0, 0.0); + uint sampleCount = 0u; + for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) { + for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) { + float3 tempVec = cos(phi) * right + sin(phi) * up; + float3 sampleVector = cos(theta) * N + sin(theta) * tempVec; + color += textureEnv.Sample(samplerEnv, sampleVector).rgb * cos(theta) * sin(theta); + sampleCount++; + } + } + return float4(PI * color / float(sampleCount), 1.0); +} diff --git a/data/hlsl/pbrtexture/pbrtexture.frag b/data/hlsl/pbrtexture/pbrtexture.frag new file mode 100644 index 00000000..9a966178 --- /dev/null +++ b/data/hlsl/pbrtexture/pbrtexture.frag @@ -0,0 +1,189 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO { + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +cbuffer uboParams : register(b1) { UBOParams uboParams; }; + +TextureCube textureIrradiance : register(t2); +SamplerState samplerIrradiance : register(s2); +Texture2D textureBRDFLUT : register(t3); +SamplerState samplerBRDFLUT : register(s3); +TextureCube prefilteredMapTexture : register(t4); +SamplerState prefilteredMapSampler : register(s4); + +Texture2D albedoMapTexture : register(t5); +SamplerState albedoMapSampler : register(s5); +Texture2D normalMapTexture : register(t6); +SamplerState normalMapSampler : register(s6); +Texture2D aoMapTexture : register(t7); +SamplerState aoMapSampler : register(s7); +Texture2D metallicMapTexture : register(t8); +SamplerState metallicMapSampler : register(s8); +Texture2D roughnessMapTexture : register(t9); +SamplerState roughnessMapSampler : register(s9); + +#define PI 3.1415926535897932384626433832795 +#define ALBEDO(uv) pow(albedoMapTexture.Sample(albedoMapSampler, uv).rgb, float3(2.2, 2.2, 2.2)) + +// From http://filmicgames.com/archives/75 +float3 Uncharted2Tonemap(float3 x) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float3 F0) +{ + return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); +} +float3 F_SchlickR(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max((1.0 - roughness).xxx, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 prefilteredReflection(float3 R, float roughness) +{ + const float MAX_REFLECTION_LOD = 9.0; // todo: param/const + float lod = roughness * MAX_REFLECTION_LOD; + float lodf = floor(lod); + float lodc = ceil(lod); + float3 a = prefilteredMapTexture.SampleLevel(prefilteredMapSampler, R, lodf).rgb; + float3 b = prefilteredMapTexture.SampleLevel(prefilteredMapSampler, R, lodc).rgb; + return lerp(a, b, lod - lodf); +} + +float3 specularContribution(float2 inUV, float3 L, float3 V, float3 N, float3 F0, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) { + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, F0); + float3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001); + float3 kD = (float3(1.0, 1.0, 1.0) - F) * (1.0 - metallic); + color += (kD * ALBEDO(inUV) / PI + spec) * dotNL; + } + + return color; +} + +// See http://www.thetenthplanet.de/archives/1180 +float3 perturbNormal(float2 inUV, float3 inWorldPos, float3 inNormal) +{ + float3 tangentNormal = normalMapTexture.Sample(normalMapSampler, inUV).xyz * 2.0 - 1.0; + + float3 q1 = ddx(inWorldPos); + float3 q2 = ddy(inWorldPos); + float2 st1 = ddx(inUV); + float2 st2 = ddy(inUV); + + float3 N = normalize(inNormal); + float3 T = normalize(q1 * st2.y - q2 * st1.y); + float3 B = -normalize(cross(N, T)); + float3x3 TBN = transpose(float3x3(T, B, N)); + + return normalize(mul(TBN, tangentNormal)); +} + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = perturbNormal(input.UV, input.WorldPos, input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + float3 R = reflect(-V, N); + + float metallic = metallicMapTexture.Sample(metallicMapSampler, input.UV).r; + float roughness = roughnessMapTexture.Sample(roughnessMapSampler, input.UV).r; + + float3 F0 = float3(0.04, 0.04, 0.04); + F0 = lerp(F0, ALBEDO(input.UV), metallic); + + float3 Lo = float3(0.0, 0.0, 0.0); + for(int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += specularContribution(input.UV, L, V, N, F0, metallic, roughness); + } + + float2 brdf = textureBRDFLUT.Sample(samplerBRDFLUT, float2(max(dot(N, V), 0.0), roughness)).rg; + float3 reflection = prefilteredReflection(R, roughness).rgb; + float3 irradiance = textureIrradiance.Sample(samplerIrradiance, N).rgb; + + // Diffuse based on irradiance + float3 diffuse = irradiance * ALBEDO(input.UV); + + float3 F = F_SchlickR(max(dot(N, V), 0.0), F0, roughness); + + // Specular reflectance + float3 specular = reflection * (F * brdf.x + brdf.y); + + // Ambient part + float3 kD = 1.0 - F; + kD *= 1.0 - metallic; + float3 ambient = (kD * diffuse + specular) * aoMapTexture.Sample(aoMapSampler, input.UV).rrr; + + float3 color = ambient + Lo; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbrtexture/pbrtexture.vert b/data/hlsl/pbrtexture/pbrtexture.vert new file mode 100644 index 00000000..5de805c6 --- /dev/null +++ b/data/hlsl/pbrtexture/pbrtexture.vert @@ -0,0 +1,38 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.UV = input.UV; + output.UV.y = 1.0 - input.UV.y; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} diff --git a/data/hlsl/pbrtexture/prefilterenvmap.frag b/data/hlsl/pbrtexture/prefilterenvmap.frag new file mode 100644 index 00000000..1f605d04 --- /dev/null +++ b/data/hlsl/pbrtexture/prefilterenvmap.frag @@ -0,0 +1,106 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t0); +SamplerState samplerEnv : register(s0); + +struct PushConsts { +[[vk::offset(64)]] float roughness; +[[vk::offset(68)]] uint numSamples; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Normal Distribution function +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +float3 prefilterEnvMap(float3 R, float roughness) +{ + float3 N = R; + float3 V = R; + float3 color = float3(0.0, 0.0, 0.0); + float totalWeight = 0.0; + int2 envMapDims; + textureEnv.GetDimensions(envMapDims.x, envMapDims.y); + float envMapDim = float(envMapDims.x); + for(uint i = 0u; i < consts.numSamples; i++) { + float2 Xi = hammersley2d(i, consts.numSamples); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + float dotNL = clamp(dot(N, L), 0.0, 1.0); + if(dotNL > 0.0) { + // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ + + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotVH = clamp(dot(V, H), 0.0, 1.0); + + // Probability Distribution Function + float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; + // Slid angle of current smple + float omegaS = 1.0 / (float(consts.numSamples) * pdf); + // Solid angle of 1 pixel across all cube faces + float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); + // Biased (+1.0) mip level for better result + float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + color += textureEnv.SampleLevel(samplerEnv, L, mipLevel).rgb * dotNL; + totalWeight += dotNL; + + } + } + return (color / totalWeight); +} + + +float4 main([[vk::location(0)]] float3 inPos : POSITION0) : SV_TARGET +{ + float3 N = normalize(inPos); + return float4(prefilterEnvMap(N, consts.roughness), 1.0); +} diff --git a/data/hlsl/pbrtexture/skybox.frag b/data/hlsl/pbrtexture/skybox.frag new file mode 100644 index 00000000..439c6287 --- /dev/null +++ b/data/hlsl/pbrtexture/skybox.frag @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +TextureCube textureEnv : register(t2); +SamplerState samplerEnv : register(s2); + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +cbuffer uboParams : register(b1) { UBOParams uboParams; }; + +// From http://filmicworlds.com/blog/filmic-tonemapping-operators/ +float3 Uncharted2Tonemap(float3 color) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; +} + +float4 main([[vk::location(0)]] float3 inUVW : POSITION0) : SV_TARGET +{ + float3 color = textureEnv.Sample(samplerEnv, inUVW).rgb; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pbrtexture/skybox.vert b/data/hlsl/pbrtexture/skybox.vert new file mode 100644 index 00000000..26e3fb6d --- /dev/null +++ b/data/hlsl/pbrtexture/skybox.vert @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} diff --git a/data/hlsl/pipelines/phong.frag b/data/hlsl/pipelines/phong.frag new file mode 100644 index 00000000..343c91a3 --- /dev/null +++ b/data/hlsl/pipelines/phong.frag @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Desaturate color + float3 color = lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.35, 0.35, 0.35); + return float4(ambient + diffuse * 1.75 + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pipelines/phong.vert b/data/hlsl/pipelines/phong.vert new file mode 100644 index 00000000..2ea7b03b --- /dev/null +++ b/data/hlsl/pipelines/phong.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pipelines/toon.frag b/data/hlsl/pipelines/toon.frag new file mode 100644 index 00000000..048b6b74 --- /dev/null +++ b/data/hlsl/pipelines/toon.frag @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Desaturate color + float3 color = lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + + float intensity = dot(N,L); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); +} \ No newline at end of file diff --git a/data/hlsl/pipelines/toon.vert b/data/hlsl/pipelines/toon.vert new file mode 100644 index 00000000..2ea7b03b --- /dev/null +++ b/data/hlsl/pipelines/toon.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pipelines/wireframe.frag b/data/hlsl/pipelines/wireframe.frag new file mode 100644 index 00000000..0ff24dd0 --- /dev/null +++ b/data/hlsl/pipelines/wireframe.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color * 1.5, 1); +} \ No newline at end of file diff --git a/data/hlsl/pipelines/wireframe.vert b/data/hlsl/pipelines/wireframe.vert new file mode 100644 index 00000000..089cd426 --- /dev/null +++ b/data/hlsl/pipelines/wireframe.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + return output; +} diff --git a/data/hlsl/pipelinestatistics/scene.frag b/data/hlsl/pipelinestatistics/scene.frag new file mode 100644 index 00000000..4cd20bf5 --- /dev/null +++ b/data/hlsl/pipelinestatistics/scene.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse + specular, 0.5); +} \ No newline at end of file diff --git a/data/hlsl/pipelinestatistics/scene.tesc b/data/hlsl/pipelinestatistics/scene.tesc new file mode 100644 index 00000000..bed96a0e --- /dev/null +++ b/data/hlsl/pipelinestatistics/scene.tesc @@ -0,0 +1,52 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +ConstantsHSOutput ConstantsHS(InputPatch patch, uint InvocationID : SV_PrimitiveID) +{ + ConstantsHSOutput output = (ConstantsHSOutput)0; + output.TessLevelInner = 2.0; + output.TessLevelOuter[0] = 1.0; + output.TessLevelOuter[1] = 1.0; + output.TessLevelOuter[2] = 1.0; + return output; +} + +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput main(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output = (HSOutput)0; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.Color = patch[InvocationID].Color; + output.ViewVec = patch[InvocationID].ViewVec; + output.LightVec = patch[InvocationID].LightVec; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pipelinestatistics/scene.tese b/data/hlsl/pipelinestatistics/scene.tese new file mode 100644 index 00000000..1cccb2b2 --- /dev/null +++ b/data/hlsl/pipelinestatistics/scene.tese @@ -0,0 +1,39 @@ +// Copyright 2020 Google LLC + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +[domain("tri")] +DSOutput main(ConstantsHSOutput input, float3 TessCoord : SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output = (DSOutput)0; + output.Pos = (TessCoord.x * patch[2].Pos) + + (TessCoord.y * patch[1].Pos) + + (TessCoord.z * patch[0].Pos); + output.Normal = TessCoord.x * patch[2].Normal + TessCoord.y * patch[1].Normal + TessCoord.z * patch[0].Normal; + output.ViewVec = TessCoord.x * patch[2].ViewVec + TessCoord.y * patch[1].ViewVec + TessCoord.z * patch[0].ViewVec; + output.LightVec = TessCoord.x * patch[2].LightVec + TessCoord.y * patch[1].LightVec + TessCoord.z * patch[0].LightVec; + output.Color = patch[0].Color; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pipelinestatistics/scene.vert b/data/hlsl/pipelinestatistics/scene.vert new file mode 100644 index 00000000..a11fe37c --- /dev/null +++ b/data/hlsl/pipelinestatistics/scene.vert @@ -0,0 +1,48 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +struct PushConsts { + float3 objPos; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + + float3 locPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + float3 worldPos = mul(ubo.modelview, float4(input.Pos + pushConsts.objPos, 1.0)).xyz; + output.Pos = mul(ubo.projection, float4(worldPos, 1.0)); + + float4 pos = mul(ubo.modelview, float4(worldPos, 1.0)); + output.Normal = mul((float3x3)ubo.modelview, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/pushconstants/lights.frag b/data/hlsl/pushconstants/lights.frag new file mode 100644 index 00000000..7b71cef6 --- /dev/null +++ b/data/hlsl/pushconstants/lights.frag @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +#define lightCount 6 + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float4 LightVec[lightCount] : TEXCOORD1; +}; + +#define MAX_LIGHT_DIST 9.0 * 9.0 + +float4 main(VSOutput input) : SV_TARGET +{ + float3 lightColor[lightCount]; + lightColor[0] = float3(1.0, 0.0, 0.0); + lightColor[1] = float3(0.0, 1.0, 0.0); + lightColor[2] = float3(0.0, 0.0, 1.0); + lightColor[3] = float3(1.0, 0.0, 1.0); + lightColor[4] = float3(0.0, 1.0, 1.0); + lightColor[5] = float3(1.0, 1.0, 0.0); + + float3 diffuse = float3(0.0, 0.0, 0.0); + // Just some very basic attenuation + for (int i = 0; i < lightCount; ++i) + { + float lRadius = MAX_LIGHT_DIST * input.LightVec[i].w; + + float dist = min(dot(input.LightVec[i], input.LightVec[i]), lRadius) / lRadius; + float distFactor = 1.0 - dist; + + diffuse += lightColor[i] * distFactor; + } + + return float4(diffuse, 1); +} \ No newline at end of file diff --git a/data/hlsl/pushconstants/lights.vert b/data/hlsl/pushconstants/lights.vert new file mode 100644 index 00000000..f9db58e8 --- /dev/null +++ b/data/hlsl/pushconstants/lights.vert @@ -0,0 +1,50 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +#define lightCount 6 + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightColor[lightCount]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct PushConsts { + float4 lightPos[lightCount]; +}; +[[vk::push_constant]] PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float4 LightVec[lightCount] : TEXCOORD1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + for (int i = 0; i < lightCount; ++i) + { + float4 worldPos = mul(ubo.model, float4(input.Pos.xyz, 1.0)); + output.LightVec[i].xyz = pushConsts.lightPos[i].xyz - input.Pos.xyz; + // Store light radius in w + output.LightVec[i].w = pushConsts.lightPos[i].w; + } + return output; +} \ No newline at end of file diff --git a/data/hlsl/pushdescriptors/cube.frag b/data/hlsl/pushdescriptors/cube.frag new file mode 100644 index 00000000..69ede0b8 --- /dev/null +++ b/data/hlsl/pushdescriptors/cube.frag @@ -0,0 +1,16 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t2); +SamplerState samplerColorMap : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/pushdescriptors/cube.vert b/data/hlsl/pushdescriptors/cube.vert new file mode 100644 index 00000000..9a8366a0 --- /dev/null +++ b/data/hlsl/pushdescriptors/cube.vert @@ -0,0 +1,38 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBOScene { + float4x4 projection; + float4x4 view; +}; +cbuffer uboCamera : register(b0) { UBOScene uboCamera; }; + +struct UBOModel { + float4x4 local; +}; +cbuffer uboModel : register(b1) { UBOModel uboModel; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(uboCamera.projection, mul(uboCamera.view, mul(uboModel.local, float4(input.Pos.xyz, 1.0)))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/radialblur/colorpass.frag b/data/hlsl/radialblur/colorpass.frag new file mode 100644 index 00000000..08577814 --- /dev/null +++ b/data/hlsl/radialblur/colorpass.frag @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +Texture2D textureGradientRamp : register(t1); +SamplerState samplerGradientRamp : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // Use max. color channel value to detect bright glow emitters + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + return float4(textureGradientRamp.Sample(samplerGradientRamp, input.UV).rgb, 1); + } + else + { + return float4(input.Color, 1); + } +} \ No newline at end of file diff --git a/data/hlsl/radialblur/colorpass.vert b/data/hlsl/radialblur/colorpass.vert new file mode 100644 index 00000000..a82eedea --- /dev/null +++ b/data/hlsl/radialblur/colorpass.vert @@ -0,0 +1,32 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float gradientPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = float2(ubo.gradientPos, 0.0f); + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} diff --git a/data/hlsl/radialblur/phongpass.frag b/data/hlsl/radialblur/phongpass.frag new file mode 100644 index 00000000..1360ff30 --- /dev/null +++ b/data/hlsl/radialblur/phongpass.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +Texture2D textureGradientRamp : register(t1); +SamplerState samplerGradientRamp : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float2 UV : TEXCOORD0; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + // No light calculations for glow color + // Use max. color channel value + // to detect bright glow emitters + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + return float4(textureGradientRamp.Sample(samplerGradientRamp, input.UV).rgb, 1); + } + else + { + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(0.2, 0.2, 0.2, 1.0); + float4 IDiffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float specular = 0.25; + float4 ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 4.0) * specular; + return float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); + } +} \ No newline at end of file diff --git a/data/hlsl/radialblur/phongpass.vert b/data/hlsl/radialblur/phongpass.vert new file mode 100644 index 00000000..22b8974b --- /dev/null +++ b/data/hlsl/radialblur/phongpass.vert @@ -0,0 +1,40 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float gradientPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = float2(ubo.gradientPos, 0.0); + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + output.EyePos = mul(ubo.model, input.Pos).xyz; + float4 lightPos = float4(0.0, 0.0, -5.0, 1.0);// * ubo.model; + output.LightVec = normalize(lightPos.xyz - input.Pos.xyz); + return output; +} diff --git a/data/hlsl/radialblur/radialblur.frag b/data/hlsl/radialblur/radialblur.frag new file mode 100644 index 00000000..3e41875e --- /dev/null +++ b/data/hlsl/radialblur/radialblur.frag @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct UBO +{ + float radialBlurScale; + float radialBlurStrength; + float2 radialOrigin; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + int2 texDim; + textureColor.GetDimensions(texDim.x, texDim.y); + float2 radialSize = float2(1.0 / texDim.x, 1.0 / texDim.y); + + float2 UV = inUV; + + float4 color = float4(0.0, 0.0, 0.0, 0.0); + UV += radialSize * 0.5 - ubo.radialOrigin; + + #define samples 32 + + for (int i = 0; i < samples; i++) + { + float scale = 1.0 - ubo.radialBlurScale * (float(i) / float(samples-1)); + color += textureColor.Sample(samplerColor, UV * scale + ubo.radialOrigin); + } + + return (color / samples) * ubo.radialBlurStrength; +} \ No newline at end of file diff --git a/data/hlsl/radialblur/radialblur.vert b/data/hlsl/radialblur/radialblur.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/radialblur/radialblur.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/renderheadless/triangle.frag b/data/hlsl/renderheadless/triangle.frag new file mode 100644 index 00000000..8a7faf06 --- /dev/null +++ b/data/hlsl/renderheadless/triangle.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/renderheadless/triangle.vert b/data/hlsl/renderheadless/triangle.vert new file mode 100644 index 00000000..6e5c2207 --- /dev/null +++ b/data/hlsl/renderheadless/triangle.vert @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +struct PushConsts { + float4x4 mvp; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(pushConsts.mvp, float4(input.Pos.xyz, 1.0)); + return output; +} diff --git a/data/hlsl/scenerendering/scene.frag b/data/hlsl/scenerendering/scene.frag new file mode 100644 index 00000000..5cf6f627 --- /dev/null +++ b/data/hlsl/scenerendering/scene.frag @@ -0,0 +1,34 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t0, space1); +SamplerState samplerColorMap : register(s0, space1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +struct Material +{ + float4 ambient; + float4 diffuse; + float4 specular; + float opacity; +}; +[[vk::push_constant]] Material material; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * material.diffuse.rgb; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * material.specular.rgb; + return float4((material.ambient.rgb + diffuse) * color.rgb + specular, 1.0-material.opacity); +} \ No newline at end of file diff --git a/data/hlsl/scenerendering/scene.vert b/data/hlsl/scenerendering/scene.vert new file mode 100644 index 00000000..7fa6d216 --- /dev/null +++ b/data/hlsl/scenerendering/scene.vert @@ -0,0 +1,47 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + + float4x4 modelView = mul(ubo.view, ubo.model); + + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(modelView, float4(input.Pos, 0.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.ViewVec = -mul(ubo.model, float4(input.Pos, 1.0)).xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/screenshot/mesh.frag b/data/hlsl/screenshot/mesh.frag new file mode 100644 index 00000000..2c14be89 --- /dev/null +++ b/data/hlsl/screenshot/mesh.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/screenshot/mesh.vert b/data/hlsl/screenshot/mesh.vert new file mode 100644 index 00000000..38f9bc79 --- /dev/null +++ b/data/hlsl/screenshot/mesh.vert @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + + float4 pos = mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + output.Normal = mul((float3x3)ubo.model, input.Normal); + + float3 lightPos = float3(1.0f, -1.0f, 1.0f); + output.LightVec = lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} diff --git a/data/hlsl/shadowmapomni/cubemapdisplay.frag b/data/hlsl/shadowmapomni/cubemapdisplay.frag new file mode 100644 index 00000000..8b964fa3 --- /dev/null +++ b/data/hlsl/shadowmapomni/cubemapdisplay.frag @@ -0,0 +1,53 @@ +// Copyright 2020 Google LLC + +TextureCube shadowCubeMapTexture : register(t1); +SamplerState shadowCubeMapSampler : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float4 outFragColor = float4(0, 0, 0, 0); + outFragColor.rgb = float3(0.0, 0.0, 0.2); + + float3 samplePos = float3(0, 0, 0); + + // Crude statement to visualize different cube map faces based on UV coordinates + int x = int(floor(inUV.x / 0.25f)); + int y = int(floor(inUV.y / (1.0 / 3.0))); + if (y == 1) { + float2 uv = float2(inUV.x * 4.0f, (inUV.y - 1.0/3.0) * 3.0); + uv = 2.0 * float2(uv.x - float(x) * 1.0, uv.y) - 1.0; + switch (x) { + case 0: // NEGATIVE_X + samplePos = float3(-1.0f, uv.y, uv.x); + break; + case 1: // POSITIVE_Z + samplePos = float3(uv.x, uv.y, 1.0f); + break; + case 2: // POSITIVE_X + samplePos = float3(1.0, uv.y, -uv.x); + break; + case 3: // NEGATIVE_Z + samplePos = float3(-uv.x, uv.y, -1.0f); + break; + } + } else { + if (x == 1) { + float2 uv = float2((inUV.x - 0.25) * 4.0, (inUV.y - float(y) / 3.0) * 3.0); + uv = 2.0 * uv - 1.0; + switch (y) { + case 0: // NEGATIVE_Y + samplePos = float3(uv.x, -1.0f, uv.y); + break; + case 2: // POSITIVE_Y + samplePos = float3(uv.x, 1.0f, -uv.y); + break; + } + } + } + + if ((samplePos.x != 0.0f) && (samplePos.y != 0.0f)) { + float dist = length(shadowCubeMapTexture.Sample(shadowCubeMapSampler, samplePos).xyz) * 0.005; + outFragColor = float4(dist.xxx, 1.0); + } + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/shadowmapomni/cubemapdisplay.vert b/data/hlsl/shadowmapomni/cubemapdisplay.vert new file mode 100644 index 00000000..41068e73 --- /dev/null +++ b/data/hlsl/shadowmapomni/cubemapdisplay.vert @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV.xy * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + diff --git a/data/hlsl/shadowmapomni/offscreen.frag b/data/hlsl/shadowmapomni/offscreen.frag new file mode 100644 index 00000000..82c9fa9b --- /dev/null +++ b/data/hlsl/shadowmapomni/offscreen.frag @@ -0,0 +1,14 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 LightPos : POSITION1; +}; + +float main(VSOutput input) : SV_TARGET +{ + // Store distance to light as 32 bit float value + float3 lightVec = input.Pos.xyz - input.LightPos; + return length(lightVec); +} \ No newline at end of file diff --git a/data/hlsl/shadowmapomni/offscreen.vert b/data/hlsl/shadowmapomni/offscreen.vert new file mode 100644 index 00000000..3c504104 --- /dev/null +++ b/data/hlsl/shadowmapomni/offscreen.vert @@ -0,0 +1,34 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float4 WorldPos : POSITION0; +[[vk::location(1)]] float3 LightPos : POSITION1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct PushConsts +{ + float4x4 view; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main([[vk::location(0)]] float3 Pos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(pushConsts.view, mul(ubo.model, float4(Pos, 1.0)))); + + output.WorldPos = float4(Pos, 1.0); + output.LightPos = ubo.lightPos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/shadowmapomni/scene.frag b/data/hlsl/shadowmapomni/scene.frag new file mode 100644 index 00000000..840d8298 --- /dev/null +++ b/data/hlsl/shadowmapomni/scene.frag @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +TextureCube shadowCubeMapTexture : register(t1); +SamplerState shadowCubeMapSampler : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float3 WorldPos : POSITION1; +[[vk::location(5)]] float3 LightPos : POSITION2; +}; + +#define EPSILON 0.15 +#define SHADOW_OPACITY 0.5 + +float4 main(VSOutput input) : SV_TARGET +{ + // Lighting + float3 N = normalize(input.Normal); + float3 L = normalize(float3(1.0, 1.0, 1.0)); + + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(float3(0.05, 0.05, 0.05), 1.0); + float4 IDiffuse = float4(1.0, 1.0, 1.0, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + + float4 outFragColor = float4(IAmbient + IDiffuse * float4(input.Color, 1.0)); + + // Shadow + float3 lightVec = input.WorldPos - input.LightPos; + float sampledDist = shadowCubeMapTexture.Sample(shadowCubeMapSampler, lightVec).r; + float dist = length(lightVec); + + // Check if fragment is in shadow + float shadow = (dist <= sampledDist + EPSILON) ? 1.0 : SHADOW_OPACITY; + + outFragColor.rgb *= shadow; + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/shadowmapomni/scene.vert b/data/hlsl/shadowmapomni/scene.vert new file mode 100644 index 00000000..f6887c5f --- /dev/null +++ b/data/hlsl/shadowmapomni/scene.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 EyePos : POSITION0; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float3 WorldPos : POSITION1; +[[vk::location(5)]] float3 LightPos : POSITION2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = input.Normal; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + output.EyePos = mul(ubo.model, float4(input.Pos, 1.0f)).xyz; + output.LightVec = normalize(ubo.lightPos.xyz - input.Pos.xyz); + output.WorldPos = input.Pos; + + output.LightPos = ubo.lightPos.xyz; + return output; +} + diff --git a/data/hlsl/shadowmapping/offscreen.frag b/data/hlsl/shadowmapping/offscreen.frag new file mode 100644 index 00000000..54d4ac24 --- /dev/null +++ b/data/hlsl/shadowmapping/offscreen.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main() : SV_TARGET +{ + return float4(1.0, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/shadowmapping/offscreen.vert b/data/hlsl/shadowmapping/offscreen.vert new file mode 100644 index 00000000..b20b1d1f --- /dev/null +++ b/data/hlsl/shadowmapping/offscreen.vert @@ -0,0 +1,13 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 depthMVP; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +float4 main([[vk::location(0)]] float3 Pos : POSITION0) : SV_POSITION +{ + return mul(ubo.depthMVP, float4(Pos, 1.0)); +} \ No newline at end of file diff --git a/data/hlsl/shadowmapping/quad.frag b/data/hlsl/shadowmapping/quad.frag new file mode 100644 index 00000000..fb90f429 --- /dev/null +++ b/data/hlsl/shadowmapping/quad.frag @@ -0,0 +1,18 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +float LinearizeDepth(float depth) +{ + float n = 1.0; // camera z near + float f = 128.0; // camera z far + float z = depth; + return (2.0 * n) / (f + n - z * (f - n)); +} + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float depth = textureColor.Sample(samplerColor, inUV).r; + return float4((1.0-LinearizeDepth(depth)).xxx, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/shadowmapping/quad.vert b/data/hlsl/shadowmapping/quad.vert new file mode 100644 index 00000000..75b0658c --- /dev/null +++ b/data/hlsl/shadowmapping/quad.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/shadowmapping/scene.frag b/data/hlsl/shadowmapping/scene.frag new file mode 100644 index 00000000..5ae6167d --- /dev/null +++ b/data/hlsl/shadowmapping/scene.frag @@ -0,0 +1,68 @@ +// Copyright 2020 Google LLC + +Texture2D shadowMapTexture : register(t1); +SamplerState shadowMapSampler : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float4 ShadowCoord : TEXCOORD3; +}; + +[[vk::constant_id(0)]] const int enablePCF = 0; + +#define ambient 0.1 + +float textureProj(float4 shadowCoord, float2 off) +{ + float shadow = 1.0; + if ( shadowCoord.z > -1.0 && shadowCoord.z < 1.0 ) + { + float dist = shadowMapTexture.Sample( shadowMapSampler, shadowCoord.xy + off ).r; + if ( shadowCoord.w > 0.0 && dist < shadowCoord.z ) + { + shadow = ambient; + } + } + return shadow; +} + +float filterPCF(float4 sc) +{ + int2 texDim; + shadowMapTexture.GetDimensions(texDim.x, texDim.y); + float scale = 1.5; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + shadowFactor += textureProj(sc, float2(dx*x, dy*y)); + count++; + } + + } + return shadowFactor / count; +} + +float4 main(VSOutput input) : SV_TARGET +{ + float shadow = (enablePCF == 1) ? filterPCF(input.ShadowCoord / input.ShadowCoord.w) : textureProj(input.ShadowCoord / input.ShadowCoord.w, float2(0.0, 0.0)); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = normalize(-reflect(L, N)); + float3 diffuse = max(dot(N, L), ambient) * input.Color; + + return float4(diffuse * shadow, 1.0); +} diff --git a/data/hlsl/shadowmapping/scene.vert b/data/hlsl/shadowmapping/scene.vert new file mode 100644 index 00000000..583b6a8e --- /dev/null +++ b/data/hlsl/shadowmapping/scene.vert @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4x4 lightSpace; + float3 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float4 ShadowCoord : TEXCOORD3; +}; + +static const float4x4 biasMat = float4x4( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = input.Normal; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.LightVec = normalize(ubo.lightPos - input.Pos); + output.ViewVec = -pos.xyz; + + output.ShadowCoord = mul(biasMat, mul(ubo.lightSpace, mul(ubo.model, float4(input.Pos, 1.0)))); + return output; +} + diff --git a/data/hlsl/shadowmappingcascade/debugshadowmap.frag b/data/hlsl/shadowmappingcascade/debugshadowmap.frag new file mode 100644 index 00000000..32871804 --- /dev/null +++ b/data/hlsl/shadowmappingcascade/debugshadowmap.frag @@ -0,0 +1,16 @@ +// Copyright 2020 Google LLC + +Texture2DArray shadowMapTexture : register(t1); +SamplerState shadowMapSampler : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] uint CascadeIndex : TEXCOORD1; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float depth = shadowMapTexture.Sample(shadowMapSampler, float3(input.UV, float(input.CascadeIndex))).r; + return float4(depth.xxx, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/shadowmappingcascade/debugshadowmap.vert b/data/hlsl/shadowmappingcascade/debugshadowmap.vert new file mode 100644 index 00000000..6e8ae835 --- /dev/null +++ b/data/hlsl/shadowmappingcascade/debugshadowmap.vert @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +struct PushConsts { + float4 position; + uint cascadeIndex; +}; +[[vk::push_constant]] PushConsts pushConsts; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] uint CascadeIndex : TEXCOORD1; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.CascadeIndex = pushConsts.cascadeIndex; + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/shadowmappingcascade/depthpass.frag b/data/hlsl/shadowmappingcascade/depthpass.frag new file mode 100644 index 00000000..43939200 --- /dev/null +++ b/data/hlsl/shadowmappingcascade/depthpass.frag @@ -0,0 +1,12 @@ +// Copyright 2020 Google LLC + +Texture2D colorMapTexture : register(t0, space1); +SamplerState colorMapSampler : register(s0, space1); + +void main([[vk::location(0)]] float2 inUV : TEXCOORD0) +{ + float alpha = colorMapTexture.Sample(colorMapSampler, inUV).a; + if (alpha < 0.5) { + clip(-1); + } +} \ No newline at end of file diff --git a/data/hlsl/shadowmappingcascade/depthpass.vert b/data/hlsl/shadowmappingcascade/depthpass.vert new file mode 100644 index 00000000..78e70e5b --- /dev/null +++ b/data/hlsl/shadowmappingcascade/depthpass.vert @@ -0,0 +1,36 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; +// todo: pass via specialization constant +#define SHADOW_MAP_CASCADE_COUNT 4 + +struct PushConsts { + float4 position; + uint cascadeIndex; +}; +[[vk::push_constant]] PushConsts pushConsts; + +struct UBO { + float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + float3 pos = input.Pos + pushConsts.position.xyz; + output.Pos = mul(ubo.cascadeViewProjMat[pushConsts.cascadeIndex], float4(pos, 1.0)); + return output; +} \ No newline at end of file diff --git a/data/hlsl/shadowmappingcascade/scene.frag b/data/hlsl/shadowmappingcascade/scene.frag new file mode 100644 index 00000000..6a7388f4 --- /dev/null +++ b/data/hlsl/shadowmappingcascade/scene.frag @@ -0,0 +1,131 @@ +// Copyright 2020 Google LLC + +#define SHADOW_MAP_CASCADE_COUNT 4 + +Texture2DArray shadowMapTexture : register(t1); +SamplerState shadowMapSampler : register(s1); +Texture2D colorMapTexture : register(t0, space1); +SamplerState colorMapSampler : register(s0, space1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewPos : POSITION1; +[[vk::location(3)]] float3 Pos : POSITION0; +[[vk::location(4)]] float2 UV : TEXCOORD0; +}; + +[[vk::constant_id(0)]] const int enablePCF = 0; + +#define ambient 0.3 + +struct UBO { + float4 cascadeSplits; + float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT]; + float4x4 inverseViewMat; + float3 lightDir; + float _pad; + int colorCascades; +}; +cbuffer ubo : register(b2) { UBO ubo; }; + +static const float4x4 biasMat = float4x4( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +); + +float textureProj(float4 shadowCoord, float2 offset, uint cascadeIndex) +{ + float shadow = 1.0; + float bias = 0.005; + + if ( shadowCoord.z > -1.0 && shadowCoord.z < 1.0 ) { + float dist = shadowMapTexture.Sample(shadowMapSampler, float3(shadowCoord.xy + offset, cascadeIndex)).r; + if (shadowCoord.w > 0 && dist < shadowCoord.z - bias) { + shadow = ambient; + } + } + return shadow; + +} + +float filterPCF(float4 sc, uint cascadeIndex) +{ + int3 texDim; + shadowMapTexture.GetDimensions(texDim.x, texDim.y, texDim.z); + float scale = 0.75; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) { + for (int y = -range; y <= range; y++) { + shadowFactor += textureProj(sc, float2(dx*x, dy*y), cascadeIndex); + count++; + } + } + return shadowFactor / count; +} + +float4 main(VSOutput input) : SV_TARGET +{ + float4 outFragColor; + float4 color = colorMapTexture.Sample(colorMapSampler, input.UV); + if (color.a < 0.5) { + clip(-1); + } + + // Get cascade index for the current fragment's view position + uint cascadeIndex = 0; + for(uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) { + if(input.ViewPos.z < ubo.cascadeSplits[i]) { + cascadeIndex = i + 1; + } + } + + // Depth compare for shadowing + float4 shadowCoord = mul(biasMat, mul(ubo.cascadeViewProjMat[cascadeIndex], float4(input.Pos, 1.0))); + + float shadow = 0; + if (enablePCF == 1) { + shadow = filterPCF(shadowCoord / shadowCoord.w, cascadeIndex); + } else { + shadow = textureProj(shadowCoord / shadowCoord.w, float2(0.0, 0.0), cascadeIndex); + } + + // Directional light + float3 N = normalize(input.Normal); + float3 L = normalize(-ubo.lightDir); + float3 H = normalize(L + input.ViewPos); + float diffuse = max(dot(N, L), ambient); + float3 lightColor = float3(1.0, 1.0, 1.0); + outFragColor.rgb = max(lightColor * (diffuse * color.rgb), float3(0.0, 0.0, 0.0)); + outFragColor.rgb *= shadow; + outFragColor.a = color.a; + + // Color cascades (if enabled) + if (ubo.colorCascades == 1) { + switch(cascadeIndex) { + case 0 : + outFragColor.rgb *= float3(1.0f, 0.25f, 0.25f); + break; + case 1 : + outFragColor.rgb *= float3(0.25f, 1.0f, 0.25f); + break; + case 2 : + outFragColor.rgb *= float3(0.25f, 0.25f, 1.0f); + break; + case 3 : + outFragColor.rgb *= float3(1.0f, 1.0f, 0.25f); + break; + } + } + + return outFragColor; +} diff --git a/data/hlsl/shadowmappingcascade/scene.vert b/data/hlsl/shadowmappingcascade/scene.vert new file mode 100644 index 00000000..957845b2 --- /dev/null +++ b/data/hlsl/shadowmappingcascade/scene.vert @@ -0,0 +1,47 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO { + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewPos : POSITION1; +[[vk::location(3)]] float3 WorldPos : POSITION0; +[[vk::location(4)]] float2 UV : TEXCOORD0; +}; + +struct PushConsts { + float4 position; + uint cascadeIndex; +}; +[[vk::push_constant]] PushConsts pushConsts; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = input.Normal; + output.UV = input.UV; + float3 pos = input.Pos + pushConsts.position.xyz; + output.WorldPos = pos; + output.ViewPos = mul(ubo.view, float4(pos.xyz, 1.0)).xyz; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(pos.xyz, 1.0)))); + return output; +} + diff --git a/data/hlsl/skeletalanimation/mesh.frag b/data/hlsl/skeletalanimation/mesh.frag new file mode 100644 index 00000000..4f207e51 --- /dev/null +++ b/data/hlsl/skeletalanimation/mesh.frag @@ -0,0 +1,26 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0);// * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.5, 0.5, 0.5); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/skeletalanimation/mesh.vert b/data/hlsl/skeletalanimation/mesh.vert new file mode 100644 index 00000000..eff95d72 --- /dev/null +++ b/data/hlsl/skeletalanimation/mesh.vert @@ -0,0 +1,55 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +[[vk::location(4)]] float4 BoneWeights : TEXCOORD1; +[[vk::location(5)]] int4 BoneIDs : TEXCOORD2; +}; + +#define MAX_BONES 64 + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4x4 bones[MAX_BONES]; + float4 lightPos; + float4 viewPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float4x4 boneTransform = ubo.bones[input.BoneIDs[0]] * input.BoneWeights[0]; + boneTransform += ubo.bones[input.BoneIDs[1]] * input.BoneWeights[1]; + boneTransform += ubo.bones[input.BoneIDs[2]] * input.BoneWeights[2]; + boneTransform += ubo.bones[input.BoneIDs[3]] * input.BoneWeights[3]; + + output.Color = input.Color; + output.UV = input.UV; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, mul(boneTransform, float4(input.Pos.xyz, 1.0))))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)mul(ubo.model, boneTransform), input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/skeletalanimation/texture.frag b/data/hlsl/skeletalanimation/texture.frag new file mode 100644 index 00000000..75af0820 --- /dev/null +++ b/data/hlsl/skeletalanimation/texture.frag @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, input.UV); + + float distSqr = dot(input.LightVec, input.LightVec); + float3 lVec = input.LightVec * rsqrt(distSqr); + + const float attInvRadius = 1.0/5000.0; + float atten = max(clamp(1.0 - attInvRadius * sqrt(distSqr), 0.0, 1.0), 0.0); + + // Fake drop shadow + const float shadowInvRadius = 1.0/2500.0; + float dropshadow = max(clamp(1.0 - shadowInvRadius * sqrt(distSqr), 0.0, 1.0), 0.0); + + float4 outFragColor = float4(color.rgba * (1.0 - dropshadow)); + outFragColor.rgb *= atten; + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/skeletalanimation/texture.vert b/data/hlsl/skeletalanimation/texture.vert new file mode 100644 index 00000000..25656b7d --- /dev/null +++ b/data/hlsl/skeletalanimation/texture.vert @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 lightPos; + float4 viewPos; + float2 uvOffset; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV + ubo.uvOffset; + float4 pos = float4(input.Pos, 1.0); + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, pos))); + + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} diff --git a/data/hlsl/specializationconstants/uber.frag b/data/hlsl/specializationconstants/uber.frag new file mode 100644 index 00000000..57ac65e6 --- /dev/null +++ b/data/hlsl/specializationconstants/uber.frag @@ -0,0 +1,73 @@ +// Copyright 2020 Google LLC + +Texture2D textureColormap : register(t1); +SamplerState samplerColormap : register(s1); +Texture2D textureDiscard : register(t2); +SamplerState samplerDiscard : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +// We use this constant to control the flow of the shader depending on the +// lighting model selected at pipeline creation time +[[vk::constant_id(0)]] const int LIGHTING_MODEL = 0; +// Parameter for the toon shading part of the shader +[[vk::constant_id(1)]] const /*float*/int PARAM_TOON_DESATURATION = 0.0f; + +float4 main(VSOutput input) : SV_TARGET +{ + switch (LIGHTING_MODEL) { + case 0: // Phong + { + float3 ambient = input.Color * float3(0.25, 0.25, 0.25); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.75, 0.75, 0.75); + return float4(ambient + diffuse * 1.75 + specular, 1.0); + } + case 1: // Toon + { + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float intensity = dot(N,L); + float3 color; + if (intensity > 0.98) + color = input.Color * 1.5; + else if (intensity > 0.9) + color = input.Color * 1.0; + else if (intensity > 0.5) + color = input.Color * 0.6; + else if (intensity > 0.25) + color = input.Color * 0.4; + else + color = input.Color * 0.2; + // Desaturate a bit + color = float3(lerp(color, dot(float3(0.2126,0.7152,0.0722), color).xxx, asfloat(PARAM_TOON_DESATURATION))); + return float4(color, 1); + } + case 2: // Textured + { + float4 color = textureColormap.Sample(samplerColormap, input.UV).rrra; + float3 ambient = color.rgb * float3(0.25, 0.25, 0.25) * input.Color; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color.rgb; + float specular = pow(max(dot(R, V), 0.0), 32.0) * color.a; + return float4(ambient + diffuse + specular.xxx, 1.0); + } + } + + return float4(0, 0, 0, 0); +} \ No newline at end of file diff --git a/data/hlsl/specializationconstants/uber.vert b/data/hlsl/specializationconstants/uber.vert new file mode 100644 index 00000000..2ea7b03b --- /dev/null +++ b/data/hlsl/specializationconstants/uber.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/sphericalenvmapping/sem.frag b/data/hlsl/sphericalenvmapping/sem.frag new file mode 100644 index 00000000..7bee1db6 --- /dev/null +++ b/data/hlsl/sphericalenvmapping/sem.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +Texture2DArray matCapTexture : register(t1); +SamplerState matCapSampler : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float3 EyePos : POSITION0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] int TexIndex : TEXCOORD1; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 r = reflect( input.EyePos, input.Normal ); + float3 r2 = float3( r.x, r.y, r.z + 1.0 ); + float m = 2.0 * length( r2 ); + float2 vN = r.xy / m + .5; + return float4( matCapTexture.Sample( matCapSampler, float3(vN, input.TexIndex)).rgb * (clamp(input.Color.r * 2, 0.0, 1.0)), 1.0 ); +} diff --git a/data/hlsl/sphericalenvmapping/sem.vert b/data/hlsl/sphericalenvmapping/sem.vert new file mode 100644 index 00000000..c2f4c10e --- /dev/null +++ b/data/hlsl/sphericalenvmapping/sem.vert @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + int texIndex; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float3 EyePos : POSITION0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] int TexIndex : TEXCOORD1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model); + output.EyePos = normalize( mul(modelView, input.Pos ).xyz ); + output.TexIndex = ubo.texIndex; + output.Normal = normalize( mul((float3x3)ubo.normal, input.Normal) ); + float3 r = reflect( output.EyePos, output.Normal ); + float m = 2.0 * sqrt( pow(r.x, 2.0) + pow(r.y, 2.0) + pow(r.z + 1.0, 2.0)); + output.Pos = mul(ubo.projection, mul(modelView, input.Pos)); + return output; +} diff --git a/data/hlsl/ssao/blur.frag b/data/hlsl/ssao/blur.frag new file mode 100644 index 00000000..e370ddd6 --- /dev/null +++ b/data/hlsl/ssao/blur.frag @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +Texture2D textureSSAO : register(t0); +SamplerState samplerSSAO : register(s0); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + const int blurRange = 2; + int n = 0; + int2 texDim; + textureSSAO.GetDimensions(texDim.x, texDim.y); + float2 texelSize = 1.0 / (float2)texDim; + float result = 0.0; + for (int x = -blurRange; x < blurRange; x++) + { + for (int y = -blurRange; y < blurRange; y++) + { + float2 offset = float2(float(x), float(y)) * texelSize; + result += textureSSAO.Sample(samplerSSAO, inUV + offset).r; + n++; + } + } + return result / (float(n)); +} \ No newline at end of file diff --git a/data/hlsl/ssao/composition.frag b/data/hlsl/ssao/composition.frag new file mode 100644 index 00000000..b89db525 --- /dev/null +++ b/data/hlsl/ssao/composition.frag @@ -0,0 +1,56 @@ +// Copyright 2020 Google LLC + +Texture2D textureposition : register(t0); +SamplerState samplerposition : register(s0); +Texture2D textureNormal : register(t1); +SamplerState samplerNormal : register(s1); +Texture2D textureAlbedo : register(t2); +SamplerState samplerAlbedo : register(s2); +Texture2D textureSSAO : register(t3); +SamplerState samplerSSAO : register(s3); +Texture2D textureSSAOBlur : register(t4); +SamplerState samplerSSAOBlur : register(s4); +struct UBO +{ + float4x4 _dummy; + int ssao; + int ssaoOnly; + int ssaoBlur; +}; +cbuffer uboParams : register(b5) { UBO uboParams; }; + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float3 fragPos = textureposition.Sample(samplerposition, inUV).rgb; + float3 normal = normalize(textureNormal.Sample(samplerNormal, inUV).rgb * 2.0 - 1.0); + float4 albedo = textureAlbedo.Sample(samplerAlbedo, inUV); + + float ssao = (uboParams.ssaoBlur == 1) ? textureSSAOBlur.Sample(samplerSSAOBlur, inUV).r : textureSSAO.Sample(samplerSSAO, inUV).r; + + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 L = normalize(lightPos - fragPos); + float NdotL = max(0.5, dot(normal, L)); + + float4 outFragColor; + if (uboParams.ssaoOnly == 1) + { + outFragColor.rgb = ssao.rrr; + } + else + { + float3 baseColor = albedo.rgb * NdotL; + + if (uboParams.ssao == 1) + { + outFragColor.rgb = ssao.rrr; + + if (uboParams.ssaoOnly != 1) + outFragColor.rgb *= baseColor; + } + else + { + outFragColor.rgb = baseColor; + } + } + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/ssao/fullscreen.vert b/data/hlsl/ssao/fullscreen.vert new file mode 100644 index 00000000..b13c2bf2 --- /dev/null +++ b/data/hlsl/ssao/fullscreen.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/data/hlsl/ssao/gbuffer.frag b/data/hlsl/ssao/gbuffer.frag new file mode 100644 index 00000000..a95ef24f --- /dev/null +++ b/data/hlsl/ssao/gbuffer.frag @@ -0,0 +1,34 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; +static const float NEAR_PLANE = 0.1f; //todo: specialization const +static const float FAR_PLANE = 64.0f; //todo: specialization const + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + output.Position = float4(input.WorldPos, linearDepth(input.Pos.z)); + output.Normal = float4(normalize(input.Normal) * 0.5 + 0.5, 1.0); + output.Albedo = float4(input.Color * 2.0, 1.0); + return output; +} \ No newline at end of file diff --git a/data/hlsl/ssao/gbuffer.vert b/data/hlsl/ssao/gbuffer.vert new file mode 100644 index 00000000..85f7e07d --- /dev/null +++ b/data/hlsl/ssao/gbuffer.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 WorldPos : POSITION0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + + output.UV = input.UV; + + // Vertex position in view space + output.WorldPos = mul(ubo.view, mul(ubo.model, input.Pos)).xyz; + + // Normal in view space + float3x3 normalMatrix = (float3x3)mul(ubo.view, ubo.model); + output.Normal = mul(normalMatrix, input.Normal); + + output.Color = input.Color; + return output; +} diff --git a/data/hlsl/ssao/ssao.frag b/data/hlsl/ssao/ssao.frag new file mode 100644 index 00000000..966b2a87 --- /dev/null +++ b/data/hlsl/ssao/ssao.frag @@ -0,0 +1,73 @@ +// Copyright 2020 Google LLC + +Texture2D texturePositionDepth : register(t0); +SamplerState samplerPositionDepth : register(s0); +Texture2D textureNormal : register(t1); +SamplerState samplerNormal : register(s1); +Texture2D ssaoNoiseTexture : register(t2); +SamplerState ssaoNoiseSampler : register(s2); + +#define SSAO_KERNEL_ARRAY_SIZE 64 +[[vk::constant_id(0)]] const int SSAO_KERNEL_SIZE = 64; +[[vk::constant_id(1)]] const float SSAO_RADIUS = 0.5; + +struct UBOSSAOKernel +{ + float4 samples[SSAO_KERNEL_ARRAY_SIZE]; +}; +cbuffer uboSSAOKernel : register(b3) { UBOSSAOKernel uboSSAOKernel; }; + +struct UBO +{ + float4x4 projection; +}; +cbuffer ubo : register(b4) { UBO ubo; }; + +float main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + // Get G-Buffer values + float3 fragPos = texturePositionDepth.Sample(samplerPositionDepth, inUV).rgb; + float3 normal = normalize(textureNormal.Sample(samplerNormal, inUV).rgb * 2.0 - 1.0); + + // Get a random vector using a noise lookup + int2 texDim; + texturePositionDepth.GetDimensions(texDim.x, texDim.y); + int2 noiseDim; + ssaoNoiseTexture.GetDimensions(noiseDim.x, noiseDim.y); + const float2 noiseUV = float2(float(texDim.x)/float(noiseDim.x), float(texDim.y)/(noiseDim.y)) * inUV; + float3 randomVec = ssaoNoiseTexture.Sample(ssaoNoiseSampler, noiseUV).xyz * 2.0 - 1.0; + + // Create TBN matrix + float3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); + float3 bitangent = cross(tangent, normal); + float3x3 TBN = transpose(float3x3(tangent, bitangent, normal)); + + // Calculate occlusion value + float occlusion = 0.0f; + for(int i = 0; i < SSAO_KERNEL_SIZE; i++) + { + float3 samplePos = mul(TBN, uboSSAOKernel.samples[i].xyz); + samplePos = fragPos + samplePos * SSAO_RADIUS; + + // project + float4 offset = float4(samplePos, 1.0f); + offset = mul(ubo.projection, offset); + offset.xyz /= offset.w; + offset.xyz = offset.xyz * 0.5f + 0.5f; + + float sampleDepth = -texturePositionDepth.Sample(samplerPositionDepth, offset.xy).w; + +#define RANGE_CHECK 1 +#ifdef RANGE_CHECK + // Range check + float rangeCheck = smoothstep(0.0f, 1.0f, SSAO_RADIUS / abs(fragPos.z - sampleDepth)); + occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f) * rangeCheck; +#else + occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f); +#endif + } + occlusion = 1.0 - (occlusion / float(SSAO_KERNEL_SIZE)); + + return occlusion; +} + diff --git a/data/hlsl/stencilbuffer/outline.frag b/data/hlsl/stencilbuffer/outline.frag new file mode 100644 index 00000000..9892e709 --- /dev/null +++ b/data/hlsl/stencilbuffer/outline.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main() : SV_TARGET +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/stencilbuffer/outline.vert b/data/hlsl/stencilbuffer/outline.vert new file mode 100644 index 00000000..7f1f17a7 --- /dev/null +++ b/data/hlsl/stencilbuffer/outline.vert @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; + float outlineWidth; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +float4 main(VSInput input) : SV_POSITION +{ + // Extrude along normal + float4 pos = float4(input.Pos.xyz + input.Normal * ubo.outlineWidth, input.Pos.w); + return mul(ubo.projection, mul(ubo.model, pos)); +} diff --git a/data/hlsl/stencilbuffer/toon.frag b/data/hlsl/stencilbuffer/toon.frag new file mode 100644 index 00000000..990105ff --- /dev/null +++ b/data/hlsl/stencilbuffer/toon.frag @@ -0,0 +1,32 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 color; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float intensity = dot(N,L); + if (intensity > 0.98) + color = input.Color * 1.5; + else if (intensity > 0.9) + color = input.Color * 1.0; + else if (intensity > 0.5) + color = input.Color * 0.6; + else if (intensity > 0.25) + color = input.Color * 0.4; + else + color = input.Color * 0.2; + // Desaturate a bit + color = lerp(color, dot(float3(0.2126,0.7152,0.0722), color).xxx, 0.1); + return float4(color, 1); +} \ No newline at end of file diff --git a/data/hlsl/stencilbuffer/toon.vert b/data/hlsl/stencilbuffer/toon.vert new file mode 100644 index 00000000..7ab4fdfe --- /dev/null +++ b/data/hlsl/stencilbuffer/toon.vert @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = float3(1.0, 0.0, 0.0); + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/subpasses/composition.frag b/data/hlsl/subpasses/composition.frag new file mode 100644 index 00000000..29fd3113 --- /dev/null +++ b/data/hlsl/subpasses/composition.frag @@ -0,0 +1,69 @@ +// Copyright 2020 Google LLC + +[[vk::input_attachment_index(0)]][[vk::binding(0)]] SubpassInput samplerposition; +[[vk::input_attachment_index(1)]][[vk::binding(1)]] SubpassInput samplerNormal; +[[vk::input_attachment_index(2)]][[vk::binding(2)]] SubpassInput samplerAlbedo; + +#define MAX_NUM_LIGHTS 64 +[[vk::constant_id(0)]] const int NUM_LIGHTS = 64; + +struct Light { + float4 position; + float3 color; + float radius; +}; + +struct UBO +{ + float4 viewPos; + Light lights[MAX_NUM_LIGHTS]; +}; + +cbuffer ubo : register(b3) { UBO ubo; } + + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD) : SV_TARGET +{ + // Read G-Buffer values from previous sub pass + float3 fragPos = samplerposition.SubpassLoad().rgb; + float3 normal = samplerNormal.SubpassLoad().rgb; + float4 albedo = samplerAlbedo.SubpassLoad(); + + #define ambient 0.15 + + // Ambient part + float3 fragcolor = albedo.rgb * ambient; + + for(int i = 0; i < NUM_LIGHTS; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + // Light to fragment + L = normalize(L); + + // Attenuation + float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0); + + // Diffuse part + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten; + + // Specular part + // Specular map values are stored in alpha of albedo mrt + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + //float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 32.0) * atten; + + fragcolor += diff;// + spec; + } + + return float4(fragcolor, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/subpasses/composition.vert b/data/hlsl/subpasses/composition.vert new file mode 100644 index 00000000..188b7298 --- /dev/null +++ b/data/hlsl/subpasses/composition.vert @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/hlsl/subpasses/gbuffer.frag b/data/hlsl/subpasses/gbuffer.frag new file mode 100644 index 00000000..2e278903 --- /dev/null +++ b/data/hlsl/subpasses/gbuffer.frag @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 WorldPos : POSITION0; +}; + +struct FSOutput +{ +[[vk::location(0)]] float4 Color : SV_TARGET0; +[[vk::location(1)]] float4 Position : SV_TARGET1; +[[vk::location(2)]] float4 Normal : SV_TARGET2; +[[vk::location(3)]] float4 Albedo : SV_TARGET3; +}; + +[[vk::constant_id(0)]] const float NEAR_PLANE = 0.1f; +[[vk::constant_id(1)]] const float FAR_PLANE = 256.0f; + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} + +FSOutput main(VSOutput input) +{ + FSOutput output = (FSOutput)0; + output.Position = float4(input.WorldPos, 1.0); + + float3 N = normalize(input.Normal); + N.y = -N.y; + output.Normal = float4(N, 1.0); + + output.Albedo.rgb = input.Color; + + // Store linearized depth in alpha component + output.Position.a = linearDepth(input.Pos.z); + + // Write color attachments to avoid undefined behaviour (validation error) + output.Color = float4(0.0, 0.0, 0.0, 0.0); + return output; +} \ No newline at end of file diff --git a/data/hlsl/subpasses/gbuffer.vert b/data/hlsl/subpasses/gbuffer.vert new file mode 100644 index 00000000..d4f7d73e --- /dev/null +++ b/data/hlsl/subpasses/gbuffer.vert @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 WorldPos : POSITION0; +[[vk::location(3)]] float3 Tangent : TEXCOORD1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + + // Vertex position in world space + output.WorldPos = mul(ubo.model, input.Pos).xyz; + // GL to Vulkan coord space + output.WorldPos.y = -output.WorldPos.y; + + // Normal in world space + output.Normal = mul((float3x3)ubo.model, normalize(input.Normal)); + + // Currently just vertex color + output.Color = input.Color; + return output; +} diff --git a/data/hlsl/subpasses/transparent.frag b/data/hlsl/subpasses/transparent.frag new file mode 100644 index 00000000..28b46bc1 --- /dev/null +++ b/data/hlsl/subpasses/transparent.frag @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC + +[[vk::input_attachment_index(0)]][[vk::binding(1)]] SubpassInput samplerPositionDepth; +Texture2D textureTexture : register(t2); +SamplerState samplerTexture : register(s2); + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +[[vk::constant_id(0)]] const float NEAR_PLANE = 0.1f; +[[vk::constant_id(1)]] const float FAR_PLANE = 256.0f; + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} + +float4 main (VSOutput input) : SV_TARGET +{ + // Sample depth from deferred depth buffer and discard if obscured + float depth = samplerPositionDepth.SubpassLoad().a; + if ((depth != 0.0) && (linearDepth(input.Pos.z) > depth)) + { + clip(-1); + }; + + return textureTexture.Sample(samplerTexture, input.UV); +} diff --git a/data/hlsl/subpasses/transparent.vert b/data/hlsl/subpasses/transparent.vert new file mode 100644 index 00000000..4d327410 --- /dev/null +++ b/data/hlsl/subpasses/transparent.vert @@ -0,0 +1,35 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +VSOutput main (VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.UV = input.UV; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/terraintessellation/skysphere.frag b/data/hlsl/terraintessellation/skysphere.frag new file mode 100644 index 00000000..a40c1b13 --- /dev/null +++ b/data/hlsl/terraintessellation/skysphere.frag @@ -0,0 +1,10 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t1); +SamplerState samplerColorMap : register(s1); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOODR0) : SV_TARGET +{ + float4 color = textureColorMap.Sample(samplerColorMap, inUV); + return float4(color.rgb, 1.0); +} diff --git a/data/hlsl/terraintessellation/skysphere.vert b/data/hlsl/terraintessellation/skysphere.vert new file mode 100644 index 00000000..d6f65906 --- /dev/null +++ b/data/hlsl/terraintessellation/skysphere.vert @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 mvp; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.mvp, float4(input.Pos, 1.0)); + output.UV = input.UV; + output.UV.y = 1.0 - output.UV.y; + return output; +} diff --git a/data/hlsl/terraintessellation/terrain.frag b/data/hlsl/terraintessellation/terrain.frag new file mode 100644 index 00000000..ee1a2991 --- /dev/null +++ b/data/hlsl/terraintessellation/terrain.frag @@ -0,0 +1,65 @@ +// Copyright 2020 Google LLC + +Texture2D textureHeight : register(t1); +SamplerState samplerHeight : register(s1); +Texture2DArray textureLayers : register(t2); +SamplerState samplerLayers : register(s2); + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float3 EyePos : POSITION1; +[[vk::location(5)]] float3 WorldPos : POSITION0; +}; + +float3 sampleTerrainLayer(float2 inUV) +{ + // Define some layer ranges for sampling depending on terrain height + float2 layers[6]; + layers[0] = float2(-10.0, 10.0); + layers[1] = float2(5.0, 45.0); + layers[2] = float2(45.0, 80.0); + layers[3] = float2(75.0, 100.0); + layers[4] = float2(95.0, 140.0); + layers[5] = float2(140.0, 190.0); + + float3 color = float3(0.0, 0.0, 0.0); + + // Get height from displacement map + float height = textureHeight.SampleLevel(samplerHeight, inUV, 0.0).r * 255.0; + + for (int i = 0; i < 6; i++) + { + float range = layers[i].y - layers[i].x; + float weight = (range - abs(height - layers[i].y)) / range; + weight = max(0.0, weight); + color += weight * textureLayers.Sample(samplerLayers, float3(inUV * 16.0, i)).rgb; + } + + return color; +} + +float fog(float density, float4 FragCoord) +{ + const float LOG2 = -1.442695; + float dist = FragCoord.z / FragCoord.w * 0.1; + float d = density * dist; + return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0); +} + +float4 main(DSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.5, 0.5, 0.5); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + + float4 color = float4((ambient + diffuse) * sampleTerrainLayer(input.UV), 1.0); + + const float4 fogColor = float4(0.47, 0.5, 0.67, 0.0); + return lerp(color, fogColor, fog(0.25, input.Pos)); +} diff --git a/data/hlsl/terraintessellation/terrain.tesc b/data/hlsl/terraintessellation/terrain.tesc new file mode 100644 index 00000000..595546f5 --- /dev/null +++ b/data/hlsl/terraintessellation/terrain.tesc @@ -0,0 +1,141 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float4 frustumPlanes[6]; + float displacementFactor; + float tessellationFactor; + float2 viewportDim; + float tessellatedEdgeSize; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +Texture2D textureHeight : register(t1); +SamplerState samplerHeight : register(s1); + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct HSOutput +{ +[[vk::location(2)]] float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[4] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +// Calculate the tessellation factor based on screen space +// dimensions of the edge +float screenSpaceTessFactor(float4 p0, float4 p1) +{ + // Calculate edge mid point + float4 midPoint = 0.5 * (p0 + p1); + // Sphere radius as distance between the control points + float radius = distance(p0, p1) / 2.0; + + // View space + float4 v0 = mul(ubo.modelview, midPoint); + + // Project into clip space + float4 clip0 = mul(ubo.projection, (v0 - float4(radius, float3(0.0, 0.0, 0.0)))); + float4 clip1 = mul(ubo.projection, (v0 + float4(radius, float3(0.0, 0.0, 0.0)))); + + // Get normalized device coordinates + clip0 /= clip0.w; + clip1 /= clip1.w; + + // Convert to viewport coordinates + clip0.xy *= ubo.viewportDim; + clip1.xy *= ubo.viewportDim; + + // Return the tessellation factor based on the screen size + // given by the distance of the two edge control points in screen space + // and a reference (min.) tessellation size for the edge set by the application + return clamp(distance(clip0, clip1) / ubo.tessellatedEdgeSize * ubo.tessellationFactor, 1.0, 64.0); +} + +// Checks the current's patch visibility against the frustum using a sphere check +// Sphere radius is given by the patch size +bool frustumCheck(float4 Pos, float2 inUV) +{ + // Fixed radius (increase if patch size is increased in example) + const float radius = 8.0f; + float4 pos = Pos; + pos.y -= textureHeight.SampleLevel(samplerHeight, inUV, 0.0).r * ubo.displacementFactor; + + // Check sphere against frustum planes + for (int i = 0; i < 6; i++) { + if (dot(pos, ubo.frustumPlanes[i]) + radius < 0.0) + { + return false; + } + } + return true; +} + +ConstantsHSOutput ConstantsHS(InputPatch patch) +{ + ConstantsHSOutput output = (ConstantsHSOutput)0; + + if (!frustumCheck(patch[0].Pos, patch[0].UV)) + { + output.TessLevelInner[0] = 0.0; + output.TessLevelInner[1] = 0.0; + output.TessLevelOuter[0] = 0.0; + output.TessLevelOuter[1] = 0.0; + output.TessLevelOuter[2] = 0.0; + output.TessLevelOuter[3] = 0.0; + } + else + { + if (ubo.tessellationFactor > 0.0) + { + output.TessLevelOuter[0] = screenSpaceTessFactor(patch[3].Pos, patch[0].Pos); + output.TessLevelOuter[1] = screenSpaceTessFactor(patch[0].Pos, patch[1].Pos); + output.TessLevelOuter[2] = screenSpaceTessFactor(patch[1].Pos, patch[2].Pos); + output.TessLevelOuter[3] = screenSpaceTessFactor(patch[2].Pos, patch[3].Pos); + output.TessLevelInner[0] = lerp(output.TessLevelOuter[0], output.TessLevelOuter[3], 0.5); + output.TessLevelInner[1] = lerp(output.TessLevelOuter[2], output.TessLevelOuter[1], 0.5); + } + else + { + // Tessellation factor can be set to zero by example + // to demonstrate a simple passthrough + output.TessLevelInner[0] = 1.0; + output.TessLevelInner[1] = 1.0; + output.TessLevelOuter[0] = 1.0; + output.TessLevelOuter[1] = 1.0; + output.TessLevelOuter[2] = 1.0; + output.TessLevelOuter[3] = 1.0; + } + } + + return output; +} + +[domain("quad")] +[partitioning("integer")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(4)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput main(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output = (HSOutput)0; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} diff --git a/data/hlsl/terraintessellation/terrain.tese b/data/hlsl/terraintessellation/terrain.tese new file mode 100644 index 00000000..c9646108 --- /dev/null +++ b/data/hlsl/terraintessellation/terrain.tese @@ -0,0 +1,71 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float4 frustumPlanes[6]; + float displacementFactor; + float tessellationFactor; + float2 viewportDim; + float tessellatedEdgeSize; +}; +cbuffer ubo : register(b0) { UBO ubo; }; + +Texture2D displacementMapTexture : register(t1); +SamplerState displacementMapSampler : register(s1); + +struct HSOutput +{ +[[vk::location(2)]] float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[4] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +[[vk::location(4)]] float3 EyePos : POSITION1; +[[vk::location(5)]] float3 WorldPos : POSITION0; +}; + +[domain("quad")] +DSOutput main(ConstantsHSOutput input, float2 TessCoord : SV_DomainLocation, const OutputPatch patch) +{ + // Interpolate UV coordinates + DSOutput output = (DSOutput)0; + float2 uv1 = lerp(patch[0].UV, patch[1].UV, TessCoord.x); + float2 uv2 = lerp(patch[3].UV, patch[2].UV, TessCoord.x); + output.UV = lerp(uv1, uv2, TessCoord.y); + + float3 n1 = lerp(patch[0].Normal, patch[1].Normal, TessCoord.x); + float3 n2 = lerp(patch[3].Normal, patch[2].Normal, TessCoord.x); + output.Normal = lerp(n1, n2, TessCoord.y); + + // Interpolate positions + float4 pos1 = lerp(patch[0].Pos, patch[1].Pos, TessCoord.x); + float4 pos2 = lerp(patch[3].Pos, patch[2].Pos, TessCoord.x); + float4 pos = lerp(pos1, pos2, TessCoord.y); + // Displace + pos.y -= displacementMapTexture.SampleLevel(displacementMapSampler, output.UV, 0.0).r * ubo.displacementFactor; + // Perspective projection + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + // Calculate vectors for lighting based on tessellated position + output.ViewVec = -pos.xyz; + output.LightVec = normalize(ubo.lightPos.xyz + output.ViewVec); + output.WorldPos = pos.xyz; + output.EyePos = mul(ubo.modelview, pos).xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/terraintessellation/terrain.vert b/data/hlsl/terraintessellation/terrain.vert new file mode 100644 index 00000000..06898dfe --- /dev/null +++ b/data/hlsl/terraintessellation/terrain.vert @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos.xyz, 1.0); + output.UV = input.UV; + output.Normal = input.Normal; + return output; +} \ No newline at end of file diff --git a/data/hlsl/tessellation/base.frag b/data/hlsl/tessellation/base.frag new file mode 100644 index 00000000..0a34282b --- /dev/null +++ b/data/hlsl/tessellation/base.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +Texture2D textureColorMap : register(t2); +SamplerState samplerColorMap : register(s2); + +struct DSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +float4 main(DSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(float3(0.0, -4.0, 4.0)); + + float4 color = textureColorMap.Sample(samplerColorMap, input.UV); + + return float4(clamp(max(dot(N,L), 0.0), 0.2, 1.0) * color.rgb * 1.5, 1); +} diff --git a/data/hlsl/tessellation/base.vert b/data/hlsl/tessellation/base.vert new file mode 100644 index 00000000..3fcb8aec --- /dev/null +++ b/data/hlsl/tessellation/base.vert @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos.xyz, 1.0); + output.Normal = input.Normal; + output.UV = input.UV; + return output; +} \ No newline at end of file diff --git a/data/hlsl/tessellation/passthrough.tesc b/data/hlsl/tessellation/passthrough.tesc new file mode 100644 index 00000000..738b2229 --- /dev/null +++ b/data/hlsl/tessellation/passthrough.tesc @@ -0,0 +1,46 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +ConstantsHSOutput ConstantsHS(InputPatch patch, uint InvocationID : SV_PrimitiveID) +{ + ConstantsHSOutput output = (ConstantsHSOutput)0; + output.TessLevelInner = 1; + output.TessLevelOuter[0] = 1; + output.TessLevelOuter[1] = 1; + output.TessLevelOuter[2] = 1; + return output; +} + +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput main(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output = (HSOutput)0; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} \ No newline at end of file diff --git a/data/hlsl/tessellation/passthrough.tese b/data/hlsl/tessellation/passthrough.tese new file mode 100644 index 00000000..535a55ad --- /dev/null +++ b/data/hlsl/tessellation/passthrough.tese @@ -0,0 +1,44 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; + float tessAlpha; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +[domain("tri")] +DSOutput main(ConstantsHSOutput input, float3 TessCoord : SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output = (DSOutput)0; + output.Pos = (TessCoord.x * patch[0].Pos) + + (TessCoord.y * patch[1].Pos) + + (TessCoord.z * patch[2].Pos); + output.Pos = mul(ubo.projection, mul(ubo.model, output.Pos)); + + output.Normal = TessCoord.x*patch[0].Normal + TessCoord.y*patch[1].Normal + TessCoord.z*patch[2].Normal; + output.UV = TessCoord.x*patch[0].UV + TessCoord.y*patch[1].UV + TessCoord.z*patch[2].UV; + return output; +} \ No newline at end of file diff --git a/data/hlsl/tessellation/pntriangles.tesc b/data/hlsl/tessellation/pntriangles.tesc new file mode 100644 index 00000000..37f52f0e --- /dev/null +++ b/data/hlsl/tessellation/pntriangles.tesc @@ -0,0 +1,128 @@ +// Copyright 2020 Google LLC + +// PN patch data +struct PnPatch +{ + float b210; + float b120; + float b021; + float b012; + float b102; + float b201; + float b111; + float n110; + float n011; + float n101; +}; + +// tessellation levels +struct UBO +{ + float tessLevel; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float2 UV : TEXCOORD0; +[[vk::location(6)]] float pnPatch[10] : TEXCOORD6; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +void SetPnPatch(out float output[10], PnPatch patch) +{ + output[0] = patch.b210; + output[1] = patch.b120; + output[2] = patch.b021; + output[3] = patch.b012; + output[4] = patch.b102; + output[5] = patch.b201; + output[6] = patch.b111; + output[7] = patch.n110; + output[8] = patch.n011; + output[9] = patch.n101; +} + +float wij(float4 iPos, float3 iNormal, float4 jPos) +{ + return dot(jPos.xyz - iPos.xyz, iNormal); +} + +float vij(float4 iPos, float3 iNormal, float4 jPos, float3 jNormal) +{ + float3 Pj_minus_Pi = jPos.xyz + - iPos.xyz; + float3 Ni_plus_Nj = iNormal+jNormal; + return 2.0*dot(Pj_minus_Pi, Ni_plus_Nj)/dot(Pj_minus_Pi, Pj_minus_Pi); +} + +ConstantsHSOutput ConstantsHS(InputPatch patch, uint InvocationID : SV_PrimitiveID) +{ + ConstantsHSOutput output = (ConstantsHSOutput)0; + output.TessLevelOuter[0] = ubo.tessLevel; + output.TessLevelOuter[1] = ubo.tessLevel; + output.TessLevelOuter[2] = ubo.tessLevel; + output.TessLevelInner = ubo.tessLevel; + return output; +} + +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput main(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output = (HSOutput)0; + // get data + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + + // set base + float P0 = patch[0].Pos[InvocationID]; + float P1 = patch[1].Pos[InvocationID]; + float P2 = patch[2].Pos[InvocationID]; + float N0 = patch[0].Normal[InvocationID]; + float N1 = patch[1].Normal[InvocationID]; + float N2 = patch[2].Normal[InvocationID]; + + // compute control points + PnPatch pnPatch; + pnPatch.b210 = (2.0*P0 + P1 - wij(patch[0].Pos, patch[0].Normal, patch[1].Pos)*N0)/3.0; + pnPatch.b120 = (2.0*P1 + P0 - wij(patch[1].Pos, patch[1].Normal, patch[0].Pos)*N1)/3.0; + pnPatch.b021 = (2.0*P1 + P2 - wij(patch[1].Pos, patch[1].Normal, patch[2].Pos)*N1)/3.0; + pnPatch.b012 = (2.0*P2 + P1 - wij(patch[2].Pos, patch[2].Normal, patch[1].Pos)*N2)/3.0; + pnPatch.b102 = (2.0*P2 + P0 - wij(patch[2].Pos, patch[2].Normal, patch[0].Pos)*N2)/3.0; + pnPatch.b201 = (2.0*P0 + P2 - wij(patch[0].Pos, patch[0].Normal, patch[2].Pos)*N0)/3.0; + float E = ( pnPatch.b210 + + pnPatch.b120 + + pnPatch.b021 + + pnPatch.b012 + + pnPatch.b102 + + pnPatch.b201 ) / 6.0; + float V = (P0 + P1 + P2)/3.0; + pnPatch.b111 = E + (E - V)*0.5; + pnPatch.n110 = N0+N1-vij(patch[0].Pos, patch[0].Normal, patch[1].Pos, patch[1].Normal)*(P1-P0); + pnPatch.n011 = N1+N2-vij(patch[1].Pos, patch[1].Normal, patch[2].Pos, patch[2].Normal)*(P2-P1); + pnPatch.n101 = N2+N0-vij(patch[2].Pos, patch[2].Normal, patch[0].Pos, patch[0].Normal)*(P0-P2); + SetPnPatch(output.pnPatch, pnPatch); + + return output; +} \ No newline at end of file diff --git a/data/hlsl/tessellation/pntriangles.tese b/data/hlsl/tessellation/pntriangles.tese new file mode 100644 index 00000000..2969504d --- /dev/null +++ b/data/hlsl/tessellation/pntriangles.tese @@ -0,0 +1,126 @@ +// Copyright 2020 Google LLC + +// PN patch data +struct PnPatch +{ + float b210; + float b120; + float b021; + float b012; + float b102; + float b201; + float b111; + float n110; + float n011; + float n101; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float tessAlpha; +}; + +cbuffer ubo : register(b1) { UBO ubo; } + +struct HSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float2 UV : TEXCOORD0; +[[vk::location(6)]] float pnPatch[10] : TEXCOORD6; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner : SV_InsideTessFactor; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +#define uvw TessCoord + +PnPatch GetPnPatch(float pnPatch[10]) +{ + PnPatch output; + output.b210 = pnPatch[0]; + output.b120 = pnPatch[1]; + output.b021 = pnPatch[2]; + output.b012 = pnPatch[3]; + output.b102 = pnPatch[4]; + output.b201 = pnPatch[5]; + output.b111 = pnPatch[6]; + output.n110 = pnPatch[7]; + output.n011 = pnPatch[8]; + output.n101 = pnPatch[9]; + return output; +} + +[domain("tri")] +DSOutput main(ConstantsHSOutput input, float3 TessCoord : SV_DomainLocation, const OutputPatch patch) +{ + PnPatch pnPatch[3]; + pnPatch[0] = GetPnPatch(patch[0].pnPatch); + pnPatch[1] = GetPnPatch(patch[1].pnPatch); + pnPatch[2] = GetPnPatch(patch[2].pnPatch); + + DSOutput output = (DSOutput)0; + float3 uvwSquared = uvw * uvw; + float3 uvwCubed = uvwSquared * uvw; + + // extract control points + float3 b210 = float3(pnPatch[0].b210, pnPatch[1].b210, pnPatch[2].b210); + float3 b120 = float3(pnPatch[0].b120, pnPatch[1].b120, pnPatch[2].b120); + float3 b021 = float3(pnPatch[0].b021, pnPatch[1].b021, pnPatch[2].b021); + float3 b012 = float3(pnPatch[0].b012, pnPatch[1].b012, pnPatch[2].b012); + float3 b102 = float3(pnPatch[0].b102, pnPatch[1].b102, pnPatch[2].b102); + float3 b201 = float3(pnPatch[0].b201, pnPatch[1].b201, pnPatch[2].b201); + float3 b111 = float3(pnPatch[0].b111, pnPatch[1].b111, pnPatch[2].b111); + + // extract control normals + float3 n110 = normalize(float3(pnPatch[0].n110, pnPatch[1].n110, pnPatch[2].n110)); + float3 n011 = normalize(float3(pnPatch[0].n011, pnPatch[1].n011, pnPatch[2].n011)); + float3 n101 = normalize(float3(pnPatch[0].n101, pnPatch[1].n101, pnPatch[2].n101)); + + // compute texcoords + output.UV = TessCoord[2]*patch[0].UV + TessCoord[0]*patch[1].UV + TessCoord[1]*patch[2].UV; + + // normal + // Barycentric normal + float3 barNormal = TessCoord[2]*patch[0].Normal + TessCoord[0]*patch[1].Normal + TessCoord[1]*patch[2].Normal; + float3 pnNormal = patch[0].Normal*uvwSquared[2] + patch[1].Normal*uvwSquared[0] + patch[2].Normal*uvwSquared[1] + + n110*uvw[2]*uvw[0] + n011*uvw[0]*uvw[1]+ n101*uvw[2]*uvw[1]; + output.Normal = ubo.tessAlpha*pnNormal + (1.0-ubo.tessAlpha) * barNormal; + + // compute interpolated pos + float3 barPos = TessCoord[2]*patch[0].Pos.xyz + + TessCoord[0]*patch[1].Pos.xyz + + TessCoord[1]*patch[2].Pos.xyz; + + // save some computations + uvwSquared *= 3.0; + + // compute PN position + float3 pnPos = patch[0].Pos.xyz*uvwCubed[2] + + patch[1].Pos.xyz*uvwCubed[0] + + patch[2].Pos.xyz*uvwCubed[1] + + b210*uvwSquared[2]*uvw[0] + + b120*uvwSquared[0]*uvw[2] + + b201*uvwSquared[2]*uvw[1] + + b021*uvwSquared[0]*uvw[1] + + b102*uvwSquared[1]*uvw[2] + + b012*uvwSquared[1]*uvw[0] + + b111*6.0*uvw[0]*uvw[1]*uvw[2]; + + // final position and normal + float3 finalPos = (1.0-ubo.tessAlpha)*barPos + ubo.tessAlpha*pnPos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(finalPos,1.0))); + return output; +} \ No newline at end of file diff --git a/data/hlsl/textoverlay/mesh.frag b/data/hlsl/textoverlay/mesh.frag new file mode 100644 index 00000000..f2eb9b6f --- /dev/null +++ b/data/hlsl/textoverlay/mesh.frag @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float diffuse = max(dot(N, L), 0.0); + float specular = pow(max(dot(R, V), 0.0), 1.0); + return float4(((diffuse + specular) * 0.25).xxx, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/textoverlay/mesh.vert b/data/hlsl/textoverlay/mesh.vert new file mode 100644 index 00000000..2abf875a --- /dev/null +++ b/data/hlsl/textoverlay/mesh.vert @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Normal = input.Normal; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, normalize(input.Normal)); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} \ No newline at end of file diff --git a/data/hlsl/textoverlay/text.frag b/data/hlsl/textoverlay/text.frag new file mode 100644 index 00000000..7525bd19 --- /dev/null +++ b/data/hlsl/textoverlay/text.frag @@ -0,0 +1,10 @@ +// Copyright 2020 Google LLC + +Texture2D textureFont : register(t0); +SamplerState samplerFont : register(s0); + +float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET +{ + float color = textureFont.Sample(samplerFont, inUV).r; + return color.xxxx; +} diff --git a/data/hlsl/textoverlay/text.vert b/data/hlsl/textoverlay/text.vert new file mode 100644 index 00000000..5de88481 --- /dev/null +++ b/data/hlsl/textoverlay/text.vert @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float2 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = float4(input.Pos, 0.0, 1.0); + output.UV = input.UV; + return output; +} diff --git a/data/hlsl/texture/texture.frag b/data/hlsl/texture/texture.frag new file mode 100644 index 00000000..78ce0f93 --- /dev/null +++ b/data/hlsl/texture/texture.frag @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColor.SampleLevel(samplerColor, input.UV, input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/texture/texture.vert b/data/hlsl/texture/texture.vert new file mode 100644 index 00000000..133d53b1 --- /dev/null +++ b/data/hlsl/texture/texture.vert @@ -0,0 +1,47 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float lodBias; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.LodBias = ubo.lodBias; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 lPos = mul((float3x3)ubo.model, lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} diff --git a/data/hlsl/texture3d/texture3d.frag b/data/hlsl/texture3d/texture3d.frag new file mode 100644 index 00000000..f9375205 --- /dev/null +++ b/data/hlsl/texture3d/texture3d.frag @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC + +Texture3D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColor.Sample(samplerColor, input.UV); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.r; + + return float4(diffuse * color.r + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/texture3d/texture3d.vert b/data/hlsl/texture3d/texture3d.vert new file mode 100644 index 00000000..39c9681c --- /dev/null +++ b/data/hlsl/texture3d/texture3d.vert @@ -0,0 +1,46 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float depth; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = float3(input.UV, ubo.depth); + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 lPos = mul((float3x3)ubo.model, lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} diff --git a/data/hlsl/texturearray/instancing.frag b/data/hlsl/texturearray/instancing.frag new file mode 100644 index 00000000..85ed6eae --- /dev/null +++ b/data/hlsl/texturearray/instancing.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +Texture2DArray textureArray : register(t1); +SamplerState samplerArray : register(s1); + +float4 main([[vk::location(0)]] float3 inUV : TEXCOORD0) : SV_TARGET +{ + return textureArray.Sample(samplerArray, inUV); +} \ No newline at end of file diff --git a/data/hlsl/texturearray/instancing.vert b/data/hlsl/texturearray/instancing.vert new file mode 100644 index 00000000..d9d77d52 --- /dev/null +++ b/data/hlsl/texturearray/instancing.vert @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +}; + +struct Instance +{ + float4x4 model; + float4 arrayIndex; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + Instance instance[8]; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UV : TEXCOORD0; +}; + +VSOutput main(VSInput input, uint InstanceIndex : SV_InstanceID) +{ + VSOutput output = (VSOutput)0; + output.UV = float3(input.UV, ubo.instance[InstanceIndex].arrayIndex.x); + float4x4 modelView = mul(ubo.view, ubo.instance[InstanceIndex].model); + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos, 1.0))); + return output; +} diff --git a/data/hlsl/texturecubemap/reflect.frag b/data/hlsl/texturecubemap/reflect.frag new file mode 100644 index 00000000..0d664402 --- /dev/null +++ b/data/hlsl/texturecubemap/reflect.frag @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC + +TextureCube textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float LodBias : TEXCOORD3; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 cI = normalize (input.ViewVec); + float3 cR = reflect (cI, normalize(input.Normal)); + cR.x *= -1; + + float4 color = textureColor.SampleLevel(samplerColor, cR, input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.5, 0.5, 0.5) * color.rgb; + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.5, 0.5, 0.5); + return float4(ambient + diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/texturecubemap/reflect.vert b/data/hlsl/texturecubemap/reflect.vert new file mode 100644 index 00000000..77bed827 --- /dev/null +++ b/data/hlsl/texturecubemap/reflect.vert @@ -0,0 +1,43 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float3 camPos; + float lodBias; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 WorldPos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float LodBias : TEXCOORD3; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + output.WorldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.Normal = -mul((float3x3)ubo.model, input.Normal); + output.LodBias = ubo.lodBias; + + float3 lightPos = float3(0.0f, -5.0f, 5.0f); + output.LightVec = lightPos.xyz - output.WorldPos.xyz; + output.ViewVec = output.WorldPos - ubo.camPos; + return output; +} diff --git a/data/hlsl/texturecubemap/skybox.frag b/data/hlsl/texturecubemap/skybox.frag new file mode 100644 index 00000000..bd2ba96d --- /dev/null +++ b/data/hlsl/texturecubemap/skybox.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +TextureCube textureCubeMap : register(t1); +SamplerState samplerCubeMap : register(s1); + +float4 main([[vk::location(0)]] float3 inUVW : TEXCOORD0) : SV_TARGET +{ + return textureCubeMap.Sample(samplerCubeMap, inUVW); +} \ No newline at end of file diff --git a/data/hlsl/texturecubemap/skybox.vert b/data/hlsl/texturecubemap/skybox.vert new file mode 100644 index 00000000..9c1e78a9 --- /dev/null +++ b/data/hlsl/texturecubemap/skybox.vert @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main([[vk::location(0)]] float3 Pos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.UVW = Pos; + output.UVW.x *= -1.0; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(Pos.xyz, 1.0)))); + return output; +} diff --git a/data/hlsl/texturemipmapgen/texture.frag b/data/hlsl/texturemipmapgen/texture.frag new file mode 100644 index 00000000..9f58e19d --- /dev/null +++ b/data/hlsl/texturemipmapgen/texture.frag @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplers[3] : register(s2); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] int SamplerIndex : TEXCOORD4; +[[vk::location(3)]] float3 Normal : NORMAL0; +[[vk::location(4)]] float3 ViewVec : TEXCOORD1; +[[vk::location(5)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = textureColor.Sample(samplers[input.SamplerIndex], input.UV, int2(0, 0), input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(L, N); + float3 diffuse = max(dot(N, L), 0.65) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/texturemipmapgen/texture.vert b/data/hlsl/texturemipmapgen/texture.vert new file mode 100644 index 00000000..8b5f3036 --- /dev/null +++ b/data/hlsl/texturemipmapgen/texture.vert @@ -0,0 +1,49 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float2 UV : TEXCOORD0; +[[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 viewPos; + float lodBias; + int samplerIndex; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] int SamplerIndex : TEXCOORD4; +[[vk::location(3)]] float3 Normal : NORMAL0; +[[vk::location(4)]] float3 ViewVec : TEXCOORD1; +[[vk::location(5)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV * float2(2.0, 1.0); + output.LodBias = ubo.lodBias; + output.SamplerIndex = ubo.samplerIndex; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(-30.0, 0.0, 0.0); + output.LightVec = worldPos - lightPos; + output.ViewVec = ubo.viewPos.xyz - worldPos; + return output; +} diff --git a/data/hlsl/texturesparseresidency/sparseresidency.frag b/data/hlsl/texturesparseresidency/sparseresidency.frag new file mode 100644 index 00000000..27458545 --- /dev/null +++ b/data/hlsl/texturesparseresidency/sparseresidency.frag @@ -0,0 +1,36 @@ +// Copyright 2020 Google LLC + +Texture2D textureColor : register(t1); +SamplerState samplerColor : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float4 color = float4(0.0, 0.0, 0.0, 0.0); + + // Fetch sparse until we get a valid texel + uint status; + float minLod = input.LodBias; + do + { + color = textureColor.SampleLevel(samplerColor, input.UV, minLod, 0, status); + minLod += 1.0f; + } while(!CheckAccessFullyMapped(status)); + + float3 N = normalize(input.Normal); + + N = normalize((input.Normal - 0.5) * 2.0); + + float3 L = normalize(input.LightVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.25) * color.rgb; + return float4(diffuse, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/texturesparseresidency/sparseresidency.vert b/data/hlsl/texturesparseresidency/sparseresidency.vert new file mode 100644 index 00000000..b5fb1236 --- /dev/null +++ b/data/hlsl/texturesparseresidency/sparseresidency.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 UV : TEXCOORD0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float lodBias; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float LodBias : TEXCOORD3; +[[vk::location(2)]] float3 Normal : NORMAL0; +[[vk::location(3)]] float3 ViewVec : TEXCOORD1; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.UV; + output.LodBias = ubo.lodBias; + output.Normal = input.Normal; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float3 lightPos = float3(0.0, 50.0f, 0.0f); + output.LightVec = lightPos - input.Pos.xyz; + output.ViewVec = ubo.viewPos.xyz - worldPos.xyz; + return output; +} diff --git a/data/hlsl/triangle/triangle.frag b/data/hlsl/triangle/triangle.frag new file mode 100644 index 00000000..8a7faf06 --- /dev/null +++ b/data/hlsl/triangle/triangle.frag @@ -0,0 +1,6 @@ +// Copyright 2020 Google LLC + +float4 main([[vk::location(0)]] float3 Color : COLOR0) : SV_TARGET +{ + return float4(Color, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/triangle/triangle.vert b/data/hlsl/triangle/triangle.vert new file mode 100644 index 00000000..881674c8 --- /dev/null +++ b/data/hlsl/triangle/triangle.vert @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projectionMatrix; + float4x4 modelMatrix; + float4x4 viewMatrix; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Pos.xyz, 1.0)))); + return output; +} diff --git a/data/hlsl/viewportarray/multiview.geom b/data/hlsl/viewportarray/multiview.geom new file mode 100644 index 00000000..b1e609fd --- /dev/null +++ b/data/hlsl/viewportarray/multiview.geom @@ -0,0 +1,56 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection[2]; + float4x4 modelview[2]; + float4 lightPos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; + uint ViewportIndex : SV_ViewportArrayIndex; + uint PrimitiveID : SV_PrimitiveID; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOOR1; +[[vk::location(3)]] float3 LightVec : TEXCOOR2; +}; + +[maxvertexcount(3)] +[instance(2)] +void main(triangle VSOutput input[3], inout TriangleStream outStream, uint InvocationID : SV_GSInstanceID, uint PrimitiveID : SV_PrimitiveID) +{ + for(int i = 0; i < 3; i++) + { + GSOutput output = (GSOutput)0; + output.Normal = mul((float3x3)ubo.modelview[InvocationID], input[i].Normal); + output.Color = input[i].Color; + + float4 pos = input[i].Pos; + float4 worldPos = mul(ubo.modelview[InvocationID], pos); + + float3 lPos = mul(ubo.modelview[InvocationID], ubo.lightPos).xyz; + output.LightVec = lPos - worldPos.xyz; + output.ViewVec = -worldPos.xyz; + + output.Pos = mul(ubo.projection[InvocationID], worldPos); + + // Set the viewport index that the vertex will be emitted to + output.ViewportIndex = InvocationID; + output.PrimitiveID = PrimitiveID; + outStream.Append( output ); + } + + outStream.RestartStrip(); +} \ No newline at end of file diff --git a/data/hlsl/viewportarray/scene.frag b/data/hlsl/viewportarray/scene.frag new file mode 100644 index 00000000..189e9955 --- /dev/null +++ b/data/hlsl/viewportarray/scene.frag @@ -0,0 +1,21 @@ +// Copyright 2020 Google LLC + +struct GSOutput +{ +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +[[vk::location(2)]] float3 ViewVec : TEXCOORD1; +[[vk::location(3)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(GSOutput input) : SV_TARGET +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/data/hlsl/viewportarray/scene.vert b/data/hlsl/viewportarray/scene.vert new file mode 100644 index 00000000..1aeca832 --- /dev/null +++ b/data/hlsl/viewportarray/scene.vert @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float3 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 Normal : NORMAL0; +[[vk::location(1)]] float3 Color : COLOR0; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = input.Normal; + output.Pos = float4(input.Pos.xyz, 1.0); + return output; +} diff --git a/data/hlsl/vulkanscene/logo.frag b/data/hlsl/vulkanscene/logo.frag new file mode 100644 index 00000000..e4a8c9df --- /dev/null +++ b/data/hlsl/vulkanscene/logo.frag @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 EyePos : POSITION0; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 diff = float4(input.Color, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + float shininess = 0.0; + float4 spec = float4(1.0, 1.0, 1.0, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 2.5) * shininess; + + return float4((diff + spec).rgb, 1); +} \ No newline at end of file diff --git a/data/hlsl/vulkanscene/logo.vert b/data/hlsl/vulkanscene/logo.vert new file mode 100644 index 00000000..dc458eee --- /dev/null +++ b/data/hlsl/vulkanscene/logo.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 TexCoord : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + float3 lightpos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 EyePos : POSITION0; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + float4x4 modelView = mul(ubo.view, ubo.model); + float4 pos = mul(modelView, input.Pos); + output.UV = input.TexCoord.xy; + output.Normal = normalize(mul((float3x3)ubo.normal, input.Normal)); + output.Color = input.Color; + output.Pos = mul(ubo.projection, pos); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(modelView, float4(1.0, 2.0, 0.0, 1.0)); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + return output; +} diff --git a/data/hlsl/vulkanscene/mesh.frag b/data/hlsl/vulkanscene/mesh.frag new file mode 100644 index 00000000..5770537a --- /dev/null +++ b/data/hlsl/vulkanscene/mesh.frag @@ -0,0 +1,48 @@ +// Copyright 2020 Google LLC + +Texture2D tex : register(t1); +SamplerState samp : register(s1); + +struct VSOutput +{ +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 EyePos : POSITION0; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +float specpart(float3 L, float3 N, float3 H) +{ + if (dot(N, L) > 0.0) + { + return pow(clamp(dot(H, N), 0.0, 1.0), 64.0); + } + return 0.0; +} + +float4 main(VSOutput input) : SV_TARGET +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float3 halfVec = normalize(input.LightVec + input.EyePos); + float diff = clamp(dot(input.LightVec, input.Normal), 0.0, 1.0); + float spec = specpart(input.LightVec, input.Normal, halfVec); + float intensity = 0.1 + diff + spec; + + float4 IAmbient = float4(0.2, 0.2, 0.2, 1.0); + float4 IDiffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float shininess = 0.75; + float4 ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 2.0) * shininess; + + float4 outFragColor = float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); + + // Some manual saturation + if (intensity > 0.95) + outFragColor *= 2.25; + if (intensity < 0.15) + outFragColor = float4(0.1, 0.1, 0.1, 0.1); + + return outFragColor; +} \ No newline at end of file diff --git a/data/hlsl/vulkanscene/mesh.vert b/data/hlsl/vulkanscene/mesh.vert new file mode 100644 index 00000000..77490e46 --- /dev/null +++ b/data/hlsl/vulkanscene/mesh.vert @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float2 TexCoord : TEXCOORD0; +[[vk::location(3)]] float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + float3 lightpos; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float2 UV : TEXCOORD0; +[[vk::location(1)]] float3 Normal : NORMAL0; +[[vk::location(2)]] float3 Color : COLOR0; +[[vk::location(3)]] float3 EyePos : POSITION0; +[[vk::location(4)]] float3 LightVec : TEXCOORD2; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.UV = input.TexCoord.xy; + output.Normal = normalize(mul((float3x3)ubo.normal, input.Normal)); + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model); + float4 pos = mul(modelView, input.Pos); + output.Pos = mul(ubo.projection, pos); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(modelView, float4(ubo.lightpos, 1.0)); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + return output; +} diff --git a/data/hlsl/vulkanscene/skybox.frag b/data/hlsl/vulkanscene/skybox.frag new file mode 100644 index 00000000..bd2ba96d --- /dev/null +++ b/data/hlsl/vulkanscene/skybox.frag @@ -0,0 +1,9 @@ +// Copyright 2020 Google LLC + +TextureCube textureCubeMap : register(t1); +SamplerState samplerCubeMap : register(s1); + +float4 main([[vk::location(0)]] float3 inUVW : TEXCOORD0) : SV_TARGET +{ + return textureCubeMap.Sample(samplerCubeMap, inUVW); +} \ No newline at end of file diff --git a/data/hlsl/vulkanscene/skybox.vert b/data/hlsl/vulkanscene/skybox.vert new file mode 100644 index 00000000..ebc7739d --- /dev/null +++ b/data/hlsl/vulkanscene/skybox.vert @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +[[vk::location(0)]] float3 UVW : TEXCOORD0; +}; + +VSOutput main([[vk::location(0)]] float3 Pos : POSITION0) +{ + VSOutput output = (VSOutput)0; + output.UVW = Pos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(Pos.xyz, 1.0))); + return output; +}