├── UVVisualizer ├── Example01.png ├── Example02.png ├── Example03.png ├── Example05.png ├── Example06.png ├── Example07.png ├── UVMapping.png ├── Example03_1.png ├── Example04_1.png ├── ShaderInspector.png ├── UVVisualizer.shader └── README.md ├── ColorChanger ├── ExamplePic1.png ├── ExamplePic2.png ├── ExamplePic3_1.png ├── ExamplePic3_2.png ├── README.md └── ColorChanger.shader ├── ColorGrid ├── ColorGridScreenshot.png ├── README.md └── ColorGrid.shader ├── UnlitAmbientOcclusion ├── Image01.png ├── Image02.png ├── Image03.png ├── README.md └── UnlitAO.shader ├── DissolveNoClip ├── README.md └── DissolveNoClip.shader ├── LICENSE └── README.md /UVVisualizer/Example01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example01.png -------------------------------------------------------------------------------- /UVVisualizer/Example02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example02.png -------------------------------------------------------------------------------- /UVVisualizer/Example03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example03.png -------------------------------------------------------------------------------- /UVVisualizer/Example05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example05.png -------------------------------------------------------------------------------- /UVVisualizer/Example06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example06.png -------------------------------------------------------------------------------- /UVVisualizer/Example07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example07.png -------------------------------------------------------------------------------- /UVVisualizer/UVMapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/UVMapping.png -------------------------------------------------------------------------------- /ColorChanger/ExamplePic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/ColorChanger/ExamplePic1.png -------------------------------------------------------------------------------- /ColorChanger/ExamplePic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/ColorChanger/ExamplePic2.png -------------------------------------------------------------------------------- /ColorChanger/ExamplePic3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/ColorChanger/ExamplePic3_1.png -------------------------------------------------------------------------------- /ColorChanger/ExamplePic3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/ColorChanger/ExamplePic3_2.png -------------------------------------------------------------------------------- /UVVisualizer/Example03_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example03_1.png -------------------------------------------------------------------------------- /UVVisualizer/Example04_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/Example04_1.png -------------------------------------------------------------------------------- /UVVisualizer/ShaderInspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UVVisualizer/ShaderInspector.png -------------------------------------------------------------------------------- /ColorGrid/ColorGridScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/ColorGrid/ColorGridScreenshot.png -------------------------------------------------------------------------------- /UnlitAmbientOcclusion/Image01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UnlitAmbientOcclusion/Image01.png -------------------------------------------------------------------------------- /UnlitAmbientOcclusion/Image02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UnlitAmbientOcclusion/Image02.png -------------------------------------------------------------------------------- /UnlitAmbientOcclusion/Image03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Demkeys/DemkeysUnityShaders/HEAD/UnlitAmbientOcclusion/Image03.png -------------------------------------------------------------------------------- /DissolveNoClip/README.md: -------------------------------------------------------------------------------- 1 | # DissolveNoClip shader 2 | #### An Unlit shader that implements a Dissolve effect using on transparency. It doesn't use clip/discard function. 3 | 4 | On certain platforms, due to the GPU architecture, using clip/discard can affect performance. This was my attempt at implementing Dissolve using only transparency. The math behind it is not perfect, but it gives you a fairly decent result. 5 | -------------------------------------------------------------------------------- /UnlitAmbientOcclusion/README.md: -------------------------------------------------------------------------------- 1 | #### Simple unlit shader that supports Ambient Occlusion maps. You can also set the AO strength to control how much the AO map affects the final color. 2 | 3 | #### Here are some screenshots: 4 | * AO Strenght: 0 5 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UnlitAmbientOcclusion/Image01.png) 6 | * AO Strenght: 0.5 7 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UnlitAmbientOcclusion/Image02.png) 8 | * AO Strenght: 1 9 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UnlitAmbientOcclusion/Image03.png) 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Abhinav a.k.a Demkeys 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DemkeysUnityShaders 2 | Unity shaders made for various purposes, written in Cg/HLSL. This is basically my collection of shaders that I'm making as I go along my journey of learning about the amazing world of shaders. There will be more and more shaders added to this over time. If these shaders help someone learn something, or help someone in any other way, great. Go ahead and use them for whatever purpose you see fit. 3 | 4 | * #### [UV Visualizer](https://github.com/Demkeys/DemkeysUnityShaders/tree/master/UVVisualizer) - Displays the UV mapping of a mesh as colors, allowing you to view the UV coordinates within the Unity Editor. 5 | * #### [Color Changer](https://github.com/Demkeys/DemkeysUnityShaders/tree/master/ColorChanger) - Debugging shader that can be used to change the color scheme of textures on your 3D models from within the Unity Editor. 6 | * #### [Unlit Ambient Occlusion](https://github.com/Demkeys/DemkeysUnityShaders/tree/master/UnlitAmbientOcclusion) - Simple unlit shader that supports Ambient Occlusions maps. 7 | * #### [DissolveNoClip](https://github.com/Demkeys/DemkeysUnityShaders/tree/master/DissolveNoClip) - Dissolve effect implemented using only transparency. No clip/discard. 8 | * #### [Color Grid](https://github.com/Demkeys/DemkeysUnityShaders/tree/master/ColorGrid) - A programmable color grid implemented in a fragment shader. The color grid executes instructions to perform operations. 9 | -------------------------------------------------------------------------------- /UnlitAmbientOcclusion/UnlitAO.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/UnlitAO" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _Color ("Color", Color) = (1,1,1,1) 7 | _AOTex ("AO Texture", 2D) = "white" {} 8 | _AOStr ("AO Strength", Range(0,1)) = 1 9 | } 10 | SubShader 11 | { 12 | Tags { "RenderType"="Opaque" } 13 | LOD 100 14 | 15 | Pass 16 | { 17 | CGPROGRAM 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | 21 | #include "UnityCG.cginc" 22 | 23 | struct appdata 24 | { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f 30 | { 31 | float2 uv : TEXCOORD0; 32 | float4 vertex : SV_POSITION; 33 | }; 34 | 35 | sampler2D _MainTex; 36 | float4 _MainTex_ST; 37 | fixed4 _Color; 38 | sampler2D _AOTex; 39 | float _AOStr; 40 | 41 | v2f vert (appdata v) 42 | { 43 | v2f o; 44 | o.vertex = UnityObjectToClipPos(v.vertex); 45 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 46 | return o; 47 | } 48 | 49 | fixed4 frag (v2f i) : SV_Target 50 | { 51 | // sample the texture 52 | fixed4 col = tex2D(_MainTex, i.uv); 53 | 54 | col *= _Color; 55 | fixed occlusion = lerp(1, tex2D(_AOTex, i.uv).r, _AOStr); 56 | 57 | col *= occlusion; 58 | return col; 59 | } 60 | ENDCG 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ColorGrid/README.md: -------------------------------------------------------------------------------- 1 | ## Color Grid 2 | 3 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/ColorGrid/ColorGridScreenshot.png) 4 | 5 | A programmable color grid implemented in a fragment shader. The color grid executes instructions to perform operations. 6 | 7 | Instruction format - (OpCode, Operand1, Operand2 and Operand3). 8 | 9 | Currently supported OpCodes: 10 | * 0 = set_color_op - Set current color. This color will be used when coloring pixels on the grid. 11 | * 1 = draw_pixel_op - Color a cell at (x,y) position. Params: x=opr1, y=opr2 12 | * 2 = draw_row_op - Fill row of cells at index. Params: index=opr1 13 | * 3 = draw_column_op - Fill column of cells at index. Params: index=opr1 14 | * 4 = randomize_grid - Fill each grid cell with a random color using seed for randomization. Params: seed=opr1 15 | * 5 = fill_grid_op - Fill all grid cells with current color. 16 | More operations might be added in the future. 17 | 18 | Color Grid has two modes: Normal and Debug. To enable debug mode set GRID_DEBUG to 1. In Debug mode you can set type out instructions directly in the shader without having to set it via script. 19 | 20 | * Normal Mode: 21 | * Set ins_arr via script. This is a Vector4 array containing instructions. 22 | * Set ins_count via script. This is the total number of instructions. 23 | * Set grid size by setting _MainTex's tiling, either via script, or in Inspector. 24 | * Color Grid will execute instructions from ins_arr. 25 | * Debug Mode: 26 | * In DebugIns() method: 27 | * Set op_data value. This is the instruction to execute. 28 | * Call decode_op_data(). 29 | * Repeat above two steps for every instruction. 30 | * Set grid size by setting _DbgGridSize x and y values in Inspector. 31 | * If using randomize_grid op, set _DbgSeed value in Inspector. 32 | * Color Grid will call DebugIns() method to execute instructions. 33 | 34 | To use Color Grid: 35 | * Create a material and attach the shader to the material. 36 | * Create a Quad in the scene and attach the material to the quad. 37 | 38 | ___NOTE: The Color Grid is implemented in the fragment shader, so the more pixels the rendered mesh is occupying on screen, the heavier the shader will become. This means that at bigger resolutions the shader can get heavier when the camera is close to the mesh. To get around this issue, use another camera to render the quad to a render texture, then use that render texture wherever. This way you can also have multiple copies of that Color Grid to display in multiple places.___ 39 | -------------------------------------------------------------------------------- /DissolveNoClip/DissolveNoClip.shader: -------------------------------------------------------------------------------- 1 | Shader "Unlit/DissolveNoClip" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _MainTexCol ("Texture Color", Color) = (1,1,1,1) 7 | _NoiseTex ("Noise Texture", 2D) = "white" {} 8 | _AlphaCutOff ("Alpha Cut Off", Range(0,1)) = 1 9 | _EdgeSize ("Edge Size", Range(0,0.5)) = 0.5 10 | _EdgeColor ("Edge Color", Color) = (1,1,1,1) 11 | } 12 | SubShader 13 | { 14 | Tags { "RenderQueue"="Transparent" } 15 | LOD 100 16 | ZWrite Off 17 | Blend SrcAlpha OneMinusSrcAlpha 18 | 19 | CGINCLUDE 20 | 21 | #include "UnityCG.cginc" 22 | 23 | struct appdata 24 | { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f 30 | { 31 | float2 uv : TEXCOORD0; 32 | float4 vertex : SV_POSITION; 33 | }; 34 | 35 | sampler2D _MainTex; 36 | float4 _MainTex_ST; 37 | fixed4 _MainTexCol; 38 | sampler2D _NoiseTex; 39 | fixed _AlphaCutOff; 40 | fixed _EdgeSize; 41 | fixed4 _EdgeColor; 42 | 43 | v2f vert (appdata v) 44 | { 45 | v2f o; 46 | o.vertex = UnityObjectToClipPos(v.vertex); 47 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 48 | return o; 49 | } 50 | 51 | fixed4 frag (v2f i) : SV_Target 52 | { 53 | fixed4 col = tex2D(_MainTex, i.uv); 54 | fixed4 noise = tex2D(_NoiseTex, i.uv); 55 | fixed dissolve = lerp(1,0,step(noise.r,_AlphaCutOff)); 56 | fixed dissolve2 = lerp(1,0,step(noise.r,_AlphaCutOff+_EdgeSize)); 57 | col *= _MainTexCol; 58 | _EdgeColor.rgb = lerp(col.rgb, _EdgeColor.rgb, 59 | smoothstep(0,0.1,_AlphaCutOff)); 60 | col.rgb = lerp(_EdgeColor.rgb, col.rgb, dissolve2); 61 | col.a = dissolve; 62 | col.a = saturate(col.a); 63 | return col; 64 | } 65 | ENDCG 66 | // Render inner faces 67 | Pass 68 | { 69 | Cull Front 70 | CGPROGRAM 71 | #pragma vertex vert 72 | #pragma fragment frag 73 | ENDCG 74 | } 75 | // Render outer faces 76 | Pass 77 | { 78 | Cull Back 79 | CGPROGRAM 80 | #pragma vertex vert 81 | #pragma fragment frag 82 | ENDCG 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /UVVisualizer/UVVisualizer.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/UV Visualizer" 2 | { 3 | Properties 4 | { 5 | _MaixTex01 ("Main Texture (white texture if left blank)", 2D) = "white" {} 6 | [Toggle] _ShowTexture ("ShowTexture", Float) = 0 7 | [KeywordEnum(Multiply,Add,Subtract,Divide,LerpMin,LerpMax)] 8 | _BlendMode ("Texture Blend Mode (if texture is shown)", Float) = 0 9 | } 10 | SubShader 11 | { 12 | Tags { "RenderQueue"="Geometry" } 13 | 14 | Pass 15 | { 16 | CGPROGRAM 17 | #pragma vertex vert 18 | #pragma fragment frag 19 | #include "UnityCG.cginc" 20 | 21 | sampler2D _MaixTex01; 22 | float4 _MaixTex01_ST; 23 | float _BlendMode; 24 | float _ShowTexture; 25 | 26 | void vert ( 27 | float4 pos : POSITION, 28 | out float4 opos : SV_POSITION, 29 | inout float4 texCoord0 : TEXCOORD0 30 | ) 31 | { 32 | opos = UnityObjectToClipPos(pos); 33 | 34 | // Texture coordinates without tiling and offset. 35 | texCoord0.zw = texCoord0.xy; 36 | 37 | // Texture coordinates with tiling and offset. 38 | texCoord0.xy = texCoord0.xy * _MaixTex01_ST.xy + _MaixTex01_ST.zw; 39 | } 40 | 41 | fixed4 frag ( 42 | float4 pos : SV_POSITION, 43 | float4 texCoord0 : TEXCOORD0 44 | ) : SV_TARGET 45 | { 46 | // Convert texture coordinates to color by assigning 47 | // x and y coordinates to r and g color channels. 48 | // The texture coordinates being used have not been 49 | // tiled or offset. 50 | fixed4 col = fixed4(texCoord0.zw, 0, 1); 51 | 52 | fixed4 texCol = tex2D(_MaixTex01, texCoord0.xy); 53 | 54 | // If ShowTexture is true, blend col and texCol based 55 | // on the selected BlendMode. 56 | if(_ShowTexture) 57 | { 58 | if(_BlendMode == 0) // Multiply 59 | col *= texCol; 60 | else if(_BlendMode == 1) // Add 61 | col += texCol; 62 | else if(_BlendMode == 2) // Subtract 63 | col -= texCol; 64 | else if(_BlendMode == 3) // Divide 65 | col /= texCol; 66 | else if(_BlendMode == 4) // LerpMin 67 | col = lerp(col, texCol, min(col, texCol)); 68 | else if(_BlendMode == 5) // LerpMax 69 | col = lerp(col, texCol, max(col, texCol)); 70 | } 71 | 72 | return col; 73 | } 74 | ENDCG 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /UVVisualizer/README.md: -------------------------------------------------------------------------------- 1 | # UV Visualizer Shader # 2 | 3 | This shader allows you to visualize a mesh's UV mapping within the Unity Editor. It displays UV coordinated as RGB colors on the mesh. The UV coordinates map to the R and G color channels respectively. UV coordinates can be anything between 0 and 1. Since the coordinates only map to the R and G channels, the B channel is always 0 and A is 1. That being said, you're mostly only gonna see colors created by mixing R and G channels. So... 4 | - (0,0) = Black 5 | - (1,0) = Red 6 | - (0,1) = Green 7 | - (1,1) = Yellow 8 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/UVMapping.png) 9 | ...and ofcourse, if you toggle the ShowTexture option ON, the color of the texture will be blended with the UV Visualization colors. 10 | 11 | ### Usage instructions: ### 12 | * Import this shader into your project. Create a material and select the UV Visualizer shader in the shader menu. 13 | * Shader Properties: 14 | - ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/ShaderInspector.png) 15 | - Main Texture - The texture that you want to apply to the mesh. If left blank, a white texture is used. 16 | - Show Texture - Whether to show the texture on the mesh or not. 17 | - Texture Blend Mode - The method to use to blend the UV VIsualization colors and Main Texture. Blend modes available: Multiply, Add, Subtract, Divide, LerpMin and LerpMax. If Show Texture is false, Texture Blend Mode is ignored. 18 | 19 | ### Here are some examples with primitive meshes, showing the UV Visualizer shader in use: ### 20 | In each example you'll see two meshes, left using the UV Visualizer shader, right using the Standard shader. 21 | - Cylinder (ShowTexture:False) 22 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example01.png) 23 | - Cube (ShowTexture:False) 24 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example02.png) 25 | - Cube (ShowTexture:True, BlendMode:Multiply) 26 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example03_1.png) 27 | - Cube (ShowTexture:True, BlendMode:Add) 28 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example04_1.png) 29 | 30 | ### Here are some examples with complex meshes, showing the UV Visualizer shader in use: ### 31 | - Mixamo Model (ShowTexture:False) 32 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example05.png) 33 | - Shield (ShowTexture:True, BlendMode:Add) 34 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example06.png) 35 | - Skull (ShowTexture:True, BlendMode:Multiply) 36 | ![](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/UVVisualizer/Example07.png) 37 | 38 | 39 | #### ___NOTE: There are other ways to see the UV mapping of a mesh, for example, you could open up the 3D model in a 3D modelling program like Blender, Maya, etc. This shader is meant for situations where you wish to get an idea of what a mesh's UV mapping looks like, right within the Unity Editor. This shader is meant to be used for debugging purposes, not really meant to be used within a game, but you can use it however you'd like.___ #### 40 | -------------------------------------------------------------------------------- /ColorChanger/README.md: -------------------------------------------------------------------------------- 1 | ## Color Changer shader ## 2 | 3 | This shader changes the colors of the texture in fragment shader. For each color channel, you can choose to Switch, Add, Subtract, Multiply or Divide it's value with the R, G, B or A channel's value. After these calculations are done, you can additionally choose to Add, Subtract, Multiply or Divide the result with another color. You can also choose whether calculations on one color channel affect calculations on another color channel. This shader is meant to be used as a debugging shader, so for example, if you wanna see what a certain model would look like with different colored textures, you can use this shader to test out different color schemes, rather than repainting and attaching a new texture for a different color scheme. That being said, the shader can be used as is, to change the color of your textures, if you wish to do so. 4 | 5 | ### Properties ### 6 | 7 | - __Texture__: Texture to use. 8 | - __Use Color Change?__: Should color change operations be done or not? If false, all operations are ignored, and the texture is not affected. 9 | - __Calculate Channels Independently__: If true, the initial color is stored in a temp buffer, so that calculations done on one channel won't affect calculations done on another channel. If false, the initial color variable is used as is in the calculations. Color channel calculations are done in the following order - R, G, B then A. So whether the color channels are calculated independently or not, affects the result. This will become moer clear in the examples. 10 | - __Red Channel Opeator__: Operator to use when doing calculations on the R channel. 11 | - __Red Channel Operand__: Operand to use when doing calculations on the R channel. 12 | - __Green Channel Opeator__: Operator to use when doing calculations on the G channel. 13 | - __Green Channel Operand__: Operand to use when doing calculations on the G channel. 14 | - __Blue Channel Opeator__: Operator to use when doing calculations on the B channel. 15 | - __Blue Channel Operand__: Operand to use when doing calculations on the B channel. 16 | - __Alpha Channel Opeator__: Operator to use when doing calculations on the A channel. 17 | - __Alpha Channel Operand__: Operand to use when doing calculations on the A channel. 18 | - __Final Color Opeator__: Operator to use when doing calculations on the color produced by previous calculations. 19 | - __Final Color Operand__: Operand to use when doing calculations on the color produced by previous calculations. 20 | 21 | Hopefully some examples will help you better understand how to use the properties in the shader. However, if you would rather just experiment by changing options randomly, that works perfectly fine too, because the whole point if this shader is to see what new color schemes you can come up with. 22 | 23 | __Example 1__: 24 | ![Example1](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/ColorChanger/ExamplePic1.png) 25 | A simpler example to help you understand the operations and how the values change. In this example the texture has only one color, Red, which in RGB would be (1,0,0). On the left you see the original texture color (red). On the right you see the resulting color after color changing operations (green). Let's take a look at the properties: 26 | Red Channel Operator: Subtract 27 | Red Channel Operand: R 28 | This means the value of R will be subtracted by itself. 29 | Green Channel Operator: Add 30 | Green Channel Operand: R 31 | This means the value of R will be added to the value of G. 32 | Blue Channel Operator: Keep 33 | Blue Channel Operand: B 34 | Since Blue Channel Operator is set to Keep, Blue channel keeps it's value, and no calculation is done. Same for Alpha channel. 35 | Final Color Operator: Multiply 36 | Final Color Operand: White (1,1,1,1) 37 | This leaves the color unaffected because is basically multiplying the values by 1. 38 | 39 | The calculation would then go like so... 40 | Initial color RGB value is (1,0,0), which is Red. 41 | 42 | `R = R-R = 1-1 = 0` 43 | 44 | `G = G+R = 0+1 = 1` 45 | 46 | `B = 0` 47 | 48 | Thus, the resulting color is Green (0,1,0). 49 | 50 | __Example 2__: 51 | Now, notice that Calculate Channels Independently is set to True. Let's set it to false. This is the result. 52 | ![Example2](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/ColorChanger/ExamplePic2.png) 53 | 54 | Here's a breakdown of the calculation: 55 | 56 | `R = R-R = 1-1 = 0` 57 | 58 | `G = G+R = 0+0 = 0` 59 | 60 | `B = 0` 61 | 62 | The resulting color is Black (0,0,0). Notice how the calculation done on the R channel affected the later calculation done on the G channel? That's what Calculate Channels Independently does. The channels are calculated in the order R-G-B-A, so if Calculate Channels Independently is set to False, calculations done on R, will affect later calculations, if the value of R is being used in them. 63 | 64 | __Example 3__: 65 | In this example I tried using the shader on the materials attached to Unity-chan. I changed some of the values for the body and hair materials. Here are the values, along with the results: 66 | ![Example3_2](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/ColorChanger/ExamplePic3_2.png) 67 | ![Example3_1](https://github.com/Demkeys/DemkeysUnityShaders/blob/master/ColorChanger/ExamplePic3_1.png) 68 | 69 | You really don't have to see the colors as numbers, and in most cases you won't have to. Just experiment with different values and see what results you get. Examples 1 and 2 visualize the colors as numbers just to help you understand how the operations affect the colors. 70 | 71 | -------------------------------------------------------------------------------- /ColorChanger/ColorChanger.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/ColorChanger" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "red" {} 6 | 7 | [Toggle] _UseColorChange ("Use Color Change?", Float) = 1 8 | [Toggle] _UseTempBuffer ("Calculate Channels Independently", Float) = 1 9 | 10 | [Header(Red Channel Operations)] 11 | [KeywordEnum(Keep,Switch,Add,Subtract,Multiply,Divide)] _R_Op ("Red Channel Operator", Float) = 0 12 | [KeywordEnum(R,G,B,A)] _R ("Red Channel Operand", Float) = 0 13 | 14 | [Header(Green Channel Operations)] 15 | [KeywordEnum(Keep,Switch,Add,Subtract,Multiply,Divide)] _G_Op ("Green Channel Operator", Float) = 0 16 | [KeywordEnum(R,G,B,A)] _G ("Green Channel Operand", Float) = 1 17 | 18 | [Header(Blue Channel Operations)] 19 | [KeywordEnum(Keep,Switch,Add,Subtract,Multiply,Divide)] _B_Op ("Blue Channel Operator", Float) = 0 20 | [KeywordEnum(R,G,B,A)] _B ("Blue Channel Operand", Float) = 2 21 | 22 | [Header(Alpha Channel Operations)] 23 | [KeywordEnum(Keep,Switch,Add,Subtract,Multiply,Divide)] _A_Op ("Alpha Channel Operator", Float) = 0 24 | [KeywordEnum(R,G,B,A)] _A ("Alpha Channel Operand", Float) = 3 25 | 26 | [Header(Final Color Operation)] 27 | [KeywordEnum(Add,Subtract,Multiply,Divide)] _FinalColOp ("Final Color Operator", Float) = 2 28 | _FinalColOperand ("Final Color Operand", Color) = (1,1,1,1) 29 | } 30 | SubShader 31 | { 32 | Tags { "RenderType"="Opaque" } 33 | LOD 100 34 | 35 | Pass 36 | { 37 | CGPROGRAM 38 | #pragma vertex vert 39 | #pragma fragment frag 40 | // make fog work 41 | #pragma multi_compile_fog 42 | 43 | #include "UnityCG.cginc" 44 | 45 | struct appdata 46 | { 47 | float4 vertex : POSITION; 48 | float2 uv : TEXCOORD0; 49 | }; 50 | 51 | struct v2f 52 | { 53 | float2 uv : TEXCOORD0; 54 | UNITY_FOG_COORDS(1) 55 | float4 vertex : SV_POSITION; 56 | }; 57 | 58 | sampler2D _MainTex; 59 | float4 _MainTex_ST; 60 | float _UseColorChange; float _UseTempBuffer; 61 | float _R_Op; float _G_Op; float _B_Op; float _A_Op; 62 | float _R; float _G; float _B; float _A; 63 | float _FinalColOp; float4 _FinalColOperand; 64 | 65 | v2f vert (appdata v) 66 | { 67 | v2f o; 68 | o.vertex = UnityObjectToClipPos(v.vertex); 69 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 70 | UNITY_TRANSFER_FOG(o,o.vertex); 71 | return o; 72 | } 73 | 74 | void ColorChannelOp(float Op, inout float Val1, float Val2) 75 | { 76 | if(Op==0) return; //Keep 77 | else if(Op==1) Val1 = Val2; // Switch 78 | else if(Op==2) Val1 += Val2; // Add 79 | else if(Op==3) Val1 -= Val2; // Sub 80 | else if(Op==4) Val1 *= Val2; // Mul 81 | else if(Op==5) Val1 /= Val2; // Div 82 | } 83 | 84 | void ChooseColorChannel(float channelOp, float outColorCh, inout float inColorCh, float4 inColor) 85 | { 86 | if(outColorCh==0) ColorChannelOp(channelOp, inColorCh, inColor.r); 87 | else if(outColorCh==1) ColorChannelOp(channelOp, inColorCh, inColor.g); 88 | else if(outColorCh==2) ColorChannelOp(channelOp, inColorCh, inColor.b); 89 | else if(outColorCh==3) ColorChannelOp(channelOp, inColorCh, inColor.a); 90 | } 91 | 92 | void FinalColorOp(float colorOp, inout float4 inCol, float4 colOperand) 93 | { 94 | if(colorOp==0) inCol += colOperand; // Add 95 | else if(colorOp==1) inCol -= colOperand; // Subtract 96 | else if(colorOp==2) inCol *= colOperand; // Multiply 97 | else if(colorOp==3) inCol /= colOperand; // Divide 98 | } 99 | 100 | fixed4 frag (v2f i) : SV_Target 101 | { 102 | // sample the texture 103 | fixed4 col = tex2D(_MainTex, i.uv); 104 | 105 | if(_UseColorChange) 106 | { 107 | if(_UseTempBuffer==1) 108 | { 109 | // Temp buffer to store initial color value, since col will be affected 110 | // during calculations. 111 | float4 tempBuffer = col; 112 | 113 | ChooseColorChannel(_R_Op, _R, col.r, tempBuffer); 114 | ChooseColorChannel(_G_Op, _G, col.g, tempBuffer); 115 | ChooseColorChannel(_B_Op, _B, col.b, tempBuffer); 116 | ChooseColorChannel(_A_Op, _A, col.a, tempBuffer); 117 | } 118 | else 119 | { 120 | ChooseColorChannel(_R_Op, _R, col.r, col); 121 | ChooseColorChannel(_G_Op, _G, col.g, col); 122 | ChooseColorChannel(_B_Op, _B, col.b, col); 123 | ChooseColorChannel(_A_Op, _A, col.a, col); 124 | } 125 | FinalColorOp(_FinalColOp, col, _FinalColOperand); 126 | } 127 | 128 | // apply fog 129 | UNITY_APPLY_FOG(i.fogCoord, col); 130 | return col; 131 | } 132 | ENDCG 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ColorGrid/ColorGrid.shader: -------------------------------------------------------------------------------- 1 | /* 2 | Color Grid: This is a grid system consisting of n by n cells. Use opcode, opr1, opr2 and opr3 (packed into op_data) to perform operations of filling cells. The grid system is implemented entirely in the fragment shader. op_data can be set from script to be able to control Color Grid via script. 3 | For testing purposes there's a Debug mode. To enable Debug Mode set GRID_DEBUG to 1. With Debug Mode enabled, instructions can be created and executed in DebugIns method. 4 | If Debug Mode is disabled set grid size by setting Texture's tiling in Inspector. 5 | If Debug Mode is enabled set grid size by setting Debug Grid Size X and Y in Inspector. 6 | 7 | NOTE for dev: The final color you're calculating, is the color for the pixel being drawn on the screen. Try not to confuse this with calculations for the color of the grid cell currently being drawn. 8 | 9 | */ 10 | Shader "Unlit/ColorGridShader" 11 | { 12 | Properties 13 | { 14 | _MainTex ("Texture", 2D) = "white" {} 15 | // _GridSize ("Grid Size", Vector) = (0,0,0,0) 16 | [Header(Debug)] 17 | _DbgSeed ("Debug Seed", Range(0,255)) = 2 18 | _DbgGridSize ("Debug Grid Size", Vector) = (4,4,0,0) 19 | } 20 | SubShader 21 | { 22 | Tags { "RenderType"="Opaque" } 23 | LOD 100 24 | 25 | Pass 26 | { 27 | CGPROGRAM 28 | #pragma vertex vert 29 | #pragma fragment frag 30 | 31 | #include "UnityCG.cginc" 32 | 33 | #define GRID_DEBUG 0 34 | 35 | // Used to set ins_arr's size because the size isn't always known at runtime. 36 | // This is especially useful when setting ins_arr from script. 37 | #define GRID_INS_MAX_COUNT 100 38 | 39 | struct appdata 40 | { 41 | float4 vertex : POSITION; 42 | float2 uv : TEXCOORD0; 43 | }; 44 | 45 | struct v2f 46 | { 47 | float2 uv : TEXCOORD0; 48 | float4 vertex : SV_POSITION; 49 | }; 50 | 51 | sampler2D _MainTex; 52 | float4 _MainTex_ST; 53 | // float4 _GridSize; 54 | uint _DbgSeed; 55 | float4 _DbgGridSize; 56 | 57 | // Color Grid variables 58 | uint4 ins_arr[GRID_INS_MAX_COUNT]; // Ins array. Set from script. 59 | uint ins_count; // Total ins in ins_arr. Set from script. 60 | uint4 op_data; // Op Data (opcode,opr1,opr2,opr3) 61 | fixed4 cell_color; // Color used when filling a cell 62 | 63 | float2 fragUV; // Interpolated UV coords 64 | uint2 pixelCellPos; // Current pixel pos converted to grid coords. 65 | uint2 gridSize; 66 | fixed4 final_color; // Shader output color 67 | 68 | v2f vert (appdata v) 69 | { 70 | v2f o; 71 | o.vertex = UnityObjectToClipPos(v.vertex); 72 | // o.uv = TRANSFORM_TEX(v.uv, _MainTex); 73 | 74 | #if GRID_DEBUG == 0 75 | o.uv = v.uv * _MainTex_ST.xy; 76 | #elif GRID_DEBUG == 1 77 | o.uv = v.uv * _DbgGridSize.xy; 78 | #endif 79 | 80 | return o; 81 | } 82 | 83 | float remap (float value, float low1, float high1, float low2, float high2) 84 | { 85 | return low2 + (value - low1) * (high2 - low2) / (high1 - low1); 86 | } 87 | 88 | // Set pixel color. This color will be used during draw_pixel_op. 89 | void set_color_op(uint3 color) 90 | { 91 | // Color is range(0-255) so remap to range(0-1). 92 | cell_color = fixed4( 93 | remap((float)color.r, 0, 255, 0, 1), 94 | remap((float)color.g, 0, 255, 0, 1), 95 | remap((float)color.b, 0, 255, 0, 1), 96 | 0 97 | ); 98 | } 99 | 100 | // Draw pixel in color grid. 101 | void draw_pixel_op(uint2 grid_pos) 102 | { 103 | // uint2 pixelCellPos = trunc(fragUV); 104 | 105 | // If pixelCellPos == grid_pos 106 | if(grid_pos.x == pixelCellPos.x && grid_pos.y == pixelCellPos.y) 107 | final_color = cell_color; 108 | 109 | // DEBUG CODE 110 | // final_color += cell_color; 111 | } 112 | 113 | // Draw row of pixels at 'index', starting from 'start'. 114 | // Index starts at uv(0,0). 115 | void draw_row_op(uint index, uint start) 116 | { 117 | for(uint i = start; i < gridSize.x; i++) draw_pixel_op(uint2(i,index)); 118 | } 119 | 120 | // Draw column of pixels at 'index', starting from 'start'. 121 | // Index starts at uv(0,0). 122 | void draw_column_op(uint index, uint start) 123 | { 124 | for(uint i = start; i < gridSize.x; i++) draw_pixel_op(uint2(index,i)); 125 | } 126 | 127 | void randomize_grid(uint seed) 128 | { 129 | // uint2 pixelCellPos = trunc(fragUV); 130 | for(uint i = 0; i < gridSize.x; i++) 131 | { 132 | for(uint j = 0; j < gridSize.y; j++) 133 | { 134 | uint3 rand_col = uint3( 135 | remap(frac(sin( dot(trunc(fragUV), float2(12.9898,91.233) )) * seed), 136 | 0,1,0,255), 137 | remap(frac(sin( dot(trunc(fragUV), float2(92.9898,178.233) )) * seed), 138 | 0,1,0,255), 139 | remap(frac(sin( dot(trunc(fragUV), float2(102.9898,38.233) )) * seed), 140 | 0,1,0,255) 141 | ); 142 | 143 | // randomize_grid_op implicitly uses set_color_op. So store the 144 | // current cell_color value in a buffer. Then after the randomize 145 | // op completes, set cell_color back to it's previous value. 146 | fixed3 tempCol = cell_color; 147 | set_color_op(rand_col); 148 | draw_pixel_op(uint2(i,j)); 149 | set_color_op(tempCol); 150 | } 151 | } 152 | } 153 | 154 | void fill_grid_op() 155 | { 156 | for(uint i = 0; i < gridSize.x; i++) 157 | { 158 | for(uint j = 0; j < gridSize.y; j++) 159 | { 160 | draw_pixel_op(uint2(i,j)); 161 | } 162 | } 163 | } 164 | 165 | // Draws a circe of 'radius' radius at 'pos' position on the Color Grid. 166 | void draw_circle_op(uint2 pos, uint radius) 167 | { 168 | // TODO 169 | } 170 | 171 | void draw_line_op(uint2 posA, uint2 posB) 172 | { 173 | // TODO 174 | } 175 | 176 | // Decord op_data and execute op using opcode and oprands. 177 | // NOTE: op_data = (opcode, opr1, opr2, opr3) 178 | void decode_op_data() 179 | { 180 | uint opcode = op_data.r; // OpCode 181 | uint3 opr = op_data.gba; // Operands (opr1,opr2,opr3) 182 | 183 | switch(opcode) 184 | { 185 | case 0x0: set_color_op(opr); break; 186 | case 0x1: draw_pixel_op(uint2(opr.xy)); break; 187 | case 0x2: draw_row_op(opr.x,opr.y); break; 188 | case 0x3: draw_column_op(opr.x,opr.y); break; 189 | case 0x4: randomize_grid(opr.x); break; 190 | case 0x5: fill_grid_op(); break; 191 | // case 0x6: draw_circle_op(opr.xy, opr.z); break; 192 | // TODO: draw_line_op, draw_circle_op 193 | default: break; 194 | } 195 | } 196 | 197 | #if GRID_DEBUG == 1 198 | // Use this method to create and execute instructions in Debug Mode. 199 | void DebugIns() 200 | { 201 | // op_data = uint4(0,170,0,50); 202 | 203 | op_data = uint4(4,_DbgSeed,0,0); 204 | decode_op_data(); 205 | 206 | op_data = uint4(0,127,0,0); 207 | decode_op_data(); 208 | op_data = uint4(1,1,1,0); 209 | decode_op_data(); 210 | op_data = uint4(0,0,127,0); 211 | decode_op_data(); 212 | op_data = uint4(1,1,2,0); 213 | decode_op_data(); 214 | op_data = uint4(2,0,0,0); 215 | decode_op_data(); 216 | op_data = uint4(2,3,1,0); 217 | decode_op_data(); 218 | // op_data = uint4(0,127,0,127); 219 | // decode_op_data(); 220 | // op_data = uint4(3,0,2,0); 221 | // decode_op_data(); 222 | 223 | 224 | // op_data = uint4(4,_DbgSeed,0,0); 225 | // decode_op_data(); 226 | // op_data = uint4(6,0,0,0); 227 | // decode_op_data(); 228 | 229 | 230 | // op_data = uint4(0,127,0,25); 231 | // decode_op_data(); 232 | // op_data = uint4(5,0,0,0); 233 | // decode_op_data(); 234 | // op_data = uint4(0,0,0,0); 235 | // decode_op_data(); 236 | // op_data = uint4(2,5,0,0); 237 | // decode_op_data(); 238 | } 239 | #endif 240 | 241 | fixed4 frag (v2f i) : SV_Target 242 | { 243 | // sample the texture 244 | // fixed4 col = tex2D(_MainTex, i.uv); 245 | fixed4 col = 0; 246 | fragUV = i.uv; 247 | pixelCellPos = trunc(fragUV); 248 | final_color = 0; 249 | // cell_color = 0; 250 | 251 | #if GRID_DEBUG == 0 252 | gridSize = (uint2)_MainTex_ST.xy; 253 | 254 | for(uint j = 0; j < ins_count; j++) 255 | { 256 | op_data = ins_arr[j]; 257 | decode_op_data(); 258 | } 259 | #elif GRID_DEBUG == 1 260 | gridSize = (uint2)_DbgGridSize.xy; 261 | 262 | DebugIns(); 263 | #endif 264 | 265 | col = final_color; 266 | // col = fixed4(fragUV,0,0); 267 | // col = fixed4(i.uv,0,0); 268 | 269 | return col; 270 | } 271 | ENDCG 272 | } 273 | } 274 | } 275 | --------------------------------------------------------------------------------