惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Jina AI
Jina AI
美团技术团队
博客园 - 聂微东
博客园 - 叶小钗
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园_首页
Spread Privacy
Spread Privacy
J
Java Code Geeks
雷峰网
雷峰网
宝玉的分享
宝玉的分享
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
量子位
L
LINUX DO - 热门话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
GRAHAM CLULEY
D
Darknet – Hacking Tools, Hacker News & Cyber Security
月光博客
月光博客
腾讯CDC
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tor Project blog
罗磊的独立博客
V
Vulnerabilities – Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
Project Zero
Project Zero
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tenable Blog
MyScale Blog
MyScale Blog
T
The Exploit Database - CXSecurity.com
GbyAI
GbyAI
博客园 - 【当耐特】
O
OpenAI News
Schneier on Security
Schneier on Security
S
Secure Thoughts
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Securelist
博客园 - 司徒正美

WebGL Fundamentals

WebGL Using 2 or More Textures WebGL Implementing DrawImage WebGL 2D Matrices WebGL Implementing A Matrix Stack WebGL 2D Rotation WebGL 2D Scale WebGL 2D Translation WebGL - Rasterization vs 3D libraries WebGL 3D - Cameras WebGL 3D Geometry - Lathe WebGL 3D - Directional Lighting WebGL 3D - Point Lighting WebGL 3D - Normal Mapping WebGL 3D - Spot Lighting WebGL - Orthographic 3D WebGL 3D Perspective Correct Texture Mapping WebGL 3D Perspective WebGL Textures WebGL and Alpha WebGL - Animation WebGL Anti-Patterns WebGL Attributes WebGL Boilerplate WebGL - Cross Origin Images WebGL Cross Platform Issues WebGL Cubemaps WebGL 3D - Data Textures WebGL - Drawing Multiple Things WebGL Drawing Without Data WebGL Environment Maps (reflections) WebGL Fog WebGL Framebuffers WebGL Fundamentals WebGL GPGPU WebGL How It Works WebGL Image Processing Continued WebGL Image Processing WebGL Indexed Vertices WebGL Optimization - Instanced Drawing WebGL - Less Code, More Fun WebGL Load Obj with Mtl WebGL Load Obj WebGL Matrices vs Math Matrices WebGL Multiple Views, Multiple Canvases WebGL Picking WebGL Planar and Perspective Projection Mapping WebGL Points, Lines, and Triangles WebGL Post Processing WebGL Precision Issues WebGL Pulling Vertices Accessing textures by pixel coordinate in WebGL2 A simple way to show the load on the GPU's vertex and fragment processing? Can anyone explain what this GLSL fragment shader is doing? Can I mute the warning about vertex attrib 0 being disabled? Create image warping effect in WebGL Creating a smudge/liquify effect How to draw Depth Sprites Determine min/max values for the entire image Don't blend a polygon that crosses itself Drawing 2D image with depth map to achieve pseudo-3D effect Drawing a heightmap Drawing layers with different points Drawing Many different models in a single draw call Drawing textured sprites with instanced drawing Efficient particle system in javascript? (WebGL) Emulating palette based graphics in WebGL FPS-like camera movement with basic matrix transformations Get the size of a point for collision checking GLSL shader to support coloring and texturing How can I compute for 500 points which of 1000 line segments is nearest to each point? How can I create a 16bit historgram of 16bit data How can I get all the uniforms and uniformBlocks How can I move the perspective vanishing point from the center of the canvas? How to Achieve Moving Line with Trail Effects How to bind an array of textures to a WebGL shader uniform? How to blend colors across 2 triangles How to combine more text drawing into fewer draw calls How to control the color between vertices How to create a torus How to detect clipped triangles in the framgment shader How to determine the average brightness in a scene? How to draw correctly textured trapezoid polygons How to fade the drawing buffer How to figure out how much GPU work to do without crashing WebGL How to get audio data into a shader How to get code completion for WebGL in Visual Studio Code How to get the 3d coordinates of a mouse click How to get pixelize effect in webgl? How to implement zoom from mouse in 2D WebGL How to import a heightmap in WebGL How to load images in the background with no jank How to make a smudge brush tool How to make WebGL canvas transparent How to optimize rendering a UI How to prevent texture bleeding with a texture atlas How to process particle positions How to read a single component with readPixels How to render large scale images like 32000x32000 How to simulate a 3D texture in WebGL How to support both WebGL and WebGL2
Apply a displacement map and specular map
WebGLFundame · 2025-02-26 · via WebGL Fundamentals

Question:

I am trying to apply both displacement mapping and specular mapping for the earth and only displacement mapping for the moon.

I could transfer height map to normal map but if I use the same height map to apply displacement mapping, it does not work as I expected..

Here is the example image

Example 1

as you can see the bumpness around the earth and the moon but there are no actual height diffrences.

If I apply specular map to the earth, the earth becomes like this

Example 2

I want only the ocean of the earth to shine but my code turns the earth into the whole black, I can only see some white dots on the earth...

These textures are from this site

Here is my both vertex shader code and the fragment shader code

"use strict";
const loc_aPosition = 3;
const loc_aNormal = 5;
const loc_aTexture = 7;
const VSHADER_SOURCE =
`#version 300 es
layout(location=${loc_aPosition}) in vec4 aPosition;
layout(location=${loc_aNormal}) in vec4 aNormal;
layout(location=${loc_aTexture}) in vec2 aTexCoord;


uniform mat4 uMvpMatrix;
uniform mat4 uModelMatrix;    // Model matrix
uniform mat4 uNormalMatrix;   // Transformation matrix of the normal

uniform sampler2D earth_disp;
uniform sampler2D moon_disp;

//uniform float earth_dispScale;
//uniform float moon_dispScale;

//uniform float earth_dispBias;
//uniform float moon_dispBias;

uniform bool uEarth;
uniform bool uMoon;


out vec2 vTexCoord;
out vec3 vNormal;
out vec3 vPosition;


void main() 
{

  float disp;

  if(uEarth)
    disp = texture(earth_disp, aTexCoord).r; //Extracting the color information from the image
  else if(uMoon)
    disp = texture(moon_disp, aTexCoord).r; //Extracting the color information from the image

  vec4 displace = aPosition;

  float displaceFactor = 2.0;
  float displaceBias = 0.5;

  if(uEarth || uMoon) //Using Displacement Mapping
  {
    displace += (displaceFactor * disp - displaceBias) * aNormal;
    gl_Position = uMvpMatrix * displace;
  }
  else //Not using displacement mapping
    gl_Position = uMvpMatrix * aPosition;

  // Calculate the vertex position in the world coordinate
  vPosition = vec3(uModelMatrix * aPosition);

  vNormal = normalize(vec3(uNormalMatrix * aNormal));
  vTexCoord = aTexCoord;

}`;

// Fragment shader program
const FSHADER_SOURCE =
`#version 300 es
precision mediump float;

uniform vec3 uLightColor;     // Light color
uniform vec3 uLightPosition;  // Position of the light source
uniform vec3 uAmbientLight;   // Ambient light color

uniform sampler2D sun_color;
uniform sampler2D earth_color;
uniform sampler2D moon_color;

uniform sampler2D earth_bump;
uniform sampler2D moon_bump;

uniform sampler2D specularMap;


in vec3 vNormal;
in vec3 vPosition;
in vec2 vTexCoord;
out vec4 fColor;

uniform bool uIsSun;
uniform bool uIsEarth;
uniform bool uIsMoon;



vec2 dHdxy_fwd(sampler2D bumpMap, vec2 UV, float bumpScale)
{
    vec2 dSTdx = dFdx( UV );
  vec2 dSTdy = dFdy( UV );
  float Hll = bumpScale * texture( bumpMap, UV ).x;
  float dBx = bumpScale * texture( bumpMap, UV + dSTdx ).x - Hll;
  float dBy = bumpScale * texture( bumpMap, UV + dSTdy ).x - Hll;
  return vec2( dBx, dBy );
}

vec3 pertubNormalArb(vec3 surf_pos, vec3 surf_norm, vec2 dHdxy)
{
    vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );
  vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );
  vec3 vN = surf_norm;  // normalized
  vec3 R1 = cross( vSigmaY, vN );
  vec3 R2 = cross( vN, vSigmaX );
  float fDet = dot( vSigmaX, R1 );
  fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
  vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );
  return normalize( abs( fDet ) * surf_norm - vGrad );
}



void main() 
{
    vec2 dHdxy;
    vec3 bumpNormal;
    float bumpness = 1.0;
    if(uIsSun)
      fColor = texture(sun_color, vTexCoord);
    else if(uIsEarth)
    {
      fColor = texture(earth_color, vTexCoord);
      dHdxy = dHdxy_fwd(earth_bump, vTexCoord, bumpness);
    }
    else if(uIsMoon)
    {
      fColor = texture(moon_color, vTexCoord);
      dHdxy = dHdxy_fwd(moon_bump, vTexCoord, bumpness);
    }



    // Normalize the normal because it is interpolated and not 1.0 in length any more
    vec3 normal = normalize(vNormal);


    // Calculate the light direction and make its length 1.
    vec3 lightDirection = normalize(uLightPosition - vPosition);



    // The dot product of the light direction and the orientation of a surface (the normal)
    float nDotL;
    if(uIsSun)
      nDotL = 1.0;
    else
      nDotL = max(dot(lightDirection, normal), 0.0);



    // Calculate the final color from diffuse reflection and ambient reflection
    vec3 diffuse = uLightColor * fColor.rgb * nDotL;
    vec3 ambient = uAmbientLight * fColor.rgb;
    float specularFactor = texture(specularMap, vTexCoord).r; //Extracting the color information from the image




    vec3 diffuseBump;
    if(uIsEarth || uIsMoon)
    {
      bumpNormal = pertubNormalArb(vPosition, normal, dHdxy);
      diffuseBump = min(diffuse + dot(bumpNormal, lightDirection), 1.1);
    }

    vec3 specular = vec3(0.0);
    float shiness = 12.0;
    vec3 lightSpecular = vec3(1.0);

    if(uIsEarth && nDotL > 0.0)
    {
      vec3 v = normalize(-vPosition); // EyePosition
      vec3 r = reflect(-lightDirection, bumpNormal); // Reflect from the surface
      specular = lightSpecular * specularFactor * pow(dot(r, v), shiness);
    }

    //Update Final Color
    if(uIsEarth)
      fColor = vec4( (diffuse * diffuseBump * specular) + ambient, fColor.a); // Specular
    else if(uIsMoon)
      fColor = vec4( (diffuse * diffuseBump) + ambient, fColor.a);
    else if(uIsSun)
      fColor = vec4(diffuse + ambient, fColor.a);
}`;

Could you tell me where do I have to check?

Answer:

If it was me I'd first strip the shader down the simplest thing and see if I get what I want. You want a specular shine so do you get a specular shine with only specular calculations in your shaders

Trimming your shaders to just draw a flat phong shading didn't produce the correct results

This line

fColor = vec4( (diffuse * specular) + ambient, fColor.a);

needed to be

fColor = vec4( (diffuse + specular) + ambient, fColor.a);

You add the specular, not multiply by it.

So now we can add in the specular map

Then you should argably not use lots of boolean conditionals on your shader. Either make different shaders for find a way to do it without the booleans. So for example we don't need

uniform sampler2D earth_disp;
uniform sampler2D moon_disp;

uniform sampler2D sun_color;
uniform sampler2D earth_color;
uniform sampler2D moon_color;

uniform sampler2D earth_bump;
uniform sampler2D moon_bump;

uniform bool uIsSun;
uniform bool uIsEarth;
uniform bool uIsMoon;

we can just have

uniform sampler2D displacementMap;
uniform sampler2D surfaceColor;
uniform sampler2D bumpMap;

Then we can set the displacementMap and the bumpMap to a single pixel 0,0,0,0 texture and there will be no displacement and no bump.

As for different lighting for sun, given the sun uses neither the bump map nor the displacement map nor even lighting at all it would arguably be better to use a different shader but, we can also just add a maxDot value like this

uniform float maxDot;

...

   nDotL = max(dot(lightDirection, normal), maxDot)

If maxDot is zero we'll get a normal dot product. If maxDot is one we get no lighting.

As for the displacement, displacement only works on vertices so you need a lot of vertices in your sphere to be able to see any displacement

As well there was an bug related to displacement. You're passing in normals as vec4 and this line

displace += (displaceFactor * disp - displaceBias) * aNormal;

Ends up adding a vec4 displacement. In other words let's say you started with an a_Position of vec4(1,0,0,1) which would be on the left side of the sphere. aNormal because you declared it as a vec4 is probably vec4(1,0,0,1) as well. Assuming you're actually passing it vec3 normal data via attributes from your buffer the default value for W is 1. Let's assume disp is 1, displaceFactor is 2 and displaceBias is 0.5 which is what you had. You end up wioth

displace = vec4(1,0,0,1) + (2 * 1 + 0.5) * vec4(1,0,0,1)
displace = vec4(1,0,0,1) + (1.5) * vec4(1,0,0,1)
displace = vec4(1,0,0,1) + vec4(1.5,0,0,1.5)
displace = vec4(2.5,0,0,2.5)

But you don't want W to be 2.5. One fix is to just use the xyz part of the normal.

displace.xyz += (displaceFactor * disp - displaceBias) * aNormal.xyz;

The more normal fix would be to only declare the normal attribute as vec3

in vec3 aNormal;

displace.xyz += (displaceFactor * disp - displaceBias) * aNormal;

In my example above the spheres are only radius = 1 so we only want adjust this displacement a little. I set displaceFactor to 0.1 and displaceBias to 0.

The question and quoted portions thereof are CC BY-SA 4.0 by ZeroFive005 from here