移除Unity参考代码
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.HighDefinition;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
class NanoVolumeCustomPass : CustomPass
|
||||
{
|
||||
const int NANO_VOLUME_PASS_ID = 0;
|
||||
|
||||
public NanoVolumeLoader nanoVolumeLoaderComponent;
|
||||
public NanoVolumeSettings nanoVolumeSettings;
|
||||
|
||||
Material mat;
|
||||
|
||||
// To make sure the shader ends up in the build, we keep a reference to it
|
||||
[SerializeField, HideInInspector]
|
||||
Shader volumeShader;
|
||||
|
||||
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
|
||||
{
|
||||
volumeShader = Shader.Find("FullScreen/NanoVolumePass");
|
||||
mat = CoreUtils.CreateEngineMaterial(volumeShader);
|
||||
}
|
||||
|
||||
protected override void Execute(CustomPassContext ctx)
|
||||
{
|
||||
if (!nanoVolumeLoaderComponent.IsLoaded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetUniforms();
|
||||
|
||||
CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer, ClearFlag.Color);
|
||||
CoreUtils.DrawFullScreen(ctx.cmd, mat, ctx.propertyBlock, shaderPassId: NANO_VOLUME_PASS_ID);
|
||||
}
|
||||
|
||||
protected override void Cleanup()
|
||||
{
|
||||
CoreUtils.Destroy(mat);
|
||||
}
|
||||
|
||||
void SetUniforms()
|
||||
{
|
||||
mat.SetBuffer("buf", nanoVolumeLoaderComponent.GetGPUBuffer());
|
||||
mat.SetFloat("_ClipPlaneMin", 0.01f);
|
||||
mat.SetFloat("_ClipPlaneMax", 1500.0f);
|
||||
|
||||
mat.SetVector("_LightDir", nanoVolumeSettings.directionalLight.transform.forward);
|
||||
|
||||
mat.SetVector("_Light", nanoVolumeSettings.directionalLight.color);
|
||||
mat.SetVector("_Scattering", nanoVolumeSettings.scatteringColor);
|
||||
|
||||
mat.SetFloat("_DensityScale", nanoVolumeSettings.DensitySlider.value);
|
||||
mat.SetFloat("_LightAbsorbation", nanoVolumeSettings.LightAbsorbation.value);
|
||||
|
||||
mat.SetInt("_RayMarchSamples", (int)nanoVolumeSettings.RaymarchSamples.value);
|
||||
mat.SetInt("_LightSamples", (int)nanoVolumeSettings.LightSteps.value);
|
||||
|
||||
mat.SetInt("_VisualizeSteps", nanoVolumeSettings.visualizeSteps);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d93f84fcf6aa8704d91b42aced4fa025
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,42 +0,0 @@
|
||||
Shader "FullScreen/NanoVolumePass"
|
||||
{
|
||||
HLSLINCLUDE
|
||||
|
||||
#pragma vertex Vert
|
||||
|
||||
#pragma target 5.0
|
||||
#pragma use_dxc
|
||||
|
||||
// Commons, includes many others
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
|
||||
|
||||
#include "Assets/NanoVDB/PseudoRandom.hlsl"
|
||||
#include "Assets/NanoVDB/NanoVolumePass.hlsl"
|
||||
|
||||
float4 FullScreenPass(Varyings varyings) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
|
||||
float depth = LoadCameraDepth(varyings.positionCS.xy);
|
||||
PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
|
||||
float3 viewDirection = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
|
||||
|
||||
float4 color = NanoVolumePass(_WorldSpaceCameraPos, -viewDirection);
|
||||
return float4(color.rgb, color.a);
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags{ "RenderPipeline" = "HDRenderPipeline" }
|
||||
Pass
|
||||
{
|
||||
Name "Nano Volume Pass"
|
||||
ZWrite Off Cull Off Blend One OneMinusSrcAlpha
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma fragment FullScreenPass
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3e61447f8553dc419567904d4bede14
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,118 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
public class NanoVolumeLoader : MonoBehaviour
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private unsafe struct NanoVolume
|
||||
{
|
||||
public uint* buf;
|
||||
public ulong byteSize;
|
||||
public ulong elementCount;
|
||||
public ulong structStride;
|
||||
};
|
||||
unsafe NanoVolume* nanoVolume;
|
||||
|
||||
[Header("Assets/path/to/volume.nvdb")]
|
||||
|
||||
public string volumePath;
|
||||
|
||||
private ComputeBuffer gpuBuffer;
|
||||
private uint[] buf;
|
||||
private bool ok;
|
||||
private bool loaded = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
SetDebugLogCallback(DebugLogCallback);
|
||||
|
||||
ok = PrepareVolume();
|
||||
if (!ok) return;
|
||||
|
||||
unsafe
|
||||
{
|
||||
int bufferSize = (int)nanoVolume->elementCount;
|
||||
int stride = (int)nanoVolume->structStride;
|
||||
|
||||
buf = new uint[bufferSize];
|
||||
|
||||
// Go through each element in nanoVolume buf and copy it to the buf array
|
||||
for (int i = 0; i < bufferSize; i++)
|
||||
{
|
||||
buf[i] = nanoVolume->buf[i];
|
||||
}
|
||||
|
||||
gpuBuffer = new ComputeBuffer(
|
||||
bufferSize,
|
||||
stride,
|
||||
ComputeBufferType.Default
|
||||
);
|
||||
gpuBuffer.SetData(buf);
|
||||
|
||||
Debug.Log("GPU Buffer initialized");
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe bool PrepareVolume()
|
||||
{
|
||||
LoadNVDB(volumePath, out nanoVolume);
|
||||
|
||||
if (nanoVolume != null)
|
||||
{
|
||||
Debug.Log($"NanoVDB initialized successfully. size={nanoVolume->byteSize} bytes, " +
|
||||
$"array length={nanoVolume->elementCount}, stride={nanoVolume->structStride}");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Failed to create NanoVolume, aborting.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
gpuBuffer?.Dispose();
|
||||
|
||||
unsafe
|
||||
{
|
||||
if (nanoVolume != null)
|
||||
{
|
||||
FreeNVDB(nanoVolume);
|
||||
nanoVolume = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ComputeBuffer GetGPUBuffer()
|
||||
{
|
||||
if (gpuBuffer == null)
|
||||
{
|
||||
Debug.LogError("Buffer is null. Make sure the NanoLoader is finished before accessing this buffer.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return gpuBuffer;
|
||||
}
|
||||
|
||||
public bool IsLoaded()
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
private delegate void DebugLogDelegate(IntPtr message);
|
||||
|
||||
private static void DebugLogCallback(IntPtr message) { Debug.Log($"[NanoVDBWrapper.dll]: {Marshal.PtrToStringAnsi(message)}"); }
|
||||
|
||||
[DllImport("NanoVDBWrapper", EntryPoint = "SetDebugLogCallback")]
|
||||
private static extern void SetDebugLogCallback(DebugLogDelegate callback);
|
||||
|
||||
[DllImport("NanoVDBWrapper", EntryPoint = "LoadNVDB")]
|
||||
private unsafe static extern void LoadNVDB(string path, out NanoVolume* ptrToStruct);
|
||||
|
||||
[DllImport("NanoVDBWrapper", EntryPoint = "FreeNVDB")]
|
||||
private unsafe static extern void FreeNVDB(NanoVolume* ptrToStruct);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8652d7dda47bd74ba2fe1af0981c096
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,276 +0,0 @@
|
||||
#ifndef NANO_VOLUME_PASS
|
||||
#define NANO_VOLUME_PASS
|
||||
|
||||
#define MIN_TRANSMITTANCE 0.05
|
||||
#define MIN_DENSITY 0.01
|
||||
#define CLOUD_COLOR float3(1, 1, 1)
|
||||
|
||||
#define COLOR_NONE float4(0, 0, 0, 0)
|
||||
#define COLOR_RED float4(1, 0, 0, 1)
|
||||
#define COLOR_GREEN float4(0, 1, 0, 1)
|
||||
#define COLOR_BLUE float4(0, 0, 1, 1)
|
||||
|
||||
#define PNANOVDB_HLSL
|
||||
#include "PNanoVDB.hlsl"
|
||||
|
||||
uniform pnanovdb_buf_t buf : register(t1);
|
||||
|
||||
uniform float4 _LightDir; // directionalLight.transform.forward
|
||||
|
||||
uniform float3 _Light;
|
||||
uniform float3 _Scattering;
|
||||
|
||||
uniform float _DensityScale;
|
||||
uniform float _LightRayLength;
|
||||
uniform float _LightAbsorbation;
|
||||
uniform float _ClipPlaneMin;
|
||||
uniform float _ClipPlaneMax;
|
||||
|
||||
uniform int _RayMarchSamples;
|
||||
uniform int _LightSamples;
|
||||
|
||||
uniform int _VisualizeSteps;
|
||||
|
||||
struct Ray
|
||||
{
|
||||
float3 origin;
|
||||
float3 direction;
|
||||
float tmin;
|
||||
float tmax;
|
||||
};
|
||||
|
||||
struct NanoVolume
|
||||
{
|
||||
pnanovdb_grid_handle_t grid;
|
||||
pnanovdb_grid_type_t grid_type;
|
||||
pnanovdb_readaccessor_t acc;
|
||||
};
|
||||
|
||||
void initVolume(inout NanoVolume volume)
|
||||
{
|
||||
pnanovdb_grid_handle_t grid = { {0} };
|
||||
pnanovdb_grid_type_t grid_type = pnanovdb_buf_read_uint32(buf, PNANOVDB_GRID_OFF_GRID_TYPE);
|
||||
pnanovdb_tree_handle_t tree = pnanovdb_grid_get_tree(buf, grid);
|
||||
pnanovdb_root_handle_t root = pnanovdb_tree_get_root(buf, tree);
|
||||
pnanovdb_readaccessor_t acc;
|
||||
pnanovdb_readaccessor_init(acc, root);
|
||||
|
||||
volume.grid = grid;
|
||||
volume.grid_type = grid_type;
|
||||
volume.acc = acc;
|
||||
}
|
||||
|
||||
float get_value_coord(inout pnanovdb_readaccessor_t acc, pnanovdb_vec3_t pos)
|
||||
{
|
||||
pnanovdb_coord_t ijk = pnanovdb_hdda_pos_to_ijk(pos);
|
||||
pnanovdb_address_t address = pnanovdb_readaccessor_get_value_address(PNANOVDB_GRID_TYPE_FLOAT, buf, acc, ijk);
|
||||
return pnanovdb_read_float(buf, address);
|
||||
}
|
||||
|
||||
uint get_dim_coord(inout pnanovdb_readaccessor_t acc, pnanovdb_vec3_t pos)
|
||||
{
|
||||
pnanovdb_coord_t ijk = pnanovdb_hdda_pos_to_ijk(pos);
|
||||
return pnanovdb_readaccessor_get_dim(PNANOVDB_GRID_TYPE_FLOAT, buf, acc, ijk);
|
||||
}
|
||||
|
||||
bool get_hdda_hit(inout pnanovdb_readaccessor_t acc, inout Ray ray, inout float valueAtHit)
|
||||
{
|
||||
float thit;
|
||||
bool hit = pnanovdb_hdda_tree_marcher(
|
||||
PNANOVDB_GRID_TYPE_FLOAT,
|
||||
buf,
|
||||
acc,
|
||||
ray.origin, ray.tmin,
|
||||
ray.direction, ray.tmax,
|
||||
thit,
|
||||
valueAtHit
|
||||
);
|
||||
ray.tmin = thit;
|
||||
return hit;
|
||||
}
|
||||
|
||||
void get_participating_media(out float sigmaS, out float sigmaE, float3 pos, inout pnanovdb_readaccessor_t acc)
|
||||
{
|
||||
sigmaS = get_value_coord(acc, pos) * _DensityScale;
|
||||
sigmaE = max(0.000001, sigmaS);
|
||||
}
|
||||
|
||||
// No inout to avoid breaking cache for main ray (Gaida 2022)
|
||||
float volumetric_shadow(float3 pos, pnanovdb_readaccessor_t acc)
|
||||
{
|
||||
if (_LightSamples < 1) { return 0; }
|
||||
|
||||
float light_dir = -(_LightDir.xyz);
|
||||
|
||||
float shadow = 1;
|
||||
float sigmaS = 0.0;
|
||||
float sigmaE = 0.0;
|
||||
|
||||
int step = 0;
|
||||
int steps = 10;
|
||||
float step_size = 1;
|
||||
while (step < steps)
|
||||
{
|
||||
float3 sample_pos = pos + step_size * light_dir;
|
||||
|
||||
get_participating_media(sigmaS, sigmaE, sample_pos, acc);
|
||||
shadow *= exp(-sigmaE * step_size);
|
||||
|
||||
if (shadow < MIN_TRANSMITTANCE)
|
||||
{
|
||||
shadow = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
step_size *= 2;
|
||||
step++;
|
||||
}
|
||||
return shadow;
|
||||
}
|
||||
|
||||
// Exp step with jitter
|
||||
float volumetric_shadow_2(float3 pos, pnanovdb_readaccessor_t acc, float3 view_dir)
|
||||
{
|
||||
if (_LightSamples < 1) { return 0; }
|
||||
|
||||
float light_dir = -(_LightDir.xyz);
|
||||
|
||||
float shadow = 1.0;
|
||||
float sigmaS = 0.0;
|
||||
float sigmaE = 0.0;
|
||||
|
||||
float step_size = 1.0;
|
||||
float jitter = 0;
|
||||
|
||||
int step = 0;
|
||||
int steps = 10;
|
||||
while (step < steps)
|
||||
{
|
||||
float3 sample_pos = pos + (jitter + step_size) * light_dir;
|
||||
|
||||
get_participating_media(sigmaS, sigmaE, sample_pos, acc);
|
||||
sigmaE *= 0.3;
|
||||
shadow *= exp(-sigmaE * step_size);
|
||||
|
||||
step++;
|
||||
step_size *= (2 + random_float(sample_pos));
|
||||
}
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
float phase_function()
|
||||
{
|
||||
return 1.0;///(4.0*3.14);
|
||||
}
|
||||
|
||||
float4 raymarch_volume(Ray ray, inout NanoVolume volume, float step_size)
|
||||
{
|
||||
float transmittance = 1.0;
|
||||
float sigmaS = 0.0;
|
||||
float sigmaE = 0.0;
|
||||
float acc_density = 0.0;
|
||||
float3 direct_light = 0.0;
|
||||
float3 ambient_light = 0.005;
|
||||
|
||||
float not_used;
|
||||
bool hit = get_hdda_hit(volume.acc, ray, not_used);
|
||||
if (!hit) { return COLOR_NONE; }
|
||||
|
||||
int step = 0;
|
||||
float skip = 0;
|
||||
while (step < _RayMarchSamples)
|
||||
{
|
||||
if (ray.tmin >= ray.tmax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// read density from ray position
|
||||
float3 pos = ray.origin + ray.direction * ray.tmin;
|
||||
get_participating_media(sigmaS, sigmaE, pos, volume.acc);
|
||||
|
||||
// Skip empty space.
|
||||
uint dim = get_dim_coord(volume.acc, pos);
|
||||
if (dim > 1)
|
||||
{
|
||||
step++;
|
||||
float skip_step = 15;
|
||||
ray.tmin += skip_step;
|
||||
skip = skip_step;
|
||||
continue;
|
||||
}
|
||||
if (sigmaS < MIN_DENSITY)
|
||||
{
|
||||
step++;
|
||||
float skip_step = 5;
|
||||
ray.tmin += skip_step;
|
||||
skip = skip_step;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skip > 0) {
|
||||
// backtrack a little bit
|
||||
ray.tmin -= skip * 0.8;
|
||||
pos = ray.origin + ray.direction * ray.tmin;
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
acc_density += sigmaS;
|
||||
|
||||
// float3 S = sigmaS * phase_function() * volumetric_shadow_2(pos, volume.acc);
|
||||
float3 S = sigmaS * phase_function() * volumetric_shadow_2(pos, volume.acc, ray.direction);
|
||||
float3 Sint = (S - S * exp(-sigmaE * step_size)) / sigmaE;
|
||||
direct_light += transmittance * Sint;
|
||||
|
||||
transmittance *= exp(-sigmaE * step_size);
|
||||
|
||||
if (acc_density > 1.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Early out if no more light is reaching this point
|
||||
if (transmittance < MIN_TRANSMITTANCE)
|
||||
{
|
||||
transmittance = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
step++;
|
||||
ray.tmin += step_size;
|
||||
}
|
||||
|
||||
// Low step count will be blue, high red.
|
||||
if (_VisualizeSteps == 1)
|
||||
{
|
||||
float t = float(step) / float(_RayMarchSamples);
|
||||
if (step <= 0)
|
||||
{
|
||||
return COLOR_NONE;
|
||||
}
|
||||
float3 final_color = lerp(COLOR_BLUE, COLOR_RED, t);
|
||||
return float4(final_color, 1);
|
||||
}
|
||||
|
||||
float3 final_color = (direct_light + ambient_light) * acc_density;
|
||||
final_color = pow(final_color, 1.0 / 2.2);
|
||||
return float4(final_color, acc_density);
|
||||
}
|
||||
|
||||
float4 NanoVolumePass(float3 origin, float3 direction)
|
||||
{
|
||||
NanoVolume volume; initVolume(volume);
|
||||
|
||||
Ray ray;
|
||||
ray.origin = origin;
|
||||
ray.direction = direction;
|
||||
ray.tmin = _ClipPlaneMin;
|
||||
ray.tmax = _ClipPlaneMax;
|
||||
|
||||
float step_size = 0.57;
|
||||
float4 final_color = raymarch_volume(ray, volume, step_size);
|
||||
return final_color;
|
||||
}
|
||||
|
||||
#endif // NANO_VOLUME_PASS
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47dfc462aec4e4d46939d91412958fe4
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,35 +0,0 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class NanoVolumeSettings : MonoBehaviour
|
||||
{
|
||||
public Light directionalLight;
|
||||
public TMP_Text vdbNameText;
|
||||
public Slider RaymarchSamples;
|
||||
public Slider TemporalFrames;
|
||||
public Slider DensitySlider;
|
||||
public Slider LightSteps;
|
||||
public Slider LightAbsorbation;
|
||||
public Color scatteringColor;
|
||||
public int visualizeSteps = 0;
|
||||
|
||||
// Called from UI Button
|
||||
public void VisualizeSteps()
|
||||
{
|
||||
if (visualizeSteps == 0)
|
||||
{
|
||||
visualizeSteps = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
visualizeSteps = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// When clicking reset button
|
||||
public void StopVisualizeSteps()
|
||||
{
|
||||
visualizeSteps = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04a3f5c1a0e0ba240ae40af9f0fcce17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,46 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fabb37c28af77741aff24d4ae1fe924
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 3
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 0
|
||||
Editor:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
Linux64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXUniversal:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,19 +0,0 @@
|
||||
// https://www.reedbeta.com/blog/quick-and-easy-gpu-random-numbers-in-d3d11/
|
||||
|
||||
uint rand_xorshift(uint seed)
|
||||
{
|
||||
// Xorshift algorithm from George Marsaglia's paper
|
||||
seed ^= (seed << 13);
|
||||
seed ^= (seed >> 17);
|
||||
seed ^= (seed << 5);
|
||||
return seed;
|
||||
}
|
||||
|
||||
float random_float(float3 view_dir)
|
||||
{
|
||||
uint seed = asuint(view_dir.x + view_dir.y + view_dir.z);
|
||||
float res = float(rand_xorshift(seed)) * (1.0 / 4294967296.0);
|
||||
res = float(rand_xorshift(asuint(res))) * (1.0 / 4294967296.0);
|
||||
res = float(rand_xorshift(asuint(res))) * (1.0 / 4294967296.0);
|
||||
return res;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2159eccf73f568d458a47d19c6254765
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,67 +0,0 @@
|
||||
#define NANOVDB_USE_OPENVDB
|
||||
#define DLLExport __declspec(dllexport)
|
||||
|
||||
#include <iostream>
|
||||
#include <nanovdb/util/IO.h>
|
||||
|
||||
struct NanoVolume {
|
||||
uint32_t* buf;
|
||||
uint64_t byteSize;
|
||||
uint64_t elementCount;
|
||||
uint64_t structStride;
|
||||
} nanoVolumeStruct;
|
||||
|
||||
extern "C" {
|
||||
typedef void(*DebugLogCallback)(const char*);
|
||||
|
||||
DLLExport void SetDebugLogCallback(DebugLogCallback callback);
|
||||
DLLExport void LoadNVDB(const char* str, struct NanoVolume** volume);
|
||||
DLLExport void FreeNVDB(struct NanoVolume* volume);
|
||||
}
|
||||
|
||||
DebugLogCallback UnityLog = nullptr;
|
||||
void SetDebugLogCallback(DebugLogCallback callback) {
|
||||
UnityLog = callback;
|
||||
}
|
||||
|
||||
nanovdb::GridHandle<nanovdb::HostBuffer> gridHandle;
|
||||
void LoadNVDB(const char* path, struct NanoVolume** volume) {
|
||||
try {
|
||||
// reads first grid from file
|
||||
gridHandle = nanovdb::io::readGrid(path);
|
||||
|
||||
// get a (raw) pointer to a NanoVDB grid of value type float
|
||||
const nanovdb::FloatGrid* buf = gridHandle.grid<float>();
|
||||
|
||||
if (!buf) {
|
||||
throw std::runtime_error("File did not contain a grid with value type float");
|
||||
}
|
||||
|
||||
*volume = (struct NanoVolume*) malloc(sizeof(struct NanoVolume));
|
||||
|
||||
if (*volume == nullptr) {
|
||||
UnityLog("Failed to allocate memory for NanoVolume struct.");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t byteSize = gridHandle.buffer().bufferSize();
|
||||
const uint64_t elementCount = byteSize / sizeof(float);
|
||||
const uint64_t structStride = sizeof(float);
|
||||
|
||||
uint32_t* buffer_ptr = (uint32_t*)gridHandle.buffer().data();
|
||||
|
||||
(*volume)->buf = buffer_ptr;
|
||||
(*volume)->byteSize = byteSize;
|
||||
(*volume)->elementCount = elementCount;
|
||||
(*volume)->structStride = structStride;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
UnityLog("An exception occurred:");
|
||||
UnityLog(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void FreeNVDB(struct NanoVolume* volume) {
|
||||
free(volume);
|
||||
volume = nullptr;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44e340e1fd2f2d148a93e969247618ba
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 3
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 0
|
||||
Editor:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
OSXUniversal:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
Win:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
Win64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,27 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb0737f1c8a9f3343b05974ce7647fd8
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,24 +0,0 @@
|
||||
# Wrapper for NanoVDB to Unity
|
||||
|
||||
> See [NanoVDBWrapper.cpp](https://github.com/andersblomqvist/unity-nanovdb/blob/main/Assets/Plugins/NanoVDBWrapper.cpp) for source code.
|
||||
|
||||
The NanoVDB library is imported to Unity through a C++ wrapper. This wrapper exposes three functions, which we use in our Unity script [NanoVolumeLoader.cs](https://github.com/andersblomqvist/unity-nanovdb/blob/main/Assets/NanoVDB/NanoVolumeLoader.cs):
|
||||
|
||||
* `void SetDebugLogCallback(DebugLogCallback callback)`
|
||||
* `void LoadNVDB(const char* str, struct NanoVolume** volume)`
|
||||
* `void FreeNVDB(struct NanoVolume* volume)`
|
||||
|
||||
The `LoadNVDB` is most important, as it loads a `.nvdb` file from disk and enables Unity to access it through the `NanoVolume` struct. This struct mainly contains a pointer to the VDB grid buffer, which is uploaded to the GPU through the `NanoVolumeLoader.cs` script. That is basically it for the wrapper.
|
||||
|
||||
*Note:* it is not recommended by the author, Ken Museth, to store `.nvdb` files on disk. Instead it is suggested to convert an OpenVDB (`.vdb`) to NanoVDB (`.nvdb`) at runtime, but that requires importing all of OpenVDB. I decided to accept a larger file size on disk instead of bothering to import OpenVDB.
|
||||
|
||||
## Compile to Unity
|
||||
|
||||
The source is compiled to Unity with MSVC and CLR. In Visual Studio, the `Common Language Runtime Support` field is set to `.NET Framework Runtime Support (/clr)`, with the target version of `v4.8`. For Unity to accept version `4.8` we need to go into Unity, Edit, Project Settings, Player, Other Settings, and set `Api Compatibility Level*` to `.NET Framework`. This will make Unity import our DLL when we have a Unity script that uses it.
|
||||
|
||||
## References
|
||||
|
||||
* CLR: https://learn.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp
|
||||
* Logging from DLL in Unity: https://stackoverflow.com/questions/43732825/use-debug-log-from-c
|
||||
* Unity Managed plugins: https://docs.unity3d.com/6000.0/Documentation/Manual/plug-ins-managed.html
|
||||
* NanoVDB presentation by Ken Museth under Supplementary Material: https://dl.acm.org/doi/10.1145/3450623.3464653
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aab0996318f585d43920e93dc5e3d2e5
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user