blob: 23c1bc64ec8756fc0b0564f9cdc69def633f25ea [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.vr.engine)
#pragma rs_fp_relaxed
int size;
int z;
rs_allocation volume;
static float3 nylander(float3 p, int n) {
float3 out;
float r = length(p);
float phi = atan2(p.y, p.x);
float theta = acos(p.z / r);
float rn = pow(r, n);
out.x = sin(n * theta) * cos(n * phi);
out.y = sin(n * theta) * sin(n * phi);
out.z = cos(n * theta);
return out * rn;
}
/**
* 8 x faster than the above for n = 3
*/
static float3 nylander3(float3 p) {
float3 out = (float3){0.f, 0.f, 0.f};
float xy2 = p.x * p.x + p.y * p.y;
if (xy2 == 0) return out;
float z23x2y2 = (3 * p.z * p.z - p.x * p.x - p.y * p.y);
out.x = (z23x2y2 * p.x * (p.x * p.x - 3 * p.y * p.y)) / xy2;
out.y = (z23x2y2 * p.y * (3 * p.x * p.x - p.y * p.y)) / xy2;
out.z = p.z * (p.z * p.z - 3 * p.x * p.x - 3 * p.y * p.y);
return out;
}
static float vsize(float3 p) {
return sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
}
short __attribute__((kernel)) mandelbulb(uint32_t x, uint32_t y) {
int size2 = size / 2;
if (z < size2) {
return 256-4*(size2-z+4)*hypot((float)x-size2,(float)y-size2) / size2 ;
}
float3 c = (float3) {(float) x, (float) y, (float) z};
c = ((c - size2) / (size2 * .9f));
int loop = 25;
float3 p = c;
float len;
for (int i = 0; i < loop; i++) {
// p = nylander(p, 3) + c;
p = nylander3(p) + c;
len = fast_length(p);
if (len > 2.f) return 255 - loop*10;
if (len < .3f) return loop*10;
}
len = length(p);
return (short) (255 - (len * 255) / 4);
}
void __attribute__((kernel)) copy(short in, uint32_t x, uint32_t y) {
rsSetElementAt_short(volume, in, x, y, z);
}