shader.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. var tvFragment = `precision highp float;
  2. varying vec2 vUV;
  3. uniform float tvWidthHeightScale;
  4. uniform float mvWidthHeightScale;
  5. uniform float bforceforceKeepContent;
  6. uniform sampler2D texture_video;
  7. // 等比例缩放画面占满屏幕,存在内容的丢失
  8. vec2 equalScalingFitTvSize(vec2 uv, float tvWidthHeightScale, float mvWidthHeightScale)
  9. {
  10. if( tvWidthHeightScale > mvWidthHeightScale )
  11. {
  12. float scale = mvWidthHeightScale/tvWidthHeightScale;
  13. uv.y = (uv.y - 0.5) * scale + 0.5;
  14. }else if( tvWidthHeightScale < mvWidthHeightScale )
  15. {
  16. float scale = tvWidthHeightScale/mvWidthHeightScale;
  17. uv.x = (uv.x - 0.5) * scale + 0.5;
  18. }
  19. return vec2( uv.x , uv.y);
  20. }
  21. // 强制保留画面内容(带有黑边)
  22. vec2 forceKeepContent(vec2 uv, float tvWidthHeightScale, float mvWidthHeightScale)
  23. {
  24. if( tvWidthHeightScale > mvWidthHeightScale )
  25. {
  26. float scale = mvWidthHeightScale/tvWidthHeightScale;
  27. uv.x = (uv.x - 0.5) / scale + 0.5;
  28. }else if( tvWidthHeightScale < mvWidthHeightScale )
  29. {
  30. float scale = tvWidthHeightScale/mvWidthHeightScale;
  31. uv.y = (uv.y - 0.5) / scale + 0.5;
  32. }
  33. return vec2( uv.x , uv.y);
  34. }
  35. void main()
  36. {
  37. vec2 uv = vUV;
  38. vec3 rgb;
  39. vec3 color = vec3(0,0,0);
  40. // 一旦设置了mvWidthHeightScale,就会触发等比例缩放or强制保内容
  41. if(tvWidthHeightScale > 0.0 && mvWidthHeightScale > 0.0)
  42. {
  43. if(bforceforceKeepContent > 0.0){
  44. uv = forceKeepContent(uv, tvWidthHeightScale, mvWidthHeightScale);
  45. }else{
  46. uv = equalScalingFitTvSize(uv, tvWidthHeightScale, mvWidthHeightScale);
  47. }
  48. }
  49. color = texture2D(texture_video, uv).rgb;
  50. // 避免纯白的出现
  51. color.r = clamp(color.r, 0.0, 0.99);
  52. color.g = clamp(color.g, 0.0, 0.99);
  53. color.b = clamp(color.b, 0.0, 0.99);
  54. if( uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 )
  55. {
  56. color = vec3(0,0,0);
  57. }
  58. gl_FragColor = vec4(color, 1.0);
  59. }
  60. `
  61. , tvVertex = `precision highp float;
  62. varying vec2 vUV;
  63. attribute vec2 uv;
  64. attribute vec3 position;
  65. uniform mat4 view;
  66. uniform mat4 projection;
  67. uniform mat4 world;
  68. void main()
  69. {
  70. vUV = uv;
  71. gl_Position = projection * view * world * vec4(position , 1.0);
  72. }
  73. `;
  74. var pureVideoFragment = `precision highp float;
  75. varying vec3 ModelPos;
  76. uniform float isYUV; // false: 0, true: 1.0
  77. uniform sampler2D texture_video;
  78. // uniform sampler2D chrominanceYTexture;
  79. // uniform sampler2D chrominanceUTexture;
  80. // uniform sampler2D chrominanceVTexture;
  81. uniform float haveShadowLight;
  82. varying vec4 vPositionFromLight;
  83. uniform float fireworkLight;
  84. varying float fireworkDistance;
  85. varying float fireworkCosTheta;
  86. uniform sampler2D shadowSampler;
  87. // uniform float focal;
  88. // uniform float captureWidth;
  89. // uniform float captureHeight;
  90. uniform vec3 focal_width_height;
  91. const float inv_2_PI = 0.1591549; // 1 / (2 * pi)
  92. const float inv_PI = 0.3183099; // 1 / ( pi)
  93. const vec2 invAtan = vec2(0.1591549, 0.3183099);
  94. float unpack(vec4 color)
  95. {
  96. const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
  97. return dot(color, bit_shift);
  98. }
  99. float ShadowCalculation(vec4 vPositionFromLight, sampler2D ShadowMap)
  100. {
  101. vec3 projCoords = vPositionFromLight.xyz / vPositionFromLight.w;
  102. vec3 depth = 0.5 * projCoords + vec3(0.5);
  103. vec2 uv = depth.xy;
  104. if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0)
  105. {
  106. return 1.0;
  107. }
  108. #ifndef SHADOWFULLFLOAT
  109. float shadow = unpack(texture2D(ShadowMap, uv));
  110. #else
  111. float shadow = texture2D(ShadowMap, uv).x;
  112. #endif
  113. if (depth.z > shadow - 1e-4)
  114. {
  115. return 0.7;
  116. }
  117. else
  118. {
  119. return 1.0;
  120. }
  121. }
  122. // const float f = 514.133282; //937.83246;
  123. // const float w = 720.0;
  124. // const float h = 1280.0;
  125. // vec2 SampleTex(vec3 pt3d, vec2 widthHeight)
  126. vec2 SampleTex(vec3 pt3d)
  127. {
  128. // // vec2 uv = vec2( f/w*pt3d.x/pt3d.z, f/h*pt3d.y/pt3d.z ); //模型变换到相机坐标系下
  129. // vec2 uv = vec2( focal/captureWidth*pt3d.x/pt3d.z, focal/captureHeight*pt3d.y/pt3d.z ); //模型变换到相机坐标系下
  130. // uv.x = uv.x + 0.5;
  131. // uv.y = uv.y + 0.5;
  132. // return uv;
  133. return focal_width_height.x / focal_width_height.yz *pt3d.xy/pt3d.z + 0.5;
  134. }
  135. void main()
  136. {
  137. vec3 yuv;
  138. vec3 rgb;
  139. vec2 uv;
  140. vec3 color = vec3(0,0,0);
  141. vec3 flash_color = fireworkLight * 1000.0 / fireworkDistance * fireworkCosTheta * vec3(1,0,0);
  142. float shadow = 1.0;
  143. if (haveShadowLight > 0.5)
  144. {
  145. shadow = ShadowCalculation(vPositionFromLight, shadowSampler);
  146. }
  147. // uv = SampleTex( normalize(ModelPos), vec2(captureWidth, captureHeight));
  148. uv = SampleTex( normalize(ModelPos) );
  149. if( isYUV < 0.5 )
  150. {
  151. color = texture2D(texture_video, uv).rgb;
  152. }else{
  153. const mat4 YUV2RGB = mat4
  154. (
  155. 1.1643828125, 0, 1.59602734375, -.87078515625,
  156. 1.1643828125, -.39176171875, -.81296875, .52959375,
  157. 1.1643828125, 2.017234375, 0, -1.081390625,
  158. 0, 0, 0, 1
  159. );
  160. vec4 result = vec4(
  161. texture2D(texture_video, vec2(uv.x, uv.y*0.666666 + 0.333333 ) ).x,
  162. texture2D(texture_video, vec2(uv.x * 0.5, uv.y*0.333333 ) ).x,
  163. texture2D(texture_video, vec2(0.5 + uv.x * 0.5, uv.y*0.333333 ) ).x,
  164. 1) * YUV2RGB;
  165. color = clamp(result.rgb, 0.0, 1.0);
  166. }
  167. if( uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 )
  168. {
  169. color = vec3(0,0,0);
  170. }
  171. // gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
  172. gl_FragColor = vec4(shadow * (color + flash_color) * 1.0, 1.0);
  173. }
  174. `
  175. , pureVideoVertex = `precision highp float;
  176. varying vec3 ModelPos;
  177. varying vec4 vPositionFromLight;
  178. varying float fireworkDistance;
  179. varying float fireworkCosTheta;
  180. attribute vec2 uv;
  181. attribute vec3 position;
  182. attribute vec4 world0;
  183. attribute vec4 world1;
  184. attribute vec4 world2;
  185. attribute vec4 world3;
  186. #ifdef NORMAL
  187. attribute vec3 normal;
  188. #endif
  189. uniform vec3 fireworkLightPosition;
  190. uniform mat4 view;
  191. uniform mat4 projection;
  192. uniform mat4 lightSpaceMatrix;
  193. uniform mat4 world;
  194. uniform mat4 worldViewProjection;
  195. float DistanceCalculation(vec3 Q, vec3 P)
  196. {
  197. return (Q.x - P.x) * (Q.x - P.x) + (Q.y - P.y) * (Q.y - P.y) + (Q.z - P.z) * (Q.z - P.z);
  198. }
  199. float CosThetaCalculation(vec3 Q, vec3 P)
  200. {
  201. return max(0.,dot(Q, P));
  202. }
  203. void main()
  204. {
  205. #include<instancesVertex>
  206. vPositionFromLight = lightSpaceMatrix * finalWorld * vec4(position, 1.0);
  207. // fireworkDistance = DistanceCalculation(vec3(finalWorld * vec4(position, 1.0)), fireworkLightPosition);
  208. fireworkDistance = distance(vec3(finalWorld * vec4(position, 1.0)), fireworkLightPosition);
  209. fireworkCosTheta = 1.0;
  210. #ifdef NORMAL
  211. vec3 directionFirework = fireworkLightPosition.xyz - vec3(finalWorld * vec4(position, 1.0));
  212. directionFirework = normalize(directionFirework);
  213. // directionFirework = directionFirework / (directionFirework.x * directionFirework.x + directionFirework.y * directionFirework.y + directionFirework.z * directionFirework.z);
  214. fireworkCosTheta = CosThetaCalculation(directionFirework, normal);
  215. #endif
  216. ModelPos = vec3( view * finalWorld * vec4(position , 1.0));
  217. gl_Position = projection * view * finalWorld * vec4(position , 1.0);
  218. }
  219. `
  220. , panoFragment = `precision highp float;
  221. uniform float isYUV; // false: 0, true: 1.0
  222. varying vec2 TexCoords;
  223. varying vec3 WorldPos;
  224. varying vec3 vNormal;
  225. uniform float haveShadowLight;
  226. varying vec4 vPositionFromLight;
  227. uniform float fireworkLight;
  228. varying float fireworkDistance;
  229. varying float fireworkCosTheta;
  230. uniform sampler2D shadowSampler;
  231. uniform vec3 centre_pose;
  232. uniform sampler2D texture_pano;
  233. const float inv_2_PI = 0.1591549; // 1 / (2 * pi)
  234. const float inv_PI = 0.3183099; // 1 / ( pi)
  235. const vec2 invAtan = vec2(0.1591549, 0.3183099);
  236. float unpack(vec4 color)
  237. {
  238. const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
  239. return dot(color, bit_shift);
  240. }
  241. float ShadowCalculation(vec4 vPositionFromLight, sampler2D ShadowMap)
  242. {
  243. vec3 projCoords = vPositionFromLight.xyz / vPositionFromLight.w;
  244. vec3 depth = 0.5 * projCoords + vec3(0.5);
  245. vec2 uv = depth.xy;
  246. if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0)
  247. {
  248. return 1.0;
  249. }
  250. #ifndef SHADOWFULLFLOAT
  251. float shadow = unpack(texture2D(ShadowMap, uv));
  252. #else
  253. float shadow = texture2D(ShadowMap, uv).x;
  254. #endif
  255. if (depth.z > shadow)
  256. {
  257. return 0.7;
  258. }
  259. else
  260. {
  261. return 1.0;
  262. }
  263. }
  264. vec2 SampleSphericalMap(vec3 pt3d)
  265. {
  266. vec2 uv = vec2( atan(-pt3d.z,pt3d.x), atan( pt3d.y, sqrt(pt3d.x*pt3d.x + pt3d.z * pt3d.z)));
  267. uv.x = 0.5 + uv.x * inv_2_PI ; // yaw: 水平方向 ,0 到 360 , 对应8k的宽
  268. uv.y = 0.5 + uv.y * inv_PI ; // pitch: 竖直方向, -64 到 64 ,对应4k的长
  269. return vec2(uv.x,uv.y);
  270. }
  271. vec3 fitUint8Range(vec3 color)
  272. {
  273. if( color.x < 0.0 ){color.x = 0.0;}
  274. if( color.x > 1.0 ){color.x = 1.0;}
  275. if( color.y < 0.0 ){color.y = 0.0;}
  276. if( color.y > 1.0 ){color.y = 1.0;}
  277. if( color.z < 0.0 ){color.z = 0.0;}
  278. if( color.z > 1.0 ){color.z = 1.0;}
  279. return color;
  280. }
  281. void main()
  282. {
  283. // // Debug
  284. // vec3 vLightPosition = vec3(0,10,100);
  285. // // World values
  286. // vec3 vPositionW = vec3( WorldPos.x, WorldPos.y, WorldPos.z );
  287. // vec3 vNormalW = normalize( vNormal) ;
  288. // vec3 viewDirectionW = normalize(vPositionW);
  289. // // Light
  290. // vec3 lightVectorW = normalize(vLightPosition - vPositionW);
  291. // // diffuse
  292. // float ndl = max(0., dot(vNormalW, lightVectorW));
  293. // gl_FragColor = vec4( ndl, ndl, ndl, 1.);
  294. vec2 uv;
  295. vec3 color = vec3(0,0,0);
  296. vec3 flash_color = fireworkLight * 1000.0 / fireworkDistance * fireworkCosTheta * vec3(1,0,0);
  297. float shadow = 1.0;
  298. if (haveShadowLight > 0.5)
  299. {
  300. shadow = ShadowCalculation(vPositionFromLight, shadowSampler);
  301. }
  302. uv = SampleSphericalMap(normalize( WorldPos - centre_pose ));
  303. if( isYUV < 0.5 )
  304. {
  305. color = texture2D(texture_pano, uv).rgb;
  306. }else{
  307. const mat4 YUV2RGB = mat4
  308. (
  309. 1.1643828125, 0, 1.59602734375, -.87078515625,
  310. 1.1643828125, -.39176171875, -.81296875, .52959375,
  311. 1.1643828125, 2.017234375, 0, -1.081390625,
  312. 0, 0, 0, 1
  313. );
  314. vec4 result = vec4(
  315. texture2D(texture_pano, vec2(uv.x, uv.y*0.666666 + 0.333333 ) ).x,
  316. texture2D(texture_pano, vec2(uv.x * 0.5, uv.y*0.333333 ) ).x,
  317. texture2D(texture_pano, vec2(0.5 + uv.x * 0.5, uv.y*0.333333 ) ).x,
  318. 1) * YUV2RGB;
  319. color = fitUint8Range(result.rgb);
  320. }
  321. if( uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 )
  322. {
  323. color = vec3(0,0,0);
  324. }
  325. gl_FragColor = vec4( shadow * (color + flash_color), 1.0);
  326. }`
  327. , panoVertex = `precision highp float;
  328. varying vec2 TexCoords;
  329. varying vec3 vNormal;
  330. varying vec3 WorldPos;
  331. varying vec4 vPositionFromLight;
  332. varying float fireworkDistance;
  333. varying float fireworkCosTheta;
  334. uniform vec3 fireworkLightPosition;
  335. uniform mat4 lightSpaceMatrix;
  336. attribute vec3 normal;
  337. attribute vec2 uv;
  338. attribute vec3 position;
  339. uniform mat4 view;
  340. uniform mat4 projection;
  341. uniform mat4 world;
  342. uniform mat4 worldViewProjection;
  343. attribute vec4 world0;
  344. attribute vec4 world1;
  345. attribute vec4 world2;
  346. attribute vec4 world3;
  347. float DistanceCalculation(vec3 Q, vec3 P)
  348. {
  349. return (Q.x - P.x) * (Q.x - P.x) + (Q.y - P.y) * (Q.y - P.y) + (Q.z - P.z) * (Q.z - P.z);
  350. }
  351. float CosThetaCalculation(vec3 Q, vec3 P)
  352. {
  353. return max(0.,dot(Q, P));
  354. }
  355. void main()
  356. {
  357. #include<instancesVertex>
  358. vPositionFromLight = lightSpaceMatrix * world * vec4(position, 1.0);
  359. fireworkDistance = DistanceCalculation(vec3(finalWorld * vec4(position, 1.0)), fireworkLightPosition);
  360. fireworkCosTheta = 1.0;
  361. vec3 newP = vec3( finalWorld * vec4(position, 1.0) );
  362. WorldPos = newP;
  363. TexCoords = uv;
  364. vNormal = normal;
  365. gl_Position = projection * view * vec4(newP , 1.0);
  366. }
  367. `;