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.ComputeContext;
 29 import hat.Accelerator.Compute;
 30 import hat.ComputeContext.Kernel;
 31 import hat.KernelContext;
 32 import hat.NDRange;
 33 import hat.backend.Backend;
 34 
 35 import  static hat.types.F32.*;
 36 
 37 import hat.buffer.F32Array;
 38 import hat.types.vec2;
 39 import static hat.types.vec2.*;
 40 import hat.types.vec3;
 41 
 42 import static hat.types.vec3.*;
 43 import hat.types.vec4;
 44 import static hat.types.vec4.*;
 45 import jdk.incubator.code.Reflect;
 46 import optkl.ifacemapper.MappableIface;
 47 import hat.buffer.Uniforms;
 48 import shade.ShaderViewer;
 49 import java.lang.invoke.MethodHandles;
 50 
 51 /*
 52 void mainImage(out vec4 fragColor, in vec2 fragCoord)
 53 {
 54     vec2 uv = (2.0 * fragCoord - iResolution.xy) / min(iResolution.x, iResolution.y);
 55 
 56     for (float i = 2.0; i < 13.0; i++)
 57     {
 58         uv.x += 0.4 / i * cos(i * 2.0 * uv.y + iTime) * cos(i * 1.5 * uv.y + iTime);
 59         uv.y += 0.4 / i * cos(i * 2.0 * uv.x + iTime);
 60     }
 61 
 62     vec3 col = cos(iTime / 4.0 - uv.xyx);
 63     col = step(0.0, col);
 64     col.b = col.g;
 65 
 66     // alpha for cineshader
 67     float alpha = 0.0;
 68     if (col.g > 0.0 || col.r > 0.0) alpha = 0.6;
 69 
 70     fragColor = vec4(col, alpha);
 71 }
 72 
 73 ** SHADERDATA
 74 {
 75    "title": "Painting with maths",
 76    "description": "Simple shader that gives an effect of painting. https://gubebra.itch.io/",
 77    "model": "person"
 78 }
 79 
 80  */
 81 
 82 //https://www.shadertoy.com/view/W33XW2
 83 public class PaintShader  {
 84     @Reflect
 85     public static vec4 createPixel(vec2 fres, float ftime, vec2 fmouse, vec2 fragCoord){
 86         vec2 uv = div(sub(mul(2.0f,fragCoord),fres), min(fres.x(), fres.y()));
 87         for (float i = 2f; i < 13f; i++) {
 88             var cosyTime = cos(i * 2.0f * uv.y() + ftime);
 89             var cosxTime = cos(i * 2.0f * uv.x() + ftime);
 90             var dx = 0.4f / i * cosyTime *cos(i * 1.5f * uv.y() + ftime);
 91             var dy = 0.4f / i * cosxTime;
 92             uv = vec2.add(uv, vec2(dx,dy));
 93         }
 94         vec3 col = cos(div(ftime, vec3.sub(4.0f, vec3(uv.x(),uv.y(),uv.x()))));
 95         col = step(vec3.vec3(0.0f), col);
 96         col = vec3(col.x(),col.y(),col.y());
 97 
 98         return vec4(col, 1f);
 99     }
100     @Reflect public static vec4 mainImage(Uniforms uniforms, vec4 fragColor, vec2 fragCoord) {
101         return createPixel(vec2.vec2(uniforms.iResolution().x(),uniforms.iResolution().y()),uniforms.iTime(),vec2.vec2(uniforms.iMouse().x(),uniforms.iMouse().y()),fragCoord);
102 
103     }
104     @Reflect
105     public static void penumbra(@MappableIface.RO KernelContext kc, @MappableIface.RO Uniforms uniforms, @MappableIface.RW F32Array f32Array) {
106         int width = (int) uniforms.iResolution().x();
107         int height = (int) uniforms.iResolution().y();
108         var fragColor = mainImage(uniforms, vec4.vec4(0f), vec2.vec2((float)(kc.gix % width), (float)(height-(kc.gix / width))));
109         f32Array.array(kc.gix * 3, fragColor.x());
110         f32Array.array(kc.gix * 3+1, fragColor.y());
111         f32Array.array(kc.gix * 3+2, fragColor.z());
112     }
113 
114     @Reflect
115     static public void compute(final ComputeContext computeContext, @MappableIface.RO Uniforms uniforms, @MappableIface.RO F32Array image, int width, int height) {
116         computeContext.dispatchKernel(NDRange.of1D(width * height), (@Reflect Kernel) kc -> penumbra(kc, uniforms, image));
117     }
118 
119     private static void update(  Accelerator acc, Uniforms uniforms, F32Array f32Array, int width, int height) {
120         acc.compute((@Reflect Compute) cc -> compute(cc, uniforms, f32Array, width, height));
121     }
122 
123     static void main(String[] args) {
124         var acc = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
125         var shader = ShaderViewer.of(acc, PaintShader.class,1024, 1024);
126         shader.startLoop((uniforms, f32Array) -> update( acc, uniforms, f32Array, shader.view.getWidth(), shader.view.getHeight()));
127     }
128 
129 }