shader buffer refactor; vulkan mesh shader fixes; (#713)
This commit is contained in:
@@ -102,7 +102,7 @@ jobs:
|
||||
- name: Package Content
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Additional Content
|
||||
name: Content
|
||||
path: |
|
||||
Content/models
|
||||
Content/scripts
|
||||
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
- name: Package Content
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Additional Content
|
||||
name: Content
|
||||
path: |
|
||||
Content/models
|
||||
Content/scripts
|
||||
|
||||
@@ -103,7 +103,7 @@ jobs:
|
||||
- name: Package Content
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Additional Content
|
||||
name: Content
|
||||
path: |
|
||||
Content/models
|
||||
Content/scripts
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2018 Google Inc.
|
||||
Copyright 2017-2022 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,12 @@ VERSION HISTORY
|
||||
#ifndef SPIRV_REFLECT_H
|
||||
#define SPIRV_REFLECT_H
|
||||
|
||||
#if defined(SPIRV_REFLECT_USE_SYSTEM_SPIRV_H)
|
||||
#include <spirv/unified1/spirv.h>
|
||||
#else
|
||||
#include "./include/spirv/unified1/spirv.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -74,8 +79,28 @@ typedef enum SpvReflectResult {
|
||||
SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE,
|
||||
SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT,
|
||||
SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE,
|
||||
SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED,
|
||||
} SpvReflectResult;
|
||||
|
||||
/*! @enum SpvReflectModuleFlagBits
|
||||
|
||||
SPV_REFLECT_MODULE_FLAG_NO_COPY - Disables copying of SPIR-V code
|
||||
when a SPIRV-Reflect shader module is created. It is the
|
||||
responsibility of the calling program to ensure that the pointer
|
||||
remains valid and the memory it's pointing to is not freed while
|
||||
SPIRV-Reflect operations are taking place. Freeing the backing
|
||||
memory will cause undefined behavior or most likely a crash.
|
||||
This is flag is intended for cases where the memory overhead of
|
||||
storing the copied SPIR-V is undesirable.
|
||||
|
||||
*/
|
||||
typedef enum SpvReflectModuleFlagBits {
|
||||
SPV_REFLECT_MODULE_FLAG_NONE = 0x00000000,
|
||||
SPV_REFLECT_MODULE_FLAG_NO_COPY = 0x00000001,
|
||||
} SpvReflectModuleFlagBits;
|
||||
|
||||
typedef uint32_t SpvReflectModuleFlags;
|
||||
|
||||
/*! @enum SpvReflectTypeFlagBits
|
||||
|
||||
*/
|
||||
@@ -95,12 +120,20 @@ typedef enum SpvReflectTypeFlagBits {
|
||||
SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x00FF0000,
|
||||
SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000,
|
||||
SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000,
|
||||
SPV_REFLECT_TYPE_FLAG_REF = 0x40000000,
|
||||
} SpvReflectTypeFlagBits;
|
||||
|
||||
typedef uint32_t SpvReflectTypeFlags;
|
||||
|
||||
/*! @enum SpvReflectDecorationBits
|
||||
|
||||
NOTE: HLSL row_major and column_major decorations are reversed
|
||||
in SPIR-V. Meaning that matrices declrations with row_major
|
||||
will get reflected as column_major and vice versa. The
|
||||
row and column decorations get appied during the compilation.
|
||||
SPIRV-Reflect reads the data as is and does not make any
|
||||
attempt to correct it to match what's in the source.
|
||||
|
||||
*/
|
||||
typedef enum SpvReflectDecorationFlagBits {
|
||||
SPV_REFLECT_DECORATION_NONE = 0x00000000,
|
||||
@@ -112,6 +145,8 @@ typedef enum SpvReflectDecorationFlagBits {
|
||||
SPV_REFLECT_DECORATION_NOPERSPECTIVE = 0x00000020,
|
||||
SPV_REFLECT_DECORATION_FLAT = 0x00000040,
|
||||
SPV_REFLECT_DECORATION_NON_WRITABLE = 0x00000080,
|
||||
SPV_REFLECT_DECORATION_RELAXED_PRECISION = 0x00000100,
|
||||
SPV_REFLECT_DECORATION_NON_READABLE = 0x00000200,
|
||||
} SpvReflectDecorationFlagBits;
|
||||
|
||||
typedef uint32_t SpvReflectDecorationFlags;
|
||||
@@ -132,6 +167,18 @@ typedef enum SpvReflectResourceType {
|
||||
*/
|
||||
typedef enum SpvReflectFormat {
|
||||
SPV_REFLECT_FORMAT_UNDEFINED = 0, // = VK_FORMAT_UNDEFINED
|
||||
SPV_REFLECT_FORMAT_R16_UINT = 74, // = VK_FORMAT_R16_UINT
|
||||
SPV_REFLECT_FORMAT_R16_SINT = 75, // = VK_FORMAT_R16_SINT
|
||||
SPV_REFLECT_FORMAT_R16_SFLOAT = 76, // = VK_FORMAT_R16_SFLOAT
|
||||
SPV_REFLECT_FORMAT_R16G16_UINT = 81, // = VK_FORMAT_R16G16_UINT
|
||||
SPV_REFLECT_FORMAT_R16G16_SINT = 82, // = VK_FORMAT_R16G16_SINT
|
||||
SPV_REFLECT_FORMAT_R16G16_SFLOAT = 83, // = VK_FORMAT_R16G16_SFLOAT
|
||||
SPV_REFLECT_FORMAT_R16G16B16_UINT = 88, // = VK_FORMAT_R16G16B16_UINT
|
||||
SPV_REFLECT_FORMAT_R16G16B16_SINT = 89, // = VK_FORMAT_R16G16B16_SINT
|
||||
SPV_REFLECT_FORMAT_R16G16B16_SFLOAT = 90, // = VK_FORMAT_R16G16B16_SFLOAT
|
||||
SPV_REFLECT_FORMAT_R16G16B16A16_UINT = 95, // = VK_FORMAT_R16G16B16A16_UINT
|
||||
SPV_REFLECT_FORMAT_R16G16B16A16_SINT = 96, // = VK_FORMAT_R16G16B16A16_SINT
|
||||
SPV_REFLECT_FORMAT_R16G16B16A16_SFLOAT = 97, // = VK_FORMAT_R16G16B16A16_SFLOAT
|
||||
SPV_REFLECT_FORMAT_R32_UINT = 98, // = VK_FORMAT_R32_UINT
|
||||
SPV_REFLECT_FORMAT_R32_SINT = 99, // = VK_FORMAT_R32_SINT
|
||||
SPV_REFLECT_FORMAT_R32_SFLOAT = 100, // = VK_FORMAT_R32_SFLOAT
|
||||
@@ -197,13 +244,15 @@ typedef enum SpvReflectShaderStageFlagBits {
|
||||
SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, // = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT = 0x00000020, // = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV = 0x00000040, // = VK_SHADER_STAGE_TASK_BIT_NV
|
||||
SPV_REFLECT_SHADER_STAGE_TASK_BIT_EXT = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT
|
||||
SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV
|
||||
SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // VK_SHADER_STAGE_RAYGEN_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // VK_SHADER_STAGE_ANY_HIT_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // VK_SHADER_STAGE_MISS_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // VK_SHADER_STAGE_INTERSECTION_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // VK_SHADER_STAGE_CALLABLE_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_MESH_BIT_EXT = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT
|
||||
SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // = VK_SHADER_STAGE_RAYGEN_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // = VK_SHADER_STAGE_ANY_HIT_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // = VK_SHADER_STAGE_MISS_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // = VK_SHADER_STAGE_INTERSECTION_BIT_KHR
|
||||
SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // = VK_SHADER_STAGE_CALLABLE_BIT_KHR
|
||||
|
||||
} SpvReflectShaderStageFlagBits;
|
||||
|
||||
@@ -259,9 +308,20 @@ typedef struct SpvReflectImageTraits {
|
||||
SpvImageFormat image_format;
|
||||
} SpvReflectImageTraits;
|
||||
|
||||
typedef enum SpvReflectArrayDimType {
|
||||
SPV_REFLECT_ARRAY_DIM_RUNTIME = 0, // OpTypeRuntimeArray
|
||||
SPV_REFLECT_ARRAY_DIM_SPEC_CONSTANT = 0xFFFFFFFF // specialization constant
|
||||
} SpvReflectArrayDimType;
|
||||
|
||||
typedef struct SpvReflectArrayTraits {
|
||||
uint32_t dims_count;
|
||||
// Each entry is either:
|
||||
// - specialization constant dimension
|
||||
// - OpTypeRuntimeArray
|
||||
// - the array length otherwise
|
||||
uint32_t dims[SPV_REFLECT_MAX_ARRAY_DIMS];
|
||||
// Stores Ids for dimensions that are specialization constants
|
||||
uint32_t spec_constant_op_ids[SPV_REFLECT_MAX_ARRAY_DIMS];
|
||||
uint32_t stride; // Measured in bytes
|
||||
} SpvReflectArrayTraits;
|
||||
|
||||
@@ -271,12 +331,13 @@ typedef struct SpvReflectBindingArrayTraits {
|
||||
} SpvReflectBindingArrayTraits;
|
||||
|
||||
/*! @struct SpvReflectTypeDescription
|
||||
|
||||
@brief Information about an OpType* instruction
|
||||
*/
|
||||
typedef struct SpvReflectTypeDescription {
|
||||
uint32_t id;
|
||||
SpvOp op;
|
||||
const char* type_name;
|
||||
// Non-NULL if type is member of a struct
|
||||
const char* struct_member_name;
|
||||
SpvStorageClass storage_class;
|
||||
SpvReflectTypeFlags type_flags;
|
||||
@@ -288,18 +349,25 @@ typedef struct SpvReflectTypeDescription {
|
||||
SpvReflectArrayTraits array;
|
||||
} traits;
|
||||
|
||||
// If underlying type is a struct (ex. array of structs)
|
||||
// this gives access to the OpTypeStruct
|
||||
struct SpvReflectTypeDescription* struct_type_description;
|
||||
|
||||
// @deprecated use struct_type_description instead
|
||||
uint32_t member_count;
|
||||
// @deprecated use struct_type_description instead
|
||||
struct SpvReflectTypeDescription* members;
|
||||
} SpvReflectTypeDescription;
|
||||
|
||||
|
||||
/*! @struct SpvReflectInterfaceVariable
|
||||
|
||||
@brief The OpVariable that is either an Input or Output to the module
|
||||
*/
|
||||
typedef struct SpvReflectInterfaceVariable {
|
||||
uint32_t spirv_id;
|
||||
const char* name;
|
||||
uint32_t location;
|
||||
uint32_t component;
|
||||
SpvStorageClass storage_class;
|
||||
const char* semantic;
|
||||
SpvReflectDecorationFlags decoration_flags;
|
||||
@@ -329,6 +397,7 @@ typedef struct SpvReflectInterfaceVariable {
|
||||
typedef struct SpvReflectBlockVariable {
|
||||
uint32_t spirv_id;
|
||||
const char* name;
|
||||
// For Push Constants, this is the lowest offset of all memebers
|
||||
uint32_t offset; // Measured in bytes
|
||||
uint32_t absolute_offset; // Measured in bytes
|
||||
uint32_t size; // Measured in bytes
|
||||
@@ -342,6 +411,11 @@ typedef struct SpvReflectBlockVariable {
|
||||
struct SpvReflectBlockVariable* members;
|
||||
|
||||
SpvReflectTypeDescription* type_description;
|
||||
|
||||
struct {
|
||||
uint32_t offset;
|
||||
} word_offset;
|
||||
|
||||
} SpvReflectBlockVariable;
|
||||
|
||||
/*! @struct SpvReflectDescriptorBinding
|
||||
@@ -369,6 +443,8 @@ typedef struct SpvReflectDescriptorBinding {
|
||||
uint32_t binding;
|
||||
uint32_t set;
|
||||
} word_offset;
|
||||
|
||||
SpvReflectDecorationFlags decoration_flags;
|
||||
} SpvReflectDescriptorBinding;
|
||||
|
||||
/*! @struct SpvReflectDescriptorSet
|
||||
@@ -390,10 +466,10 @@ typedef struct SpvReflectEntryPoint {
|
||||
SpvExecutionModel spirv_execution_model;
|
||||
SpvReflectShaderStageFlagBits shader_stage;
|
||||
|
||||
uint32_t input_variable_count;
|
||||
SpvReflectInterfaceVariable** input_variables;
|
||||
uint32_t output_variable_count;
|
||||
SpvReflectInterfaceVariable** output_variables;
|
||||
uint32_t input_variable_count;
|
||||
SpvReflectInterfaceVariable** input_variables;
|
||||
uint32_t output_variable_count;
|
||||
SpvReflectInterfaceVariable** output_variables;
|
||||
uint32_t interface_variable_count;
|
||||
SpvReflectInterfaceVariable* interface_variables;
|
||||
|
||||
@@ -405,13 +481,26 @@ typedef struct SpvReflectEntryPoint {
|
||||
uint32_t used_push_constant_count;
|
||||
uint32_t* used_push_constants;
|
||||
|
||||
uint32_t execution_mode_count;
|
||||
SpvExecutionMode* execution_modes;
|
||||
|
||||
struct LocalSize {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t z;
|
||||
} local_size;
|
||||
uint32_t invocations; // valid for geometry
|
||||
uint32_t output_vertices; // valid for geometry, tesselation
|
||||
} SpvReflectEntryPoint;
|
||||
|
||||
/*! @struct SpvReflectCapability
|
||||
|
||||
*/
|
||||
typedef struct SpvReflectCapability {
|
||||
SpvCapability value;
|
||||
uint32_t word_offset;
|
||||
} SpvReflectCapability;
|
||||
|
||||
/*! @struct SpvReflectShaderModule
|
||||
|
||||
*/
|
||||
@@ -425,6 +514,8 @@ typedef struct SpvReflectShaderModule {
|
||||
uint32_t source_language_version;
|
||||
const char* source_file;
|
||||
const char* source_source;
|
||||
uint32_t capability_count;
|
||||
SpvReflectCapability* capabilities;
|
||||
SpvExecutionModel spirv_execution_model; // Uses value(s) from first entry point
|
||||
SpvReflectShaderStageFlagBits shader_stage; // Uses value(s) from first entry point
|
||||
uint32_t descriptor_binding_count; // Uses value(s) from first entry point
|
||||
@@ -441,6 +532,7 @@ typedef struct SpvReflectShaderModule {
|
||||
SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point
|
||||
|
||||
struct Internal {
|
||||
SpvReflectModuleFlags module_flags;
|
||||
size_t spirv_size;
|
||||
uint32_t* spirv_code;
|
||||
uint32_t spirv_word_count;
|
||||
@@ -469,6 +561,22 @@ SpvReflectResult spvReflectCreateShaderModule(
|
||||
SpvReflectShaderModule* p_module
|
||||
);
|
||||
|
||||
/*! @fn spvReflectCreateShaderModule2
|
||||
|
||||
@param flags Flags for module creations.
|
||||
@param size Size in bytes of SPIR-V code.
|
||||
@param p_code Pointer to SPIR-V code.
|
||||
@param p_module Pointer to an instance of SpvReflectShaderModule.
|
||||
@return SPV_REFLECT_RESULT_SUCCESS on success.
|
||||
|
||||
*/
|
||||
SpvReflectResult spvReflectCreateShaderModule2(
|
||||
SpvReflectModuleFlags flags,
|
||||
size_t size,
|
||||
const void* p_code,
|
||||
SpvReflectShaderModule* p_module
|
||||
);
|
||||
|
||||
SPV_REFLECT_DEPRECATED("renamed to spvReflectCreateShaderModule")
|
||||
SpvReflectResult spvReflectGetShaderModule(
|
||||
size_t size,
|
||||
@@ -1329,7 +1437,7 @@ SpvReflectResult spvReflectChangeInputVariableLocation(
|
||||
by multiple entry points in the module, it will be changed in all of
|
||||
them.
|
||||
@param p_module Pointer to an instance of SpvReflectShaderModule.
|
||||
@param p_output_variable Pointer to the output variable to update.
|
||||
@param p_output_variable Pointer to the output variable to update.
|
||||
@param new_location The new location to assign to p_output_variable.
|
||||
@return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
|
||||
Otherwise, the error code indicates the cause of
|
||||
@@ -1351,11 +1459,21 @@ SpvReflectResult spvReflectChangeOutputVariableLocation(
|
||||
*/
|
||||
const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang);
|
||||
|
||||
/*! @fn spvReflectBlockVariableTypeName
|
||||
|
||||
@param p_var Pointer to block variable.
|
||||
@return Returns string of block variable's type description type name
|
||||
or NULL if p_var is NULL.
|
||||
*/
|
||||
const char* spvReflectBlockVariableTypeName(
|
||||
const SpvReflectBlockVariable* p_var
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if defined(__cplusplus) && !defined(SPIRV_REFLECT_DISABLE_CPP_BINDINGS)
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -1368,11 +1486,14 @@ namespace spv_reflect {
|
||||
class ShaderModule {
|
||||
public:
|
||||
ShaderModule();
|
||||
ShaderModule(size_t size, const void* p_code);
|
||||
ShaderModule(const std::vector<uint8_t>& code);
|
||||
ShaderModule(const std::vector<uint32_t>& code);
|
||||
ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);
|
||||
ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);
|
||||
ShaderModule(const std::vector<uint32_t>& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);
|
||||
~ShaderModule();
|
||||
|
||||
ShaderModule(ShaderModule&& other);
|
||||
ShaderModule& operator=(ShaderModule&& other);
|
||||
|
||||
SpvReflectResult GetResult() const;
|
||||
|
||||
const SpvReflectShaderModule& GetShaderModule() const;
|
||||
@@ -1477,8 +1598,9 @@ inline ShaderModule::ShaderModule() {}
|
||||
@param p_code
|
||||
|
||||
*/
|
||||
inline ShaderModule::ShaderModule(size_t size, const void* p_code) {
|
||||
m_result = spvReflectCreateShaderModule(
|
||||
inline ShaderModule::ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags) {
|
||||
m_result = spvReflectCreateShaderModule2(
|
||||
flags,
|
||||
size,
|
||||
p_code,
|
||||
&m_module);
|
||||
@@ -1487,10 +1609,11 @@ inline ShaderModule::ShaderModule(size_t size, const void* p_code) {
|
||||
/*! @fn ShaderModule
|
||||
|
||||
@param code
|
||||
|
||||
|
||||
*/
|
||||
inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code) {
|
||||
m_result = spvReflectCreateShaderModule(
|
||||
inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags) {
|
||||
m_result = spvReflectCreateShaderModule2(
|
||||
flags,
|
||||
code.size(),
|
||||
code.data(),
|
||||
&m_module);
|
||||
@@ -1499,10 +1622,11 @@ inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code) {
|
||||
/*! @fn ShaderModule
|
||||
|
||||
@param code
|
||||
|
||||
|
||||
*/
|
||||
inline ShaderModule::ShaderModule(const std::vector<uint32_t>& code) {
|
||||
m_result = spvReflectCreateShaderModule(
|
||||
inline ShaderModule::ShaderModule(const std::vector<uint32_t>& code, SpvReflectModuleFlags flags) {
|
||||
m_result = spvReflectCreateShaderModule2(
|
||||
flags,
|
||||
code.size() * sizeof(uint32_t),
|
||||
code.data(),
|
||||
&m_module);
|
||||
@@ -1516,6 +1640,20 @@ inline ShaderModule::~ShaderModule() {
|
||||
}
|
||||
|
||||
|
||||
inline ShaderModule::ShaderModule(ShaderModule&& other)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
inline ShaderModule& ShaderModule::operator=(ShaderModule&& other)
|
||||
{
|
||||
m_result = std::move(other.m_result);
|
||||
m_module = std::move(other.m_module);
|
||||
|
||||
other.m_module = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! @fn GetResult
|
||||
|
||||
@return
|
||||
@@ -2187,5 +2325,5 @@ inline SpvReflectResult ShaderModule::ChangeOutputVariableLocation(
|
||||
}
|
||||
|
||||
} // namespace spv_reflect
|
||||
#endif // defined(__cplusplus)
|
||||
#endif // defined(__cplusplus) && !defined(SPIRV_REFLECT_DISABLE_CPP_WRAPPER)
|
||||
#endif // SPIRV_REFLECT_H
|
||||
|
||||
@@ -44,8 +44,8 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE)
|
||||
|
||||
uint xEmitCount;
|
||||
uint xEmitterMeshIndexCount;
|
||||
uint xEmitterMeshVertexPositionStride;
|
||||
float xEmitterRandomness;
|
||||
float xParticleRandomColorFactor;
|
||||
|
||||
float xParticleSize;
|
||||
float xParticleScaling;
|
||||
@@ -90,11 +90,6 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE)
|
||||
|
||||
float3 xParticleVelocity;
|
||||
float xParticleDrag;
|
||||
|
||||
float xParticleRandomColorFactor;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
static const uint THREADCOUNT_EMIT = 256;
|
||||
|
||||
@@ -28,16 +28,13 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
ShaderMaterial material = load_material(geometry.materialIndex);
|
||||
|
||||
uint startIndex = prim.primitiveIndex * 3 + geometry.indexOffset;
|
||||
uint i0 = bindless_ib[geometry.ib][startIndex + 0];
|
||||
uint i1 = bindless_ib[geometry.ib][startIndex + 1];
|
||||
uint i2 = bindless_ib[geometry.ib][startIndex + 2];
|
||||
|
||||
uint4 data0 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i0 * 16);
|
||||
uint4 data1 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i1 * 16);
|
||||
uint4 data2 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i2 * 16);
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
uint i0 = bindless_buffers_uint[geometry.ib][startIndex + 0];
|
||||
uint i1 = bindless_buffers_uint[geometry.ib][startIndex + 1];
|
||||
uint i2 = bindless_buffers_uint[geometry.ib][startIndex + 2];
|
||||
|
||||
float3 p0 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i0].xyz;
|
||||
float3 p1 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i1].xyz;
|
||||
float3 p2 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i2].xyz;
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz;
|
||||
float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz;
|
||||
|
||||
@@ -18,13 +18,13 @@ ShaderMaterial EmitterGetMaterial()
|
||||
|
||||
struct VertextoPixel
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float4 tex : TEXCOORD0;
|
||||
nointerpolation float size : TEXCOORD1;
|
||||
nointerpolation uint color : TEXCOORD2;
|
||||
float4 pos : SV_POSITION;
|
||||
float4 tex : TEXCOORD0;
|
||||
float3 P : WORLDPOSITION;
|
||||
nointerpolation float frameBlend : FRAMEBLEND;
|
||||
float2 unrotated_uv : UNROTATED_UV;
|
||||
nointerpolation float frameBlend : FRAMEBLEND;
|
||||
nointerpolation float size : PARTICLESIZE;
|
||||
nointerpolation uint color : PARTICLECOLOR;
|
||||
};
|
||||
|
||||
#endif // WI_EMITTEDPARTICLE_HF
|
||||
|
||||
@@ -18,13 +18,29 @@ StructuredBuffer<uint> culledIndirectionBuffer2 : register(t3);
|
||||
static const uint VERTEXCOUNT = THREADCOUNT_MESH_SHADER * BILLBOARD_VERTEXCOUNT;
|
||||
static const uint PRIMITIVECOUNT = THREADCOUNT_MESH_SHADER * 2;
|
||||
|
||||
// VertexToPixel separated into two structures:
|
||||
struct VertextoPixel_MS
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float4 tex : TEXCOORD0;
|
||||
float3 P : WORLDPOSITION;
|
||||
float2 unrotated_uv : UNROTATED_UV;
|
||||
};
|
||||
struct VertextoPixel_MS_PRIM
|
||||
{
|
||||
nointerpolation float frameBlend : FRAMEBLEND;
|
||||
nointerpolation float size : PARTICLESIZE;
|
||||
nointerpolation uint color : PARTICLECOLOR;
|
||||
};
|
||||
|
||||
[outputtopology("triangle")]
|
||||
[numthreads(THREADCOUNT_MESH_SHADER, 1, 1)]
|
||||
void main(
|
||||
in uint tid : SV_DispatchThreadID,
|
||||
in uint tig : SV_GroupIndex,
|
||||
in uint gid : SV_GroupID,
|
||||
out vertices VertextoPixel verts[VERTEXCOUNT],
|
||||
out vertices VertextoPixel_MS verts[VERTEXCOUNT],
|
||||
out primitives VertextoPixel_MS_PRIM sharedPrimitives[PRIMITIVECOUNT],
|
||||
out indices uint3 triangles[PRIMITIVECOUNT])
|
||||
{
|
||||
uint particleCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_CULLEDCOUNT);
|
||||
@@ -35,14 +51,8 @@ void main(
|
||||
|
||||
if (tig >= realGroupCount)
|
||||
return;
|
||||
|
||||
#ifdef SPIRV
|
||||
// Workaround for mesh shader compile issue with vulkan: https://github.com/microsoft/DirectXShaderCompiler/issues/4865#issuecomment-1346806816
|
||||
ShaderGeometry geometry;
|
||||
geometry.init(); // obviously, this will not produce correct result, but let the shader compile at least in vulkan
|
||||
#else
|
||||
|
||||
ShaderGeometry geometry = EmitterGetGeometry();
|
||||
#endif // SPIRV
|
||||
|
||||
uint instanceID = tid;
|
||||
uint particleIndex = culledIndirectionBuffer2[culledIndirectionBuffer[instanceID]];
|
||||
@@ -59,30 +69,32 @@ void main(
|
||||
lerp(xEmitterFrameStart, xEmitterFrameCount, lifeLerp) :
|
||||
((xEmitterFrameStart + particle.life * xEmitterFrameRate) % xEmitterFrameCount);
|
||||
const float frameBlend = frac(spriteframe);
|
||||
|
||||
|
||||
// Transform the vertices and write them
|
||||
for (uint i = 0; i < BILLBOARD_VERTEXCOUNT; ++i)
|
||||
{
|
||||
uint vertexID = particleIndex * 4 + i;
|
||||
|
||||
uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16);
|
||||
float3 position = asfloat(data.xyz);
|
||||
float3 normal = normalize(unpack_unitvector(data.w));
|
||||
float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8));
|
||||
uint color = bindless_buffers[geometry.vb_col].Load(vertexID * 4);
|
||||
float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID];
|
||||
float3 position = pos_nor_wind.xyz;
|
||||
float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w)));
|
||||
float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID];
|
||||
|
||||
VertextoPixel Out;
|
||||
VertextoPixel_MS Out;
|
||||
Out.P = position;
|
||||
Out.pos = mul(GetCamera().view_projection, float4(position, 1));
|
||||
Out.tex = uvsets;
|
||||
Out.size = size;
|
||||
Out.color = color;
|
||||
Out.unrotated_uv = BILLBOARD[i].xy * float2(1, -1) * 0.5f + 0.5f;
|
||||
Out.frameBlend = frameBlend;
|
||||
|
||||
verts[tig * BILLBOARD_VERTEXCOUNT + i] = Out;
|
||||
}
|
||||
|
||||
VertextoPixel_MS_PRIM OutQuad;
|
||||
OutQuad.color = pack_rgba(bindless_buffers_float4[geometry.vb_col][particleIndex * 4]);
|
||||
OutQuad.size = size;
|
||||
OutQuad.frameBlend = frameBlend;
|
||||
sharedPrimitives[tig * 2 + 0] = OutQuad;
|
||||
sharedPrimitives[tig * 2 + 1] = OutQuad;
|
||||
|
||||
triangles[tig * 2 + 0] = uint3(0, 1, 2) + tig * BILLBOARD_VERTEXCOUNT;
|
||||
triangles[tig * 2 + 1] = uint3(2, 1, 3) + tig * BILLBOARD_VERTEXCOUNT;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ VertextoPixel main(uint vid : SV_VertexID, uint instanceID : SV_InstanceID)
|
||||
uint particleIndex = culledIndirectionBuffer2[culledIndirectionBuffer[instanceID]];
|
||||
uint vertexID = particleIndex * 4 + vid;
|
||||
|
||||
uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16);
|
||||
float3 position = asfloat(data.xyz);
|
||||
float3 normal = normalize(unpack_unitvector(data.w));
|
||||
float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8));
|
||||
uint color = bindless_buffers[geometry.vb_col].Load(vertexID * 4);
|
||||
float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID];
|
||||
float3 position = pos_nor_wind.xyz;
|
||||
float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w)));
|
||||
float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID];
|
||||
float4 color = bindless_buffers_float4[geometry.vb_col][vertexID];
|
||||
|
||||
|
||||
// load particle data:
|
||||
@@ -45,7 +45,7 @@ VertextoPixel main(uint vid : SV_VertexID, uint instanceID : SV_InstanceID)
|
||||
Out.pos = mul(GetCamera().view_projection, float4(position, 1));
|
||||
Out.tex = uvsets;
|
||||
Out.size = size;
|
||||
Out.color = color;
|
||||
Out.color = pack_rgba(color);
|
||||
Out.unrotated_uv = BILLBOARD[vertexID % 4].xy * float2(1, -1) * 0.5f + 0.5f;
|
||||
Out.frameBlend = frameBlend;
|
||||
return Out;
|
||||
|
||||
@@ -10,7 +10,7 @@ RWByteAddressBuffer counterBuffer : register(u4);
|
||||
|
||||
#ifdef EMIT_FROM_MESH
|
||||
Buffer<uint> meshIndexBuffer : register(t0);
|
||||
ByteAddressBuffer meshVertexBuffer_POS : register(t1);
|
||||
Buffer<float4> meshVertexBuffer_POS : register(t1);
|
||||
#endif // EMIT_FROM_MESH
|
||||
|
||||
|
||||
@@ -18,114 +18,96 @@ ByteAddressBuffer meshVertexBuffer_POS : register(t1);
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
uint emitCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_REALEMITCOUNT);
|
||||
if (DTid.x >= emitCount)
|
||||
return;
|
||||
|
||||
RNG rng;
|
||||
rng.init(uint2(xEmitterRandomness, DTid.x), GetFrame().frame_count);
|
||||
|
||||
if(DTid.x < emitCount)
|
||||
{
|
||||
RNG rng;
|
||||
rng.init(uint2(xEmitterRandomness, DTid.x), GetFrame().frame_count);
|
||||
|
||||
const float4x4 worldMatrix = xEmitterTransform.GetMatrix();
|
||||
const float4x4 worldMatrix = xEmitterTransform.GetMatrix();
|
||||
|
||||
#ifdef EMIT_FROM_MESH
|
||||
// random triangle on emitter surface:
|
||||
uint tri = (uint)((xEmitterMeshIndexCount / 3) * hash1(DTid.x + GetFrame().frame_count));
|
||||
// random triangle on emitter surface:
|
||||
const uint triangleCount = xEmitterMeshIndexCount / 3;
|
||||
const uint tri = rng.next_uint(triangleCount);
|
||||
|
||||
// load indices of triangle from index buffer
|
||||
uint i0 = meshIndexBuffer[tri * 3 + 0];
|
||||
uint i1 = meshIndexBuffer[tri * 3 + 1];
|
||||
uint i2 = meshIndexBuffer[tri * 3 + 2];
|
||||
// load indices of triangle from index buffer
|
||||
uint i0 = meshIndexBuffer[tri * 3 + 0];
|
||||
uint i1 = meshIndexBuffer[tri * 3 + 1];
|
||||
uint i2 = meshIndexBuffer[tri * 3 + 2];
|
||||
|
||||
// load vertices of triangle from vertex buffer:
|
||||
float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xEmitterMeshVertexPositionStride));
|
||||
float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xEmitterMeshVertexPositionStride));
|
||||
float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xEmitterMeshVertexPositionStride));
|
||||
// load vertices of triangle from vertex buffer:
|
||||
float4 pos_nor0 = meshVertexBuffer_POS[i0];
|
||||
float4 pos_nor1 = meshVertexBuffer_POS[i1];
|
||||
float4 pos_nor2 = meshVertexBuffer_POS[i2];
|
||||
|
||||
float3 nor0 = unpack_unitvector(asuint(pos_nor0.w));
|
||||
float3 nor1 = unpack_unitvector(asuint(pos_nor1.w));
|
||||
float3 nor2 = unpack_unitvector(asuint(pos_nor2.w));
|
||||
|
||||
uint nor_u = asuint(pos_nor0.w);
|
||||
float3 nor0;
|
||||
{
|
||||
nor0.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor0.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor0.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
}
|
||||
nor_u = asuint(pos_nor1.w);
|
||||
float3 nor1;
|
||||
{
|
||||
nor1.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor1.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor1.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
}
|
||||
nor_u = asuint(pos_nor2.w);
|
||||
float3 nor2;
|
||||
{
|
||||
nor2.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor2.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor2.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
}
|
||||
// random barycentric coords:
|
||||
float f = rng.next_float();
|
||||
float g = rng.next_float();
|
||||
[flatten]
|
||||
if (f + g > 1)
|
||||
{
|
||||
f = 1 - f;
|
||||
g = 1 - g;
|
||||
}
|
||||
float2 bary = float2(f, g);
|
||||
|
||||
// random barycentric coords:
|
||||
float f = rng.next_float();
|
||||
float g = rng.next_float();
|
||||
[flatten]
|
||||
if (f + g > 1)
|
||||
{
|
||||
f = 1 - f;
|
||||
g = 1 - g;
|
||||
}
|
||||
|
||||
// compute final surface position on triangle from barycentric coords:
|
||||
float3 pos = pos_nor0.xyz + f * (pos_nor1.xyz - pos_nor0.xyz) + g * (pos_nor2.xyz - pos_nor0.xyz);
|
||||
float3 nor = nor0 + f * (nor1 - nor0) + g * (nor2 - nor0);
|
||||
pos = mul(worldMatrix, float4(pos, 1)).xyz;
|
||||
nor = normalize(mul((float3x3)worldMatrix, nor));
|
||||
// compute final surface position on triangle from barycentric coords:
|
||||
float3 pos = attribute_at_bary(pos_nor0.xyz, pos_nor1.xyz, pos_nor2.xyz, bary);
|
||||
float3 nor = normalize(attribute_at_bary(nor0, nor1, nor2, bary));
|
||||
pos = mul(worldMatrix, float4(pos, 1)).xyz;
|
||||
nor = normalize(mul((float3x3)worldMatrix, nor));
|
||||
|
||||
#else
|
||||
|
||||
#ifdef EMITTER_VOLUME
|
||||
// Emit inside volume:
|
||||
float3 pos = mul(worldMatrix, float4(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, 1)).xyz;
|
||||
// Emit inside volume:
|
||||
float3 pos = mul(worldMatrix, float4(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, 1)).xyz;
|
||||
#else
|
||||
// Just emit from center point:
|
||||
float3 pos = mul(worldMatrix, float4(0, 0, 0, 1)).xyz;
|
||||
// Just emit from center point:
|
||||
float3 pos = mul(worldMatrix, float4(0, 0, 0, 1)).xyz;
|
||||
#endif // EMITTER_VOLUME
|
||||
|
||||
float3 nor = 0;
|
||||
float3 nor = 0;
|
||||
|
||||
#endif // EMIT_FROM_MESH
|
||||
|
||||
float particleStartingSize = xParticleSize + xParticleSize * (rng.next_float() - 0.5f) * xParticleRandomFactor;
|
||||
float particleStartingSize = xParticleSize + xParticleSize * (rng.next_float() - 0.5f) * xParticleRandomFactor;
|
||||
|
||||
// create new particle:
|
||||
Particle particle;
|
||||
particle.position = pos;
|
||||
particle.force = 0;
|
||||
particle.mass = xParticleMass;
|
||||
particle.velocity = xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
|
||||
particle.rotationalVelocity = xParticleRotation + (rng.next_float() - 0.5f) * xParticleRandomFactor;
|
||||
particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rng.next_float() - 0.5f) * xParticleLifeSpanRandomness;
|
||||
particle.life = particle.maxLife;
|
||||
particle.sizeBeginEnd = float2(particleStartingSize, particleStartingSize * xParticleScaling);
|
||||
particle.color_mirror = 0;
|
||||
particle.color_mirror |= ((rng.next_float() > 0.5f) << 31) & 0x10000000;
|
||||
particle.color_mirror |= ((rng.next_float() < 0.5f) << 30) & 0x20000000;
|
||||
// create new particle:
|
||||
Particle particle;
|
||||
particle.position = pos;
|
||||
particle.force = 0;
|
||||
particle.mass = xParticleMass;
|
||||
particle.velocity = xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
|
||||
particle.rotationalVelocity = xParticleRotation + (rng.next_float() - 0.5f) * xParticleRandomFactor;
|
||||
particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rng.next_float() - 0.5f) * xParticleLifeSpanRandomness;
|
||||
particle.life = particle.maxLife;
|
||||
particle.sizeBeginEnd = float2(particleStartingSize, particleStartingSize * xParticleScaling);
|
||||
particle.color_mirror = 0;
|
||||
particle.color_mirror |= ((rng.next_float() > 0.5f) << 31) & 0x10000000;
|
||||
particle.color_mirror |= ((rng.next_float() < 0.5f) << 30) & 0x20000000;
|
||||
|
||||
uint color_modifier = 0;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 0;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 8;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 16;
|
||||
particle.color_mirror |= pack_rgba(float4(EmitterGetMaterial().baseColor.rgb, 1)) & color_modifier;
|
||||
uint color_modifier = 0;
|
||||
color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 0;
|
||||
color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 8;
|
||||
color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 16;
|
||||
particle.color_mirror |= pack_rgba(float4(EmitterGetMaterial().baseColor.rgb, 1)) & color_modifier;
|
||||
|
||||
// new particle index retrieved from dead list (pop):
|
||||
uint deadCount;
|
||||
counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, -1, deadCount);
|
||||
uint newParticleIndex = deadBuffer[deadCount - 1];
|
||||
|
||||
// write out the new particle:
|
||||
particleBuffer[newParticleIndex] = particle;
|
||||
|
||||
// new particle index retrieved from dead list (pop):
|
||||
uint deadCount;
|
||||
counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, -1, deadCount);
|
||||
uint newParticleIndex = deadBuffer[deadCount - 1];
|
||||
|
||||
// write out the new particle:
|
||||
particleBuffer[newParticleIndex] = particle;
|
||||
|
||||
// and add index to the alive list (push):
|
||||
uint aliveCount;
|
||||
counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT, 1, aliveCount);
|
||||
aliveBuffer_CURRENT[aliveCount] = newParticleIndex;
|
||||
}
|
||||
// and add index to the alive list (push):
|
||||
uint aliveCount;
|
||||
counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT, 1, aliveCount);
|
||||
aliveBuffer_CURRENT[aliveCount] = newParticleIndex;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ RWStructuredBuffer<uint> aliveBuffer_NEW : register(u2);
|
||||
RWStructuredBuffer<uint> deadBuffer : register(u3);
|
||||
RWByteAddressBuffer counterBuffer : register(u4);
|
||||
RWStructuredBuffer<float> distanceBuffer : register(u6);
|
||||
RWByteAddressBuffer vertexBuffer_POS : register(u7);
|
||||
RWByteAddressBuffer vertexBuffer_UVS : register(u8);
|
||||
RWByteAddressBuffer vertexBuffer_COL : register(u9);
|
||||
RWBuffer<float4> vertexBuffer_POS : register(u7);
|
||||
RWBuffer<float4> vertexBuffer_UVS : register(u8);
|
||||
RWBuffer<float4> vertexBuffer_COL : register(u9);
|
||||
RWStructuredBuffer<uint> culledIndirectionBuffer : register(u10);
|
||||
RWStructuredBuffer<uint> culledIndirectionBuffer2 : register(u11);
|
||||
|
||||
@@ -292,12 +292,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
|
||||
quadPos = mul(quadPos, (float3x3)GetCamera().view); // reversed mul for inverse camera rotation!
|
||||
|
||||
// write out vertex:
|
||||
uint4 data;
|
||||
data.xyz = asuint(particle.position + quadPos);
|
||||
data.w = pack_unitvector(normalize(-GetCamera().forward));
|
||||
vertexBuffer_POS.Store4((v0 + vertexID) * 16, data);
|
||||
vertexBuffer_UVS.Store2((v0 + vertexID) * 8, pack_half4(float4(uv, uv2)));
|
||||
vertexBuffer_COL.Store((v0 + vertexID) * 4, particleColorPacked);
|
||||
vertexBuffer_POS[v0 + vertexID] = float4(particle.position + quadPos, asfloat(pack_unitvector(normalize(-GetCamera().forward))));
|
||||
vertexBuffer_UVS[v0 + vertexID] = float4(uv, uv2);
|
||||
vertexBuffer_COL[v0 + vertexID] = unpack_rgba(particleColorPacked);
|
||||
}
|
||||
|
||||
// Frustum culling:
|
||||
@@ -329,10 +326,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
|
||||
counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, 1, deadIndex);
|
||||
deadBuffer[deadIndex] = particleIndex;
|
||||
|
||||
vertexBuffer_POS.Store4((v0 + 0) * 16, 0);
|
||||
vertexBuffer_POS.Store4((v0 + 1) * 16, 0);
|
||||
vertexBuffer_POS.Store4((v0 + 2) * 16, 0);
|
||||
vertexBuffer_POS.Store4((v0 + 3) * 16, 0);
|
||||
vertexBuffer_POS[v0 + 0] = 0;
|
||||
vertexBuffer_POS[v0 + 1] = 0;
|
||||
vertexBuffer_POS[v0 + 2] = 0;
|
||||
vertexBuffer_POS[v0 + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,30 @@
|
||||
"SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" \
|
||||
"SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 34, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 35, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 36, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \
|
||||
"SRV(t0, space = 37, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" \
|
||||
"), " \
|
||||
"StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \
|
||||
"StaticSampler(s101, addressU = TEXTURE_ADDRESS_WRAP, addressV = TEXTURE_ADDRESS_WRAP, addressW = TEXTURE_ADDRESS_WRAP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \
|
||||
@@ -80,10 +99,18 @@ static const uint DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER = 2;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_SAMPLER = 3;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE = 4;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE = 5;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER = 6;
|
||||
static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 7;
|
||||
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] ByteAddressBuffer bindless_buffers[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint> bindless_ib[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint> bindless_buffers_uint[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint2> bindless_buffers_uint2[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint3> bindless_buffers_uint3[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint4> bindless_buffers_uint4[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float> bindless_buffers_float[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float2> bindless_buffers_float2[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float3> bindless_buffers_float3[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float4> bindless_buffers_float4[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLER)]] SamplerState bindless_samplers[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D bindless_textures[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2DArray bindless_textures2DArray[];
|
||||
@@ -96,6 +123,14 @@ static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6;
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D<uint4> bindless_textures_uint4[];
|
||||
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] RWByteAddressBuffer bindless_rwbuffers[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint> bindless_rwbuffers_uint[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint2> bindless_rwbuffers_uint2[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint3> bindless_rwbuffers_uint3[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint4> bindless_rwbuffers_uint4[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float> bindless_rwbuffers_float[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float2> bindless_rwbuffers_float2[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float3> bindless_rwbuffers_float3[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float4> bindless_rwbuffers_float4[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2D<float4> bindless_rwtextures[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2DArray<float4> bindless_rwtextures2DArray[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture3D<float4> bindless_rwtextures3D[];
|
||||
@@ -108,28 +143,56 @@ static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6;
|
||||
SamplerState bindless_samplers[] : register(space1);
|
||||
Texture2D bindless_textures[] : register(space2);
|
||||
ByteAddressBuffer bindless_buffers[] : register(space3);
|
||||
Buffer<uint> bindless_ib[] : register(space4);
|
||||
Buffer<uint> bindless_buffers_uint[] : register(space4);
|
||||
Buffer<uint2> bindless_buffers_uint2[] : register(space5);
|
||||
Buffer<uint3> bindless_buffers_uint3[] : register(space6);
|
||||
Buffer<uint4> bindless_buffers_uint4[] : register(space7);
|
||||
Buffer<float> bindless_buffers_float[] : register(space8);
|
||||
Buffer<float2> bindless_buffers_float2[] : register(space9);
|
||||
Buffer<float3> bindless_buffers_float3[] : register(space10);
|
||||
Buffer<float4> bindless_buffers_float4[] : register(space11);
|
||||
#ifdef RTAPI
|
||||
RaytracingAccelerationStructure bindless_accelerationstructures[] : register(space5);
|
||||
RaytracingAccelerationStructure bindless_accelerationstructures[] : register(space12);
|
||||
#endif // RTAPI
|
||||
Texture2DArray bindless_textures2DArray[] : register(space6);
|
||||
TextureCube bindless_cubemaps[] : register(space7);
|
||||
TextureCubeArray bindless_cubearrays[] : register(space8);
|
||||
Texture3D bindless_textures3D[] : register(space9);
|
||||
Texture2D<float> bindless_textures_float[] : register(space10);
|
||||
Texture2D<float2> bindless_textures_float2[] : register(space11);
|
||||
Texture2D<uint> bindless_textures_uint[] : register(space12);
|
||||
Texture2D<uint4> bindless_textures_uint4[] : register(space13);
|
||||
Texture2DArray bindless_textures2DArray[] : register(space13);
|
||||
TextureCube bindless_cubemaps[] : register(space14);
|
||||
TextureCubeArray bindless_cubearrays[] : register(space15);
|
||||
Texture3D bindless_textures3D[] : register(space16);
|
||||
Texture2D<float> bindless_textures_float[] : register(space17);
|
||||
Texture2D<float2> bindless_textures_float2[] : register(space18);
|
||||
Texture2D<uint> bindless_textures_uint[] : register(space19);
|
||||
Texture2D<uint4> bindless_textures_uint4[] : register(space20);
|
||||
|
||||
RWTexture2D<float4> bindless_rwtextures[] : register(space21);
|
||||
RWByteAddressBuffer bindless_rwbuffers[] : register(space22);
|
||||
RWBuffer<uint> bindless_rwbuffers_uint[] : register(space23);
|
||||
RWBuffer<uint2> bindless_rwbuffers_uint2[] : register(space24);
|
||||
RWBuffer<uint3> bindless_rwbuffers_uint3[] : register(space25);
|
||||
RWBuffer<uint4> bindless_rwbuffers_uint4[] : register(space26);
|
||||
RWBuffer<float> bindless_rwbuffers_float[] : register(space27);
|
||||
RWBuffer<float2> bindless_rwbuffers_float2[] : register(space28);
|
||||
RWBuffer<float3> bindless_rwbuffers_float3[] : register(space29);
|
||||
RWBuffer<float4> bindless_rwbuffers_float4[] : register(space30);
|
||||
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space31);
|
||||
RWTexture3D<float4> bindless_rwtextures3D[] : register(space32);
|
||||
RWTexture2D<uint> bindless_rwtextures_uint[] : register(space33);
|
||||
|
||||
RWTexture2D<float4> bindless_rwtextures[] : register(space14);
|
||||
RWByteAddressBuffer bindless_rwbuffers[] : register(space15);
|
||||
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space16);
|
||||
RWTexture3D<float4> bindless_rwtextures3D[] : register(space17);
|
||||
RWTexture2D<uint> bindless_rwtextures_uint[] : register(space18);
|
||||
#endif // SPIRV
|
||||
|
||||
#include "ShaderInterop_Renderer.h"
|
||||
|
||||
#ifdef SPIRV
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMeshInstance> bindless_buffers_meshinstance[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderGeometry> bindless_buffers_geometry[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMeshlet> bindless_buffers_meshlet[];
|
||||
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMaterial> bindless_buffers_material[];
|
||||
#else
|
||||
StructuredBuffer<ShaderMeshInstance> bindless_buffers_meshinstance[] : register(space34);
|
||||
StructuredBuffer<ShaderGeometry> bindless_buffers_geometry[] : register(space35);
|
||||
StructuredBuffer<ShaderMeshlet> bindless_buffers_meshlet[] : register(space36);
|
||||
StructuredBuffer<ShaderMaterial> bindless_buffers_material[] : register(space37);
|
||||
#endif // SPIRV
|
||||
|
||||
inline FrameCB GetFrame()
|
||||
{
|
||||
return g_xFrame;
|
||||
@@ -148,19 +211,19 @@ inline ShaderWeather GetWeather()
|
||||
}
|
||||
inline ShaderMeshInstance load_instance(uint instanceIndex)
|
||||
{
|
||||
return bindless_buffers[GetScene().instancebuffer].Load<ShaderMeshInstance>(instanceIndex * sizeof(ShaderMeshInstance));
|
||||
return bindless_buffers_meshinstance[GetScene().instancebuffer][instanceIndex];
|
||||
}
|
||||
inline ShaderGeometry load_geometry(uint geometryIndex)
|
||||
{
|
||||
return bindless_buffers[GetScene().geometrybuffer].Load<ShaderGeometry>(geometryIndex * sizeof(ShaderGeometry));
|
||||
return bindless_buffers_geometry[GetScene().geometrybuffer][geometryIndex];
|
||||
}
|
||||
inline ShaderMeshlet load_meshlet(uint meshletIndex)
|
||||
{
|
||||
return bindless_buffers[GetScene().meshletbuffer].Load<ShaderMeshlet>(meshletIndex * sizeof(ShaderMeshlet));
|
||||
return bindless_buffers_meshlet[GetScene().meshletbuffer][meshletIndex];
|
||||
}
|
||||
inline ShaderMaterial load_material(uint materialIndex)
|
||||
{
|
||||
return bindless_buffers[GetScene().materialbuffer].Load<ShaderMaterial>(materialIndex * sizeof(ShaderMaterial));
|
||||
return bindless_buffers_material[GetScene().materialbuffer][materialIndex];
|
||||
}
|
||||
uint load_entitytile(uint tileIndex)
|
||||
{
|
||||
|
||||
@@ -12,10 +12,10 @@ VertexToPixel main(uint vid : SV_VERTEXID)
|
||||
Out.primitiveID = vid / 3;
|
||||
|
||||
uint vertexID = primitiveBuffer[vid];
|
||||
uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16);
|
||||
float3 position = asfloat(data.xyz);
|
||||
float3 normal = normalize(unpack_unitvector(data.w));
|
||||
float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8));
|
||||
float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID];
|
||||
float3 position = pos_nor_wind.xyz;
|
||||
float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w)));
|
||||
float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID];
|
||||
|
||||
Out.fade = saturate(distance(position.xyz, GetCamera().position.xyz) / xHairViewDistance);
|
||||
Out.fade = saturate(Out.fade - 0.8f) * 5.0f; // fade will be on edge and inwards 20%
|
||||
|
||||
@@ -10,12 +10,12 @@ static const float3 HAIRPATCH[] = {
|
||||
};
|
||||
|
||||
Buffer<uint> meshIndexBuffer : register(t0);
|
||||
ByteAddressBuffer meshVertexBuffer_POS : register(t1);
|
||||
Buffer<float4> meshVertexBuffer_POS : register(t1);
|
||||
Buffer<float> meshVertexBuffer_length : register(t2);
|
||||
|
||||
RWStructuredBuffer<PatchSimulationData> simulationBuffer : register(u0);
|
||||
RWByteAddressBuffer vertexBuffer_POS : register(u1);
|
||||
RWByteAddressBuffer vertexBuffer_UVS : register(u2);
|
||||
RWBuffer<float4> vertexBuffer_POS : register(u1);
|
||||
RWBuffer<float4> vertexBuffer_UVS : register(u2);
|
||||
RWBuffer<uint> culledIndexBuffer : register(u3);
|
||||
RWStructuredBuffer<IndirectDrawArgsIndexedInstanced> indirectBuffer : register(u4);
|
||||
|
||||
@@ -24,11 +24,13 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
{
|
||||
if (DTid.x >= xHairParticleCount)
|
||||
return;
|
||||
|
||||
// Generate patch:
|
||||
|
||||
|
||||
RNG rng;
|
||||
rng.init(uint2(xHairRandomSeed, DTid.x), 0);
|
||||
|
||||
// random triangle on emitter surface:
|
||||
uint tri = (uint)((xHairBaseMeshIndexCount / 3) * hash1(DTid.x));
|
||||
const uint triangleCount = xHairBaseMeshIndexCount / 3;
|
||||
const uint tri = rng.next_uint(triangleCount);
|
||||
|
||||
// load indices of triangle from index buffer
|
||||
uint i0 = meshIndexBuffer[tri * 3 + 0];
|
||||
@@ -36,19 +38,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
uint i2 = meshIndexBuffer[tri * 3 + 2];
|
||||
|
||||
// load vertices of triangle from vertex buffer:
|
||||
float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xHairBaseMeshVertexPositionStride));
|
||||
float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xHairBaseMeshVertexPositionStride));
|
||||
float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xHairBaseMeshVertexPositionStride));
|
||||
float3 nor0 = unpack_unitvector(asuint(pos_nor0.w));
|
||||
float3 nor1 = unpack_unitvector(asuint(pos_nor1.w));
|
||||
float3 nor2 = unpack_unitvector(asuint(pos_nor2.w));
|
||||
float4 pos_nor0 = meshVertexBuffer_POS[i0];
|
||||
float4 pos_nor1 = meshVertexBuffer_POS[i1];
|
||||
float4 pos_nor2 = meshVertexBuffer_POS[i2];
|
||||
float3 nor0 = unpack_unitvector(asuint(pos_nor0.w));
|
||||
float3 nor1 = unpack_unitvector(asuint(pos_nor1.w));
|
||||
float3 nor2 = unpack_unitvector(asuint(pos_nor2.w));
|
||||
float length0 = meshVertexBuffer_length[i0];
|
||||
float length1 = meshVertexBuffer_length[i1];
|
||||
float length2 = meshVertexBuffer_length[i2];
|
||||
|
||||
// random barycentric coords:
|
||||
RNG rng;
|
||||
rng.init(uint2(xHairRandomSeed, DTid.x), 0);
|
||||
float f = rng.next_float();
|
||||
float g = rng.next_float();
|
||||
[flatten]
|
||||
@@ -79,12 +79,12 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
binormal_length |= (uint)(lerp(1, rng.next_float(), saturate(xHairRandomness)) * strand_length * 255) << 24;
|
||||
|
||||
// Identifies the hair strand root particle:
|
||||
const uint strandID = DTid.x * xHairSegmentCount;
|
||||
|
||||
const uint strandID = DTid.x * xHairSegmentCount;
|
||||
|
||||
// Transform particle by the emitter object matrix:
|
||||
const float4x4 worldMatrix = xHairTransform.GetMatrix();
|
||||
float3 base = mul(worldMatrix, float4(position.xyz, 1)).xyz;
|
||||
target = normalize(mul((float3x3)worldMatrix, target));
|
||||
float3 base = mul(worldMatrix, float4(position.xyz, 1)).xyz;
|
||||
target = normalize(mul((float3x3)worldMatrix, target));
|
||||
const float3 root = base;
|
||||
|
||||
float3 diff = GetCamera().position - root;
|
||||
@@ -97,7 +97,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
float3 normal = 0;
|
||||
|
||||
const float delta_time = clamp(GetFrame().delta_time, 0, 1.0 / 30.0); // clamp delta time to avoid simulation blowing up
|
||||
|
||||
|
||||
for (uint segmentID = 0; segmentID < xHairSegmentCount; ++segmentID)
|
||||
{
|
||||
// Identifies the hair strand segment particle:
|
||||
@@ -111,8 +111,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
simulationBuffer[particleID].normal_velocity = f32tof16(target);
|
||||
}
|
||||
|
||||
normal += f16tof32(simulationBuffer[particleID].normal_velocity);
|
||||
normal = normalize(normal);
|
||||
normal += f16tof32(simulationBuffer[particleID].normal_velocity);
|
||||
normal = normalize(normal);
|
||||
|
||||
float len = (binormal_length >> 24) & 0x000000FF;
|
||||
len /= 255.0f;
|
||||
@@ -123,8 +123,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
|
||||
// Accumulate forces, apply colliders:
|
||||
float3 force = 0;
|
||||
for (uint i = 0; i < GetFrame().forcefieldarray_count; ++i)
|
||||
{
|
||||
for (uint i = 0; i < GetFrame().forcefieldarray_count; ++i)
|
||||
{
|
||||
ShaderEntity entity = load_entity(GetFrame().forcefieldarray_offset + i);
|
||||
|
||||
[branch]
|
||||
@@ -198,15 +198,15 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pull back to rest position:
|
||||
force += (target - normal) * xStiffness;
|
||||
force += (target - normal) * xStiffness;
|
||||
|
||||
force *= delta_time;
|
||||
force *= delta_time;
|
||||
|
||||
// Simulation buffer load:
|
||||
float3 velocity = f16tof32(simulationBuffer[particleID].normal_velocity >> 16u);
|
||||
float3 velocity = f16tof32(simulationBuffer[particleID].normal_velocity >> 16u);
|
||||
|
||||
// Apply surface-movement-based velocity:
|
||||
const float3 old_base = simulationBuffer[particleID].position;
|
||||
@@ -272,12 +272,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
{
|
||||
position = 0;
|
||||
}
|
||||
|
||||
uint4 data;
|
||||
data.xyz = asuint(position);
|
||||
data.w = pack_unitvector(normalize(normal + wind));
|
||||
vertexBuffer_POS.Store4((v0 + vertexID) * 16, data);
|
||||
vertexBuffer_UVS.Store2((v0 + vertexID) * 8, pack_half4(float4(uv, uv))); // a second uv set could be used here
|
||||
|
||||
vertexBuffer_POS[v0 + vertexID] = float4(position, asfloat(pack_unitvector(normalize(normal + wind))));
|
||||
vertexBuffer_UVS[v0 + vertexID] = uv.xyxy; // a second uv set could be used here
|
||||
}
|
||||
|
||||
// Frustum culling:
|
||||
@@ -310,5 +307,5 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
|
||||
// Offset next segment root to current tip:
|
||||
base = tip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ static const float2 BILLBOARD[] = {
|
||||
float2(1, 1),
|
||||
};
|
||||
|
||||
ByteAddressBuffer vb_pos_nor : register(t0);
|
||||
Buffer<float4> vb_pos_nor : register(t0);
|
||||
ByteAddressBuffer impostor_data : register(t2);
|
||||
|
||||
VSOut main(uint vertexID : SV_VertexID)
|
||||
@@ -16,7 +16,7 @@ VSOut main(uint vertexID : SV_VertexID)
|
||||
uint2 data = impostor_data.Load2((vertexID / 4u) * sizeof(uint2));
|
||||
|
||||
VSOut Out;
|
||||
Out.pos3D = asfloat(vb_pos_nor.Load3(vertexID * sizeof(uint4)));
|
||||
Out.pos3D = vb_pos_nor[vertexID].xyz;
|
||||
Out.pos = mul(GetCamera().view_projection, float4(Out.pos3D, 1));
|
||||
Out.uv = float2(BILLBOARD[vertexID % 4u] * float2(0.5f, -0.5f) + 0.5f);
|
||||
Out.slice = data.x & 0xFFFFFF;
|
||||
|
||||
@@ -11,7 +11,7 @@ static const float3 BILLBOARD[] =
|
||||
};
|
||||
|
||||
RWBuffer<uint> output_indices : register(u0);
|
||||
RWByteAddressBuffer output_vertices_pos_nor : register(u1);
|
||||
RWBuffer<float4> output_vertices_pos_nor : register(u1);
|
||||
RWByteAddressBuffer output_impostor_data : register(u2);
|
||||
RWStructuredBuffer<IndirectDrawArgsIndexedInstanced> output_indirect : register(u3);
|
||||
|
||||
@@ -103,7 +103,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
pos = mul(pos, float3x3(right, up, face));
|
||||
pos *= instance.radius;
|
||||
pos += instance.center;
|
||||
output_vertices_pos_nor.Store4((vertexOffset + vertexID) * sizeof(uint4), uint4(asuint(pos), pack_unitvector(face)));
|
||||
output_vertices_pos_nor[vertexOffset + vertexID] = float4(pos, asfloat(pack_unitvector(face)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,23 +121,9 @@ struct VertexInput
|
||||
uint vertexID : SV_VertexID;
|
||||
uint instanceID : SV_InstanceID;
|
||||
|
||||
float4 GetPosition()
|
||||
float4 GetPositionNormalWind()
|
||||
{
|
||||
return float4(bindless_buffers[GetMesh().vb_pos_nor_wind].Load<float3>(vertexID * sizeof(uint4)), 1);
|
||||
}
|
||||
float3 GetNormal()
|
||||
{
|
||||
const uint normal_wind = bindless_buffers[GetMesh().vb_pos_nor_wind].Load<uint4>(vertexID * sizeof(uint4)).w;
|
||||
float3 normal;
|
||||
normal.x = (float)((normal_wind >> 0u) & 0xFF) / 255.0 * 2 - 1;
|
||||
normal.y = (float)((normal_wind >> 8u) & 0xFF) / 255.0 * 2 - 1;
|
||||
normal.z = (float)((normal_wind >> 16u) & 0xFF) / 255.0 * 2 - 1;
|
||||
return normal;
|
||||
}
|
||||
float GetWindWeight()
|
||||
{
|
||||
const uint normal_wind = bindless_buffers[GetMesh().vb_pos_nor_wind].Load<uint4>(vertexID * sizeof(uint4)).w;
|
||||
return ((normal_wind >> 24u) & 0xFF) / 255.0;
|
||||
return bindless_buffers_float4[GetMesh().vb_pos_nor_wind][vertexID];
|
||||
}
|
||||
|
||||
float4 GetUVSets()
|
||||
@@ -145,7 +131,7 @@ struct VertexInput
|
||||
[branch]
|
||||
if (GetMesh().vb_uvs < 0)
|
||||
return 0;
|
||||
return unpack_half4(bindless_buffers[GetMesh().vb_uvs].Load2(vertexID * sizeof(uint2)));
|
||||
return bindless_buffers_float4[GetMesh().vb_uvs][vertexID];
|
||||
}
|
||||
|
||||
ShaderMeshInstancePointer GetInstancePointer()
|
||||
@@ -163,7 +149,7 @@ struct VertexInput
|
||||
[branch]
|
||||
if (GetMesh().vb_atl < 0)
|
||||
return 0;
|
||||
return unpack_half2(bindless_buffers[GetMesh().vb_atl].Load(vertexID * sizeof(uint)));
|
||||
return bindless_buffers_float2[GetMesh().vb_atl][vertexID];
|
||||
}
|
||||
|
||||
float4 GetVertexColor()
|
||||
@@ -171,7 +157,7 @@ struct VertexInput
|
||||
[branch]
|
||||
if (GetMesh().vb_col < 0)
|
||||
return 1;
|
||||
return unpack_rgba(bindless_buffers[GetMesh().vb_col].Load(vertexID * sizeof(uint)));
|
||||
return bindless_buffers_float4[GetMesh().vb_col][vertexID];
|
||||
}
|
||||
|
||||
float4 GetTangent()
|
||||
@@ -179,7 +165,7 @@ struct VertexInput
|
||||
[branch]
|
||||
if (GetMesh().vb_tan < 0)
|
||||
return 0;
|
||||
return unpack_utangent(bindless_buffers[GetMesh().vb_tan].Load(vertexID * sizeof(uint))) * 2 - 1;
|
||||
return bindless_buffers_float4[GetMesh().vb_tan][vertexID];
|
||||
}
|
||||
|
||||
ShaderMeshInstance GetInstance()
|
||||
@@ -206,7 +192,10 @@ struct VertexSurface
|
||||
|
||||
inline void create(in ShaderMaterial material, in VertexInput input)
|
||||
{
|
||||
position = input.GetPosition();
|
||||
float4 pos_nor_wind = input.GetPositionNormalWind();
|
||||
uint normal_wind = asuint(pos_nor_wind.w);
|
||||
position = float4(pos_nor_wind.xyz, 1);
|
||||
normal = unpack_unitvector(normal_wind);
|
||||
color = GetMaterial().baseColor * unpack_rgba(input.GetInstance().color);
|
||||
color.a *= 1 - input.GetInstancePointer().GetDither();
|
||||
emissiveColor = input.GetInstance().emissive;
|
||||
@@ -217,7 +206,7 @@ struct VertexSurface
|
||||
color *= input.GetVertexColor();
|
||||
}
|
||||
|
||||
normal = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), input.GetNormal()));
|
||||
normal = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), normal));
|
||||
|
||||
tangent = input.GetTangent();
|
||||
tangent.xyz = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), tangent.xyz));
|
||||
@@ -233,7 +222,7 @@ struct VertexSurface
|
||||
[branch]
|
||||
if (material.IsUsingWind())
|
||||
{
|
||||
position.xyz += compute_wind(position.xyz, input.GetWindWeight());
|
||||
position.xyz += compute_wind(position.xyz, ((normal_wind >> 24u) & 0xFF) / 255.0);
|
||||
}
|
||||
#endif // DISABLE_WIND
|
||||
}
|
||||
|
||||
@@ -10,35 +10,18 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
|
||||
[branch]
|
||||
if (push.vb_pos_nor_wind < 0 || vertexID >= push.vertexCount)
|
||||
return;
|
||||
|
||||
const uint fetchAddress_POS_NOR = vertexID * sizeof(float4);
|
||||
const uint fetchAddress_TAN = vertexID * sizeof(uint);
|
||||
const uint fetchAddress_BON = vertexID * sizeof(uint4);
|
||||
|
||||
// Manual type-conversion for pos:
|
||||
uint4 pos_nor_u = bindless_buffers[push.vb_pos_nor_wind].Load4(fetchAddress_POS_NOR);
|
||||
float3 pos = asfloat(pos_nor_u.xyz);
|
||||
|
||||
// Manual type-conversion for normal:
|
||||
|
||||
float4 pos_nor_wind = bindless_buffers_float4[push.vb_pos_nor_wind][vertexID];
|
||||
uint nor_wind = asuint(pos_nor_wind.w);
|
||||
|
||||
float3 pos = pos_nor_wind.xyz;
|
||||
float4 nor = 0;
|
||||
{
|
||||
nor.x = (float)((pos_nor_u.w >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.y = (float)((pos_nor_u.w >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.z = (float)((pos_nor_u.w >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.w = (float)((pos_nor_u.w >> 24) & 0x000000FF) / 255.0f; // wind
|
||||
}
|
||||
|
||||
// Manual type-conversion for tangent:
|
||||
float4 tan = 0;
|
||||
[branch]
|
||||
if (push.vb_tan >= 0)
|
||||
{
|
||||
uint vtan = bindless_buffers[push.vb_tan].Load(fetchAddress_TAN);
|
||||
tan.x = (float)((vtan >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
tan.y = (float)((vtan >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
tan.z = (float)((vtan >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
tan.w = (float)((vtan >> 24) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
}
|
||||
nor.x = (float)((nor_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.y = (float)((nor_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.z = (float)((nor_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor.w = (float)((nor_wind >> 24) & 0x000000FF) / 255.0f; // wind
|
||||
|
||||
float4 tan = bindless_buffers_float4[push.vb_tan][vertexID];
|
||||
|
||||
ByteAddressBuffer skinningbuffer = bindless_buffers[push.skinningbuffer_index];
|
||||
|
||||
@@ -46,17 +29,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
|
||||
[branch]
|
||||
if (push.morph_count > 0)
|
||||
{
|
||||
ByteAddressBuffer morphvb = bindless_buffers[push.morphvb_index];
|
||||
Buffer<float4> morphvb = bindless_buffers_float4[push.morphvb_index];
|
||||
for (uint morph_index = 0; morph_index < push.morph_count; ++morph_index)
|
||||
{
|
||||
MorphTargetGPU morph = skinningbuffer.Load<MorphTargetGPU>(push.morph_offset + morph_index * sizeof(MorphTargetGPU));
|
||||
if (morph.offset_pos != ~0u)
|
||||
{
|
||||
pos += unpack_half3(morphvb.Load<uint2>(morph.offset_pos + vertexID * sizeof(uint2))) * morph.weight;
|
||||
pos += morphvb[morph.offset_pos + vertexID].xyz * morph.weight;
|
||||
}
|
||||
if (morph.offset_nor != ~0u)
|
||||
{
|
||||
nor.xyz += unpack_half3(morphvb.Load<uint2>(morph.offset_nor + vertexID * sizeof(uint2))) * morph.weight;
|
||||
nor.xyz += morphvb[morph.offset_nor + vertexID].xyz * morph.weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,17 +54,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
|
||||
if (push.vb_bon >= 0)
|
||||
{
|
||||
// Manual type-conversion for bone props:
|
||||
uint4 ind_wei_u = bindless_buffers[push.vb_bon].Load4(fetchAddress_BON);
|
||||
uint4 ind_wei_u = bindless_buffers[push.vb_bon].Load4(vertexID * sizeof(uint4));
|
||||
|
||||
ind.x = (ind_wei_u.x >> 0) & 0x0000FFFF;
|
||||
ind.y = (ind_wei_u.x >> 16) & 0x0000FFFF;
|
||||
ind.z = (ind_wei_u.y >> 0) & 0x0000FFFF;
|
||||
ind.w = (ind_wei_u.y >> 16) & 0x0000FFFF;
|
||||
ind.x = (ind_wei_u.x >> 0) & 0xFFFF;
|
||||
ind.y = (ind_wei_u.x >> 16) & 0xFFFF;
|
||||
ind.z = (ind_wei_u.y >> 0) & 0xFFFF;
|
||||
ind.w = (ind_wei_u.y >> 16) & 0xFFFF;
|
||||
|
||||
wei.x = (float)((ind_wei_u.z >> 0) & 0x0000FFFF) / 65535.0f;
|
||||
wei.y = (float)((ind_wei_u.z >> 16) & 0x0000FFFF) / 65535.0f;
|
||||
wei.z = (float)((ind_wei_u.w >> 0) & 0x0000FFFF) / 65535.0f;
|
||||
wei.w = (float)((ind_wei_u.w >> 16) & 0x0000FFFF) / 65535.0f;
|
||||
wei.x = float((ind_wei_u.z >> 0) & 0xFFFF) / 65535.0f;
|
||||
wei.y = float((ind_wei_u.z >> 16) & 0xFFFF) / 65535.0f;
|
||||
wei.z = float((ind_wei_u.w >> 0) & 0xFFFF) / 65535.0f;
|
||||
wei.w = float((ind_wei_u.w >> 16) & 0xFFFF) / 65535.0f;
|
||||
}
|
||||
if (any(wei))
|
||||
{
|
||||
@@ -89,10 +72,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
|
||||
float3 n = 0;
|
||||
float3 t = 0;
|
||||
float weisum = 0;
|
||||
|
||||
// force loop to reduce register pressure
|
||||
// also enabled early-exit
|
||||
[loop]
|
||||
|
||||
for (uint i = 0; ((i < 4) && (weisum < 1.0f)); ++i)
|
||||
{
|
||||
float4x4 m = skinningbuffer.Load<ShaderTransform>(push.bone_offset + ind[i] * sizeof(ShaderTransform)).GetMatrix();
|
||||
@@ -114,23 +94,18 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
|
||||
[branch]
|
||||
if (push.so_pos_nor_wind >= 0)
|
||||
{
|
||||
pos_nor_u.xyz = asuint(pos.xyz);
|
||||
pos_nor_u.w = 0;
|
||||
pos_nor_u.w |= (uint)((nor.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
pos_nor_u.w |= (uint)((nor.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
pos_nor_u.w |= (uint)((nor.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
pos_nor_u.w |= (uint)(nor.w * 255.0f) << 24; // wind
|
||||
bindless_rwbuffers[push.so_pos_nor_wind].Store4(fetchAddress_POS_NOR, pos_nor_u);
|
||||
uint nor_wind = 0;
|
||||
nor_wind |= uint((nor.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
nor_wind |= uint((nor.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
nor_wind |= uint((nor.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
nor_wind |= uint(nor.w * 255.0f) << 24; // wind
|
||||
pos_nor_wind = float4(pos.xyz, asfloat(nor_wind));
|
||||
bindless_rwbuffers_float4[push.so_pos_nor_wind][vertexID] = pos_nor_wind;
|
||||
}
|
||||
|
||||
[branch]
|
||||
if (push.so_tan >= 0)
|
||||
{
|
||||
uint vtan = 0;
|
||||
vtan |= (uint)((tan.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
vtan |= (uint)((tan.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
vtan |= (uint)((tan.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
vtan |= (uint)((tan.w * 0.5f + 0.5f) * 255.0f) << 24;
|
||||
bindless_rwbuffers[push.so_tan].Store(fetchAddress_TAN, vtan);
|
||||
bindless_rwbuffers_float4[push.so_tan][vertexID] = tan;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,9 +288,9 @@ struct Surface
|
||||
uint i0;
|
||||
uint i1;
|
||||
uint i2;
|
||||
uint4 data0;
|
||||
uint4 data1;
|
||||
uint4 data2;
|
||||
float4 data0;
|
||||
float4 data1;
|
||||
float4 data2;
|
||||
float3 pre;
|
||||
|
||||
bool preload_internal(PrimitiveID prim)
|
||||
@@ -309,15 +309,15 @@ struct Surface
|
||||
layerMask = material.layerMask & inst.layerMask;
|
||||
|
||||
const uint startIndex = prim.primitiveIndex * 3 + geometry.indexOffset;
|
||||
Buffer<uint> indexBuffer = bindless_ib[NonUniformResourceIndex(geometry.ib)];
|
||||
Buffer<uint> indexBuffer = bindless_buffers_uint[NonUniformResourceIndex(geometry.ib)];
|
||||
i0 = indexBuffer[startIndex + 0];
|
||||
i1 = indexBuffer[startIndex + 1];
|
||||
i2 = indexBuffer[startIndex + 2];
|
||||
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_pos_nor_wind)];
|
||||
data0 = buf.Load4(i0 * sizeof(uint4));
|
||||
data1 = buf.Load4(i1 * sizeof(uint4));
|
||||
data2 = buf.Load4(i2 * sizeof(uint4));
|
||||
Buffer<float4> buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_pos_nor_wind)];
|
||||
data0 = buf[i0];
|
||||
data1 = buf[i1];
|
||||
data2 = buf[i2];
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -329,9 +329,9 @@ struct Surface
|
||||
const bool is_emittedparticle = geometry.flags & SHADERMESH_FLAG_EMITTEDPARTICLE;
|
||||
const bool simple_lighting = is_hairparticle || is_emittedparticle;
|
||||
|
||||
float3 n0 = unpack_unitvector(data0.w);
|
||||
float3 n1 = unpack_unitvector(data1.w);
|
||||
float3 n2 = unpack_unitvector(data2.w);
|
||||
float3 n0 = unpack_unitvector(asuint(data0.w));
|
||||
float3 n1 = unpack_unitvector(asuint(data1.w));
|
||||
float3 n2 = unpack_unitvector(asuint(data2.w));
|
||||
N = attribute_at_bary(n0, n1, n2, bary);
|
||||
N = mul((float3x3)inst.transformInverseTranspose.GetMatrix(), N);
|
||||
N = normalize(N);
|
||||
@@ -342,9 +342,9 @@ struct Surface
|
||||
facenormal = N;
|
||||
|
||||
#ifdef SURFACE_LOAD_MIPCONE
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
float3 p0 = data0.xyz;
|
||||
float3 p1 = data1.xyz;
|
||||
float3 p2 = data2.xyz;
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz;
|
||||
float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz;
|
||||
@@ -363,10 +363,10 @@ struct Surface
|
||||
[branch]
|
||||
if (geometry.vb_uvs >= 0)
|
||||
{
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_uvs)];
|
||||
float4 uv0 = unpack_half4(buf.Load2(i0 * sizeof(uint2)));
|
||||
float4 uv1 = unpack_half4(buf.Load2(i1 * sizeof(uint2)));
|
||||
float4 uv2 = unpack_half4(buf.Load2(i2 * sizeof(uint2)));
|
||||
Buffer<float4> buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_uvs)];
|
||||
float4 uv0 = buf[i0];
|
||||
float4 uv1 = buf[i1];
|
||||
float4 uv2 = buf[i2];
|
||||
// all three must be transformed, to have correct derivatives (not enough to only transform final uvsets):
|
||||
uv0.xy = mad(uv0.xy, material.texMulAdd.xy, material.texMulAdd.zw);
|
||||
uv1.xy = mad(uv1.xy, material.texMulAdd.xy, material.texMulAdd.zw);
|
||||
@@ -387,12 +387,11 @@ struct Surface
|
||||
[branch]
|
||||
if (geometry.vb_tan >= 0)
|
||||
{
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_tan)];
|
||||
const float4 t0 = unpack_utangent(buf.Load(i0 * sizeof(uint)));
|
||||
const float4 t1 = unpack_utangent(buf.Load(i1 * sizeof(uint)));
|
||||
const float4 t2 = unpack_utangent(buf.Load(i2 * sizeof(uint)));
|
||||
Buffer<float4> buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_tan)];
|
||||
const float4 t0 = buf[i0];
|
||||
const float4 t1 = buf[i1];
|
||||
const float4 t2 = buf[i2];
|
||||
T = attribute_at_bary(t0, t1, t2, bary);
|
||||
T = T * 2 - 1;
|
||||
T.xyz = mul((float3x3)inst.transformInverseTranspose.GetMatrix(), T.xyz);
|
||||
T.xyz = normalize(T.xyz);
|
||||
B = normalize(cross(T.xyz, N) * T.w);
|
||||
@@ -491,10 +490,10 @@ struct Surface
|
||||
[branch]
|
||||
if (geometry.vb_col >= 0 && material.IsUsingVertexColors())
|
||||
{
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_col)];
|
||||
const float4 c0 = unpack_rgba(buf.Load(i0 * sizeof(uint)));
|
||||
const float4 c1 = unpack_rgba(buf.Load(i1 * sizeof(uint)));
|
||||
const float4 c2 = unpack_rgba(buf.Load(i2 * sizeof(uint)));
|
||||
Buffer<float4> buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_col)];
|
||||
const float4 c0 = buf[i0];
|
||||
const float4 c1 = buf[i1];
|
||||
const float4 c2 = buf[i2];
|
||||
float4 vertexColor = attribute_at_bary(c0, c1, c2, bary);
|
||||
baseColor *= vertexColor;
|
||||
}
|
||||
@@ -502,10 +501,10 @@ struct Surface
|
||||
[branch]
|
||||
if (inst.lightmap >= 0 && geometry.vb_atl >= 0)
|
||||
{
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_atl)];
|
||||
const float2 a0 = unpack_half2(buf.Load(i0 * sizeof(uint)));
|
||||
const float2 a1 = unpack_half2(buf.Load(i1 * sizeof(uint)));
|
||||
const float2 a2 = unpack_half2(buf.Load(i2 * sizeof(uint)));
|
||||
Buffer<float2> buf = bindless_buffers_float2[NonUniformResourceIndex(geometry.vb_atl)];
|
||||
const float2 a0 = buf[i0];
|
||||
const float2 a1 = buf[i1];
|
||||
const float2 a2 = buf[i2];
|
||||
float2 atlas = attribute_at_bary(a0, a1, a2, bary);
|
||||
|
||||
Texture2D<float4> tex = bindless_textures[NonUniformResourceIndex(inst.lightmap)];
|
||||
@@ -826,16 +825,16 @@ struct Surface
|
||||
[branch]
|
||||
if (geometry.vb_pre >= 0)
|
||||
{
|
||||
ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_pre)];
|
||||
pre0 = asfloat(buf.Load3(i0 * sizeof(uint4)));
|
||||
pre1 = asfloat(buf.Load3(i1 * sizeof(uint4)));
|
||||
pre2 = asfloat(buf.Load3(i2 * sizeof(uint4)));
|
||||
Buffer<float4> buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_pre)];
|
||||
pre0 = buf[i0].xyz;
|
||||
pre1 = buf[i1].xyz;
|
||||
pre2 = buf[i2].xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
pre0 = asfloat(data0.xyz);
|
||||
pre1 = asfloat(data1.xyz);
|
||||
pre2 = asfloat(data2.xyz);
|
||||
pre0 = data0.xyz;
|
||||
pre1 = data1.xyz;
|
||||
pre2 = data2.xyz;
|
||||
}
|
||||
pre = attribute_at_bary(pre0, pre1, pre2, bary);
|
||||
pre = mul(inst.transformPrev.GetMatrix(), float4(pre, 1)).xyz;
|
||||
@@ -850,9 +849,9 @@ struct Surface
|
||||
|
||||
bary = barycentrics;
|
||||
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
float3 p0 = data0.xyz;
|
||||
float3 p1 = data1.xyz;
|
||||
float3 p2 = data2.xyz;
|
||||
|
||||
#ifdef SURFACE_LOAD_QUAD_DERIVATIVES
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
@@ -874,9 +873,9 @@ struct Surface
|
||||
if (!preload_internal(prim))
|
||||
return false;
|
||||
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
float3 p0 = data0.xyz;
|
||||
float3 p1 = data1.xyz;
|
||||
float3 p2 = data2.xyz;
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz;
|
||||
float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz;
|
||||
@@ -892,9 +891,9 @@ struct Surface
|
||||
if (!preload_internal(prim))
|
||||
return false;
|
||||
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
float3 p0 = data0.xyz;
|
||||
float3 p1 = data1.xyz;
|
||||
float3 p2 = data2.xyz;
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz;
|
||||
float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz;
|
||||
@@ -903,9 +902,9 @@ struct Surface
|
||||
[branch]
|
||||
if (material.IsUsingWind())
|
||||
{
|
||||
float wind0 = ((data0.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind1 = ((data1.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind2 = ((data2.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind0 = ((asuint(data0.w) >> 24u) & 0xFF) / 255.0;
|
||||
float wind1 = ((asuint(data1.w) >> 24u) & 0xFF) / 255.0;
|
||||
float wind2 = ((asuint(data2.w) >> 24u) & 0xFF) / 255.0;
|
||||
|
||||
// this is hella slow to do per pixel:
|
||||
P0 += compute_wind(P0, wind0);
|
||||
@@ -938,9 +937,9 @@ struct Surface
|
||||
if (!preload_internal(prim))
|
||||
return false;
|
||||
|
||||
float3 p0 = asfloat(data0.xyz);
|
||||
float3 p1 = asfloat(data1.xyz);
|
||||
float3 p2 = asfloat(data2.xyz);
|
||||
float3 p0 = data0.xyz;
|
||||
float3 p1 = data1.xyz;
|
||||
float3 p2 = data2.xyz;
|
||||
float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz;
|
||||
float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz;
|
||||
float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz;
|
||||
@@ -949,9 +948,9 @@ struct Surface
|
||||
[branch]
|
||||
if (material.IsUsingWind())
|
||||
{
|
||||
float wind0 = ((data0.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind1 = ((data1.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind2 = ((data2.w >> 24u) & 0xFF) / 255.0;
|
||||
float wind0 = ((asuint(data0.w) >> 24u) & 0xFF) / 255.0;
|
||||
float wind1 = ((asuint(data1.w) >> 24u) & 0xFF) / 255.0;
|
||||
float wind2 = ((asuint(data2.w) >> 24u) & 0xFF) / 255.0;
|
||||
|
||||
// this is hella slow to do per pixel:
|
||||
P0 += compute_wind(P0, wind0);
|
||||
|
||||
@@ -63,22 +63,38 @@ float4x4 saturationMatrix(float saturation)
|
||||
[RootSignature(
|
||||
"RootConstants(num32BitConstants=16, b999),"
|
||||
"DescriptorTable( "
|
||||
"SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)"
|
||||
"SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)"
|
||||
"), "
|
||||
"StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)"
|
||||
)]
|
||||
|
||||
@@ -121,22 +121,22 @@ namespace wi
|
||||
|
||||
vb_pos.offset = buffer_offset;
|
||||
buffer_offset += AlignTo(vb_pos.size, alignment);
|
||||
vb_pos.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos.offset, vb_pos.size);
|
||||
vb_pos.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos.offset, vb_pos.size);
|
||||
vb_pos.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos.offset, vb_pos.size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos.offset, vb_pos.size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos.subresource_srv);
|
||||
vb_pos.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos.subresource_uav);
|
||||
|
||||
vb_uvs.offset = buffer_offset;
|
||||
buffer_offset += AlignTo(vb_uvs.size, alignment);
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size);
|
||||
vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size);
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT);
|
||||
vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT);
|
||||
vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv);
|
||||
vb_uvs.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_uvs.subresource_uav);
|
||||
|
||||
vb_col.offset = buffer_offset;
|
||||
buffer_offset += AlignTo(vb_col.size, alignment);
|
||||
vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size);
|
||||
vb_col.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_col.offset, vb_col.size);
|
||||
vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size, &MeshComponent::Vertex_COL::FORMAT);
|
||||
vb_col.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_col.offset, vb_col.size, &MeshComponent::Vertex_COL::FORMAT);
|
||||
vb_col.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_col.subresource_srv);
|
||||
vb_col.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_col.subresource_uav);
|
||||
|
||||
@@ -365,8 +365,7 @@ namespace wi
|
||||
cb.xEmitterTransform.Create(transform.world);
|
||||
cb.xEmitCount = (uint32_t)emit;
|
||||
cb.xEmitterMeshIndexCount = mesh == nullptr ? 0 : (uint32_t)mesh->indices.size();
|
||||
cb.xEmitterMeshVertexPositionStride = sizeof(MeshComponent::Vertex_POS);
|
||||
cb.xEmitterRandomness = wi::random::GetRandom(0, 1000) * 0.001f;
|
||||
cb.xEmitterRandomness = wi::random::GetRandom(0.0f, 1.0f);
|
||||
cb.xParticleLifeSpan = life;
|
||||
cb.xParticleLifeSpanRandomness = random_life;
|
||||
cb.xParticleNormalFactor = normal_factor;
|
||||
|
||||
@@ -363,9 +363,9 @@ namespace vulkan_internal
|
||||
switch (value)
|
||||
{
|
||||
case ShaderStage::MS:
|
||||
return VK_SHADER_STAGE_MESH_BIT_NV;
|
||||
return VK_SHADER_STAGE_MESH_BIT_EXT;
|
||||
case ShaderStage::AS:
|
||||
return VK_SHADER_STAGE_TASK_BIT_NV;
|
||||
return VK_SHADER_STAGE_TASK_BIT_EXT;
|
||||
case ShaderStage::VS:
|
||||
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
case ShaderStage::HS:
|
||||
@@ -3293,8 +3293,12 @@ using namespace vulkan_internal;
|
||||
pso_dynamicStates.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE);
|
||||
|
||||
dynamicStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicStateInfo.dynamicStateCount = (uint32_t)pso_dynamicStates.size();
|
||||
dynamicStateInfo.pDynamicStates = pso_dynamicStates.data();
|
||||
dynamicStateInfo.dynamicStateCount = (uint32_t)pso_dynamicStates.size();
|
||||
|
||||
dynamicStateInfo_MeshShader.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicStateInfo_MeshShader.pDynamicStates = pso_dynamicStates.data();
|
||||
dynamicStateInfo_MeshShader.dynamicStateCount = (uint32_t)pso_dynamicStates.size() - 1; // don't include VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE for mesh shader
|
||||
|
||||
// Note: limiting descriptors by constant amount is needed, because the bindless sets are bound to multiple slots to match DX12 layout
|
||||
// And binding to multiple slot adds up towards limits, so the limits will be quickly reached for some descriptor types
|
||||
@@ -4474,10 +4478,10 @@ using namespace vulkan_internal;
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::MS:
|
||||
internal_state->stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_NV;
|
||||
internal_state->stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT;
|
||||
break;
|
||||
case ShaderStage::AS:
|
||||
internal_state->stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_NV;
|
||||
internal_state->stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT;
|
||||
break;
|
||||
case ShaderStage::VS:
|
||||
internal_state->stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
@@ -4538,6 +4542,8 @@ using namespace vulkan_internal;
|
||||
|
||||
for (auto& x : bindings)
|
||||
{
|
||||
if (x->accessed == 0)
|
||||
continue;
|
||||
const bool bindless = x->set > 0;
|
||||
|
||||
if (bindless)
|
||||
@@ -4554,9 +4560,7 @@ using namespace vulkan_internal;
|
||||
descriptor.descriptorType = (VkDescriptorType)x->descriptor_type;
|
||||
|
||||
if (bindless)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& imageViewType = internal_state->imageViewTypes.emplace_back();
|
||||
imageViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||
@@ -5504,7 +5508,14 @@ using namespace vulkan_internal;
|
||||
|
||||
pipelineInfo.pTessellationState = &tessellationInfo;
|
||||
|
||||
pipelineInfo.pDynamicState = &dynamicStateInfo;
|
||||
if (pso->desc.ms == nullptr)
|
||||
{
|
||||
pipelineInfo.pDynamicState = &dynamicStateInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
pipelineInfo.pDynamicState = &dynamicStateInfo_MeshShader;
|
||||
}
|
||||
|
||||
if (renderpass_info != nullptr)
|
||||
{
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace wi::graphics
|
||||
|
||||
wi::vector<VkDynamicState> pso_dynamicStates;
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateInfo = {};
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateInfo_MeshShader = {};
|
||||
|
||||
VkBuffer nullBuffer = VK_NULL_HANDLE;
|
||||
VmaAllocation nullBufferAllocation = VK_NULL_HANDLE;
|
||||
|
||||
@@ -141,24 +141,24 @@ namespace wi
|
||||
|
||||
buffer_offset = AlignTo(buffer_offset, alignment);
|
||||
vb_pos[0].offset = buffer_offset;
|
||||
vb_pos[0].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[0].offset, vb_pos[0].size);
|
||||
vb_pos[0].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[0].offset, vb_pos[0].size);
|
||||
vb_pos[0].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[0].offset, vb_pos[0].size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos[0].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[0].offset, vb_pos[0].size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos[0].descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos[0].subresource_srv);
|
||||
vb_pos[0].descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos[0].subresource_uav);
|
||||
buffer_offset += vb_pos[0].size;
|
||||
|
||||
buffer_offset = AlignTo(buffer_offset, alignment);
|
||||
vb_pos[1].offset = buffer_offset;
|
||||
vb_pos[1].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[1].offset, vb_pos[1].size);
|
||||
vb_pos[1].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[1].offset, vb_pos[1].size);
|
||||
vb_pos[1].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[1].offset, vb_pos[1].size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos[1].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[1].offset, vb_pos[1].size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
vb_pos[1].descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos[1].subresource_srv);
|
||||
vb_pos[1].descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos[1].subresource_uav);
|
||||
buffer_offset += vb_pos[1].size;
|
||||
|
||||
buffer_offset = AlignTo(buffer_offset, alignment);
|
||||
vb_uvs.offset = buffer_offset;
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size);
|
||||
vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size);
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT);
|
||||
vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT);
|
||||
vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv);
|
||||
vb_uvs.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_uvs.subresource_uav);
|
||||
buffer_offset += vb_uvs.size;
|
||||
|
||||
@@ -4176,7 +4176,7 @@ void UpdateRenderData(
|
||||
{
|
||||
push.morph_count = mesh.active_morph_count;
|
||||
push.morph_offset = mesh.morphGPUOffset;
|
||||
push.morphvb_index = device->GetDescriptorIndex(&mesh.generalBuffer, SubresourceType::SRV);
|
||||
push.morphvb_index = mesh.vb_mor.descriptor_srv;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace wi::scene
|
||||
desc.stride = sizeof(ShaderMeshInstance);
|
||||
desc.size = desc.stride * instanceArraySize * 2; // *2 to grow fast
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_RAW;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED;
|
||||
if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA))
|
||||
{
|
||||
// Non-UMA: separate Default usage buffer
|
||||
@@ -99,7 +99,7 @@ namespace wi::scene
|
||||
desc.stride = sizeof(ShaderMaterial);
|
||||
desc.size = desc.stride * materialArraySize * 2; // *2 to grow fast
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_RAW;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED;
|
||||
if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA))
|
||||
{
|
||||
// Non-UMA: separate Default usage buffer
|
||||
@@ -253,7 +253,7 @@ namespace wi::scene
|
||||
desc.stride = sizeof(ShaderGeometry);
|
||||
desc.size = desc.stride * geometryArraySize * 2; // *2 to grow fast
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_RAW;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED;
|
||||
if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA))
|
||||
{
|
||||
// Non-UMA: separate Default usage buffer
|
||||
@@ -356,7 +356,7 @@ namespace wi::scene
|
||||
desc.stride = sizeof(ShaderMeshlet);
|
||||
desc.size = desc.stride * meshletCount * 2; // *2 to grow fast
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_RAW;
|
||||
desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED;
|
||||
bool success = device->CreateBuffer(&desc, nullptr, &meshletBuffer);
|
||||
assert(success);
|
||||
device->SetName(&meshletBuffer, "meshletBuffer");
|
||||
@@ -679,7 +679,7 @@ namespace wi::scene
|
||||
desc.size =
|
||||
AlignTo(AlignTo(sizeof(IndirectDrawArgsIndexedInstanced), alignment), sizeof(IndirectDrawArgsIndexedInstanced)) + // indirect args, additional structured buffer alignment
|
||||
AlignTo(allocated_impostor_capacity * sizeof(uint) * 6, alignment) + // indices (must overestimate here for 32-bit indices, because we create 16 bit and 32 bit descriptors)
|
||||
AlignTo(allocated_impostor_capacity * sizeof(uint4) * 4, alignment) + // vertices
|
||||
AlignTo(allocated_impostor_capacity * sizeof(MeshComponent::Vertex_POS) * 4, alignment) + // vertices
|
||||
AlignTo(allocated_impostor_capacity * sizeof(uint2), alignment) // impostordata
|
||||
;
|
||||
device->CreateBuffer(&desc, nullptr, &impostorBuffer);
|
||||
@@ -715,9 +715,9 @@ namespace wi::scene
|
||||
|
||||
buffer_offset = AlignTo(buffer_offset, alignment);
|
||||
impostor_vb.offset = buffer_offset;
|
||||
impostor_vb.size = allocated_impostor_capacity * sizeof(uint4) * 4;
|
||||
impostor_vb.subresource_srv = device->CreateSubresource(&impostorBuffer, SubresourceType::SRV, impostor_vb.offset, impostor_vb.size);
|
||||
impostor_vb.subresource_uav = device->CreateSubresource(&impostorBuffer, SubresourceType::UAV, impostor_vb.offset, impostor_vb.size);
|
||||
impostor_vb.size = allocated_impostor_capacity * sizeof(MeshComponent::Vertex_POS) * 4;
|
||||
impostor_vb.subresource_srv = device->CreateSubresource(&impostorBuffer, SubresourceType::SRV, impostor_vb.offset, impostor_vb.size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
impostor_vb.subresource_uav = device->CreateSubresource(&impostorBuffer, SubresourceType::UAV, impostor_vb.offset, impostor_vb.size, &MeshComponent::Vertex_POS::FORMAT);
|
||||
impostor_vb.descriptor_srv = device->GetDescriptorIndex(&impostorBuffer, SubresourceType::SRV, impostor_vb.subresource_srv);
|
||||
impostor_vb.descriptor_uav = device->GetDescriptorIndex(&impostorBuffer, SubresourceType::UAV, impostor_vb.subresource_uav);
|
||||
buffer_offset += impostor_vb.size;
|
||||
|
||||
@@ -579,15 +579,17 @@ namespace wi::scene
|
||||
AlignTo(vertex_boneindices.size() * sizeof(Vertex_BON), alignment)
|
||||
;
|
||||
|
||||
constexpr Format morph_format = Format::R16G16B16A16_FLOAT;
|
||||
constexpr size_t morph_stride = GetFormatStride(morph_format);
|
||||
for (MorphTarget& morph : morph_targets)
|
||||
{
|
||||
if (!morph.vertex_positions.empty())
|
||||
{
|
||||
bd.size += AlignTo(vertex_positions.size() * sizeof(XMHALF4), alignment);
|
||||
bd.size += AlignTo(vertex_positions.size() * morph_stride, alignment);
|
||||
}
|
||||
if (!morph.vertex_normals.empty())
|
||||
{
|
||||
bd.size += AlignTo(vertex_normals.size() * sizeof(XMHALF4), alignment);
|
||||
bd.size += AlignTo(vertex_normals.size() * morph_stride, alignment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,11 +737,12 @@ namespace wi::scene
|
||||
// morph buffers:
|
||||
if (!morph_targets.empty())
|
||||
{
|
||||
vb_mor.offset = buffer_offset;
|
||||
for (MorphTarget& morph : morph_targets)
|
||||
{
|
||||
if (!morph.vertex_positions.empty())
|
||||
{
|
||||
morph.offset_pos = buffer_offset;
|
||||
morph.offset_pos = (buffer_offset - vb_mor.offset) / morph_stride;
|
||||
XMHALF4* vertices = (XMHALF4*)(buffer_data + buffer_offset);
|
||||
std::fill(vertices, vertices + vertex_positions.size(), 0);
|
||||
if (morph.sparse_indices_positions.empty())
|
||||
@@ -763,7 +766,7 @@ namespace wi::scene
|
||||
}
|
||||
if (!morph.vertex_normals.empty())
|
||||
{
|
||||
morph.offset_nor = buffer_offset;
|
||||
morph.offset_nor = (buffer_offset - vb_mor.offset) / morph_stride;
|
||||
XMHALF4* vertices = (XMHALF4*)(buffer_data + buffer_offset);
|
||||
std::fill(vertices, vertices + vertex_normals.size(), 0);
|
||||
if (morph.sparse_indices_normals.empty())
|
||||
@@ -786,6 +789,7 @@ namespace wi::scene
|
||||
buffer_offset += AlignTo(morph.vertex_normals.size() * sizeof(XMHALF4), alignment);
|
||||
}
|
||||
}
|
||||
vb_mor.size = buffer_offset - vb_mor.offset;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -799,27 +803,27 @@ namespace wi::scene
|
||||
ib.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, ib.subresource_srv);
|
||||
|
||||
assert(vb_pos_nor_wind.IsValid());
|
||||
vb_pos_nor_wind.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.offset, vb_pos_nor_wind.size);
|
||||
vb_pos_nor_wind.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.offset, vb_pos_nor_wind.size, &Vertex_POS::FORMAT);
|
||||
vb_pos_nor_wind.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.subresource_srv);
|
||||
|
||||
if (vb_tan.IsValid())
|
||||
{
|
||||
vb_tan.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_tan.offset, vb_tan.size);
|
||||
vb_tan.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_tan.offset, vb_tan.size, &Vertex_TAN::FORMAT);
|
||||
vb_tan.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_tan.subresource_srv);
|
||||
}
|
||||
if (vb_uvs.IsValid())
|
||||
{
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size);
|
||||
vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &Vertex_UVS::FORMAT);
|
||||
vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv);
|
||||
}
|
||||
if (vb_atl.IsValid())
|
||||
{
|
||||
vb_atl.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_atl.offset, vb_atl.size);
|
||||
vb_atl.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_atl.offset, vb_atl.size, &Vertex_TEX::FORMAT);
|
||||
vb_atl.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_atl.subresource_srv);
|
||||
}
|
||||
if (vb_col.IsValid())
|
||||
{
|
||||
vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size);
|
||||
vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size, &Vertex_COL::FORMAT);
|
||||
vb_col.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_col.subresource_srv);
|
||||
}
|
||||
if (vb_bon.IsValid())
|
||||
@@ -827,6 +831,11 @@ namespace wi::scene
|
||||
vb_bon.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_bon.offset, vb_bon.size);
|
||||
vb_bon.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_bon.subresource_srv);
|
||||
}
|
||||
if (vb_mor.IsValid())
|
||||
{
|
||||
vb_mor.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_mor.offset, vb_mor.size, &morph_format);
|
||||
vb_mor.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_mor.subresource_srv);
|
||||
}
|
||||
|
||||
if (!vertex_boneindices.empty() || !morph_targets.empty())
|
||||
{
|
||||
@@ -860,8 +869,8 @@ namespace wi::scene
|
||||
so_pos_nor_wind.offset = buffer_offset;
|
||||
so_pos_nor_wind.size = vb_pos_nor_wind.size;
|
||||
buffer_offset += AlignTo(so_pos_nor_wind.size, alignment);
|
||||
so_pos_nor_wind.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.offset, so_pos_nor_wind.size);
|
||||
so_pos_nor_wind.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.offset, so_pos_nor_wind.size);
|
||||
so_pos_nor_wind.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.offset, so_pos_nor_wind.size, &Vertex_POS::FORMAT);
|
||||
so_pos_nor_wind.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.offset, so_pos_nor_wind.size, &Vertex_POS::FORMAT);
|
||||
so_pos_nor_wind.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.subresource_srv);
|
||||
so_pos_nor_wind.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.subresource_uav);
|
||||
|
||||
@@ -870,8 +879,8 @@ namespace wi::scene
|
||||
so_tan.offset = buffer_offset;
|
||||
so_tan.size = vb_tan.size;
|
||||
buffer_offset += AlignTo(so_tan.size, alignment);
|
||||
so_tan.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_tan.offset, so_tan.size);
|
||||
so_tan.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_tan.offset, so_tan.size);
|
||||
so_tan.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_tan.offset, so_tan.size, &Vertex_TAN::FORMAT);
|
||||
so_tan.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_tan.offset, so_tan.size, &Vertex_TAN::FORMAT);
|
||||
so_tan.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_tan.subresource_srv);
|
||||
so_tan.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_tan.subresource_uav);
|
||||
}
|
||||
@@ -879,8 +888,8 @@ namespace wi::scene
|
||||
so_pre.offset = buffer_offset;
|
||||
so_pre.size = vb_pos_nor_wind.size;
|
||||
buffer_offset += AlignTo(so_pre.size, alignment);
|
||||
so_pre.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pre.offset, so_pre.size);
|
||||
so_pre.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pre.offset, so_pre.size);
|
||||
so_pre.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pre.offset, so_pre.size, &Vertex_POS::FORMAT);
|
||||
so_pre.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pre.offset, so_pre.size, &Vertex_POS::FORMAT);
|
||||
so_pre.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_pre.subresource_srv);
|
||||
so_pre.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_pre.subresource_uav);
|
||||
}
|
||||
|
||||
@@ -409,6 +409,7 @@ namespace wi::scene
|
||||
BufferView vb_atl;
|
||||
BufferView vb_col;
|
||||
BufferView vb_bon;
|
||||
BufferView vb_mor;
|
||||
BufferView so_pos_nor_wind;
|
||||
BufferView so_tan;
|
||||
BufferView so_pre;
|
||||
@@ -498,7 +499,7 @@ namespace wi::scene
|
||||
XMFLOAT3 pos = XMFLOAT3(0.0f, 0.0f, 0.0f);
|
||||
uint32_t normal_wind = 0;
|
||||
|
||||
void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint8_t wind)
|
||||
constexpr void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint8_t wind)
|
||||
{
|
||||
pos.x = _pos.x;
|
||||
pos.y = _pos.y;
|
||||
@@ -514,39 +515,37 @@ namespace wi::scene
|
||||
XMFLOAT3 N = GetNor_FULL();
|
||||
return XMLoadFloat3(&N);
|
||||
}
|
||||
inline void MakeFromParams(const XMFLOAT3& normal)
|
||||
constexpr void MakeFromParams(const XMFLOAT3& normal)
|
||||
{
|
||||
normal_wind = normal_wind & 0xFF000000; // reset only the normals
|
||||
|
||||
normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
normal_wind |= uint32_t((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
normal_wind |= uint32_t((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
normal_wind |= uint32_t((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
}
|
||||
inline void MakeFromParams(const XMFLOAT3& normal, uint8_t wind)
|
||||
constexpr void MakeFromParams(const XMFLOAT3& normal, uint8_t wind)
|
||||
{
|
||||
normal_wind = 0;
|
||||
|
||||
normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
normal_wind |= (uint32_t)wind << 24;
|
||||
normal_wind |= uint32_t((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
normal_wind |= uint32_t((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
normal_wind |= uint32_t((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
normal_wind |= uint32_t(wind) << 24;
|
||||
}
|
||||
inline XMFLOAT3 GetNor_FULL() const
|
||||
constexpr XMFLOAT3 GetNor_FULL() const
|
||||
{
|
||||
XMFLOAT3 nor_FULL(0, 0, 0);
|
||||
|
||||
nor_FULL.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor_FULL.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor_FULL.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
|
||||
nor_FULL.x = (float((normal_wind >> 0) & 0xFF) / 255.0f) * 2.0f - 1.0f;
|
||||
nor_FULL.y = (float((normal_wind >> 8) & 0xFF) / 255.0f) * 2.0f - 1.0f;
|
||||
nor_FULL.z = (float((normal_wind >> 16) & 0xFF) / 255.0f) * 2.0f - 1.0f;
|
||||
|
||||
return nor_FULL;
|
||||
}
|
||||
inline uint8_t GetWind() const
|
||||
constexpr uint8_t GetWind() const
|
||||
{
|
||||
return (normal_wind >> 24) & 0x000000FF;
|
||||
return (normal_wind >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
static const wi::graphics::Format FORMAT = wi::graphics::Format::R32G32B32A32_FLOAT;
|
||||
static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R32G32B32A32_FLOAT;
|
||||
};
|
||||
struct Vertex_TEX
|
||||
{
|
||||
@@ -557,64 +556,63 @@ namespace wi::scene
|
||||
tex = XMHALF2(texcoords.x, texcoords.y);
|
||||
}
|
||||
|
||||
static const wi::graphics::Format FORMAT = wi::graphics::Format::R16G16_FLOAT;
|
||||
static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R16G16_FLOAT;
|
||||
};
|
||||
struct Vertex_UVS
|
||||
{
|
||||
Vertex_TEX uv0;
|
||||
Vertex_TEX uv1;
|
||||
static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R16G16B16A16_FLOAT;
|
||||
};
|
||||
struct Vertex_BON
|
||||
{
|
||||
uint64_t ind = 0;
|
||||
uint64_t wei = 0;
|
||||
uint16_t ind0 = 0;
|
||||
uint16_t ind1 = 0;
|
||||
uint16_t ind2 = 0;
|
||||
uint16_t ind3 = 0;
|
||||
|
||||
void FromFULL(const XMUINT4& boneIndices, const XMFLOAT4& boneWeights)
|
||||
uint16_t wei0 = 0;
|
||||
uint16_t wei1 = 1;
|
||||
uint16_t wei2 = 2;
|
||||
uint16_t wei3 = 3;
|
||||
|
||||
constexpr void FromFULL(const XMUINT4& boneIndices, const XMFLOAT4& boneWeights)
|
||||
{
|
||||
ind = 0;
|
||||
wei = 0;
|
||||
ind0 = uint16_t(boneIndices.x);
|
||||
ind1 = uint16_t(boneIndices.y);
|
||||
ind2 = uint16_t(boneIndices.z);
|
||||
ind3 = uint16_t(boneIndices.w);
|
||||
|
||||
ind |= (uint64_t)boneIndices.x << 0;
|
||||
ind |= (uint64_t)boneIndices.y << 16;
|
||||
ind |= (uint64_t)boneIndices.z << 32;
|
||||
ind |= (uint64_t)boneIndices.w << 48;
|
||||
|
||||
wei |= (uint64_t)(boneWeights.x * 65535.0f) << 0;
|
||||
wei |= (uint64_t)(boneWeights.y * 65535.0f) << 16;
|
||||
wei |= (uint64_t)(boneWeights.z * 65535.0f) << 32;
|
||||
wei |= (uint64_t)(boneWeights.w * 65535.0f) << 48;
|
||||
wei0 = uint16_t(boneWeights.x * 65535.0f);
|
||||
wei1 = uint16_t(boneWeights.y * 65535.0f);
|
||||
wei2 = uint16_t(boneWeights.z * 65535.0f);
|
||||
wei3 = uint16_t(boneWeights.w * 65535.0f);
|
||||
}
|
||||
inline XMUINT4 GetInd_FULL() const
|
||||
constexpr XMUINT4 GetInd_FULL() const
|
||||
{
|
||||
XMUINT4 ind_FULL(0, 0, 0, 0);
|
||||
|
||||
ind_FULL.x = ((ind >> 0) & 0x0000FFFF);
|
||||
ind_FULL.y = ((ind >> 16) & 0x0000FFFF);
|
||||
ind_FULL.z = ((ind >> 32) & 0x0000FFFF);
|
||||
ind_FULL.w = ((ind >> 48) & 0x0000FFFF);
|
||||
|
||||
return ind_FULL;
|
||||
return XMUINT4(ind0, ind1, ind2, ind3);
|
||||
}
|
||||
inline XMFLOAT4 GetWei_FULL() const
|
||||
constexpr XMFLOAT4 GetWei_FULL() const
|
||||
{
|
||||
XMFLOAT4 wei_FULL(0, 0, 0, 0);
|
||||
|
||||
wei_FULL.x = (float)((wei >> 0) & 0x0000FFFF) / 65535.0f;
|
||||
wei_FULL.y = (float)((wei >> 16) & 0x0000FFFF) / 65535.0f;
|
||||
wei_FULL.z = (float)((wei >> 32) & 0x0000FFFF) / 65535.0f;
|
||||
wei_FULL.w = (float)((wei >> 48) & 0x0000FFFF) / 65535.0f;
|
||||
|
||||
return wei_FULL;
|
||||
return XMFLOAT4(
|
||||
float(wei0) / 65535.0f,
|
||||
float(wei1) / 65535.0f,
|
||||
float(wei2) / 65535.0f,
|
||||
float(wei3) / 65535.0f
|
||||
);
|
||||
}
|
||||
};
|
||||
struct Vertex_COL
|
||||
{
|
||||
uint32_t color = 0;
|
||||
static const wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM;
|
||||
static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM;
|
||||
};
|
||||
struct Vertex_TAN
|
||||
{
|
||||
uint32_t tangent = 0;
|
||||
int8_t x = 0;
|
||||
int8_t y = 0;
|
||||
int8_t z = 0;
|
||||
int8_t w = 0;
|
||||
|
||||
void FromFULL(const XMFLOAT4& tan)
|
||||
{
|
||||
@@ -623,14 +621,14 @@ namespace wi::scene
|
||||
XMFLOAT4 t;
|
||||
XMStoreFloat4(&t, T);
|
||||
t.w = tan.w;
|
||||
tangent = 0;
|
||||
tangent |= (uint)((t.x * 0.5f + 0.5f) * 255.0f) << 0;
|
||||
tangent |= (uint)((t.y * 0.5f + 0.5f) * 255.0f) << 8;
|
||||
tangent |= (uint)((t.z * 0.5f + 0.5f) * 255.0f) << 16;
|
||||
tangent |= (uint)((t.w * 0.5f + 0.5f) * 255.0f) << 24;
|
||||
|
||||
x = int8_t(t.x * 127.0f);
|
||||
y = int8_t(t.y * 127.0f);
|
||||
z = int8_t(t.z * 127.0f);
|
||||
w = int8_t(t.w * 127.0f);
|
||||
}
|
||||
|
||||
static const wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM;
|
||||
static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_SNORM;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 71;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 256;
|
||||
const int revision = 257;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user