├── BlendingInDetail.rfx ├── LICENSE ├── Meshes ├── Sphere.3ds └── Teapot.3ds ├── README.md ├── Textures ├── Diffuse.png ├── GraceCross.dds ├── GraceCrossDiffuse.dds ├── NormalBase.png ├── NormalDetail.png └── Top_N.png └── Website ├── RNM.png └── RNM2.png /BlendingInDetail.rfx: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 39 | 40 | 65 | 66 | 90 | 91 | 115 | 116 | 140 | 141 | 175 | 176 | 208 | 209 | 241 | 242 | 251 | 252 | 262 | 263 | 271 | 272 | 280 | 281 | 288 | 289 | 295 | 296 | 302 | 303 | 311 | 312 | 317 | 318 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 359 | 360 | 365 | 366 | 367 | 368 | 379 | 380 | 391 | 392 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 462 | 463 | 467 | 468 | 473 | 474 | 479 | 480 | 485 | 486 | 492 | 493 | 499 | 500 | 506 | 507 | 512 | 513 | 521 | 522 | 527 | 528 | 533 | 534 | 539 | 540 | 545 | 546 | 552 | 553 | 558 | 559 | 564 | 565 | 569 | 570 | 577 | 578 | 582 | 583 | 588 | 589 | 599 | 600 | 606 | 607 | 611 | 612 | 616 | 617 | 621 | 622 | 626 | 627 | 631 | 632 | 647 | 648 | 658 | 659 | 666 | 667 | 677 | 678 | 692 | 693 | 715 | 716 | 730 | 731 | 736 | 737 | 747 | 748 | 758 | 759 | 765 | 766 | 774 | 775 | 783 | 784 | 792 | 793 | 826 | 827 | 850 | 851 | 856 | 857 | 862 | 863 | 868 | 869 | 885 | 886 | 891 | 892 | 895 | 896 | 899 | 900 | 906 | ]> 907 | 908 | 909 | 910 | 911 | 912 | 914 | 916 | 918 | 920 | 921 | 0250250Artist Editor1001-1054054042799sharpness1100-104859592001456789101112131415161718192021222324252627282930313233343536373839404142434445464748494614351100014351100013391780014351100014351100014351100013391780014351100014351100013821920014351100014351100012013100012013100014351100013391780014351100013391780014351100013821920014351100014351100014351100014279900142799001427990014279900137418100142799001193299001193299001193299001427990014279900142799001374181001427990014279900142799001427990014279900142799001435110001435110001427990020005055220806151535431319250521520250250Workspace1000-10510514001250250001250123561560250250Output1002-1055055300581911804272427991591142799000435110spread_x1101-104763633006288198313748243511016311435110000435110Cs1102-104667673006622132043524351101671143511000042799Ks1103-1045717130070191180427242799171114279900042799Kd1104-1044757530074191180427242799175114279900042799Ka1105-1043797930078191180427242799179114279900042799spread_y1106-104283833008219118042724279918311427990030085191180427242799186114279900042799power1107-10418686042799Cs1108-10409191300901911804272427991911142799000374181lightDir1109-103995953009419200037423741811951137418100042799bumpAA1110-1038999930098191180427242799199114279900042799spread_y1111-10371031033001021911804272427991103114279900042799Cd1112-103610710730010619118042724279911071142799000193299myColor1113-10351111113001101931801932193299111111193299000193299Cs1114-10341151153001141931801932193299111511193299000193299Cd1115-1033119119300118196410453219329911191119329900042799bumpAA1116-103212312330012219118042724279911231142799000374181lightPos1117-1031127127300126192000374237418111271137418100042799gamma1118-10301311313001301911804272427991131114279900042799f1MyFloat1119-10291351353001341911804272427991135114279900042799baked_power1120-10281391393001381911804272427991139114279900042799bOneOver1121-102714314330014219118042724279911431142799000435110fDetailFactor1122-10261471473001462213204352435110114711435110003001492213204352435110115011435110000435110fDetailFactor1123-1025150150500300435110fDetailMapScale1124-1024156156300155011004352435110115611435110000382192lightPos1125-10231601603001592221403822382192116011382192000435110power1126-10221641643001632213204352435110116411435110000339178iMethod1127-10211681683001672220003392339178116811339178000435110fDetailMapScale1128-10201721723001712213204352435110117211435110000339178iMethod1129-10191761763001752220003392339178117611339178000435110fDetailFactor1130-10181801803001792213204352435110118011435110000201310cDiffuse1131-10171841843001832233202012201310118411201310000201310cSpecular1132-10161881883001872233202012201310118811201310000435110fSpecularPower1133-101519219230019148559574311782435110119211435110000435110fExposure1134-101419619630019548559574311782435110119611435110000382192vLightPos1135-101320020030019944463676911512382192120011382192000435110fAmbientScale1136-10122042043002032213204352435110120411435110000435110fSpecularScale1137-101120820830020748559574311782435110120811435110000339178iMethod1138-101021221230021145162979111302339178121211339178000435110fGlossiness1139-10921621630021522132192023552435110121611435110000435110fDetailScale1140-10822022030021922132192023552435110122011435110000435110fDetailFactor1141-107224224300223221321920235524351101224114351100030022622200192022592339178122711339178000339178iMethod1142-1062272270435110fFresnel1143-1052322323002312213204352435110123211435110000435110fFresnelScale1144-104236236300235221320435243511012361143511000353236 923 | ]]> 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1046 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1061 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1172 | 1174 | 1175 | 1176 | 1177 | 1178 | 1193 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1281 | 1282 | 1283 | 1284 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | = 0 ? -1 : 1; 1377 | float4 b = n1 >= 0 ? 1 : 0; 1378 | n1 = 2*a + n1; 1379 | n2 = n2*a + b; 1380 | float3 r = n1*n2 - a; 1381 | return normalize(r); 1382 | } 1383 | 1384 | float3 blend_pd(float4 n1, float4 n2) 1385 | { 1386 | n1 = n1*2 - 1; 1387 | n2 = n2.xyzz*float4(2, 2, 2, 0) + float4(-1, -1, -1, 0); 1388 | float3 r = n1.xyz*n2.z + n2.xyw*n1.z; 1389 | return normalize(r); 1390 | } 1391 | 1392 | float3 blend_whiteout(float4 n1, float4 n2) 1393 | { 1394 | n1 = n1*2 - 1; 1395 | n2 = n2*2 - 1; 1396 | float3 r = float3(n1.xy + n2.xy, n1.z*n2.z); 1397 | return normalize(r); 1398 | } 1399 | 1400 | float3 blend_udn(float4 n1, float4 n2) 1401 | { 1402 | float3 c = float3(2, 1, 0); 1403 | float3 r; 1404 | r = n2*c.yyz + n1.xyz; 1405 | r = r*c.xxx - c.xxy; 1406 | return normalize(r); 1407 | } 1408 | 1409 | float3 blend_rnm(float4 n1, float4 n2) 1410 | { 1411 | float3 t = n1.xyz*float3( 2, 2, 2) + float3(-1, -1, 0); 1412 | float3 u = n2.xyz*float3(-2, -2, 2) + float3( 1, 1, -1); 1413 | float3 r = t*dot(t, u) - u*t.z; 1414 | return normalize(r); 1415 | } 1416 | 1417 | float3 blend_unity(float4 n1, float4 n2) 1418 | { 1419 | n1 = n1.xyzz*float4(2, 2, 2, -2) + float4(-1, -1, -1, 1); 1420 | n2 = n2*2 - 1; 1421 | float3 r; 1422 | r.x = dot(n1.zxx, n2.xyz); 1423 | r.y = dot(n1.yzy, n2.xyz); 1424 | r.z = dot(n1.xyw, -n2.xyz); 1425 | return normalize(r); 1426 | } 1427 | 1428 | //--------------------------------------------------------------------------------------- 1429 | // Choose the technique 1430 | //--------------------------------------------------------------------------------------- 1431 | #define TECHNIQUE 5 1432 | 1433 | float4 MainPS(float2 vTex :TEXCOORD0, 1434 | float3 vLight :TEXCOORD1, 1435 | float3 vView :TEXCOORD2, 1436 | float3 vNormal :TEXCOORD3, 1437 | float3 vBinormal :TEXCOORD4, 1438 | float3 vTangent :TEXCOORD5) : COLOR 1439 | { 1440 | float3 L = normalize(vLight); 1441 | float3 V = normalize(vView); 1442 | 1443 | float4 n1 = tex2D(BaseNormal, vTex); 1444 | float4 n2 = tex2D(DetailNormal, vTex * fDetailFactor); 1445 | float3 N; 1446 | 1447 | if (iMethod == 0) 1448 | N = blend_linear(n1, n2); 1449 | else if (iMethod == 1) 1450 | N = blend_overlay(n1, n2); 1451 | else if (iMethod == 2) 1452 | N = blend_pd(n1, n2); 1453 | else if (iMethod == 3) 1454 | N = blend_whiteout(n1, n2); 1455 | else if (iMethod == 4) 1456 | N = blend_udn(n1, n2); 1457 | else if (iMethod == 5) 1458 | N = blend_rnm(n1, n2); 1459 | else 1460 | N = blend_unity(n1, n2); 1461 | 1462 | float3 H = normalize(V + L); 1463 | 1464 | // Specular power from glossiness 1465 | float fSpecularPower = exp2(1 + fGlossiness*10); 1466 | 1467 | // Energy-conserving specular power 1468 | float fSpec = pow(saturate(dot(H, N)), fSpecularPower); 1469 | fSpec *= (fSpecularPower + 2)/8; 1470 | 1471 | // Lambert 1472 | float NdotL = saturate(dot(L, N)); 1473 | 1474 | // Texture Maps 1475 | float4 cDiff = pow(tex2D(DiffuseMap, vTex) * cDiffuse, fGamma); 1476 | float4 cSpec = pow(cSpecular, fGamma) * fSpec; 1477 | 1478 | // (Linear) Ambient lighting cubemap lookup with new normal 1479 | float3 N_WS = normalize(mul(N, float3x3(vTangent, vBinormal, vNormal))); 1480 | float4 cAmbient = texCUBE(DiffuseEnvMap, N_WS) * fAmbientScale * cDiff; 1481 | 1482 | // Lighting 1483 | float4 cFinal = (cDiff + cSpec)*NdotL + cAmbient; 1484 | 1485 | // Tonemap 1486 | cFinal = 1 - pow(2, -fExposure*cFinal); 1487 | 1488 | // Final Result 1489 | cFinal = pow(cFinal, 1/fGamma); 1490 | 1491 | return cFinal; 1492 | } 1493 | ]]> 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1581 | 1582 | 1583 | 1584 | 1585 | 1586 | 1587 | 1588 | 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | 1600 | 1601 | 1602 | 1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | 1634 | 1635 | 1636 | 1637 | 1638 | 1639 | 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | 1651 | 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1658 | 1659 | 1660 | 1661 | 1662 | 1663 | 1664 | 1665 | 1666 | 1667 | 1668 | 1669 | 1670 | 1671 | 1750 | 1751 | 1752 | 1753 | 1754 | 1755 | 1756 | 1757 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2012 Colin Barré-Brisebois, Stephen Hill. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Meshes/Sphere.3ds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Meshes/Sphere.3ds -------------------------------------------------------------------------------- /Meshes/Teapot.3ds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Meshes/Teapot.3ds -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reoriented Normal Mapping 2 | This repository constains the code for Reoriented Normal Mapping [1], a technique to compute proper blending of tangent space normals via quaternion rotation. 3 | 4 | 5 | 6 | Details regarding the technique and how it compares to other approaches can be found [here](http://blog.selfshadow.com/publications/blending-in-detail/). 7 | 8 | The code is provided in the form of a RenderMonkey project. You can download RenderMonkey [here](http://gpuopen.com/archive/gamescgi/rendermonkey-toolsuite/). 9 | 10 | # Implementation Summary 11 | 12 | 13 | ```hlsl 14 | float3 t = tex2D(BaseNormal, uv) * float3(2, 2, 2) + float3(-1, -1, 0); 15 | float3 u = tex2D(DetailNormal, uv) * float3(-2, -2, 2) + float3(1, 1, -1); 16 | float3 r = t * dot(t, u) / t.z – u; 17 | ``` 18 | 19 | # References 20 | [1] Barré-Brisebois, Colin and Hill, Stephen. "Blending in Detail - Reoriented Normal Mapping", 2012, [Available Online](http://blog.selfshadow.com/publications/blending-in-detail/). 21 | -------------------------------------------------------------------------------- /Textures/Diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/Diffuse.png -------------------------------------------------------------------------------- /Textures/GraceCross.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/GraceCross.dds -------------------------------------------------------------------------------- /Textures/GraceCrossDiffuse.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/GraceCrossDiffuse.dds -------------------------------------------------------------------------------- /Textures/NormalBase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/NormalBase.png -------------------------------------------------------------------------------- /Textures/NormalDetail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/NormalDetail.png -------------------------------------------------------------------------------- /Textures/Top_N.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Textures/Top_N.png -------------------------------------------------------------------------------- /Website/RNM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Website/RNM.png -------------------------------------------------------------------------------- /Website/RNM2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zigguratvertigo/ReorientedNormalMapping/84930d8217788c6824c09ae010d8f919b7e3c5d0/Website/RNM2.png --------------------------------------------------------------------------------