refactor: 重构项目结构为 MVS 多示例版本,添加 README 文档
This commit is contained in:
3454
MVS/VolumeRenderer/Res/Shader/PNanoVDB.hlsl
Normal file
3454
MVS/VolumeRenderer/Res/Shader/PNanoVDB.hlsl
Normal file
File diff suppressed because it is too large
Load Diff
99
MVS/VolumeRenderer/Res/Shader/gs.hlsl
Normal file
99
MVS/VolumeRenderer/Res/Shader/gs.hlsl
Normal file
@@ -0,0 +1,99 @@
|
||||
struct VertexData{
|
||||
float4 position:POSITION;
|
||||
float4 texcoord:TEXCOORD0;
|
||||
float4 normal:NORMAL;
|
||||
float4 tangent:TANGENT;
|
||||
};
|
||||
|
||||
struct VSOut{
|
||||
float4 position:SV_POSITION;
|
||||
float4 normal:NORMAL;
|
||||
float4 texcoord:TEXCOORD0;
|
||||
};
|
||||
|
||||
static const float PI=3.141592;
|
||||
cbuffer globalConstants:register(b0){
|
||||
float4 misc;
|
||||
};
|
||||
|
||||
Texture2D T_DiffuseTexture:register(t0);
|
||||
SamplerState samplerState:register(s0);
|
||||
|
||||
struct MaterialData{
|
||||
float r;
|
||||
};
|
||||
StructuredBuffer<MaterialData> materialData:register(t0,space1);
|
||||
cbuffer DefaultVertexCB:register(b1){
|
||||
float4x4 ProjectionMatrix;
|
||||
float4x4 ViewMatrix;
|
||||
float4x4 ModelMatrix;
|
||||
float4x4 IT_ModelMatrix;
|
||||
float4x4 ReservedMemory[1020];
|
||||
};
|
||||
|
||||
VSOut MainVS(VertexData inVertexData){
|
||||
VSOut vo;
|
||||
vo.normal=mul(IT_ModelMatrix,inVertexData.normal);
|
||||
float4 positionWS=mul(ModelMatrix,inVertexData.position);
|
||||
float4 positionVS=mul(ViewMatrix,positionWS);
|
||||
vo.position=mul(ProjectionMatrix,positionVS);
|
||||
//vo.position=float4(positionWS.xyz+vo.normal.xyz*sin(misc.x)*0.2f,1.0f);
|
||||
vo.texcoord=inVertexData.texcoord;
|
||||
return vo;
|
||||
}
|
||||
|
||||
[maxvertexcount(4)]
|
||||
void MainGS(triangle VSOut inPoint[3],uint inPrimitiveID:SV_PrimitiveID,
|
||||
inout TriangleStream<VSOut> outTriangleStream){
|
||||
outTriangleStream.Append(inPoint[0]);
|
||||
outTriangleStream.Append(inPoint[1]);
|
||||
outTriangleStream.Append(inPoint[2]);
|
||||
/*VSOut vo;
|
||||
float3 positionWS=inPoint[0].position.xyz;
|
||||
float3 N=normalize(inPoint[0].normal.xyz);
|
||||
vo.normal=float4(N,0.0f);
|
||||
float3 helperVec=abs(N.y)>0.999?float3(0.0f,0.0f,1.0f):float3(0.0f,1.0f,0.0f);
|
||||
float3 tangent=normalize(cross(N,helperVec));//u
|
||||
float3 bitangent=normalize(cross(tangent,N));//v
|
||||
float scale=materialData[inPrimitiveID].r;
|
||||
|
||||
|
||||
float3 p0WS=positionWS-(bitangent*0.5f-tangent*0.5f)*scale;//left bottom
|
||||
float4 p0VS=mul(ViewMatrix,float4(p0WS,1.0f));
|
||||
vo.position=mul(ProjectionMatrix,p0VS);
|
||||
vo.texcoord=float4(0.0f,1.0f,0.0f,0.0f);
|
||||
outTriangleStream.Append(vo);
|
||||
|
||||
float3 p1WS=positionWS-(bitangent*0.5f+tangent*0.5f)*scale;//right bottom
|
||||
float4 p1VS=mul(ViewMatrix,float4(p1WS,1.0f));
|
||||
vo.position=mul(ProjectionMatrix,p1VS);
|
||||
vo.texcoord=float4(1.0f,1.0f,0.0f,0.0f);
|
||||
outTriangleStream.Append(vo);
|
||||
|
||||
float3 p2WS=positionWS+(bitangent*0.5f+tangent*0.5f)*scale;//left top
|
||||
float4 p2VS=mul(ViewMatrix,float4(p2WS,1.0f));
|
||||
vo.position=mul(ProjectionMatrix,p2VS);
|
||||
vo.texcoord=float4(0.0f,0.0f,0.0f,0.0f);
|
||||
outTriangleStream.Append(vo);
|
||||
|
||||
float3 p3WS=positionWS+(bitangent*0.5f-tangent*0.5f)*scale;//right top
|
||||
float4 p3VS=mul(ViewMatrix,float4(p3WS,1.0f));
|
||||
vo.position=mul(ProjectionMatrix,p3VS);
|
||||
vo.texcoord=float4(1.0f,0.0f,0.0f,0.0f);
|
||||
outTriangleStream.Append(vo);*/
|
||||
|
||||
}
|
||||
|
||||
float4 MainPS(VSOut inPSInput):SV_TARGET{
|
||||
float3 N=normalize(inPSInput.normal.xyz);
|
||||
float3 bottomColor=float3(0.1f,0.4f,0.6f);
|
||||
float3 topColor=float3(0.7f,0.7f,0.7f);
|
||||
float theta=asin(N.y);//-PI/2 ~ PI/2
|
||||
theta/=PI;//-0.5~0.5
|
||||
theta+=0.5f;//0.0~1.0
|
||||
float ambientColorIntensity=1.0;
|
||||
float3 ambientColor=lerp(bottomColor,topColor,theta)*ambientColorIntensity;
|
||||
float4 diffuseColor=T_DiffuseTexture.Sample(samplerState,inPSInput.texcoord.xy);
|
||||
float3 surfaceColor=diffuseColor.rgb;
|
||||
return float4(surfaceColor,1.0f);
|
||||
}
|
||||
65
MVS/VolumeRenderer/Res/Shader/ndctriangle.hlsl
Normal file
65
MVS/VolumeRenderer/Res/Shader/ndctriangle.hlsl
Normal file
@@ -0,0 +1,65 @@
|
||||
struct VertexData{
|
||||
float4 position:POSITION;
|
||||
float4 texcoord:TEXCOORD0;
|
||||
float4 normal:NORMAL;
|
||||
float4 tangent:TANGENT;
|
||||
};
|
||||
|
||||
struct VSOut{
|
||||
float4 position:SV_POSITION;
|
||||
float4 normal:NORMAL;
|
||||
float4 texcoord:TEXCOORD0;
|
||||
float4 positionWS:TEXCOORD1;
|
||||
};
|
||||
|
||||
static const float PI=3.141592;
|
||||
cbuffer globalConstants:register(b0){
|
||||
float4 misc;
|
||||
};
|
||||
|
||||
cbuffer DefaultVertexCB:register(b1){
|
||||
float4x4 ProjectionMatrix;
|
||||
float4x4 ViewMatrix;
|
||||
float4x4 ModelMatrix;
|
||||
float4x4 IT_ModelMatrix;
|
||||
float4x4 ReservedMemory[1020];
|
||||
};
|
||||
|
||||
VSOut MainVS(VertexData inVertexData){
|
||||
VSOut vo;
|
||||
vo.normal=mul(IT_ModelMatrix,inVertexData.normal);
|
||||
float3 positionMS=inVertexData.position.xyz+vo.normal*sin(misc.x);
|
||||
float4 positionWS=mul(ModelMatrix,float4(positionMS,1.0));
|
||||
float4 positionVS=mul(ViewMatrix,positionWS);
|
||||
vo.position=mul(ProjectionMatrix,positionVS);
|
||||
vo.positionWS=positionWS;
|
||||
vo.texcoord=inVertexData.texcoord;
|
||||
return vo;
|
||||
}
|
||||
|
||||
float4 MainPS(VSOut inPSInput):SV_TARGET{
|
||||
float3 N=normalize(inPSInput.normal.xyz);
|
||||
float3 bottomColor=float3(0.1f,0.4f,0.6f);
|
||||
float3 topColor=float3(0.7f,0.7f,0.7f);
|
||||
float theta=asin(N.y);//-PI/2 ~ PI/2
|
||||
theta/=PI;//-0.5~0.5
|
||||
theta+=0.5f;//0.0~1.0
|
||||
float ambientColorIntensity=0.2;
|
||||
float3 ambientColor=lerp(bottomColor,topColor,theta)*ambientColorIntensity;
|
||||
float3 L=normalize(float3(1.0f,1.0f,-1.0f));
|
||||
|
||||
float diffuseIntensity=max(0.0f,dot(N,L));
|
||||
float3 diffuseLightColor=float3(0.1f,0.4f,0.6f);
|
||||
float3 diffuseColor=diffuseLightColor*diffuseIntensity;
|
||||
|
||||
float3 specularColor=float3(0.0f,0.0f,0.0f);
|
||||
if(diffuseIntensity>0.0f){
|
||||
float3 cameraPositionWS=float3(0.0f,0.0f,0.0f);
|
||||
float3 V=normalize(cameraPositionWS.xyz-inPSInput.positionWS.xyz);
|
||||
float3 R=normalize(reflect(-L,N));
|
||||
float specularIntensity=pow(max(0.0f,dot(V,R)),128.0f);
|
||||
specularColor=float3(1.0f,1.0f,1.0f)*specularIntensity;
|
||||
}
|
||||
float3 surfaceColor=ambientColor+diffuseColor+specularColor;
|
||||
return float4(surfaceColor,1.0f);
|
||||
}
|
||||
250
MVS/VolumeRenderer/Res/Shader/volume.hlsl
Normal file
250
MVS/VolumeRenderer/Res/Shader/volume.hlsl
Normal file
@@ -0,0 +1,250 @@
|
||||
#define PNANOVDB_HLSL
|
||||
#define PNANOVDB_ADDRESS_32
|
||||
#include "PNanoVDB.hlsl"
|
||||
|
||||
cbuffer CB0 : register(b1)
|
||||
{
|
||||
float4x4 _InverseViewProjection; // 64 bytes
|
||||
float4 _CameraPos_Density; // xyz = CameraPos, w = DensityScale
|
||||
float4 _BBoxMin_Step; // xyz = BBoxMin, w = StepSize
|
||||
float4 _BBoxMax_MaxSteps; // xyz = BBoxMax, w = MaxSteps
|
||||
float4 _Rotation_Pad_LightSamples; // x = RotationY, yzw = pad, but we'll use differently
|
||||
float4 _LightDir_Samples; // xyz = LightDir, w = LightSamples
|
||||
};
|
||||
|
||||
StructuredBuffer<uint> buf : register(t1);
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float2 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
};
|
||||
|
||||
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;
|
||||
grid.address.byte_offset = 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, float3 pos)
|
||||
{
|
||||
pnanovdb_vec3_t p = pos;
|
||||
pnanovdb_coord_t ijk = pnanovdb_hdda_pos_to_ijk(p);
|
||||
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, float3 pos)
|
||||
{
|
||||
pnanovdb_vec3_t p = pos;
|
||||
pnanovdb_coord_t ijk = pnanovdb_hdda_pos_to_ijk(p);
|
||||
return pnanovdb_readaccessor_get_dim(PNANOVDB_GRID_TYPE_FLOAT, buf, acc, ijk);
|
||||
}
|
||||
|
||||
bool get_hdda_hit(inout pnanovdb_readaccessor_t acc, inout float tmin, float3 origin, float3 direction, float tmax, out float valueAtHit)
|
||||
{
|
||||
pnanovdb_vec3_t p_origin = origin;
|
||||
pnanovdb_vec3_t p_direction = direction;
|
||||
float thit;
|
||||
bool hit = pnanovdb_hdda_tree_marcher(
|
||||
PNANOVDB_GRID_TYPE_FLOAT,
|
||||
buf,
|
||||
acc,
|
||||
p_origin, tmin,
|
||||
p_direction, tmax,
|
||||
thit,
|
||||
valueAtHit
|
||||
);
|
||||
tmin = thit;
|
||||
return hit;
|
||||
}
|
||||
|
||||
float phase_function()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
uint rand_xorshift(uint seed)
|
||||
{
|
||||
seed ^= (seed << 13);
|
||||
seed ^= (seed >> 17);
|
||||
seed ^= (seed << 5);
|
||||
return seed;
|
||||
}
|
||||
|
||||
float random_float(float3 pos)
|
||||
{
|
||||
uint seed = asuint(pos.x + pos.y + pos.z);
|
||||
float res = float(rand_xorshift(seed)) * (1.0 / 4294967296.0);
|
||||
res = float(rand_xorshift(asuint(res))) * (1.0 / 4294967296.0);
|
||||
return res;
|
||||
}
|
||||
|
||||
float volumetric_shadow(float3 pos, float densityScale, inout pnanovdb_readaccessor_t acc)
|
||||
{
|
||||
float lightSamples = _LightDir_Samples.w;
|
||||
if (lightSamples < 1) { return 0.0; }
|
||||
|
||||
float3 light_dir = _LightDir_Samples.xyz;
|
||||
|
||||
float shadow = 1.0;
|
||||
float sigmaS = 0.0;
|
||||
float sigmaE = 0.0;
|
||||
float step_size = 1.0;
|
||||
float jitter = 0;
|
||||
|
||||
int steps = 10;
|
||||
for (int step = 0; step < steps; step++)
|
||||
{
|
||||
float3 sample_pos = pos + (jitter + step_size) * light_dir;
|
||||
|
||||
sigmaS = get_value_coord(acc, sample_pos) * densityScale;
|
||||
sigmaE = max(0.000001, sigmaS);
|
||||
sigmaE *= 0.3;
|
||||
shadow *= exp(-sigmaE * step_size);
|
||||
|
||||
step_size *= 2.0;
|
||||
}
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
PSInput MainVS(VSInput input)
|
||||
{
|
||||
PSInput output;
|
||||
output.position = float4(input.position, 0.0, 1.0);
|
||||
output.texcoord = input.texcoord;
|
||||
|
||||
float4 worldPosH = mul(_InverseViewProjection, float4(input.position, 0.5, 1.0));
|
||||
output.worldPos = worldPosH.xyz / worldPosH.w;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool intersectBox(float3 origin, float3 dir, float3 boxMin, float3 boxMax, out float tmin, out float tmax)
|
||||
{
|
||||
float3 invDir = 1.0 / dir;
|
||||
float3 t1 = (boxMin - origin) * invDir;
|
||||
float3 t2 = (boxMax - origin) * invDir;
|
||||
|
||||
tmin = max(max(min(t1.x, t2.x), min(t1.y, t2.y)), min(t1.z, t2.z));
|
||||
tmax = min(min(max(t1.x, t2.x), max(t1.y, t2.y)), max(t1.z, t2.z));
|
||||
|
||||
return tmax >= tmin && tmax > 0;
|
||||
}
|
||||
|
||||
float4 MainPS(PSInput input) : SV_TARGET
|
||||
{
|
||||
float3 rayDir = normalize(input.worldPos - _CameraPos_Density.xyz);
|
||||
|
||||
float tmin = 0.01;
|
||||
float tmax = 5000.0;
|
||||
|
||||
NanoVolume volume;
|
||||
initVolume(volume);
|
||||
|
||||
float3 color = float3(0, 0, 0);
|
||||
float transmittance = 1.0;
|
||||
float acc_density = 0.0;
|
||||
float3 ambient_light = 0.005;
|
||||
|
||||
float _DensityScale = _CameraPos_Density.w;
|
||||
float _StepSize = _BBoxMin_Step.w;
|
||||
float _MaxSteps = _BBoxMax_MaxSteps.w;
|
||||
float _RotationY = _Rotation_Pad_LightSamples.x;
|
||||
float _LightSamples = _LightDir_Samples.w;
|
||||
|
||||
float cosR = cos(_RotationY);
|
||||
float sinR = sin(_RotationY);
|
||||
float3x3 invRotY = float3x3(
|
||||
cosR, 0, sinR,
|
||||
0, 1, 0,
|
||||
-sinR, 0, cosR
|
||||
);
|
||||
|
||||
float3 localCameraPos = mul(invRotY, _CameraPos_Density.xyz);
|
||||
float3 localRayDir = mul(invRotY, rayDir);
|
||||
|
||||
float not_used;
|
||||
bool hit = get_hdda_hit(volume.acc, tmin, localCameraPos, localRayDir, tmax, not_used);
|
||||
if (!hit) { return float4(0, 0, 0, 0); }
|
||||
|
||||
float skip = 0;
|
||||
|
||||
for (int i = 0; i < (int)_MaxSteps; i++) {
|
||||
if (tmin >= tmax) break;
|
||||
|
||||
float3 localPos = localCameraPos + localRayDir * tmin;
|
||||
|
||||
uint dim = get_dim_coord(volume.acc, localPos);
|
||||
if (dim > 1) {
|
||||
float skip_step = 15.0;
|
||||
tmin += skip_step;
|
||||
skip = skip_step;
|
||||
continue;
|
||||
}
|
||||
|
||||
float density = get_value_coord(volume.acc, localPos) * _DensityScale;
|
||||
|
||||
if (density < 0.01) {
|
||||
float skip_step = 5.0;
|
||||
tmin += skip_step;
|
||||
skip = skip_step;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skip > 0) {
|
||||
tmin -= skip * 0.8;
|
||||
localPos = localCameraPos + localRayDir * tmin;
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
float sigmaS = density;
|
||||
float sigmaE = max(0.000001, sigmaS);
|
||||
acc_density += sigmaS;
|
||||
|
||||
float shadow = volumetric_shadow(localPos, _DensityScale, volume.acc);
|
||||
float3 S = sigmaS * phase_function() * shadow * float3(1, 1, 1);
|
||||
float3 Sint = (S - S * exp(-sigmaE * _StepSize)) / sigmaE;
|
||||
color += transmittance * Sint;
|
||||
transmittance *= exp(-sigmaE * _StepSize);
|
||||
|
||||
if (acc_density > 1.0) break;
|
||||
|
||||
if (transmittance < 0.05)
|
||||
{
|
||||
transmittance = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
tmin += _StepSize;
|
||||
}
|
||||
|
||||
float3 final_color = (color + ambient_light) * acc_density;
|
||||
final_color = pow(final_color, 1.0 / 2.2);
|
||||
return float4(final_color, acc_density);
|
||||
}
|
||||
26
MVS/VolumeRenderer/Res/Shader/wireframe.hlsl
Normal file
26
MVS/VolumeRenderer/Res/Shader/wireframe.hlsl
Normal file
@@ -0,0 +1,26 @@
|
||||
cbuffer CB0 : register(b1)
|
||||
{
|
||||
float4x4 _ViewProjection;
|
||||
};
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 position : POSITION;
|
||||
};
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
PSInput MainVS(VSInput input)
|
||||
{
|
||||
PSInput output;
|
||||
output.position = mul(_ViewProjection, float4(input.position, 1.0));
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 MainPS(PSInput input) : SV_TARGET
|
||||
{
|
||||
return float4(0.0, 1.0, 0.0, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user