|
Post by ftlmars on Nov 8, 2015 12:45:34 GMT
is it posible to have markers over the sea and ocean?
|
|
|
Post by kenamis on Nov 9, 2015 6:11:12 GMT
Yes, it's possible
|
|
|
Post by kramar on Nov 9, 2015 14:54:31 GMT
To elaborate, it is possible, but not with the marker system that is provided by default in the package. I believe Kenamis has made some changes to the marker shaders. I need to do something similar and will post here once I'm done. (I don't when this will be though).
|
|
|
Post by kenamis on Nov 9, 2015 20:38:51 GMT
For hex markers on the sea, all I did was copied the hex marker code from the terrain shader into the water shader. To get the grid, I used one of the hex marker layers for the grid and did away completely with the hex outline shader. Khash has hinted at doing that in other posts. If he doesn't mind I could post the changes to the water shader that I made.
|
|
|
Post by khash on Nov 10, 2015 10:57:23 GMT
haha nice. Sure. Share! I love when community cooperates
|
|
|
Post by ftlmars on Nov 11, 2015 7:03:19 GMT
Yes pls, guys share you shader changes. The rest I think I can by my self
|
|
|
Post by kenamis on Nov 17, 2015 17:04:17 GMT
Sorry I haven't posted the code yet. I am on a business trip but I should be back this weekend.
|
|
|
Post by ftlmars on Nov 18, 2015 9:12:24 GMT
Sorry I haven't posted the code yet. I am on a business trip but I should be back this weekend. yes, sure
|
|
|
Post by kenamis on Nov 18, 2015 16:24:55 GMT
Shader "HoneyFramework/Water" { Properties { _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.063 _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.44 _WaveSpeed ("Wave speed (map1 x,y; map2 x,y)", Vector) = (2,.5,-2,-1.5) _BumpMap ("Normalmap ", 2D) = "bump" {} _ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {} _WaterTone ("Water tone", COLOR) = ( 0, .17, .29, 0) //antiquity _MarkersGraphic ("Markers Graphic", 2D) = "black" {} _MarkersPositionData ("Markers Position Data", 2D) = "black" {} //marker settings: (marker graphic count width, // marker graphic count height, // marker data width hex count, <- expected to be square for height // marker hex data size, <- number of following pixels of data for each hex _MarkerSettings("Marker Settings", vector) = (8, 8, 64, 2) }
// ----------------------------------------------------------- // Fragment program cards
Subshader { Tags { "WaterMode"="Refractive" "RenderType"="Transparent" } Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Off
CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
//------- UTILS --------
struct Vector3i { int x; int y; int z;
//this value tells us uv of the hex. which is 0,0 in one corner and 1,1 in the oposite. //Perfect to draw texture for teh hex. Note that only single hex will have influence in each pixel! no blenddrawings here! float2 uv; };
//converts integer hex coordinates into flat world position used for uv and other 2d scapce calculations float2 ConvertToPosition(Vector3i v) { float cos30 = sqrt(3.0) * 0.5;
float2 X = float2(1, 0); float2 Y = float2(-0.5, cos30); float2 Z = float2(-0.5, -cos30); return X * v.x + Y * v.y + Z * v.z; }
//this code expects hex radius to be 1 for simplification. Vector3i GetHexCoord(float2 pos) { //Convert world flat coordinates into hex FLOAT position float TWO_THIRD = 2.0 / 3.0; float ONE_THIRD = 1.0 / 3.0; float COMPONENT = ONE_THIRD * sqrt(3.0);
float x = TWO_THIRD * pos.x; float y = (COMPONENT * pos.y - ONE_THIRD * pos.x); float z = -x - y;
//we cant use floating hex position, so before return we need to convert it to integer. //also its important to understand that floating point position contains some artifacts if converted separately into integers //we have to do some post-calculation cleanup to be able to recover from them. Vector3i v; v.x = round(x); v.y = round(y); v.z = round(z);
//find delta between rounded and original value float dx = abs(v.x - x); float dy = abs(v.y - y); float dz = abs(v.z - z);
//value which after rounding get most offset contains biggest artifacts, we want to discard it and recover form {a + b + c = 0} equation if (dz > dy && dz > dx) { v.z = -v.x - v.y; } else if (dy > dx) { v.y = -v.x - v.z; } else { v.x = -v.y - v.z; }
//recover delta between testpoint and hex center as UV
float2 center = ConvertToPosition(v); float2 offset = pos - center; v.uv = offset*0.5 + float2(0.5, 0.5);
return v; }
sampler2D _ReflectionTex; sampler2D _ReflectiveColor; float _ReflDistort; float _WaveScale; sampler2D _RefractionTex; sampler2D _BumpMap; sampler2D _CameraDepthTexture; half4 _WaterTone; half4 _WaveSpeed;
//antiquity sampler2D _MarkersGraphic; sampler2D _MarkersPositionData; float4 _MarkerSettings; //******
struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; };
struct v2f { float4 pos : SV_POSITION; float4 ref : TEXCOORD0; float2 bumpuv0 : TEXCOORD1; float2 bumpuv1 : TEXCOORD2; float3 viewDir : TEXCOORD3; float3 worldPos : TEXCOORD4; };
v2f vert(appdata v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float4 waveScale = float4(_WaveScale, _WaveScale, _WaveScale * 0.4, _WaveScale * 0.45);
float4 waveOffset = float4( fmod(_WaveSpeed.x * waveScale.x * _Time.x, 1 ), fmod(_WaveSpeed.y * waveScale.y * _Time.x, 1 ), fmod(_WaveSpeed.z * waveScale.z * _Time.x, 1 ), fmod(_WaveSpeed.w * waveScale.w * _Time.x, 1 ));
// scroll bump waves float4 temp; temp.xyzw = v.vertex.xzxz * waveScale + waveOffset; o.bumpuv0 = temp.xy; o.bumpuv1 = temp.wz; // object space view direction (will normalize per pixel) o.viewDir.xzy = ObjSpaceViewDir(v.vertex); o.ref = ComputeScreenPos(o.pos); o.worldPos = mul (_Object2World, v.vertex).xyz; return o; }
half4 frag( v2f i ) : SV_Target { //Water depth //Get the distance to the camera from the depth buffer for this point float sceneZ = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.ref)).r);
//Actual distance to the camera float partZ = i.ref.z;
//If the two are similar, then there is an object intersecting with our object fixed diff = (abs(sceneZ - partZ)) ; fixed minDepthBorder = 0.32; fixed depthBorder = .34; fixed waterDepth = 0; if (diff > minDepthBorder && diff <= depthBorder) { //low intensity on border to smoothen it. //it will scale last 0.05 tint to 50% alpha
fixed brackets = depthBorder - minDepthBorder; waterDepth = 0.5 * (diff- minDepthBorder) / brackets;
} else if (diff > depthBorder) { //higher intensity when depth is entered waterDepth = 0.5 + (diff - depthBorder)*5; }
//Water reflection adn refraction
i.viewDir = normalize(i.viewDir); // combine two scrolling bumpmaps into one half3 bump1 = UnpackNormal(tex2D( _BumpMap, i.bumpuv0 )).rgb; half3 bump2 = UnpackNormal(tex2D( _BumpMap, i.bumpuv1 )).rgb; half3 bump = (bump1 + bump2) * 0.5;
// fresnel factor half fresnelFac = dot( i.viewDir, bump*waterDepth ); // perturb reflection/refraction UVs by bumpmap, and lookup colors float4 uv1 = i.ref; uv1.xy += bump * _ReflDistort; // final color is between refracted and reflected based on fresnel half4 color;
float2 tmpUV = float2(i.worldPos.x, i.worldPos.z)/10; tmpUV += bump * waterDepth * _ReflDistort; tmpUV.xy += _Time.x/3; half4 sky = tex2D(_ReflectiveColor, tmpUV); sky.rgb = sky * 0.25 + _WaterTone * 0.75; sky.a = waterDepth; //Antiquity, begin marker code float dataResolution = _MarkerSettings.z; int dataSize = round( _MarkerSettings.w); float2 pos = float2(i.worldPos.x, i.worldPos.z); Vector3i v = GetHexCoord(pos); float trueDataResolution = dataSize*dataResolution; float2 dataUV = float2( (v.x*dataSize+0.5) /trueDataResolution, (v.y*dataSize+0.5)/trueDataResolution); float2 data2UV = dataUV + float2(1.0/trueDataResolution, 0); float2 data3UV = dataUV + float2( 0, 1.0/trueDataResolution);//antiquity float4 data = tex2D (_MarkersPositionData, dataUV); float4 data2 = tex2D (_MarkersPositionData, data2UV); float4 data3 = tex2D (_MarkersPositionData, data3UV);//antiquity float2 markerUV; half4 marker; float2 markerCorner; const float TWO_PI = 6.28; // 1st marker layer int type = round(data.r * _MarkerSettings.x * _MarkerSettings.y); if (type != 0) { float2 markerPoint = float2(v.uv.x, v.uv.y) - float2(0.5, 0.5); //Short way of 2d rotation matrix float angle = TWO_PI * data2.r; float cosRot = cos(angle); float sinRot = sin(angle); float2 singleMarkerUV = float2(markerPoint.x * cosRot - markerPoint.y * sinRot, markerPoint.y * cosRot + markerPoint.x * sinRot);
//Index of the type in atlas column and row int typeX = fmod(type, _MarkerSettings.x); int typeY = floor(_MarkerSettings.y - (type + 0.01) / _MarkerSettings.x);
float2 atlasMarkerUV = singleMarkerUV + float2(0.5, 0.5) + float2(typeX, typeY);
//make atlas UV to be within 0-1 atlasMarkerUV.x = atlasMarkerUV.x / _MarkerSettings.x; atlasMarkerUV.y = atlasMarkerUV.y / _MarkerSettings.y; marker = tex2D (_MarkersGraphic, atlasMarkerUV); //antiquity marker.r = data3.r; marker.g = data3.g; marker.b = data3.b; //antiquity sky.rgb = sky.rgb * (1 - marker.a) + marker.rgb * (marker.a); } // 2nd marker layer type = round(data.g * _MarkerSettings.x * _MarkerSettings.y); if (type != 0) { float2 markerPoint = float2(v.uv.x, v.uv.y) - float2(0.5, 0.5); //Short way of 2d rotation matrix float angle = TWO_PI * data2.g; float cosRot = cos(angle); float sinRot = sin(angle); float2 singleMarkerUV = float2(markerPoint.x * cosRot - markerPoint.y * sinRot, markerPoint.y * cosRot + markerPoint.x * sinRot);
//Index of the type in atlas column and row int typeX = fmod(type, _MarkerSettings.x); int typeY = floor(_MarkerSettings.y - (type + 0.01) / _MarkerSettings.x);
float2 atlasMarkerUV = singleMarkerUV + float2(0.5, 0.5) + float2(typeX, typeY);
//make atlas UV to be within 0-1 atlasMarkerUV.x = atlasMarkerUV.x / _MarkerSettings.x; atlasMarkerUV.y = atlasMarkerUV.y / _MarkerSettings.y; marker = tex2D (_MarkersGraphic, atlasMarkerUV); sky.rgb = sky.rgb * (1 - marker.a) + marker.rgb * (marker.a); }
// 3rd marker layer type = round(data.b * _MarkerSettings.x * _MarkerSettings.y); if (type != 0) { float2 markerPoint = float2(v.uv.x, v.uv.y) - float2(0.5, 0.5); //Short way of 2d rotation matrix float angle = TWO_PI * data2.b; float cosRot = cos(angle); float sinRot = sin(angle); float2 singleMarkerUV = float2(markerPoint.x * cosRot - markerPoint.y * sinRot, markerPoint.y * cosRot + markerPoint.x * sinRot);
//Index of the type in atlas column and row int typeX = fmod(type, _MarkerSettings.x); int typeY = floor(_MarkerSettings.y - (type + 0.01) / _MarkerSettings.x);
float2 atlasMarkerUV = singleMarkerUV + float2(0.5, 0.5) + float2(typeX, typeY);
//make atlas UV to be within 0-1 atlasMarkerUV.x = atlasMarkerUV.x / _MarkerSettings.x; atlasMarkerUV.y = atlasMarkerUV.y / _MarkerSettings.y; marker = tex2D (_MarkersGraphic, atlasMarkerUV); sky.rgb = sky.rgb * (1 - marker.a) + marker.rgb * (marker.a); }
// 4th marker layer type = round(data.a * _MarkerSettings.x * _MarkerSettings.y); if (type != 0) { float2 markerPoint = float2(v.uv.x, v.uv.y) - float2(0.5, 0.5); //Short way of 2d rotation matrix float angle = TWO_PI * data2.a; float cosRot = cos(angle); float sinRot = sin(angle); float2 singleMarkerUV = float2(markerPoint.x * cosRot - markerPoint.y * sinRot, markerPoint.y * cosRot + markerPoint.x * sinRot);
//Index of the type in atlas column and row int typeX = fmod(type, _MarkerSettings.x); int typeY = floor(_MarkerSettings.y - (type + 0.01) / _MarkerSettings.x);
float2 atlasMarkerUV = singleMarkerUV + float2(0.5, 0.5) + float2(typeX, typeY);
//make atlas UV to be within 0-1 atlasMarkerUV.x = atlasMarkerUV.x / _MarkerSettings.x; atlasMarkerUV.y = atlasMarkerUV.y / _MarkerSettings.y; marker = tex2D (_MarkersGraphic, atlasMarkerUV); sky.rgb = sky.rgb * (1 - marker.a) + marker.rgb * (marker.a); } //*********************
//color.rgb = sky * 0.25 + _WaterTone * 0.75; //color.a = waterDepth; //return color; return sky; } ENDCG
} } }
I'm actually new to shaders so this may not be the best. Unity is complaining about some shader compilers errors (too many instructions), but it does run and works for me. I think this needs to be converted to a surface shader? Anyone know any further?
|
|
|
Post by kenamis on Nov 18, 2015 16:27:34 GMT
Now, all this is doing is letting the water have the ability to tap into the hex markers system. You'll still have to set the markers and if you intend to have the grid system, you'll need to disable the hard-coded grid outline shader calls and use a layer of the hexmarkers system for the grid.
|
|
|
Post by kramar on Jun 28, 2016 20:46:52 GMT
Hi, So I tried using the shader provided in this thread and it doesn't seem to work. I'm still getting the markers on the terrain under the water. Is there something I am missing? Note, I had to add "#pragma target 3.0", otherwise I would get errors and it wouldn't work at all. Any help would be appreciated. Cheers
|
|
|
Post by kenamis on Jun 28, 2016 22:52:59 GMT
You have to send the marker information to the shader/material, look in chunk.cs
public void SetMarkerMaterials() { if (chunkMaterial != null && MHGameSettings.GetMarkersMode()) { chunkMaterial.SetTexture("_MarkersGraphic", HexMarkers.GetMarkersTexture()); chunkMaterial.SetTexture("_MarkersPositionData", HexMarkers.GetHexDataTexture()); chunkMaterial.SetVector("_MarkerSettings", HexMarkers.GetMarkersSettings());
//water markers if( waterMaterial == null ) Debug.LogError("Chunk:waterMaterial not found!"); else { waterMaterial.SetTexture("_MarkersGraphic", HexMarkers.GetMarkersTexture()); waterMaterial.SetTexture("_MarkersPositionData", HexMarkers.GetHexDataTexture()); waterMaterial.SetVector("_MarkerSettings", HexMarkers.GetMarkersSettings()); } } }
i think that's all you should need
|
|
|
Post by kenamis on Jun 29, 2016 3:33:35 GMT
Also, I have since changed the hex outlines to not use a whole layer of the hexmarkers system. I just added a new variable to the shader that accepts an integer index and applies it to the given area in the shader like the rest of the layers. If the integer is 0 then there is no outline applied, if it is >0 then that marker is applied. I figured it would save a layer and a lot of data passed to the GPU because you don't need the outline specific to each hex locations, it's an all or nothing thing. Then all you need to do is hook up an option in script to set the shader's variable from 0 to the index and back to turn on or off the outlines.
|
|
|
Post by kramar on Jun 29, 2016 13:35:01 GMT
You have to send the marker information to the shader/material, look in chunk.cs public void SetMarkerMaterials() { if (chunkMaterial != null && MHGameSettings.GetMarkersMode()) { chunkMaterial.SetTexture("_MarkersGraphic", HexMarkers.GetMarkersTexture()); chunkMaterial.SetTexture("_MarkersPositionData", HexMarkers.GetHexDataTexture()); chunkMaterial.SetVector("_MarkerSettings", HexMarkers.GetMarkersSettings());
//water markers if( waterMaterial == null ) Debug.LogError("Chunk:waterMaterial not found!"); else { waterMaterial.SetTexture("_MarkersGraphic", HexMarkers.GetMarkersTexture()); waterMaterial.SetTexture("_MarkersPositionData", HexMarkers.GetHexDataTexture()); waterMaterial.SetVector("_MarkerSettings", HexMarkers.GetMarkersSettings()); } } }
i think that's all you should need That did it! I knew I was missing something...
|
|
|
Post by kramar on Jun 29, 2016 13:37:35 GMT
Also, I have since changed the hex outlines to not use a whole layer of the hexmarkers system. I just added a new variable to the shader that accepts an integer index and applies it to the given area in the shader like the rest of the layers. If the integer is 0 then there is no outline applied, if it is >0 then that marker is applied. I figured it would save a layer and a lot of data passed to the GPU because you don't need the outline specific to each hex locations, it's an all or nothing thing. Then all you need to do is hook up an option in script to set the shader's variable from 0 to the index and back to turn on or off the outlines. I'm not planning on using your hex outlines, but if you did improve your them you should probably post your changes for those who are... Thanks again for all your work on this. I really know very little about shaders, so this saved me a lot of time!
|
|