// // Copyright (C) Pixar. All rights reserved. // // This license governs use of the accompanying software. If you // use the software, you accept this license. If you do not accept // the license, do not use the software. // // 1. Definitions // The terms "reproduce," "reproduction," "derivative works," and // "distribution" have the same meaning here as under U.S. // copyright law. A "contribution" is the original software, or // any additions or changes to the software. // A "contributor" is any person or entity that distributes its // contribution under this license. // "Licensed patents" are a contributor's patent claims that read // directly on its contribution. // // 2. Grant of Rights // (A) Copyright Grant- Subject to the terms of this license, // including the license conditions and limitations in section 3, // each contributor grants you a non-exclusive, worldwide, // royalty-free copyright license to reproduce its contribution, // prepare derivative works of its contribution, and distribute // its contribution or any derivative works that you create. // (B) Patent Grant- Subject to the terms of this license, // including the license conditions and limitations in section 3, // each contributor grants you a non-exclusive, worldwide, // royalty-free license under its licensed patents to make, have // made, use, sell, offer for sale, import, and/or otherwise // dispose of its contribution in the software or derivative works // of the contribution in the software. // // 3. Conditions and Limitations // (A) No Trademark License- This license does not grant you // rights to use any contributor's name, logo, or trademarks. // (B) If you bring a patent claim against any contributor over // patents that you claim are infringed by the software, your // patent license from such contributor to the software ends // automatically. // (C) If you distribute any portion of the software, you must // retain all copyright, patent, trademark, and attribution // notices that are present in the software. // (D) If you distribute any portion of the software in source // code form, you may do so only under this license by including a // complete copy of this license with your distribution. If you // distribute any portion of the software in compiled or object // code form, you may only do so under a license that complies // with this license. // (E) The software is licensed "as-is." You bear the risk of // using it. The contributors give no express warranties, // guarantees or conditions. You may have additional consumer // rights under your local laws which this license cannot change. // To the extent permitted under your local laws, the contributors // exclude the implied warranties of merchantability, fitness for // a particular purpose and non-infringement. // vec4 PTexLookup(vec4 patchCoord, sampler2DArray data, samplerBuffer packings, isamplerBuffer pages) { vec2 uv = patchCoord.xy; int faceID = int(patchCoord.w); int page = texelFetch(pages, faceID).x; vec4 packing = texelFetch(packings, faceID); vec3 coords = vec3( packing.x + uv.x * packing.z, packing.y + uv.y * packing.w, page); return texture(data, coords); } uniform sampler2DArray textureImage_Data; uniform samplerBuffer textureImage_Packing; uniform isamplerBuffer textureImage_Pages; vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord) { float disp = PTexLookup(patchCoord, textureImage_Data, textureImage_Packing, textureImage_Pages).x; return position + 0.01*vec4(disp * normal, 0); } //-------------------------------------------------------------- // Geometry Shader //-------------------------------------------------------------- #ifdef GEOMETRY_SHADER layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; #define EDGE_VERTS 3 in block { OutputVertex v; } inpt[3]; out block { OutputVertex v; noperspective out vec4 edgeDistance; } outpt; void emit(int index, vec4 position, vec3 normal, vec4 patchCoord) { outpt.v.position = position; outpt.v.patchCoord = patchCoord; outpt.v.normal = normal; gl_Position = ProjectionMatrix * outpt.v.position; EmitVertex(); } const float VIEWPORT_SCALE = 1024.0; // XXXdyu float edgeDistance(vec4 p, vec4 p0, vec4 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); } void emit(int index, vec4 position, vec3 normal, vec4 patchCoord, vec4 edgeVerts[EDGE_VERTS]) { outpt.edgeDistance[0] = edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]); outpt.edgeDistance[1] = edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]); outpt.edgeDistance[2] = edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]); emit(index, position, normal, patchCoord); } // -------------------------------------- void main() { gl_PrimitiveID = gl_PrimitiveIDIn; vec4 position[3]; vec4 patchCoord[3]; vec3 normal[3]; // patch coords are computed in tessellation shader patchCoord[0] = inpt[0].v.patchCoord; patchCoord[1] = inpt[1].v.patchCoord; patchCoord[2] = inpt[2].v.patchCoord; #ifdef USE_PTEX_DISPLACEMENT position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]); position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]); position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]); #else position[0] = inpt[0].v.position; position[1] = inpt[1].v.position; position[2] = inpt[2].v.position; #endif normal[0] = inpt[0].v.normal; normal[1] = inpt[1].v.normal; normal[2] = inpt[2].v.normal; #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) vec4 edgeVerts[EDGE_VERTS]; edgeVerts[0] = ProjectionMatrix * inpt[0].v.position; edgeVerts[1] = ProjectionMatrix * inpt[1].v.position; edgeVerts[2] = ProjectionMatrix * inpt[2].v.position; edgeVerts[0].xy /= edgeVerts[0].w; edgeVerts[1].xy /= edgeVerts[1].w; edgeVerts[2].xy /= edgeVerts[2].w; emit(0, position[0], normal[0], patchCoord[0], edgeVerts); emit(1, position[1], normal[1], patchCoord[1], edgeVerts); emit(2, position[2], normal[2], patchCoord[2], edgeVerts); #else emit(0, position[0], normal[0], patchCoord[0]); emit(1, position[1], normal[1], patchCoord[1]); emit(2, position[2], normal[2], patchCoord[2]); #endif EndPrimitive(); } #endif //-------------------------------------------------------------- // Fragment Shader //-------------------------------------------------------------- #ifdef FRAGMENT_SHADER in block { OutputVertex v; noperspective in vec4 edgeDistance; } inpt; out vec4 outColor; #define NUM_LIGHTS 2 struct LightSource { vec4 position; vec4 ambient; vec4 diffuse; vec4 specular; }; layout(std140) uniform Lighting { LightSource lightSource[NUM_LIGHTS]; }; uniform vec4 diffuseColor = vec4(1); uniform vec4 ambientColor = vec4(1); vec4 lighting(vec4 diffuse, vec3 Peye, vec3 Neye) { vec4 color = vec4(0); for (int i = 0; i < NUM_LIGHTS; ++i) { vec4 Plight = lightSource[i].position; vec3 l = (Plight.w == 0.0) ? normalize(Plight.xyz) : normalize(Plight.xyz - Peye); vec3 n = normalize(Neye); vec3 h = normalize(l + vec3(0,0,1)); // directional viewer float d = max(0.0, dot(n, l)); float s = pow(max(0.0, dot(n, h)), 500.0f); color += lightSource[i].ambient * ambientColor + d * lightSource[i].diffuse * diffuse + s * lightSource[i].specular; } color.a = 1; return color; } #ifdef USE_PTEX_DISPLACEMENT vec3 perturbNormalFromDisplacement(vec3 position, vec3 normal, vec4 patchCoord) { // by Morten S. Mikkelsen // http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf // slightly modified for ptex guttering vec3 vSigmaS = dFdx(position); vec3 vSigmaT = dFdy(position); vec3 vN = normal; vec3 vR1 = cross(vSigmaT, vN); vec3 vR2 = cross(vN, vSigmaS); float fDet = dot(vSigmaS, vR1); vec2 texDx = dFdx(patchCoord.xy); vec2 texDy = dFdy(patchCoord.xy); // limit forward differencing to the width of ptex gutter const float resolution = 128.0; float d = (0.5/resolution)/max(length(texDx), length(texDy)); vec4 STll = patchCoord; vec4 STlr = patchCoord + d * vec4(texDx.x, texDx.y, 0, 0); vec4 STul = patchCoord + d * vec4(texDy.x, texDy.y, 0, 0); float Hll = PTexLookup(STll, textureImage_Data, textureImage_Packing, textureImage_Pages).x; float Hlr = PTexLookup(STlr, textureImage_Data, textureImage_Packing, textureImage_Pages).x; float Hul = PTexLookup(STul, textureImage_Data, textureImage_Packing, textureImage_Pages).x; float dBs = (Hlr - Hll)/d; float dBt = (Hul - Hll)/d; vec3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2); return normalize(abs(fDet) * vN - vSurfGrad); } #endif // USE_PTEX_NORMAL vec4 edgeColor(vec4 Cfill, vec4 edgeDistance) { #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) float d = min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2])); vec4 Cedge = vec4(0.5, 0.5, 0.5, 1.0); float p = exp2(-2 * d * d); #if defined(GEOMETRY_OUT_WIRE) if (p < 0.25) discard; #endif Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p); #endif return Cfill; } void main() { vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal); #ifdef USE_PTEX_DISPLACEMENT N = perturbNormalFromDisplacement(inpt.v.position.xyz, N, inpt.v.patchCoord); #endif vec4 Cf = vec4(1.0); #if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) Cf = edgeColor(Cf, inpt.edgeDistance); #endif #ifdef USE_PTEX_COLOR Cf = Cf * (vec4(1) - vec4(PTexLookup(inpt.v.patchCoord, textureImage_Data, textureImage_Packing, textureImage_Pages).x)); #endif Cf = lighting(Cf, inpt.v.position.xyz, N); outColor = Cf; } #endif