// // Copyright 2013 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // struct OutputPointVertex { float4 positionOut : SV_Position; }; cbuffer Transform : register( b0 ) { float4x4 ModelViewMatrix; float4x4 ProjectionMatrix; float4x4 ModelViewProjectionMatrix; }; cbuffer Tessellation : register( b1 ) { float TessLevel; int GregoryQuadOffsetBase; int PrimitiveIdBase; }; cbuffer Config : register( b3 ) { float displacementScale; float mipmapBias; }; float4x4 OsdModelViewMatrix() { return ModelViewMatrix; } float4x4 OsdProjectionMatrix() { return ProjectionMatrix; } float4x4 OsdModelViewProjectionMatrix() { return ModelViewProjectionMatrix; } float OsdTessLevel() { return TessLevel; } int OsdGregoryQuadOffsetBase() { return GregoryQuadOffsetBase; } int OsdPrimitiveIdBase() { return PrimitiveIdBase; } // --------------------------------------------------------------------------- #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 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; #else float disp(0); #endif return position + float4(disp*normal, 0) * displacementScale; } #endif #line 20117 float4 GeneratePatchCoord(float2 localUV, int primitiveID) // for non-adpative { int2 ptexIndex = OsdPatchParamBuffer[GetPrimitiveID(primitiveID)].xy; int faceID = ptexIndex.x; int lv = 1 << ((ptexIndex.y & 0xf) - ((ptexIndex.y >> 4) & 1)); int u = (ptexIndex.y >> 17) & 0x3ff; int v = (ptexIndex.y >> 7) & 0x3ff; float2 uv = localUV; uv = (uv * float2(1, 1)/lv) + float2(u, v)/lv; return float4(uv.x, uv.y, lv+0.5, faceID+0.5); } // --------------------------------------------------------------------------- // Vertex Shader // --------------------------------------------------------------------------- void vs_main( in InputVertex input, out OutputVertex output ) { output.positionOut = mul(ModelViewProjectionMatrix, input.position); output.position = mul(ModelViewMatrix, input.position); output.normal = mul(ModelViewMatrix,float4(input.normal, 0)).xyz; } // --------------------------------------------------------------------------- // Geometry Shader // --------------------------------------------------------------------------- OutputVertex outputVertex(OutputVertex input, float3 normal) { OutputVertex v = input; v.normal = normal; return v; } OutputVertex outputVertex(OutputVertex input, float3 normal, float4 patchCoord) { OutputVertex v = input; v.normal = normal; v.patchCoord = patchCoord; return v; } #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) #ifdef PRIM_TRI #define EDGE_VERTS 3 #endif #ifdef PRIM_QUAD #define EDGE_VERTS 4 #endif static float VIEWPORT_SCALE = 1024.0; // XXXdyu float edgeDistance(float2 p, float2 p0, float2 p1) { return VIEWPORT_SCALE * abs((p.x - p0.x) * (p1.y - p0.y) - (p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy); } OutputVertex outputWireVertex(OutputVertex input, float3 normal, int index, float2 edgeVerts[EDGE_VERTS]) { OutputVertex v = input; v.normal = normal; v.edgeDistance[0] = edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]); v.edgeDistance[1] = edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]); #ifdef PRIM_TRI v.edgeDistance[2] = edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]); #endif #ifdef PRIM_QUAD v.edgeDistance[2] = edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]); v.edgeDistance[3] = edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]); #endif return v; } #endif #ifdef PRIM_QUAD [maxvertexcount(6)] void gs_main( lineadj OutputVertex input[4], inout TriangleStream triStream, uint primitiveID : SV_PrimitiveID) { float3 A = (input[0].position - input[1].position).xyz; float3 B = (input[3].position - input[1].position).xyz; float3 C = (input[2].position - input[1].position).xyz; float3 n0 = normalize(cross(B, A)); float4 patchCoord[4]; patchCoord[0] = GeneratePatchCoord(float2(0, 0), primitiveID); patchCoord[1] = GeneratePatchCoord(float2(1, 0), primitiveID); patchCoord[2] = GeneratePatchCoord(float2(1, 1), primitiveID); patchCoord[3] = GeneratePatchCoord(float2(0, 1), primitiveID); triStream.Append(outputVertex(input[0], n0, patchCoord[0])); triStream.Append(outputVertex(input[1], n0, patchCoord[1])); triStream.Append(outputVertex(input[3], n0, patchCoord[3])); triStream.RestartStrip(); triStream.Append(outputVertex(input[3], n0, patchCoord[3])); triStream.Append(outputVertex(input[1], n0, patchCoord[1])); triStream.Append(outputVertex(input[2], n0, patchCoord[2])); triStream.RestartStrip(); } #else // PRIM_TRI [maxvertexcount(3)] void gs_main( triangle OutputVertex input[3], inout TriangleStream triStream ) { float4 position[3]; float4 patchCoord[3]; float3 normal[3]; // patch coords are computed in tessellation shader patchCoord[0] = input[0].patchCoord; patchCoord[1] = input[1].patchCoord; patchCoord[2] = input[2].patchCoord; position[0] = input[0].position; position[1] = input[1].position; position[2] = input[2].position; #ifdef NORMAL_FACET // emit flat normals for displaced surface float3 A = (position[0] - position[1]).xyz; float3 B = (position[2] - position[1]).xyz; normal[0]= normalize(cross(B, A)); normal[1] = normal[0]; normal[2] = normal[0]; #else normal[0] = input[0].normal; normal[1] = input[1].normal; normal[2] = input[2].normal; #endif #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) float2 edgeVerts[3]; edgeVerts[0] = input[0].positionOut.xy / input[0].positionOut.w; edgeVerts[1] = input[1].positionOut.xy / input[1].positionOut.w; edgeVerts[2] = input[2].positionOut.xy / input[2].positionOut.w; triStream.Append(outputWireVertex(input[0], normal[0], 0, edgeVerts)); triStream.Append(outputWireVertex(input[1], normal[1], 1, edgeVerts)); triStream.Append(outputWireVertex(input[2], normal[2], 2, edgeVerts)); #else triStream.Append(outputVertex(input[0], normal[0])); triStream.Append(outputVertex(input[1], normal[1])); triStream.Append(outputVertex(input[2], normal[2])); #endif } #endif // --------------------------------------------------------------------------- // Lighting // --------------------------------------------------------------------------- #define NUM_LIGHTS 2 struct LightSource { float4 position; float4 ambient; float4 diffuse; float4 specular; }; cbuffer Lighting : register( b2 ) { LightSource lightSource[NUM_LIGHTS]; }; float4 lighting(float4 texColor, float3 Peye, float3 Neye, float occ) { float4 color = float4(0.0, 0.0, 0.0, 0.0); float3 n = Neye; for (int i = 0; i < NUM_LIGHTS; ++i) { float4 Plight = lightSource[i].position; float3 l = (Plight.w == 0.0) ? normalize(Plight.xyz) : normalize(Plight.xyz - Peye); float3 h = normalize(l + float3(0,0,1)); // directional viewer float d = max(0.0, dot(n, l)); float s = pow(max(0.0, dot(n, h)), 64.0f); color += (1.0 - occ) * ((lightSource[i].ambient + d * lightSource[i].diffuse) * texColor + s * lightSource[i].specular); } color.a = 1.0; return color; } // --------------------------------------------------------------------------- // Pixel Shader // --------------------------------------------------------------------------- float4 edgeColor(float4 Cfill, float4 edgeDistance) { #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) #ifdef PRIM_TRI float d = min(edgeDistance[0], min(edgeDistance[1], edgeDistance[2])); #endif #ifdef PRIM_QUAD float d = min(min(edgeDistance[0], edgeDistance[1]), min(edgeDistance[2], edgeDistance[3])); #endif float4 Cedge = float4(1.0, 1.0, 0.0, 1.0); float p = exp2(-2 * d * d); #if defined(GEOMETRY_OUT_WIRE) if (p < 0.25) discard; #endif Cfill.rgb = lerp(Cfill.rgb, Cedge.rgb, p); #endif return Cfill; } // --------------------------------------------------------------------------- // 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 textureImage_Packing : register(t5); #endif #ifdef USE_PTEX_OCCLUSION Texture2DArray textureOcclusion_Data : register(t8); Buffer textureOcclusion_Packing : register(t9); #endif #ifdef USE_PTEX_SPECULAR Texture2DArray textureSpecular_Data : register(t10); Buffer textureSpecular_Packing : register(t11); #endif void ps_main(in OutputVertex input, out float4 outColor : SV_Target ) { // ------------ 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) float4 texColor = PtexLookupNearest(input.patchCoord, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_HW_BILINEAR) float4 texColor = PtexLookupFast(input.patchCoord, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_BILINEAR) float4 texColor = PtexMipmapLookup(input.patchCoord, mipmapBias, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_BIQUADRATIC) float4 texColor = PtexMipmapLookupQuadratic(input.patchCoord, mipmapBias, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PATCHTYPE) float4 texColor = edgeColor(lighting(overrideColor, input.position.xyz, normal, 0), input.edgeDistance); outColor = texColor; return; #elif defined(COLOR_PATCHCOORD) float4 texColor = edgeColor(lighting(input.patchCoord, input.position.xyz, normal, 0), input.edgeDistance); outColor = texColor; return; #elif defined(COLOR_NORMAL) float4 texColor = edgeColor(float4(normal.x, normal.y, normal.z, 1), input.edgeDistance); outColor = texColor; return; #else // COLOR_NONE float4 texColor = float4(0.5, 0.5, 0.5, 1); #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); // ------------ wireframe --------------- outColor = edgeColor(Cf, input.edgeDistance); }