diff --git a/Docs/README.3DClouds b/Docs/README.3DClouds index 8bc6039d4..13bd33bd1 100644 --- a/Docs/README.3DClouds +++ b/Docs/README.3DClouds @@ -43,8 +43,6 @@ The cloud is defined by the following properties: - whether to choose the vertical texture index based on sprite height within the clouds (default false) - Number of sprite to generate for the cloud (default 20) - - Light multiplier for sprites at the bottom of the cloud - (default 1.0) - minimum width of the sprites used to create the cloud (default 200) - maximum width of the sprites used to create the cloud @@ -56,7 +54,39 @@ The cloud is defined by the following properties: - vertical scaling factor to apply to to the sprite after billboarding. A small value would create a sprite that looks squashed when viewed from the side. (default 1.0) - + - See Shading below (default 1.0) + - See Shading below (default min-...-factor + 0.1) + - See Shading below (default 1.0) + - See Shading below (default min-...-factor + 0.1) + - See Shading below (default 1.0) + - See Shading below (default min-...-factor + 0.1) + - See Shading below (default 0.5) + - See Shading below (default min-...-factor + 0.1) + +Shading +------- + +the [min|max]-...-lighting-factor properties allow you to define diffuse lighting +multipliers to the bottom, middle, top, sunny and shaded parts of the cloud. In +each case, individual clouds will have a random multiplier between the min and +max values used to allow for some variation between individual clouds. + +The top, middle and bottom lighting factors are applied based on the pixels vertical +positon in the cloud. A linear interpolation is used either between top/middle (if +the pixel is above the middle of the cloud) or middle/bottom (if the pixel is below +the middle of the cloud). + +The top factor is also applied to _all_ pixels on the sunny side of the cloud. The +shade factor is applied based on the pixel position away from the sun, linearly +interpolated from top to shade. E.g this is not a straight linear interpolation +from top to shade across the entire cloud. + +The final lighting factor is determined by the minimum of the vertical factor and +the sunny/shade factor. Note that this is applied to the individual pixels, not +sprites. + +Textures +-------- The texture to use for the sprites is defined in the tag. To allow some variation, you can create a texture file containing multiple diff --git a/Effects/cloud.eff b/Effects/cloud.eff index 8ac147507..93f2c3747 100644 --- a/Effects/cloud.eff +++ b/Effects/cloud.eff @@ -60,6 +60,10 @@ usrAttr2 11 + + usrAttr3 + 12 + baseTexture diff --git a/Effects/water.eff b/Effects/water.eff index a9220a564..59e484e5a 100644 --- a/Effects/water.eff +++ b/Effects/water.eff @@ -12,7 +12,9 @@ - Textures/Water/normalmap2.png + + Textures/Water/waves-ver10-nm.dds + linear-mipmap-linear repeat repeat @@ -20,7 +22,9 @@ - Textures/Water/dudvmap2.png + + Textures/Water/waves-ver10-dudv.dds + linear-mipmap-linear repeat repeat @@ -34,7 +38,14 @@ normalized - Textures/Water/sea_foam.png + Textures/Water/sea_foam.dds + linear-mipmap-linear + repeat + repeat + normalized + + + Textures/Water/perlin-noise-nm.dds linear-mipmap-linear repeat repeat @@ -73,6 +84,10 @@ /environment/config/boundary/entry[0]/wind-from-north-fps + + /environment/config/boundary/entry[0]/wind-from-heading-deg + + @@ -218,6 +233,28 @@ texture[5]/internal-format + + 6 + + texture[6]/image + + + texture[6]/filter + + + texture[6]/wrap-s + + + texture[6]/wrap-t + + + texture[6]/internal-format + + + + 9 + noise + Shaders/water.vert Shaders/water.frag @@ -247,6 +284,11 @@ sampler-2d 5 + + perlin_normalmap + sampler-2d + 6 + saturation float @@ -317,6 +359,18 @@ windN + + WindFrom + float + + wind-from + + + + Noise + sampler-3d + 9 + diff --git a/Environment/cloudlayers.xml b/Environment/cloudlayers.xml index 613f51622..d4d9a520b 100644 --- a/Environment/cloudlayers.xml +++ b/Environment/cloudlayers.xml @@ -35,33 +35,29 @@ ns = Nimbostratus (Rain cloud) 1600 - 2000 4000 - 3000 10 cl_cumulus.png 4 4 - 0.3 + 0.3 + 0.4 800 - 1200 800 - 1200 + true 800 - 400 - 500 - 200 + 800 10 cl_cumulus.png 4 4 - 0.3 + 0.3 + 0.4 400 - 800 400 - 800 + true 600 @@ -69,89 +65,95 @@ ns = Nimbostratus (Rain cloud) 400 800 20 - cl_cumulus.png + cl_cumulus2.png 4 4 - 0.6 + 0.2 + 0.3 400 700 300 700 + true - 300 - 800 - 200 - 300 - 10 - cl_cumulus.png + 600 + 900 + 400 + 600 + 20 + cl_cumulus2.png 4 4 - 0.7 - 200 + 0.4 + 0.5 + 300 400 - 150 + 200 300 + true 1200 3000 - 200 - 400 + 400 + 800 40 cl_st.png 1 1 - 0.2 + 0.2 300 600 100 200 + false + 0.5 600 2000 - 200 - 300 + 400 + 600 40 cl_st.png 1 1 - 0.3 + 0.3 300 600 100 200 + false + 0.5 - 800 - 1500 - 100 - 200 - 40 - cl_st.png - 1 - 1 - 0.9 - 300 - 600 - 200 - 400 - - - 1800 - 2500 + 1000 200 - 400 40 - cl_st.png - 1 - 1 - 0.9 + cl_cumulus.png + 4 + 4 + 0.9 400 800 - 300 - 500 + 400 + 800 + false + 0.3 + + + 2000 + 1000 + 40 + cl_st.png + 1 + 1 + 0.9 + 600 + 600 + false + 0.4 diff --git a/Nasal/mp_broadcast.nas b/Nasal/mp_broadcast.nas index 63323bc11..62d4a7411 100644 --- a/Nasal/mp_broadcast.nas +++ b/Nasal/mp_broadcast.nas @@ -7,6 +7,65 @@ ## ############################################################################### +############################################################################### +# Event broadcast channel using a MP enabled string property. +# Events from users in multiplayer.ignore are ignored. +# +# EventChannel.new(mpp_path) +# Create a new event broadcast channel. Any MP user with the same +# primitive will receive all messages sent to the channel from the point +# she/he joined (barring severe MP packet loss). +# NOTE: Message delivery is not guaranteed. +# mpp_path - MP property path : string +# +# EventChannel.register(event_hash, handler) +# Register a handler for the event identified by the hash event_hash. +# event_hash - hash value for the event : a unique 4 character string +# handler - a handler function for the event : func (msg) +# +# EventChannel.deregister(event_hash) +# Deregister the handler for the event identified by the hash event_hash. +# event_hash - hash value for the event : a unique 4 character string +# +# EventChannel.send(event_hash, msg) +# Sends the event event_hash with the message msg to the channel. +# event_hash - hash value for the event : a unique 4 character string +# msg - text string with Binary data encoded data : string +# +# EventChannel.die() +# Destroy this EventChannel instance. +# +var EventChannel = {}; +EventChannel.new = func (mpp_path) { + var obj = BroadcastChannel.new(mpp_path, + func (n, msg) { obj._process(n, msg) }); + # Save send from being overriden. + obj.parent_send = obj.send; + # Put EventChannel methods before BroadcastChannel methods. + obj.parents = [EventChannel] ~ obj.parents; + obj.events = {}; + return obj; +} +EventChannel.register = func (event_hash, + handler) { + me.events[event_hash] = handler; +} +EventChannel.deregister = func (event_hash) { + delete(me.events, event_hash); +} +EventChannel.send = func (event_hash, + msg) { + me.parent_send(event_hash ~ msg); +} +############################################################ +# Internals. +EventChannel._process = func (n, msg) { + var event_hash = Binary.readHash(msg); + if (contains(me.events, event_hash)) { + me.events[event_hash](substr(msg, Binary.sizeOf["Hash"])); + } +} + ############################################################################### # Broadcast primitive using a MP enabled string property. # Broadcasts from users in multiplayer.ignore are ignored. @@ -60,6 +119,7 @@ BroadcastChannel.new = func (mpp_path, process, send_buf : [], peers : {}, loopid : 0, + running : 0, PERIOD : 1.3, last_time : 0.0, # For join handling. last_send : 0.0, # For the send queue @@ -74,7 +134,8 @@ BroadcastChannel.new = func (mpp_path, process, return obj; } BroadcastChannel.send = func (msg) { - if (me.send_node == nil) return; + if (!me.running or me.send_node == nil) + return; var t = getprop("/sim/time/elapsed-sec"); if (((t - me.last_send) > me.SEND_TIME) and (size(me.send_buf) == 0)) { @@ -83,17 +144,25 @@ BroadcastChannel.send = func (msg) { if (me.send_to_self) me.process_msg(props.globals, msg); } else { append(me.send_buf, msg); - } + } } BroadcastChannel.die = func { me.loopid += 1; + me.running = 0; # print("BroadcastChannel[" ~ me.mpp_path ~ "] ... destroyed."); } BroadcastChannel.start = func { - me.loopid += 1; - settimer(func { me._loop_(me.loopid); }, 0, 1); + if (!getprop("/sim/multiplay/online")) { + me.stop(); + } else { + #print("mp_broadcast.nas: starting channel " ~ me.send_node.getPath() ~ "."); + me.running = 1; + me._loop_(me.loopid += 1); + } } BroadcastChannel.stop = func { + #print("mp_broadcast.nas: stopping channel " ~ me.send_node.getPath() ~ "."); + me.running = 0; me.loopid += 1; } @@ -147,8 +216,11 @@ BroadcastChannel.update = func { } } } -BroadcastChannel._loop_ = func(id) { +BroadcastChannel._loop_ = func (id) { + me.running or return; id == me.loopid or return; + + #print("mp_broadcast.nas: " ~ me.send_node.getPath() ~ ":" ~ id ~ "."); me.update(); settimer(func { me._loop_(id); }, 0, 1); } @@ -159,6 +231,7 @@ BroadcastChannel._loop_ = func(id) { # NOTE: MP is picky about what it sends in a string propery. # Encode 7 bits as a printable 8 bit character. var Binary = {}; +Binary.TWOTO28 = 268435456; Binary.TWOTO31 = 2147483648; Binary.TWOTO32 = 4294967296; Binary.sizeOf = {}; @@ -230,6 +303,21 @@ Binary.decodeCoord = func (str) { Binary.decodeDouble(substr(str, 20))); return coord; } +############################################################ +# Encodes a string as a hash value. +Binary.sizeOf["Hash"] = 4; +Binary.stringHash = func (str) { + var hash = 0; + for(var i=0; i= 1.5){ finalColor = refl + specular; } else { finalColor = refl; } - if (windEffect >= 10.0){ - float windScale3 = pow(windScale, 3); - - if (N.g >= 0.0005 + 0.085 * windScale3){ - vec4 foam_texel = texture2D(sea_foam, vec2(waterTex1+ disdis*sca2) * windScale3 * 50.0); - finalColor = mix(finalColor, max(finalColor, foam_texel), smoothstep(0.0005 + 0.085 * windScale3, 0.1, N.g)); - } - - } - finalColor *= ambient_light; + float foamSlope = 0.1 + 0.1 * windScale; + if (windEffect >= 10.0) + if (N.g >= foamSlope){ + vec4 foam_texel = texture2D(sea_foam, vec2(waterTex2 * tscale) * 30.0); + finalColor = mix(finalColor, max(finalColor, finalColor + foam_texel), smoothstep(foamSlope, 0.25, N.g)); + } + finalColor *= ambient_light; - gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor); + gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor); } diff --git a/Shaders/water.vert b/Shaders/water.vert index 5e3b35496..4e8ae53f7 100644 --- a/Shaders/water.vert +++ b/Shaders/water.vert @@ -2,6 +2,8 @@ // http://www.bonzaisoftware.com/water_tut.html and its glsl conversion // available at http://forum.bonzaisoftware.com/viewthread.php?tid=10 // © Michael Horsch - 2005 +// Major update and revisions - 2011-10-07 +// © Emilian Huminiuc and Vivian Meazza #version 120 @@ -9,36 +11,48 @@ varying vec4 waterTex1; varying vec4 waterTex2; varying vec4 waterTex4; varying vec4 ecPosition; -uniform float osg_SimulationTime; -uniform float WindE, WindN; + varying vec3 viewerdir; varying vec3 lightdir; varying vec3 normal; +uniform float osg_SimulationTime; +uniform float WindE, WindN; + +/////// functions ///////// + +void rotationmatrix(in float angle, out mat4 rotmat) +{ + rotmat = mat4( cos( angle ), -sin( angle ), 0.0, 0.0, + sin( angle ), cos( angle ), 0.0, 0.0, + 0.0 , 0.0 , 1.0, 0.0, + 0.0 , 0.0 , 0.0, 1.0 ); +} + void main(void) { -vec3 N = normalize(gl_Normal); -normal = N; + mat4 RotationMatrix; + vec3 N = normalize(gl_Normal); + normal = N; -ecPosition = gl_ModelViewMatrix * gl_Vertex; + ecPosition = gl_ModelViewMatrix * gl_Vertex; -viewerdir = vec3(gl_ModelViewMatrixInverse[3]) - vec3(gl_Vertex); -lightdir = normalize(vec3(gl_ModelViewMatrixInverse * gl_LightSource[0].position)); + viewerdir = vec3(gl_ModelViewMatrixInverse[3]) - vec3(gl_Vertex); + lightdir = normalize(vec3(gl_ModelViewMatrixInverse * gl_LightSource[0].position)); -waterTex4 = vec4( ecPosition.xzy, 0.0 ); + waterTex4 = vec4( ecPosition.xzy, 0.0 ); -vec4 t1 = vec4(0.0, osg_SimulationTime * 0.005217, 0.0, 0.0); -vec4 t2 = vec4(0.0, osg_SimulationTime * -0.0012, 0.0, 0.0); + vec4 t1 = vec4(0.0, osg_SimulationTime * 0.005217, 0.0, 0.0); + vec4 t2 = vec4(0.0, osg_SimulationTime * -0.0012, 0.0, 0.0); -//float windFactor = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.3; -float windFactor = 0.001; + float windFactor = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.01; + float Angle = atan(-WindN + 0.001, WindE + 0.001) - atan(1.0); -waterTex1 = gl_MultiTexCoord0 + t1; -waterTex1.x += WindE * windFactor; -waterTex1.y += WindN * windFactor; -waterTex2 = gl_MultiTexCoord0 + t2; -waterTex2.x += WindE * windFactor; -waterTex2.y += WindN * windFactor; + rotationmatrix(Angle, RotationMatrix); + waterTex1 = gl_MultiTexCoord0 * RotationMatrix - t1 * windFactor; -gl_Position = ftransform(); + rotationmatrix(Angle, RotationMatrix); + waterTex2 = gl_MultiTexCoord0 * RotationMatrix - t2 * windFactor; + + gl_Position = ftransform(); } \ No newline at end of file diff --git a/Textures/Water/perlin-noise-nm.dds b/Textures/Water/perlin-noise-nm.dds new file mode 100644 index 000000000..1fed871fa Binary files /dev/null and b/Textures/Water/perlin-noise-nm.dds differ diff --git a/Textures/Water/sea_foam.dds b/Textures/Water/sea_foam.dds new file mode 100644 index 000000000..fcfb68d9d Binary files /dev/null and b/Textures/Water/sea_foam.dds differ diff --git a/Textures/Water/water-normalmap2.dds b/Textures/Water/water-normalmap2.dds new file mode 100644 index 000000000..ddd54c00e Binary files /dev/null and b/Textures/Water/water-normalmap2.dds differ diff --git a/Textures/Water/waves-ver10-dudv.dds b/Textures/Water/waves-ver10-dudv.dds new file mode 100644 index 000000000..7ccb9632d Binary files /dev/null and b/Textures/Water/waves-ver10-dudv.dds differ diff --git a/Textures/Water/waves-ver10-nm.dds b/Textures/Water/waves-ver10-nm.dds new file mode 100644 index 000000000..544b775b5 Binary files /dev/null and b/Textures/Water/waves-ver10-nm.dds differ diff --git a/Textures/Water/waves2.dds b/Textures/Water/waves2.dds new file mode 100644 index 000000000..47646d45b Binary files /dev/null and b/Textures/Water/waves2.dds differ diff --git a/preferences.xml b/preferences.xml index d7081f3f3..f9bd58988 100644 --- a/preferences.xml +++ b/preferences.xml @@ -1273,6 +1273,11 @@ Started September 2000 by David Megginson, david@megginson.com + + false + + +