// Define inputs from application. struct VertexIn { float4 inPosition : POSITION; float2 inTexCoords : TEXCOORD0; }; // Define outputs from vertex shader. struct VertexOut { float4 outPosition : POSITION; float2 outTexCoords : TEXCOORD0; }; VertexOut main_vp(VertexIn vIn, uniform float4x4 p_ModelViewProjection // Model view projection matrix ) { VertexOut vOut; vOut.outPosition = mul(p_ModelViewProjection, vIn.inPosition); vOut.outTexCoords = vIn.inTexCoords; return vOut; } /**************************************************************************/ /* */ /* FUNCTIONS */ /* */ /**************************************************************************/ float2 get2DCoord(float pos,float texwidth) { float2 uv; // Rectangular coordinate => ( 0..texwidth, 0..texwidth ) uv.y = floor( pos / texwidth ); uv.x = pos - texwidth * uv.y; // pos % texwidth // Convert to uniform space / normalize => ( 0..1, 0..1 ) uv = ( uv + 0.5 ) / texwidth; return uv; } float3 getBarycentricCoordinatesColor( in float2 point, in float2 point1, in float2 point2, in float2 point3, in float3 color1, in float3 color2, in float3 color3, out float3 coordinates) { float A, B, C, D, E, F; float lambda1, lambda2, lambda3; A=point1.x-point3.x; B=point2.x-point3.x; C=point3.x-point.x; D=point1.y-point3.y; E=point2.y-point3.y; F=point3.y-point.y; if(A==0.0 && B==0.0) { float aux; aux=A; A=D; D=aux; aux=B; B=E; E=aux; aux=C; C=F; F=aux; } lambda1=((B*F)-(C*E)) / ((A*E) - (B*D)); lambda2=((A*F)-(C*D)) / ((B*D)-(A*E)); lambda3=1.0-lambda1-lambda2; coordinates = float3(lambda1, lambda2, lambda3); return (lambda1 * color1 + lambda2 * color2 + lambda3 * color3); } float2 transformPoint( in float texelSeamID, in float3 p, in sampler1D transformationMap1, in sampler1D transformationMap2, in float transformationMapsSize) { //De momento solo tenemos seam a seam!!! float3 part1, part2; float2 result; float3x3 M; if(p.z!=texelSeamID) { part1 = tex1D(transformationMap1,(p.z + 0.5) / transformationMapsSize).rgb; part2 = tex1D(transformationMap2,(p.z + 0.5) / transformationMapsSize).rgb; M=float3x3(part1,part2,float3(0.0,0.0,1.0)); result = mul(M,float3(p.x,1.0-p.y,1.0)).xy; result.y=1.0-result.y; } else result = p.xy; return result; } float pointInTriangle( in float2 P, //in float seamID, in float2 A, in float2 B, in float2 C) { //float2 A,B,C; float2 v0, v1, v2; float dot00, dot01, dot02, dot11, dot12; float invDenom; float u,v; // Compute vectors v0 = C - A; v1 = B - A; v2 = P - A; // Compute dot products dot00 = dot(v0, v0); dot01 = dot(v0, v1); dot02 = dot(v0, v2); dot11 = dot(v1, v1); dot12 = dot(v1, v2); // Compute barycentric coordinates invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; // Check if point is in triangle if((u > 0.0) && (v > 0.0) && (u + v < 1.0)) { return 1.0; } else { return 0.0; } } void updateIndexTexCoords(inout float2 currentTexCoords, in float displacement, in float size) { currentTexCoords = currentTexCoords + float2(displacement,0.0); if(currentTexCoords.x>1.0) currentTexCoords = float2(0.5/size,currentTexCoords.y+displacement); } void getTraingleVertices( in float texelType, in sampler2D verticesMap, in sampler1D transformationMap1, in sampler1D transformationMap2, inout float2 texCoordsCurrentVertice, in float displacementVertices, in float verticesTextureSize, in float transformationTextureSize, out float2 transformedV1, out float2 transformedV2, out float2 transformedV3, inout float2 v1Color, inout float2 v2Color, inout float2 v3Color, inout float2 color1TexCoords, inout float2 color2TexCoords, inout float2 color3TexCoords) { float3 v1,v2,v3; //Vertex 1 v1 = tex2D(verticesMap,texCoordsCurrentVertice).rgb; v1Color=v1.xy; if(v1.z>=0.0) { //Shared vertice transformedV1 = transformPoint(texelType,v1,transformationMap1,transformationMap2,transformationTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color1TexCoords=float2(-1.0,-1.0); } else if(v1.z==-1.0) { //Join vertice transformedV1 = v1.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color1TexCoords=float2(-1.0,-1.0); } else { //Intersection vertex or Seam vertex transformedV1 = v1.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color1TexCoords=texCoordsCurrentVertice; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); } //Vertex 2 v2 = tex2D(verticesMap,texCoordsCurrentVertice).rgb; v2Color=v2.xy; if(v2.z>=0.0) { //Shared vertice transformedV2 = transformPoint(texelType,v2,transformationMap1,transformationMap2,transformationTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color2TexCoords=float2(-1.0,-1.0); } else if(v2.z==-1.0) { //Join vertice transformedV2 = v2.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color2TexCoords=float2(-1.0,-1.0); } else { //Intersection vertex or Seam vertex transformedV2 = v2.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color2TexCoords=texCoordsCurrentVertice; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); } //Vertex 3 v3 = tex2D(verticesMap,texCoordsCurrentVertice).rgb; v3Color=v3.xy; if(v3.z>=0.0) { //Shared vertice transformedV3 = transformPoint(texelType,v3,transformationMap1,transformationMap2,transformationTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color3TexCoords=float2(-1.0,-1.0); } else if(v3.z==-1.0) { //Join vertice transformedV3 = v3.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color3TexCoords=float2(-1.0,-1.0); } else { //Intersection vertex or Seam vertex transformedV3 = v3.xy; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); color3TexCoords=texCoordsCurrentVertice; updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); updateIndexTexCoords(texCoordsCurrentVertice,displacementVertices,verticesTextureSize); } } float3 getWeightedVerticeColor(in float2 colorTexCoords,in sampler2D verticesMap,in sampler2D colorMap,in float verticesTextureSize) { float3 infoV1,infoV2; float3 color1,color2; float2 texCoords; texCoords=colorTexCoords; infoV1 = tex2D(verticesMap,colorTexCoords).rgb; updateIndexTexCoords(texCoords,1.0/verticesTextureSize,verticesTextureSize); color1 = tex2D(colorMap,infoV1.xy).rgb; infoV2 = tex2D(verticesMap,texCoords).rgb; color2 = tex2D(colorMap,infoV2.xy).rgb; return ((infoV1.z * color1) + (infoV2.z * color2)); } float3 evaluateColor( in float2 uv, in float2 v1, in float2 v2, in float2 v3, in float2 transformedV1, in float2 transformedV2, in float2 transformedV3, in float2 color1TexCoords,in float2 color2TexCoords,in float2 color3TexCoords, in sampler2D verticesMap, in sampler2D colorMap, in float verticesTextureSize, inout float3 coordinates ) { float3 color1,color2,color3; if(color1TexCoords.x>0) { color1 = getWeightedVerticeColor(color1TexCoords,verticesMap,colorMap,verticesTextureSize); } else color1 = tex2D(colorMap,v1).rgb; if(color2TexCoords.x>0) { color2 = getWeightedVerticeColor(color2TexCoords,verticesMap,colorMap,verticesTextureSize); } else color2 = tex2D(colorMap,v2).rgb; if(color3TexCoords.x>0) { color3 = getWeightedVerticeColor(color3TexCoords,verticesMap,colorMap,verticesTextureSize); } else color3 = tex2D(colorMap,v3).rgb; return getBarycentricCoordinatesColor(uv,transformedV1,transformedV2,transformedV3,color1,color2,color3,coordinates); } float4 unpackSubtexelInformation(float info) { int num; float4 result; num = (int)info; result.w=fmod((float)num,2.0); num=num/2; result.z=fmod((float)num,2.0); num=num/2; result.y=fmod((float)num,2.0); result.x=num/2; return result; } float fragmentOnSewingTriangles(in float2 texCoords,in float displacementTexelX,in float displacementTexelY,float4 subTexelInfo) { float2 currentTexel; int currentTexelX = texCoords.x / displacementTexelX; int currentTexelY = texCoords.y / displacementTexelY; currentTexel.x = (currentTexelX * displacementTexelX) + (displacementTexelX / 2.0); currentTexel.y = (currentTexelY * displacementTexelY) + (displacementTexelY / 2.0); //Determine the cuadrant of the current fragment within the texel it belongs if(texCoords.x > currentTexel.x) { if(texCoords.y > currentTexel.y) return subTexelInfo.z; //3rd cuadrant else return subTexelInfo.w; //4th cuadrant } else { if(texCoords.y > currentTexel.y) return subTexelInfo.y; //2nd cuadrant else return subTexelInfo.x; //1rst cuadrant } } /****************************************************************************************************/ struct Fragment { float4 color : COLOR0; }; Fragment main_fp(VertexOut v, uniform float4 p_sewingTheSeams, uniform float4 p_sewingTriangles, uniform float4 p_travellersTextureSize, uniform float4 p_transformationTexturesSize, uniform float4 p_trianglesTextureSize, uniform float4 p_verticesTextureSize, uniform sampler2D colorMap : register(s0), uniform sampler2D travellersMap : register(s1), uniform sampler1D transformationMap1 : register(s2), uniform sampler1D transformationMap2 : register(s3), uniform sampler2D trianglesMap : register(s4), uniform sampler2D verticesMap : register(s5) ) { Fragment fOut; float3 fragmentColor; float2 uv = float2(v.outTexCoords.x, 1.0-v.outTexCoords.y).rg; if(p_sewingTheSeams.x || p_sewingTriangles.x) { float4 texelType = tex2D(travellersMap,uv).rgba; float displacementTexelX = 1.0 / p_travellersTextureSize.x; float displacementTexelY = 1.0 / p_travellersTextureSize.y; //Interior fragment = GPU Filtering if(texelType.g==-1.0) fragmentColor = tex2D(colorMap,uv).rgb; else { //Sewing The Seams fragment float4 subTexelInfo=unpackSubtexelInformation(texelType.a); if(fragmentOnSewingTriangles(uv,displacementTexelX,displacementTexelY,subTexelInfo)) { float2 v1,v2,v3; float idxTriangle,currentTriangle,nTriangles; float trobat,displacementVertices,displacementTriangles,inTriangle; float2 texCoordsCurrentTriangle, texCoordsCurrentVertice; float3 coordinates; float2 transformedV1, transformedV2,transformedV3; float2 color1TexCoords,color2TexCoords,color3TexCoords; color1TexCoords=float2(-1.0,-1.0); color2TexCoords=float2(-1.0,-1.0); color3TexCoords=float2(-1.0,-1.0); displacementVertices = 1.0 / p_verticesTextureSize.x; displacementTriangles = 1.0 / p_trianglesTextureSize.x; //Obtain texture coordinates texCoordsCurrentTriangle = get2DCoord(texelType.g,p_trianglesTextureSize.x); //Get the number of triangles nTriangles = tex2D(trianglesMap,texCoordsCurrentTriangle).r; updateIndexTexCoords(texCoordsCurrentTriangle,displacementTriangles,p_trianglesTextureSize.x); currentTriangle = tex2D(trianglesMap,texCoordsCurrentTriangle).r; idxTriangle = 0.0; trobat = 0.0; fragmentColor = float3(0.0,0.0,0.0); while((idxTriangle