1// 2// Copyright 2013 Pixar 3// 4// Licensed under the Apache License, Version 2.0 (the "Apache License") 5// with the following modification; you may not use this file except in 6// compliance with the Apache License and the following modification to it: 7// Section 6. Trademarks. is deleted and replaced with: 8// 9// 6. Trademarks. This License does not grant permission to use the trade 10// names, trademarks, service marks, or product names of the Licensor 11// and its affiliates, except as required to comply with Section 4(c) of 12// the License and to reproduce the content of the NOTICE file. 13// 14// You may obtain a copy of the Apache License at 15// 16// http://www.apache.org/licenses/LICENSE-2.0 17// 18// Unless required by applicable law or agreed to in writing, software 19// distributed under the Apache License with the above modification is 20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21// KIND, either express or implied. See the Apache License for the specific 22// language governing permissions and limitations under the Apache License. 23// 24 25vec4 PTexLookup(vec4 patchCoord, 26 sampler2DArray data, 27 samplerBuffer packings, 28 isamplerBuffer pages) 29{ 30 vec2 uv = patchCoord.xy; 31 int faceID = int(patchCoord.w); 32 int page = texelFetch(pages, faceID).x; 33 vec4 packing = texelFetch(packings, faceID); 34 vec3 coords = vec3( packing.x + uv.x * packing.z, 35 packing.y + uv.y * packing.w, 36 page); 37 38 return texture(data, coords); 39} 40 41uniform sampler2DArray textureImage_Data; 42uniform samplerBuffer textureImage_Packing; 43uniform isamplerBuffer textureImage_Pages; 44 45vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord) 46{ 47 float disp = PTexLookup(patchCoord, 48 textureImage_Data, 49 textureImage_Packing, 50 textureImage_Pages).x; 51 return position + 0.01*vec4(disp * normal, 0); 52} 53 54//-------------------------------------------------------------- 55// Uniform Blocks 56//-------------------------------------------------------------- 57 58layout(std140) uniform Transform { 59 mat4 ModelViewMatrix; 60 mat4 ProjectionMatrix; 61 mat4 ModelViewProjectionMatrix; 62 mat4 ModelViewInverseMatrix; 63 mat4 ProjectionWithoutPickMatrix; 64}; 65 66layout(std140) uniform Tessellation { 67 float TessLevel; 68}; 69 70uniform int GregoryQuadOffsetBase; 71uniform int PrimitiveIdBase; 72 73//-------------------------------------------------------------- 74// Osd external functions 75//-------------------------------------------------------------- 76 77mat4 OsdModelViewMatrix() 78{ 79 return ModelViewMatrix; 80} 81mat4 OsdProjectionMatrix() 82{ 83 return ProjectionMatrix; 84} 85mat4 OsdModelViewProjectionMatrix() 86{ 87 return ModelViewProjectionMatrix; 88} 89float OsdTessLevel() 90{ 91 return TessLevel; 92} 93int OsdGregoryQuadOffsetBase() 94{ 95 return GregoryQuadOffsetBase; 96} 97int OsdPrimitiveIdBase() 98{ 99 return PrimitiveIdBase; 100} 101int OsdBaseVertex() 102{ 103 return 0; 104} 105 106//-------------------------------------------------------------- 107// Geometry Shader 108//-------------------------------------------------------------- 109#ifdef GEOMETRY_SHADER 110 111 layout(triangles) in; 112 113 layout(triangle_strip, max_vertices = 3) out; 114 115 #define EDGE_VERTS 3 116 117 in block { 118 OutputVertex v; 119 } inpt[3]; 120 121out block { 122 OutputVertex v; 123 noperspective out vec4 edgeDistance; 124} outpt; 125 126void emit(int index, vec4 position, vec3 normal, vec4 patchCoord) 127{ 128 outpt.v.position = position; 129 outpt.v.patchCoord = patchCoord; 130 outpt.v.normal = normal; 131 132 gl_Position = ProjectionMatrix * outpt.v.position; 133 EmitVertex(); 134} 135 136const float VIEWPORT_SCALE = 1024.0; // XXXdyu 137 138float edgeDistance(vec4 p, vec4 p0, vec4 p1) 139{ 140 return VIEWPORT_SCALE * 141 abs((p.x - p0.x) * (p1.y - p0.y) - 142 (p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy); 143} 144 145void emit(int index, vec4 position, vec3 normal, vec4 patchCoord, vec4 edgeVerts[EDGE_VERTS]) 146{ 147 outpt.edgeDistance[0] = 148 edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]); 149 outpt.edgeDistance[1] = 150 edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]); 151 outpt.edgeDistance[2] = 152 edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]); 153 emit(index, position, normal, patchCoord); 154} 155 156// -------------------------------------- 157 158void main() 159{ 160 gl_PrimitiveID = gl_PrimitiveIDIn; 161 162 vec4 position[3]; 163 vec4 patchCoord[3]; 164 vec3 normal[3]; 165 166 // patch coords are computed in tessellation shader 167 patchCoord[0] = inpt[0].v.patchCoord; 168 patchCoord[1] = inpt[1].v.patchCoord; 169 patchCoord[2] = inpt[2].v.patchCoord; 170 171#ifdef USE_PTEX_DISPLACEMENT 172 position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]); 173 position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]); 174 position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]); 175#else 176 position[0] = inpt[0].v.position; 177 position[1] = inpt[1].v.position; 178 position[2] = inpt[2].v.position; 179#endif 180 181 normal[0] = inpt[0].v.normal; 182 normal[1] = inpt[1].v.normal; 183 normal[2] = inpt[2].v.normal; 184 185#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) 186 vec4 edgeVerts[EDGE_VERTS]; 187 edgeVerts[0] = ProjectionMatrix * inpt[0].v.position; 188 edgeVerts[1] = ProjectionMatrix * inpt[1].v.position; 189 edgeVerts[2] = ProjectionMatrix * inpt[2].v.position; 190 191 edgeVerts[0].xy /= edgeVerts[0].w; 192 edgeVerts[1].xy /= edgeVerts[1].w; 193 edgeVerts[2].xy /= edgeVerts[2].w; 194 195 emit(0, position[0], normal[0], patchCoord[0], edgeVerts); 196 emit(1, position[1], normal[1], patchCoord[1], edgeVerts); 197 emit(2, position[2], normal[2], patchCoord[2], edgeVerts); 198#else 199 emit(0, position[0], normal[0], patchCoord[0]); 200 emit(1, position[1], normal[1], patchCoord[1]); 201 emit(2, position[2], normal[2], patchCoord[2]); 202#endif 203 204 EndPrimitive(); 205} 206 207#endif 208 209//-------------------------------------------------------------- 210// Fragment Shader 211//-------------------------------------------------------------- 212#ifdef FRAGMENT_SHADER 213 214in block { 215 OutputVertex v; 216 noperspective in vec4 edgeDistance; 217} inpt; 218 219out vec4 outColor; 220 221#define NUM_LIGHTS 2 222 223struct LightSource { 224 vec4 position; 225 vec4 ambient; 226 vec4 diffuse; 227 vec4 specular; 228}; 229 230layout(std140) uniform Lighting { 231 LightSource lightSource[NUM_LIGHTS]; 232}; 233 234uniform vec4 diffuseColor = vec4(1); 235uniform vec4 ambientColor = vec4(1); 236 237vec4 238lighting(vec4 diffuse, vec3 Peye, vec3 Neye) 239{ 240 vec4 color = vec4(0); 241 242 for (int i = 0; i < NUM_LIGHTS; ++i) { 243 244 vec4 Plight = lightSource[i].position; 245 246 vec3 l = (Plight.w == 0.0) 247 ? normalize(Plight.xyz) : normalize(Plight.xyz - Peye); 248 249 vec3 n = normalize(Neye); 250 vec3 h = normalize(l + vec3(0,0,1)); // directional viewer 251 252 float d = max(0.0, dot(n, l)); 253 float s = pow(max(0.0, dot(n, h)), 500.0f); 254 255 color += lightSource[i].ambient * ambientColor 256 + d * lightSource[i].diffuse * diffuse 257 + s * lightSource[i].specular; 258 } 259 260 color.a = 1; 261 return color; 262} 263 264#ifdef USE_PTEX_DISPLACEMENT 265vec3 266perturbNormalFromDisplacement(vec3 position, vec3 normal, vec4 patchCoord) 267{ 268 // by Morten S. Mikkelsen 269 // http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf 270 // slightly modified for ptex guttering 271 272 vec3 vSigmaS = dFdx(position); 273 vec3 vSigmaT = dFdy(position); 274 vec3 vN = normal; 275 vec3 vR1 = cross(vSigmaT, vN); 276 vec3 vR2 = cross(vN, vSigmaS); 277 float fDet = dot(vSigmaS, vR1); 278 279 vec2 texDx = dFdx(patchCoord.xy); 280 vec2 texDy = dFdy(patchCoord.xy); 281 282 // limit forward differencing to the width of ptex gutter 283 const float resolution = 128.0; 284 float d = (0.5/resolution)/max(length(texDx), length(texDy)); 285 286 vec4 STll = patchCoord; 287 vec4 STlr = patchCoord + d * vec4(texDx.x, texDx.y, 0, 0); 288 vec4 STul = patchCoord + d * vec4(texDy.x, texDy.y, 0, 0); 289 float Hll = PTexLookup(STll, textureImage_Data, textureImage_Packing, textureImage_Pages).x; 290 float Hlr = PTexLookup(STlr, textureImage_Data, textureImage_Packing, textureImage_Pages).x; 291 float Hul = PTexLookup(STul, textureImage_Data, textureImage_Packing, textureImage_Pages).x; 292 float dBs = (Hlr - Hll)/d; 293 float dBt = (Hul - Hll)/d; 294 295 vec3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2); 296 return normalize(abs(fDet) * vN - vSurfGrad); 297} 298#endif // USE_PTEX_NORMAL 299 300vec4 301edgeColor(vec4 Cfill, vec4 edgeDistance) 302{ 303#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) 304 float d = 305 min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2])); 306 vec4 Cedge = vec4(0.5, 0.5, 0.5, 1.0); 307 float p = exp2(-2 * d * d); 308 309#if defined(GEOMETRY_OUT_WIRE) 310 if (p < 0.25) discard; 311#endif 312 313 Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p); 314#endif 315 return Cfill; 316} 317 318void 319main() 320{ 321 vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal); 322#ifdef USE_PTEX_DISPLACEMENT 323 N = perturbNormalFromDisplacement(inpt.v.position.xyz, 324 N, 325 inpt.v.patchCoord); 326#endif 327 328 vec4 Cf = vec4(1.0); 329#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE) 330 Cf = edgeColor(Cf, inpt.edgeDistance); 331#endif 332 333#ifdef USE_PTEX_COLOR 334 Cf = Cf * (vec4(1) - vec4(PTexLookup(inpt.v.patchCoord, 335 textureImage_Data, 336 textureImage_Packing, 337 textureImage_Pages).x)); 338#endif 339 340 Cf = lighting(Cf, inpt.v.position.xyz, N); 341 342 outColor = Cf; 343} 344 345#endif 346