HLSL for getting cylinder effect - silverlight

I need to write an application with Silverlight 4 and need to show images like wrapped on cylinder. I need some HLSL code, as I wont to do that with Effects of Silverlight.
I don't wont to do that with 3D libarries for silverlight. I only need HLSL code for changing pixels.
I need for my image to look like this
Thanks.

This seems to be the effect you want, you may wish to change the 0.2 value to increase or decrease the effect or make this adjustable in your shader but that's a simple change to do. I'd recommend Shazzam if your not using it for writing shaders for WPF or Silverlight.
sampler2D input : register(s0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float y = uv.y+(sin(uv.x*3.14) * lerp(-1,1,uv.y) * 0.2);
if(y < 0 || y > 1)
return float4(0,0,0,0);
else
return tex2D(input,float2(uv.x,y));
}

While you could do this with HLSL if you really wanted to, you'd normally do it by creating a mesh in the shape you want, then applying the picture to the mesh as a texture.

Related

Depth issue with infinite grid in opengl 3.3 with glsl

I'm following this article, using sokol_gfx with opengl core 3.3 profile. The grid renders, is transparent, is rendered after other objects in the scene, and blending is enabled.
When the camera is close to objects the grid will render behind them, however, as the camera moves away the grid will render in front of the objects. Also, when the camera is close to objects the grid doesnt render behind them when it should, it penetrates the object a little and then becomes transparent.
Here is an image showing the grid rendering on top of an object it should not, but also rendering behind an object it should. Both of the cubes are above the grid, it should be rendering behind both of them.
Depth
And here is an image showing the grid rendering past where it should. The bottom of the cube is on the same plane as the grid, the grid should stop at the edge of the cube, not go in a little ways and then stop.
Too much grid
Depth calculation from grid fragment shader:
float compute_depth (vec3 position) {
vec4 clip_space_position = frag_projection * frag_view * vec4 (position.xyz, 1.0);
return (clip_space_position.z / clip_space_position.w);
}
The full project is located here
I had the same issue. The problem is that the article is written for Vulkan, which handles the depth differently from OpenGL.
After reading GLSL gl_FragCoord.z Calculation and Setting gl_FragDepth I managed to solve the issue by modifying the fragment shader like this:
float compute_depth (vec3 position) {
vec4 clip_space_position = frag_projection * frag_view * vec4 (position.xyz, 1.0);
return 0.5 + 0.5 * (clip_space_position.z / clip_space_position.w);
}

How could mix noise and texture by Opengl shader?

I want to put my noise texture(like perlin noise or something else) on image texture,
when i add noise texture and image texture directly,it will make the src image texture light,
fragColor = vec4(image_texture+noise_texture,1.0);
when i use mix func, some arear will be darker,
fragColor = mix(image_texture,noise_texture,factor)
neither effect is good.
I've referred to a code that use the alpha channel for overlay directly,but it seems to change the background of the GLFW window directly to the image texture,because its shader doesn't use texture,just use alpha channel like this:
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
which I don't know how to do too. So,is there any good way to mix noise and texture?

CN1: Gradient with alpha channel

I would like to have a gradient which goes from black to transparent (not white). How can I achieve this?
From my attempt below I assume the gradient style color's alpha value is not considered:
gui_Footer.allStyles.apply {
backgroundType = Style.BACKGROUND_GRADIENT_LINEAR_VERTICAL
border = RoundRectBorder.create().topOnlyMode(true).cornerRadius(1f)
backgroundGradientEndColor = ColorUtil.BLACK
backgroundGradientStartColor = ColorUtil.argb(0, 255, 255, 255)
}
Gradients in Codename One ignore the alpha byte. While we could technically add support for alpha gradients it's not something that's planned at this time. You can probably generate such an image by manipulating the RGB data but it would be more efficient to just generate an RGB image of a gradient and draw it scaled.
Notice that this is generally the most efficient approach since the GPU works by drawing textures very efficiently. If an image is a power of 2 (e.g. 256x128 pixels) it can fit perfectly in a texture and it's drawn very fast. Much faster than our builtin gradients.

Using GLKBaseEffect is it possible to colorize a texture

I have a sheet of black shapes surrounded by transparency. I have successfully loaded this texture with GLKit and I can draw the shapes using GLKBaseEffect into rectangles. Is there a way to change the color of the black (ie non-transparent) pixels, so I can draw yellow shapes or blue shapes etc? Or do I need a custom shader to do this?
It seems like you'll need a custom shader (which I highly recommend working with) as you need to check individual texel color values, but here are some suggestions to try first:
You can pass color as per-vertex data in a vertex attribute array pointing to GLKVertexAttribColor. This will allow you to individually set the color of each vertex (and ultimately, faces) but it will be difficult to see where they line up against your texture.
You can try enabling the following property on your effect:
effect.colorMaterialEnabled = YES;
But, for both cases, if your texels are completely black then I don't think any changes in color will show.
I think a custom shader is definitely the way to go, as you'll need to do something like this:
highp vec4 finalColor;
highp vec4 textureColor = texture2D(uTexture, vTexel);
highp vec4 surfaceColor = uColor;
// If texel is non-transparent (check alpha channel)
if(textureColor.a > 0.001)
finalColor = surfaceColor;
else
finalColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = finalColor;
Where anything prefixed with u is a uniform variable passed into the shader.
To get fully colorized textures, use:
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
Which tells OpenGL to take whatever color is in your texture and multiply it by whatever color the underlying geometry is. You can then use vertex coloring to get neat fades and whatnot.
NOTE: You'll want to change your texture from black to white (1, 1, 1, 1), so multiplication works correctly.
NOTE: Here are some other settings that you should already have in place:
self.effect.texture2d0.enabled = GL_TRUE;
self.effect.texture2d0.target = GLKTextureTarget2D;
self.effect.texture2d0.name = self.texture.name;
self.effect.colorMaterialEnabled = GL_TRUE;
NOTE: You can experiment with GLKTextureEnvModeDecal, too, which blends your texture on top of colored geometry (as when applying a decal), so the transparent parts of the texture show the geometry underneath.

Handling alpha channel in WPF pixel shader effect

Is there something unusual about how the alpha component is handled in a pixel shader? I have a WPF application for which my artist is giving me grayscale images to use as backgrounds, and the application colorizes those images according to the current state. So I wrote a pixel shader (using the WPF Pixel Shader Effects Library infrastructure) to use as an effect on an Image element. The shader takes a color as a parameter, which it converts to HSL so it can manipulate brightness. Then for each grey pixel, it computes a color whose brightness is interpolated between the color parameter and white in proportion to the brightness of the source pixel.
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
// ...Do messy computation involving src brightness and color parameter...
float4 dst;
dst.r = ...
dst.g = ...
dst.b = ...
dst.a = src.a;
return dst;
}
This works just fine on the pixels where alpha = 1. But where alpha = 0, the resultant pixels come out white, rather than having the window's background show through. So I made a tiny change:
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
if (src.a == 0)
return src;
...
and now the transparent parts really are transparent. Why? Why didn't the dst.a = src.a statement in the first version accomplish that? Unfortunately, even this is only a partial fix, because it looks to me like the pixels with 0 < alpha < 1 are coming out white.
Does anyone know what I'm not understanding about alpha?
After some more web searching, I discovered the piece I was missing.
According to an article on MSDN: "WPF uses pre-multiplied alpha everywhere internally for a number of performance reasons, so that's also the way we interpret the color values in the custom pixel shader."
So the fix turns out to be to throw in a multiplication by alpha:
float4 main(float2 uv : TEXCOORD) : COLOR
{
...
dst.rgb *= src.a;
return dst;
}
And now my output looks as I expect it to.
0 < alpha < 1 are coming out white
What ranges are you expecting here?
All values are going to be in the range 0.0 and 1.0... pixel shaders do not work in discrete 256 colour ranges, they are floating point where 1.0 is the maximum intensity.
If your calculations end up setting r/g/b values to >1.0 you are going to get white...
http://www.facewound.com/tutorials/shader1/
Dude I am working on a XNA game, and I had to use a grayscale pixel shader and I got the same problem you are facing.
I donno if you are familiar with XNA environment or not, but I solved the problem by changing the SpriteBatch drawing SpriteBlendMode from SpriteBlendMode.None to SpriteBlendMode.AlphaBlend, I hope this can help you knowing the reason.
regards,

Resources