vr.rs revision 89e35a551ee4b0bfcb3ede10da3b027dba1da7ef
16d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme/* 26d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Copyright (C) 2015 The Android Open Source Project 36d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 46d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 56d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * you may not use this file except in compliance with the License. 66d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * You may obtain a copy of the License at 76d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 86d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * http://www.apache.org/licenses/LICENSE-2.0 96d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Unless required by applicable law or agreed to in writing, software 116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * See the License for the specific language governing permissions and 146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * limitations under the License. 156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 17782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov#pragma version(1) 186d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme#pragma rs java_package_name(com.example.android.rs.vr.engine) 19d633f072552815301a559520a1f93eb7e79ba319Felipe Leme#pragma rs_fp_relaxed 20d633f072552815301a559520a1f93eb7e79ba319Felipe Leme 210f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov#define FLOAT_MAX 3.4028234E30f 22436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme#define JITTER_LENGTH 3457 230f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganovfloat jitter[JITTER_LENGTH]; 246d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemefloat3 s; 26782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovfloat3 dx; 27782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovfloat3 dy; 28640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemefloat3 dz; 29640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemefloat zoomFactor; 3000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganovrs_matrix4x4 matrix4; 316d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemers_matrix3x3 matrix3; 326d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeuchar4 base_color; 336d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemestatic float3 mLight; 346d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemestatic float rscale; 356d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 36640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme// material color 376d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemers_allocation opacity; 386d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemers_allocation color_map; 396d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 406d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemestatic void fillJitter() { 4100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov for (int i = 0; i < JITTER_LENGTH; i++) { 4200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov jitter[i] = (rsRand(rscale)+rsRand(rscale)+rsRand(rscale))/3; 4300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov } 446d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme} 456d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 46782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovvoid setup_vectors() { 476d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme s = rsMatrixMultiply(&matrix4, (float3) {0.5f, 0.5f, 0.5f}).xyz; 486d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme dx = rsMatrixMultiply(&matrix3, (float3) {1.f, 0.f, 0.f}); 49782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov dy = rsMatrixMultiply(&matrix3, (float3) {0.f, 1.f, 0.f}); 50640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme dz = rsMatrixMultiply(&matrix3, (float3) {0.f, 0.f, 1.f}); 51640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme zoomFactor = dz.x * dz.x + dz.y * dz.y + dz.z * dz.z; 525311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme zoomFactor /= dx.x * dx.x + dx.y * dx.y + dx.z * dx.z; 5300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov base_color.r = 0; 540f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov base_color.g = 0; 556d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme base_color.b = 0; 560f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov base_color.a = 255; 570f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 580f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float3 mLightRelitvePos = (float3) {0.f, 0.7071f, -0.7071f}; // light relitve to camera 595311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme mLight = mLightRelitvePos.x + dx + mLightRelitvePos.y * dy + mLightRelitvePos.z * dz; 6000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov mLight = normalize(mLight); 610f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov rscale = 1.5f/length(dz); 626d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme fillJitter(); 636d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme} 646d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 65640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemestatic float triLinear(float v_0_0_0, float v_0_0_1, float v_0_1_0, float v_0_1_1, 660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_1_0_0, float v_1_0_1, float v_1_1_0, float v_1_1_1, 67436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float3 delta) { 68436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float v_0_0 = mix(v_0_0_0, v_0_0_1, delta.x); 69436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float v_0_1 = mix(v_0_1_0, v_0_1_1, delta.x); 70640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float v_1_0 = mix(v_1_0_0, v_1_0_1, delta.x); 710f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_1_1 = mix(v_1_1_0, v_1_1_1, delta.x); 72436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float v_0 = mix(v_0_0, v_0_1, delta.y); 73436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float v_1 = mix(v_1_0, v_1_1, delta.y); 74436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float v = mix(v_0, v_1, delta.z); 755311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme return v; 765311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme} 775311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 785311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Lemers_allocation bricks; 795311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Lemers_allocation brick_index; 805311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Lemeint brick_dimx; 8100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganovint brick_dimy; 8200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganovint brick_dimz; 8300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov 8400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganovstatic int isInBrick(int3 p) { 8500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov int bx = p.x >> 5; 860f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov int by = p.y >> 5; 870f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov int bz = p.z >> 5; 88436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme int brickno = bx + (by + brick_dimy * bz) * brick_dimx; 89436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 90436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme brickno *= 32 * 32; 910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov int off = brickno + (p.z & 0x1F) * 32 + (p.y & 0x1F); 920f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov uint slice = rsGetElementAt_uint(bricks, off); 93436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme return slice & (1 << (p.x & 0x1F)); 94436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme} 956d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 966d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemers_allocation volume; 976d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemers_allocation zbuff; 986d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemebool debug = true; 9900c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov 10078696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Lemeuchar4 __attribute__ ((kernel)) draw_z_buffer(float2 in, uint32_t x, uint32_t y) { 1010f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov uchar4 out = base_color; 1025311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 1035311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float zsuface = in.x + .5f; 10400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float zstart = zsuface; 10500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float zend = in.y - 2.f;//0.5f; 10600c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float zlen = zend - zstart; 1076d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 1086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme if (zstart == FLOAT_MAX || zlen < 0) { 1096d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme return out; 1100f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1110f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 1126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float3 p = s + x * dx + y * dy + dz * zstart; 1136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float zb = zend; 114640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme int izlen = (int) zlen; 115640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float light = 1; 1165311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float4 total_color = (float4) {0.f, 0.f, 0.f, 0.f}; 11700c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov 1180f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (false) { // show the walls only used for debuging 1190f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov int3 ip = convert_int3(p); 1200f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov ip = clamp(ip, 4, 500); 1216d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme short pix = rsGetElementAt_short(volume, ip.x, ip.y, ip.z); 122eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov 12300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov int intensity = (((short) pix) & 0xFFFF); 124eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov // intensity = clamp(intensity,0,400); 1256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme uchar4 color = rsGetElementAt_uchar4(color_map, intensity * 2); 126eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov // int op = rsGetElementAt_uchar(opacity, intensity); 127eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov 12800c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov out.r = color.r; 1296d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme out.g = color.g; 1306d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme out.b = color.b; 1316d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme out.a = 255; 1325311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme return out; 1335311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme } 1345311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme { 1355311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme int3 ip = convert_int3(p); 1365311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 1375311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme if (isInBrick(ip)) { // isInBrick(ip)) { 1385311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 1395311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float3 delta = p - convert_float3(ip); 1405311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme // TODO switch to rsAllocationVLoadX_short2 141640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme // short2 tmps = rsAllocationVLoadX_short2(volume, ip.x + 0, ip.y + 0, ip.z + 0); 142436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme // float2 tmp = convert_float2(tmps); 1430f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_0_0_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z + 0); 144782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_0_0_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z + 0); 1450f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 14600c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float v_0_1_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 0); 147782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_0_1_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 0); 148782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_1_0_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z + 1); 149782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_1_0_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z + 1); 150782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_1_1_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 1); 151782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_1_1_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 1); 1520f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v = triLinear(v_0_0_0, v_0_0_1, v_0_1_0, v_0_1_1, 1530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov v_1_0_0, v_1_0_1, v_1_1_0, v_1_1_1, 154782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov delta); 155436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme int intensity = (((short) v) & 0xFFFF); 156640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme uchar op = rsGetElementAt_uchar(opacity, intensity); 157782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov 158640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme if (op != 0) { // near the surface "broken" 159782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov 160782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float sdx = rsGetElementAt_float2(zbuff, max(0, (int) x - 1), y).x - in.x; 161782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float sdy = rsGetElementAt_float2(zbuff, x, max(0, (int) y - 1)).x - in.x; 162640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float dot_prod = sqrt(1 / (1 + (sdy * sdy + sdx * sdx) * zoomFactor)); 16300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float opf = op * (1/255.f); 164782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov uchar4 color = rsGetElementAt_uchar4(color_map, intensity * 2); 165782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov uchar4 mat = rsGetElementAt_uchar4(color_map, intensity * 2 + 1); 166436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float4 fcolor = convert_float4(color);; 167782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov 1680f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float ambient = mat.x * (1/255.f); 1690f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov // float specular = mat.y * (1/255.f); 170436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme float diffuse = mat.z * (1/255.f); 171782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float lop = (ambient + diffuse * dot_prod) * light * opf; 17200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov light -= opf; 173436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme total_color += fcolor * lop; 174782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov zb = zstart; 175436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 1760f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1770f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1780f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 179436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme p += dz * jitter[(x+(y<<11))%JITTER_LENGTH]; 180436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 181436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme if (light > 0) { 182436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme for (int k = 0; k < izlen - 1; k++) { 183640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme 184640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme int3 ip = convert_int3(p); 185640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme if (isInBrick(ip)) { 186640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float3 delta = p - convert_float3(ip); 187640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme 188640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float v_0_0_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z + 0); 189640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float v_0_0_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z + 0); 19082e3793c15298f9c62edee23259c116606f10911Felipe Leme float v_0_1_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 0); 191640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float v_0_1_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 0); 1926d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float v_1_0_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z + 1); 1936d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float v_1_0_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z + 1); 194782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov float v_1_1_0 = (float) rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 1); 195640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme float v_1_1_1 = (float) rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 1); 1966d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float v = triLinear(v_0_0_0, v_0_0_1, v_0_1_0, v_0_1_1, 19700c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov v_1_0_0, v_1_0_1, v_1_1_0, v_1_1_1, 1985311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme delta); 1995311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme int intensity = (((short) v) & 0xFFFF); 2006d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme uchar op = rsGetElementAt_uchar(opacity, intensity); 201640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme 2020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (op != 0) { 2035311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 2045311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float3 v; 2055311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float3 vn; 2065311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 2075311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_0_2 = rsGetElementAt_short(volume, ip.x + 2, ip.y + 0, ip.z + 0); 2085311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_1_2 = rsGetElementAt_short(volume, ip.x + 2, ip.y + 1, ip.z + 0); 2095311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_0_2 = rsGetElementAt_short(volume, ip.x + 2, ip.y + 0, ip.z + 1); 2105311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_1_2 = rsGetElementAt_short(volume, ip.x + 2, ip.y + 1, ip.z + 1); 21124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme v.x = triLinear(v_0_0_1, v_0_0_2, v_0_1_1, v_0_1_2, 2125311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme v_1_0_1, v_1_0_2, v_1_1_1, v_1_1_2, 2135311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme delta); 2145311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 2155311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_0_n = rsGetElementAt_short(volume, ip.x - 1, ip.y + 0, ip.z + 0); 2165311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_1_n = rsGetElementAt_short(volume, ip.x - 1, ip.y + 1, ip.z + 0); 2175311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_0_n = rsGetElementAt_short(volume, ip.x - 1, ip.y + 0, ip.z + 1); 2185311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_1_n = rsGetElementAt_short(volume, ip.x - 1, ip.y + 1, ip.z + 1); 2195311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme vn.x = triLinear(v_0_0_n, v_0_0_0, v_0_1_n, v_0_1_0, 2205311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme v_1_0_n, v_1_0_0, v_1_1_n, v_1_1_0, 2215311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme delta); 2225311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme 2235311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_2_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 2, ip.z + 0); 2245311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_0_2_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 2, ip.z + 0); 2255311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_2_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 2, ip.z + 1); 2265311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_1_2_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 2, ip.z + 1); 2275311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme v.y = triLinear(v_0_1_0, v_0_1_1, v_0_2_0, v_0_2_1, 2285311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme v_1_1_0, v_1_1_1, v_1_2_0, v_1_2_1, 2290f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov delta); 2300f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 2310f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_0_n_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 0); 2320f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_0_n_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 0); 2330f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_1_n_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 1); 2340f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_1_n_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 1); 2355311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme vn.y = triLinear(v_0_n_0, v_0_n_1, v_0_0_0, v_0_0_1, 2365311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme v_1_n_0, v_1_n_1, v_1_0_0, v_1_0_1, 2370f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov delta); 2380f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 2390f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_n_0_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z - 1); 2400f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_n_0_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z - 1); 2415311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme float v_n_1_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z - 1); 2420f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_n_1_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z - 1); 2430f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov vn.z = triLinear(v_n_0_0, v_n_0_1, v_n_1_0, v_n_1_1, 2440f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov v_0_0_0, v_0_0_1, v_0_1_0, v_0_1_1, 2455311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme delta); 2466d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2476d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float v_2_0_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 0, ip.z + 2); 2486d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float v_2_0_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 0, ip.z + 2); 2490f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float v_2_1_0 = rsGetElementAt_short(volume, ip.x + 0, ip.y + 1, ip.z + 2); 25000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float v_2_1_1 = rsGetElementAt_short(volume, ip.x + 1, ip.y + 1, ip.z + 2); 25100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov v.z = triLinear(v_1_0_0, v_1_0_1, v_1_1_0, v_1_1_1, 25200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov v_2_0_0, v_2_0_1, v_2_1_0, v_2_1_1, 25300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov delta); 25400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov 2556d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float3 dv = normalize(v - vn); 2560f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float dot_prod = dot(dv, dz); 2570f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float opf = op / 255.f; 2580f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 25900c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov uchar4 color = rsGetElementAt_uchar4(color_map, intensity * 2); 26024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme uchar4 mat = rsGetElementAt_uchar4(color_map, intensity * 2 + 1); 26100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov float4 fcolor = convert_float4(color);; 2620f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 2636d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme // float3 mLight = (float3) {0,-1,0}; 2646d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float3 normal = dv; 2650f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float3 r = 2 * normal * dot(mLight, normal) - mLight; 2660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov float spec = dot(r, dz); 2670f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 2680f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov // Eye point in this space is in the direction (0,0,-1) 2696d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme // Spec * Math.pow(R_z , P) lets use power == 2 (cheap) 2706d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2716d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float ambient = mat.x * (1/255.f); // ambient 2726d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float specular = mat.y * (1/255.f); // specular not used right now 2736d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float diffuse = mat.z * (1/255.f);// diffuse 2746d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme float lop = (ambient + diffuse * dot_prod + specular * pow(spec, 10)) * light * opf; 2756d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme light -= opf; 2766d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme total_color += fcolor * lop; 2776d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2786d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme zb = zstart + k; 2796d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme if (light <= 0) { 2806d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme break; 2816d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2826d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 283eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov } 28400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov 28500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov p += dz; 2865311206f3434d631c6ea81ab2e76a46ca18119b6Felipe Leme } 2870f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 2886d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2896d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme out = convert_uchar4(clamp(total_color, 0.f, 255.f)); 290782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov out.a = 0xFF; 2916d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2920f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return out; 2930f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov} 2940f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov