• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

Budinga

Members
  • Content count

    28
  • Joined

  • Last visited

Community Reputation

331 Neutral

About Budinga

  • Rank
    Member
  1. Ok a little update I managed to figure out a few things now the flat version I found quite simple to get working , but I am aiming for the spherical version and I am stuck on the code for the matrix generation if anybody can give me a little insite in to what im doing wrong. At the moment I am using this code, but I am sure it dosent work properly as I only get a broken up sphere , so is there something im doing wrong do I need to construct the matrix in a different way.   [code]Vector3 ux, uy, uz, oo; if (radius == 0) { // flat ocean ux = Vector3.UnitX; uy = Vector3.UnitY; uz = Vector3.UnitZ; oo = new Vector3(camtolocal.X, camtolocal.Y,0);   } else { // spherical ocean uz = Vector3.Normalize(camtolocal);// unit z vector of ocean frame, in local space ? if (oldcamtolocal != Matrix.Identity) {     ux = Vector3.Normalize(Vector3.Cross(new Vector3(oldcamtolocal.M21, oldcamtolocal.M22, oldcamtolocal.M23), uz));     ? ? } else { ux = Vector3.Normalize(Vector3.Cross(Vector3.UnitZ, uz));   } uy = Vector3.Cross(uz, ux);// unit y vector // negate this ?? oo = uz * radius; // origin of ocean frame, in local space     }   Matrix localtoocean = new Matrix( ux.X, ux.Y, ux.Z, -Vector3.Dot(ux, oo), uy.X, uy.Y, uy.Z, -Vector3.Dot(uy, oo), uz.X, uz.Y, uz.Z, -Vector3.Dot(uz, oo), 0.0f, 0.0f, 0.0f, 1.0f);[/code]
  2. Ok I am getting some ware now on the flat plane ocean, just gotta work on the spherical one. Just wanted to ask some advice on one more thing. When I load the precomputed scattering textures any advice on how to do this in xna, ive used the io.file to load the raw data I have tried to load it single by single. Af far as I can see he uses a half float to store each pixel, how the heck do I load this in to xna. P.S still don't have the vertex shader working100% thanx smasherprog at least I am now getting someware. :)
  3. Hi,   Thanx for your answer I gathered it was something like that, the main thing I need to ask is did you transpose your Matrix before you passed them to the shader or did you just pass them the same way as the example and just change the y and z components. I did actually try swapping the whole everything first and I got nothing so I had to start again.  
  4. Hi Guyz. Well I have decided to use the great Eric Bruneton's water shaders in my procedural planet renderer, now I have managed to port the shaders, and also with a slightly modified ocean rendering class I get something on the screen, but due to the fact that he use's, a different coord system, well I think that's it I cant seem to get my brain round it. So I was wondering if anybody could spot my problem. Original Render Function [source] bool DrawOceanTask::Impl::run() { if (Logger::DEBUG_LOGGER != NULL) { Logger::DEBUG_LOGGER->log("OCEAN", "DrawOcean"); } ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer(); ptr<Program> prog = SceneManager::getCurrentProgram(); if (o->nbWavesU == NULL) { o->nbWavesU = prog->getUniform1f("nbWaves"); o->wavesU = prog->getUniformSampler("wavesSampler"); o->cameraToOceanU = prog->getUniformMatrix4f("cameraToOcean"); o->screenToCameraU = prog->getUniformMatrix4f("screenToCamera"); o->cameraToScreenU = prog->getUniformMatrix4f("cameraToScreen"); o->oceanToCameraU = prog->getUniformMatrix3f("oceanToCamera"); o->oceanToWorldU = prog->getUniformMatrix4f("oceanToWorld"); o->oceanCameraPosU = prog->getUniform3f("oceanCameraPos"); o->oceanSunDirU = prog->getUniform3f("oceanSunDir"); o->horizon1U = prog->getUniform3f("horizon1"); o->horizon2U = prog->getUniform3f("horizon2"); o->timeU = prog->getUniform1f("time"); o->radiusU = prog->getUniform1f("radius"); o->heightOffsetU = prog->getUniform1f("heightOffset"); o->lodsU = prog->getUniform4f("lods"); assert(o->nbWavesU != NULL); o->generateWaves(); } vector< ptr<TileSampler> > uniforms; SceneNode::FieldIterator ui = n->getFields(); while (ui.hasNext()) { ptr<TileSampler> u = ui.next().cast<TileSampler>(); if (u != NULL && u->getTerrain(0) != NULL) { u->setTileMap(); } } // compute ltoo = localToOcean transform, where ocean frame = tangent space at // camera projection on sphere o->radius in local space mat4d ctol = n->getLocalToCamera().inverse(); vec3d cl = ctol * vec3d::ZERO; // camera in local space if ((o->radius == 0.0 && cl.z > o->zmin) || (o->radius > 0.0 && cl.length() > o->radius + o->zmin) || (o->radius < 0.0 && vec2d(cl.y, cl.z).length() < -o->radius - o->zmin)) { o->oldLtoo = mat4d::IDENTITY; o->offset = vec3d::ZERO; return true; } vec3d ux, uy, uz, oo; if (o->radius == 0.0) { // flat ocean ux = vec3d::UNIT_X; uy = vec3d::UNIT_Y; uz = vec3d::UNIT_Z; oo = vec3d(cl.x, cl.y, 0.0); } else if (o->radius > 0.0) { // spherical ocean uz = cl.normalize(); // unit z vector of ocean frame, in local space if (o->oldLtoo != mat4d::IDENTITY) { ux = vec3d(o->oldLtoo[1][0], o->oldLtoo[1][1], o->oldLtoo[1][2]).crossProduct(uz).normalize(); } else { ux = vec3d::UNIT_Z.crossProduct(uz).normalize(); } uy = uz.crossProduct(ux); // unit y vector oo = uz * o->radius; // origin of ocean frame, in local space } else { // cylindrical ocean uz = vec3d(0.0, -cl.y, -cl.z).normalize(); ux = vec3d::UNIT_X; uy = uz.crossProduct(ux); oo = vec3d(cl.x, 0.0, 0.0) + uz * o->radius; } mat4d ltoo = mat4d( ux.x, ux.y, ux.z, -ux.dotproduct(oo), uy.x, uy.y, uy.z, -uy.dotproduct(oo), uz.x, uz.y, uz.z, -uz.dotproduct(oo), 0.0, 0.0, 0.0, 1.0); // compute ctoo = cameraToOcean transform mat4d ctoo = ltoo * ctol; if (o->oldLtoo != mat4d::IDENTITY) { vec3d delta = ltoo * (o->oldLtoo.inverse() * vec3d::ZERO); o->offset += delta; } o->oldLtoo = ltoo; mat4d ctos = n->getOwner()->getCameraToScreen(); mat4d stoc = ctos.inverse(); vec3d oc = ctoo * vec3d::ZERO; if (o->oceanSunDirU != NULL) { // TODO how to get sun dir in a better way? SceneManager::NodeIterator i = n->getOwner()->getNodes("light"); if (i.hasNext()) { ptr<SceneNode> l = i.next(); vec3d worldSunDir = l->getLocalToParent() * vec3d::ZERO; vec3d oceanSunDir = ltoo.mat3x3() * (n->getWorldToLocal().mat3x3() * worldSunDir); o->oceanSunDirU->set(oceanSunDir.cast<float>()); } } vec4<GLint> screen = fb->getViewport(); vec4d frustum[6]; SceneManager::getFrustumPlanes(ctos, frustum); vec3d left = frustum[0].xyz().normalize(); vec3d right = frustum[1].xyz().normalize(); float fov = (float) safe_acos(-left.dotproduct(right)); float pixelSize = atan(tan(fov / 2.0f) / (screen.w / 2.0f)); // angle under which a screen pixel is viewed from the camera o->cameraToOceanU->setMatrix(ctoo.cast<float>()); o->screenToCameraU->setMatrix(stoc.cast<float>()); o->cameraToScreenU->setMatrix(ctos.cast<float>()); o->oceanToCameraU->setMatrix(ctoo.inverse().mat3x3().cast<float>()); o->oceanCameraPosU->set(vec3f(float(-o->offset.x), float(-o->offset.y), float(oc.z))); if (o->oceanToWorldU != NULL) { o->oceanToWorldU->setMatrix((n->getLocalToWorld() * ltoo.inverse()).cast<float>()); } if (o->horizon1U != NULL) { float h = oc.z; vec3d A0 = (ctoo * vec4d((stoc * vec4d(0.0, 0.0, 0.0, 1.0)).xyz(), 0.0)).xyz(); vec3d dA = (ctoo * vec4d((stoc * vec4d(1.0, 0.0, 0.0, 0.0)).xyz(), 0.0)).xyz(); vec3d B = (ctoo * vec4d((stoc * vec4d(0.0, 1.0, 0.0, 0.0)).xyz(), 0.0)).xyz(); if (o->radius == 0.0) { o->horizon1U->set(vec3f(-(h * 1e-6 + A0.z) / B.z, -dA.z / B.z, 0.0)); o->horizon2U->set(vec3f::ZERO); } else { double h1 = h * (h + 2.0 * o->radius); double h2 = (h + o->radius) * (h + o->radius); double alpha = B.dotproduct(B) * h1 - B.z * B.z * h2; double beta0 = (A0.dotproduct(B) * h1 - B.z * A0.z * h2) / alpha; double beta1 = (dA.dotproduct(B) * h1 - B.z * dA.z * h2) / alpha; double gamma0 = (A0.dotproduct(A0) * h1 - A0.z * A0.z * h2) / alpha; double gamma1 = (A0.dotproduct(dA) * h1 - A0.z * dA.z * h2) / alpha; double gamma2 = (dA.dotproduct(dA) * h1 - dA.z * dA.z * h2) / alpha; o->horizon1U->set(vec3f(-beta0, -beta1, 0.0)); o->horizon2U->set(vec3f(beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2)); } } o->timeU->set(n->getOwner()->getTime() * 1e-6); if (o->radiusU != NULL) { o->radiusU->set(o->radius < 0.0 ? -o->radius : o->radius); } o->heightOffsetU->set(-o->meanHeight); o->lodsU->set(vec4f(o->resolution, pixelSize * o->resolution, log(o->lambdaMin) / log(2.0f), (o->nbWavesU->get() - 1.0f) / (log(o->lambdaMax) / log(2.0f) - log(o->lambdaMin) / log(2.0f)))); if (o->screenGrid == NULL || o->screenWidth != screen.z || o->screenHeight != screen.w) { o->screenWidth = screen.z; o->screenHeight = screen.w; o->screenGrid = new Mesh<vec2f, unsigned int>(TRIANGLES, GPU_STATIC); o->screenGrid->addAttributeType(0, 2, A32F, false); float f = 1.25f; int NX = int(f * screen.z / o->resolution); int NY = int(f * screen.w / o->resolution); for (int i = 0; i < NY; ++i) { for (int j = 0; j < NX; ++j) { o->screenGrid->addVertex(vec2f(2.0*f*j/(NX-1.0f)-f, 2.0*f*i/(NY-1.0f)-f)); } } for (int i = 0; i < NY-1; ++i) { for (int j = 0; j < NX-1; ++j) { o->screenGrid->addIndice(i*NX+j); o->screenGrid->addIndice(i*NX+j+1); o->screenGrid->addIndice((i+1)*NX+j); o->screenGrid->addIndice((i+1)*NX+j); o->screenGrid->addIndice(i*NX+j+1); o->screenGrid->addIndice((i+1)*NX+j+1); } } } fb->draw(prog, *(o->screenGrid)); return true; } [/source] Now my update function (basically tries to do the same thing. [source] public void Update(GameTime gametime) { // compute ltoo = localToOcean transform, where ocean frame = tangent space at // camera projection on sphere o->radius in local space //Matrix.CreateRotationY (MathHelper.ToRadians(90)) * Matrix.CreateRotationZ (MathHelper.ToRadians(90))* Matrix ctol = Matrix.Identity * Matrix.Invert(Parent.cam.View); Vector3 cl = Vector3.Transform(Vector3.Zero, ctol);//camera in local space if ((radius == 0.0 && cl.Z > zmin) || (radius > 0.0 && cl.Length() > radius + zmin) || (radius < 0.0 && new Vector2(cl.Y, cl.Z).Length() < -radius - zmin)) { oldLtoo = Matrix.Identity; offset = Vector3.Zero; return; } Vector3 ux, uy, uz, oo; if (radius == 0.0) { // flat ocean ux = Vector3.UnitX; uy = Vector3.UnitY; uz = Vector3.UnitZ; oo = new Vector3(cl.X, cl.Y, 0.0f); } else if (radius > 0.0) { // spherical ocean uz = Vector3.Normalize(cl);// unit z vector of ocean frame, in local space if (oldLtoo != Matrix.Identity) { //Matrix m = Matrix.Transpose(oldLtoo); //ux = vec3d(o->oldLtoo[1][0], o->oldLtoo[1][1], o->oldLtoo[1][2]).crossProduct(uz).normalize(); ux = Vector3.Normalize(Vector3.Cross(new Vector3(oldLtoo.M21, oldLtoo.M22, oldLtoo.M23), uz)); } else { ux = Vector3.Normalize(Vector3.Cross(Vector3.UnitZ, uz)); } uy = Vector3.Cross(uz, ux);// unit y vector // negate this ?? //oo = uz * radius; // origin of ocean frame, in local space oo = ux * radius; } else { // cylindrical ocean uz = Vector3.Normalize(new Vector3(0, -cl.Y, -cl.Z)); ux = Vector3.UnitX; uy = Vector3.Cross(uz, ux); oo = new Vector3(cl.X, 0, 0) + uz * radius; } Matrix ltoo = new Matrix( ux.X, uy.X, uz.X, 0.0f, ux.Y, uy.Y, uz.Y, 0.0f, ux.Z, uy.Z, uz.Z, 0.0f, -Vector3.Dot(ux, oo), -Vector3.Dot(uy, oo), -Vector3.Dot(uz, oo), 1.0f); ltoo = Matrix.Transpose(ltoo); // compute ctoo = cameraToOcean transform Matrix ctoo = ltoo * Matrix.Transpose (ctol); if (oldLtoo != Matrix.Identity) { Vector3 delta = Vector3.Transform(Vector3.Zero, Matrix.Transpose ( ltoo * Matrix.Invert(oldLtoo))); offset += delta; } oldLtoo = ltoo; Matrix ctos = Matrix.Transpose (Parent.cam.Projection); //world*view*projection //n->getOwner()->getCameraToScreen(); Matrix stoc = Matrix.Invert (ctos); Vector3 oc = Vector3.Transform(Vector3.Zero, ctoo); Vector3 worldsunDir = Parent.vLightDirection; Vector3 oceanSunDir = Vector3.Transform(worldsunDir, ltoo * Parent.cam.View); BoundingFrustum frustum = new BoundingFrustum(ctos); Vector3 left = frustum.Left.Normal; Vector3 right = frustum.Right.Normal; float fov = (float)System.Math.Acos(Vector3.Dot(-left, right)); float pixelSize = (float)System.Math.Atan(System.Math.Tan(fov / 2.0f) / (device.Viewport.Height / 2.0f));// angle under which a screen pixel is viewed from the camera float h = oc.Z; Vector4 tmp1,tmp2; tmp1 = Vector4.Transform ( new Vector4 (0,0,0,1),stoc); tmp2 = Vector4.Transform (new Vector4 (tmp1.X,tmp1.Y,tmp1.Z,0),ctoo); Vector3 A0 = new Vector3 (tmp2.X,tmp2.Y,tmp2.Z); tmp1 = Vector4.Transform ( new Vector4 (1,0,0,0),stoc); tmp2 = Vector4.Transform (new Vector4 (tmp1.X,tmp1.Y,tmp1.Z,0),ctoo); Vector3 dA = new Vector3 (tmp2.X,tmp2.Y,tmp2.Z); tmp1 = Vector4.Transform ( new Vector4 (0,1,0,0),stoc); tmp2 = Vector4.Transform (new Vector4 (tmp1.X,tmp1.Y,tmp1.Z,0),ctoo); Vector3 B = new Vector3 (tmp2.X,tmp2.Y,tmp2.Z); if (radius == 0.0) { horizon1U = new Vector3(-(h * 1e-6f + A0.Z) / B.Z, -dA.Z / B.Z, 0); horizon2U = Vector3.Zero; } else { double h1 = h * (h + 2.0 * radius); double h2 = (h + radius) * (h + radius); double alpha = Vector3.Dot (B,B) * h1 - B.Z * B.Z * h2; double beta0 = (Vector3.Dot (A0,B) * h1 - B.Z * A0.Z * h2) / alpha; double beta1 = (Vector3.Dot (dA,B) * h1 - B.Z * dA.Z * h2) / alpha; double gamma0 = (Vector3.Dot (A0,A0) * h1 - A0.Z * A0.Z * h2) / alpha; double gamma1 = (Vector3.Dot(A0,dA) * h1 - A0.Z * dA.Z * h2) / alpha; double gamma2 = (Vector3.Dot(dA,dA) * h1 - dA.Z * dA.Z * h2) / alpha; horizon1U = new Vector3((float)-beta0, (float)-beta1, 0); horizon2U = new Vector3((float)beta0 * (float)beta0 - (float)gamma0, 2.0f * ((float)beta0 * (float)beta1 - (float)gamma1), (float)beta1 * (float)beta1 - (float)gamma2); } timeU = (float)gametime.TotalGameTime.TotalMilliseconds *0.0001f; heightOffsetU = -meanHeight; lodsU = new Vector4(resolution, pixelSize * resolution, (float)System.Math.Log(lambdaMin) / (float)System.Math.Log(2.0f), (nbWaves - 1.0f) / ((float)System.Math.Log(lambdaMax) / (float)System.Math.Log(2.0f) - (float)System.Math.Log(lambdaMin) / (float)System.Math.Log(2.0f))); cameraToOceanU = Matrix.Transpose (ctoo); screenToCameraU = stoc; cameraToScreenU = ctos; oceanCameraPosU = new Vector3(-offset.X, -offset.Y, -offset.Z); oceanToWorldU = Matrix.Transpose ( Parent.cam.Projection * Parent.cam.View) * Matrix.Invert (ltoo); oceanToCameraU = Matrix.Transpose(Matrix.Invert(ctoo)); //Global Variables watereffect.Parameters["cameraToOcean"].SetValue(cameraToOceanU); watereffect.Parameters["screenToCamera"].SetValue(screenToCameraU); // World Projection Matrix Inverse watereffect.Parameters["cameraToScreen"].SetValue (cameraToScreenU); // World Projection Matrix watereffect.Parameters["oceanToCamera"].SetValue(oceanToCameraU); watereffect.Parameters["oceanToWorld"].SetValue(oceanToWorldU); watereffect.Parameters["oceanCameraPos"].SetValue(oceanCameraPosU); watereffect.Parameters["oceanSunDir"].SetValue(oceanSunDir); watereffect.Parameters["horizon1"].SetValue(horizon1U); watereffect.Parameters["horizon2"].SetValue(horizon2U); watereffect.Parameters["worldCameraPos"].SetValue(Parent.cam.Position); watereffect.Parameters["worldSunDir"].SetValue(worldsunDir); watereffect.Parameters["seaColor"].SetValue(seaColor); watereffect.Parameters["seaRoughness"].SetValue(sigmaXsq); watereffect.Parameters["radius"].SetValue(radius); watereffect.Parameters["nbWaves"].SetValue(nbWaves); // number of waves watereffect.Parameters["heightOffset"].SetValue(heightOffsetU); ; // so that surface height is centered around z = 0 watereffect.Parameters["time"].SetValue (timeU); // current time // grid cell size in pixels, angle under which a grid cell is seen, // and parameters of the geometric series used for wavelengths watereffect.Parameters["lods"].SetValue(lodsU); if (screengrid == null || screenWidth != device.Viewport.Width || screenHeight != device.Viewport.Height ) { screenWidth = device.Viewport.Width; screenHeight = device.Viewport.Height; screengrid = new ScreenGrid (); float f = 1.25f; int NX = (int)(f * screenWidth / resolution); int NY = (int)(f * screenHeight / resolution); for (int i = 0; i < NY; ++i) { for (int j = 0; j < NX; ++j) { screengrid.AddVertex (new Vector2(2.0f*f*j/(NX-1.0f)-f, 2.0f*f*i/(NY-1.0f)-f)); } } for (int i = 0; i < NY-1; ++i) { for (int j = 0; j < NX-1; ++j) { screengrid.AddIndices(i * NX + j); screengrid.AddIndices(i * NX + j + 1); screengrid.AddIndices((i + 1) * NX + j); screengrid.AddIndices((i + 1) * NX + j); screengrid.AddIndices(i * NX + j + 1); screengrid.AddIndices((i + 1) * NX + j + 1); } } screengrid.UpdateBuffers(device); } } [/source] and now for the shader code original code [source] /* * Proland: a procedural landscape rendering library. * Copyright (c) 2008-2011 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Proland is distributed under a dual-license scheme. * You can obtain a specific license from Inria: proland-licensing@inria.fr. */ /* * Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat. */ #include "globalsShader.glhl" #include "textureTile.glsl" const float Z0 = 1.0; uniform float radius; uniform mat4 cameraToOcean; uniform mat4 screenToCamera; uniform mat4 cameraToScreen; uniform mat3 oceanToCamera; uniform mat4 oceanToWorld; uniform vec3 oceanCameraPos; uniform vec3 oceanSunDir; uniform vec3 horizon1; uniform vec3 horizon2; uniform float nbWaves; // number of waves uniform sampler1D wavesSampler; // waves parameters (h, omega, kx, ky) in wind space uniform float heightOffset; // so that surface height is centered around z = 0 uniform float time; // current time // grid cell size in pixels, angle under which a grid cell is seen, // and parameters of the geometric series used for wavelengths uniform vec4 lods; #define NYQUIST_MIN 0.5 // wavelengths below NYQUIST_MIN * sampling period are fully attenuated #define NYQUIST_MAX 1.25 // wavelengths above NYQUIST_MAX * sampling period are not attenuated at all const float g = 9.81; const float PI = 3.141592657; #ifdef _VERTEX_ layout(location=0) in vec3 vertex; out float oceanLod; out vec2 oceanUv; // coordinates in wind space used to compute P(u) out vec3 oceanP; // wave point P(u) in ocean space out vec3 oceanDPdu; // dPdu in wind space, used to compute N out vec3 oceanDPdv; // dPdv in wind space, used to compute N out float oceanRoughness; // variance of unresolved waves in wind space vec2 oceanPos(vec3 vertex, out float t, out vec3 cameraDir, out vec3 oceanDir) { float horizon = horizon1.x + horizon1.y * vertex.x - sqrt(horizon2.x + (horizon2.y + horizon2.z * vertex.x) * vertex.x); cameraDir = normalize((screenToCamera * vec4(vertex.x, min(vertex.y, horizon), 0.0, 1.0)).xyz); oceanDir = (cameraToOcean * vec4(cameraDir, 0.0)).xyz; float cz = oceanCameraPos.z; float dz = oceanDir.z; if (radius == 0.0) { t = (heightOffset + Z0 - cz) / dz; } else { float b = dz * (cz + radius); float c = cz * (cz + 2.0 * radius); float tSphere = - b - sqrt(max(b * b - c, 0.0)); float tApprox = - cz / dz * (1.0 + cz / (2.0 * radius) * (1.0 - dz * dz)); t = abs((tApprox - tSphere) * dz) < 1.0 ? tApprox : tSphere; } return oceanCameraPos.xy + t * oceanDir.xy; } vec2 oceanPos(vec3 vertex) { float t; vec3 cameraDir; vec3 oceanDir; return oceanPos(vertex, t, cameraDir, oceanDir); } void main() { float t; vec3 cameraDir; vec3 oceanDir; vec2 uv = oceanPos(vertex, t, cameraDir, oceanDir); float lod = - t / oceanDir.z * lods.y; // size in meters of one grid cell, projected on the sea surface vec2 duv = oceanPos(vertex + vec3(0.0, 0.01, 0.0)) - uv; vec3 dP = vec3(0.0, 0.0, heightOffset + (radius > 0.0 ? 0.0 : Z0)); vec3 dPdu = vec3(1.0, 0.0, 0.0); vec3 dPdv = vec3(0.0, 1.0, 0.0); float roughness = getSeaRoughness(); if (duv.x != 0.0 || duv.y != 0.0) { float iMin = max(floor((log2(NYQUIST_MIN * lod) - lods.z) * lods.w), 0.0); for (float i = iMin; i < nbWaves; ++i) { vec4 wt = textureLod(wavesSampler, (i + 0.5) / nbWaves, 0.0); float phase = wt.y * time - dot(wt.zw, uv); float s = sin(phase); float c = cos(phase); float overk = g / (wt.y * wt.y); float wm = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod); vec3 factor = wm * wt.x * vec3(wt.zw * overk, 1.0); dP += factor * vec3(s, s, c); vec3 dPd = factor * vec3(c, c, -s); dPdu -= dPd * wt.z; dPdv -= dPd * wt.w; wt.zw *= overk; float kh = wt.x / overk; roughness -= wt.z * wt.z * (1.0 - sqrt(1.0 - kh * kh)); } } vec3 p = t * oceanDir + dP + vec3(0.0, 0.0, oceanCameraPos.z); if (radius > 0.0) { dPdu += vec3(0.0, 0.0, -p.x / (radius + p.z)); dPdv += vec3(0.0, 0.0, -p.y / (radius + p.z)); } gl_Position = cameraToScreen * vec4(t * cameraDir + oceanToCamera * dP, 1.0); oceanLod = lod; oceanUv = uv; oceanP = p; oceanDPdu = dPdu; oceanDPdv = dPdv; oceanRoughness = roughness; } #endif #ifdef _FRAGMENT_ #include "atmosphereShader.glhl" #include "oceanBrdf.glhl" #include "clouds.glhl" in float oceanLod; in vec2 oceanUv; in vec3 oceanP; in vec3 oceanDPdu; in vec3 oceanDPdv; in float oceanRoughness; layout(location=0) out vec4 data; void main() { vec3 WSD = getWorldSunDir(); vec3 WCP = getWorldCameraPos(); float lod = oceanLod; vec2 uv = oceanUv; vec3 dPdu = oceanDPdu; vec3 dPdv = oceanDPdv; float roughness = oceanRoughness; float iMAX = min(ceil((log2(NYQUIST_MAX * lod) - lods.z) * lods.w), nbWaves - 1.0); float iMax = floor((log2(NYQUIST_MIN * lod) - lods.z) * lods.w); float iMin = max(0.0, floor((log2(NYQUIST_MIN * lod / lods.x) - lods.z) * lods.w)); for (float i = iMin; i <= iMAX; i += 1.0) { vec4 wt = textureLod(wavesSampler, (i + 0.5) / nbWaves, 0.0); float phase = wt.y * time - dot(wt.zw, uv); float s = sin(phase); float c = cos(phase); float overk = g / (wt.y * wt.y); float wm = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod); float wn = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod * lods.x); vec3 factor = (1.0 - wm) * wn * wt.x * vec3(wt.zw * overk, 1.0); vec3 dPd = factor * vec3(c, c, -s); dPdu -= dPd * wt.z; dPdv -= dPd * wt.w; wt.zw *= overk; float kh = i < iMax ? wt.x / overk : 0.0; float wkh = (1.0 - wn) * kh; roughness -= wt.z * wt.z * (sqrt(1.0 - wkh * wkh) - sqrt(1.0 - kh * kh)); } roughness = max(roughness, 1e-5); vec3 earthCamera = vec3(0.0, 0.0, oceanCameraPos.z + radius); vec3 earthP = radius > 0.0 ? normalize(oceanP + vec3(0.0, 0.0, radius)) * (radius + 10.0) : oceanP; vec3 oceanCamera = vec3(0.0, 0.0, oceanCameraPos.z); vec3 V = normalize(oceanCamera - oceanP); vec3 N = normalize(cross(dPdu, dPdv)); if (dot(V, N) < 0.0) { N = reflect(N, V); // reflects backfacing normals } vec3 sunL; vec3 skyE; vec3 extinction; sunRadianceAndSkyIrradiance(earthP, N, oceanSunDir, sunL, skyE); vec3 worldP = (oceanToWorld * vec4(oceanP, 1.0)).xyz; sunL *= cloudsShadow(worldP, WSD, 0.0, dot(normalize(worldP), WSD), radius); vec3 surfaceColor = oceanRadiance(V, N, oceanSunDir, roughness, sunL, skyE); // aerial perspective vec3 inscatter = inScattering(earthCamera, earthP, oceanSunDir, extinction, 0.0); vec3 finalColor = surfaceColor * extinction + inscatter; data.rgb = hdr(finalColor); data.a = 1.0; } #endif [/source] and now for my code [source] //Global Variables float4x4 cameraToOcean; float4x4 screenToCamera; // World Projection Matrix Inverse float4x4 cameraToScreen; // World Projection Matrix float3x3 oceanToCamera; float4x4 oceanToWorld; float3 oceanCameraPos; float3 oceanSunDir; float3 horizon1; float3 horizon2; float3 worldCameraPos; float3 worldSunDir; float3 seaColor; float hdrExposure = 0.3f; float seaRoughness; float radius; float nbWaves; // number of waves float heightOffset; // so that surface height is centered around z = 0 float time; // current time // grid cell size in pixels, angle under which a grid cell is seen, // and parameters of the geometric series used for wavelengths float4 lods; ? //Constants #define PI 3.141592657 const float Z0 = 1.0; const float g = 9.81; #define NYQUIST_MIN 0.5 // wavelengths below NYQUIST_MIN * sampling period are fully attenuated #define NYQUIST_MAX 1.25 // wavelengths above NYQUIST_MAX * sampling period are not attenuated at all //Textures texture wavesTexture; // waves parameters (h, omega, kx, ky) in wind space texture2d sampler wavesSampler = sampler_state { texture = <wavesTexture>; magfilter = POINT; minfilter = POINT; mipfilter = POINT; AddressU = CLAMP; AddressV = CLAMP; }; ? struct VertexShaderInput { float4 Position : POSITION0; }; struct VertexShaderOutput { float4 Position : POSITION0; float oceanLod : TEXCOORD0; float2 oceanUv : TEXCOORD1; // coordinates in wind space used to compute P(u) float3 oceanP: TEXCOORD2; // wave point P(u) in ocean space float3 oceanDPdu: TEXCOORD3; // dPdu in wind space, used to compute N float3 oceanDPdv: TEXCOORD4; // dPdv in wind space, used to compute N float oceanRoughness: TEXCOORD5; // variance of unresolved waves in wind space }; //-------------------------------------------------------------- //Utilitie Function Section //-------------------------------------------------------------- float3 hdr(float3 L) { #ifndef NOHDR L = L * hdrExposure; L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r); L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g); L.b = L.b < 1.413 ? pow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b); #endif return L; } //--------------------------------------------- // Fresnel Functions //--------------------------------------------- float meanFresnel(float cosThetaV, float sigmaV) { return pow(1.0 - cosThetaV, 5.0 * exp(-2.69 * sigmaV)) / (1.0 + 22.7 * pow(sigmaV, 1.5)); } float meanFresnel(float3 V, float3 N, float sigmaSq) { return meanFresnel(dot(V, N), sqrt(sigmaSq)); } //----------------------------------------------- //Radiance Functions //----------------------------------------------- float reflectedSunRadiance(float3 V, float3 N, float3 L, float sigmaSq) { float3 H = normalize(L + V); float hn = dot(H, N); float p = exp(-2.0 * ((1.0 - hn * hn) / sigmaSq) / (1.0 + hn)) / (4.0 * PI * sigmaSq); float c = 1.0 - dot(V, H); float c2 = c * c; float fresnel = 0.02 + 0.98 * c2 * c2 * c; float zL = dot(L, N); float zV = dot(V, N); zL = max(zL, 0.01); zV = max(zV, 0.01); // brdf times cos(thetaL) return zL <= 0.0 ? 0.0 : max(fresnel * p * sqrt(abs(zL / zV)), 0.0); } float3 oceanRadiance(float3 V, float3 N, float3 L, float seaRoughness, float3 sunL, float3 skyE) { float F = meanFresnel(V, N, seaRoughness); float3 Lsun = reflectedSunRadiance(V, N, L, seaRoughness) * sunL; float3 Lsky = skyE * F / PI; float3 Lsea = (1.0 - F) * seaColor * skyE / PI; return Lsun + Lsky + Lsea; } //-------------------------------------------------------------- //Ocean Position Functions //-------------------------------------------------------------- float2 oceanPos(float3 vertex, out float t, out float3 cameraDir, out float3 oceanDir) { float horizon = horizon1.x + horizon1.y * vertex.x - sqrt(horizon2.x + (horizon2.y + horizon2.z * vertex.x) * vertex.x); cameraDir = normalize((mul(screenToCamera , float4(vertex.x, min(vertex.y, horizon), 0.0, 1.0))).xyz); oceanDir = (mul(cameraToOcean , float4(cameraDir, 0.0))).xyz; float cz = oceanCameraPos.z; float dz = oceanDir.z; if (radius == 0.0) { t = (heightOffset + Z0 - cz) / dz; } else { float b = dz * (cz + radius); float c = cz * (cz + 2.0 * radius); float tSphere = - b - sqrt(max(b * b - c, 0.0)); float tApprox = - cz / dz * (1.0 + cz / (2.0 * radius) * (1.0 - dz * dz)); t = abs((tApprox - tSphere) * dz) < 1.0 ? tApprox : tSphere; } return oceanCameraPos.xy + t * oceanDir.xy; } ? float2 oceanPos(float3 vertex) { float t; float3 cameraDir; float3 oceanDir; return oceanPos(vertex, t, cameraDir, oceanDir); } ? ? //-------------------------------------------------------------- VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output = (VertexShaderOutput)0; float t; float3 cameraDir; float3 oceanDir; float2 uv = oceanPos(input.Position.xyz, t, cameraDir, oceanDir); float lod = -t / oceanDir.y * lods.y; //-t / oceanDir.z * lods.y; // size in meters of one grid cell, projected on the sea surface float2 duv = oceanPos(input.Position.xyz + float3(0.0, 0.01, 0.0)) - uv; // maybe y not z //float4 tempPos = float4(worldPos.x, 0, worldPos.y, 1.0f); //worldPos /= 2000.0f; //worldPos += 0.5f / 512.0f; float3 dP = float3(0.0, 0.0, heightOffset + (radius > 0.0 ? 0.0 : Z0)); // maybe y not z float3 dPdu = float3(1.0, 0.0, 0.0); // maybe y not z float3 dPdv = float3(0.0, 1.0, 0.0); // maybe y not z ? float roughness = seaRoughness; if (duv.x != 0.0 || duv.y != 0.0) { float iMin = max(floor((log2(NYQUIST_MIN * lod) - lods.z) * lods.w), 0.0); for (float i = iMin; i < nbWaves; ++i) { float4 wt = tex1Dlod(wavesSampler, (i + 0.5) / nbWaves); float phase = wt.y * time - dot(wt.zw, uv); float s = sin(phase); float c = cos(phase); float overk = g / (wt.y * wt.y); float wm = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod); float3 factor = wm * wt.x * float3(wt.zw * overk, 1.0); dP += factor * float3(s, s, c); float3 dPd = factor * float3(c, c, -s); dPdu -= dPd * wt.z; dPdv -= dPd * wt.w; wt.zw *= overk; float kh = wt.x / overk; roughness -= wt.z * wt.z * (1.0 - sqrt(1.0 - kh * kh)); } } ? ? ? float3 p = t * oceanDir + dP + float3(0.0, 0.0, oceanCameraPos.z); // maybe y not z if (radius > 0.0) { dPdu += float3(0.0, 0.0, -p.x / (radius + p.z)); dPdv += float3(0.0, 0.0, -p.y / (radius + p.z)); } output.Position = mul(cameraToScreen, float4(t * cameraDir + mul(dP,oceanToCamera), 1.0)); //output.Position = mul(cameraToScreen,float4(input.Position.xyz,1)); //logrithmic zbuffer. const float Cc = 1.0; const float Far = 1000000000000.0; output.Position.z = log(Cc*output.Position.z + 1) / log(Cc*Far + 1) * output.Position.w; output.oceanLod = lod; output.oceanUv = uv; output.oceanP = p; output.oceanDPdu = dPdu; output.oceanDPdv = dPdv; output.oceanRoughness = roughness; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float3 WSD = worldSunDir; float3 WCP = worldCameraPos; float lod = input.oceanLod; float2 uv = input.oceanUv; float3 dPdu = input.oceanDPdu; float3 dPdv = input.oceanDPdv; float roughness = input.oceanRoughness; float iMAX = min(ceil((log2(NYQUIST_MAX * lod) - lods.z) * lods.w), nbWaves - 1.0); float iMax = floor((log2(NYQUIST_MIN * lod) - lods.z) * lods.w); float iMin = max(0.0, floor((log2(NYQUIST_MIN * lod / lods.x) - lods.z) * lods.w)); for (float i = iMin; i <= iMAX; i += 1.0) { float4 wt = tex1Dlod(wavesSampler, (i + 0.5) / nbWaves); float phase = wt.y * time - dot(wt.zw, uv); float s = sin(phase); float c = cos(phase); float overk = g / (wt.y * wt.y); float wm = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod); float wn = smoothstep(NYQUIST_MIN, NYQUIST_MAX, (2.0 * PI) * overk / lod * lods.x); float3 factor = (1.0 - wm) * wn * wt.x * float3(wt.zw * overk, 1.0); float3 dPd = factor * float3(c, c, -s); dPdu -= dPd * wt.z; dPdv -= dPd * wt.w; wt.zw *= overk; float kh = i < iMax ? wt.x / overk : 0.0; float wkh = (1.0 - wn) * kh; roughness -= wt.z * wt.z * (sqrt(1.0 - wkh * wkh) - sqrt(1.0 - kh * kh)); } roughness = max(roughness, 1e-5); float3 earthCamera = float3(0.0, 0.0, oceanCameraPos.z + radius); float3 earthP = radius > 0.0 ? normalize(input.oceanP + float3(0.0, 0.0, radius)) * (radius + 10.0) : input.oceanP; float3 oceanCamera = float3(0.0, 0.0, oceanCameraPos.z); float3 V = normalize(oceanCamera - input.oceanP); float3 N = normalize(cross(dPdu, dPdv)); if (dot(V, N) < 0.0) { N = reflect(N, V); // reflects backfacing normals } float3 sunL = (float3)1; float3 skyE = (float3)1; float3 extinction = (float3)1; //sunRadianceAndSkyIrradiance(earthP, N, oceanSunDir, sunL, skyE); float3 worldP = (mul(oceanToWorld , float4(input.oceanP, 1.0))).xyz; //sunL *= cloudsShadow(worldP, WSD, 0.0, dot(normalize(worldP), WSD), radius); float3 surfaceColor = oceanRadiance(V, N, oceanSunDir, roughness, sunL, skyE); // aerial perspective float3 inscatter = (float3)1; //= inScattering(earthCamera, earthP, oceanSunDir, extinction, 0.0); float3 finalColor = surfaceColor * extinction + inscatter; float4 data; data.rgb = hdr(finalColor); data.a = 1.0; return data; //return float4(1, 0, 0, 1); } technique Technique1 { pass Pass1 { // TODO: set renderstates here. VertexShader = compile vs_3_0 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } } [/source] and now a picture of the result im getting. Bare in mind this is suppose to be a sphere, it looks like its half working must be something to do with the y/z axis. I know its not a good thing to just post code and ask for help but im going nuts trying to figure this out any help will be much appreciated. Budinga and this is the flat version it seems to be working but the projection and the surface its projecting is been rendered very strange.
  5. The simplest way to do it is to just check the mounse has clicked within the bounds of the rectangle. example: This is just a psudo example. [code] if (mouse.leftclick) { if (mouse.x > rectangle.position.x && mouse.x < (rectangle.position.x+width)) { if (mouse.y < rectangle.position.y && mouse.y < (rectangle.position.y + height)) { do something when rectangle is cliked. } } } [/code] If you mean what i think you mean about win32 to d3d you mean you need to compensate for the clientsize verses windows size have a look at this link. [code] [url="http://www.directxtutorial.com/Tutorial11/A-A/AA4.aspx"]http://www.directxtutorial.com/Tutorial11/A-A/AA4.aspx[/url] [/code]
  6. I am currently working on a Planet renderer uses a geomipmaps for the terrain, and realtime atmospheric scattering, water and clouds are a bit crappy at the moment, but i am getting there i have just managed to get the fps from 20fps to max of 150fps so still heavy work in progress. But thought i mite post some screenshots. [url="http://imageshack.us/photo/my-images/685/screeny80.jpg/"][img]http://img685.imageshack.us/img685/1241/screeny80.jpg[/img][/url]
  7. Well i am having a problem trying to snc the clipmap cube face centers from my procedural planet renderer, im very stuck at the moment. I want to get the same cube center no matter were the camera is i think i need some sort of projection. heres a pic of the clipmaps synced, but they do that as i move away and when i move close the move away from me. Anybody got any ideas. [url="http://imageshack.us/photo/my-images/339/screeny55.jpg/"][img]http://img339.imageshack.us/img339/4744/screeny55.jpg[/img][/url] Maybe i could have some sort of virtual box and project, from the camera and get an x,z coord on that box, just a bit stumped on how to go about it. Any ideas will be great.
  8. I just noticed all my code is msessed up i cant seem to get it posted right, i will just explain the prob i got. Well when i draw the atmosphere after the planet like i am suppost to i get a white sphere in the middle no blending, and then when i enable alphablending which as far as i can tell is right i get some strange triangle anomolies, maybe i have written the shader wrong or the sphere is wrong i am very confused as far as i know the sphere is above 20k verts, wnybody got any ideas.
  9. [quote name='Budinga' timestamp='1295988330' post='4764657'] <P>Well i have spent loadz of time working on procedural planet based on oneal's sandbox all written in vb.net and xna.i have the basic shaders working down to a T, but i have 1 problem, as i have to render the atmosphere mesh after the planet and cull the front faces as i understand when i do this i get gaps in the triangles and it overlays the planet, am i generating it wrong or am i doing something else wrong. the way i got round it is to render the atmosphere after the planet with not depth buffer but this does not work properly as when you go round the planet the atmosphere lookes strange. here is the code i am using to generate and render the sphere. i also got a slight prob using the bitshifting to calculate the quadtrees but im getting there, i think i should fix this first as the rest works ok for now.<BR><BR>[code]<BR> Public Sub New(ByVal Dev As GraphicsDevice, ByVal Cam As Camera, ByVal PlMap As PlanetaryMap, ByVal FromSpaceShader As Effect, ByVal Stacks As Integer, ByVal Slices As Integer, ByVal Radius As Single)<BR> Device = Dev<BR> Camera = Camera<BR> Planet = PlMap<BR> Dim elm() As VertexElement = {New VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0)}<BR> Declaration = New VertexDeclaration(Device, elm)</P> <P> ' Calculates the resulting number of vertices and indices<BR> Dim numberVertices = (Stacks + 1) * (Slices + 1)<BR> Dim numberIndices = (3 * Stacks * (Slices + 1)) * 2<BR> Dim indices As Integer() = New Integer(numberIndices - 1) {}<BR> Dim vertices As Vector3() = New Vector3(numberVertices - 1) {}</P> <P> Dim StackAngle As Single = MathHelper.Pi / CSng(Stacks)<BR> Dim SliceAngle As Single = CSng(Math.PI * 2.0) / CSng(Slices)</P> <P> ' Generate the group of Stacks for the sphere <BR> Dim wVertexIndex As Integer = 0<BR> Dim vertexCount As Integer = 0<BR> Dim indexCount As Integer = 0</P> <P> For stack As Integer = 0 To (Stacks + 1) - 1</P> <P> Dim r As Single = CSng(Math.Sin(CSng(stack) * StackAngle))<BR> Dim y As Single = CSng(Math.Cos(CSng(stack) * StackAngle))</P> <P> ' Generate the group of segments for the current Stack <BR> For slice As Integer = 0 To (Slices + 1) - 1<BR> Dim x As Single = r * CSng(Math.Sin(CSng(slice) * SliceAngle))<BR> Dim z As Single = r * CSng(Math.Cos(CSng(slice) * SliceAngle))<BR> vertices(vertexCount) = New Vector3(x * Radius, y * Radius, z * Radius)</P> <P> 'vertices(vertexCount).Normal = Vector3.Normalize(New Vector3(x, y, z))</P> <P> 'vertices(vertexCount).TextureCoordinate = New Vector2(CSng(slice) / CSng(Slices), CSng(stack) / CSng(Stacks))<BR> vertexCount += 1<BR> If Not (stack = (Stacks - 1)) Then<BR> ' First Face<BR> indices(indexCount) = wVertexIndex + (Slices + 1)<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex + 1<BR> indexCount += 1</P> <P> ' Second Face<BR> indices(indexCount) = wVertexIndex + (Slices)<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex + (Slices + 1)<BR> indexCount += 1</P> <P> wVertexIndex += 1<BR> End If<BR> Next<BR> Next</P> <P> Me.IndexCount = indexCount<BR> Me.VertexCount = wVertexIndex</P> <P> Vertexbuffer = New VertexBuffer(Device, GetType(Vector3), numberVertices, BufferUsage.None)<BR> Vertexbuffer.SetData(vertices, 0, vertices.Length)<BR> IndexBuffer = New IndexBuffer(Device, GetType(Integer), numberIndices, BufferUsage.None)<BR> IndexBuffer.SetData(indices, 0, indices.Length)<BR> AtmosphereEffect = FromSpaceShader<BR> End Sub<BR>[/code]<BR><BR><BR>and the render code<BR><BR>[code]<BR> Public Sub Draw(ByVal gametime As GameTime)</P> <P> Device.VertexDeclaration = Declaration</P> <P> </P> <P> Device.Vertices(0).SetSource(Vertexbuffer, 0, 12)<BR> Device.Indices = IndexBuffer</P> <P> SetAtmosphereFromSPaceShaderVariables(gametime)<BR><BR> If IsInAtmosphere Then<BR> AtmosphereEffect.CurrentTechnique = AtmosphereEffect.Techniques("SkyFromAtmosphere")<BR> Else<BR> AtmosphereEffect.CurrentTechnique = AtmosphereEffect.Techniques("SkyFromSpace")<BR> End If</P> <P><BR> AtmosphereEffect.Begin()</P> <P> For Each pass As EffectPass In AtmosphereEffect.CurrentTechnique.Passes<BR> pass.Begin()</P> <P> Device.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, VertexCount, 0, IndexCount)</P> <P> pass.End()<BR> Next</P> <P> AtmosphereEffect.End()</P> <P> Device.RenderState.DepthBufferEnable = True<BR></P> <P> End Sub<BR>[/code]<BR><BR>you can see the progress screenshots at budinga.blogspot.com. Help is always much apreciated. </P> [/quote]
  10. <P>Well i have spent loadz of time working on procedural planet based on oneal's sandbox all written in vb.net and xna.i have the basic shaders working down to a T, but i have 1 problem, as i have to render the atmosphere mesh after the planet and cull the front faces as i understand when i do this i get gaps in the triangles and it overlays the planet, am i generating it wrong or am i doing something else wrong. the way i got round it is to render the atmosphere after the planet with not depth buffer but this does not work properly as when you go round the planet the atmosphere lookes strange. here is the code i am using to generate and render the sphere. i also got a slight prob using the bitshifting to calculate the quadtrees but im getting there, i think i should fix this first as the rest works ok for now.<BR><BR>[code]<BR> Public Sub New(ByVal Dev As GraphicsDevice, ByVal Cam As Camera, ByVal PlMap As PlanetaryMap, ByVal FromSpaceShader As Effect, ByVal Stacks As Integer, ByVal Slices As Integer, ByVal Radius As Single)<BR> Device = Dev<BR> Camera = Camera<BR> Planet = PlMap<BR> Dim elm() As VertexElement = {New VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0)}<BR> Declaration = New VertexDeclaration(Device, elm)</P> <P> ' Calculates the resulting number of vertices and indices<BR> Dim numberVertices = (Stacks + 1) * (Slices + 1)<BR> Dim numberIndices = (3 * Stacks * (Slices + 1)) * 2<BR> Dim indices As Integer() = New Integer(numberIndices - 1) {}<BR> Dim vertices As Vector3() = New Vector3(numberVertices - 1) {}</P> <P> Dim StackAngle As Single = MathHelper.Pi / CSng(Stacks)<BR> Dim SliceAngle As Single = CSng(Math.PI * 2.0) / CSng(Slices)</P> <P> ' Generate the group of Stacks for the sphere <BR> Dim wVertexIndex As Integer = 0<BR> Dim vertexCount As Integer = 0<BR> Dim indexCount As Integer = 0</P> <P> For stack As Integer = 0 To (Stacks + 1) - 1</P> <P> Dim r As Single = CSng(Math.Sin(CSng(stack) * StackAngle))<BR> Dim y As Single = CSng(Math.Cos(CSng(stack) * StackAngle))</P> <P> ' Generate the group of segments for the current Stack <BR> For slice As Integer = 0 To (Slices + 1) - 1<BR> Dim x As Single = r * CSng(Math.Sin(CSng(slice) * SliceAngle))<BR> Dim z As Single = r * CSng(Math.Cos(CSng(slice) * SliceAngle))<BR> vertices(vertexCount) = New Vector3(x * Radius, y * Radius, z * Radius)</P> <P> 'vertices(vertexCount).Normal = Vector3.Normalize(New Vector3(x, y, z))</P> <P> 'vertices(vertexCount).TextureCoordinate = New Vector2(CSng(slice) / CSng(Slices), CSng(stack) / CSng(Stacks))<BR> vertexCount += 1<BR> If Not (stack = (Stacks - 1)) Then<BR> ' First Face<BR> indices(indexCount) = wVertexIndex + (Slices + 1)<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex + 1<BR> indexCount += 1</P> <P> ' Second Face<BR> indices(indexCount) = wVertexIndex + (Slices)<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex<BR> indexCount += 1</P> <P> indices(indexCount) = wVertexIndex + (Slices + 1)<BR> indexCount += 1</P> <P> wVertexIndex += 1<BR> End If<BR> Next<BR> Next</P> <P> Me.IndexCount = indexCount<BR> Me.VertexCount = wVertexIndex</P> <P> Vertexbuffer = New VertexBuffer(Device, GetType(Vector3), numberVertices, BufferUsage.None)<BR> Vertexbuffer.SetData(vertices, 0, vertices.Length)<BR> IndexBuffer = New IndexBuffer(Device, GetType(Integer), numberIndices, BufferUsage.None)<BR> IndexBuffer.SetData(indices, 0, indices.Length)<BR> AtmosphereEffect = FromSpaceShader<BR> End Sub<BR>[/code]<BR><BR><BR>and the render code<BR><BR>[code]<BR> Public Sub Draw(ByVal gametime As GameTime)</P> <P> Device.VertexDeclaration = Declaration</P> <P> </P> <P> Device.Vertices(0).SetSource(Vertexbuffer, 0, 12)<BR> Device.Indices = IndexBuffer</P> <P> SetAtmosphereFromSPaceShaderVariables(gametime)<BR><BR> If IsInAtmosphere Then<BR> AtmosphereEffect.CurrentTechnique = AtmosphereEffect.Techniques("SkyFromAtmosphere")<BR> Else<BR> AtmosphereEffect.CurrentTechnique = AtmosphereEffect.Techniques("SkyFromSpace")<BR> End If</P> <P><BR> AtmosphereEffect.Begin()</P> <P> For Each pass As EffectPass In AtmosphereEffect.CurrentTechnique.Passes<BR> pass.Begin()</P> <P> Device.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, VertexCount, 0, IndexCount)</P> <P> pass.End()<BR> Next</P> <P> AtmosphereEffect.End()</P> <P> Device.RenderState.DepthBufferEnable = True<BR></P> <P> End Sub<BR>[/code]<BR><BR>you can see the progress screenshots at budinga.blogspot.com. Help is always much apreciated. </P> I was generating the sphere wrong, needed to get rid of the -1 in the loop and also use trianglelist instead of strip.
  11. I could be wrong but as far as i remember the libs are in C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0 this is what i use for my vb.net apps, hope this helps. and im not sure , but for unmanaged dx you have to set the include and lib dir's for the dx sdk.
  12. Right i have noticed what i was well asuming wrong the shader works, the only problem is it assumes that the sphere i am using the shader on is the planet so the white very obvious is the lit areas, now i just need to find a way to make it look cool and transparent enough for my planet. The code works well to an extent, i have changed it a bit. But i hope it comes in usefull to somebody, its not really my code anyways so thanx.
  13. Well i have progressed slightly in my quest to create a planet renderer in MDX 1.1 and vb.net. I now have a planet no LOD yet well a cube morphed in to a sphere, and i can somewat heightmap it, i am now trying to get an atmosphere shader working,based on sponeil.net code in HL shader, it is based on an implementation i found on the forums. I start with a DXMesh sphere and pass the shader over it all i get is a white band, and the rest of it is black. Here is an image of what i get. [URL] http://yfrog.com/evscreenshot492010143010j [/URL] [URL] http://yfrog.com/msscreenshot492010143016j [/URL] I am completely confused i have tryed everything all i get is that no matter what i do. My code i use is 'Atmosphere mesh generation code [CODE] Private Sub GenerateAtmosphere() AtmosphereInnerRad = CType((Me.Radius / 100 * 25) + Me.Radius, Single) Atmospehere = Mesh.Sphere(dev, AtmosphereInnerRad, 256, 128) Dim elements As VertexElement() = New VertexElement() {New VertexElement(0, 0, DeclarationType.Short4, DeclarationMethod.Default, DeclarationUsage.Position, 0), VertexElement.VertexDeclarationEnd} AtmosphereDeclaration = New VertexDeclaration(dev, elements) Atmospehere = Atmospehere.Clone(MeshFlags.Managed, elements, dev) End Sub [/CODE] shader setup code [CODE] Private Sub SetSkyFromSpaceEffectParameters() Dim m_vLight As Vector3 = New Vector3(1000, 1000, 1000) Dim ld As Single = Vector3MathHelper.MagnitudeSingle(m_vLight) Dim m_vLightDirection As Vector3 = New Vector3(m_vLight.X / ld, m_vLight.Y / ld, m_vLight.Z / ld) Dim m_nSamples As Single = 2 ' Number of sample rays to use in integral equation Dim m_Kr As Single = 0.0025F ' Rayleigh scattering constant Dim m_Kr4PI As Single = m_Kr * 4.0F * PI Dim m_Km As Single = 0.0015F ' Mie scattering constant Dim m_Km4PI As Single = m_Km * 4.0F * PI Dim m_ESun As Single = 5.0F ' Sun brightness constant Dim m_g As Single = -0.95F ' The Mie phase asymmetry factor 'Dim SkyRad As Single = Me.Radius + Me.Radius / 4 Dim m_fInnerRadius As Single = AtmosphereInnerRad Dim m_fOuterRadius As Single = AtmosphereInnerRad * 1.025F '* 4 'AtmosphereInnerRad * 1.025F Dim m_fScale As Single = 1 / (m_fOuterRadius - m_fInnerRadius) Dim m_fwavelength(2) As Single m_fwavelength(0) = 0.65F ' 650 nm for red m_fwavelength(1) = 0.57F ' 570 nm for green m_fwavelength(2) = 0.475F ' 475 nm for blue Dim m_fWavelength4(2) As Single m_fWavelength4(0) = Pow(m_fwavelength(0), 4.0F) ''powf?? m_fWavelength4(1) = Pow(m_fwavelength(1), 4.0F) m_fWavelength4(2) = Pow(m_fwavelength(2), 4.0F) Dim m_fRayleighScaleDepth As Single = 0.25F '0.25F Dim m_fMieScaleDepth As Single = 0.1F Dim m_fExposure As Single = 2.0F Dim CamPos() As Single = New Single() {Camera.CameraPosition.X, Camera.CameraPosition.Y, Camera.CameraPosition.Z} Dim LightPos() As Single = New Single() {m_vLightDirection.X, m_vLightDirection.Y, m_vLightDirection.Z} Dim Wavl() As Single = New Single() {1 / m_fWavelength4(0), 1 / m_fWavelength4(1), 1 / m_fWavelength4(2)} Dim CameraMag As Single = Vector3MathHelper.MagnitudeSingle(Camera.CameraPosition) Dim CameraMagSqr As Single = Vector3MathHelper.MagnitudeSquaredSingle(Camera.CameraPosition) AtmosphereEffect.SetValue("v3CameraPos", CamPos) AtmosphereEffect.SetValue("v3LightPos", LightPos) ' shader v1 AtmosphereEffect.SetValue("v3InvWavelength", Wavl) AtmosphereEffect.SetValue("fCameraHeight", CameraMag) AtmosphereEffect.SetValue("fCameraHeight2", CameraMagSqr) AtmosphereEffect.SetValue("fInnerRadius", m_fInnerRadius) AtmosphereEffect.SetValue("fInnerRadius2", m_fInnerRadius * m_fInnerRadius) AtmosphereEffect.SetValue("fOuterRadius", m_fOuterRadius) AtmosphereEffect.SetValue("fOuterRadius2", m_fOuterRadius * m_fOuterRadius) AtmosphereEffect.SetValue("fKrESun", m_Kr * m_ESun) ' shader v1 AtmosphereEffect.SetValue("fKmESun", m_Km * m_ESun) ' shader v1 AtmosphereEffect.SetValue("fKr4PI", m_Kr4PI) 'shader v1 AtmosphereEffect.SetValue("fKm4PI", m_Km4PI) 'shader v1 AtmosphereEffect.SetValue("fScale", m_fScale) '1.0F / (m_fOuterRadius - m_fInnerRadius))'shader v1 AtmosphereEffect.SetValue("fScaleDepth", m_fRayleighScaleDepth) 'shader v1 AtmosphereEffect.SetValue("fScaleOverScaleDepth", (1.0F / (m_fOuterRadius - m_fInnerRadius)) / m_fRayleighScaleDepth) AtmosphereEffect.SetValue("g", m_g) AtmosphereEffect.SetValue("g2", m_g * m_g) AtmosphereEffect.SetValue("nSamples", m_nSamples) 'shader v1 AtmosphereEffect.SetValue("fSamples", m_nSamples) 'shader v1 'AtmosphereEffect.SetValue("numSamples", m_nSamples) 'AtmosphereEffect.SetValue("samples", m_nSamples) AtmosphereEffect.SetValue("fExposure", m_fExposure) Dim World As Matrix = Matrix.Translation(New Vector3(0, 0, 0)) * Matrix.Scaling(1, 1, 1) 'Matrix.Scaling(AtmosphereInnerRad, AtmosphereInnerRad, AtmosphereInnerRad) '* Matrix.RotationX(Pitch) Dim WVP As Matrix = World * Camera.ViewProjectionMatrix 'dev.Transform.View * dev.Transform.Projection AtmosphereEffect.SetValue("WorldViewProjectionMatrix", WVP) ' shader v1 End Sub [/CODE] and finally my shader code [CODE] float4x4 WorldViewProjectionMatrix; float3 v3CameraPos; // The camera's current position float3 v3LightPos; // The direction vector to the light source float3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels float fCameraHeight; // The camera's current height float fCameraHeight2; // fCameraHeight^2 float fOuterRadius; // The outer (atmosphere) radius float fOuterRadius2; // fOuterRadius^2 float fInnerRadius; // The inner (planetary) radius float fInnerRadius2; // fInnerRadius^2 float fKrESun; // Kr * ESun float fKmESun; // Km * ESun float fKr4PI; // Kr * 4 * PI float fKm4PI; // Km * 4 * PI float fScale; // 1 / (fOuterRadius - fInnerRadius) float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found) float fScaleOverScaleDepth; // fScale / fScaleDepth int nSamples; float fSamples; float g; float g2; float fExposure =2; struct VertexShaderInput { float4 Position : POSITION0; }; struct VertexShaderOutput { float4 Position : POSITION0; float4 RayleighColor : TEXCOORD0; float4 MieColor : TEXCOORD1; float3 Direction : TEXCOORD2; }; float scale(float fCos) { float x = 1.0 - fCos; return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); } VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere) float3 v3Pos = input.Position.xyz; float3 v3Ray = v3Pos - v3CameraPos; float fFar = length(v3Ray); v3Ray /= fFar; // Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere) float B = 2.0 * dot(v3CameraPos, v3Ray); float C = fCameraHeight2 - fOuterRadius2; float fDet = max(0.0, B*B - 4.0 * C); float fNear = 0.5 * (-B - sqrt(fDet)); // Calculate the ray's starting position, then calculate its scattering offset float3 v3Start = v3CameraPos + v3Ray * fNear; fFar -= fNear; float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius; float fStartDepth = exp(-1.0 / fScaleDepth); float fStartOffset = fStartDepth*scale(fStartAngle); // Initialize the scattering loop variables float fSampleLength = fFar / fSamples; float fScaledLength = fSampleLength * fScale; float3 v3SampleRay = v3Ray * fSampleLength; float3 v3SamplePoint = v3Start + v3SampleRay * 0.5; // Now loop through the sample rays float3 v3FrontColor = float3(0.0, 0.0, 0.0); for(int i=0; i<nSamples; i++) { float fHeight = length(v3SamplePoint); float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight; float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle))); float3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); v3FrontColor += v3Attenuate * (fDepth * fScaledLength); v3SamplePoint += v3SampleRay; } // Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader output.MieColor = float4(v3FrontColor * fKmESun, 1.0); output.RayleighColor = float4(v3FrontColor * (v3InvWavelength * fKrESun), 1.0); output.Position = mul(input.Position, WorldViewProjectionMatrix); output.Direction = v3CameraPos - v3Pos; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float fCos = dot(v3LightPos, input.Direction) / length(input.Direction); float fRayleighPhase = 0.75 * (1.0 + fCos*fCos); float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5); float4 col=(fRayleighPhase * input.RayleighColor) + (fMiePhase * input.MieColor); col.a=max(col.b,col.r); //return fRayleighPhase * input.RayleighColor + fMiePhase * input.MieColor; return 1 - exp(-fExposure * col); } technique SkyFromSpace { pass Pass1 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } } [/CODE] I know this can be really tricky to get working, but it is slowing down work on other things, all help is much apreciated. [Edited by - Budinga on September 15, 2010 1:29:28 PM]
  14. OpenGL

    ok this is solved now. But just a question of advice do you guyz think i should use Roam or Quadtree for my planatery engine.
  15. OpenGL

    Thanx. Any ideas on getting normal vector of a d3d plane??? as far as i can see its just dim p as plane dim normal as vector3 = new vector3(p.a,p.b,p.c) is this correct or am i missing something??