dxPtexViwer : more parity to ptexViewer

This commit is contained in:
Takahito Tejima 2013-10-07 19:07:26 -07:00
parent 3e28bbe7d6
commit b41d55eda3
2 changed files with 287 additions and 19 deletions

View File

@ -235,6 +235,7 @@ ID3D11Texture2D * g_pDepthStencilBuffer = NULL;
ID3D11Buffer* g_pcbPerFrame = NULL;
ID3D11Buffer* g_pcbTessellation = NULL;
ID3D11Buffer* g_pcbLighting = NULL;
ID3D11Buffer* g_pcbConfig = NULL;
ID3D11DepthStencilView* g_pDepthStencilView = NULL;
bool g_bDone = false;
@ -786,7 +787,7 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
translate(pData->ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly);
rotate(pData->ModelViewMatrix, g_rotate[1], 1, 0, 0);
rotate(pData->ModelViewMatrix, g_rotate[0], 0, 1, 0);
translate(pData->ModelViewMatrix, -g_center[0], -g_center[2], g_center[1]);
translate(pData->ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]);
identity(pData->ProjectionMatrix);
perspective(pData->ProjectionMatrix, 45.0, aspect, 0.01f, 500.0);
@ -827,6 +828,36 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 );
}
// Update config state
{
__declspec(align(16))
struct Config {
float displacementScale;
float mipmapBias;
};
if (! g_pcbConfig) {
D3D11_BUFFER_DESC cbDesc;
ZeroMemory(&cbDesc, sizeof(cbDesc));
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.ByteWidth = sizeof(Config);
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pcbConfig);
}
assert(g_pcbConfig);
D3D11_MAPPED_SUBRESOURCE MappedResource;
g_pd3dDeviceContext->Map(g_pcbConfig, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
Config * pData = ( Config* )MappedResource.pData;
pData->displacementScale = g_displacementScale;
pData->mipmapBias = g_mipmapBias;
g_pd3dDeviceContext->Unmap( g_pcbConfig, 0 );
}
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->VSSetShader(config->vertexShader, NULL, 0);
@ -836,11 +867,13 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
g_pd3dDeviceContext->HSSetConstantBuffers(1, 1, &g_pcbTessellation);
g_pd3dDeviceContext->DSSetShader(config->domainShader, NULL, 0);
g_pd3dDeviceContext->DSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->DSSetConstantBuffers(3, 1, &g_pcbConfig);
g_pd3dDeviceContext->GSSetShader(config->geometryShader, NULL, 0);
g_pd3dDeviceContext->GSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetShader(config->pixelShader, NULL, 0);
g_pd3dDeviceContext->PSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting);
g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbConfig);
if (g_mesh->GetDrawContext()->vertexBufferSRV) {
g_pd3dDeviceContext->VSSetShaderResources(0, 1, &g_mesh->GetDrawContext()->vertexBufferSRV);
@ -859,6 +892,22 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
g_pd3dDeviceContext->PSSetShaderResources(4, 1, g_osdPTexImage->GetTexelsSRV());
g_pd3dDeviceContext->PSSetShaderResources(5, 1, g_osdPTexImage->GetLayoutSRV());
if (g_osdPTexDisplacement) {
g_pd3dDeviceContext->DSSetShaderResources(6, 1, g_osdPTexDisplacement->GetTexelsSRV());
g_pd3dDeviceContext->DSSetShaderResources(7, 1, g_osdPTexDisplacement->GetLayoutSRV());
g_pd3dDeviceContext->PSSetShaderResources(6, 1, g_osdPTexDisplacement->GetTexelsSRV());
g_pd3dDeviceContext->PSSetShaderResources(7, 1, g_osdPTexDisplacement->GetLayoutSRV());
}
if (g_osdPTexOcclusion) {
g_pd3dDeviceContext->PSSetShaderResources(8, 1, g_osdPTexOcclusion->GetTexelsSRV());
g_pd3dDeviceContext->PSSetShaderResources(9, 1, g_osdPTexOcclusion->GetLayoutSRV());
}
if (g_osdPTexSpecular) {
g_pd3dDeviceContext->PSSetShaderResources(10, 1, g_osdPTexSpecular->GetTexelsSRV());
g_pd3dDeviceContext->PSSetShaderResources(11, 1, g_osdPTexSpecular->GetLayoutSRV());
}
}
static void
@ -1028,6 +1077,7 @@ quit() {
SAFE_RELEASE(g_pcbPerFrame);
SAFE_RELEASE(g_pcbTessellation);
SAFE_RELEASE(g_pcbLighting);
SAFE_RELEASE(g_pcbConfig);
SAFE_RELEASE(g_pDepthStencilView);
SAFE_RELEASE(g_pSwapChainRTV);
@ -1206,8 +1256,8 @@ initHUD()
g_hud->AddCheckBox("Adaptive (`)", g_adaptive,
10, 150, callbackCheckBox, HUD_CB_ADAPTIVE, '`');
g_hud->AddRadioButton(HUD_RB_SCHEME, "CATMARK", true, 10, 190, callbackScheme, 0);
g_hud->AddRadioButton(HUD_RB_SCHEME, "BILINEAR", false, 10, 210, callbackScheme, 1);
g_hud->AddRadioButton(HUD_RB_SCHEME, "CATMARK", true, 10, 190, callbackScheme, 0, 's');
g_hud->AddRadioButton(HUD_RB_SCHEME, "BILINEAR", false, 10, 210, callbackScheme, 1, 's');
for (int i = 1; i < 8; ++i) {
char level[16];
@ -1279,7 +1329,7 @@ initHUD()
g_hud->AddSlider("Mipmap Bias", 0, 5, 0,
-200, 450, 20, false, callbackSlider, 0);
g_hud->AddSlider("Displacementd", 0, 5, 1,
g_hud->AddSlider("Displacement", 0, 5, 1,
-200, 490, 20, false, callbackSlider, 1);
if (g_osdPTexOcclusion != NULL) {
@ -1377,8 +1427,6 @@ initD3D11(HWND hWnd)
float diffuse[4];
float specular[4];
} lightSource[2];
float displacementScale;
float mipmapBias;
} lightingData = {
0.5, 0.2f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f,
@ -1389,12 +1437,8 @@ initD3D11(HWND hWnd)
0.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.0f,
0.0f
};
lightingData.mipmapBias = g_mipmapBias;
D3D11_BUFFER_DESC cbDesc;
ZeroMemory(&cbDesc, sizeof(cbDesc));
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
@ -1573,7 +1617,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmd
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
@ -1643,12 +1687,18 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmd
initD3D11(hWnd);
initHUD();
createOsdMesh(g_level, g_kernel);
// load ptex files
g_osdPTexImage = createPtex(colorFilename);
if (displacementFilename)
g_osdPTexDisplacement = createPtex(displacementFilename);
if (occlusionFilename)
g_osdPTexOcclusion = createPtex(occlusionFilename);
if (specularFilename)
g_osdPTexSpecular = createPtex(specularFilename);
initHUD();
fitFrame();

View File

@ -26,6 +26,11 @@ struct OutputPointVertex {
float4 positionOut : SV_Position;
};
cbuffer Config : register( b3 ) {
float displacementScale;
float mipmapBias;
};
struct PtexPacking
{
int page;
@ -131,6 +136,85 @@ float4 PTexLookup(float4 patchCoord,
return result;
}
// quadratic
void EvalQuadraticBSpline(float u, out float B[3], out float BU[3])
{
B[0] = 0.5 * (u*u - 2.0*u + 1);
B[1] = 0.5 + u - u*u;
B[2] = 0.5 * u*u;
BU[0] = u - 1.0;
BU[1] = 1 - 2 * u;
BU[2] = u;
}
float4 PTexLookupQuadratic(out float4 du,
out float4 dv,
float4 patchCoord,
int level,
Texture2DArray data,
Buffer<int> packings)
{
float2 uv = patchCoord.xy;
int faceID = int(patchCoord.w);
PtexPacking ppack = getPtexPacking(packings, faceID, level);
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
uv.y * ppack.height + ppack.vOffset);
coords -= float2(0.5, 0.5);
int cX = int(round(coords.x));
int cY = int(round(coords.y));
float x = 0.5 - (float(cX) - coords.x);
float y = 0.5 - (float(cY) - coords.y);
// ---------------------------
float4 d[9];
d[0] = data[int3(cX-1, cY-1, ppack.page)];
d[1] = data[int3(cX-1, cY-0, ppack.page)];
d[2] = data[int3(cX-1, cY+1, ppack.page)];
d[3] = data[int3(cX-0, cY-1, ppack.page)];
d[4] = data[int3(cX-0, cY-0, ppack.page)];
d[5] = data[int3(cX-0, cY+1, ppack.page)];
d[6] = data[int3(cX+1, cY-1, ppack.page)];
d[7] = data[int3(cX+1, cY-0, ppack.page)];
d[8] = data[int3(cX+1, cY+1, ppack.page)];
float B[3], D[3];
float4 BUCP[3], DUCP[3];
EvalQuadraticBSpline(y, B, D);
for (int i = 0; i < 3; ++i) {
BUCP[i] = float4(0, 0, 0, 0);
DUCP[i] = float4(0, 0, 0, 0);
for (int j = 0; j < 3; j++) {
float4 A = d[i*3+j];
BUCP[i] += A * B[j];
DUCP[i] += A * D[j];
}
}
EvalQuadraticBSpline(x, B, D);
float4 result = float4(0, 0, 0, 0);
du = float4(0, 0, 0, 0);
dv = float4(0, 0, 0, 0);
for (int i = 0; i < 3; ++i) {
result += B[i] * BUCP[i];
du += D[i] * BUCP[i];
dv += B[i] * DUCP[i];
}
du *= ppack.width;
dv *= ppack.height;
return result;
}
float4 PTexMipmapLookup(float4 patchCoord,
float level,
Texture2DArray data,
@ -147,6 +231,85 @@ float4 PTexMipmapLookup(float4 patchCoord,
return result;
}
float4 PTexMipmapLookupQuadratic(out float4 du,
out float4 dv,
float4 patchCoord,
float level,
Texture2DArray data,
Buffer<int> packings)
{
// TODO take into account difflevel
int levelm = int(floor(level));
int levelp = int(ceil(level));
float t = level - float(levelm);
float4 du0, du1, dv0, dv1;
float4 r0 = PTexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings);
float4 r1 = PTexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings);
float4 result = lerp(r0, r1, t);
du = lerp(du0, du1, t);
dv = lerp(dv0, dv1, t);
return result;
}
float4 PTexMipmapLookupQuadratic(float4 patchCoord,
float level,
Texture2DArray data,
Buffer<int> packings)
{
float4 du, dv;
return PTexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings);
}
// ---------------------------------------------------------------------------
#if defined(DISPLACEMENT_HW_BILINEAR) \
|| defined(DISPLACEMENT_BILINEAR) \
|| defined(DISPLACEMENT_BIQUADRATIC) \
|| defined(NORMAL_HW_SCREENSPACE) \
|| defined(NORMAL_SCREENSPACE) \
|| defined(NORMAL_BIQUADRATIC) \
|| defined(NORMAL_BIQUADRATIC_WG)
Texture2DArray textureDisplace_Data : register(t6);
Buffer<int> textureDisplace_Packing : register(t7);
#endif
#if defined(DISPLACEMENT_HW_BILINEAR) \
|| defined(DISPLACEMENT_BILINEAR) \
|| defined(DISPLACEMENT_BIQUADRATIC)
#undef OSD_DISPLACEMENT_CALLBACK
#define OSD_DISPLACEMENT_CALLBACK \
output.position = \
displacement(output.position, \
output.normal, \
output.patchCoord);
float4 displacement(float4 position, float3 normal, float4 patchCoord)
{
#if defined(DISPLACEMENT_HW_BILINEAR)
float disp = PTexLookupFast(patchCoord,
textureDisplace_Data,
textureDisplace_Packing).x;
#elif defined(DISPLACEMENT_BILINEAR)
float disp = PTexMipmapLookup(patchCoord, mipmapBias,
textureDisplace_Data,
textureDisplace_Packing).x;
#elif defined(DISPLACEMENT_BIQUADRATIC)
float disp = PTexMipmapLookupQuadratic(patchCoord, mipmapBias,
textureDisplace_Data,
textureDisplace_Packing).x;
#endif
return position + float4(disp*normal, 0) * displacementScale;
}
#endif
// ---------------------------------------------------------------------------
// Vertex Shader
// ---------------------------------------------------------------------------
@ -299,8 +462,6 @@ struct LightSource {
cbuffer Lighting : register( b2 ) {
LightSource lightSource[NUM_LIGHTS];
float displacementScale;
float mipmapBias;
};
float4
@ -362,15 +523,57 @@ edgeColor(float4 Cfill, float4 edgeDistance)
// Pixel Shader
// ---------------------------------------------------------------------------
#if defined(COLOR_PTEX_NEAREST) || \
defined(COLOR_PTEX_HW_BILINEAR) || \
defined(COLOR_PTEX_BILINEAR) || \
defined(COLOR_PTEX_BIQUADRATIC)
Texture2DArray textureImage_Data : register(t4);
Buffer<int> textureImage_Packing : register(t5);
#endif
#ifdef USE_PTEX_OCCLUSION
Texture2DArray textureOcclusion_Data : register(t8);
Buffer<int> textureOcclusion_Packing : register(t9);
#endif
#ifdef USE_PTEX_SPECULAR
Texture2DArray textureSpecular_Data : register(t10);
Buffer<int> textureSpecular_Packing : register(t11);
#endif
void
ps_main( in OutputVertex input,
bool isFrontFacing : SV_IsFrontFace,
out float4 outColor : SV_Target )
ps_main(in OutputVertex input,
out float4 outColor : SV_Target )
{
float3 normal = (isFrontFacing ? input.normal : -input.normal);
// ------------ normal ---------------
#if defined(NORMAL_HW_SCREENSPACE) || defined(NORMAL_SCREENSPACE)
float3 normal = perturbNormalFromDisplacement(input.position.xyz,
input.normal,
input.patchCoord);
#elif defined(NORMAL_BIQUADRATIC) || defined(NORMAL_BIQUADRATIC_WG)
float4 du, dv;
float4 disp = PTexMipmapLookupQuadratic(du, dv, input.patchCoord,
mipmapBias,
textureDisplace_Data,
textureDisplace_Packing);
disp *= displacementScale;
du *= displacementScale;
dv *= displacementScale;
float3 n = normalize(cross(input.tangent, input.bitangent));
float3 tangent = input.tangent + n * du.x;
float3 bitangent = input.bitangent + n * dv.x;
#if defined(NORMAL_BIQUADRATIC_WG)
tangent += input.Nu * disp.x;
bitangent += input.Nv * disp.x;
#endif
float3 normal = normalize(cross(tangent, bitangent));
#else
float3 normal = input.normal;
#endif
// ------------ color ---------------
#if defined(COLOR_PTEX_NEAREST)
@ -409,9 +612,24 @@ ps_main( in OutputVertex input,
#endif
// ------------ occlusion ---------------
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(input.patchCoord,
textureOcclusion_Data,
textureOcclusion_Packing).x;
#else
float occ = 0.0;
#endif
// ------------ specular ---------------
#ifdef USE_PTEX_SPECULAR
float specular = PTexLookup(input.patchCoord,
textureSpecular_Data,
textureSpecular_Packing).x;
#else
float specular = 1.0;
#endif
// ------------ lighting ---------------
float4 Cf = lighting(texColor, input.position.xyz, normal, occ);