1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package shade.shaders;
 26 
 27 import hat.Accelerator;
 28 import hat.Accelerator.Compute;
 29 import hat.ComputeContext;
 30 import hat.ComputeContext.Kernel;
 31 import hat.KernelContext;
 32 import hat.NDRange;
 33 import hat.backend.Backend;
 34 import hat.buffer.F32Array;
 35 import hat.buffer.Uniforms;
 36 
 37 import jdk.incubator.code.Reflect;
 38 import optkl.ifacemapper.MappableIface;
 39 import shade.ShaderViewer;
 40 
 41 import java.lang.invoke.MethodHandles;
 42 import hat.types.vec2;
 43 import hat.types.vec3;
 44 import hat.types.vec4;
 45 import hat.types.mat2;
 46 import static hat.types.F32.*;
 47 import static hat.types.mat2.*;
 48 import static hat.types.vec2.*;
 49 import static hat.types.vec3.*;
 50 import static hat.types.vec4.*;
 51 /*
 52 // https://www.shadertoy.com/view/MdXSzS
 53 // The Big Bang - just a small explosion somewhere in a massive Galaxy of Universes.
 54 // Outside of this there's a massive galaxy of 'Galaxy of Universes'... etc etc. :D
 55 
 56 // To fake a perspective it takes advantage of the screen being wider than it is tall.
 57 
 58 void mainImage( out vec4 fragColor, in vec2 fragCoord )
 59 {
 60    vec2 uv = (fragCoord.xy / iResolution.xy) - .5;
 61    float t = iTime * .1 + ((.25 + .05 * sin(iTime * .1))/(length(uv.xy) + .07)) * 2.2;
 62    float si = sin(t);
 63    float co = cos(t);
 64    mat2 ma = mat2(co, si, -si, co);
 65 
 66    float v1, v2, v3;
 67    v1 = v2 = v3 = 0.0;
 68 
 69    float s = 0.0;
 70    for (int i = 0; i < 90; i++)
 71    {
 72       vec3 p = s * vec3(uv, 0.0);
 73       p.xy *= ma;
 74       p += vec3(.22, .3, s - 1.5 - sin(iTime * .13) * .1);
 75       for (int i = 0; i < 8; i++){
 76          p = abs(p) / dot(p,p) - 0.659;
 77       }
 78       v1 += dot(p,p) * .0015 * (1.8 + sin(length(uv.xy * 13.0) + .5  - iTime * .2));
 79       v2 += dot(p,p) * .0013 * (1.5 + sin(length(uv.xy * 14.5) + 1.2 - iTime * .3));
 80       v3 += length(p.xy*10.) * .0003;
 81       s  += .035;
 82    }
 83 
 84    float len = length(uv);
 85    v1 *= smoothstep(.7, .0, len);
 86    v2 *= smoothstep(.5, .0, len);
 87    v3 *= smoothstep(.9, .0, len);
 88 
 89    vec3 col = vec3( v3 * (1.5 + sin(iTime * .2) * .4),(v1 + v3) * .3, v2)
 90                 + smoothstep(0.2, .0, len) * .85 + smoothstep(.0, .6, v3) * .3;
 91 
 92    fragColor=vec4(min(pow(abs(col), vec3(1.2)), 1.0), 1.0);
 93 }
 94 
 95  */
 96 //https://www.shadertoy.com/view/MdXSzS
 97 public class GalaxyShader {
 98     @Reflect
 99     public static vec4 createPixel(vec2 fres, float ftime, vec2 fmouse, vec2 fragCoord){
100         vec2 uv = sub(div(fragCoord, fres), .5f);
101         float t = ftime * .1f + ((.25f + .05f * sin(ftime * .1f))/(length(uv) + .07f)) * 2.2f;
102         float si = sin(t);
103         float co = cos(t);
104         mat2 ma = mat2(co, si, -si, co);
105 
106         float v1=0f;
107         float v2=0f;
108         float v3=0f;
109 
110         float s = 0.0f;
111         for (int i = 0; i < 90; i++) {
112             vec3 p = mul(s, vec3(uv.x(),uv.y(), 0.0f));
113             vec2 p_xy = mul(vec2(p.x(),p.y()),ma);p = vec3(p_xy.x(),p_xy.y(),p.z());  //p.xy *= ma;
114             p = add(p,vec3(.22f, .3f, s - 1.5f - sin(ftime * .13f) * .1f));
115             for (int i2 = 0; i2 < 8; i2++)   {
116                 p = sub(div(abs(p), dot(p,p)),0.659f);
117             }
118 
119             v1 += dot(p,p) * .0015f * (1.8f + sin(length(mul(uv, 13.0f)) + .5f  - ftime * .2f));
120             v2 += dot(p,p) * .0013f * (1.5f + sin(length(mul(uv, 14.5f)) + 1.2f - ftime * .3f));
121             v3 += length(mul(vec2(p.x(), p.y()),10f)) * .0003f;
122             s  += .035f;
123         }
124 
125         float len = length(uv);
126         v1 *= smoothstep(.7f, .0f, len);
127         v2 *= smoothstep(.5f, .0f, len);
128         v3 *= smoothstep(.9f, .0f, len);
129 
130         vec3 col = add(vec3( v3 * (1.5f + sin(ftime * .2f) * .4f), (v1 + v3) * .3f, v2),
131                  smoothstep(0.2f, .0f, len) * .85f + smoothstep(.0f, .6f, v3) * .3f);
132 
133         return normalize(vec4(min(pow(abs(col), vec3(1.2f)), 1.0f), 1.0f));
134     }
135 /*
136     @Reflect
137     public static vec4 createPixel1(vec2 fres, float ftime, vec2 fmouse, vec2 fragCoord){
138         //ut vec4 O, vec2 I
139         vec4 O=vec4(0f);
140         vec3 p= vec3(0f);
141         vec3 // Ray position
142                 r = normalize(sub(vec3(add(fragCoord,fragCoord),0f) , vec3(fres.x(), fres.y(), fres.y()))); // Ray direction
143                 vec3 a = normalize(tan(add(ftime*.2f,vec3(0f,1f,2f)))); // Rotation axis
144         float i=0; // Iterator
145                 float t=0f; // Distance
146                 float v=0f; // Density
147                 float n=0f; // Noise iterator
148         // Raymarching loop
149 
150         for (O=add(O,i); i++<60.f;t+=v*.06f){
151             p=mul(t,r);
152             // Move camera back
153             p = add(p, vec3(0f,0f,5f));
154 
155             // Rotate around rotation axis
156             p = sub(mul(mul(a,dot(a,p)),2f),p);
157             // Turbulence
158             for (n=-.3f; n++<9f; p=add(p,mul(2f,div(sin(add(mul(p,n),ftime*n),n)))));
159             // Density based on distance to sphere
160             v = abs(length(p)-2.f)+.01f;
161             // Color accumulation based on iteration and density
162             O=add(O,div(exp(sin(add((i*.2f),vec4(0f,2f,4f,0f)))),v));
163         }
164         // Tone mapping
165         O = F32.tanh(O/2e2f);
166     return O;
167     }
168 */
169     @Reflect public static vec4 mainImage(Uniforms uniforms, vec4 fragColor, vec2 fragCoord) {
170         return createPixel(vec2.vec2(uniforms.iResolution().x(),uniforms.iResolution().y()),uniforms.iTime(),vec2.vec2(uniforms.iMouse().x(),uniforms.iMouse().y()),fragCoord);
171     }
172 
173 
174     @Reflect
175     public static void penumbra(@MappableIface.RO KernelContext kc, @MappableIface.RO Uniforms uniforms, @MappableIface.RW F32Array f32Array) {
176         int width = (int) uniforms.iResolution().x();
177         int height = (int) uniforms.iResolution().y();
178         var fragColor = mainImage(uniforms, vec4.vec4(0f), vec2.vec2((float)(kc.gix % width), (float)(height-(kc.gix / width))));
179         f32Array.array(kc.gix * 3, fragColor.x());
180         f32Array.array(kc.gix * 3+1, fragColor.y());
181         f32Array.array(kc.gix * 3+2, fragColor.z());
182     }
183 
184     @Reflect
185     static public void compute(final ComputeContext computeContext, @MappableIface.RO Uniforms uniforms, @MappableIface.RO F32Array image, int width, int height) {
186         computeContext.dispatchKernel(NDRange.of1D(width * height), (@Reflect Kernel) kc -> penumbra(kc, uniforms, image));
187     }
188 
189     public static void update(  Accelerator acc, Uniforms uniforms, F32Array f32Array, int width, int height) {
190         acc.compute((@Reflect Compute) cc -> compute(cc, uniforms, f32Array, width, height));
191     }
192 
193     static void main(String[] args) {
194         var acc = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
195         var shader = ShaderViewer.of(acc, GalaxyShader.class,1200, 800);
196         shader.startLoop((uniforms, f32Array) -> update( acc, uniforms, f32Array, shader.view.getWidth(), shader.view.getHeight()));
197     }
198 }