Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/svm/svm_image.h
| Show All 10 Lines | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | * distributed under the License is distributed on an "AS IS" BASIS, | ||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint flags) | ccl_device float4 svm_image_texture(const KernelGlobals *kg, int id, float x, float y, uint flags) | ||||
| { | { | ||||
| if (id == -1) { | if (id == -1) { | ||||
| return make_float4( | return make_float4( | ||||
| TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A); | TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A); | ||||
| } | } | ||||
| float4 r = kernel_tex_image_interp(kg, id, x, y); | float4 r = kernel_tex_image_interp(kg, id, x, y); | ||||
| const float alpha = r.w; | const float alpha = r.w; | ||||
| Show All 11 Lines | |||||
| } | } | ||||
| /* Remap coordinate from 0..1 box to -1..-1 */ | /* Remap coordinate from 0..1 box to -1..-1 */ | ||||
| ccl_device_inline float3 texco_remap_square(float3 co) | ccl_device_inline float3 texco_remap_square(float3 co) | ||||
| { | { | ||||
| return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f; | return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f; | ||||
| } | } | ||||
| ccl_device void svm_node_tex_image( | ccl_device_noinline int svm_node_tex_image( | ||||
| KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) | const KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int offset) | ||||
| { | { | ||||
| uint co_offset, out_offset, alpha_offset, flags; | uint co_offset, out_offset, alpha_offset, flags; | ||||
| svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); | svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); | ||||
| float3 co = stack_load_float3(stack, co_offset); | float3 co = stack_load_float3(stack, co_offset); | ||||
| float2 tex_co; | float2 tex_co; | ||||
| if (node.w == NODE_IMAGE_PROJ_SPHERE) { | if (node.w == NODE_IMAGE_PROJ_SPHERE) { | ||||
| Show All 9 Lines | ccl_device_noinline int svm_node_tex_image( | ||||
| } | } | ||||
| /* TODO(lukas): Consider moving tile information out of the SVM node. | /* TODO(lukas): Consider moving tile information out of the SVM node. | ||||
| * TextureInfo seems a reasonable candidate. */ | * TextureInfo seems a reasonable candidate. */ | ||||
| int id = -1; | int id = -1; | ||||
| int num_nodes = (int)node.y; | int num_nodes = (int)node.y; | ||||
| if (num_nodes > 0) { | if (num_nodes > 0) { | ||||
| /* Remember the offset of the node following the tile nodes. */ | /* Remember the offset of the node following the tile nodes. */ | ||||
| int next_offset = (*offset) + num_nodes; | int next_offset = offset + num_nodes; | ||||
| /* Find the tile that the UV lies in. */ | /* Find the tile that the UV lies in. */ | ||||
| int tx = (int)tex_co.x; | int tx = (int)tex_co.x; | ||||
| int ty = (int)tex_co.y; | int ty = (int)tex_co.y; | ||||
| /* Check that we're within a legitimate tile. */ | /* Check that we're within a legitimate tile. */ | ||||
| if (tx >= 0 && ty >= 0 && tx < 10) { | if (tx >= 0 && ty >= 0 && tx < 10) { | ||||
| int tile = 1001 + 10 * ty + tx; | int tile = 1001 + 10 * ty + tx; | ||||
| /* Find the index of the tile. */ | /* Find the index of the tile. */ | ||||
| for (int i = 0; i < num_nodes; i++) { | for (int i = 0; i < num_nodes; i++) { | ||||
| uint4 tile_node = read_node(kg, offset); | uint4 tile_node = read_node(kg, &offset); | ||||
| if (tile_node.x == tile) { | if (tile_node.x == tile) { | ||||
| id = tile_node.y; | id = tile_node.y; | ||||
| break; | break; | ||||
| } | } | ||||
| if (tile_node.z == tile) { | if (tile_node.z == tile) { | ||||
| id = tile_node.w; | id = tile_node.w; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* If we found the tile, offset the UVs to be relative to it. */ | /* If we found the tile, offset the UVs to be relative to it. */ | ||||
| if (id != -1) { | if (id != -1) { | ||||
| tex_co.x -= tx; | tex_co.x -= tx; | ||||
| tex_co.y -= ty; | tex_co.y -= ty; | ||||
| } | } | ||||
| } | } | ||||
| /* Skip over the remaining nodes. */ | /* Skip over the remaining nodes. */ | ||||
| *offset = next_offset; | offset = next_offset; | ||||
| } | } | ||||
| else { | else { | ||||
| id = -num_nodes; | id = -num_nodes; | ||||
| } | } | ||||
| float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, flags); | float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, flags); | ||||
| if (stack_valid(out_offset)) | if (stack_valid(out_offset)) | ||||
| stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); | stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); | ||||
| if (stack_valid(alpha_offset)) | if (stack_valid(alpha_offset)) | ||||
| stack_store_float(stack, alpha_offset, f.w); | stack_store_float(stack, alpha_offset, f.w); | ||||
| return offset; | |||||
| } | } | ||||
| ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_tex_image_box(const KernelGlobals *kg, | ||||
| ShaderData *sd, | |||||
| float *stack, | |||||
| uint4 node) | |||||
| { | { | ||||
| /* get object space normal */ | /* get object space normal */ | ||||
| float3 N = sd->N; | float3 N = sd->N; | ||||
| N = sd->N; | N = sd->N; | ||||
| object_inverse_normal_transform(kg, sd, &N); | object_inverse_normal_transform(kg, sd, &N); | ||||
| /* project from direction vector to barycentric coordinates in triangles */ | /* project from direction vector to barycentric coordinates in triangles */ | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | ccl_device_noinline void svm_node_tex_image_box(const KernelGlobals *kg, | ||||
| } | } | ||||
| if (stack_valid(out_offset)) | if (stack_valid(out_offset)) | ||||
| stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); | stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); | ||||
| if (stack_valid(alpha_offset)) | if (stack_valid(alpha_offset)) | ||||
| stack_store_float(stack, alpha_offset, f.w); | stack_store_float(stack, alpha_offset, f.w); | ||||
| } | } | ||||
| ccl_device void svm_node_tex_environment(KernelGlobals *kg, | ccl_device_noinline void svm_node_tex_environment(const KernelGlobals *kg, | ||||
| ShaderData *sd, | ShaderData *sd, | ||||
| float *stack, | float *stack, | ||||
| uint4 node) | uint4 node) | ||||
| { | { | ||||
| uint id = node.y; | uint id = node.y; | ||||
| uint co_offset, out_offset, alpha_offset, flags; | uint co_offset, out_offset, alpha_offset, flags; | ||||
| uint projection = node.w; | uint projection = node.w; | ||||
| svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); | svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); | ||||
| float3 co = stack_load_float3(stack, co_offset); | float3 co = stack_load_float3(stack, co_offset); | ||||
| Show All 18 Lines | |||||