10 . 2. hlsl effects ii

21
10.2. HLSL EFFECTS II More advanced forms of effect

Upload: bela

Post on 24-Feb-2016

67 views

Category:

Documents


0 download

DESCRIPTION

10 . 2. HLSL Effects II. More advanced forms of effect. HLSL Effects : Refractoion. Refraction HLSL effect. Refraction. A refraction effect is the change in direction of a wave (e.g. light/sound) due to a change in speed (typically when moving from one medium to another). - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 10 . 2. HLSL Effects II

10.2. HLSL EFFECTS IIMore advanced forms of effect

Page 2: 10 . 2. HLSL Effects II

HLSL EFFECTS : REFRACTOIONRefraction HLSL effect

Page 3: 10 . 2. HLSL Effects II

A refraction effect is the change in direction of a wave (e.g. light/sound) due to a change in speed (typically when moving from one medium to another).

The effect can be described using Snell's law which states that the angle of incidence (θ1) is related to the angle of refraction (θ2) based on the refractive index of each medium (n1, n2) as follows:

Refraction

Page 4: 10 . 2. HLSL Effects II

This particular implement will use three (full-screen) render targets:• Refraction target –

containing the source scene on which the refraction effect will be applied.

• Diffuse target – source texture (e.g. stained glass windows) that will be alpha combined within the refraction effect.

• Normal target – in order to simulate refraction we need to know the surface normal (held in this render target)

Refraction

Page 5: 10 . 2. HLSL Effects II

Refraction (definitions)GraphicsDeviceManager graphics;

Texture2D scene;

Texture2D refractionNormal;Texture2D refractionDiffuse;

float refractionOpacity = .2f;

float normalMapHeight = .05f;

RenderTarget2D sceneTarget;RenderTarget2D refractionNormalTarget; RenderTarget2D refractionDiffuseTarget;

sceneTarget = new RenderTarget2D(graphics.GraphicsDevice,graphics.GraphicsDevice.Viewport.Width,graphics.GraphicsDevice.Viewport.Height,1, SurfaceFormat.Color );

refractionNormalTarget = // same as aboverefractionDiffuseTarget = // same as above

Three render targets are defined to hold the rendered scene and any refraction normal+diffuse textures

In this example, a ‘mock’ scene is held within a texture as the refraction background

The fraction surface normals are defined alongside a diffuse image (e.g. stained glass windows) that will be alpha combined with the background scene).

This specifies the alpha value to be used to combine the diffuse texture within the effect

Height of each normal, controlling the strength of the refraction effect

Each render target is constructed to be the same size as the screen. This is convenient, however it is inefficient if the refracted textures only covers a small bit of the screen.

Page 6: 10 . 2. HLSL Effects II

Refraction (draw)protected override void Draw(GameTime gameTime){

RenderScene ();RenderRefractionDiffuseMap();RenderRefractionNormalMap();

refractionEffect.Parameters[“refractionDiffuse"].SetValue(refractionDiffuseTarget.GetTexture());

refractionEffect.Parameters[“refractionNormal"].

SetValue(refractionNormalTarget.GetTexture());

refractionEffect.Parameters[" refractionOpacity "].SetValue(refractionOpacity);

refractionEffect.Parameters["normalMapHeight"].SetValue(normalMapHeight);

Draw the base scene into the reflection map

Define the regions that will be refracted alongside refaction normals and diffuse textures

batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);

refractionEffect.Begin();refractionEffect.CurrentTechnique.Passes[0].Begin();

batch.Draw( sceneTarget.GetTexture(),new Rectangle( 0, 0,graphics.GraphicsDevice.PresentationParameters.BackBufferWidth,graphics.GraphicsDevice.PresentationParameters.BackBufferHeight),Color.White);

refractionEffect.CurrentTechnique.Passes[0].End();refractionEffect.End();batch.End();

base.Draw(gameTime);}

Pass the relevant parameters into the effect in preparation for drawing

Draw the generated scene texture to the screen, passing the texture through the refraction effect

Page 7: 10 . 2. HLSL Effects II

The RenderScene , RenderRefractionDiffuseMap, and RenderRefractionNormalMap methods all have the same structure and simply draw the relevant texture to the corresponding full-screen render target.

Refraction (draw)private void RenderScene (){

graphics.GraphicsDevice.SetRenderTarget(0, sceneTarget);

graphics.GraphicsDevice.Clear(Color.TransparentBlack);

batch.Begin();batch.Draw( scene,

new Rectangle( 0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height),

Color.White);batch.End();

graphics.GraphicsDevice.SetRenderTarget(0, null);

}

Set the desired render target

Obviously the batch can be used to draw numerous images (either defining the background scene or using multiple refractive objects)

Ensure all pixels have a default alpha value of 0

Change the render target to the back buffer

Page 8: 10 . 2. HLSL Effects II

Refraction (shader) float4 RefractionPixelShader(float2 texCoord : TEXCOORD0) : COLOR0

{float4 colour = 0;float4 texColour = tex2D(diffuseSampler, texCoord);

if (texColour.a > 0){

float4 normal = tex2D(normalSampler, texCoord);float2 offset = normalMapHeight * normal.rg;

float4 refractedColour = tex2D(sceneSampler , texCoord + offset);

colour = (texColour * refractionOpacity) + (refractedColour * (1.0f - refractionOpacity));

}

else{

colour = tex2D(sceneSampler , texCoord);}

return colour; }

Define the output colour and retrieve the diffuse refraction colour for current pixel

Test to see if this pixel should be refracted (alpha value > 0)

sampler sceneSampler : register(s0);

texture refractionDiffuse;sampler diffuseSampler = sampler_state{ Texture = (refractionDiffuse); };

float refractionOpacity = .5;

texture refractionNormal;sampler normalSampler = sampler_state{ Texture = (refractionDiffuse); };

float normalMapHeight = .05;

technique Refraction{

pass Pass0{

PixelShader = compile ps_2_0 RefractionPixelShader();

}}

Background scene sampler

Diffuse refraction texture and alpha value

Normal refraction texture and normal height

Technique definition

Extract the corresponding normal and transform into a texture lookup offset

Determine the refracted colour

Combine the refracted colour with the diffuse refraction colour

If alpha value = 0, it is assumed there is no refraction, i.e. just return normal colour

Page 9: 10 . 2. HLSL Effects II

HLSL EFFECTS : SHOCKWAVEShockwave HLSL effect

Page 10: 10 . 2. HLSL Effects II

A shockwave effect is a wavelike effect that expands out from some centre point.

A shockwave can be defined to have a wave front and wave tail. Typically the wave front is more ‘compressed’ than the wave tail.

Shockwave

Centre

RadiusWave

fron

tWa

ve ta

il

Page 11: 10 . 2. HLSL Effects II

Shockwave (definitions)

GraphicsDeviceManager graphics;SpriteBatch batch;Effect shockwaveEffect;

Texture2D scene;

RenderTarget2D renderTarget;

double time;

bool isAdditive;

renderTarget = new RenderTarget2D(graphics.GraphicsDevice,

graphics.GraphicsDevice,graphics.GraphicsDevice.Viewport.Width,graphics.GraphicsDevice.Viewport.Height,1, SurfaceFormat.Color );

Core objects used to define and support the operation of the effect

In this example, a ‘mock’ scene is held within a texture as the refraction background

The render target is used to hold the shockwave (build using the scene texture), which is then recombined with the scene

The shockwave time spans from 0 (just started) to 1 (maximum duration)

The isAdditive flag determines if additive or normal alpha blending is employed.

Page 12: 10 . 2. HLSL Effects II

Shockwave (update+draw)

protected override void Update(GameTime gameTime)

{time += gameTime.

ElapsedGameTime.TotalSeconds;if (time > 1.0f)

time = 0.0f;}

protected override void Draw(GameTime gameTime){

graphics.GraphicsDevice.SetRenderTarget(0, renderTarget);

batch.Begin();batch.Draw( scene,

new Rectangle( 0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height),Color.White);

batch.End();

graphics.GraphicsDevice.SetRenderTarget(0, null);

batch.Begin();batch.Draw( renderTarget.GetTexture(),

new Rectangle( 0, 0, graphics.GraphicsDevice.Viewport.Width,

graphics.GraphicsDevice.Viewport.Height),Color.White);

batch.End();

// ...

Draw the rendered scene to the back buffer

Setup the render target

Draw the base scene into the render target – typically lots of drawing

Page 13: 10 . 2. HLSL Effects II

Shockwave (draw)shockwaveEffect.Parameters["xcenter"].SetValue(0.5f);shockwaveEffect.Parameters["ycenter"].SetValue(0.5f);

shockwaveEffect.Parameters["width"].SetValue((float) time * 0.75f);shockwaveEffect.Parameters["magnitude"].SetValue((1.0f - (float) time ));

batch.Begin( Additive ? SpriteBlendMode.Additive : SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);

shockwaveEffect.Begin();EffectPass pass = shockwaveEffect.CurrentTechnique.Passes[0];pass.Begin();batch.Draw(renderTarget.GetTexture(), new Rectangle( 0, 0,

graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height),pass.End();shockwaveEffect.End();

batch.End();}

Generate the shockwave using the render target and draw to the back buffer.

Store the centre of the shockwave (in texture space, i.e. from 0 to 1) Set the current

width and magnitude of the shockwave (expanding width and diminishing magnitude over time)

Start the sprite batch with the correct blend mode

Render the generated scene using the shockwave effect

Page 14: 10 . 2. HLSL Effects II

Shockwave (shader)sampler2D samplerState : register(s0);

float xcenter;float ycenter;float magnitude;float width;

technique shockwave { pass {

pixelShader = compile ps_2_0 shockwave();

} }

float4 shockwave(float2 texCoord : TEXCOORD0) : COLOR0 {

float4 colour;float xdif = texCoord.x - xcenter;float ydif = texCoord.y - ycenter;float distance = sqrt(xdif * xdif + ydif * ydif) - width;float offset = abs(d);

if (distance < 0.1 && distance > -0.2) {if (distance < 0.0)

offset = (0.2 - offset) / 2.0;else

offset = (0.1 - offset);

texCoord.x += -(xdif * offset * magnitude); texCoord.y += -(ydif * offset * magnitude); colour = tex2D(samplerState, texCoord );

colour.a = offset * 12.0;} else {

colour.a = 0.0;}

return colour; }

If pixel is within shockwave radius, then determine offset lookup (the front of the wave is more strongly ramped than the tail of the wave)

Determine the shockwave’s pixel colour

Fade the shockwave out towards the edges of the waveIf not part of the

shockwave, then set the alpha value to zero

Define the centre of the shockwave, alongside its current magnitude and width

Determine distance from centre of shockwave. Set initial texture lookup offset to abs(distance)

Page 15: 10 . 2. HLSL Effects II

HLSL EFFECTS : POINT SPRITESUsing HLSL to draw point sprites

Page 16: 10 . 2. HLSL Effects II

Point Sprites (particle effects with point sprites)

If not using point sprites, each particle must be rendered using a screen aligned quad (i.e. two triangles sharing four vertices).

Using point sprites, only one vertex need be sent per particle with any drawn texture automatically mapped and aligned towards the screen.

The vertex/pixel shader can be used to update the particle effect (i.e. freeing up the CPU). Point sprites can be equally used within 2D and 3D games.

Page 17: 10 . 2. HLSL Effects II

Point Sprites (defining a custom vertex) public struct CustomVertexDefinition

{public Vector3 Position;public float PointSize;

public static int SizeInBytes = (3+1) * sizeof(float);

public CustomVertexDefinition( Vector3 Position, float PointSize) {this.Position = Position;this.PointSize = PointSize;

}

public static VertexElement[] VertexElements ={

new VertexElement( 0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),

new VertexElement(0, sizeof(float)*3, VertexElementFormat.Single,VertexElementMethod.Default, VertexElementUsage.PointSize, 0)

};}

The parameters needed to drive the point sprite effect should be defined here (ranging from a simple position, to a scale, alpha value, etc., etc.

The total size of the vertex (in bytes) must be defined here. Currently four floats.

Each vertex element is defined here. The second VertexElement parameter defines the offset for that element. The VertexElementUsage will enable the vertex element to be semantically mapped within the shader.

CustomVertexDefinition[] spriteArray = new CustomVertexDefinition[numSprites];

VertexDeclaration customVertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, CustomVertexDefinition.VertexElements);

Page 18: 10 . 2. HLSL Effects II

Point Sprites(world view projection matrix)Matrix projectionMatrix =

Matrix.CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearPlaneDistance, farPlaneDistance );

Matrix viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector );

Matrix worldMatrix = Matrix.Identity * Matrix.CreateTranslation(

new Vector3( 0, 0, -5) ) ;

Matrix wvpMatrix = worldMatrix * viewMatrix * projectionMatrix;

How wide and far the camera can see

What the camera is looking at

The world location of the camera

The combined world-view-projection matrix

Page 19: 10 . 2. HLSL Effects II

Point Sprites(drawing point sprites)protected override void Draw(GameTime gameTime){

graphics.GraphicsDevice.RenderState.PointSpriteEnable = true;

graphics.GraphicsDevice.VertexDeclaration = vertexPosColDecl;

// ...

pointSpritesEffect.Begin();foreach (EffectPass pass in pointSpritesEffect.CurrentTechnique.Passes){

pass.Begin(); graphics.GraphicsDevice.DrawUserPrimitives<CustomVertexDefinition>(

PrimitiveType.PointList, spriteArray, 0, spriteArray.Length);pass.End();

}pointSpritesEffect.End();

graphics.GraphicsDevice.RenderState.PointSpriteEnable = false;}

Instruct the GPU to consider vertices as point sprites

Specify the vertex format that will be used

Run the shader (e.g. particle effect)

Pass the created point sprite verticies to the GPU

Turn off point sprite drawing

Store other shader parameters, e.g. wvp matrix, etc.

Page 20: 10 . 2. HLSL Effects II

Point Sprites(shader)float4 vertexShader(

float4 position : POSITION0) : POSITION0{

// Vertex parameter transformation

return mul(position, wvpMatrix);}

float4 pixelShader(PixelShaderInput input) : COLOR0

{float4 colour =

tex2D(pointSpriteSampler, input.texCoord.xy );

// Transform pixel colour

return colour;}

Define the world-view-projection matrix

Define the point sprite texture

As the PC and XBox 360 use different input semantics when using point sprites, ensure a correct mapping

Transform any vertex parameters if needed

Translate world particle position to the on-screen position

Determine the base particle colour

Transform the output colour if needed

float4x4 wvpMatrix;

texture pointSpriteTexture;sampler pointSpriteSampler = sampler_state{

texture = <pointSpriteTexture>;};

struct PixelShaderInput{ #ifdef XBOX float2 texCoord : SPRITETEXCOORD; #else float2 texCoord : TEXCOORD0; #endif };

Page 21: 10 . 2. HLSL Effects II

Summary

To do:Complete Question

ClinicIf using XNA, decide if

you want to introduce custom effects into your game.

Today we explored:

Development of a refraction and shockwave shader effect

Exploration of point sprites and how they can be used for particle effects